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  virtual void changedPosition(gu_sdf_qelem *e, unsigned int idx) const
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,
410  UT_Vector3 &result,
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  bool findRayIntersection(
436  UT_Vector3 &result,
437  const UT_Vector3 &a,
438  const UT_Vector3 &b,
439  fpreal boundaryvalue = 0.0) const;
440 
441 
442  const UT_Vector3 &getVoxelSize() const { return myVoxelSize; }
443  fpreal getVoxelDiameter() const { return myVoxelDiameter; }
444  const UT_Vector3 &getSize() const { return mySize; }
445  const UT_Vector3 &getOrig() const { return myOrig; }
446 
447  void setOrig(const UT_Vector3 &o);
448  void setSize(const UT_Vector3 &s);
449 
450  /// Computes the center of mass of the SDF.
451  void computeCenterOfMass(
452  UT_Vector3 &centerofmass) const;
453 
454  /// Computes the volume of the SDF.
455  fpreal computeVolume() const;
456 
457  /// Computes the inertial tensor.
458  /// You provide the center of mass for it to use.
459  /// Each sample point of the SDF is treated as a point mass. The
460  /// mass is 0 for cell-points outside of the object, 1 for those
461  /// fully inside, and suitably scaled for others.
462  void computeInertialTensor(UT_DMatrix3 &tensor,
463  const UT_Vector3 &centerofmass) const;
464 
465  /// Returns the amount of memory used by this object.
466  int64 getMemoryUsage() const;
467 
468  /// These invert the sense of the SDF. This means the getDistance()
469  /// function will always return -getDistance(), effectively turning
470  /// the object inside out.
471  /// This does not affect the calculation of volumes, etc!
472  /// (Technically, an inverted SDF has infinite volume, which isn't
473  /// all that useful anyways)
474  bool isInverted() const { return myInvert; }
475  void setInverted(bool invert) { myInvert = invert; }
476 
477  /// These offset the zero isosurface of the SDF. This means that
478  /// getDistance() will always return getDistance() - offset,
479  /// effectively inflating (if offset is positive) or deflating (if
480  /// offset is negative) the object.
481  ///
482  /// Offsetting happens before inversion.
483  fpreal getOffset() const { return myOffset; }
484  void setOffset(fpreal offset) { myOffset = offset; }
485 
486  /// Load and save this SDF.
487  /// This occurs in binary format.
488  void save(std::ostream &os) const;
489  bool load(UT_IStream &is);
490 
491 protected:
492  /// This sends rays along all the major axes. The cell distances
493  /// are set to the distance along the axes to surfaces.
494  void sendRays(const GU_Detail *gdp,
495  bool laserscan,
496  bool usemetafield,
497  fpreal tol);
498 
499  /// This fixes the sign of the distance field by finding a
500  /// consensus among neighbouring voxels.
501  /// This requires myQueueIndices to be present.
502  /// If forcebounds is set, it will make the boundary all positive
503  /// in sign, making it easier to recover from holes.
504  void fixSigns(bool forcebounds);
505 
506  /// This finds consensus among the neighbours of this point
507  /// It may then flip this points sign. If it does so, the
508  /// point and it's neighbours are added to the list to
509  /// be tested in the future.
510  /// This uses myQueueIndices to track if a voxel has been added before.
511  /// Returns 1 if a point flipped, 0 otherwise.
512  int findConsensus(int x, int y, int z,
513  int iteration,
514  fpreal alpha, fpreal beta,
515  UT_Array<gu_sdf_voxpos> &flippedlist);
516 
517  /// Performs a fast sweep along the given axis. Any voxel pair
518  /// that has a bad consensus will be raytested & flipped.
519  /// The flip is then propagated.
520  /// dir is +/-1 to represent a forward or back sweep.
521  int fastSweepCorrect(GU_RayIntersect *isect,
522  int axis, int dir, fpreal alpha,
523  fpreal tol);
524 
525  /// Rasterizers...
526  void rasterize(const GEO_Primitive *prim);
527  void rasterizePoly(const GEO_PrimPoly *poly);
528 
529  /// This takes coordinates in cell space.
530  void rasterizeRawTri(UT_Vector3 p1, UT_Vector3 p2, UT_Vector3 p3);
531 
532  /// This sets the given cell to a specific SDF value. This will be
533  /// considered a finalized value, so it will be written to the
534  /// output voxel array, any QElem will be deleted, and any neighbouring
535  /// cells will get tentative values.
536  /// Propagation to neighbouring cells only occurs if dist < maxdist,
537  /// unless maxdist < 0
538  void setCellDist(int x, int y, int z, fpreal dist,
539  fpreal maxdist=-1.0);
540 
541  /// Sets a tentative value to a given cell.
542  void setCellTentative(int x, int y, int z,
543  fpreal tentative);
544 
545  /// Gets or creates the qelement at the given location. Returns 0
546  /// if the element has already been processed.
547  gu_sdf_qelem *getQElem(int x, int y, int z,
548  bool create=true);
549 
550  /// If you change the weight of the qelem, this will update the queue.
551  void updateQElem(gu_sdf_qelem *qelem);
552 
553  /// Calculates the distance to a cell by using the finalized
554  /// distances to adjacent cells.
555  /// The olddistance is used to determine sign.
556  fpreal findMinDist(int x, int y, int z,
557  fpreal olddist) const;
558 
559  /// Propagate distances from all elements in the queue until maximum
560  /// distance is reached.
561  void propagateQueue(fpreal maxdist);
562 
563  /// Builds a shell of distance values around the geometry
564  /// based on minimum distance values.
565  /// We want to fill in the cell values
566  /// from (x,y,z) to (x+xw-1,y+yw-1,z+zw-1)
567  /// inclusive. We only fill values that are within a band about
568  /// the surface, leaving the rest for FMM. This is because min
569  /// distance calls are expensive!
570  void buildFromMinDist(GU_RayIntersect &isect,
571  int x, int y, int z,
572  int xw, int yw, int zw);
573 
574  /// Builds a shell of distance values around the geometry
575  /// from the point cloud data.
576  /// If normals are present, they are used to calculate sidedness.
577  /// Otherwise, the SDF becomes an unsigned distance-to-implicit surface.
578  void buildFromPointCloud(const GU_Detail *gdp,
579  const GU_SDFParms &parms);
580 
581  //
582  // Fast Iterative Method additions
583  //
584 
585  bool findZeroCrossing(UT_VoxelProbeCubeF &src_probe, fpreal &voxeldist, const fpreal isocontour);
586 
587  void buildFromVolumeFIM(const UT_VoxelArrayF &src, const fpreal isocontour, const fpreal maxdist,
588  const fpreal tolerance, const int iterations);
589 
590  THREADED_METHOD7(GU_SDF, activelist.entries() > 100, solveEikonalIterationFIM,
593  UT_Array<bool>&, tileoccupied,
594  const UT_VoxelArrayF&, olddst,
595  const UT_Array<UT_Vector3I>&, activelist,
596  const fpreal, maxdist, const fpreal, tolerance);
597 
598  void solveEikonalIterationFIMPartial(UT_VoxelArrayF &dst,
600  UT_Array<bool> &tileoccupied,
601  const UT_VoxelArrayF &olddst,
602  const UT_Array<UT_Vector3I> &activelist,
603  const fpreal maxdist, const fpreal tolerance,
604  const UT_JobInfo &info);
605 
606  THREADED_METHOD1(GU_SDF, activelist.entries() > 100, assignSolvableLabelsFIM,
607  const UT_Array<UT_Vector3I>&, activelist);
608 
609  void assignSolvableLabelsFIMPartial(const UT_Array<UT_Vector3I> &activelist,
610  const UT_JobInfo &info);
611 
612  THREADED_METHOD1(GU_SDF, activelist.entries() > 100, removeSolvableLabelsFIM,
613  const UT_Array<UT_Vector3I>&, activelist);
614 
615  void removeSolvableLabelsFIMPartial(const UT_Array<UT_Vector3I> &activelist,
616  const UT_JobInfo &info);
617 
618  THREADED_METHOD2(GU_SDF, myQueueIndices->numTiles() > 20, loadFinishedCellNeighboursFIM,
620  UT_Array<bool>&, tileoccupied);
621 
622  void loadFinishedCellNeighboursFIMPartial(UT_Array<UT_Array<UT_Vector3I>> &list,
623  UT_Array<bool> &tileoccupied,
624  const UT_JobInfo &info);
625 
626  THREADED_METHOD3(GU_SDF, occupied.entries() > 100, uncompressActiveTilesFIM,
627  UT_VoxelArrayF&, olddst,
629  const UT_Array<bool>&, occupied);
630 
631  void uncompressActiveTilesFIMPartial(UT_VoxelArrayF &olddst,
633  const UT_Array<bool> &occupied,
634  const UT_JobInfo &info);
635 
636  THREADED_METHOD5(GU_SDF, src.numTiles() > 20, computeAndLabelZeroCrossingsFIM,
638  UT_VoxelArrayF&, olddst,
639  const UT_VoxelArrayF&, src,
640  const fpreal, isocontour,
641  const fpreal, maxdist);
642 
643  void computeAndLabelZeroCrossingsFIMPartial(UT_VoxelArrayF &dst,
644  UT_VoxelArrayF &olddst,
645  const UT_VoxelArrayF &src,
646  const fpreal isocontour,
647  const fpreal maxdist,
648  const UT_JobInfo &info);
649 
650  THREADED_METHOD5(GU_SDF, src.numTiles() > 20, buildVolumeZeroCrossings,
651  UT_Array<UT_Array<UT_Vector3I>> &, crossingindices,
652  UT_Array<UT_Array<fpreal>> &, crossingdists,
653  const UT_VoxelArrayF&, src,
654  const fpreal, isocontour,
655  const fpreal, maxdist);
656 
657  void buildVolumeZeroCrossingsPartial(UT_Array<UT_Array<UT_Vector3I>> &crossingindices,
658  UT_Array<UT_Array<fpreal>> &crossingdists,
659  const UT_VoxelArrayF &src,
660  const fpreal isocontour,
661  const fpreal maxdist,
662  const UT_JobInfo &info);
663 
664  /// Builds a shell of distance values around the given iso-contour
665  /// of the volume. This allows one to then reinitialize an SDF function.
666  void buildFromVolume(const UT_VoxelArrayF &src, const fpreal isocontour,
667  const fpreal maxdist);
668 
669  /// Takes a list of GEO_Points and finds the best fititng
670  /// plane which interpolates them. If noff is not -1, it
671  /// will derive the normals from the point normals.
672  UT_Plane findPlaneFromNeighbour(
673  const UT_Vector3 &sample,
674  const GU_Detail *gdp,
675  const GA_OffsetArray &neighbour,
676  const GA_ROHandleV3 &normalattrib) const;
677 
678 
680  myVoxels->numTiles() > 16,
681  copyVolumeSamples,
682  const GU_Detail *, gdp,
683  const UT_ValArray<const GEO_Primitive *> &, volumes);
684 
685  void copyVolumeSamplesPartial(const GU_Detail *gdp,
686  const UT_ValArray<const GEO_Primitive *> &volumes,
687  const UT_JobInfo &info);
688 
689  /// This is the actual explicit array of voxels. It is not
690  /// present if the SDF array is implicit. It does not incorporate the
691  /// offset or inversion.
693 
694  /// What sort of implicit representation we are using.
695  /// SDF_EXPLICIT if we have none.
697 
699 
700  /// This flags whether we act as if our SDF had the opposite sign
701  /// than it does.
702  bool myInvert;
703  /// This defines how far we should shift the zero isosurface of the SDF.
705 
706  /// Real world coordinates are transformed into the voxel array's 0-1
707  /// space by subtracting myOrig and dividing by mySize.
709 
712 
713  /// This stores the size of a voxel along each axis.
715 
716  /// This caches the diameter of a voxel cell. Ie, myVoxelSize.length()
718 
719  /// These are used in the building stage to rasterize to, and in the
720  /// expansion stage as the priority queues.
725 };
726 
727 #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:708
int refpos
Definition: GU_SDF.h:47
GLboolean invert
Definition: glcorearb.h:548
#define THREADED_METHOD1(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
GEO_PrimVolumeXform myHeightXform
Definition: GU_SDF.h:710
void setIsoContour(fpreal iso)
Definition: GU_SDF.h:204
const UT_Vector3 & getVoxelSize() const
Definition: GU_SDF.h:442
void setAlignedVolume(bool aligned)
Definition: GU_SDF.h:207
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
virtual float getVolume(int speaker)
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
#define SYSabs(a)
Definition: SYS_Math.h:1369
void setSweepCount(int sweepcount)
Definition: GU_SDF.h:198
fpreal getOffset() const
Definition: GU_SDF.h:483
GLint y
Definition: glcorearb.h:102
void setSweepThreshold(fpreal sweepthreshold)
Definition: GU_SDF.h:201
const UT_Vector3 & getOrig() const
Definition: GU_SDF.h:445
3D Vector class.
Definition: GU_SDF.h:302
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:704
#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:692
void setOffset(fpreal offset)
Definition: GU_SDF.h:484
long long int64
Definition: SYS_Types.h:107
fpreal getVoxelDiameter() const
Definition: GU_SDF.h:443
fpreal getSweepThreshold() const
Definition: GU_SDF.h:202
sdfImplicitType myImplicitType
Definition: GU_SDF.h:696
GLfloat f
Definition: glcorearb.h:1925
const UT_Vector3 & getImplicitNormal() const
Definition: GU_SDF.h:364
int getIterationsFIM() const
Definition: GU_SDF.h:223
UT_IntArray myQueueFreeList
Definition: GU_SDF.h:723
This class provides a way to manage a reference to an attribute permitting Read-Only access...
void setInverted(bool invert)
Definition: GU_SDF.h:475
void setVolumeBuildFIM(bool activator)
Definition: GU_SDF.h:216
int myHeightAxis
Definition: GU_SDF.h:711
#define THREADED_METHOD2(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2)
GLintptr offset
Definition: glcorearb.h:664
const UT_Vector3 & getSize() const
Definition: GU_SDF.h:444
fpreal getToleranceFIM() const
Definition: GU_SDF.h:220
UT_Vector3 myImplicitNormal
Definition: GU_SDF.h:698
UT_VoxelArrayF * getFunction() const
Definition: GU_SDF.h:333
void setIterationsFIM(int iters)
Definition: GU_SDF.h:222
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:111
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:12
int getSweepCount() const
Definition: GU_SDF.h:199
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
bool getVolumeBuildFIM() const
Definition: GU_SDF.h:217
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:279
GLenum mode
Definition: glcorearb.h:98
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:453
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:1792
double fpreal
Definition: SYS_Types.h:270
bool isInverted() const
Definition: GU_SDF.h:474
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:714
sdfMode getMode() const
bool isImplicit() const
Definition: GU_SDF.h:344
virtual int setVolume(int speaker, float vol)
bool operator()(const gu_sdf_qelem &e1, const gu_sdf_qelem &e2) const
Definition: GU_SDF.h:76
GLint GLenum GLint x
Definition: glcorearb.h:408
gu_sdf_queue * myQueue
Definition: GU_SDF.h:724
sdfImplicitType getImplicitType() const
Returns the type of implicit surface, if any.
Definition: GU_SDF.h:359
UT_VoxelArray< int > * myQueueIndices
Definition: GU_SDF.h:721
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:717
sdfImplicitType
Definition: GU_SDF.h:308
bool myInvert
Definition: GU_SDF.h:702
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:722
GU_ConstDetailHandle myGDH
Definition: GU_SDF.h:282
bool isValid() const
Definition: GU_SDF.h:347
virtual void changedPosition(gu_sdf_qelem *e, unsigned int idx) const
Definition: GU_SDF.h:97
GLenum src
Definition: glcorearb.h:1792