HDK
|
#include <GU_SDF.h>
Public Types | |
enum | sdfImplicitType { SDF_EXPLICIT, SDF_SPHERE, SDF_PLANE, SDF_BOX, SDF_HEIGHTFIELD } |
Public Member Functions | |
GU_SDF () | |
virtual | ~GU_SDF () |
void | build (const GU_Detail *gdp, const GU_SDFParms &parms) |
Build from the given gdp. More... | |
void | initEmpty (const UT_BoundingBox &bbox, int xres, int yres, int zres) |
UT_VoxelArrayF * | getFunction () const |
const GEO_PrimVolumeXform & | getHeightXform () const |
Returns the transform of a heightfield SDF. More... | |
int | getHeightAxis () const |
Returns the vertical axis of a heightfield SDF. More... | |
bool | isImplicit () const |
bool | isValid () const |
sdfImplicitType | getImplicitType () const |
Returns the type of implicit surface, if any. More... | |
const UT_Vector3 & | getImplicitNormal () const |
void | getDivisions (int &xdiv, int &ydiv, int &zdiv) const |
fpreal | getDistance (const UT_Vector3 &pos) const |
Calculates the SDF field at the point. More... | |
fpreal | getFastDistance (const UT_Vector3 &pos, fpreal &tol) const |
UT_Vector3 | getGradient (const UT_Vector3 &pos) const |
Returns the gradient of the SDF at the point. More... | |
UT_Vector3 | findClosest (const UT_Vector3 &pos, fpreal iso=0.0, fpreal cfl_cond=0.9, fpreal tol=1e-3) const |
UT_Vector3 | advect (const UT_Vector3 &pos, fpreal dist, fpreal cfl_cond=0.9f, bool normalize_gradient=true) const |
bool | findSmallestOnEdge (fpreal &minvalue, UT_Vector3 &result, const UT_Vector3 &a, const UT_Vector3 &b, fpreal cutoff=SYS_FPREAL_MAX) const |
bool | findSmallestOnTri (fpreal &minValue, UT_Vector2 &resultBary, const UT_Vector3 &p0, const UT_Vector3 &p1, const UT_Vector3 &p2, fpreal cutoff=SYS_FPREAL_MAX) const |
template<typename FLOAT > | |
bool | findRayIntersection (UT_Vector3T< FLOAT > &result, const UT_Vector3T< FLOAT > &a, const UT_Vector3T< FLOAT > &b, fpreal boundaryvalue=0.0) const |
const UT_Vector3 & | getVoxelSize () const |
fpreal | getVoxelDiameter () const |
const UT_Vector3 & | getSize () const |
const UT_Vector3 & | getOrig () const |
void | setOrig (const UT_Vector3 &o) |
void | setSize (const UT_Vector3 &s) |
void | computeCenterOfMass (UT_Vector3 ¢erofmass) const |
Computes the center of mass of the SDF. More... | |
fpreal | computeVolume () const |
Computes the volume of the SDF. More... | |
void | computeInertialTensor (UT_DMatrix3 &tensor, const UT_Vector3 ¢erofmass) const |
int64 | getMemoryUsage () const |
Returns the amount of memory used by this object. More... | |
bool | isInverted () const |
void | setInverted (bool invert) |
fpreal | getOffset () const |
void | setOffset (fpreal offset) |
void | save (std::ostream &os) const |
bool | load (UT_IStream &is) |
Static Public Member Functions | |
static void | expandBounds (UT_BoundingBox &bbox, int xres, int yres, int zres) |
static bool | isMultithreaded (const GU_SDFParms &parms) |
Returns whether the specified build mode is multithreaded. More... | |
Protected Member Functions | |
void | sendRays (const GU_Detail *gdp, bool laserscan, bool usemetafield, fpreal tol) |
void | fixSigns (bool forcebounds) |
int | findConsensus (int x, int y, int z, int iteration, fpreal alpha, fpreal beta, UT_Array< gu_sdf_voxpos > &flippedlist) |
int | fastSweepCorrect (GU_RayIntersect *isect, int axis, int dir, fpreal alpha, fpreal tol) |
void | rasterize (const GEO_Primitive *prim) |
Rasterizers... More... | |
void | rasterizePoly (const GEO_PrimPoly *poly) |
void | rasterizeRawTri (UT_Vector3 p1, UT_Vector3 p2, UT_Vector3 p3) |
This takes coordinates in cell space. More... | |
void | setCellDist (int x, int y, int z, fpreal dist, fpreal maxdist=-1.0) |
void | setCellTentative (int x, int y, int z, fpreal tentative) |
Sets a tentative value to a given cell. More... | |
gu_sdf_qelem * | getQElem (int x, int y, int z, bool create=true) |
void | updateQElem (gu_sdf_qelem *qelem) |
If you change the weight of the qelem, this will update the queue. More... | |
fpreal | findMinDist (int x, int y, int z, fpreal olddist) const |
void | propagateQueue (fpreal maxdist) |
void | buildFromMinDist (GU_RayIntersect &isect, int x, int y, int z, int xw, int yw, int zw) |
void | buildFromPointCloud (const GU_Detail *gdp, const GU_SDFParms &parms) |
bool | findZeroCrossing (UT_VoxelROProbeCubeF &src_probe, fpreal &voxeldist, const fpreal isocontour) |
void | buildFromVolumeFIM (const UT_VoxelArrayF &src, const fpreal isocontour, const fpreal maxdist, const fpreal tolerance, const int iterations) |
THREADED_METHOD7 (GU_SDF, activelist.entries() > 100, solveEikonalIterationFIM, UT_VoxelArrayF &, dst, UT_Array< UT_Array< UT_Vector3I >> &, newlist, UT_Array< bool > &, tileoccupied, const UT_VoxelArrayF &, olddst, const UT_Array< UT_Vector3I > &, activelist, const fpreal, maxdist, const fpreal, tolerance) | |
void | solveEikonalIterationFIMPartial (UT_VoxelArrayF &dst, UT_Array< UT_Array< UT_Vector3I >> &newlist, UT_Array< bool > &tileoccupied, const UT_VoxelArrayF &olddst, const UT_Array< UT_Vector3I > &activelist, const fpreal maxdist, const fpreal tolerance, const UT_JobInfo &info) |
THREADED_METHOD1 (GU_SDF, activelist.entries() > 100, assignSolvableLabelsFIM, const UT_Array< UT_Vector3I > &, activelist) | |
void | assignSolvableLabelsFIMPartial (const UT_Array< UT_Vector3I > &activelist, const UT_JobInfo &info) |
THREADED_METHOD1 (GU_SDF, activelist.entries() > 100, removeSolvableLabelsFIM, const UT_Array< UT_Vector3I > &, activelist) | |
void | removeSolvableLabelsFIMPartial (const UT_Array< UT_Vector3I > &activelist, const UT_JobInfo &info) |
THREADED_METHOD2 (GU_SDF, myQueueIndices->numTiles() > 20, loadFinishedCellNeighboursFIM, UT_Array< UT_Array< UT_Vector3I >> &, newlist, UT_Array< bool > &, tileoccupied) | |
void | loadFinishedCellNeighboursFIMPartial (UT_Array< UT_Array< UT_Vector3I >> &list, UT_Array< bool > &tileoccupied, const UT_JobInfo &info) |
THREADED_METHOD3 (GU_SDF, occupied.entries() > 100, uncompressActiveTilesFIM, UT_VoxelArrayF &, olddst, UT_VoxelArrayF &, dst, const UT_Array< bool > &, occupied) | |
void | uncompressActiveTilesFIMPartial (UT_VoxelArrayF &olddst, UT_VoxelArrayF &dst, const UT_Array< bool > &occupied, const UT_JobInfo &info) |
THREADED_METHOD5 (GU_SDF, src.numTiles() > 20, computeAndLabelZeroCrossingsFIM, UT_VoxelArrayF &, dst, UT_VoxelArrayF &, olddst, const UT_VoxelArrayF &, src, const fpreal, isocontour, const fpreal, maxdist) | |
void | computeAndLabelZeroCrossingsFIMPartial (UT_VoxelArrayF &dst, UT_VoxelArrayF &olddst, const UT_VoxelArrayF &src, const fpreal isocontour, const fpreal maxdist, const UT_JobInfo &info) |
THREADED_METHOD5 (GU_SDF, src.numTiles() > 20, buildVolumeZeroCrossings, UT_Array< UT_Array< UT_Vector3I >> &, crossingindices, UT_Array< UT_Array< fpreal >> &, crossingdists, const UT_VoxelArrayF &, src, const fpreal, isocontour, const fpreal, maxdist) | |
void | buildVolumeZeroCrossingsPartial (UT_Array< UT_Array< UT_Vector3I >> &crossingindices, UT_Array< UT_Array< fpreal >> &crossingdists, const UT_VoxelArrayF &src, const fpreal isocontour, const fpreal maxdist, const UT_JobInfo &info) |
void | buildFromVolume (const UT_VoxelArrayF &src, const fpreal isocontour, const fpreal maxdist) |
UT_Plane | findPlaneFromNeighbour (const UT_Vector3 &sample, const GU_Detail *gdp, const GA_OffsetArray &neighbour, const GA_ROHandleV3 &normalattrib) const |
THREADED_METHOD2 (GU_SDF, myVoxels->numTiles() > 16, copyVolumeSamples, const GU_Detail *, gdp, const UT_ValArray< const GEO_Primitive * > &, volumes) | |
void | copyVolumeSamplesPartial (const GU_Detail *gdp, const UT_ValArray< const GEO_Primitive * > &volumes, const UT_JobInfo &info) |
Protected Attributes | |
UT_VoxelArrayF * | myVoxels |
sdfImplicitType | myImplicitType |
UT_Vector3 | myImplicitNormal |
bool | myInvert |
fpreal | myOffset |
This defines how far we should shift the zero isosurface of the SDF. More... | |
UT_Vector3 | myOrig |
UT_Vector3 | mySize |
GEO_PrimVolumeXform | myHeightXform |
int | myHeightAxis |
UT_Vector3 | myVoxelSize |
This stores the size of a voxel along each axis. More... | |
fpreal | myVoxelDiameter |
This caches the diameter of a voxel cell. Ie, myVoxelSize.length() More... | |
UT_VoxelArray< int > * | myQueueIndices |
UT_ValArray< gu_sdf_qelem * > | myQueueElements |
UT_IntArray | myQueueFreeList |
gu_sdf_queue * | myQueue |
GU_SDF This class builds a signed distance function from a given GU_Detail. Signed distance functions contain an approximate distance to the original surface in each voxel cell. If cell is inside the the geometry, it has a negative distance. Sidedness of geometry is determined by surface normals. The geometry should be relatively watertight.
GU_SDF::GU_SDF | ( | ) |
|
virtual |
UT_Vector3 GU_SDF::advect | ( | const UT_Vector3 & | pos, |
fpreal | dist, | ||
fpreal | cfl_cond = 0.9f , |
||
bool | normalize_gradient = true |
||
) | const |
Advects a point according to the SDF's gradient field. Advection continues until the point has moved the given distance. If normalize_gradient is false, it is moved until the given amount of time has passed.
|
protected |
void GU_SDF::build | ( | const GU_Detail * | gdp, |
const GU_SDFParms & | parms | ||
) |
Build from the given gdp.
|
protected |
Builds a shell of distance values around the geometry based on minimum distance values. We want to fill in the cell values from (x,y,z) to (x+xw-1,y+yw-1,z+zw-1) inclusive. We only fill values that are within a band about the surface, leaving the rest for FMM. This is because min distance calls are expensive!
|
protected |
Builds a shell of distance values around the geometry from the point cloud data. If normals are present, they are used to calculate sidedness. Otherwise, the SDF becomes an unsigned distance-to-implicit surface.
|
protected |
Builds a shell of distance values around the given iso-contour of the volume. This allows one to then reinitialize an SDF function.
|
protected |
|
protected |
|
protected |
void GU_SDF::computeCenterOfMass | ( | UT_Vector3 & | centerofmass | ) | const |
Computes the center of mass of the SDF.
void GU_SDF::computeInertialTensor | ( | UT_DMatrix3 & | tensor, |
const UT_Vector3 & | centerofmass | ||
) | const |
Computes the inertial tensor. You provide the center of mass for it to use. Each sample point of the SDF is treated as a point mass. The mass is 0 for cell-points outside of the object, 1 for those fully inside, and suitably scaled for others.
fpreal GU_SDF::computeVolume | ( | ) | const |
Computes the volume of the SDF.
|
protected |
|
static |
Expands the given bounding box so it contains a two cell border on all sides. This helps condition the SDF stuff by ensuring the outer cells are all outside.
|
protected |
Performs a fast sweep along the given axis. Any voxel pair that has a bad consensus will be raytested & flipped. The flip is then propagated. dir is +/-1 to represent a forward or back sweep.
UT_Vector3 GU_SDF::findClosest | ( | const UT_Vector3 & | pos, |
fpreal | iso = 0.0 , |
||
fpreal | cfl_cond = 0.9 , |
||
fpreal | tol = 1e-3 |
||
) | const |
Returns the closest point on the iso surface to the given point. The Courant-Friedreichs-Lewy condition governs how carefully we step to find the solution. 0.9 is near optimal, 0.5 is conservative.
|
protected |
This finds consensus among the neighbours of this point It may then flip this points sign. If it does so, the point and it's neighbours are added to the list to be tested in the future. This uses myQueueIndices to track if a voxel has been added before. Returns 1 if a point flipped, 0 otherwise.
Calculates the distance to a cell by using the finalized distances to adjacent cells. The olddistance is used to determine sign.
|
protected |
Takes a list of GEO_Points and finds the best fititng plane which interpolates them. If noff is not -1, it will derive the normals from the point normals.
bool GU_SDF::findRayIntersection | ( | UT_Vector3T< FLOAT > & | result, |
const UT_Vector3T< FLOAT > & | a, | ||
const UT_Vector3T< FLOAT > & | b, | ||
fpreal | boundaryvalue = 0.0 |
||
) | const |
Returns the point along a path where it first intersects the SDF. If the path doesn't intersect the SDF, this function returns false. If the start of the path is inside the SDF, the function returns true, and returns the starting point of the path as the intersection.
bool GU_SDF::findSmallestOnEdge | ( | fpreal & | minvalue, |
UT_Vector3 & | result, | ||
const UT_Vector3 & | a, | ||
const UT_Vector3 & | b, | ||
fpreal | cutoff = SYS_FPREAL_MAX |
||
) | const |
Finds the smallest value in the SDF along the given line segment. The value must be smaller than the cutoff value. Returns false if no close value found.
bool GU_SDF::findSmallestOnTri | ( | fpreal & | minValue, |
UT_Vector2 & | resultBary, | ||
const UT_Vector3 & | p0, | ||
const UT_Vector3 & | p1, | ||
const UT_Vector3 & | p2, | ||
fpreal | cutoff = SYS_FPREAL_MAX |
||
) | const |
Finds the smallest value in the SDF inside the given triangle. The value must be smaller than the cutoff value. Returns false if no close value found.
Note: this algorithm is far from perfect. It does only a very partial scan over the interior of the triangle, and it doesn't work well with implicit box SDFs.
|
protected |
|
protected |
This fixes the sign of the distance field by finding a consensus among neighbouring voxels. This requires myQueueIndices to be present. If forcebounds is set, it will make the boundary all positive in sign, making it easier to recover from holes.
fpreal GU_SDF::getDistance | ( | const UT_Vector3 & | pos | ) | const |
Calculates the SDF field at the point.
Returns the divisions that the spaces is voxelized into. This is meaningful even for implicit surfaces, as they have a prefered division set for purposes like advection.
fpreal GU_SDF::getFastDistance | ( | const UT_Vector3 & | pos, |
fpreal & | tol | ||
) | const |
|
inline |
UT_Vector3 GU_SDF::getGradient | ( | const UT_Vector3 & | pos | ) | const |
Returns the gradient of the SDF at the point.
|
inline |
|
inline |
|
inline |
|
inline |
int64 GU_SDF::getMemoryUsage | ( | ) | const |
Returns the amount of memory used by this object.
|
inline |
These offset the zero isosurface of the SDF. This means that getDistance() will always return getDistance() - offset, effectively inflating (if offset is positive) or deflating (if offset is negative) the object.
Offsetting happens before inversion.
|
inline |
|
protected |
Gets or creates the qelement at the given location. Returns 0 if the element has already been processed.
|
inline |
|
inline |
void GU_SDF::initEmpty | ( | const UT_BoundingBox & | bbox, |
int | xres, | ||
int | yres, | ||
int | zres | ||
) |
Initializes an empty sdf of a given resolution and from a given bounding box.
|
inline |
|
inline |
These invert the sense of the SDF. This means the getDistance() function will always return -getDistance(), effectively turning the object inside out. This does not affect the calculation of volumes, etc! (Technically, an inverted SDF has infinite volume, which isn't all that useful anyways)
|
inlinestatic |
bool GU_SDF::load | ( | UT_IStream & | is | ) |
|
protected |
Propagate distances from all elements in the queue until maximum distance is reached.
|
protected |
Rasterizers...
|
protected |
|
protected |
This takes coordinates in cell space.
|
protected |
void GU_SDF::save | ( | std::ostream & | os | ) | const |
Load and save this SDF. This occurs in binary format.
|
protected |
This sends rays along all the major axes. The cell distances are set to the distance along the axes to surfaces.
This sets the given cell to a specific SDF value. This will be considered a finalized value, so it will be written to the output voxel array, any QElem will be deleted, and any neighbouring cells will get tentative values. Propagation to neighbouring cells only occurs if dist < maxdist, unless maxdist < 0
Sets a tentative value to a given cell.
void GU_SDF::setOrig | ( | const UT_Vector3 & | o | ) |
void GU_SDF::setSize | ( | const UT_Vector3 & | s | ) |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
If you change the weight of the qelem, this will update the queue.
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |