diff --git a/source/MRMesh/MRMesh.cpp b/source/MRMesh/MRMesh.cpp index 1ffbfa4800ac..3e3d083b2009 100644 --- a/source/MRMesh/MRMesh.cpp +++ b/source/MRMesh/MRMesh.cpp @@ -488,6 +488,14 @@ Vector3d Mesh::holeDirArea( EdgeId e0 ) const return 0.5 * sum; } +Vector3f Mesh::leftTangent( EdgeId e ) const +{ + assert( topology.left( e ) ); + const auto lNorm = leftNormal( e ); + const auto eDir = edgeVector( e ).normalized(); + return cross( lNorm, eDir ); +} + Vector3f Mesh::dirDblArea( VertId v ) const { Vector3f sum; diff --git a/source/MRMesh/MRMesh.h b/source/MRMesh/MRMesh.h index 9461a4a5b2ec..bfc97f4544c5 100644 --- a/source/MRMesh/MRMesh.h +++ b/source/MRMesh/MRMesh.h @@ -186,6 +186,9 @@ struct [[nodiscard]] Mesh /// if the hole is planar then returned vector is orthogonal to the plane pointing outside and its magnitude is equal to hole area [[nodiscard]] MRMESH_API Vector3d holeDirArea( EdgeId e ) const; + /// computes unit vector that is both orthogonal to given edge and to the normal of its left triangle, the vector is directed inside left triangle + [[nodiscard]] MRMESH_API Vector3f leftTangent( EdgeId e ) const; + /// computes triangular face normal from its vertices [[nodiscard]] Vector3f leftNormal( EdgeId e ) const { return leftDirDblArea( e ).normalized(); }