diff --git a/openvdb/openvdb/tools/LevelSetTubes.h b/openvdb/openvdb/tools/LevelSetTubes.h index b0af9ba6eb..fec1748530 100644 --- a/openvdb/openvdb/tools/LevelSetTubes.h +++ b/openvdb/openvdb/tools/LevelSetTubes.h @@ -5,7 +5,7 @@ /// /// @file LevelSetTubes.h /// -/// @brief Generate a narrow-band level set of a capsule, round cone, and tube complex. +/// @brief Generate a narrow-band level set of a capsule, tapered capsule, and tube complex. /// /// @note By definition a level set has a fixed narrow band width /// (the half width is defined by LEVEL_SET_HALF_WIDTH in Types.h), @@ -71,13 +71,13 @@ createLevelSetCapsule(const Vec3s& pt1, const Vec3s& pt2, float radius, float vo /// @brief Return a grid of type @c GridType containing a narrow-band level set -/// representation of a round cone (tube with sphere caps and different radii at both ends, +/// representation of a tapered capsule (tube with sphere caps and different radii at both ends, /// or equivalently the convex hull of two spheres with possibly different centers and radii). /// -/// @param pt1 First round cone endpoint in world units. -/// @param pt2 Second round cone endpoint in world units. -/// @param radius1 Radius of the round cone at @c pt1 in world units. -/// @param radius2 Radius of the round cone at @c pt2 in world units. +/// @param pt1 First tapered capsule endpoint in world units. +/// @param pt2 Second tapered capsule endpoint in world units. +/// @param radius1 Radius of the tapered capsule at @c pt1 in world units. +/// @param radius2 Radius of the tapered capsule at @c pt2 in world units. /// @param voxelSize Voxel size in world units. /// @param halfWidth Half the width of the narrow band, in voxel units. /// @param interrupter Interrupter adhering to the util::NullInterrupter interface. @@ -86,18 +86,18 @@ createLevelSetCapsule(const Vec3s& pt1, const Vec3s& pt2, float radius, float vo /// @note @c GridType::ValueType must be a floating-point scalar. template typename GridType::Ptr -createLevelSetRoundCone(const Vec3s& pt1, const Vec3s& pt2, float radius1, float radius2, +createLevelSetTaperedCapsule(const Vec3s& pt1, const Vec3s& pt2, float radius1, float radius2, float voxelSize, float halfWidth = float(LEVEL_SET_HALF_WIDTH), InterruptT* interrupter = nullptr, bool threaded = true); /// @brief Return a grid of type @c GridType containing a narrow-band level set -/// representation of a round cone (tube with sphere caps and different radii at both ends, +/// representation of a tapered capsule (tube with sphere caps and different radii at both ends, /// or equivalently the convex hull of two spheres with possibly different centers and radii). /// -/// @param pt1 First round cone endpoint in world units. -/// @param pt2 Second round cone endpoint in world units. -/// @param radius1 Radius of the round cone at @c pt1 in world units. -/// @param radius2 Radius of the round cone at @c pt2 in world units. +/// @param pt1 First tapered capsule endpoint in world units. +/// @param pt2 Second tapered capsule endpoint in world units. +/// @param radius1 Radius of the tapered capsule at @c pt1 in world units. +/// @param radius2 Radius of the tapered capsule at @c pt2 in world units. /// @param voxelSize Voxel size in world units. /// @param halfWidth Half the width of the narrow band, in voxel units. /// @param threaded If true multi-threading is enabled (true by default). @@ -105,7 +105,7 @@ createLevelSetRoundCone(const Vec3s& pt1, const Vec3s& pt2, float radius1, float /// @note @c GridType::ValueType must be a floating-point scalar. template typename GridType::Ptr -createLevelSetRoundCone(const Vec3s& pt1, const Vec3s& pt2, float radius1, float radius2, +createLevelSetTaperedCapsule(const Vec3s& pt1, const Vec3s& pt2, float radius1, float radius2, float voxelSize, float halfWidth = float(LEVEL_SET_HALF_WIDTH), bool threaded = true); /// @brief Different policies when creating a tube complex with varying radii @@ -114,7 +114,7 @@ createLevelSetRoundCone(const Vec3s& pt1, const Vec3s& pt2, float radius1, float ///
TUBE_VERTEX_RADII ///
Specify that the tube complex radii are per-vertex, /// meaning each tube has different radii at its two endpoints -/// and the complex is a collection of round cones. +/// and the complex is a collection of tapered capsules. /// ///
TUBE_SEGMENT_RADII ///
Specify that the tube complex radii are per-segment, @@ -576,14 +576,14 @@ class CapsuleVoxelizer /// @brief Class used to generate a grid of type @c GridType containing a narrow-band level set -/// representation of a round cone. +/// representation of a tapered capsule. /// /// @note @c GridType::ValueType must be a floating-point scalar. template -class RoundConeVoxelizer +class TaperedCapsuleVoxelizer : public ConvexVoxelizer< GridType, - RoundConeVoxelizer, + TaperedCapsuleVoxelizer, InterruptT> { using GridPtr = typename GridType::Ptr; @@ -593,7 +593,7 @@ class RoundConeVoxelizer using BaseT = ConvexVoxelizer< GridType, - RoundConeVoxelizer, + TaperedCapsuleVoxelizer, InterruptT >; @@ -604,7 +604,7 @@ class RoundConeVoxelizer friend class ConvexVoxelizer< GridType, - RoundConeVoxelizer, + TaperedCapsuleVoxelizer, InterruptT >; @@ -617,18 +617,18 @@ class RoundConeVoxelizer /// /// @note The voxel size and half width are determined from the input grid, /// meaning the voxel size and background value need to be set prior to voxelization - RoundConeVoxelizer(GridPtr& grid, const bool& threaded = true, + TaperedCapsuleVoxelizer(GridPtr& grid, const bool& threaded = true, InterruptT* interrupter = nullptr) : BaseT(grid, threaded, interrupter) { } - /// @brief Create a round cone + /// @brief Create a tapered capsule /// - /// @param pt1 first endpoint of the round cone in world units - /// @param pt2 second endpoint of the round cone in world units - /// @param radius1 radius of the round cone at @c pt1 in world units - /// @param radius2 radius of the round cone at @c pt2 in world units + /// @param pt1 first endpoint of the tapered capsule in world units + /// @param pt2 second endpoint of the tapered capsule in world units + /// @param radius1 radius of the tapered capsule at @c pt1 in world units + /// @param radius2 radius of the tapered capsule at @c pt2 in world units void operator()(const Vec3s& pt1, const Vec3s& pt2, const float& radius1, const float& radius2) { @@ -637,13 +637,13 @@ class RoundConeVoxelizer // ball if ((pt1 - pt2).lengthSqr() <= math::Pow2(radius1 - radius2)) { OPENVDB_THROW(RuntimeError, - "The round cone is degenerate, in this case it is a ball. Consider using the CapsuleVoxelizer class instead."); + "The tapered capsule is degenerate, in this case it is a ball. Consider using the CapsuleVoxelizer class instead."); } // tube if (math::Abs(radius1 - radius2) < 0.001f*BaseT::voxelSize()) { OPENVDB_THROW(RuntimeError, - "The round cone is degenerate, in this case it is a capsule. Consider using the CapsuleVoxelizer class instead."); + "The tapered capsule is degenerate, in this case it is a capsule. Consider using the CapsuleVoxelizer class instead."); } initialize(pt1, pt2, radius1, radius2); @@ -653,7 +653,8 @@ class RoundConeVoxelizer private: - inline void setXYRangeData(const Index& step = 1) override + inline void + setXYRangeData(const Index& step = 1) override { // short circuit when one circle is in the other if (mXYNorm2 <= mRdiff2) { @@ -690,7 +691,8 @@ class RoundConeVoxelizer } // https://en.wikipedia.org/wiki/Belt_problem#Pulley_problem - inline bool pullyPoints(Vec2s& p1t, Vec2s& p2t, Vec2s& p1b, Vec2s& p2b) const + inline bool + pullyPoints(Vec2s& p1t, Vec2s& p2t, Vec2s& p1b, Vec2s& p2b) const { const float diff = mXYNorm2 - mRdiff2; if (diff < 0.0f) @@ -710,7 +712,8 @@ class RoundConeVoxelizer return true; } - inline void setLineXYData(const Vec2s& q1, const Vec2s& q2, const float& step) + inline void + setLineXYData(const Vec2s& q1, const Vec2s& q2, const float& step) { if (math::Abs(q1.x() - q2.x()) < math::Tolerance::value()) { float x = tileCeil(q1.x(), step); @@ -734,7 +737,8 @@ class RoundConeVoxelizer } } - inline void setCircleXYData(const Vec2s& q1, const Vec2s& q2, + inline void + setCircleXYData(const Vec2s& q1, const Vec2s& q2, const float& step, const bool is_pt1) { const Vec3s &p1 = is_pt1 ? mPt1 : mPt2; @@ -753,7 +757,8 @@ class RoundConeVoxelizer } } - inline void setCircleHiXYData(const float& x1, const float& x2, + inline void + setCircleHiXYData(const float& x1, const float& x2, const float& step, const bool& is_pt1) { const float x_test = static_cast(math::Floor(0.5f*(x1+x2))); @@ -772,7 +777,8 @@ class RoundConeVoxelizer } } - inline void setCircleLoXYData(const float& x1, const float& x2, + inline void + setCircleLoXYData(const float& x1, const float& x2, const float& step, const bool& is_pt1) { const float x_test = static_cast(math::Floor(0.5f*(x1+x2))); @@ -793,7 +799,8 @@ class RoundConeVoxelizer // Round Cone: https://iquilezles.org/articles/distfunctions/ // distance in index space - inline ValueT signedDistance(const Vec3s& p) const + inline float + signedDistance(const Vec3s& p) const { const Vec3s w = p - mPt1; const ValueT y = w.dot(mV), @@ -812,12 +819,13 @@ class RoundConeVoxelizer return (math::Sqrt(x2*mA2*mInvVLenSqr) + y*mRdiff)*mInvVLenSqr - mRad1; } - inline bool tileCanFit(const Index& dim) const override + inline bool + tileCanFit(const Index& dim) const override { return math::Max(mRad1, mRad2) >= BaseT::halfWidth() + 0.70711f * (dim-1u); } - std::function roundConeBottomTop = + std::function TaperedCapsuleBottomTop = [this](float& zb, float& zt, const float& x, const float& y) { const Vec2s q(x, y); @@ -892,7 +900,8 @@ class RoundConeVoxelizer }; // https://www.geometrictools.com/Documentation/IntersectionLineCone.pdf - inline void openConeFrustumBottomTop(float& conezb, float& conezt, int& cint_cnt, + inline void + openConeFrustumBottomTop(float& conezb, float& conezt, int& cint_cnt, const float& x, const float& y) const { cint_cnt = 0; @@ -935,7 +944,8 @@ class RoundConeVoxelizer // ignore the c2 == c1 == 0 case, where the ray is on the boundary of the cone } - inline bool validFrustumRange(const double& t, const double& ddotdiff) const + inline bool + validFrustumRange(const double& t, const double& ddotdiff) const { const double h = ddotdiff - t * mConeD.z(); @@ -1059,12 +1069,12 @@ class RoundConeVoxelizer mC2 = math::Pow2(mConeD.z()) - mGamma; mC2Inv = mC2 != 0.0 ? 1.0/mC2 : 1.0; - BaseT::bottomTop = roundConeBottomTop; + BaseT::bottomTop = TaperedCapsuleBottomTop; } // ------------ private members ------------ - // round cone data -- populated via initialize() + // tapered capsule data -- populated via initialize() Vec3s mPt1, mPt2, mV; @@ -1079,14 +1089,14 @@ class RoundConeVoxelizer float mX1, mY1, mZ1, mX2, mY2, mZ2; -}; // class RoundConeVoxelizer +}; // class TaperedCapsuleVoxelizer /// @brief Class used to generate a grid of type @c GridType containing a narrow-band level set /// representation of a tube complex. /// /// @note @c GridType::ValueType must be a floating-point scalar. -/// @note Setting @c PerSegmentRadii to @c true gives a complex of capsules and a complex of round cones otherwise. +/// @note Setting @c PerSegmentRadii to @c true gives a complex of capsules and a complex of tapered capsules otherwise. template class TubeComplexVoxelizer { @@ -1246,7 +1256,7 @@ class TubeComplexVoxelizer { inline void perVertexRadiusVoxelize(const tbb::blocked_range& rng) { - RoundConeVoxelizer rc_voxelizer(mGrid, false); + TaperedCapsuleVoxelizer rc_voxelizer(mGrid, false); CapsuleVoxelizer c_voxelizer(mGrid, false); @@ -1390,7 +1400,7 @@ createLevelSetTubeComplex(const std::vector& vertices, const std::vector< using ValueT = typename GridType::ValueType; using CapsuleComplexVoxelizer = typename lvlset::TubeComplexVoxelizer; - using RoundConeComplexVoxelizer = typename lvlset::TubeComplexVoxelizer; + using TaperedCapsuleComplexVoxelizer = typename lvlset::TubeComplexVoxelizer; static_assert(std::is_floating_point::value, "createLevelSetTubeComplex must return a scalar grid"); @@ -1425,7 +1435,7 @@ createLevelSetTubeComplex(const std::vector& vertices, const std::vector< GridPtr tubegrid; if (vertices.size() == radii.size()) { - RoundConeComplexVoxelizer op(vertices, segments, radii, + TaperedCapsuleComplexVoxelizer op(vertices, segments, radii, voxelSize, background, interrupter); const tbb::blocked_range segmentRange(0, op.bucketSize()); @@ -1489,21 +1499,21 @@ createLevelSetCapsule(const Vec3s& pt1, const Vec3s& pt2, float radius, float vo } -// ------------ createLevelSetRoundCone ------------- // +// ------------ createLevelSetTaperedCapsule ------------- // template typename GridType::Ptr -createLevelSetRoundCone(const Vec3s& pt1, const Vec3s& pt2, float radius1, float radius2, +createLevelSetTaperedCapsule(const Vec3s& pt1, const Vec3s& pt2, float radius1, float radius2, float voxelSize, float halfWidth, InterruptT* interrupter, bool threaded) { using GridPtr = typename GridType::Ptr; using ValueT = typename GridType::ValueType; using CapsuleVoxelizer = typename lvlset::CapsuleVoxelizer; - using RoundConeVoxelizer = typename lvlset::RoundConeVoxelizer; + using TaperedCapsuleVoxelizer = typename lvlset::TaperedCapsuleVoxelizer; static_assert(std::is_floating_point::value, - "createLevelSetRoundCone must return a scalar grid"); + "createLevelSetTaperedCapsule must return a scalar grid"); if (voxelSize <= 0) OPENVDB_THROW(ValueError, "voxel size must be positive"); if (halfWidth <= 0) OPENVDB_THROW(ValueError, "half-width must be positive"); @@ -1528,9 +1538,9 @@ createLevelSetRoundCone(const Vec3s& pt1, const Vec3s& pt2, float radius1, float CapsuleVoxelizer voxelizer(grid, threaded, interrupter); voxelizer(pt1, pt2, radius1); - } else { // round cone + } else { // tapered capsule - RoundConeVoxelizer voxelizer(grid, threaded, interrupter); + TaperedCapsuleVoxelizer voxelizer(grid, threaded, interrupter); voxelizer(pt1, pt2, radius1, radius2); } @@ -1539,10 +1549,10 @@ createLevelSetRoundCone(const Vec3s& pt1, const Vec3s& pt2, float radius1, float template typename GridType::Ptr -createLevelSetRoundCone(const Vec3s& pt1, const Vec3s& pt2, float radius1, float radius2, +createLevelSetTaperedCapsule(const Vec3s& pt1, const Vec3s& pt2, float radius1, float radius2, float voxelSize, float halfWidth, bool threaded) { - return createLevelSetRoundCone( + return createLevelSetTaperedCapsule( pt1, pt2, radius1, radius2, voxelSize, halfWidth, nullptr, threaded); } @@ -1578,7 +1588,7 @@ OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION) #undef _FUNCTION #define _FUNCTION(TreeT) \ - Grid::Ptr createLevelSetRoundCone>(const Vec3s&, const Vec3s&, \ + Grid::Ptr createLevelSetTaperedCapsule>(const Vec3s&, const Vec3s&, \ float, float, float, float, util::NullInterrupter*, bool) OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION) #undef _FUNCTION