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 
27 ///
28 /// Stores the transform associated with a volume, allowing the
29 /// to/from code to be inlined outside of this library.
30 ///
32 {
33 public:
34  // Converts from world space to [0,1] space.
36  {
37  pos -= myCenter;
38  pos *= myInverseXform;
39 
40  // Undo any taper effect.
41  if (myHasTaper)
42  {
43  fpreal zscale = (1 - pos.z()) * 0.5f;
44  fpreal taperx = 1 + (-1 + myTaperX) * zscale;
45  fpreal tapery = 1 + (-1 + myTaperY) * zscale;
46 
47  if (taperx == 0.0f)
48  pos.x() = 0.0;
49  else
50  pos.x() /= taperx;
51  if (tapery == 0.0f)
52  pos.y() = 0.0;
53  else
54  pos.y() /= tapery;
55  }
56 
57  // This gets us a value in the -1 to 1 box. We need to evaluate
58  // in the 0 to 1 box, however.
59  pos.x() += 1;
60  pos.y() += 1;
61  pos.z() += 1;
62  pos *= 0.5;
63 
64  return pos;
65  }
66 
67  // Converts from [0,1] space over the voxels to world space
69  {
70  // convert to -1 to 1 box.
71  pos.x() -= 0.5;
72  pos.y() -= 0.5;
73  pos.z() -= 0.5;
74  pos *= 2;
75 
76  // Apply the taper effect.
77  if (myHasTaper)
78  {
79  fpreal zscale = (1 - pos.z()) * 0.5f;
80  fpreal taperx = 1 + (-1 + myTaperX) * zscale;
81  fpreal tapery = 1 + (-1 + myTaperY) * zscale;
82 
83  pos.x() *= taperx;
84  pos.y() *= tapery;
85  }
86  // Convert to world space.
87  pos *= myXform;
88  pos += myCenter;
89 
90  return pos;
91  }
92 
93  inline void toVoxelSpace(UT_BoundingBox &box) const
94  {
95  int i;
96  UT_Vector3 v[8] = {
97  UT_Vector3(box.xmin(), box.ymin(), box.zmin()),
98  UT_Vector3(box.xmin(), box.ymin(), box.zmax()),
99  UT_Vector3(box.xmin(), box.ymax(), box.zmin()),
100  UT_Vector3(box.xmin(), box.ymax(), box.zmax()),
101  UT_Vector3(box.xmax(), box.ymin(), box.zmin()),
102  UT_Vector3(box.xmax(), box.ymin(), box.zmax()),
103  UT_Vector3(box.xmax(), box.ymax(), box.zmin()),
104  UT_Vector3(box.xmax(), box.ymax(), box.zmax()),
105  };
106 
107  box.initBounds();
108  for (i = 0; i < 8; i++)
109  {
110  box.enlargeBounds(toVoxelSpace(v[i]));
111  }
112  }
113 
114  inline void fromVoxelSpace(UT_BoundingBox &box) const
115  {
116  int i;
117  UT_Vector3 v[8] = {
118  UT_Vector3(box.xmin(), box.ymin(), box.zmin()),
119  UT_Vector3(box.xmin(), box.ymin(), box.zmax()),
120  UT_Vector3(box.xmin(), box.ymax(), box.zmin()),
121  UT_Vector3(box.xmin(), box.ymax(), box.zmax()),
122  UT_Vector3(box.xmax(), box.ymin(), box.zmin()),
123  UT_Vector3(box.xmax(), box.ymin(), box.zmax()),
124  UT_Vector3(box.xmax(), box.ymax(), box.zmin()),
125  UT_Vector3(box.xmax(), box.ymax(), box.zmax()),
126  };
127 
128  box.initBounds();
129  for (i = 0; i < 8; i++)
130  {
131  box.enlargeBounds(fromVoxelSpace(v[i]));
132  }
133  }
134 
135  /// Returns the *un-tapered* matrix4 corresponding to fromVoxelSpace().
136  /// @{
137  void getTransform4(UT_Matrix4F &matx) const;
138  void getTransform4(UT_Matrix4D &matx) const;
139  /// @}
140 
141  /// Compute the size for this transform (relative to myCenter)
142  UT_Vector3R computeSize() const;
143 
144  // NOTE: This ordering is saved in .hip files!
146  {
147  NON_SQUARE = 0,
152  BY_SIZE
153  };
154 
155  /// Convert the "uniformsamples" parm menu item index to a sampling type
157  { return SamplingType(i); }
158 
159  /// Compute the resolution (and size) from a common set of parameters.
160  /// If twod_axis is one of [0,1,2], then that axis clamped to a divisions
161  /// of 1 and a size of 0. The number of divisions is returned with size
162  /// set to div_size multiplied by divisions before the z_div_scale.
163  static UT_Vector3R computeResolution(
164  SamplingType sampling_type,
165  const UT_Vector3R &non_uniform_divs,
166  fpreal uniform_divs,
167  fpreal div_size,
168  fpreal z_div_scale,
169  UT_Vector3R &size_inout,
170  int twod_axis = -1);
171 
172  /// Compute a space transform from center, size, and taper
173  static GEO_PrimVolumeXform frustumSpaceTransform(
174  const UT_Vector3R &size,
175  const UT_Vector3R &center,
176  fpreal taper_x, fpreal taper_y);
177 
178  /// Compute a space transform from camera settings.
179  /// The ortho_zoom parameter is only used when is_ortho = true.
180  static GEO_PrimVolumeXform cameraFrustum(
181  fpreal focal,
182  fpreal aperture,
183  const UT_Vector2R &image_res,
184  fpreal pixel_aspect,
185  bool is_ortho,
186  fpreal ortho_zoom,
187  fpreal clip_near,
188  fpreal clip_far,
189  bool use_cam_window,
190  const UT_BoundingRectR &cam_window,
191  const UT_BoundingRectR &cam_crop,
192  const UT_BoundingRectR &window,
193  const UT_Matrix4R &post_xform,
194  const GEO_Detail *match_src);
195 
196 public:
197  // @{
198  void save(std::ostream &os, bool binary = false) const;
199  bool load(UT_IStream &is);
200  // @}
201 
202  void init()
203  {
204  myCenter.assign(0, 0, 0);
205  myXform.identity();
206  myInverseXform.identity();
207  myHasTaper = false;
208  myTaperX = 1.0;
209  myTaperY = 1.0;
210  }
211 
212  bool operator==(const GEO_PrimVolumeXform &x) const
213  {
214  return
215  myXform == x.myXform &&
216  myCenter == x.myCenter &&
217  myHasTaper == x.myHasTaper &&
218  myTaperX == x.myTaperX &&
219  myTaperY == x.myTaperY;
220  }
221 
222  UT_Matrix3 myXform, myInverseXform;
225  float myTaperX, myTaperY;
226 };
227 
229 {
230 protected:
231  /// NOTE: The constructor should only be called from subclass
232  /// constructors.
234 
235  /// NOTE: The destructor should only be called from subclass
236  /// destructors.
237  ~GEO_PrimVolume() override;
238 
239 public:
240 //
241 // Methods common to all primitives.
243  UT_Vector3 &nml,
244  float u, float v=0, float w=0) const override;
245  int getBBox(UT_BoundingBox *bbox) const override;
246  void addToBSphere(
247  UT_BoundingSphere *bsphere) const override;
248  void enlargePointBounds(UT_BoundingBox &box) const override;
249  /// @{
250  /// Enlarge a bounding box by the bounding box of the primitive. A
251  /// return value of false indicates an error in the operation, most
252  /// likely an invalid P. For any attribute other than the position
253  /// these methods simply enlarge the bounding box based on the vertex.
254  bool enlargeBoundingBox(
256  const GA_Attribute *P) const override;
257  bool enlargeBoundingBox(
258  UT_BoundingBox &b,
259  const GA_Attribute *P) const override;
260  /// @}
261  /// Enlarge a bounding sphere to encompass the primitive. A return value
262  /// of false indicates an error in the operation, most likely an invalid
263  /// P. For any attribute other than the position this method simply
264  /// enlarges the sphere based on the vertex.
267  const GA_Attribute *P) const override;
268  /// For a volume the barycenter is the same as the point.
269  UT_Vector3 baryCenter() const override;
270  UT_Vector3 computeNormal() const override;
271  bool saveH9(
272  std::ostream &os, bool binary,
273  const UT_Array<GA_AttribSaveDataH9> &prim_attribs,
274  const UT_Array<GA_AttribSaveDataH9> &vtx_attribs
275  ) const override;
276  bool loadH9(
277  UT_IStream &is,
278  const UT_Array<GA_AttribLoadDataH9> &prim_attribs,
279  const UT_Array<GA_AttribLoadDataH9> &vtx_attribs
280  ) override;
281 
282  bool saveVoxelArray(UT_JSONWriter &w,
283  const GA_SaveMap &map) const;
284  bool loadVoxelArray(UT_JSONParser &p,
285  const GA_LoadMap &map);
286 
287  bool loadRes(const UT_JSONValue &jval);
288  bool saveBorder(UT_JSONWriter &w,
289  const GA_SaveMap &map) const;
290  bool loadBorder(UT_JSONParser &p,
291  const GA_LoadMap &map);
292  bool saveCompression(UT_JSONWriter &w,
293  const GA_SaveMap &map) const;
294  bool loadCompression(UT_JSONParser &p,
295  const GA_LoadMap &map);
296  bool saveVisualization(UT_JSONWriter &w,
297  const GA_SaveMap &map) const;
298  bool loadVisualization(UT_JSONParser &p,
299  const GA_LoadMap &map);
300 
301  /// @{
302  /// Methods to save/load shared voxel data
303  static const int theSharedVoxelMagic=('V'<<24)|('o'<<16)|('x'<<8)|('l');
305  int dtype,
306  GA_SharedDataHandlePtr data) override;
307  bool saveSharedLoadData(
308  UT_JSONWriter &w,
309  GA_SaveMap &save,
310  GA_GeometryIndex *geo_index) const override;
311  bool getSharedVoxelKey(UT_WorkBuffer &key) const;
313  allocateSharedDataLoader();
314  /// @}
315 
316  // Transforms the matrix associated with this primitive. The
317  // translate component is ignored: Translate the vertices of
318  // the primitive to translate the primitive.
319  // This only works with quadrics (sphere, tube, metaballs) and volumes.
320  void transform(const UT_Matrix4 &mat) override;
321 
322  void reverse() override {}
323  GEO_Primitive *copy(int preserve_shared_pts = 0) const override;
324  void copyPrimitive(const GEO_Primitive *src) override;
325  void copySubclassData(const GA_Primitive *source) override;
330 
333  {
334  return getVertexOffset(0);
335  }
338  {
339  return getPointOffset(0);
340  }
343  {
344  return getPos3(0);
345  }
347  void setPos3(const UT_Vector3 &pos)
348  {
349  return setPos3(0, pos);
350  }
351 
352  // Take the whole set of points into consideration when applying the
353  // point removal operation to this primitive. The method returns 0 if
354  // successful, -1 if it failed because it would have become degenerate,
355  // and -2 if it failed because it would have had to remove the primitive
356  // altogether.
357  int detachPoints(GA_PointGroup &grp) override;
358 
359  /// Before a point is deleted, all primitives using the point will be
360  /// notified. The method should return "false" if it's impossible to
361  /// delete the point. Otherwise, the vertices should be removed.
362  GA_DereferenceStatus dereferencePoint(GA_Offset point,
363  bool dry_run=false) override;
364  GA_DereferenceStatus dereferencePoints(const GA_RangeMemberQuery &pt_q,
365  bool dry_run=false) override;
366 
367  bool isDegenerate() const override;
368 
369  // Map the normalized length (distance value [0,1]) parameter to the unit
370  // parameterization of the primitve
372  float ulength, float vlength,
373  float &uparm, float &vparm) const override;
375  float ulength, float vlength,
376  float &uparm, float &vparm,
377  float tolerance) const override;
378 
380  float uparm, float vparm,
381  float &ulength, float &vlength) const override;
382 
383  fpreal calcVolume(const UT_Vector3 &refpt) const override;
384  fpreal calcArea() const override;
385 
386 //
387 // Methods unique to PrimVolume.
388 
389 #if GA_PRIMITIVE_VERTEXLIST
391  void setVertexPoint(GA_Offset pt)
392  {
394  }
395 #else
397  {
398  wireVertex(myVertex, pt);
399  }
400 #endif
401 
402  /// This method assigns a preallocated vertex to the quadric, optionally
403  /// creating the topological link between the primitive and new vertex.
404  void assignVertex(GA_Offset new_vtx, bool update_topology);
405 
406  // Have we been deactivated and stashed?
407  void stashed(bool beingstashed,
408  GA_Offset offset = GA_INVALID_OFFSET) override;
409 
410  const UT_Matrix3 &getTransform() const { return myXform; }
411  void setTransform(const UT_Matrix3 &m)
412  { myXform = m;
413  myInverseXform = m;
414  myInverseXform.invert();
415  }
416 
417  void getTransform4( UT_Matrix4 &matx) const;
418  void getTransform4( UT_DMatrix4 &matx) const;
419  void setTransform4(const UT_Matrix4 &matx);
420  void setTransform4(const UT_DMatrix4 &matx);
421 
422  void getLocalTransform(UT_Matrix3D &x) const override;
423  void setLocalTransform(const UT_Matrix3D &x) override;
424 
425  /// Converts from world space to local space.
426  const UT_Matrix3 &getInverseTransform() const { return myInverseXform; }
427  void getInverseTransform4(UT_Matrix4 &matx) const;
428 
429  float getTaperX() const { return myTaperX; }
430  void setTaperX(float t) { myTaperX = t; }
431  float getTaperY() const { return myTaperY; }
432  void setTaperY(float t) { myTaperY = t; }
433 
434  /// True if the two volumes have same resolution and map the
435  /// same indices to the same positions.
436  bool isAligned(const GEO_PrimVolume *vol) const;
437 
438  /// True if we are aligned with the world axes. Ie, all our
439  /// off diagonals are zero and our diagonal is positive.
440  bool isWorldAxisAligned() const;
441 
442  /// Returns the POD class which can convert to and from
443  /// 0..1 voxel space coordinates.
444  GEO_PrimVolumeXform getSpaceTransform() const;
445  void setSpaceTransform(GEO_PrimVolumeXform xform);
446 
447  /// Returns the POD class which can convert to and from
448  /// voxel index space coordinates.
449  GEO_PrimVolumeXform getIndexSpaceTransform() const;
450  GEO_PrimVolumeXform getIndexSpaceTransform(const UT_VoxelArrayF &vox) const;
451 
452  /// Converts from world space to 0..1 voxel space.
453  UT_Vector3 toVoxelSpace(const UT_Vector3 &pos) const;
454  /// Converts from 0..1 voxel space to world space.
455  UT_Vector3 fromVoxelSpace(const UT_Vector3 &pos) const;
456 
457  /// Converts from world space to 0..1 voxel space.
458  void toVoxelSpace(UT_BoundingBox &box) const;
459  /// Converts from 0..1 voxel space to world space.
460  void fromVoxelSpace(UT_BoundingBox &box) const;
461 
462  /// Copies the given voxel array and makes it our own voxel array.
463  void setVoxels(const UT_VoxelArrayF *vox);
464  void setVoxels(UT_VoxelArrayHandleF handle);
465 
466  /// Takes ownership of the voxel array, caller should not refer
467  /// to vox any more.
468  void stealVoxels(UT_VoxelArrayF *vox);
469 
470  /// Returns a handle to a voxel array containing our data.
471  /// This is should be thought of a copy of the data - changing
472  /// it will not change the underlying data, casting this to
473  /// a write handle will write to the newly created handle, not
474  /// the one stored in this volume.
475  UT_VoxelArrayHandleF getVoxelHandle() const;
476 
477  /// Returns a voxel handle without trying to load the shared data
478  /// This should only be used for the loader
479  /// DO NOT USE! IF YOU THINK YOU SHOULD YOUR PROBABLY WRONG
481  {
482  return myVoxelHandle;
483  }
484 
485  /// This is a handle that you can write to and affect the volume.
486  UT_VoxelArrayWriteHandleF getVoxelWriteHandle();
487 
488  /// Convert an index in the voxel array into the corresponding worldspace
489  /// location
490  bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
491  void findexToPos(UT_Vector3 index, UT_Vector3 &pos) const;
492  bool indexToPos(exint x, exint y, exint z, UT_Vector3D &pos) const;
493  void findexToPos(UT_Vector3D index, UT_Vector3D &pos) const;
494 
495  /// Returns true if the given point is entirely inside the volume's
496  /// definition, ie, if posToIndex would return true.
497  bool isInside(UT_Vector3 pos) const;
498 
499  /// Returns true only if strictly inside. This means only actual
500  /// voxel samples will be used for interpolation, so the boundary
501  /// conditions will be unused
502  bool isInsideStrict(UT_Vector3 pos) const;
503  /// By passing in a specific read handle, we can accelerate
504  /// isInsideStrict()
505  bool isInsideStrict(const UT_Vector3 &opos, const UT_VoxelArrayReadHandleF &vox) const;
506 
507  /// Returns true only if index is inside.
508  bool isIndexInside(int x, int y, int z) const;
509  /// By passing in a specific read handle, we can accelerate
510  bool isIndexInside(int x, int y, int z, const UT_VoxelArrayReadHandleF &vox) const;
511 
512  /// Convert a 3d position into the closest index value. Returns
513  /// false if the resulting index was out of range (but still sets it)
514  bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
515  bool posToIndex(UT_Vector3 pos, UT_Vector3 &index) const;
516  bool posToIndex(UT_Vector3D pos, exint &x, exint &y, exint &z) const;
517  bool posToIndex(UT_Vector3D pos, UT_Vector3D &index) const;
518 
519  /// Evaluate the voxel value at the given world space position.
520  fpreal getValue(const UT_Vector3 &pos) const;
521  void getValues(float *f, int stride, const UT_Vector3 *p, int num) const;
522  void getValues(double *f, int stride, const UT_Vector3D *p, int num) const;
523  // Only works with scalar grids.
524  UT_Vector3 getGradient(const UT_Vector3 &pos) const;
525  UT_Vector3 getGradient(const UT_Vector3 &pos, const UT_VoxelArrayReadHandleF &handle) const;
526 
527  /// By passing in a specific read handle and inverse transform
528  /// we can accelerate the getValue()
529  fpreal getValue(const UT_Vector3 &pos, const UT_VoxelArrayReadHandleF &handle) const;
530 
531  /// Evaluate the specific voxel indexed from 0,0,0.
532  fpreal getValueAtIndex(int ix, int iy, int iz) const;
533  void getValuesAtIndices(float *f, int stride, const int *ix, const int *iy, const int *iz, int num) const;
534  void getValuesAtIndices(int *f, int stride, const int *ix, const int *iy, const int *iz, int num) const;
535  void getValuesAtIndices(double *f, int stride, const exint *ix, const exint *iy, const exint *iz, int num) const;
536  void getValuesAtIndices(exint *f, int stride, const exint *ix, const exint *iy, const exint *iz, int num) const;
537  /// Returns the resolution of the voxel array.
538  void getRes(int &rx, int &ry, int &rz) const;
539  /// Computes the voxel diameter by taking a step in x, y, and z
540  /// converting to world space and taking the length of that vector.
541  fpreal getVoxelDiameter() const;
542 
543  /// Returns the length of the voxel when you take an x, y, and z step
544  UT_Vector3 getVoxelSize() const;
545 
546  /// Computes the total density of the volume, scaled by
547  /// the volume's size. Negative values will be ignored.
548  fpreal calcPositiveDensity() const;
549 
550  /// Compute useful aggregate properties of the volume.
551  fpreal calcMinimum() const;
552  fpreal calcMaximum() const;
553  fpreal calcAverage() const;
554 
555  /// Determines if we should be treated as an SDF. This means
556  /// our function will continue to increase outside of the bounding
557  /// box according to the distance to the bounding box.
558  bool isSDF() const { return myIsSDF; }
559 
560  /// Determine our orientation if we are to be considered a heightfield.
561  /// Returns false if we shouldn't be treated as a heightfield.
562  bool computeHeightFieldProperties(int &a1, int &a2, int &axis, fpreal &scale) const;
563  bool computeHeightFieldProperties(int &a1, int &a2, int &axis, fpreal &scale, const UT_VoxelArrayF &vox, const GEO_PrimVolumeXform &indexxform) const;
564 
565  /// Get the border options in terms of GEO's values.
566  static const char *getBorderToken(GEO_VolumeBorder border);
567  static GEO_VolumeBorder getBorderEnum(const char *token,
569  void setBorder(GEO_VolumeBorder border, fpreal val);
570  GEO_VolumeBorder getBorder() const;
571  fpreal getBorderValue() const;
572 
573  /// Control the compression of these objects.
574  fpreal getCompressionTolerance() const;
575  void setCompressionTolerance(fpreal tol);
576  void recompress();
577 
578  /// Control how we display this in the viewport
579  static const char *getVisualizationToken(GEO_VolumeVis vis);
580  static GEO_VolumeVis getVisualizationEnum(const char *vis,
582  const GEO_VolumeOptions &getVisOptions() const { return myVis; }
584  { setVisualization(vis.myMode, vis.myIso, vis.myDensity); }
585  void setVisualization(GEO_VolumeVis vis, fpreal iso, fpreal density);
586  fpreal getVisIso() const { return myVis.myIso; }
587  fpreal getVisDensity() const { return myVis.myDensity; }
588  GEO_VolumeVis getVisualization() const { return myVis.myMode; }
589 
590  const GA_PrimitiveJSON *getJSON() const override;
591 
592  /// Voxel traverser. This serializes the voxels into a linear array of
593  /// scalar data.
594  class serialize
595  {
596  public:
598  : myVoxels()
599  , myBorder(0)
600  , myXres(0)
601  , myYres(0)
602  , myZres(0)
603  , myEntries(0)
604  , myCurr(0)
605  {}
607  : myVoxels(src.myVoxels)
608  , myBorder(src.myBorder)
609  , myXres(src.myXres)
610  , myYres(src.myYres)
611  , myZres(src.myZres)
612  , myEntries(src.myEntries)
613  , myCurr(src.myCurr)
614  {}
616  {
617  myVoxels = src.myVoxels;
618  myBorder = src.myBorder;
619  myXres = src.myXres;
620  myYres = src.myYres;
621  myZres = src.myZres;
622  myEntries = src.myEntries;
623  myCurr = src.myCurr;
624  return *this;
625  }
626  /// Random access of a voxel value
628  {
629  if (index >= 0 && index < myEntries)
630  {
631  exint x, y, z;
632  x = index % myXres;
633  index = (index - x) / myXres;
634  y = index % myYres;
635  index = (index - y) / myYres;
636  z = index % myZres;
637  return (*myVoxels)(x, y, z);
638  }
639  return myBorder;
640  }
641 
642  /// @{
643  /// Iterator interface
644  bool atEnd() const { return myCurr >= myEntries; }
645  void rewind() { myCurr = 0; }
646  void advance() { myCurr++; }
647  serialize &operator++() { advance(); return *this; }
648  /// No post increment as it is harmful.
649  /// @}
650  /// Iterator access methods
651  exint entries() const { return myEntries; }
652  exint index() const { return myCurr; }
653  fpreal voxel() const { return getVoxel(myCurr); }
654  private:
655  serialize(const GEO_PrimVolume &prim)
656  : myVoxels(prim.getVoxelHandle())
657  , myCurr(0)
658  {
659  prim.getRes(myXres, myYres, myZres);
660  myBorder = prim.getBorderValue();
661  myEntries = myXres*myYres*myZres;
662  }
663  UT_VoxelArrayReadHandleF myVoxels;
664  fpreal myBorder;
665  exint myCurr, myEntries;
666  int myXres, myYres, myZres;
667  friend class GEO_PrimVolume;
668  };
669  serialize getSerialize() const { return serialize(*this); }
670 
671 
672  /// Acquire a CE grid and cache it on the GPU. If marked for
673  /// writing, the CPU version will be overwritten.
674  /// Note that the getVoxelHandle does *NOT* auto-flush these!
675  /// NOTE: If someone else fetches a non-read grid, and you fetch it
676  /// as a read grid, you will not get any copied data.
677  CE_Grid *getCEGrid(bool read, bool write) const;
678 
679  /// Any modified CE cache on the GPU will be copied back to the
680  /// CPU. Will leave result on GPU.
681  void flushCEWriteCaches() override;
682 
683  /// Remove all CE caches from the GPU, possibly writing back
684  /// if necessary.
685  void flushCECaches() override;
686 
687  /// Set a "proxy" compute grid that we may reference for our data, but
688  /// not modify. Upon first request, the data is then copied to a main
689  /// voxel array.
690  void setBorrowedCEGrid(CE_Grid* grid);
691  /// Returns true if this volume primitive has a compute grid that is
692  /// externally owned.
693  /// NOTE: this method should only be used to query presence of a borrowed
694  /// compute grid; getCEGrid() will automatically make a copy if needed.
695  bool hasBorrowedCEGrid() const { return !myCEGridIsOwned; }
696 
697 protected:
699  { return GA_FAMILY_NONE; }
700 
701 #if !GA_PRIMITIVE_VERTEXLIST
702  virtual void clearForDeletion();
703 #endif
704 
705 #if !GA_PRIMITIVE_VERTEXLIST
706  /// Defragmentation
707  virtual void swapVertexOffsets(const GA_Defragment &defrag);
708 #endif
709 
710  GA_DECLARE_INTRINSICS(override)
711 
712  virtual bool savePrivateH9(std::ostream &os, bool binary) const;
713  virtual bool loadPrivateH9(UT_IStream &is);
714 
715  // A versioned loading method.
716  bool loadVoxelDataH9(UT_IStream &is,
718  int version);
719 
721  { return getPointOffset(); }
722 
723  /// Gets the handle to our voxels
725 
726  // All accesses of myVoxelHandle should go though getMyVoxelHandle
727  // so that the voxels are loaded from shared data before access
732 
733  mutable CE_Grid *myCEGrid;
734  mutable bool myCEGridAuthorative;
735  mutable bool myCEGridIsOwned;
736 
737  bool evaluatePointRefMap(
738  GA_Offset result_vtx,
739  GA_AttributeRefMap &hlist,
740  fpreal u, fpreal v,
741  uint du, uint dv) const override;
743  UT_Vector4 &pos,
744  float u, float v = 0,
745  unsigned du=0, unsigned dv=0) const override
746  {
747  return GEO_Primitive::evaluatePointV4(pos, u, v,
748  du, dv);
749  }
751  GA_Offset result_vertex,
752  GA_AttributeRefMap &hlist) const override;
753 
755  GA_Offset result_vtx,
756  GA_AttributeRefMap &map,
757  fpreal u, fpreal v, fpreal w=0) const override;
759  UT_Vector4 &pos,
760  fpreal u, fpreal v, fpreal w=0) const override;
761 
762 private:
763 #if !GA_PRIMITIVE_VERTEXLIST
764  GA_Offset myVertex; // My vertex
765 #endif
766  UT_Matrix3 myXform; // My Transform
767  UT_Matrix3 myInverseXform; // My inverse transform
768  bool myIsSDF : 1; // Are we a signed distance field?
769 
770  GEO_VolumeOptions myVis;
771 
772  // The taper is the radius of the bottom half, z-minus, of the default box
773  // The top half's radius is one. These radii are then modified by
774  // myXform.
775  fpreal myTaperX, myTaperY;
776 
777  friend std::ostream &operator<<(std::ostream &os, const GEO_PrimVolume &d)
778  {
779  d.saveH9(os, 0,
782  return os;
783  }
785 };
787 
788 #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:783
void setTaperX(float t)
virtual void flushCECaches()
Definition: GA_Primitive.h:787
serialize getSerialize() const
Definition of a geometry attribute.
Definition: GA_Attribute.h:196
GEO_VolumeVis getVisualization() const
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
virtual UT_Vector3 baryCenter() const
GLsizeiptr size
Definition: glew.h:1681
GLenum src
Definition: glew.h:2410
virtual void copyPrimitive(const GEO_Primitive *src)=0
virtual void clearForDeletion()
Definition: GA_Primitive.h:658
UT_VoxelArrayHandleF myVoxelHandle
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)
GLuint index
Definition: glew.h:1814
#define SYS_DEPRECATED_PUSH_DISABLE()
float getTaperY() const
#define SYS_DEPRECATED_POP_DISABLE()
virtual void copySubclassData(const GA_Primitive *source)
Definition: GA_Primitive.h:484
GLuint const GLfloat * val
Definition: glew.h:2794
void setVisOptions(const GEO_VolumeOptions &vis)
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:13880
int evaluatePointV4(UT_Vector4 &pos, float u, float v=0, unsigned du=0, unsigned dv=0) const override
fpreal calcVolume(const UT_Vector3 &) const override
UT_Vector3T< float > UT_Vector3
SYS_FORCE_INLINE UT_Vector3 getPos3() const
serialize & operator=(const serialize &src)
virtual bool saveSharedLoadData(UT_JSONWriter &w, GA_SaveMap &save, GA_GeometryIndex *geo_index) const
int64 exint
Definition: SYS_Types.h:125
fpreal getVisDensity() const
const GEO_VolumeOptions & getVisOptions() const
static GA_PrimitiveFamilyMask buildFamilyMask()
void reverse() override
Reverse the order of vertices.
GA_Offset vertexPoint() const
GLsizei GLsizei GLchar * source
Definition: glew.h:1832
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:76
#define GA_DECLARE_INTRINSICS(OVERRIDE)
Definition: GA_Primitive.h:80
bool enlargeBoundingBox(UT_BoundingRect &b, const GA_Attribute *P) const override
GEO_VolumeVis myMode
const GLdouble * m
Definition: glew.h:9124
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:34
Abstract base class for a range membership query object.
const GLdouble * v
Definition: glew.h:1391
virtual bool savePrivateH9(std::ostream &os, bool binary) const
fpreal calcArea() const override
UT_SharedPtr< GA_SharedDataHandle > GA_SharedDataHandlePtr
void read(T &in, bool &v)
Definition: ImfXdr.h:611
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.
#define GA_INVALID_OFFSET
Definition: GA_Types.h:676
GLdouble GLdouble z
Definition: glew.h:1559
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:639
virtual bool enlargeBoundingSphere(UT_BoundingSphere &b, const GA_Attribute *P) const
const UT_Matrix3 & getTransform() const
UT_Vector3 toVoxelSpace(UT_Vector3 pos) const
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Size i) const
Definition: GA_Primitive.h:274
virtual void setLocalTransform(const UT_Matrix3D &matrix)
Set the local transform. The default implementation does nothing.
SYS_FORCE_INLINE T & y()
Definition: UT_Vector3.h:513
GEO_VolumeBorder
GLclampf f
Definition: glew.h:3499
virtual int evaluateInteriorPointV4(UT_Vector4 &pos, fpreal u, fpreal v, fpreal w=0) const
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
UT_VoxelArrayHandleF & getMyVoxelHandle() const
Gets the handle to our voxels.
void setTransform(const UT_Matrix3 &m)
bool hasBorrowedCEGrid() const
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
const GLuint GLenum const void * binary
Definition: glew.h:3502
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: glew.h:1254
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
const UT_Matrix3 & getInverseTransform() const
Converts from world space to local space.
SYS_FORCE_INLINE T & z()
Definition: UT_Vector3.h:515
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
virtual const GA_PrimitiveJSON * getJSON() const =0
fpreal getVoxel(exint index) const
Random access of a voxel value.
Provide a JSON interface to a primitive.
fpreal getVisIso() const
void setBorrowedCEGrid(CE_Grid *grid)
#define GEO_API
Definition: GEO_API.h:14
GEO_VolumeVis
fpreal getBorderValue() const
A handle to simplify manipulation of multiple attributes.
Options during loading.
Definition: GA_LoadMap.h:42
virtual int getBBox(UT_BoundingBox *bbox) const =0
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
float getTaperX() const
void toVoxelSpace(UT_BoundingBox &box) const
UT_Lock mySharedDataLock
void enlargeBounds(const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const override
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:280
serialize(const serialize &src)
virtual void unitLengthToUnitPair(float ulength, float vlength, float &uparm, float &vparm) const
GLsizei stride
Definition: glew.h:1523
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 &)
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
virtual void enlargePointBounds(UT_BoundingBox &box) const
GLfloat GLfloat p
Definition: glew.h:16321
virtual void getLocalTransform(UT_Matrix3D &matrix) const
virtual bool loadPrivateH9(UT_IStream &is)
void setVertexPoint(GA_Offset pt)
virtual int detachPoints(GA_PointGroup &grp)=0
void setTaperY(float t)
static const UT_Array< GA_AttribSaveDataH9 > & theEmptySaveAttribs
Convience objects to pass as arguments to saveH9()/loadH9().
GLuint num
Definition: glew.h:2690
fpreal64 fpreal
Definition: SYS_Types.h:277
bool operator==(const GEO_PrimVolumeXform &x) const
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
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:77
virtual bool evaluatePointRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v=0, uint du=0, uint dv=0) const =0
SYS_FORCE_INLINE T & x()
Definition: UT_Vector3.h:511
virtual void addToBSphere(UT_BoundingSphere *bsphere) const
SYS_FORCE_INLINE GA_Offset getPointOffset() const
CE_Grid * myCEGrid
#define const
Definition: zconf.h:214
void write(T &out, bool v)
Definition: ImfXdr.h:332
virtual bool registerSharedLoadData(int load_data_type, GA_SharedDataHandlePtr item)
unsigned int uint
Definition: SYS_Types.h:45
void getRes(int &rx, int &ry, int &rz) const
Returns the resolution of the voxel array.
GLdouble GLdouble t
Definition: glew.h:1398
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)
UT_VoxelArrayHandleF getHandleToVoxelsWithoutLoading() const
GLintptr offset
Definition: glew.h:1682