HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_SDF.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: Geometry library (C++)
7  *
8  * COMMENTS: Builds a Signed Distance Function from a GU_Detail.
9  * This also supports implicit SDFs. These lack any
10  * voxel representation.
11  */
12 
13 #ifndef __GU_SDF_H__
14 #define __GU_SDF_H__
15 
16 #include "GU_API.h"
17 #include <UT/UT_Vector3.h>
18 #include <UT/UT_VectorTypes.h>
19 #include <UT/UT_BoundingBox.h>
20 #include <UT/UT_Plane.h>
21 #include <UT/UT_VoxelArray.h>
22 #include <UT/UT_PriorityQueue.h>
23 #include <UT/UT_IntArray.h>
24 #include <UT/UT_Array.h>
25 #include <GA/GA_Handle.h>
26 #include <GA/GA_Types.h>
27 #include <GEO/GEO_PrimVolume.h>
28 #include "GU_DetailHandle.h"
29 
30 class GU_Detail;
31 class GA_ROAttributeRef;
32 class GU_RayIntersect;
33 class GEO_PrimPoly;
34 class GEO_Primitive;
35 class GU_SDF;
36 
37 ///
38 /// gu_sdf_qelem
39 /// This is used as an element in our queue.
40 ///
42 {
43 public:
44  // Where we are in the queue.
45  int qpos;
46  // Where we are in the ref array.
47  int refpos;
48  // What our x/y/z cell position is.
49  int x, y, z;
50  // What our value is.
52 };
53 
54 ///
55 /// gu_sdf_voxpos
56 /// This is used to store a specific element of our voxel.
57 ///
59 {
60 public:
62  gu_sdf_voxpos(int px, int py, int pz)
63  {
64  x = px; y = py; z = pz;
65  }
66  int x, y, z;
67 };
68 
69 ///
70 /// gu_sdf_comp
71 /// Comparator used by our queue.
72 ///
74 {
75 public:
76  bool operator()(const gu_sdf_qelem &e1, const gu_sdf_qelem &e2) const
77  {
78  return SYSabs(e1.dist) > SYSabs(e2.dist);
79  }
80  bool operator()(const gu_sdf_qelem *e1, const gu_sdf_qelem *e2) const
81  {
82  return SYSabs(e1->dist) > SYSabs(e2->dist);
83  }
84 };
85 
86 ///
87 /// gu_sdf_queue
88 /// This is a queue of voxels sorted by minimum distance.
89 /// We want to subclass to be able to track where we are in the
90 /// queue. This lets us update the queue when we change our elements
91 /// distance.
92 ///
94  public UT_PriorityQueue<gu_sdf_qelem *, gu_sdf_comp, true>
95 {
96 public:
97  void changedPosition(gu_sdf_qelem *e, unsigned int idx) const override
98  {
99  e->qpos = idx;
100  }
101 };
102 
103 ///
104 /// GU_SDFParms
105 /// All the parameters to build an SDF can be set using this class
106 ///
108 {
109 public:
110  GU_SDFParms();
111  virtual ~GU_SDFParms();
112 
113  enum sdfMode
114  {
125  HEIGHTFIELD
126  };
127 
128  /// These set the general method by which the SDF is computed.
129  void setMode(sdfMode mode);
130  sdfMode getMode() const;
131 
132  /// This sets the axis used for planar SDFs.
133  void setPlaneAxis(const UT_Vector3 &axis);
134  const UT_Vector3 &getPlaneAxis() const;
135 
136  /// Sets the divisions used by the SDF. The given values represent
137  /// the number of cells that will be present in each direction.
138  /// The SDF samples the center of the cells to determine their
139  /// values.
140  void setDivisions(int divx, int divy, int divz);
141  void getDivisions(int &divx, int &divy, int &divz) const;
142 
143  /// Determines if we should invert the sense of the SDFs field.
144  void setInvert(bool invert);
145  bool getInvert() const;
146 
147  /// Sets the offset applied to the SDF's field.
148  void setOffset(fpreal offset);
149  fpreal getOffset() const;
150 
151  /// Sets the tolerance to be used for ray intersection
152  /// This is multiplied by the bounding box size of the sdf to
153  /// determine the final tolerance.
154  void setTol(fpreal tol);
155  fpreal getTol() const;
156 
157  /// Sets the volume used for building the sdf.
158  /// This must match the resolution of the sdf's parameters.
159  void setVolume(UT_VoxelArrayF *vol);
160  UT_VoxelArrayF *getVolume() const;
161 
162  /// Sets the bounding box which the SDF will be sampled in.
163  /// Note that the bounding box should fully contain the geometry
164  /// or settings like ForceBounds become meaningless.
165  /// If this method is not called, the bounding box will be set
166  /// to the bounding box of the GDP increased by the expandBounds
167  /// function.
168  void setBBox(const UT_BoundingBox &bbox);
169  bool hasBBox() const;
170  void getBBox(UT_BoundingBox &bbox) const;
171 
172  /// LaserScan will consider only the most extreme intersections along
173  /// each axis, allowing geometry with bad normals or holes to process.
174  /// This is only used with ray-based methods.
175  void setLaserScan(bool laserscan);
176  bool getLaserScan() const;
177 
178  /// FixSigns uses consensus methods to recover from holes.
179  void setFixSigns(int fixsigns);
180  int getFixSigns() const;
181 
182  /// ForceBounds forces all of the outermost voxels to be
183  /// marked as outside. This only applies when FixSigns is set.
184  void setForceBounds(bool forcebounds);
185  bool getForceBounds() const;
186 
187  /// Sets the maximum distance to which the SDF will be evaluated.
188  /// Theoritically, things outside this distance will be left
189  /// at +/- infinitity. In practice, this is still not used.
190  void setMaxDistance(fpreal dist);
191  fpreal getMaxDistance() const;
192 
193  /// Sets the number of neighbours inspected for doing MLS computation
194  /// when constructing from a point cloud.
195  void setNumNeighbour(int numneighbour);
196  int getNumNeighbour() const;
197 
198  void setSweepCount(int sweepcount) { mySweepCount = sweepcount;};
199  int getSweepCount() const { return mySweepCount; }
200 
201  void setSweepThreshold(fpreal sweepthreshold) { mySweepThreshold = sweepthreshold; };
202  fpreal getSweepThreshold() const { return mySweepThreshold; }
203 
204  void setIsoContour(fpreal iso) { myIsoContour = iso; }
205  fpreal getIsoContour() const { return myIsoContour; }
206 
207  void setAlignedVolume(bool aligned) { myAlignedVolume = aligned; }
208  bool getAlignedVolume() const { return myAlignedVolume; }
209 
210  // If the SDF is a VOLUME, has correct signs, and max distance is set, we will want
211  // to make sure the background voxels outside of the narrow band match the sign
212  // of the source volume's voxels.
213  void setMatchSourceSign();
214  bool getMatchSourceSign() const;
215 
216  void setVolumeBuildFIM(bool activator) { myVolumeBuildFIM = activator; }
217  bool getVolumeBuildFIM() const { return myVolumeBuildFIM; }
218 
219  void setToleranceFIM(fpreal tol) { myToleranceFIM = tol; }
220  fpreal getToleranceFIM() const { return myToleranceFIM; }
221 
222  void setIterationsFIM(int iters) { myIterationsFIM = iters; }
223  int getIterationsFIM() const { return myIterationsFIM; }
224 
225 private:
226 
227  sdfMode myMode;
228  int myDivX, myDivY, myDivZ;
229 
230  bool myInvert;
231 
232  fpreal myTol;
233 
234  UT_VoxelArrayF *myVolume;
235 
236  bool myHasBBox;
237  UT_BoundingBox myBBox;
238 
239  UT_Vector3 myPlaneAxis;
240 
241  bool myLaserScan;
242  int myFixSigns;
243  bool myForceBounds;
244 
245  fpreal myOffset;
246  fpreal myMaxDist;
247 
248  int myNumNeighbour;
249 
250  int mySweepCount;
251  fpreal mySweepThreshold;
252 
253  fpreal myIsoContour;
254 
255  bool myAlignedVolume;
256 
257  bool myMatchSourceSign;
258 
259  bool myVolumeBuildFIM;
260  fpreal myToleranceFIM;
261  int myIterationsFIM;
262 };
263 
264 ///
265 /// GU_SDFDelayedBuilder
266 /// This class marshalls the data to build a GU_SDF so it can be
267 /// done multithreaded.
268 ///
270 {
271 public:
273  virtual ~GU_SDFDelayedBuilder();
274 
275  void build();
276 
277  // multithread build of sdfs.
278  static void buildList(UT_Array<GU_SDFDelayedBuilder> &buildlist);
279 
283 
284 private:
286  buildlist.entries() > 1,
287  doBuildList,
288  UT_Array<GU_SDFDelayedBuilder> &, buildlist)
289  void doBuildListPartial(UT_Array<GU_SDFDelayedBuilder> &buildlist,
290  const UT_JobInfo &info);
291 };
292 
293 
294 ///
295 /// GU_SDF
296 /// This class builds a signed distance function from a given GU_Detail.
297 /// Signed distance functions contain an approximate distance to the original
298 /// surface in each voxel cell. If cell is inside the the geometry, it
299 /// has a negative distance. Sidedness of geometry is determined by
300 /// surface normals. The geometry should be relatively watertight.
301 ///
303 {
304 public:
305  GU_SDF();
306  virtual ~GU_SDF();
307 
309  {
310  SDF_EXPLICIT, // Not implicit.
314  SDF_HEIGHTFIELD
315  };
316 
317  /// Expands the given bounding box so it contains a two cell border
318  /// on all sides. This helps condition the SDF stuff by ensuring
319  /// the outer cells are all outside.
320  static void expandBounds(UT_BoundingBox &bbox,
321  int xres, int yres, int zres);
322 
323  /// Build from the given gdp.
324  void build(const GU_Detail *gdp,
325  const GU_SDFParms &parms);
326 
327  /// Initializes an empty sdf of a given resolution and from a given
328  /// bounding box.
329  void initEmpty(const UT_BoundingBox &bbox,
330  int xres, int yres, int zres);
331 
332 
333  UT_VoxelArrayF *getFunction() const { return myVoxels; }
334 
335  /// Returns the transform of a heightfield SDF.
337  { return myHeightXform; }
338 
339  /// Returns the vertical axis of a heightfield SDF.
340  int getHeightAxis() const { return myHeightAxis; }
341 
342  /// Implicit SDFs have no array of voxels, instead defining themselves
343  /// as a simple atomic shape.
344  bool isImplicit() const
345  { return myImplicitType != SDF_EXPLICIT; }
346 
347  bool isValid() const
348  {
349  return (isImplicit() || getFunction() != 0);
350  }
351 
352  /// Returns whether the specified build mode is multithreaded.
353  static bool isMultithreaded(const GU_SDFParms &parms)
354  {
355  return (parms.getMode() == GU_SDFParms::VOLUMESAMPLE);
356  }
357 
358  /// Returns the type of implicit surface, if any.
360  { return myImplicitType; }
361 
362  /// The normal definining the implicit function. This is only
363  /// meaninful for half-plane implicit functions.
365  { return myImplicitNormal; }
366 
367  /// Returns the divisions that the spaces is voxelized into.
368  /// This is meaningful even for implicit surfaces, as they have
369  /// a prefered division set for purposes like advection.
370  void getDivisions(int &xdiv, int &ydiv, int &zdiv) const;
371 
372  /// Calculates the SDF field at the point.
373  fpreal getDistance(const UT_Vector3 &pos) const;
374 
375  // This calculates the distance to the SDF using a faster, but
376  // less accurate method. The tol parameter is set to the
377  // tolerance to which the distance was computed.
378  // Basically, this will point sample the SDF, put the distance to
379  // the point sample in the tol parameter, and return the point sample.
380  // This involves 1/8th of the voxel lookup as a getDistance.
381  fpreal getFastDistance(const UT_Vector3 &pos, fpreal &tol) const;
382 
383  /// Returns the gradient of the SDF at the point.
384  UT_Vector3 getGradient(const UT_Vector3 &pos) const;
385 
386  /// Returns the closest point on the iso surface to the given
387  /// point.
388  /// The Courant-Friedreichs-Lewy condition governs how carefully
389  /// we step to find the solution. 0.9 is near optimal, 0.5 is
390  /// conservative.
391  UT_Vector3 findClosest(const UT_Vector3 &pos,
392  fpreal iso = 0.0,
393  fpreal cfl_cond = 0.9,
394  fpreal tol = 1e-3) const;
395 
396  /// Advects a point according to the SDF's gradient field.
397  /// Advection continues until the point has moved the given distance.
398  /// If normalize_gradient is false, it is moved until the given
399  /// amount of *time* has passed.
400  UT_Vector3 advect(const UT_Vector3 &pos,
401  fpreal dist,
402  fpreal cfl_cond = 0.9f,
403  bool normalize_gradient = true) const;
404 
405  /// Finds the smallest value in the SDF along the given line
406  /// segment. The value must be smaller than the cutoff value.
407  /// Returns false if no close value found.
408  bool findSmallestOnEdge(
409  fpreal &minvalue,
411  const UT_Vector3 &a,
412  const UT_Vector3 &b,
413  fpreal cutoff = SYS_FPREAL_MAX) const;
414 
415  /// Finds the smallest value in the SDF inside the given triangle.
416  /// The value must be smaller than the cutoff value.
417  /// Returns false if no close value found.
418  ///
419  /// Note: this algorithm is far from perfect. It does only a very
420  /// partial scan over the interior of the triangle, and it doesn't work
421  /// well with implicit box SDFs.
422  bool findSmallestOnTri(
423  fpreal &minValue,
424  UT_Vector2 &resultBary,
425  const UT_Vector3 &p0,
426  const UT_Vector3 &p1,
427  const UT_Vector3 &p2,
428  fpreal cutoff = SYS_FPREAL_MAX) const;
429 
430 
431  /// Returns the point along a path where it first intersects the SDF.
432  /// If the path doesn't intersect the SDF, this function returns false.
433  /// If the start of the path is inside the SDF, the function returns
434  /// true, and returns the starting point of the path as the intersection.
435  template <typename FLOAT>
436  bool findRayIntersection(
438  const UT_Vector3T<FLOAT> &a,
439  const UT_Vector3T<FLOAT> &b,
440  fpreal boundaryvalue = 0.0) const;
441 
442 
443 
444  const UT_Vector3 &getVoxelSize() const { return myVoxelSize; }
445  fpreal getVoxelDiameter() const { return myVoxelDiameter; }
446  const UT_Vector3 &getSize() const { return mySize; }
447  const UT_Vector3 &getOrig() const { return myOrig; }
448 
449  void setOrig(const UT_Vector3 &o);
450  void setSize(const UT_Vector3 &s);
451 
452  /// Computes the center of mass of the SDF.
453  void computeCenterOfMass(
454  UT_Vector3 &centerofmass) const;
455 
456  /// Computes the volume of the SDF.
457  fpreal computeVolume() const;
458 
459  /// Computes the inertial tensor.
460  /// You provide the center of mass for it to use.
461  /// Each sample point of the SDF is treated as a point mass. The
462  /// mass is 0 for cell-points outside of the object, 1 for those
463  /// fully inside, and suitably scaled for others.
464  void computeInertialTensor(UT_DMatrix3 &tensor,
465  const UT_Vector3 &centerofmass) const;
466 
467  /// Returns the amount of memory used by this object.
468  int64 getMemoryUsage() const;
469 
470  /// These invert the sense of the SDF. This means the getDistance()
471  /// function will always return -getDistance(), effectively turning
472  /// the object inside out.
473  /// This does not affect the calculation of volumes, etc!
474  /// (Technically, an inverted SDF has infinite volume, which isn't
475  /// all that useful anyways)
476  bool isInverted() const { return myInvert; }
477  void setInverted(bool invert) { myInvert = invert; }
478 
479  /// These offset the zero isosurface of the SDF. This means that
480  /// getDistance() will always return getDistance() - offset,
481  /// effectively inflating (if offset is positive) or deflating (if
482  /// offset is negative) the object.
483  ///
484  /// Offsetting happens before inversion.
485  fpreal getOffset() const { return myOffset; }
486  void setOffset(fpreal offset) { myOffset = offset; }
487 
488  /// Load and save this SDF.
489  /// This occurs in binary format.
490  void save(std::ostream &os) const;
491  bool load(UT_IStream &is);
492 
493 protected:
494  /// This sends rays along all the major axes. The cell distances
495  /// are set to the distance along the axes to surfaces.
496  void sendRays(const GU_Detail *gdp,
497  bool laserscan,
498  bool usemetafield,
499  fpreal tol);
500 
501  /// This fixes the sign of the distance field by finding a
502  /// consensus among neighbouring voxels.
503  /// This requires myQueueIndices to be present.
504  /// If forcebounds is set, it will make the boundary all positive
505  /// in sign, making it easier to recover from holes.
506  void fixSigns(bool forcebounds);
507 
508  /// This finds consensus among the neighbours of this point
509  /// It may then flip this points sign. If it does so, the
510  /// point and it's neighbours are added to the list to
511  /// be tested in the future.
512  /// This uses myQueueIndices to track if a voxel has been added before.
513  /// Returns 1 if a point flipped, 0 otherwise.
514  int findConsensus(int x, int y, int z,
515  int iteration,
516  fpreal alpha, fpreal beta,
517  UT_Array<gu_sdf_voxpos> &flippedlist);
518 
519  /// Performs a fast sweep along the given axis. Any voxel pair
520  /// that has a bad consensus will be raytested & flipped.
521  /// The flip is then propagated.
522  /// dir is +/-1 to represent a forward or back sweep.
523  int fastSweepCorrect(GU_RayIntersect *isect,
524  int axis, int dir, fpreal alpha,
525  fpreal tol);
526 
527  /// Rasterizers...
528  void rasterize(const GEO_Primitive *prim);
529  void rasterizePoly(const GEO_PrimPoly *poly);
530 
531  /// This takes coordinates in cell space.
532  void rasterizeRawTri(UT_Vector3 p1, UT_Vector3 p2, UT_Vector3 p3);
533 
534  /// This sets the given cell to a specific SDF value. This will be
535  /// considered a finalized value, so it will be written to the
536  /// output voxel array, any QElem will be deleted, and any neighbouring
537  /// cells will get tentative values.
538  /// Propagation to neighbouring cells only occurs if dist < maxdist,
539  /// unless maxdist < 0
540  void setCellDist(int x, int y, int z, fpreal dist,
541  fpreal maxdist=-1.0);
542 
543  /// Sets a tentative value to a given cell.
544  void setCellTentative(int x, int y, int z,
545  fpreal tentative);
546 
547  /// Gets or creates the qelement at the given location. Returns 0
548  /// if the element has already been processed.
549  gu_sdf_qelem *getQElem(int x, int y, int z,
550  bool create=true);
551 
552  /// If you change the weight of the qelem, this will update the queue.
553  void updateQElem(gu_sdf_qelem *qelem);
554 
555  /// Calculates the distance to a cell by using the finalized
556  /// distances to adjacent cells.
557  /// The olddistance is used to determine sign.
558  fpreal findMinDist(int x, int y, int z,
559  fpreal olddist) const;
560 
561  /// Propagate distances from all elements in the queue until maximum
562  /// distance is reached.
563  void propagateQueue(fpreal maxdist);
564 
565  /// Builds a shell of distance values around the geometry
566  /// based on minimum distance values.
567  /// We want to fill in the cell values
568  /// from (x,y,z) to (x+xw-1,y+yw-1,z+zw-1)
569  /// inclusive. We only fill values that are within a band about
570  /// the surface, leaving the rest for FMM. This is because min
571  /// distance calls are expensive!
572  void buildFromMinDist(GU_RayIntersect &isect,
573  int x, int y, int z,
574  int xw, int yw, int zw);
575 
576  /// Builds a shell of distance values around the geometry
577  /// from the point cloud data.
578  /// If normals are present, they are used to calculate sidedness.
579  /// Otherwise, the SDF becomes an unsigned distance-to-implicit surface.
580  void buildFromPointCloud(const GU_Detail *gdp,
581  const GU_SDFParms &parms);
582 
583  //
584  // Fast Iterative Method additions
585  //
586 
587  bool findZeroCrossing(UT_VoxelROProbeCubeF &src_probe, fpreal &voxeldist, const fpreal isocontour);
588 
589  void buildFromVolumeFIM(const UT_VoxelArrayF &src, const fpreal isocontour, const fpreal maxdist,
590  const fpreal tolerance, const int iterations);
591 
592  THREADED_METHOD7(GU_SDF, activelist.entries() > 100, solveEikonalIterationFIM,
595  UT_Array<bool>&, tileoccupied,
596  const UT_VoxelArrayF&, olddst,
597  const UT_Array<UT_Vector3I>&, activelist,
598  const fpreal, maxdist, const fpreal, tolerance);
599 
600  void solveEikonalIterationFIMPartial(UT_VoxelArrayF &dst,
602  UT_Array<bool> &tileoccupied,
603  const UT_VoxelArrayF &olddst,
604  const UT_Array<UT_Vector3I> &activelist,
605  const fpreal maxdist, const fpreal tolerance,
606  const UT_JobInfo &info);
607 
608  THREADED_METHOD1(GU_SDF, activelist.entries() > 100, assignSolvableLabelsFIM,
609  const UT_Array<UT_Vector3I>&, activelist);
610 
611  void assignSolvableLabelsFIMPartial(const UT_Array<UT_Vector3I> &activelist,
612  const UT_JobInfo &info);
613 
614  THREADED_METHOD1(GU_SDF, activelist.entries() > 100, removeSolvableLabelsFIM,
615  const UT_Array<UT_Vector3I>&, activelist);
616 
617  void removeSolvableLabelsFIMPartial(const UT_Array<UT_Vector3I> &activelist,
618  const UT_JobInfo &info);
619 
620  THREADED_METHOD2(GU_SDF, myQueueIndices->numTiles() > 20, loadFinishedCellNeighboursFIM,
622  UT_Array<bool>&, tileoccupied);
623 
624  void loadFinishedCellNeighboursFIMPartial(UT_Array<UT_Array<UT_Vector3I>> &list,
625  UT_Array<bool> &tileoccupied,
626  const UT_JobInfo &info);
627 
628  THREADED_METHOD3(GU_SDF, occupied.entries() > 100, uncompressActiveTilesFIM,
629  UT_VoxelArrayF&, olddst,
631  const UT_Array<bool>&, occupied);
632 
633  void uncompressActiveTilesFIMPartial(UT_VoxelArrayF &olddst,
635  const UT_Array<bool> &occupied,
636  const UT_JobInfo &info);
637 
638  THREADED_METHOD5(GU_SDF, src.numTiles() > 20, computeAndLabelZeroCrossingsFIM,
640  UT_VoxelArrayF&, olddst,
641  const UT_VoxelArrayF&, src,
642  const fpreal, isocontour,
643  const fpreal, maxdist);
644 
645  void computeAndLabelZeroCrossingsFIMPartial(UT_VoxelArrayF &dst,
646  UT_VoxelArrayF &olddst,
647  const UT_VoxelArrayF &src,
648  const fpreal isocontour,
649  const fpreal maxdist,
650  const UT_JobInfo &info);
651 
652  THREADED_METHOD5(GU_SDF, src.numTiles() > 20, buildVolumeZeroCrossings,
653  UT_Array<UT_Array<UT_Vector3I>> &, crossingindices,
654  UT_Array<UT_Array<fpreal>> &, crossingdists,
655  const UT_VoxelArrayF&, src,
656  const fpreal, isocontour,
657  const fpreal, maxdist);
658 
659  void buildVolumeZeroCrossingsPartial(UT_Array<UT_Array<UT_Vector3I>> &crossingindices,
660  UT_Array<UT_Array<fpreal>> &crossingdists,
661  const UT_VoxelArrayF &src,
662  const fpreal isocontour,
663  const fpreal maxdist,
664  const UT_JobInfo &info);
665 
666  /// Builds a shell of distance values around the given iso-contour
667  /// of the volume. This allows one to then reinitialize an SDF function.
668  void buildFromVolume(const UT_VoxelArrayF &src, const fpreal isocontour,
669  const fpreal maxdist);
670 
671  /// Takes a list of GEO_Points and finds the best fititng
672  /// plane which interpolates them. If noff is not -1, it
673  /// will derive the normals from the point normals.
674  UT_Plane findPlaneFromNeighbour(
675  const UT_Vector3 &sample,
676  const GU_Detail *gdp,
677  const GA_OffsetArray &neighbour,
678  const GA_ROHandleV3 &normalattrib) const;
679 
680 
682  myVoxels->numTiles() > 16,
683  copyVolumeSamples,
684  const GU_Detail *, gdp,
685  const UT_ValArray<const GEO_Primitive *> &, volumes);
686 
687  void copyVolumeSamplesPartial(const GU_Detail *gdp,
688  const UT_ValArray<const GEO_Primitive *> &volumes,
689  const UT_JobInfo &info);
690 
691  /// This is the actual explicit array of voxels. It is not
692  /// present if the SDF array is implicit. It does not incorporate the
693  /// offset or inversion.
695 
696  /// What sort of implicit representation we are using.
697  /// SDF_EXPLICIT if we have none.
699 
701 
702  /// This flags whether we act as if our SDF had the opposite sign
703  /// than it does.
704  bool myInvert;
705  /// This defines how far we should shift the zero isosurface of the SDF.
707 
708  /// Real world coordinates are transformed into the voxel array's 0-1
709  /// space by subtracting myOrig and dividing by mySize.
711 
714 
715  /// This stores the size of a voxel along each axis.
717 
718  /// This caches the diameter of a voxel cell. Ie, myVoxelSize.length()
720 
721  /// These are used in the building stage to rasterize to, and in the
722  /// expansion stage as the priority queues.
727 };
728 
729 #endif
GA_API const UT_StringHolder dist
#define THREADED_METHOD7(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7)
UT_Vector3 mySize
Definition: GU_SDF.h:710
int refpos
Definition: GU_SDF.h:47
void rasterize(const PointDataTreeOrGridT &points, TransferT &transfer, const FilterT &filter=NullFilter(), InterrupterT *interrupter=nullptr)
Perform potentially complex rasterization from a user defined transfer scheme.
GLboolean invert
Definition: glcorearb.h:549
#define THREADED_METHOD1(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
GEO_PrimVolumeXform myHeightXform
Definition: GU_SDF.h:712
void setIsoContour(fpreal iso)
Definition: GU_SDF.h:204
const UT_Vector3 & getVoxelSize() const
Definition: GU_SDF.h:444
void setAlignedVolume(bool aligned)
Definition: GU_SDF.h:207
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
#define SYSabs(a)
Definition: SYS_Math.h:1540
void setSweepCount(int sweepcount)
Definition: GU_SDF.h:198
fpreal getOffset() const
Definition: GU_SDF.h:485
GLint y
Definition: glcorearb.h:103
void setSweepThreshold(fpreal sweepthreshold)
Definition: GU_SDF.h:201
**But if you need a result
Definition: thread.h:613
const UT_Vector3 & getOrig() const
Definition: GU_SDF.h:447
Definition: GU_SDF.h:302
void changedPosition(gu_sdf_qelem *e, unsigned int idx) const override
Definition: GU_SDF.h:97
static bool isMultithreaded(const GU_SDFParms &parms)
Returns whether the specified build mode is multithreaded.
Definition: GU_SDF.h:353
GU_SDFParms myParms
Definition: GU_SDF.h:280
fpreal myOffset
This defines how far we should shift the zero isosurface of the SDF.
Definition: GU_SDF.h:706
#define THREADED_METHOD3(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3)
gu_sdf_voxpos(int px, int py, int pz)
Definition: GU_SDF.h:62
UT_VoxelArrayF * myVoxels
Definition: GU_SDF.h:694
void setOffset(fpreal offset)
Definition: GU_SDF.h:486
fpreal getVoxelDiameter() const
Definition: GU_SDF.h:445
fpreal getSweepThreshold() const
Definition: GU_SDF.h:202
sdfImplicitType myImplicitType
Definition: GU_SDF.h:698
GLfloat f
Definition: glcorearb.h:1926
const UT_Vector3 & getImplicitNormal() const
Definition: GU_SDF.h:364
GLintptr offset
Definition: glcorearb.h:665
int getIterationsFIM() const
Definition: GU_SDF.h:223
UT_IntArray myQueueFreeList
Definition: GU_SDF.h:725
This class provides a way to manage a reference to an attribute permitting Read-Only access...
void setInverted(bool invert)
Definition: GU_SDF.h:477
int setVolume(int speaker, float vol) override
void setVolumeBuildFIM(bool activator)
Definition: GU_SDF.h:216
int myHeightAxis
Definition: GU_SDF.h:713
#define THREADED_METHOD2(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2)
const UT_Vector3 & getSize() const
Definition: GU_SDF.h:446
fpreal getToleranceFIM() const
Definition: GU_SDF.h:220
UT_Vector3 myImplicitNormal
Definition: GU_SDF.h:700
UT_VoxelArrayF * getFunction() const
Definition: GU_SDF.h:333
long long int64
Definition: SYS_Types.h:116
void setIterationsFIM(int iters)
Definition: GU_SDF.h:222
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
const GEO_PrimVolumeXform & getHeightXform() const
Returns the transform of a heightfield SDF.
Definition: GU_SDF.h:336
#define THREADED_METHOD5(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5)
int qpos
Definition: GU_SDF.h:45
#define GU_API
Definition: GU_API.h:14
int getSweepCount() const
Definition: GU_SDF.h:199
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
bool getVolumeBuildFIM() const
Definition: GU_SDF.h:217
GLint GLenum GLint x
Definition: glcorearb.h:409
bool operator()(const gu_sdf_qelem *e1, const gu_sdf_qelem *e2) const
Definition: GU_SDF.h:80
#define SYS_FPREAL_MAX
Definition: SYS_Types.h:286
GLenum mode
Definition: glcorearb.h:99
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:648
GU_SDF * mySDF
Definition: GU_SDF.h:281
fpreal getIsoContour() const
Definition: GU_SDF.h:205
IFDmantra py
Definition: HDK_Image.dox:266
GLenum GLenum dst
Definition: glcorearb.h:1793
bool isInverted() const
Definition: GU_SDF.h:476
void setToleranceFIM(fpreal tol)
Definition: GU_SDF.h:219
UT_Vector3 myVoxelSize
This stores the size of a voxel along each axis.
Definition: GU_SDF.h:716
sdfMode getMode() const
bool isImplicit() const
Definition: GU_SDF.h:344
fpreal64 fpreal
Definition: SYS_Types.h:277
bool operator()(const gu_sdf_qelem &e1, const gu_sdf_qelem &e2) const
Definition: GU_SDF.h:76
gu_sdf_queue * myQueue
Definition: GU_SDF.h:726
sdfImplicitType getImplicitType() const
Returns the type of implicit surface, if any.
Definition: GU_SDF.h:359
UT_VoxelArray< int > * myQueueIndices
Definition: GU_SDF.h:723
int getHeightAxis() const
Returns the vertical axis of a heightfield SDF.
Definition: GU_SDF.h:340
fpreal myVoxelDiameter
This caches the diameter of a voxel cell. Ie, myVoxelSize.length()
Definition: GU_SDF.h:719
sdfImplicitType
Definition: GU_SDF.h:308
bool myInvert
Definition: GU_SDF.h:704
float getVolume(int speaker) override
gu_sdf_voxpos()
Definition: GU_SDF.h:61
fpreal dist
Definition: GU_SDF.h:51
bool getAlignedVolume() const
Definition: GU_SDF.h:208
UT_ValArray< gu_sdf_qelem * > myQueueElements
Definition: GU_SDF.h:724
GU_ConstDetailHandle myGDH
Definition: GU_SDF.h:282
bool isValid() const
Definition: GU_SDF.h:347
GLenum src
Definition: glcorearb.h:1793