HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_PrimVDB.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GEO_PrimVDB.h ( GEO Library, C++)
7  *
8  * COMMENTS: Custom VDB primitive.
9  */
10 
11 #ifndef __GEO_PrimVDB__
12 #define __GEO_PrimVDB__
13 
14 #include "GEO_API.h"
15 
16 #include "GEO_Primitive.h"
17 
18 // NOTE: Not using SYS_Version for now.
19 #include <UT/UT_Version.h>
20 
21 #if (UT_VERSION_INT < 0x0c010072) // earlier than 12.1.114
22 #include "GEO_PrimVolume.h"
23 #else
24 #include "GEO_VolumeOptions.h"
25 #endif
26 
27 #include <GA/GA_Defines.h>
28 
29 #include <SYS/SYS_AtomicInt.h> // for SYS_AtomicCounter
30 
31 #include <UT/UT_BoundingBox.h>
32 #include <UT/UT_VDBUtils.h>
33 
34 #include <openvdb/Platform.h>
35 #include <openvdb/openvdb.h>
36 
37 
38 class GEO_Detail;
39 class GEO_PrimVolume;
41 class UT_MemoryCounter;
42 
43 #if (UT_VERSION_INT < 0x0c050000) // earlier than 12.5.0
45 {
47  {
48  }
50  : myMode(mode)
51  , myIso(iso)
52  , myDensity(density)
53  {
54  }
55  bool operator==(const GEO_VolumeOptions &v) const
56  {
58  return (myMode == v.myMode
59  && myIso == v.myIso
60  && myDensity == v.myDensity);
62  }
63  bool operator!=(const GEO_VolumeOptions &v) const
64  {
65  return !(*this == v);
66  }
67 
71 };
72 #endif
73 
74 
76 {
77 public:
78  typedef uint64 UniqueId;
79 
80 protected:
81  /// NOTE: The constructor should only be called from subclass
82  /// constructors.
84 
85 public:
87  { return GA_FAMILY_NONE; }
88 
89  /// @{
90  /// Required interface methods
91  virtual bool isDegenerate() const;
92  virtual int getBBox(UT_BoundingBox *bbox) const;
93  virtual void reverse();
94  virtual UT_Vector3 computeNormal() const;
95  virtual void copyPrimitive(const GEO_Primitive *src);
96 #if (UT_VERSION_INT >= 0x12000023)
97  virtual void copySubclassData(const GA_Primitive *source);
98 #else
99  virtual void copyUnwiredForMerge(const GA_Primitive *src,
100  const GA_MergeMap &map);
101 #endif
102 
110  { return getVertexOffset(0); }
113  { return getPointOffset(0); }
116  { setPointOffset(0, pt); }
119  { return getPos3(0); }
121  void setPos3(const UT_Vector3 &pos)
122  { setPos3(0, pos); }
123 
124  /// Convert an index in the voxel array into the corresponding worldspace
125  /// location
126  void indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
127  void findexToPos(UT_Vector3 index, UT_Vector3 &pos) const;
128  void indexToPos(exint x, exint y, exint z, UT_Vector3D &pos) const;
129  void findexToPos(UT_Vector3D index, UT_Vector3D &pos) const;
130 
131  /// Convert a 3d position into the closest index value.
132  void posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
133  void posToIndex(UT_Vector3 pos, UT_Vector3 &index) const;
134  void posToIndex(UT_Vector3D pos, exint &x, exint &y, exint &z) const;
135  void posToIndex(UT_Vector3D pos, UT_Vector3D &index) const;
136 
137  /// Evaluate the voxel value at the given world space position.
138  /// Note that depending on the underlying VDB type, this may not
139  /// be sensible, in which case a zero will silently be returned
140  fpreal getValueF(const UT_Vector3 &pos) const;
141  fpreal getValueAtIndexF(int ix, int iy, int iz) const;
142  UT_Vector3D getValueV3(const UT_Vector3 &pos) const;
143  UT_Vector3D getValueAtIndexV3(int ix, int iy, int iz) const;
144 
145  void getValues(float *f, int stride, const UT_Vector3 *pos, int num) const;
146  void getValues(int *f, int stride, const UT_Vector3 *pos, int num) const;
147  void getValuesAtIndices(float *f, int stride, const int *ix, const int *iy, const int *iz, int num) const;
148  void getValuesAtIndices(int *f, int stride, const int *ix, const int *iy, const int *iz, int num) const;
149 
150  /// Vector grid variants.
151  void getValues(UT_Vector3 *f, int stride, const UT_Vector3 *pos, int num) const;
152  void getValuesAtIndices(UT_Vector3 *f, int stride, const int *ix, const int *iy, const int *iz, int num) const;
153 
154  void getValues(double *f, int stride, const UT_Vector3D *pos, int num) const;
155  void getValues(exint *f, int stride, const UT_Vector3D *pos, int num) const;
156  void getValuesAtIndices(double *f, int stride, const exint *ix, const exint *iy, const exint *iz, int num) const;
157  void getValuesAtIndices(exint *f, int stride, const exint *ix, const exint *iy, const exint *iz, int num) const;
158 
159  /// Vector grid variants.
160  void getValues(UT_Vector3D *f, int stride, const UT_Vector3D *pos, int num) const;
161  void getValuesAtIndices(UT_Vector3D *f, int stride, const exint *ix, const exint *iy, const exint *iz, int num) const;
162 
163  // Worldspace gradient at the given position
164  UT_Vector3 getGradient(const UT_Vector3 &pos) const;
165 
166  /// Evaluate this grid's gradients at the given world space positions.
167  /// Does nothing and returns false if grid is non-scalar.
168  /// If normalize is true, then the gradients will be normalized to be unit
169  /// length.
170  bool evalGradients(
171  UT_Vector3 *gradients,
172  int gradients_stride,
173  const UT_Vector3 *positions,
174  int num_positions,
175  bool normalize = false) const;
176 
177  /// Get the storage type of the grid
180  { return myGridAccessor.getStorageType(); }
181  /// Get the tuple size, usually 1 or 3
183  int getTupleSize() const
184  { return UTvdbGetGridTupleSize(getStorageType()); }
185 
186  bool isSDF() const;
187 
188  /// True if the two volumes map the same indices to the same positions.
189  bool isAligned(const GEO_PrimVDB *vdb) const;
190  /// True if the two volumes have the same active regions
191  bool isActiveRegionMatched(const GEO_PrimVDB *vdb) const;
192 
193  /// True if we are aligned with the world axes. Ie, all our
194  /// off diagonals are zero and our diagonal is positive.
195  bool isWorldAxisAligned() const;
196 
197  // Transform the matrix associated with this primitive. Translate is
198  // ignored.
199  virtual void transform(const UT_Matrix4 &mat);
200 
201  /// Accessors for the 4x4 matrix representing the affine transform that
202  /// converts from index space voxel coordinates to world space. For frustum
203  /// maps, this will be transform as if the taper value is set to 1.
204  /// @{
205  void setTransform4(const UT_DMatrix4 &xform4);
206  void setTransform4(const UT_Matrix4 &xform4);
207  UT_Matrix4D getTransform4() const;
208  /// @}
209 
210  // Take the whole set of points into consideration when applying the
211  // point removal operation to this primitive. The method returns 0 if
212  // successful, -1 if it failed because it would have become degenerate,
213  // and -2 if it failed because it would have had to remove the primitive
214  // altogether.
215  virtual int detachPoints(GA_PointGroup &grp);
216  /// Before a point is deleted, all primitives using the point will be
217  /// notified. The method should return "false" if it's impossible to
218  /// delete the point. Otherwise, the vertices should be removed.
219  virtual GA_DereferenceStatus dereferencePoint(GA_Offset point,
220  bool dry_run=false);
221  virtual GA_DereferenceStatus dereferencePoints(
222  const GA_RangeMemberQuery &pt_q,
223  bool dry_run=false);
224  virtual const GA_PrimitiveJSON *getJSON() const;
225 
226  /// This method assigns a preallocated vertex to the quadric, optionally
227  /// creating the topological link between the primitive and new vertex.
228  void assignVertex(GA_Offset new_vtx, bool update_topology);
229 
230  /// Evalaute a point given a u,v coordinate (with derivatives)
231  virtual bool evaluatePointRefMap(GA_Offset result_vtx,
232  GA_AttributeRefMap &hlist,
233  fpreal u, fpreal v, uint du, uint dv) const;
234  /// Evalaute position given a u,v coordinate (with derivatives)
235  virtual int evaluatePointV4(UT_Vector4 &pos, float u, float v = 0,
236  unsigned du=0, unsigned dv=0) const
237  {
238  return GEO_Primitive::evaluatePointV4(pos, u, v,
239  du, dv);
240  }
241  /// @}
242 
243  /// Convert transforms between native volumes and VDBs
244  /// @{
245 
246  /// Get a GEO_PrimVolumeXform which represent's the grid's full transform.
247  /// The returned space's fromVoxelSpace() method will convert index space
248  /// voxel coordinates to world space positions (and the vice versa for
249  /// toVoxelSpace()).
250  GEO_PrimVolumeXform getIndexSpaceTransform() const;
251 
252  /// Equivalent to getSpaceTransform(getGrid().evalActiveVoxelBoundingBox()).
253  /// The returned space's fromVoxelSpace() method will convert 0-1
254  /// coordinates over the active voxel bounding box to world space (and vice
255  /// versa for toVoxelSpace()).
256  GEO_PrimVolumeXform getSpaceTransform() const;
257 
258  /// Gives the equivalent to GEO_PrimVolume's getSpaceTransform() by using
259  /// the given bounding box to determine the bounds of the transform.
260  /// The resulting world space sample points will be offset by half a voxel
261  /// so that they match GEO_PrimVolume.
262  /// The returned space's fromVoxelSpace() method will convert 0-1
263  /// coordinates over the bbox extents to world space (and vice versa for
264  /// toVoxelSpace()).
265  GEO_PrimVolumeXform getSpaceTransform(const UT_BoundingBoxD &bbox) const;
266 
267  /// Sets the transform from a GEO_PrimVolume's getSpaceTransform() by using
268  /// the index space [(0,0,0), resolution] bbox. If force_taper is true,
269  /// then the resulting transform will always be a NonlinearFrustumMap even
270  /// if there is no tapering.
271  void setSpaceTransform(const GEO_PrimVolumeXform &space,
272  const UT_Vector3R &resolution,
273  bool force_taper = false);
274 
275  /// @}
276 
277  fpreal getTaper() const;
278 
279  /// Returns the resolution of the active voxel array.
280  /// Does *not* mean the indices go from 0..rx, however!
281  void getRes(int &rx, int &ry, int &rz) const;
282 
283  /// Computes the voxel diameter by taking a step in x, y, and z
284  /// converting to world space and taking the length of that vector.
285  fpreal getVoxelDiameter() const;
286 
287  /// Returns the length of the voxel when you take an x, y, and z step
288  UT_Vector3 getVoxelSize() const;
289 
290  /// Compute useful aggregate properties of the volume.
291  fpreal calcMinimum() const;
292  fpreal calcMaximum() const;
293  fpreal calcAverage() const;
294 
295  /// VDBs may either be unbounded, or created with a specific frustum
296  /// range. The latter is important for tapered VDBs that otherwise
297  /// have a singularity at the camera location. Tools can use the
298  /// presence of an idxbox as a clipping box in index space.
299  /// This does *NOT* relate to getRes - it may be much larger or
300  /// even in some cases smaller.
301  bool getFrustumBounds(UT_BoundingBox &idxbox) const;
302 
304  {
305  ACTIVATE_UNION, // Activate anything in source
306  ACTIVATE_INTERSECT, // Deactivate anything not in source
307  ACTIVATE_SUBTRACT, // Deactivate anything in source
308  ACTIVATE_COPY // Set our activation to match source
309  };
310 
311  /// Activates voxels given an *index* space bounding box. This
312  /// is an inclusive box.
313  /// If this is Frustum VDB, the activation will be clipped by that.
314  /// Setting the value only takes effect if the voxels are activated,
315  /// deactivated voxels are set to the background.
317  const openvdb::CoordBBox& bbox,
318  ActivateOperation operation,
319  bool setvalue, fpreal value)
320  {
321  activateIndexBBoxAdapter(
322  &bbox, operation, setvalue, value);
323  }
324 
325  /// Activates all of the voxels in this VDB that are touched
326  /// by active voxels in the source.
327  /// If ignore_transform is true, voxels will be activated
328  /// by grid index instead of world space position.
329  void activateByVDB(const GEO_PrimVDB *vdb,
330  ActivateOperation operation,
331  bool setvalue, fpreal value,
332  bool ignore_transform=false);
333 
334  /// @{
335  /// Though not strictly required (i.e. not pure virtual), these methods
336  /// should be implemented for proper behaviour.
337  virtual GEO_Primitive *copy(int preserve_shared_pts = 0) const;
338 
339  // Have we been deactivated and stashed?
340  virtual void stashed(bool beingstashed, GA_Offset offset=GA_INVALID_OFFSET);
341 
342  /// @}
343 
344  /// @{
345  /// Optional interface methods. Though not required, implementing these
346  /// will give better behaviour for the new primitive.
347  virtual UT_Vector3 baryCenter() const;
348  virtual fpreal calcVolume(const UT_Vector3 &refpt) const;
349  /// Calculate the surface area of the active voxels where
350  /// a voxel face contributes if it borders an inactive voxel.
351  virtual fpreal calcArea() const;
352  /// @}
353 
354  /// @{
355  /// Enlarge a bounding box by the bounding box of the primitive. A
356  /// return value of false indicates an error in the operation, most
357  /// likely an invalid P. For any attribute other than the position
358  /// these methods simply enlarge the bounding box based on the vertex.
359  virtual bool enlargeBoundingBox(UT_BoundingRect &b,
360  const GA_Attribute *P) const;
361  virtual bool enlargeBoundingBox(UT_BoundingBox &b,
362  const GA_Attribute *P) const;
363  virtual void enlargePointBounds(UT_BoundingBox &e) const;
364  /// @}
365  /// Enlarge a bounding sphere to encompass the primitive. A return value
366  /// of false indicates an error in the operation, most likely an invalid
367  /// P. For any attribute other than the position this method simply
368  /// enlarges the sphere based on the vertex.
370  const GA_Attribute *P) const;
371 
372  /// Accessor for the local 3x3 affine transform matrix for the primitive.
373  /// For frustum maps, this will be transform as if the taper value is set
374  /// to 1.
375  /// @{
376  virtual void getLocalTransform(UT_Matrix3D &result) const;
377  virtual void setLocalTransform(const UT_Matrix3D &new_mat3);
378  /// @}
379 
380  /// @internal Hack to condition 4x4 matrices that we avoid creating what
381  /// OpenVDB erroneously thinks are singular matrices. Returns true if mat4
382  /// was modified.
383  static bool conditionMatrix(UT_Matrix4D &mat4);
384 
385  /// Visualization accessors
386  /// @{
387  const GEO_VolumeOptions &getVisOptions() const { return myVis; }
389  { setVisualization(vis.myMode, vis.myIso, vis.myDensity, vis.myLod); }
390 
392  GEO_VolumeVis vismode,
393  fpreal iso,
394  fpreal density,
396  {
397  myVis.myMode = vismode;
398  myVis.myIso = iso;
399  myVis.myDensity = density;
400  myVis.myLod = lod;
401  }
402  GEO_VolumeVis getVisualization() const { return myVis.myMode; }
403  fpreal getVisIso() const { return myVis.myIso; }
404  fpreal getVisDensity() const { return myVis.myDensity; }
405  GEO_VolumeVisLod getVisLod() const { return myVis.myLod; }
406  /// @}
407 
408  /// Load the order from a JSON value
409  bool loadOrder(const UT_JSONValue &p);
410 
411  /// @{
412  /// Save/Load vdb to a JSON stream
413  bool saveVDB(UT_JSONWriter &w, const GA_SaveMap &sm,
414  bool as_shmem = false) const;
415  bool loadVDB(UT_JSONParser &p,
416  bool as_shmem = false);
417  /// @}
418 
419  bool saveVisualization(
420  UT_JSONWriter &w,
421  const GA_SaveMap &map) const;
422  bool loadVisualization(
423  UT_JSONParser &p,
424  const GA_LoadMap &map);
425 
426  /// Method to perform quick lookup of vertex without the virtual call
428  {
429  UT_ASSERT_P(index < 1);
430  return getVertexOffset();
431  }
432 
433  void setVertexPoint(int i, GA_Offset pt)
434  {
435  if (i == 0)
436  setPointOffset(pt);
437  }
438 
439  /// @brief Computes the total density of the volume, scaled by
440  /// the volume's size. Negative values will be ignored.
441  fpreal calcPositiveDensity() const;
442 
444  bool hasGrid() const { return myGridAccessor.hasGrid(); }
445 
446  /// @brief If this primitive's grid's voxel data (i.e., its tree)
447  /// is shared, replace the tree with a deep copy of itself that is
448  /// not shared with anyone else.
451  { myGridAccessor.makeGridUnique(); }
452 
453  /// @brief Returns if the tree is not shared. If it is not shared,
454  /// one can make destructive edits without makeGridUnique.
455  bool isGridUnique() const
456  { return myGridAccessor.isGridUnique(); }
457 
458  /// @brief Return a reference to this primitive's grid.
459  /// @note Calling setGrid() invalidates all references previously returned.
461  const openvdb::GridBase & getConstGrid() const
462  { return myGridAccessor.getConstGrid(*this); }
463  /// @brief Return a reference to this primitive's grid.
464  /// @note Calling setGrid() invalidates all references previously returned.
466  const openvdb::GridBase & getGrid() const
467  { return getConstGrid(); }
468  /// @brief Return a reference to this primitive's grid.
469  /// @note Calling setGrid() invalidates all references previously returned.
470  /// @warning Call makeGridUnique() before modifying the grid's voxel data.
472  openvdb::GridBase & getGrid()
473  {
474  incrGridUniqueIds();
475  return myGridAccessor.getGrid(*this);
476  }
477 
478  /// @brief Return a shared pointer to this primitive's grid.
479  /// @note Calling setGrid() causes the grid to which the shared pointer
480  /// refers to be disassociated with this primitive.
482  openvdb::GridBase::ConstPtr getConstGridPtr() const
483  { return myGridAccessor.getConstGridPtr(*this); }
484  /// @brief Return a shared pointer to this primitive's grid.
485  /// @note Calling setGrid() causes the grid to which the shared pointer
486  /// refers to be disassociated with this primitive.
487  openvdb::GridBase::ConstPtr getGridPtr() const
488  { return getConstGridPtr(); }
489  /// @brief Return a shared pointer to this primitive's grid.
490  /// @note Calling setGrid() causes the grid to which the shared pointer
491  /// refers to be disassociated with this primitive.
492  /// @warning Call makeGridUnique() before modifying the grid's voxel data.
494  openvdb::GridBase::Ptr getGridPtr()
495  {
496  incrGridUniqueIds();
497  return myGridAccessor.getGridPtr(*this);
498  }
499 
500  /// @brief Set this primitive's grid to a shallow copy of the given grid.
501  /// @note Invalidates all previous getGrid() and getConstGrid() references
503  void setGrid(const openvdb::GridBase &grid, bool copyPosition=true)
504  {
505  incrGridUniqueIds();
506  myGridAccessor.setGrid(grid, *this, copyPosition);
507  }
508 
509  /// @brief Return a reference to this primitive's grid metadata.
510  /// @note Calling setGrid() invalidates all references previously returned.
511  const openvdb::MetaMap& getConstMetadata() const
512  { return getConstGrid(); }
513  /// @brief Return a reference to this primitive's grid metadata.
514  /// @note Calling setGrid() invalidates all references previously returned.
515  const openvdb::MetaMap& getMetadata() const
516  { return getConstGrid(); }
517  /// @brief Return a reference to this primitive's grid metadata.
518  /// @note Calling setGrid() invalidates all references previously returned.
520  openvdb::MetaMap& getMetadata()
521  {
522  incrMetadataUniqueId();
523  return myGridAccessor.getGrid(*this);
524  }
525 
526  /// @brief Return the value of this primitive's "name" attribute
527  /// in the given detail.
528  const char * getGridName() const;
529 
530  /// @brief Return this primitive's serial number.
531  /// @details A primitive's serial number never changes.
533  { return static_cast<UniqueId>(myUniqueId.relaxedLoad()); }
534 
535  /// @brief Return the serial number of this primitive's voxel data.
536  /// @details The serial number is incremented whenever a non-const
537  /// reference or pointer to this primitive's grid is requested
538  /// (whether or not the voxel data is ultimately modified).
540  { return static_cast<UniqueId>(myTreeUniqueId.relaxedLoad()); }
541  /// @brief Return the serial number of this primitive's grid metadata.
542  /// @details The serial number is incremented whenever a non-const
543  /// reference to the metadata or non-const access to the grid is requested
544  /// (whether or not the metadata is ultimately modified).
546  { return static_cast<UniqueId>(myMetadataUniqueId.relaxedLoad()); }
547  /// @brief Return the serial number of this primitive's transform.
548  /// @details The serial number is incremented whenever the transform
549  /// is modified or non-const access to this primitive's grid is requested
550  /// (whether or not the transform is ultimately modified).
552  { return static_cast<UniqueId>(myTransformUniqueId.relaxedLoad()); }
553 
554 protected:
556 
557  /// Register intrinsic attributes
559 
560  /// Return true if the given metadata token is an intrinsic
561  static bool isIntrinsicMetadata(const char *name);
562 
563  /// @warning vertexPoint() doesn't check the bounds. Use with caution.
564  GA_Offset vertexPoint(GA_Size) const
565  { return getPointOffset(); }
566 
567  /// Report approximate memory usage, excluding sizeof(*this),
568  /// because the subclass doesn't have access to myGridAccessor.
569  int64 getBaseMemoryUsage() const;
570 
571  // This is called by the subclasses to count the
572  // memory used by this, excluding sizeof(*this).
574 
575  /// @brief Return an ID number that is guaranteed to be unique across
576  /// all VDB primitives.
577  static UniqueId nextUniqueId();
578 
580  { myTreeUniqueId.maximum(nextUniqueId()); }
582  { myMetadataUniqueId.maximum(nextUniqueId()); }
584  { myTransformUniqueId.maximum(nextUniqueId()); }
586  {
587  incrTreeUniqueId();
588  incrMetadataUniqueId();
589  incrTransformUniqueId();
590  }
591 
592  /// @brief Replace this primitive's grid with a shallow copy
593  /// of another primitive's grid.
594  void copyGridFrom(const GEO_PrimVDB&, bool copyPosition=true);
595 
596  /// @brief GridAccessor manages access to a GEO_PrimVDB's grid.
597  /// @details In keeping with OpenVDB library conventions, the grid
598  /// is stored internally by shared pointer. However, grid objects
599  /// are never shared among primitives, though their voxel data
600  /// (i.e., their trees) may be shared.
601  /// <p>Among other things, GridAccessor
602  /// - ensures that each primitive's transform and metadata are unique
603  /// (i.e., not shared with anyone else)
604  /// - allows primitives to share voxel data but, via makeGridUnique(),
605  /// provides a way to break the connection
606  /// - ensures that the primitive's transform and the grid's transform
607  /// are in sync (specifically, the translation component, which is
608  /// stored independently as a vertex offset).
610  {
611  public:
613  GridAccessor() : myStorageType(UT_VDB_INVALID)
614  { }
615 
617  void clear()
618  {
619  myGrid.reset();
620  myStorageType = UT_VDB_INVALID;
621  }
622 
624  openvdb::GridBase &
625  getGrid(const GEO_PrimVDB &prim)
626  { updateGridTranslates(prim); return *myGrid; }
627 
629  const openvdb::GridBase &
630  getConstGrid(const GEO_PrimVDB &prim) const
631  { updateGridTranslates(prim); return *myGrid; }
632 
634  openvdb::GridBase::Ptr
635  getGridPtr(const GEO_PrimVDB &prim)
636  { updateGridTranslates(prim); return myGrid; }
637 
639  openvdb::GridBase::ConstPtr
640  getConstGridPtr(const GEO_PrimVDB &prim) const
641  { updateGridTranslates(prim); return myGrid; }
642 
643  // These accessors will ensure the transform's translate is set into
644  // the vertex position.
646  void setGrid(const openvdb::GridBase& grid, GEO_PrimVDB& prim, bool copyPosition=true)
647  { setGridAdapter(&grid, prim, copyPosition); }
650  const openvdb::math::Transform &xform,
651  GEO_PrimVDB &prim)
652  { setTransformAdapter(&xform, prim); }
653 
654  void makeGridUnique();
655  bool isGridUnique() const;
656 
658  UT_VDBType getStorageType() const { return myStorageType; }
659 
661  bool hasGrid() const { return myGrid != 0; }
662 
663  private:
664  void updateGridTranslates(const GEO_PrimVDB &prim) const;
665 
667  void setVertexPosition(
668  const openvdb::math::Transform &xform,
669  GEO_PrimVDB &prim)
670  { setVertexPositionAdapter(&xform, prim); }
671 
672  void setGridAdapter(const void* grid, GEO_PrimVDB&, bool copyPosition);
673  void setTransformAdapter(const void* xform, GEO_PrimVDB&);
674  void setVertexPositionAdapter(const void* xform, GEO_PrimVDB&);
675 
676  private:
677  openvdb::GridBase::Ptr myGrid;
678  UT_VDBType myStorageType;
679  };
680 
681 private:
682  void activateIndexBBoxAdapter(
683  const void* bbox,
684  ActivateOperation,
685  bool setvalue, fpreal value);
686 
687 
688  GridAccessor myGridAccessor;
689 
690  GEO_VolumeOptions myVis;
691 
692  AtomicUniqueId myUniqueId;
693  AtomicUniqueId myTreeUniqueId;
694  AtomicUniqueId myMetadataUniqueId;
695  AtomicUniqueId myTransformUniqueId;
696 
697 }; // class GEO_PrimVDB
698 
699 
700 #if 0 // ndef SESI_OPENVDB
701 namespace openvdb_houdini {
702 using ::GEO_VolumeOptions;
703 using ::GEO_PrimVDB;
704 }
705 #endif
706 
707 
708 ////////////////////////////////////////
709 
710 
711 namespace UT_VDBUtils {
712 
713 // This overload of UT_VDBUtils::callTypedGrid(), for GridBaseType = GEO_PrimVDB,
714 // calls makeGridUnique() on the primitive just before instantiating and
715 // invoking the functor on the primitive's grid. This delays the call
716 // to makeGridUnique() until it is known to be necessary and thus avoids
717 // making deep copies of grids of types that won't be processed.
718 template<typename GridType, typename OpType>
719 inline void
720 callTypedGrid(GEO_PrimVDB& prim, OpType& op)
721 {
722  prim.makeGridUnique();
723 
724 #ifdef _MSC_VER
725  op.operator()<GridType>(*(UTverify_cast<GridType*>(&prim.getGrid())));
726 #else
727  op.template operator()<GridType>(*(UTverify_cast<GridType*>(&prim.getGrid())));
728 #endif
729 }
730 
731 // Overload of callTypedGrid() for GridBaseType = const GEO_PrimVDB
732 template<typename GridType, typename OpType>
733 inline void
734 callTypedGrid(const GEO_PrimVDB& prim, OpType& op)
735 {
736 #ifdef _MSC_VER
737  op.operator()<GridType>(*(UTverify_cast<const GridType*>(&prim.getConstGrid())));
738 #else
739  op.template operator()<GridType>(*(UTverify_cast<const GridType*>(&prim.getConstGrid())));
740 #endif
741 }
742 
743 } // namespace UT_VDBUtils
744 
745 // Define UTvdbProcessTypedGrid*() (see UT_VDBUtils.h) for grids
746 // belonging to primitives, for various subsets of grid types.
749 
750 
751 ////////////////////////////////////////
752 
753 
754 /// @brief Utility function to process the grid of a const primitive using functor @a op.
755 /// @details It will invoke @code op.operator()<GridT>(const GridT &grid) @endcode
756 /// @{
757 template <typename OpT>
758 inline bool GEOvdbProcessTypedGrid(const GEO_PrimVDB &vdb, OpT &op)
759 {
760  return UTvdbProcessTypedGrid(vdb.getStorageType(), vdb.getGrid(), op);
761 }
762 
763 template <typename OpT>
764 inline bool GEOvdbProcessTypedGridReal(const GEO_PrimVDB &vdb, OpT &op)
765 {
766  return UTvdbProcessTypedGridReal(vdb.getStorageType(), vdb.getGrid(), op);
767 }
768 
769 template <typename OpT>
770 inline bool GEOvdbProcessTypedGridScalar(const GEO_PrimVDB &vdb, OpT &op)
771 {
772  return UTvdbProcessTypedGridScalar(vdb.getStorageType(), vdb.getGrid(), op);
773 }
774 
775 template <typename OpT>
776 inline bool GEOvdbProcessTypedGridTopology(const GEO_PrimVDB &vdb, OpT &op)
777 {
778  return UTvdbProcessTypedGridTopology(vdb.getStorageType(), vdb.getGrid(), op);
779 }
780 
781 template <typename OpT>
782 inline bool GEOvdbProcessTypedGridVec3(const GEO_PrimVDB &vdb, OpT &op)
783 {
784  return UTvdbProcessTypedGridVec3(vdb.getStorageType(), vdb.getGrid(), op);
785 }
786 
787 template <typename OpT>
788 inline bool GEOvdbProcessTypedGridPoint(const GEO_PrimVDB &vdb, OpT &op)
789 {
790  return UTvdbProcessTypedGridPoint(vdb.getStorageType(), vdb.getGrid(), op);
791 }
792 /// @}
793 
794 /// @brief Utility function to process the grid of a primitive using functor @a op.
795 /// @param vdb the primitive whose grid is to be processed
796 /// @param op a functor with a call operator of the form
797 /// @code op.operator()<GridT>(GridT &grid) @endcode
798 /// @param makeUnique if @c true, call <tt>vdb.makeGridUnique()</tt> before
799 /// invoking the functor
800 /// @{
801 template <typename OpT>
802 inline bool GEOvdbProcessTypedGrid(GEO_PrimVDB &vdb, OpT &op, bool makeUnique = true)
803 {
804  if (makeUnique) return UTvdbProcessTypedGrid(vdb.getStorageType(), vdb, op);
805  return UTvdbProcessTypedGrid(vdb.getStorageType(), vdb.getGrid(), op);
806 }
807 
808 template <typename OpT>
809 inline bool GEOvdbProcessTypedGridReal(GEO_PrimVDB &vdb, OpT &op, bool makeUnique = true)
810 {
811  if (makeUnique) return UTvdbProcessTypedGridReal(vdb.getStorageType(), vdb, op);
812  return UTvdbProcessTypedGridReal(vdb.getStorageType(), vdb.getGrid(), op);
813 }
814 
815 template <typename OpT>
816 inline bool GEOvdbProcessTypedGridScalar(GEO_PrimVDB &vdb, OpT &op, bool makeUnique = true)
817 {
818  if (makeUnique) return UTvdbProcessTypedGridScalar(vdb.getStorageType(), vdb, op);
819  return UTvdbProcessTypedGridScalar(vdb.getStorageType(), vdb.getGrid(), op);
820 }
821 
822 template <typename OpT>
823 inline bool GEOvdbProcessTypedGridTopology(GEO_PrimVDB &vdb, OpT &op, bool makeUnique = true)
824 {
825  if (makeUnique) return UTvdbProcessTypedGridTopology(vdb.getStorageType(), vdb, op);
826  return UTvdbProcessTypedGridTopology(vdb.getStorageType(), vdb.getGrid(), op);
827 }
828 
829 template <typename OpT>
830 inline bool GEOvdbProcessTypedGridVec3(GEO_PrimVDB &vdb, OpT &op, bool makeUnique = true)
831 {
832  if (makeUnique) return UTvdbProcessTypedGridVec3(vdb.getStorageType(), vdb, op);
833  return UTvdbProcessTypedGridVec3(vdb.getStorageType(), vdb.getGrid(), op);
834 }
835 
836 template <typename OpT>
837 inline bool GEOvdbProcessTypedGridPoint(GEO_PrimVDB &vdb, OpT &op, bool makeUnique = true)
838 {
839  if (makeUnique) return UTvdbProcessTypedGridPoint(vdb.getStorageType(), vdb, op);
840  return UTvdbProcessTypedGridPoint(vdb.getStorageType(), vdb.getGrid(), op);
841 }
842 /// @}
843 
844 #endif // __GEO_PrimVDB__
bool operator==(const GEO_VolumeOptions &v) const
Definition: GEO_PrimVDB.h:55
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
GridAccessor manages access to a GEO_PrimVDB's grid.
Definition: GEO_PrimVDB.h:609
virtual GEO_Primitive * copy(int preserve_shared_pts=0) const
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GA_Primitive.h:246
virtual UT_Vector3 baryCenter() const
openvdb::GridBase::ConstPtr getGridPtr() const
Return a shared pointer to this primitive's grid.
Definition: GEO_PrimVDB.h:487
GA_Offset fastVertexOffset(GA_Size UT_IF_ASSERT_P(index)) const
Method to perform quick lookup of vertex without the virtual call.
Definition: GEO_PrimVDB.h:427
GLenum src
Definition: glew.h:2410
virtual void copyPrimitive(const GEO_Primitive *src)=0
SYS_FORCE_INLINE UT_VDBType getStorageType() const
Get the storage type of the grid.
Definition: GEO_PrimVDB.h:179
bool GEOvdbProcessTypedGridTopology(const GEO_PrimVDB &vdb, OpT &op)
Utility function to process the grid of a const primitive using functor op.
Definition: GEO_PrimVDB.h:776
SYS_FORCE_INLINE void setPos3(const UT_Vector3 &pos)
Definition: GEO_PrimVDB.h:121
GLuint const GLchar * name
Definition: glew.h:1814
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
SYS_FORCE_INLINE openvdb::MetaMap & getMetadata()
Return a reference to this primitive's grid metadata.
Definition: GEO_PrimVDB.h:520
SYS_FORCE_INLINE GridAccessor()
Definition: GEO_PrimVDB.h:613
void copyUnwiredForMerge(const GA_Primitive *src, const GA_MergeMap &map)
Definition: GA_Primitive.h:455
GLenum mode
Definition: glew.h:2163
SYS_FORCE_INLINE void clear()
Definition: GEO_PrimVDB.h:617
GLuint index
Definition: glew.h:1814
SYS_FORCE_INLINE openvdb::GridBase::ConstPtr getConstGridPtr() const
Return a shared pointer to this primitive's grid.
Definition: GEO_PrimVDB.h:482
bool operator!=(const GEO_VolumeOptions &v) const
Definition: GEO_PrimVDB.h:63
virtual void copySubclassData(const GA_Primitive *source)
Definition: GA_Primitive.h:476
SYS_AtomicCounter AtomicUniqueId
Definition: GEO_PrimVDB.h:555
const openvdb::MetaMap & getMetadata() const
Return a reference to this primitive's grid metadata.
Definition: GEO_PrimVDB.h:515
SYS_FORCE_INLINE const openvdb::GridBase & getConstGrid() const
Return a reference to this primitive's grid.
Definition: GEO_PrimVDB.h:461
virtual int evaluatePointV4(UT_Vector4 &pos, float u, float v=0, unsigned du=0, unsigned dv=0) const
Evalaute position given a u,v coordinate (with derivatives)
Definition: GEO_PrimVDB.h:235
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
SYS_FORCE_INLINE void setPointOffset(GA_Size i, GA_Offset ptoff)
Definition: GA_Primitive.h:252
UniqueId getUniqueId() const
Return this primitive's serial number.
Definition: GEO_PrimVDB.h:532
virtual bool enlargeBoundingBox(UT_BoundingRect &b, const GA_Attribute *P) const
GLsizei GLsizei GLchar * source
Definition: glew.h:1832
virtual GA_DereferenceStatus dereferencePoint(GA_Offset point, bool dry_run=false)=0
void incrTransformUniqueId()
Definition: GEO_PrimVDB.h:583
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:75
#define GA_DECLARE_INTRINSICS(OVERRIDE)
Definition: GA_Primitive.h:80
GEO_VolumeVis myMode
Definition: GEO_PrimVDB.h:68
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
Abstract base class for a range membership query object.
const GLdouble * v
Definition: glew.h:1391
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
Definition: UT_Assert.h:208
UT_VDBType
Definition: UT_VDBUtils.h:11
#define GA_NO_OVERRIDE
Definition: GA_Primitive.h:76
const GEO_VolumeOptions & getVisOptions() const
Definition: GEO_PrimVDB.h:387
#define UT_IF_ASSERT_P(ZZ)
Definition: UT_Assert.h:161
bool GEOvdbProcessTypedGridPoint(const GEO_PrimVDB &vdb, OpT &op)
Utility function to process the grid of a const primitive using functor op.
Definition: GEO_PrimVDB.h:788
SYS_FORCE_INLINE openvdb::GridBase::ConstPtr getConstGridPtr(const GEO_PrimVDB &prim) const
Definition: GEO_PrimVDB.h:640
UniqueId getMetadataUniqueId() const
Return the serial number of this primitive's grid metadata.
Definition: GEO_PrimVDB.h:545
void incrGridUniqueIds()
Definition: GEO_PrimVDB.h:585
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:231
SYS_FORCE_INLINE int64 getBaseMemoryUsage() const
Report approximate memory usage for myVertexList for subclasses.
Definition: GA_Primitive.h:796
GA_PrimitiveFamilyMask
void setVisualization(GEO_VolumeVis vismode, fpreal iso, fpreal density, GEO_VolumeVisLod lod=GEO_VOLUMEVISLOD_FULL)
Definition: GEO_PrimVDB.h:391
virtual UT_Vector3 computeNormal() const =0
Return a normal vector for the primitive.
#define GA_INVALID_OFFSET
Definition: GA_Types.h:674
SYS_FORCE_INLINE UT_Vector3 getPos3() const
Definition: GEO_PrimVDB.h:118
bool GEOvdbProcessTypedGridReal(const GEO_PrimVDB &vdb, OpT &op)
Utility function to process the grid of a const primitive using functor op.
Definition: GEO_PrimVDB.h:764
bool GEOvdbProcessTypedGridVec3(const GEO_PrimVDB &vdb, OpT &op)
Utility function to process the grid of a const primitive using functor op.
Definition: GEO_PrimVDB.h:782
GLdouble GLdouble z
Definition: glew.h:1559
uint64 UniqueId
Definition: GEO_PrimVDB.h:78
virtual bool isDegenerate() const =0
Is the primitive degenerate.
GA_Size GA_Offset
Definition: GA_Types.h:637
SYS_FORCE_INLINE bool hasGrid() const
Definition: GEO_PrimVDB.h:661
virtual bool enlargeBoundingSphere(UT_BoundingSphere &b, const GA_Attribute *P) const
SYS_FORCE_INLINE GA_Offset getPointOffset() const
Definition: GEO_PrimVDB.h:112
long long int64
Definition: SYS_Types.h:111
#define UT_VDB_DECL_PROCESS_TYPED_GRID(GRID_BASE_T)
Utility function that, given a generic grid pointer, calls a functor on the fully-resolved grid...
Definition: UT_VDBUtils.h:241
SYS_FORCE_INLINE UT_VDBType getStorageType() const
Definition: GEO_PrimVDB.h:658
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Size i) const
Definition: GA_Primitive.h:266
virtual void setLocalTransform(const UT_Matrix3D &matrix)
Set the local transform. The default implementation does nothing.
GEO_VolumeOptions(GEO_VolumeVis mode, fpreal iso, fpreal density)
Definition: GEO_PrimVDB.h:49
unsigned long long uint64
Definition: SYS_Types.h:112
GLclampf f
Definition: glew.h:3499
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
SYS_FORCE_INLINE openvdb::GridBase::Ptr getGridPtr()
Return a shared pointer to this primitive's grid.
Definition: GEO_PrimVDB.h:494
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
bool GEOvdbProcessTypedGridScalar(const GEO_PrimVDB &vdb, OpT &op)
Utility function to process the grid of a const primitive using functor op.
Definition: GEO_PrimVDB.h:770
GEO_VolumeVisLod myLod
virtual fpreal calcArea() const
int64 exint
Definition: SYS_Types.h:120
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:134
void incrMetadataUniqueId()
Definition: GEO_PrimVDB.h:581
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
virtual const GA_PrimitiveJSON * getJSON() const =0
void setVertexPoint(int i, GA_Offset pt)
Definition: GEO_PrimVDB.h:433
Provide a JSON interface to a primitive.
#define GEO_API
Definition: GEO_API.h:14
void activateIndexBBox(const openvdb::CoordBBox &bbox, ActivateOperation operation, bool setvalue, fpreal value)
Definition: GEO_PrimVDB.h:316
SYS_FORCE_INLINE void setTransform(const openvdb::math::Transform &xform, GEO_PrimVDB &prim)
Definition: GEO_PrimVDB.h:649
GEO_VolumeVis
SYS_FORCE_INLINE int getTupleSize() const
Get the tuple size, usually 1 or 3.
Definition: GEO_PrimVDB.h:183
virtual void reverse()=0
Reverse the order of vertices.
A handle to simplify manipulation of multiple attributes.
UniqueId getTreeUniqueId() const
Return the serial number of this primitive's voxel data.
Definition: GEO_PrimVDB.h:539
SYS_FORCE_INLINE bool hasGrid() const
Definition: GEO_PrimVDB.h:444
Options during loading.
Definition: GA_LoadMap.h:42
virtual int getBBox(UT_BoundingBox *bbox) const =0
#define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
Definition: Math.h:74
GridType::Ptr normalize(const GridType &grid, bool threaded, InterruptT *interrupt)
Normalize the vectors of the given vector-valued grid.
SYS_FORCE_INLINE void setGrid(const openvdb::GridBase &grid, GEO_PrimVDB &prim, bool copyPosition=true)
Definition: GEO_PrimVDB.h:646
SYS_FORCE_INLINE openvdb::GridBase & getGrid(const GEO_PrimVDB &prim)
Definition: GEO_PrimVDB.h:625
SYS_FORCE_INLINE openvdb::GridBase::Ptr getGridPtr(const GEO_PrimVDB &prim)
Definition: GEO_PrimVDB.h:635
virtual GA_DereferenceStatus dereferencePoints(const GA_RangeMemberQuery &pt_q, bool dry_run=false)=0
SYS_FORCE_INLINE GA_Offset getVertexOffset() const
Definition: GEO_PrimVDB.h:109
unsigned int uint
Definition: SYS_Types.h:44
SYS_FORCE_INLINE void setGrid(const openvdb::GridBase &grid, bool copyPosition=true)
Set this primitive's grid to a shallow copy of the given grid.
Definition: GEO_PrimVDB.h:503
SYS_FORCE_INLINE void setPos3(GA_Size i, const UT_Vector3 &pos) const
Definition: GA_Primitive.h:272
UniqueId getTransformUniqueId() const
Return the serial number of this primitive's transform.
Definition: GEO_PrimVDB.h:551
GLsizei stride
Definition: glew.h:1523
virtual void transform(const UT_Matrix4 &)
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
virtual void enlargePointBounds(UT_BoundingBox &box) const
GLfloat GLfloat p
Definition: glew.h:16321
SYS_FORCE_INLINE const openvdb::GridBase & getConstGrid(const GEO_PrimVDB &prim) const
Definition: GEO_PrimVDB.h:630
virtual void getLocalTransform(UT_Matrix3D &matrix) const
double fpreal
Definition: SYS_Types.h:276
virtual int detachPoints(GA_PointGroup &grp)=0
GLuint counter
Definition: glew.h:2740
fpreal getVisDensity() const
Definition: GEO_PrimVDB.h:404
SYS_FORCE_INLINE void makeGridUnique()
If this primitive's grid's voxel data (i.e., its tree) is shared, replace the tree with a deep copy o...
Definition: GEO_PrimVDB.h:450
bool isGridUnique() const
Returns if the tree is not shared. If it is not shared, one can make destructive edits without makeGr...
Definition: GEO_PrimVDB.h:455
GLuint num
Definition: glew.h:2690
int UTvdbGetGridTupleSize(UT_VDBType type)
Returns the tuple size of a grid given its value type.
Definition: UT_VDBUtils.h:108
GLint lod
Definition: glew.h:1385
virtual fpreal calcVolume(const UT_Vector3 &) const
SYS_FORCE_INLINE GA_Offset getVertexOffset(GA_Size primvertexnum) const
Definition: GA_Primitive.h:232
void setVisOptions(const GEO_VolumeOptions &vis)
Definition: GEO_PrimVDB.h:388
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:76
virtual bool evaluatePointRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v=0, uint du=0, uint dv=0) const =0
GEO_VolumeVisLod getVisLod() const
Definition: GEO_PrimVDB.h:405
GLuint64EXT * result
Definition: glew.h:14007
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_PrimVDB.h:86
void callTypedGrid(GEO_PrimVDB &prim, OpType &op)
Definition: GEO_PrimVDB.h:720
GEO_VolumeVisLod
#define const
Definition: zconf.h:214
SYS_FORCE_INLINE const openvdb::GridBase & getGrid() const
Return a reference to this primitive's grid.
Definition: GEO_PrimVDB.h:466
fpreal getVisIso() const
Definition: GEO_PrimVDB.h:403
SYS_FORCE_INLINE void setPointOffset(GA_Offset pt)
Definition: GEO_PrimVDB.h:115
void countBaseMemory(UT_MemoryCounter &counter) const
GLsizei const GLfloat * value
Definition: glew.h:1849
GEO_VolumeVis getVisualization() const
Definition: GEO_PrimVDB.h:402
SYS_FORCE_INLINE openvdb::GridBase & getGrid()
Return a reference to this primitive's grid.
Definition: GEO_PrimVDB.h:472
bool GEOvdbProcessTypedGrid(const GEO_PrimVDB &vdb, OpT &op)
Utility function to process the grid of a const primitive using functor op.
Definition: GEO_PrimVDB.h:758
void incrTreeUniqueId()
Definition: GEO_PrimVDB.h:579
virtual int evaluatePointV4(UT_Vector4 &pos, float u, float v=0, unsigned du=0, unsigned dv=0) const
virtual void stashed(bool beingstashed, GA_Offset offset=GA_INVALID_OFFSET)
const openvdb::MetaMap & getConstMetadata() const
Return a reference to this primitive's grid metadata.
Definition: GEO_PrimVDB.h:511
GLintptr offset
Definition: glew.h:1682
#define OPENVDB_NO_FP_EQUALITY_WARNING_END
Definition: Math.h:75