HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_PrimVolume.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_PrimVolume.h ( GEO Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GEO_PrimVolume__
12 #define __GEO_PrimVolume__
13 
14 #include <UT/UT_BoundingRect.h>
15 #include <UT/UT_VoxelArray.h>
16 
17 #include "GEO_API.h"
18 #include "GEO_Primitive.h"
19 #include "GEO_VolumeOptions.h"
20 
21 class UT_JSONWriter;
22 class UT_JSONParser;
23 class GA_SaveMap;
24 class GA_LoadMap;
25 class CE_Grid;
26 class CE_Image;
27 class IMX_Layer;
28 
29 ///
30 /// Stores the transform associated with a volume, allowing the
31 /// to/from code to be inlined outside of this library.
32 ///
34 {
35 public:
36  // Converts from world space to [0,1] space.
38  {
39  pos -= myCenter;
40  pos *= myInverseXform;
41 
42  // Undo any taper effect.
43  if (myHasTaper)
44  {
45  fpreal zscale = (1 - pos.z()) * 0.5f;
46  fpreal taperx = 1 + (-1 + myTaperX) * zscale;
47  fpreal tapery = 1 + (-1 + myTaperY) * zscale;
48 
49  if (taperx == 0.0f)
50  pos.x() = 0.0;
51  else
52  pos.x() /= taperx;
53  if (tapery == 0.0f)
54  pos.y() = 0.0;
55  else
56  pos.y() /= tapery;
57  }
58 
59  // This gets us a value in the -1 to 1 box. We need to evaluate
60  // in the 0 to 1 box, however.
61  pos.x() += 1;
62  pos.y() += 1;
63  pos.z() += 1;
64  pos *= 0.5;
65 
66  return pos;
67  }
68 
69  // Converts from [0,1] space over the voxels to world space
71  {
72  // convert to -1 to 1 box.
73  pos.x() -= 0.5;
74  pos.y() -= 0.5;
75  pos.z() -= 0.5;
76  pos *= 2;
77 
78  // Apply the taper effect.
79  if (myHasTaper)
80  {
81  fpreal zscale = (1 - pos.z()) * 0.5f;
82  fpreal taperx = 1 + (-1 + myTaperX) * zscale;
83  fpreal tapery = 1 + (-1 + myTaperY) * zscale;
84 
85  pos.x() *= taperx;
86  pos.y() *= tapery;
87  }
88  // Convert to world space.
89  pos *= myXform;
90  pos += myCenter;
91 
92  return pos;
93  }
94 
95  // Returns jacobian of the transformation `toVoxelSpace` at point `pos`
96  //
97  // If `myHasTaper() == false` then the jacobian does not depend on the position `pos`.
98  //
99  // Vector `v` located at point `pos` gets transformed by `toVoxelSpace` map as:
100  // v -> v * toVoxelSpaceJacobian(pos)
101  //
102  // `toVoxelSpaceJacobian(pos)` is inverse of `fromVoxelSpaceJacobian(toVoxelSpace(pos))`
104  {
105  if (!myHasTaper)
106  return myInverseXform*0.5;
107 
108  pos -= myCenter;
109  pos *= myInverseXform;
110 
111  float zscale = (1 - pos.z()) * 0.5f;
112  float taperx = 1 + (-1 + myTaperX) * zscale;
113  float tapery = 1 + (-1 + myTaperY) * zscale;
114 
115  UT_Matrix3 tapergrad{
116  1.f / taperx,
117  0.f,
118  0.f,
119  0.f,
120  1.f / tapery,
121  0.f,
122  0.5f * (myTaperX - 1.f) * pos.x() / (taperx * taperx),
123  0.5f * (myTaperY - 1.f) * pos.y() / (tapery * tapery),
124  1.f};
125 
126  return myInverseXform*tapergrad*0.5;
127  }
128 
129  // Returns jacobian of the transformation `fromVoxelSpace` at point `pos`
130  //
131  // If `myHasTaper == false` then the jacobian does not depend on the position `pos`.
132  //
133  // Vector `v` located at point `pos` gets transformed by `fromVoxelSpace` map as:
134  // v -> v * fromVoxelSpaceJacobian(pos)
135  //
136  // `fromVoxelSpaceJacobian(pos)` is inverse of `toVoxelSpaceJacobian(fromVoxelSpace(pos))`
138  {
139  if (!myHasTaper)
140  return 2.f*myXform;
141 
142  pos.x() -= 0.5;
143  pos.y() -= 0.5;
144  pos.z() -= 0.5;
145  pos *= 2;
146 
147  float zscale = (1 - pos.z()) * 0.5f;
148  float taperx = 1 + (-1 + myTaperX) * zscale;
149  float tapery = 1 + (-1 + myTaperY) * zscale;
150 
151  UT_Matrix3 tapergrad{
152  1.f * taperx,
153  0.f,
154  0.f,
155  0.f,
156  1.f * tapery,
157  0.f,
158  0.5f * (1.f - myTaperX) * pos.x(),
159  0.5f * (1.f - myTaperY) * pos.y(),
160  1.f};
161 
162  return 2.f*tapergrad*myXform;
163  }
164 
165 
166  inline void transform(const UT_Matrix4 &xform)
167  {
168  myCenter *= xform;
169  myXform.multiply3(xform);
170  myInverseXform = myXform;
171  myInverseXform.invert();
172  }
173 
174  inline void transform(const UT_Matrix4D &xform)
175  {
176  myCenter *= xform;
177  myXform *= UT_Matrix3D(xform);
178  myInverseXform = myXform;
179  myInverseXform.invert();
180  }
181 
182  inline void toVoxelSpace(UT_BoundingBox &box) const
183  {
184  int i;
185  UT_Vector3 v[8] = {
186  UT_Vector3(box.xmin(), box.ymin(), box.zmin()),
187  UT_Vector3(box.xmin(), box.ymin(), box.zmax()),
188  UT_Vector3(box.xmin(), box.ymax(), box.zmin()),
189  UT_Vector3(box.xmin(), box.ymax(), box.zmax()),
190  UT_Vector3(box.xmax(), box.ymin(), box.zmin()),
191  UT_Vector3(box.xmax(), box.ymin(), box.zmax()),
192  UT_Vector3(box.xmax(), box.ymax(), box.zmin()),
193  UT_Vector3(box.xmax(), box.ymax(), box.zmax()),
194  };
195 
196  box.initBounds();
197  for (i = 0; i < 8; i++)
198  {
199  box.enlargeBounds(toVoxelSpace(v[i]));
200  }
201  }
202 
203  inline void fromVoxelSpace(UT_BoundingBox &box) const
204  {
205  int i;
206  UT_Vector3 v[8] = {
207  UT_Vector3(box.xmin(), box.ymin(), box.zmin()),
208  UT_Vector3(box.xmin(), box.ymin(), box.zmax()),
209  UT_Vector3(box.xmin(), box.ymax(), box.zmin()),
210  UT_Vector3(box.xmin(), box.ymax(), box.zmax()),
211  UT_Vector3(box.xmax(), box.ymin(), box.zmin()),
212  UT_Vector3(box.xmax(), box.ymin(), box.zmax()),
213  UT_Vector3(box.xmax(), box.ymax(), box.zmin()),
214  UT_Vector3(box.xmax(), box.ymax(), box.zmax()),
215  };
216 
217  box.initBounds();
218  for (i = 0; i < 8; i++)
219  {
220  box.enlargeBounds(fromVoxelSpace(v[i]));
221  }
222  }
223 
224  /// Returns the *un-tapered* matrix4 corresponding to fromVoxelSpace().
225  /// @{
226  void getTransform4(UT_Matrix4F &matx) const;
227  void getTransform4(UT_Matrix4D &matx) const;
228  /// @}
229 
230  /// Returns if the transform is flagged as having a taper.
231  bool isTapered() const { return myHasTaper; }
232 
233  /// Compute the size for this transform (relative to myCenter)
234  UT_Vector3R computeSize() const;
235 
236  // NOTE: This ordering is saved in .hip files!
238  {
239  NON_SQUARE = 0,
244  BY_SIZE
245  };
246 
247  /// Convert the "uniformsamples" parm menu item index to a sampling type
249  { return SamplingType(i); }
250 
251  /// Compute the resolution (and size) from a common set of parameters.
252  /// If twod_axis is one of [0,1,2], then that axis clamped to a divisions
253  /// of 1 and a size of 0. The number of divisions is returned with size
254  /// set to div_size multiplied by divisions before the z_div_scale.
255  static UT_Vector3R computeResolution(
256  SamplingType sampling_type,
257  const UT_Vector3R &non_uniform_divs,
258  fpreal uniform_divs,
259  fpreal div_size,
260  fpreal z_div_scale,
261  UT_Vector3R &size_inout,
262  int twod_axis = -1);
263 
264  /// Compute a space transform from center, size, and taper
265  static GEO_PrimVolumeXform frustumSpaceTransform(
266  const UT_Vector3R &size,
267  const UT_Vector3R &center,
268  fpreal taper_x, fpreal taper_y);
269 
270  /// Compute a space transform from camera settings.
271  /// The ortho_zoom parameter is only used when is_ortho = true.
272  static GEO_PrimVolumeXform cameraFrustum(
273  fpreal focal,
274  fpreal aperture,
275  const UT_Vector2R &image_res,
276  fpreal pixel_aspect,
277  bool is_ortho,
278  fpreal ortho_zoom,
279  fpreal clip_near,
280  fpreal clip_far,
281  bool use_cam_window,
282  const UT_BoundingRectR &cam_window,
283  const UT_BoundingRectR &cam_crop,
284  const UT_BoundingRectR &window,
285  const UT_Matrix4R &post_xform,
286  const GEO_Detail *match_src);
287 
288 public:
289  // @{
290  void save(std::ostream &os, bool binary = false) const;
291  bool load(UT_IStream &is);
292  // @}
293 
294  void init()
295  {
296  myCenter.assign(0, 0, 0);
297  myXform.identity();
298  myInverseXform.identity();
299  myHasTaper = false;
300  myTaperX = 1.0;
301  myTaperY = 1.0;
302  }
303 
304  bool operator==(const GEO_PrimVolumeXform &x) const
305  {
306  return
307  myXform == x.myXform &&
308  myCenter == x.myCenter &&
309  myHasTaper == x.myHasTaper &&
310  myTaperX == x.myTaperX &&
311  myTaperY == x.myTaperY;
312  }
313 
314  UT_Matrix3 myXform, myInverseXform;
317  float myTaperX, myTaperY;
318 };
319 
321 {
322 protected:
323  /// NOTE: The constructor should only be called from subclass
324  /// constructors.
326 
327  /// NOTE: The destructor should only be called from subclass
328  /// destructors.
329  ~GEO_PrimVolume() override;
330 
331 public:
333  {
334  // The order here matches typeid() in VEX:
335  // If you change the order, update the intrinsics.
341  };
342 
343 //
344 // Methods common to all primitives.
346  UT_Vector3 &nml,
347  float u, float v=0, float w=0) const override;
348  bool getBBox(UT_BoundingBox *bbox) const override;
349  void addToBSphere(
350  UT_BoundingSphere *bsphere) const override;
351  void enlargePointBounds(UT_BoundingBox &box) const override;
352  /// @{
353  /// Enlarge a bounding box by the bounding box of the primitive. A
354  /// return value of false indicates an error in the operation, most
355  /// likely an invalid P. For any attribute other than the position
356  /// these methods simply enlarge the bounding box based on the vertex.
357  bool enlargeBoundingBox(
359  const GA_Attribute *P) const override;
360  bool enlargeBoundingBox(
361  UT_BoundingBox &b,
362  const GA_Attribute *P) const override;
363  /// @}
364  /// Enlarge a bounding sphere to encompass the primitive. A return value
365  /// of false indicates an error in the operation, most likely an invalid
366  /// P. For any attribute other than the position this method simply
367  /// enlarges the sphere based on the vertex.
370  const GA_Attribute *P) const override;
371  /// For a volume the barycenter is the same as the point.
372  UT_Vector3 baryCenter() const override;
373  UT_Vector3 computeNormal() const override;
374  UT_Vector3D computeNormalD() const override;
375  bool saveH9(
376  std::ostream &os, bool binary,
377  const UT_Array<GA_AttribSaveDataH9> &prim_attribs,
378  const UT_Array<GA_AttribSaveDataH9> &vtx_attribs
379  ) const override;
380  bool loadH9(
381  UT_IStream &is,
382  const UT_Array<GA_AttribLoadDataH9> &prim_attribs,
383  const UT_Array<GA_AttribLoadDataH9> &vtx_attribs
384  ) override;
385 
386  bool saveVoxelArray(UT_JSONWriter &w,
387  const GA_SaveMap &map) const;
388  bool loadVoxelArray(UT_JSONParser &p,
389  const GA_LoadMap &map);
390 
391  bool loadRes(const UT_JSONValue &jval);
392  bool loadStorageType(const char *storagename);
393  bool saveBorder(UT_JSONWriter &w,
394  const GA_SaveMap &map) const;
395  bool loadBorder(UT_JSONParser &p,
396  const GA_LoadMap &map);
397  bool saveCompression(UT_JSONWriter &w,
398  const GA_SaveMap &map) const;
399  bool loadCompression(UT_JSONParser &p,
400  const GA_LoadMap &map);
401  bool saveVisualization(UT_JSONWriter &w,
402  const GA_SaveMap &map) const;
403  bool loadVisualization(UT_JSONParser &p,
404  const GA_LoadMap &map);
405 
406  /// @{
407  /// Methods to save/load shared voxel data
408  static const int theSharedVoxelMagic=('V'<<24)|('o'<<16)|('x'<<8)|('l');
410  int dtype,
411  GA_SharedDataHandlePtr data) override;
412  bool saveSharedLoadData(
413  UT_JSONWriter &w,
414  GA_SaveMap &save,
415  GA_GeometryIndex *geo_index) const override;
416  bool getSharedVoxelKey(UT_WorkBuffer &key) const;
418  allocateSharedDataLoader();
419  /// @}
420 
421  // Transforms the matrix associated with this primitive. The
422  // translate component is ignored: Translate the vertices of
423  // the primitive to translate the primitive.
424  // This only works with quadrics (sphere, tube, metaballs) and volumes.
425  void transform(const UT_Matrix4 &mat) override;
426 
427  void reverse() override {}
428  GEO_Primitive *copy(int preserve_shared_pts = 0) const override;
429  void copyPrimitive(const GEO_Primitive *src) override;
430  void copySubclassData(const GA_Primitive *source) override;
435 
438  {
439  return getVertexOffset(0);
440  }
443  {
444  return getPointOffset(0);
445  }
448  {
449  return getPos3(0);
450  }
452  void setPos3(const UT_Vector3 &pos)
453  {
454  return setPos3(0, pos);
455  }
456 
457  // Take the whole set of points into consideration when applying the
458  // point removal operation to this primitive. The method returns 0 if
459  // successful, -1 if it failed because it would have become degenerate,
460  // and -2 if it failed because it would have had to remove the primitive
461  // altogether.
462  int detachPoints(GA_PointGroup &grp) override;
463 
464  /// Before a point is deleted, all primitives using the point will be
465  /// notified. The method should return "false" if it's impossible to
466  /// delete the point. Otherwise, the vertices should be removed.
467  GA_DereferenceStatus dereferencePoint(GA_Offset point,
468  bool dry_run=false) override;
469  GA_DereferenceStatus dereferencePoints(const GA_RangeMemberQuery &pt_q,
470  bool dry_run=false) override;
471 
472  bool isDegenerate() const override;
473 
474  // Map the normalized length (distance value [0,1]) parameter to the unit
475  // parameterization of the primitve
477  float ulength, float vlength,
478  float &uparm, float &vparm) const override;
480  float ulength, float vlength,
481  float &uparm, float &vparm,
482  float tolerance) const override;
483 
485  float uparm, float vparm,
486  float &ulength, float &vlength) const override;
487 
488  fpreal calcVolume(const UT_Vector3 &refpt) const override;
489  fpreal calcArea() const override;
490 
491 //
492 // Methods unique to PrimVolume.
493 
494 #if GA_PRIMITIVE_VERTEXLIST
496  void setVertexPoint(GA_Offset pt)
497  {
499  }
500 #else
502  {
503  wireVertex(myVertex, pt);
504  }
505 #endif
506 
507  /// This method assigns a preallocated vertex to the quadric, optionally
508  /// creating the topological link between the primitive and new vertex.
509  void assignVertex(GA_Offset new_vtx, bool update_topology);
510 
511  // Have we been deactivated and stashed?
512  void stashed(bool beingstashed,
513  GA_Offset offset = GA_INVALID_OFFSET) override;
514 
515  /// Sets the number of components for the volume. comps is internally
516  /// clamped to be between 1 and 4. Calling this function resets the
517  /// primitive.
518  void setTupleSize(int comps);
519  /// Returns the number of components (or the tuple size) for this volume.
520  int getTupleSize() const { return myChannelCount; };
521 
522  /// Changes this volume to one storing integers. Calling this function
523  /// resets the primitive.
524  void setStoresIntegers(bool ints);
525  /// Returns true if this volume stores integers.
526  bool getStoresIntegers() const { return myStoreIntegers; }
527 
528  /// Return the current storage type of the volume.
529  StorageType getStorageType() const;
530  /// Changes this volume to the specified storage type. Resets
531  /// the primitive.
532  void setStorageType(StorageType store);
533 
534  /// True if this is a traditional scalar volume.
535  bool isScalarVolume() const
536  { return getTupleSize() == 1 && getStoresIntegers() == false; }
537 
538  const UT_Matrix3 &getTransform() const { return myXform; }
539  void setTransform(const UT_Matrix3 &m)
540  { myXform = m;
541  myInverseXform = m;
542  myInverseXform.invert();
543  }
544 
545  void getTransform4( UT_Matrix4 &matx) const;
546  void getTransform4( UT_DMatrix4 &matx) const;
547  void setTransform4(const UT_Matrix4 &matx);
548  void setTransform4(const UT_DMatrix4 &matx);
549 
550  void getLocalTransform(UT_Matrix3D &x) const override;
551  void setLocalTransform(const UT_Matrix3D &x) override;
552 
553  /// Converts from world space to local space.
554  const UT_Matrix3 &getInverseTransform() const { return myInverseXform; }
555  void getInverseTransform4(UT_Matrix4 &matx) const;
556 
557  float getTaperX() const { return myTaperX; }
558  void setTaperX(float t) { myTaperX = t; }
559  float getTaperY() const { return myTaperY; }
560  void setTaperY(float t) { myTaperY = t; }
561 
562  /// True if the two volumes have same resolution and map the
563  /// same indices to the same positions.
564  bool isAligned(const GEO_PrimVolume *vol) const;
565 
566  /// True if we are aligned with the world axes. Ie, all our
567  /// off diagonals are zero and our diagonal is positive.
568  bool isWorldAxisAligned() const;
569 
570  /// Returns the POD class which can convert to and from
571  /// 0..1 voxel space coordinates.
572  GEO_PrimVolumeXform getSpaceTransform() const;
573  void setSpaceTransform(GEO_PrimVolumeXform xform);
574 
575  /// Returns the POD class which can convert to and from
576  /// voxel index space coordinates.
577  /// Note: The transformation is not the same as `posToIndex`
578  /// getIndexSpaceTransform().toVoxelSpace(pos) == posToIndex(pos) + {0.5, 0.5, 0.5}
579  GEO_PrimVolumeXform getIndexSpaceTransform() const;
580  template <typename T>
581  GEO_PrimVolumeXform getIndexSpaceTransform(const UT_VoxelArray<T> &vox) const;
582 
583  /// Converts from world space to 0..1 voxel space.
584  UT_Vector3 toVoxelSpace(const UT_Vector3 &pos) const;
585  /// Converts from 0..1 voxel space to world space.
586  UT_Vector3 fromVoxelSpace(const UT_Vector3 &pos) const;
587 
588  /// Converts from world space to 0..1 voxel space.
589  void toVoxelSpace(UT_BoundingBox &box) const;
590  /// Converts from 0..1 voxel space to world space.
591  void fromVoxelSpace(UT_BoundingBox &box) const;
592 
593  /// Copies the given voxel array and makes it our own voxel array.
594  void setVoxels(const UT_VoxelArrayF *vox);
595  void setVoxels(const UT_VoxelArrayV2 *vox);
596  void setVoxels(const UT_VoxelArrayV3 *vox);
597  void setVoxels(const UT_VoxelArrayV4 *vox);
598  void setVoxels(const UT_VoxelArrayI *vox);
599  void setVoxels(UT_VoxelArrayHandleF handle);
600  void setVoxels(UT_VoxelArrayHandleV2 handle);
601  void setVoxels(UT_VoxelArrayHandleV3 handle);
602  void setVoxels(UT_VoxelArrayHandleV4 handle);
603  void setVoxels(UT_VoxelArrayHandleI handle);
604 
605  /// Takes ownership of the voxel array, caller should not refer
606  /// to vox any more.
607  void stealVoxels(UT_VoxelArrayF *vox);
608  void stealVoxels(UT_VoxelArrayV2 *vox);
609  void stealVoxels(UT_VoxelArrayV3 *vox);
610  void stealVoxels(UT_VoxelArrayV4 *vox);
611  void stealVoxels(UT_VoxelArrayI *vox);
612 
613  /// Returns a handle to a voxel array containing our data.
614  /// This is should be thought of a copy of the data - changing
615  /// it will not change the underlying data, casting this to
616  /// a write handle will write to the newly created handle, not
617  /// the one stored in this volume.
618  UT_VoxelArrayHandleF getVoxelHandle() const;
620  {
621  return getVoxelHandle();
622  }
623  UT_VoxelArrayHandleV2 getVoxelHandleV2() const;
624  UT_VoxelArrayHandleV3 getVoxelHandleV3() const;
625  UT_VoxelArrayHandleV4 getVoxelHandleV4() const;
626  UT_VoxelArrayHandleI getVoxelHandleI() const;
627 
628  template <typename BASE>
630  {
631  if constexpr (SYS_IsSame_v<UT_Vector4, BASE>)
632  return getVoxelHandleV4();
633  if constexpr (SYS_IsSame_v<UT_Vector3, BASE>)
634  return getVoxelHandleV3();
635  if constexpr (SYS_IsSame_v<UT_Vector2, BASE>)
636  return getVoxelHandleV2();
637  if constexpr (SYS_IsSame_v<float, BASE>)
638  return getVoxelHandleF();
639  if constexpr (SYS_IsSame_v<int64, BASE>)
640  return getVoxelHandleI();
641  }
642 
643  template <typename BASE>
645  {
646  if constexpr (SYS_IsSame_v<UT_Vector4, BASE>)
647  return getVoxelWriteHandleV4();
648  if constexpr (SYS_IsSame_v<UT_Vector3, BASE>)
649  return getVoxelWriteHandleV3();
650  if constexpr (SYS_IsSame_v<UT_Vector2, BASE>)
651  return getVoxelWriteHandleV2();
652  if constexpr (SYS_IsSame_v<float, BASE>)
653  return getVoxelWriteHandleF();
654  if constexpr (SYS_IsSame_v<int64, BASE>)
655  return getVoxelWriteHandleI();
656 
657  }
658 
659  /// Returns a voxel handle without trying to load the shared data
660  /// This should only be used for the loader
661  /// DO NOT USE! IF YOU THINK YOU SHOULD YOU'RE PROBABLY WRONG
662  template <typename BASE = float>
664  {
665  if constexpr (SYS_IsSame_v<UT_Vector4, BASE>)
666  return myVoxelHandleP;
667  if constexpr (SYS_IsSame_v<UT_Vector3, BASE>)
668  return myVoxelHandleV;
669  if constexpr (SYS_IsSame_v<UT_Vector2, BASE>)
670  return myVoxelHandleU;
671  if constexpr (SYS_IsSame_v<float, BASE>)
672  return myVoxelHandleF;
673  if constexpr (SYS_IsSame_v<int64, BASE>)
674  return myVoxelHandleI;
675  }
676 
677  /// This is a handle that you can write to and affect the volume.
678  UT_VoxelArrayWriteHandleF getVoxelWriteHandle();
680  {
681  return getVoxelWriteHandle();
682  }
683  UT_VoxelArrayWriteHandleV2 getVoxelWriteHandleV2();
684  UT_VoxelArrayWriteHandleV3 getVoxelWriteHandleV3();
685  UT_VoxelArrayWriteHandleV4 getVoxelWriteHandleV4();
686  UT_VoxelArrayWriteHandleI getVoxelWriteHandleI();
687 
688  /// This function calls operator() on op with a COW read handle to this
689  /// volume's actual voxel array handle. operator() must be templated to
690  /// support different handles:
691  /// template <typename T>
692  /// void operator()(const UT_COWReadHandle<UT_VoxelArray<T>>&);
693  template <typename OP>
694  void dispatchToReadHandle(OP& op) const;
695 
696  /// This function calls operator() on op with a COW write handle to this
697  /// volume's actual voxel array handle. operator() must be templated to
698  /// support different handles:
699  /// template <typename T>
700  /// void operator()(const UT_COWWriteHandle<UT_VoxelArray<T>>&);
701  /// If force_load is true, voxel data is first fully loaded; otherwise,
702  /// the handle is used as is.
703  template <typename OP>
704  void dispatchToWriteHandle(OP& op, bool force_load);
705 
706  template <typename OP>
707  void dispatch(const OP &op) const
708  { dispatch(getStorageType(), op); }
709 
710  template <typename OP>
711  static void dispatch(StorageType storage, const OP &op)
712  {
713  switch (storage)
714  {
715  case VOLUME_TYPE_FLOAT: op((float) 0); break;
716  case VOLUME_TYPE_VECTOR2: op(UT_Vector2(0,0)); break;
717  case VOLUME_TYPE_VECTOR3: op(UT_Vector3(0,0,0)); break;
718  case VOLUME_TYPE_VECTOR4: op(UT_Vector4(0,0,0,0)); break;
719  case VOLUME_TYPE_INTEGER: op((int64) 0); break;
720  }
721  }
722 
723  /// Convert an index in the voxel array into the corresponding worldspace
724  /// location
725  bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
726  void findexToPos(UT_Vector3 index, UT_Vector3 &pos) const;
727  bool indexToPos(exint x, exint y, exint z, UT_Vector3D &pos) const;
728  void findexToPos(UT_Vector3D index, UT_Vector3D &pos) const;
729 
730  /// Returns true if the given point is entirely inside the volume's
731  /// definition, ie, if posToIndex would return true.
732  bool isInside(UT_Vector3 pos) const;
733 
734  /// Returns true only if strictly inside. This means only actual
735  /// voxel samples will be used for interpolation, so the boundary
736  /// conditions will be unused
737  bool isInsideStrict(UT_Vector3 pos) const;
738  /// By passing in a specific read handle, we can accelerate
739  /// isInsideStrict()
740  template <typename T>
741  bool isInsideStrict(const UT_Vector3 &opos,
742  const UT_COWReadHandle<UT_VoxelArray<T>> &vox) const;
743 
744  /// Returns true only if index is inside.
745  bool isIndexInside(int x, int y, int z) const;
746  /// By passing in a specific read handle, we can accelerate
747  template <typename T>
748  bool isIndexInside(int x, int y, int z,
749  const UT_COWReadHandle<UT_VoxelArray<T>> &vox) const;
750 
751  /// Convert a 3d position into the closest index value. Returns
752  /// false if the resulting index was out of range (but still sets it)
753  bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
754  bool posToIndex(UT_Vector3 pos, UT_Vector3 &index) const;
755  bool posToIndex(UT_Vector3D pos, exint &x, exint &y, exint &z) const;
756  bool posToIndex(UT_Vector3D pos, UT_Vector3D &index) const;
757 
758  /// Evaluate the voxel value at the given world space position.
759  fpreal getValue(const UT_Vector3 &pos) const;
760  void getValues(float *f, int stride, const UT_Vector3 *p, int num) const;
761  void getValues(double *f, int stride, const UT_Vector3D *p, int num) const;
762  void getValues(UT_Vector2F *f, int stride, const UT_Vector3 *p, int num) const;
763  void getValues(UT_Vector2D *f, int stride, const UT_Vector3D *p, int num) const;
764  void getValues(UT_Vector3F *f, int stride, const UT_Vector3 *p, int num) const;
765  void getValues(UT_Vector3D *f, int stride, const UT_Vector3D *p, int num) const;
766  void getValues(UT_Vector4F *f, int stride, const UT_Vector3 *p, int num) const;
767  void getValues(UT_Vector4D *f, int stride, const UT_Vector3D *p, int num) const;
768  void getValues(int32 *f, int stride, const UT_Vector3 *p, int num) const;
769  void getValues(int64 *f, int stride, const UT_Vector3D *p, int num) const;
770  // Only works with scalar grids.
771  UT_Vector3 getGradient(const UT_Vector3 &pos) const;
772  UT_Vector3 getGradient(const UT_Vector3 &pos, const UT_VoxelArrayReadHandleF &handle) const;
773 
774  /// By passing in a specific read handle and inverse transform
775  /// we can accelerate the getValue()
776  fpreal getValue(const UT_Vector3 &pos, const UT_VoxelArrayReadHandleF &handle) const;
777 
778  template <typename TYPE>
779  TYPE getValueByType(const UT_Vector3 &pos) const
780  {
781  return getValueByType<TYPE>(pos, getVoxelHandleByType<TYPE>());
782  }
783  template <typename TYPE>
784  TYPE getValueByType(const UT_Vector3 &pos, const UT_VoxelArrayReadHandle<TYPE> &vox) const
785  {
786  if constexpr (SYSisSame<TYPE, float>())
787  {
788  return getValue(pos, vox);
789  }
790  else
791  {
792  UT_Vector3 localpos;
793  localpos = toVoxelSpace(pos);
794 
795  // Now we can evaluate normally.
796  return (*vox)(localpos);
797  }
798  }
799 
800  /// Evaluate the specific voxel indexed from 0,0,0.
801  fpreal getValueAtIndex(int ix, int iy, int iz) const;
802  void getValuesAtIndices(float *f, int stride, const int *ix, const int *iy, const int *iz, int num) const;
803  void getValuesAtIndices(int *f, int stride, const int *ix, const int *iy, const int *iz, int num) const;
804  void getValuesAtIndices(double *f, int stride, const exint *ix, const exint *iy, const exint *iz, int num) const;
805  void getValuesAtIndices(exint *f, int stride, const exint *ix, const exint *iy, const exint *iz, int num) const;
806  /// Returns the resolution of the voxel array.
807  void getRes(int &rx, int &ry, int &rz) const;
808  void getRes(int64 &rx, int64 &ry, int64 &rz) const;
809  /// Computes the voxel diameter by taking a step in x, y, and z
810  /// converting to world space and taking the length of that vector.
811  fpreal getVoxelDiameter() const;
812 
813  /// Returns the length of the voxel when you take an x, y, and z step
814  UT_Vector3 getVoxelSize() const;
815 
816  /// Computes the total density of the volume, scaled by
817  /// the volume's size. Negative values will be ignored.
818  fpreal calcPositiveDensity() const;
819 
820  /// Compute useful aggregate properties of the volume.
821  fpreal calcMinimum() const;
822  fpreal calcMaximum() const;
823  fpreal calcAverage() const;
824 
825  /// Determines if we should be treated as an SDF. This means
826  /// our function will continue to increase outside of the bounding
827  /// box according to the distance to the bounding box.
828  bool isSDF() const { return myIsSDF; }
829 
830  /// Determine our orientation if we are to be considered a heightfield.
831  /// Returns false if we shouldn't be treated as a heightfield.
832  bool computeHeightFieldProperties(int &a1, int &a2, int &axis, fpreal &scale) const;
833  bool computeHeightFieldProperties(int &a1, int &a2, int &axis, fpreal &scale, const UT_VoxelArrayF &vox, const GEO_PrimVolumeXform &indexxform) const;
834 
835  /// Get the border options in terms of GEO's values.
836  static const char *getBorderToken(GEO_VolumeBorder border);
837  static GEO_VolumeBorder getBorderEnum(const char *token,
839  void setBorder(GEO_VolumeBorder border, fpreal val, int component = 0);
840  GEO_VolumeBorder getBorder() const;
841  fpreal getBorderValue(int component = 0) const;
842 
843 
844  /// Control the compression of these objects.
845  fpreal getCompressionTolerance() const;
846  void setCompressionTolerance(fpreal tol);
847  void recompress();
848 
849  /// Control how we display this in the viewport
850  static const char *getVisualizationToken(GEO_VolumeVis vis);
851  static GEO_VolumeVis getVisualizationEnum(const char *vis,
853  const GEO_VolumeOptions &getVisOptions() const { return myVis; }
855  { setVisualization(vis.myMode, vis.myIso, vis.myDensity); }
856  void setVisualization(GEO_VolumeVis vis, fpreal iso, fpreal density);
857  fpreal getVisIso() const { return myVis.myIso; }
858  fpreal getVisDensity() const { return myVis.myDensity; }
859  fpreal getVisTiles() const { return myVis.myTiles; }
860  void setVisTiles(fpreal tiles) { myVis.myTiles = tiles; }
861  GEO_VolumeVis getVisualization() const { return myVis.myMode; }
862  GEO_VolumeTypeInfo getTypeInfo() const { return myVis.myTypeInfo; }
863  void setTypeInfo(GEO_VolumeTypeInfo info) { myVis.myTypeInfo = info; }
864 
865  const GA_PrimitiveJSON *getJSON() const override;
866 
867  /// Voxel traverser. This serializes the voxels into a linear array of
868  /// scalar data.
869  template <typename T>
871  {
872  public:
873  serializeT() = default;
874 
875 
876  /// Random access of a voxel value
878  {
879  constexpr bool SCALAR = std::is_arithmetic<T>::value;
880  if (index >= 0 && index < myEntries)
881  {
882  exint tuple = index % myTupleSize;
883  index -= tuple;
884  index /= myTupleSize;
885  exint x, y, z;
886  x = index % myXres;
887  index = (index - x) / myXres;
888  y = index % myYres;
889  index = (index - y) / myYres;
890  z = index % myZres;
891  T val = (*myVoxels)(x, y, z);
892  if constexpr(SCALAR)
893  {
894  return val;
895  }
896  else
897  {
898  return val[tuple];
899  }
900  }
901  return myBorder;
902  }
903 
904  /// @{
905  /// Iterator interface
906  bool atEnd() const { return myCurr >= myEntries; }
907  void rewind() { myCurr = 0; }
908  void advance() { myCurr++; }
909  serializeT &operator++() { advance(); return *this; }
910  /// No post increment as it is harmful.
911  /// @}
912  /// Iterator access methods
913  exint entries() const { return myEntries; }
914  exint index() const { return myCurr; }
915  fpreal voxel() const { return getVoxel(myCurr); }
916  private:
917  serializeT(const GEO_PrimVolume &prim)
918  : myVoxels(prim.getVoxelHandleByType<T>())
919  , myCurr(0)
920  {
921  prim.getRes(myXres, myYres, myZres);
922  myBorder = prim.getBorderValue();
923  myTupleSize = prim.getTupleSize();
924  myEntries = myXres*myYres*myZres * myTupleSize;
925  }
927  fpreal myBorder = 0;
928  int myTupleSize = 1;
929  exint myCurr = 0, myEntries = 0;
930  int myXres = 0, myYres = 0, myZres = 0;
931  friend class GEO_PrimVolume;
932  };
933 
935 
936  serialize getSerialize() const { return serialize(*this); }
937  template <typename T>
939  { return serializeT<T>(*this); }
940 
941 
942  /// Acquire a CE grid and cache it on the GPU. If marked for
943  /// writing, the CPU version will be overwritten.
944  /// Note that the getVoxelHandle does *NOT* auto-flush these!
945  /// NOTE: If someone else fetches a non-read grid, and you fetch it
946  /// as a read grid, you will not get any copied data.
947  CE_Grid *getCEGrid(bool read, bool write) const;
948 
949  /// Acquire an IMX layer for this volume. If marked for reading, it will
950  /// have identical data to this volume. If marked for writing, this volume's
951  /// data will be overwritten.
952  UT_SharedPtr<IMX_Layer> getIMXLayer(bool read, bool write) const;
953 
954  /// Any modified CE cache on the GPU will be copied back to the
955  /// CPU. Will leave result on GPU.
956  void flushCEWriteCaches() override;
957 
958  /// Remove all CE caches from the GPU, possibly writing back
959  /// if necessary.
960  void flushCECaches() override;
961 
962  /// Steal the underlying CE buffer from the source.
963  void stealCEBuffers(const GA_Primitive *src) override;
964 
965  /// Set a proxy compute image that we may reference for our data, but not
966  /// modify. Upon first request, the data is then copied to a main voxel
967  /// array.
969  /// Returns true if this volume primitive has a compute image that is
970  /// externally owned.
971  /// NOTE: this method should only be used to query presence of a borrowed
972  /// compute image; getCEImage() will automatically make a copy if needed.
973  bool hasBorrowedIMXLayer() const
974  { return !myIMXLayerIsOwned; }
975 
976  /// Set a "proxy" compute grid that we may reference for our data, but
977  /// not modify. Upon first request, the data is then copied to a main
978  /// voxel array.
979  void setBorrowedCEGrid(CE_Grid* grid);
980  /// Returns true if this volume primitive has a compute grid that is
981  /// externally owned.
982  /// NOTE: this method should only be used to query presence of a borrowed
983  /// compute grid; getCEGrid() will automatically make a copy if needed.
984  bool hasBorrowedCEGrid() const { return !myCEGridIsOwned; }
985  /// Returns true if the volume is fully loaded. If it has a pending
986  /// CE grid (hasBorrowedCEGrid) or shared data to load, returns false.
987  bool isFullyLoaded() const
988  {
989  if (mySharedVoxelData) return false;
990  if (!myCEGridIsOwned && myCEGridAuthorative) return false;
991  if (!myIMXLayerIsOwned && myIMXLayerAuthorative) return false;
992  return true;
993  }
994 
995 protected:
997  { return GA_FAMILY_NONE; }
998 
999 #if !GA_PRIMITIVE_VERTEXLIST
1000  virtual void clearForDeletion();
1001 #endif
1002 
1003 #if !GA_PRIMITIVE_VERTEXLIST
1004  /// Defragmentation
1005  virtual void swapVertexOffsets(const GA_Defragment &defrag);
1006 #endif
1007 
1008  GA_DECLARE_INTRINSICS(override)
1009 
1010  virtual bool savePrivateH9(std::ostream &os, bool binary) const;
1011  virtual bool loadPrivateH9(UT_IStream &is);
1012 
1013  // A versioned loading method.
1014  bool loadVoxelDataH9(UT_IStream &is,
1016  int version);
1017 
1018  // Resets all voxel array handles belonging to this primitive and
1019  // allocates the needed ones. Also relinquishes any non-owned CE
1020  // data.
1021  void resetAndAllocateHandles();
1022 
1024  { return getPointOffset(); }
1025 
1026  /// Gets the handle to our voxels
1032 
1033 
1034  // All accesses of myVoxelHandle should go though getMyVoxelHandle
1035  // so that the voxels are loaded from shared data before access
1046 
1047  mutable CE_Grid *myCEGrid;
1048  mutable bool myCEGridAuthorative;
1049  mutable bool myCEGridIsOwned;
1050 
1053  mutable bool myIMXLayerIsOwned;
1054 
1055  bool evaluatePointRefMap(
1056  GA_Offset result_vtx,
1057  GA_AttributeRefMap &hlist,
1058  fpreal u, fpreal v,
1059  uint du, uint dv) const override;
1061  UT_Vector4 &pos,
1062  float u, float v = 0,
1063  unsigned du=0, unsigned dv=0) const override
1064  {
1065  return GEO_Primitive::evaluatePointV4(pos, u, v,
1066  du, dv);
1067  }
1069  GA_Offset result_vertex,
1070  GA_AttributeRefMap &hlist) const override;
1071 
1073  GA_Offset result_vtx,
1074  GA_AttributeRefMap &map,
1075  fpreal u, fpreal v, fpreal w=0) const override;
1077  UT_Vector4 &pos,
1078  fpreal u, fpreal v, fpreal w=0) const override;
1079 
1080 private:
1081 #if !GA_PRIMITIVE_VERTEXLIST
1082  GA_Offset myVertex; // My vertex
1083 #endif
1084  UT_Matrix3 myXform; // My Transform
1085  UT_Matrix3 myInverseXform; // My inverse transform
1086  bool myIsSDF : 1; // Are we a signed distance field?
1087 
1088  GEO_VolumeOptions myVis;
1089 
1090  // The taper is the radius of the bottom half, z-minus, of the default box
1091  // The top half's radius is one. These radii are then modified by
1092  // myXform.
1093  fpreal myTaperX, myTaperY;
1094 
1095  friend std::ostream &operator<<(std::ostream &os, const GEO_PrimVolume &d)
1096  {
1097  d.saveH9(os, 0,
1100  return os;
1101  }
1103 };
1105 
1106 /// Returns string token from the StorageType enum value.
1109 /// Returns the GEO_PrimVolume::StorageType enum value from string token. def is
1110 /// returned if token is unknown.
1113  const char *token,
1115 
1116 inline size_t format(char *buf, size_t bufsize, const GEO_PrimVolume::StorageType &v)
1117 {
1118  UT::Format::Writer writer(buf, bufsize);
1120  return f.format(writer, "{}", {GEOgetVolumeStorageTypeToken(v)});
1121 }
1122 
1123 #endif
void fromVoxelSpace(UT_BoundingBox &box) const
virtual void flushCEWriteCaches()
Copy any modified caches from the GPU back to CPU cache.
Definition: GA_Primitive.h:812
void setTaperX(float t)
virtual void flushCECaches()
Definition: GA_Primitive.h:816
serialize getSerialize() const
Definition of a geometry attribute.
Definition: GA_Attribute.h:198
GEO_VolumeVis getVisualization() const
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
virtual GEO_Primitive * copy(int preserve_shared_pts=0) const
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GA_Primitive.h:254
GLenum GLuint GLsizei bufsize
Definition: glcorearb.h:1818
UT_Matrix3 fromVoxelSpaceJacobian(UT_Vector3 pos) const
virtual UT_Vector3 baryCenter() const
UT_SharedPtr< IMX_Layer > getIMXLayer(bool read, bool write) const
UT_COWHandle< UT_VoxelArray< BASE > > getHandleToVoxelsWithoutLoading() const
virtual void copyPrimitive(const GEO_Primitive *src)=0
int int32
Definition: SYS_Types.h:39
virtual void clearForDeletion()
Definition: GA_Primitive.h:687
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
bool loadVoxelDataH9(UT_IStream &is, UT_VoxelArrayWriteHandleF voxels, int version)
bool isFullyLoaded() const
UT_Vector2T< float > UT_Vector2
UT_VoxelArrayHandleV4 myVoxelHandleP
TYPE getValueByType(const UT_Vector3 &pos, const UT_VoxelArrayReadHandle< TYPE > &vox) const
virtual UT_Vector3D computeNormalD() const =0
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
const GLdouble * v
Definition: glcorearb.h:837
UT_VoxelArrayHandleV2 & getMyVoxelHandleV2() const
#define SYS_DEPRECATED_PUSH_DISABLE()
float getTaperY() const
#define SYS_DEPRECATED_POP_DISABLE()
virtual void copySubclassData(const GA_Primitive *source)
Definition: GA_Primitive.h:508
GLsizei const GLfloat * value
Definition: glcorearb.h:824
void setVisOptions(const GEO_VolumeOptions &vis)
bool enlargeBoundingBox(UT_BoundingRect &b, const GA_Attribute *p) const override
static void dispatch(StorageType storage, const OP &op)
int evaluatePointV4(UT_Vector4 &pos, float u, float v=0, unsigned du=0, unsigned dv=0) const override
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
fpreal calcVolume(const UT_Vector3 &) const override
UT_Vector3T< float > UT_Vector3
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
SYS_FORCE_INLINE UT_Vector3 getPos3() const
void transform(const UT_Matrix4 &xform)
virtual bool saveSharedLoadData(UT_JSONWriter &w, GA_SaveMap &save, GA_GeometryIndex *geo_index) const
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
int64 exint
Definition: SYS_Types.h:125
fpreal getVisDensity() const
void resetAndAllocateHandles()
const GEO_VolumeOptions & getVisOptions() const
static GA_PrimitiveFamilyMask buildFamilyMask()
void reverse() override
Reverse the order of vertices.
GA_Offset vertexPoint() const
GA_SharedDataHandlePtr mySharedVoxelData
virtual GA_DereferenceStatus dereferencePoint(GA_Offset point, bool dry_run=false)=0
SYS_FORCE_INLINE GA_Offset getVertexOffset() const
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:87
#define GA_DECLARE_INTRINSICS(OVERRIDE)
Definition: GA_Primitive.h:80
GEO_VolumeVis myMode
GLint y
Definition: glcorearb.h:103
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
Abstract base class for a range membership query object.
GEO_API const char * GEOgetVolumeStorageTypeToken(GEO_PrimVolume::StorageType type)
Returns string token from the StorageType enum value.
virtual bool savePrivateH9(std::ostream &os, bool binary) const
int getTupleSize() const
Returns the number of components (or the tuple size) for this volume.
fpreal calcArea() const override
UT_SharedPtr< GA_SharedDataHandle > GA_SharedDataHandlePtr
UT_VoxelArrayHandleV4 & getMyVoxelHandleV4() const
virtual void swapVertexOffsets(const GA_Defragment &defrag)
UT_Vector3 fromVoxelSpace(UT_Vector3 pos) const
virtual void unitToUnitLengthPair(float uparm, float vparm, float &ulength, float &vlength) const
void wireVertex(GA_Offset vertex, GA_Offset point)
virtual bool loadH9(UT_IStream &is, const UT_Array< GA_AttribLoadDataH9 > &prim_attribs, const UT_Array< GA_AttribLoadDataH9 > &vtx_attribs)
GA_PrimitiveFamilyMask
virtual UT_Vector3 computeNormal() const =0
Return a normal vector for the primitive.
UT_VoxelArrayHandleV3 myVoxelHandleV
#define GA_INVALID_OFFSET
Definition: GA_Types.h:687
__hostdev__ float getValue(uint32_t i) const
Definition: NanoVDB.h:5578
UT_VoxelArrayWriteHandleF getVoxelWriteHandleF()
friend std::ostream & operator<<(std::ostream &os, const GEO_PrimVolume &d)
virtual bool isDegenerate() const =0
Is the primitive degenerate.
fpreal getVisTiles() const
GA_Size GA_Offset
Definition: GA_Types.h:646
virtual bool enlargeBoundingSphere(UT_BoundingSphere &b, const GA_Attribute *P) const
const UT_Matrix3 & getTransform() const
GA_API const UT_StringHolder scale
UT_Vector3 toVoxelSpace(UT_Vector3 pos) const
UT_VoxelArrayHandleV3 & getMyVoxelHandleV3() const
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Size i) const
Definition: GA_Primitive.h:274
GLfloat f
Definition: glcorearb.h:1926
virtual void setLocalTransform(const UT_Matrix3D &matrix)
Set the local transform. The default implementation does nothing.
UT_Matrix3 toVoxelSpaceJacobian(UT_Vector3 pos) const
UT_VoxelArrayHandleF & getMyVoxelHandleF() const
Gets the handle to our voxels.
UT_Vector4T< float > UT_Vector4
TYPE getValueByType(const UT_Vector3 &pos) const
serializeT< float > serialize
GLintptr offset
Definition: glcorearb.h:665
GEO_VolumeBorder
virtual int evaluateInteriorPointV4(UT_Vector4 &pos, fpreal u, fpreal v, fpreal w=0) const
void transform(const UT_Matrix4D &xform)
bool hasBorrowedIMXLayer() const
GEO_VolumeTypeInfo getTypeInfo() const
void setTransform(const UT_Matrix3 &m)
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
bool hasBorrowedCEGrid() const
GEO_VolumeTypeInfo
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
const UT_Matrix3 & getInverseTransform() const
Converts from world space to local space.
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
virtual const GA_PrimitiveJSON * getJSON() const =0
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
Provide a JSON interface to a primitive.
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
UT_COWWriteHandle< UT_VoxelArray< BASE > > getVoxelWriteHandleByType()
fpreal getVisIso() const
void setBorrowedCEGrid(CE_Grid *grid)
#define GEO_API
Definition: GEO_API.h:14
GEO_VolumeVis
long long int64
Definition: SYS_Types.h:116
A handle to simplify manipulation of multiple attributes.
Options during loading.
Definition: GA_LoadMap.h:42
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
bool getStoresIntegers() const
Returns true if this volume stores integers.
float getTaperX() const
void toVoxelSpace(UT_BoundingBox &box) const
UT_Lock mySharedDataLock
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
void enlargeBounds(const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
GLint GLenum GLint x
Definition: glcorearb.h:409
serializeT< T > getSerializeByType() const
bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const override
fpreal getBorderValue(int component=0) const
SYS_FORCE_INLINE void setPos3(const UT_Vector3 &pos)
bool mySharedDataHandleLoaded
virtual GA_DereferenceStatus dereferencePoints(const GA_RangeMemberQuery &pt_q, bool dry_run=false)=0
static SamplingType samplingType(int i)
Convert the "uniformsamples" parm menu item index to a sampling type.
bool isSDF() const
virtual bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const
SYS_FORCE_INLINE void setPos3(GA_Size i, const UT_Vector3 &pos) const
Definition: GA_Primitive.h:286
GLdouble t
Definition: glad.h:2397
UT_COWHandle< UT_VoxelArray< BASE > > getVoxelHandleByType() const
UT_VoxelArrayHandleF getVoxelHandleF() const
virtual void unitLengthToUnitPair(float ulength, float vlength, float &uparm, float &vparm) const
GT_API const UT_StringHolder version
virtual bool evaluateBaryCenterRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map) const
virtual bool evaluateInteriorPointRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v, fpreal w=0) const
CE_Grid * getCEGrid(bool read, bool write) const
virtual void transform(const UT_Matrix4 &)
virtual void enlargePointBounds(UT_BoundingBox &box) const
GLsizeiptr size
Definition: glcorearb.h:664
virtual void getLocalTransform(UT_Matrix3D &matrix) const
#define SCALAR(T)
Simplify checking for scalar types.
Definition: GA_Handle.h:498
virtual bool loadPrivateH9(UT_IStream &is)
UT_VoxelArrayHandleF myVoxelHandleF
void setVertexPoint(GA_Offset pt)
virtual int detachPoints(GA_PointGroup &grp)=0
GLint GLint GLsizei GLint border
Definition: glcorearb.h:108
fpreal getVoxel(exint index) const
Random access of a voxel value.
void setTaperY(float t)
static const UT_Array< GA_AttribSaveDataH9 > & theEmptySaveAttribs
Convience objects to pass as arguments to saveH9()/loadH9().
UT_SharedPtr< IMX_Layer > myIMXLayer
fpreal64 fpreal
Definition: SYS_Types.h:277
virtual bool getBBox(UT_BoundingBox *bbox) const =0
GLuint index
Definition: glcorearb.h:786
bool operator==(const GEO_PrimVolumeXform &x) const
GLuint GLfloat * val
Definition: glcorearb.h:1608
SYS_FORCE_INLINE void initBounds()
virtual int evaluateNormalVector(UT_Vector3 &nml, float u, float v=0, float w=0) const
SYS_FORCE_INLINE GA_Offset getVertexOffset(GA_Size primvertexnum) const
Definition: GA_Primitive.h:240
virtual void stealCEBuffers(const GA_Primitive *src)
Steal the underlying CE buffer from the source.
Definition: GA_Primitive.h:819
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
int invert(T tol=0.0F)
virtual bool evaluatePointRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v=0, uint du=0, uint dv=0) const =0
void setVisTiles(fpreal tiles)
virtual void addToBSphere(UT_BoundingSphere *bsphere) const
void setTypeInfo(GEO_VolumeTypeInfo info)
SYS_FORCE_INLINE GA_Offset getPointOffset() const
bool isTapered() const
Returns if the transform is flagged as having a taper.
CE_Grid * myCEGrid
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
void setBorrowedIMXLayer(const UT_SharedPtr< IMX_Layer > &l)
size_t format(W &writer, const char *format, std::initializer_list< ArgValue > args)
UT_VoxelArrayHandleV2 myVoxelHandleU
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
UT_VoxelArrayHandleI myVoxelHandleI
virtual bool registerSharedLoadData(int load_data_type, GA_SharedDataHandlePtr item)
UT_VoxelArrayHandleI & getMyVoxelHandleI() const
type
Definition: core.h:1059
unsigned int uint
Definition: SYS_Types.h:45
void getRes(int &rx, int &ry, int &rz) const
Returns the resolution of the voxel array.
GEO_API GEO_PrimVolume::StorageType GEOgetVolumeStorageTypeEnum(const char *token, GEO_PrimVolume::StorageType def)
void dispatch(const OP &op) const
bool isScalarVolume() const
True if this is a traditional scalar volume.
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)
Definition: format.h:895
UT_Matrix3T< fpreal64 > UT_Matrix3D
GLenum src
Definition: glcorearb.h:1793
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663