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