21 #ifndef __UT_TriangleMesh__
22 #define __UT_TriangleMesh__
91 bool reindex_points =
false,
96 {
return int(myVertexPoint.size()) / 3; }
100 {
return int(myPointVertex.size()); }
111 {
return 3 * t +
j % 3; }
116 {
return triangleHedge(t,
j); }
125 {
return hedgeTriangle(v); }
130 {
return myVertexPoint(3 * t +
j % 3); }
137 {
return (h % 3 == 2) ? h - 2 : h + 1; }
141 {
return (h % 3 == 0) ? h + 2 : h - 1; }
144 int onext(
int h)
const {
return sym(lprev(h)); }
148 {
return myVertexPoint(v); }
160 {
return myVertexPoint(apxVertex(h)); }
166 int lprev(
int h)
const {
return apxVertex(h); }
169 int sym(
int h)
const {
return myHedgeSym(h); }
187 {
return int(myBoundaryRepHedges.size()); }
192 {
return myBoundaryRepHedges(comp); }
198 {
return -
SYSmin(0, sym(h)) - 1; }
204 {
return myNumInteriorHedges; }
207 {
return numHedges() - numInteriorHedges(); }
210 {
return numBoundaryHedges(); }
213 {
return numPoints() - numBoundaryPoints(); }
216 {
return numBoundaryHedges()
217 + numInteriorHedges() / 2; }
220 {
return numPoints() + numTriangles()
230 int myNumInteriorHedges = 0;
237 template <
typename E>
251 {
return myEmbedding->pointPosition(pt); }
254 { myEmbedding = ptpos; }
257 {
return myEmbedding !=
nullptr; }
283 template <
typename T>
288 template <
typename F,
typename A>
291 const A &pt_atlas)
const;
296 template <
typename F>
302 template <
typename F>
355 auto pointNormal(
int p,
bool area_weighted =
false)
const;
397 const E *myEmbedding =
nullptr;
400 template <
typename E>
404 return (pointPosition(trianglePoint(t, 0))
405 + pointPosition(trianglePoint(t, 1))
406 + pointPosition(trianglePoint(t, 2))) / 3.0;
409 template <
typename E>
413 auto a = pointPosition(trianglePoint(t, 0));
414 auto b = pointPosition(trianglePoint(t, 1));
415 auto c = pointPosition(trianglePoint(t, 2));
424 template <
typename E>
425 template <
typename T>
429 auto a = pointPosition(trianglePoint(t, 0));
430 auto b = pointPosition(trianglePoint(t, 1));
431 auto c = pointPosition(trianglePoint(t, 2));
434 auto areax2 = nml.normalize();
437 + f1 *
cross(nml,
a -
c)) / areax2;
440 template <
typename E>
441 template <
typename F>
448 for (
int i = 0; i < 3; i++)
450 auto h = triangleHedge(t, i);
455 auto t_sym = hedgeTriangle(h_sym);
456 auto f_sym = tri_fn(t_sym);
459 auto wt = 1.0 / (hedgeCotan(
h) + hedgeCotan(h_sym));
460 res += (f_sym -
f) * wt;
469 template <
typename E>
470 template <
typename F>
477 auto ring_area = 0.0;
479 auto h0 = pointHedge(p);
485 auto cot = hedgeCotan(
h);
489 cot += hedgeCotan(h_sym);
493 res += cot * (f_dst -
f);
494 ring_area += triangleArea(hedgeTriangle(
h));
495 }
while (
h = onext(
h),
h >= 0 &&
h != h0);
499 h_sym = h_sym >= 0 ? lprev(sym(h_sym)) : lprev(h0);
500 auto cot = hedgeCotan(h_sym);
501 auto f_dst = pt_fn(
srcPoint(h_sym));
502 res += cot * (f_dst -
f);
508 template <
typename E>
509 template <
typename F,
typename A>
512 const A &pt_atlas)
const
514 auto hedge_contribution = [&](
int h)
517 auto t = hedgeTriangle(
h);
519 auto c = hedgeCotan(
h);
520 auto h_z = pt_atlas.hedgeComplexCoord(
h);
521 auto z =
s *
c * h_z * i;
526 auto t_sym = hedgeTriangle(h_sym);
527 auto s_sym = tri_fn(t_sym);
528 z -= s_sym *
c * h_z * i;
535 auto h0 = pointHedge(p);
539 z += hedge_contribution(
h);
540 }
while (
h = onext(
h),
h >= 0 &&
h != h0);
542 return pt_atlas.extrinsicPointTangent(p, z) / pointDualArea(p);
545 template <
typename E>
552 template <
typename E>
556 auto cotsum = hedgeCotan(h);
559 cotsum += hedgeCotan(h_sym);
561 return 0.5 * hedgeLength(h) * cotsum;
564 template <
typename E>
572 auto n0 = triangleNormal(hedgeTriangle(h));
573 auto n1 = triangleNormal(hedgeTriangle(h_sym));
574 auto e = hedgeVector(h);
576 return SYSatan(
dot(e,
cross(n0, n1)),
dot(n0, n1));
579 template <
typename E>
583 auto a = pointPosition(
dstPoint(lnext(h)));
593 template <
typename E>
597 auto h = pointHedge(p);
599 auto sum = triangleArea(hedgeTriangle(
h));
601 while (
h = onext(
h),
h >= 0 &&
h != h0)
602 sum += triangleArea(hedgeTriangle(
h));
604 return sum /
Real(3.0);
607 template <
typename E>
611 auto h = pointHedge(p);
613 auto sum = hedgeAngle(lnext(
h));
615 while (
h = onext(
h),
h >= 0 &&
h != h0)
616 sum += hedgeAngle(lnext(
h));
621 template <
typename E>
625 auto h = pointHedge(p);
630 auto nml = triangleNormal(hedgeTriangle(
h),
false);
631 while (
h = onext(
h),
h >= 0 &&
h != h0)
632 nml += triangleNormal(hedgeTriangle(
h),
false);
638 auto nml = triangleNormal(hedgeTriangle(
h)) * hedgeAngle(lnext(
h));
639 while (
h = onext(
h),
h >= 0 &&
h != h0)
640 nml += triangleNormal(hedgeTriangle(
h)) * hedgeAngle(lnext(
h));
646 template <
typename E>
654 template <
typename E>
658 auto h0 = pointHedge(p);
663 b += hedgeLength(
h) * hedgeDihedralAngle(
h);
664 }
while (
h = onext(
h),
h >= 0 &&
h != h0);
665 return Real(0.25) *
b;
668 template <
typename E>
673 for (
int i = 0; i < 3; i++)
675 int h = triangleHedge(t, i);
677 auto a = hedgeAngle(h);
678 K += (isBoundaryPoint(p) ? 1 : 2) *
M_PI *
a / pointAngleSum(p);
684 template <
typename E>
689 for (
int i = 0; i < 3; i++)
691 auto h = triangleHedge(t, i);
692 H += 0.25 * hedgeLength(
h) * hedgeDihedralAngle(
h);
702 auto partial_angle_sum =
Real(0.0);
704 for (
int i = 0; i < 3; i++)
706 auto h = triangleHedge(t, i);
707 auto l = hedgeLength(
h);
708 auto alpha = hedgeDihedralAngle(
h);
710 auto theta = partial_angle_sum;
713 Complex r(SYScos(2.0 * theta), SYSsin(2.0 * theta));
716 partial_angle_sum += (
M_PI - hedgeAngle(lprev(
h)));
734 auto n = triangleNormal(t);
735 auto x = hedgeVector(triangleHedge(t, 0));
739 return x * SYScos(angular) + Jx * SYSsin(angular);
749 template <
typename M>
764 {
return myPointScale(p); }
787 {
return myMesh.hedgeLength(h); }
848 for (
int p = range.begin(), pe = range.end(); p != pe; p++)
850 auto h0 = mesh.pointHedge(p);
861 angle_sum += mesh.hedgeAngle(mesh.lnext(
h));
862 myHedgeAngle(
h) = angle_sum;
863 }
while (
h = mesh.onext(
h),
h >= 0 &&
h != h0);
864 myPointScale(p) = 2 *
M_PI / angle_sum;
873 if (h == myMesh.pointHedge(myMesh.srcPoint(h)))
876 return myHedgeAngle(myMesh.lnext(myMesh.sym(h)));
883 auto a = hedgeAngularCoord(h);
884 return radialCoord(h) *
Complex(SYScos(
a), SYSsin(
a));
891 auto a = hedgeAngularCoord(h);
913 angle /= pointAngleScale(p);
915 auto h0 = myMesh.pointHedge(p);
920 if (myHedgeAngle(
h) > angle)
923 }
while (
h = myMesh.onext(
h),
h >= 0 &&
h != h0);
937 auto h = angularLowerBoundHedge(p, angular);
938 auto n = myMesh.triangleNormal(myMesh.hedgeTriangle(
h));
939 auto a = (angular - hedgeAngularCoord(
h)) / pointAngleScale(p);
941 auto v = myMesh.hedgeVector(
h);
958 return extrinsicPointTangent(p, complexToRadial(z), complexToAngular(z));
966 auto h0 = myMesh.pointHedge(p);
970 auto l = myMesh.hedgeLength(
h);
971 auto alpha = myMesh.hedgeDihedralAngle(
h);
972 z += l *
alpha * hedgeComplexDirection(
h, 2);
973 }
while (
h = myMesh.onext(
h),
h >= 0 &&
h != h0);
SYS_FORCE_INLINE int lnext(int h) const
SYS_FORCE_INLINE int apxVertex(int h) const
SYS_FORCE_INLINE int boundaryHedge(int comp) const
SYS_FORCE_INLINE int vertexPoint(int v) const
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
SYS_FORCE_INLINE GA_Offset srcPoint(const GA_Detail *gdp, GEO_Hedge h)
SYS_FORCE_INLINE auto pointNormal(int p, bool area_weighted=false) const
void UTparallelFor(const Range &range, const Body &body, const int subscribe_ratio=2, const int min_grain_size=1, const bool force_use_task_scope=true)
typename std::complex< Real > Complex
UT_PointAtlas(const M &mesh)
auto triangleLaplacian(int t, const F &tri_fn) const
SYS_FORCE_INLINE auto hedgeDihedralAngle(int h) const
SYS_FORCE_INLINE int triangleVertex(int t, int j=0) const
SIM_API const UT_StringHolder angle
SYS_FORCE_INLINE int pointVertex(int p) const
typename M::Vector3 Vector3
SYS_FORCE_INLINE Real hedgeAngularOffset(int h) const
SYS_FORCE_INLINE Real pointAngleScale(int p) const
SYS_FORCE_INLINE auto pointAngleSum(int p) const
SYS_FORCE_INLINE Complex hedgeComplexDirection(int h, int n=1) const
SYS_FORCE_INLINE int srcVertex(int h) const
void setSizeNoInit(exint newsize)
Vector3 pointGradient(int p, const F &tri_fn, const A &pt_atlas) const
vfloat4 sqrt(const vfloat4 &a)
GLdouble GLdouble GLdouble z
int numInteriorPoints() const
GA_Offset srcVertex(GEO_Hedge)
GLboolean GLboolean GLboolean GLboolean a
SYS_FORCE_INLINE int numTriangles() const
GLdouble GLdouble GLdouble q
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
SYS_FORCE_INLINE auto hedgeLength(int h) const
int numBoundaryPoints() const
SYS_FORCE_INLINE int hedgeTriangle(int h) const
Vector3 extrinsicPointTangent(int p, Real radial, Real angular) const
SYS_FORCE_INLINE int numPoints() const
SYS_FORCE_INLINE Real radialCoord(int h) const
void setMeshPointPositions(const E *ptpos)
SYS_FORCE_INLINE int apxPoint(int h) const
auto pointLaplacian(int p, const F &pt_fn) const
void updateFromAngleAxis(T angle, const UT_Vector3T< T > &axis, int normalize=1)
SIM_DerScalar length() const
typename PointCoords::value_type Real
SYS_FORCE_INLINE int numVertices() const
SYS_FORCE_INLINE int numBoundaries() const
int angularLowerBoundHedge(int p, Real angle) const
SYS_FORCE_INLINE Complex hedgeComplexCoord(int h) const
SYS_FORCE_INLINE auto pointGaussCurvature(int p) const
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
SYS_FORCE_INLINE Complex pointMaxPrincipalDirection(int p) const
UT_EmbeddedTriangleMesh()=default
Vector3 extrinsicTriangleTangent(int p, Real radial, Real angular) const
SYS_FORCE_INLINE bool isBoundaryPoint(int p) const
STATIC_INLINE uint64_t H(uint64_t x, uint64_t y, uint64_t mul, int r)
GLfloat GLfloat GLfloat alpha
SYS_FORCE_INLINE Real complexToRadial(Complex z) const
SYS_FORCE_INLINE int sym(int h) const
SYS_API fpreal32 SYSfloor(fpreal32 val)
SYS_FORCE_INLINE int lprev(int h) const
GLboolean GLboolean GLboolean b
SYS_FORCE_INLINE auto hedgeAngle(int h) const
typename GU_TriangleMeshDetailLinkT< T >::value_type PointCoords
int numBoundaryHedges() const
SYS_FORCE_INLINE GA_Offset dstVertex(T &iface, GEO_Hedge h)
SYS_FORCE_INLINE Real hedgeAngularCoord(int h) const
SYS_FORCE_INLINE auto triangleArea(int t) const
SYS_FORCE_INLINE int onext(int h) const
int eulerCharacteristic() const
auto triangleGradient(int t, T f0, T f1, T f2) const
SYS_FORCE_INLINE auto triangleMeanCurvature(int t) const
GLfloat GLfloat GLfloat GLfloat h
SYS_FORCE_INLINE auto pointPosition(int pt) const
SYS_FORCE_INLINE int dstPoint(int h) const
SYS_FORCE_INLINE Complex triangleMaxPrincipalDirection(int t) const
SYS_FORCE_INLINE int numHedges() const
SYS_FORCE_INLINE auto pointMeanCurvature(int p) const
SYS_FORCE_INLINE int triangleHedge(int t, int j=0) const
SYS_FORCE_INLINE bool isBoundaryHedge(int h) const
SYS_FORCE_INLINE auto triangleGaussCurvature(int t) const
SYS_FORCE_INLINE int vertexTriangle(int v) const
SYS_FORCE_INLINE int pointHedge(int p) const
typename M::Complex Complex
SYS_FORCE_INLINE Real complexToAngular(Complex z) const
SYS_FORCE_INLINE auto triangleNormal(int t, bool normalize=true) const
bool hasEmbedding() const
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
SYS_FORCE_INLINE int dstVertex(int h) const
SYS_FORCE_INLINE auto dualHedgeLength(int h) const
SYS_FORCE_INLINE auto triangleBarycenter(int t) const
SYS_FORCE_INLINE auto pointDualArea(int p) const
UT_Vector3T< T > rotate(const UT_Vector3T< T > &) const
SYS_FORCE_INLINE auto hedgeVector(int h) const
int numInteriorHedges() const
SYS_FORCE_INLINE int hedgeBoundary(int h) const
SYS_FORCE_INLINE int trianglePoint(int t, int j=0) const
SYS_FORCE_INLINE auto hedgeCotan(int h) const
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)
constexpr T normalize(UT_FixedVector< T, D > &a) noexcept
SYS_FORCE_INLINE int srcPoint(int h) const
SYS_FORCE_INLINE GA_Offset dstPoint(T &iface, GEO_Hedge h)
SYS_FORCE_INLINE bool isBoundaryHedge(T &iface, GEO_Hedge h)