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