From df6198ac81e2cacab1ef2680528b9f4d6d8d3b8f Mon Sep 17 00:00:00 2001 From: erik pernod Date: Fri, 12 Apr 2024 14:32:42 +0200 Subject: [PATCH] [Geometry] Update method intersectionWithEdge signature and redirect all methods to it in EdgeSetGeometryAlgorithms (#4194) * [Geometry] Update method signature of intersectionWithEdge to pass barycentric coordinates instead of 3D coord. * [Topology.Container] Update all method compute2EdgesIntersection to use the generic method in Edge class * Apply suggestions from code review Co-authored-by: Frederick Roy * Update EdgeSetGeometryAlgorithms.inl * Update EdgeSetGeometryAlgorithms.inl * fix sofacuda * Fix snapping error * Fix incision test output values * Update Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --------- Co-authored-by: Frederick Roy Co-authored-by: Frederick Roy Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- .../dynamic/EdgeSetGeometryAlgorithms.h | 17 ++- .../dynamic/EdgeSetGeometryAlgorithms.inl | 139 ++++++------------ .../dynamic/TriangleSetGeometryAlgorithms.inl | 12 +- .../tests/TopologicalChangeProcessor_test.cpp | 6 +- .../Geometry/src/sofa/geometry/Edge.h | 16 +- Sofa/framework/Geometry/test/Edge_test.cpp | 78 ++++++---- .../Dynamic/IncisionTrianglesProcess.scn | 1 + 7 files changed, 124 insertions(+), 145 deletions(-) diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h index 846c1a278c3..1cf6908495b 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h @@ -130,11 +130,19 @@ class EdgeSetGeometryAlgorithms : public PointSetGeometryAlgorithms /** \brief Compute the intersection coordinate of the 2 input straight lines. Lines vector director are computed using coord given in input. * @param edge1 tab Coord[2] from the 2 vertices composing first edge * @param edge2 same for second edge - * @param intersected bool default value true, changed as false if no intersection is done. + * @param intersected bool set to true if intersection otherwise false. * @return Coord of intersection point, 0 if no intersection. */ Coord compute2EdgesIntersection (const Coord edge1[2], const Coord edge2[2], bool& intersected); + /** \brief Compute the intersection coordinate of an Edge from the topology and a segment defined by 2 points [a, b]. + * @param edgeID index of the first edge + * @param segment defined by 2 points [a, b] + * @param intersected bool set to true if intersection otherwise false. + * @return Coord of intersection point, 0 if no intersection. + */ + Coord computeEdgeSegmentIntersection(const EdgeID edgeID, const type::Vec3& a, const type::Vec3& b, bool& intersected); + bool computeEdgePlaneIntersection (EdgeID edgeID, sofa::type::Vec<3,Real> pointOnPlane, sofa::type::Vec<3,Real> normalOfPlane, sofa::type::Vec<3,Real>& intersection); bool computeRestEdgePlaneIntersection (EdgeID edgeID, sofa::type::Vec<3,Real> pointOnPlane, sofa::type::Vec<3,Real> normalOfPlane, sofa::type::Vec<3,Real>& intersection); @@ -160,10 +168,9 @@ class EdgeSetGeometryAlgorithms : public PointSetGeometryAlgorithms /** return a pointer to the container of cubature points */ NumericalIntegrationDescriptor &getEdgeNumericalIntegrationDescriptor(); - bool computeEdgeSegmentIntersection(EdgeID edgeID, - const sofa::type::Vec<3,Real>& a, - const sofa::type::Vec<3, Real>& b, - Real &baryCoef); + + SOFA_ATTRIBUTE_DEPRECATED("v24.06", "v24.12", "Use the method computeEdgeSegmentIntersection returning a Coord") + bool computeEdgeSegmentIntersection(EdgeID edgeID, const type::Vec3& a, const type::Vec3& b, Real &baryCoef); // compute barycentric coefficients diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl index 3514eb50933..89a18b5d13e 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl @@ -246,6 +246,7 @@ void EdgeSetGeometryAlgorithms< DataTypes >::defineEdgeCubaturePoints() { } edgeNumericalIntegration.addQuadratureMethod(m,10,qpa); } + template< class DataTypes> typename DataTypes::Real EdgeSetGeometryAlgorithms< DataTypes >::computeEdgeLength( const EdgeID i) const { @@ -438,9 +439,13 @@ auto EdgeSetGeometryAlgorithms::computePointProjectionOnEdge (const E // Compute Coord of projection point H: Coord coord_H = compute2EdgesIntersection ( coord_edge1, coord_edge2, intersected); - sofa::type::Vec<3, Real> h; DataTypes::get(h[0], h[1], h[2], coord_H); - - return computeEdgeBarycentricCoordinates(h, theEdge[0], theEdge[1]); + if (intersected) + { + sofa::type::Vec<3, Real> h; DataTypes::get(h[0], h[1], h[2], coord_H); + return computeEdgeBarycentricCoordinates(h, theEdge[0], theEdge[1]); + } + else + return sofa::type::vector< SReal >(); } template @@ -493,73 +498,43 @@ bool EdgeSetGeometryAlgorithms::computeRestEdgePlaneIntersection (Edg } + template typename DataTypes::Coord EdgeSetGeometryAlgorithms::compute2EdgesIntersection (const Coord edge1[2], const Coord edge2[2], bool& intersected) { + auto a0 = type::Vec3(DataTypes::getCPos(edge1[0])); + auto a1 = type::Vec3(DataTypes::getCPos(edge1[1])); + auto b0 = type::Vec3(DataTypes::getCPos(edge2[0])); + auto b1 = type::Vec3(DataTypes::getCPos(edge2[1])); - // Creating director vectors: - Coord vec1 = edge1[1] - edge1[0]; - Coord vec2 = edge2[1] - edge2[0]; - Coord X; - for (unsigned int i=0; i(0.0001); - Real lambda = 0.0; - Real alpha = 0.0; - - // Searching vector composante not null: - for (unsigned int i=0; i epsilon) || (vec1[i] < -epsilon) ) - { - ind1 = i; - - for (unsigned int j = 0; j epsilon || vec2[j] < -epsilon) && (j != i)) - { - ind2 = j; + type::Vec2 baryCoords(type::NOINIT); + intersected = sofa::geometry::Edge::intersectionWithEdge(a0, a1, b0, b1, baryCoords); - // Solving system: - Real coef_lambda = vec1[ind1] - ( vec1[ind2]*vec2[ind1]/vec2[ind2] ); + type::vector< Coord > ancestors = {edge1[0], edge1[1]}; + type::vector< Real > coefs = { static_cast(baryCoords[0]), static_cast(baryCoords[1])}; - if (coef_lambda < epsilon && coef_lambda > -epsilon) - break; - - lambda = ( edge2[0][ind1] - edge1[0][ind1] + (edge1[0][ind2] - edge2[0][ind2])*vec2[ind1]/vec2[ind2]) * 1/coef_lambda; - alpha = (edge1[0][ind2] + lambda * vec1[ind2] - edge2[0][ind2]) * 1 /vec2[ind2]; - break; - } - } + return DataTypes::interpolate(ancestors, coefs); +} - if (lambda != 0.0) - break; - } - if ((ind1 == -1) || (ind2 == -1)) - { - msg_error() << "Vector director is null." ; - intersected = false; - return X; - } +template +typename DataTypes::Coord EdgeSetGeometryAlgorithms::computeEdgeSegmentIntersection(const EdgeID edgeID, const type::Vec3& a, const type::Vec3& b, bool& intersected) +{ + const Edge& theEdge = this->m_topology->getEdge(edgeID); + const VecCoord& pos = (this->object->read(core::ConstVecCoordId::position())->getValue()); - // Compute X coords: - for (unsigned int i = 0; i 0.1 ) - { - msg_error() << "Edges don't intersect themself." ; - intersected = false; - } + type::vector< Coord > ancestors = {e0, e1}; + type::vector< Real > coefs = { static_cast(baryCoords[0]), static_cast(baryCoords[1]) }; - return X; + return DataTypes::interpolate(ancestors, coefs); } @@ -770,44 +745,22 @@ void EdgeSetGeometryAlgorithms::initPointAdded(PointID index, const c template bool EdgeSetGeometryAlgorithms::computeEdgeSegmentIntersection(EdgeID edgeID, - const sofa::type::Vec<3, Real>& a, - const sofa::type::Vec<3, Real>& b, + const type::Vec3& a, + const type::Vec3& b, Real &baryCoef) { - bool is_intersect = false; - - const Edge& e = this->m_topology->getEdge(edgeID); - const VecCoord& p = (this->object->read(core::ConstVecCoordId::position())->getValue()); - const typename DataTypes::Coord& c0 = p[e[0]]; - const typename DataTypes::Coord& c1 = p[e[1]]; - - sofa::type::Vec<3, Real> p0{ c0[0],c0[1],c0[2] }; - sofa::type::Vec<3, Real> p1{ c1[0],c1[1],c1[2] }; - sofa::type::Vec<3, Real> pa{ a[0],a[1],a[2] }; - sofa::type::Vec<3, Real> pb{ b[0],b[1],b[2] }; - - sofa::type::Vec<3, Real> v_0a = p0 - pa; - sofa::type::Vec<3, Real> v_ba = pb - pa; - sofa::type::Vec<3, Real> v_10 = p1 - p0; - - Real d0aba, dba10, d0a10, dbaba, d1010; - - d0aba = v_0a * v_ba; - dba10 = v_ba * v_ba; - d0a10 = v_0a * v_10; - dbaba = v_ba * v_ba; - d1010 = v_10 * v_10; - - Real deno, num; - deno = d1010 * dbaba - dba10 * dba10; - - if (abs(deno) > std::numeric_limits::epsilon()) - { - num = d0aba * dba10 - d0a10 * dbaba; + const Edge& theEdge = this->m_topology->getEdge(edgeID); + const VecCoord& pos = (this->object->read(core::ConstVecCoordId::position())->getValue()); + + const typename DataTypes::Coord& e0 = pos[theEdge[0]]; + const typename DataTypes::Coord& e1 = pos[theEdge[1]]; + auto p0 = type::Vec3(DataTypes::getCPos(e0)); + auto p1 = type::Vec3(DataTypes::getCPos(e1)); + + type::Vec2 baryCoords(type::NOINIT); + bool is_intersect = sofa::geometry::Edge::intersectionWithEdge(p0, p1, a, b, baryCoords); + baryCoef = baryCoords[0]; - baryCoef = num / deno; - is_intersect = true; - } return is_intersect; } diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl index 55282af87de..abec1b27a3b 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl @@ -4428,8 +4428,10 @@ void TriangleSetGeometryAlgorithms::SnapBorderPath(PointID pa, Coord& auto new_coord = this->computePointProjectionOnEdge(theEdge, thePoint, intersected); - if (!intersected) - msg_error() << "Orthogonal projection failed"; + if (!intersected){ + // Orthogonal projection failed, not possible to snap this point on the ith edge of the triangle + continue; + } topoPath_list[0] = geometry::ElementType::EDGE; @@ -4532,8 +4534,10 @@ void TriangleSetGeometryAlgorithms::SnapBorderPath(PointID pa, Coord& DataTypes::get(thePoint[0], thePoint[1], thePoint[2], b); auto new_coord = this->computePointProjectionOnEdge(theEdge, thePoint, intersected); - if (!intersected) - msg_error() << "Orthogonal projection failed"; + if (!intersected){ + // Orthogonal projection failed, not possible to snap this point on the ith edge of the triangle + continue; + } topoPath_list.back() = geometry::ElementType::EDGE; indices_list.back() = theEdge; diff --git a/Sofa/Component/Topology/Utility/tests/TopologicalChangeProcessor_test.cpp b/Sofa/Component/Topology/Utility/tests/TopologicalChangeProcessor_test.cpp index b02464692fc..2114477f075 100644 --- a/Sofa/Component/Topology/Utility/tests/TopologicalChangeProcessor_test.cpp +++ b/Sofa/Component/Topology/Utility/tests/TopologicalChangeProcessor_test.cpp @@ -121,9 +121,9 @@ struct InciseProcessor_test : TopologicalChangeProcessor_test m_instance.simulate(0.05); } - EXPECT_EQ(topoCon->getNbTriangles(), 1677); - EXPECT_EQ(topoCon->getNbEdges(), 2704); - EXPECT_EQ(topoCon->getNbPoints(), 1026); + EXPECT_EQ(topoCon->getNbTriangles(), 1648); + EXPECT_EQ(topoCon->getNbEdges(), 2646); + EXPECT_EQ(topoCon->getNbPoints(), 997); return true; } diff --git a/Sofa/framework/Geometry/src/sofa/geometry/Edge.h b/Sofa/framework/Geometry/src/sofa/geometry/Edge.h index eae2636787a..f23618e9eab 100644 --- a/Sofa/framework/Geometry/src/sofa/geometry/Edge.h +++ b/Sofa/framework/Geometry/src/sofa/geometry/Edge.h @@ -216,7 +216,7 @@ struct Edge * @tparam T scalar * @param pA, pB nodes of the first edge * @param pC, pD nodes of the second edge - * @param intersection node will be filled if there is an intersection otherwise will return std::numeric_limits::min() + * @param intersectionBaryCoord barycentric coordinates of the intersection point expressed as alpa * pA + beta * pB if there is an intersection , node will be filled if there is an intersection otherwise will return [0, 0] * @return bool true if there is an intersection, otherwise false */ template> > [[nodiscard]] - static constexpr bool intersectionWithEdge(const Node& pA, const Node& pB, const Node& pC, const Node& pD, Node& intersection) + static constexpr bool intersectionWithEdge(const Node& pA, const Node& pB, const Node& pC, const Node& pD, sofa::type::Vec<2, T>& intersectionBaryCoord) { // The 2 segment equations using pX on edge1 and pY on edge2 can be defined by: // pX = pA + alpha (pB - pA) @@ -243,7 +243,7 @@ struct Edge if (alphaDenom < std::numeric_limits::epsilon()) // collinear { - intersection = sofa::type::Vec<2, T>(std::numeric_limits::min(), std::numeric_limits::min()); + intersectionBaryCoord = sofa::type::Vec<2, T>(0, 0); return false; } @@ -251,12 +251,12 @@ struct Edge if (alpha < 0 || alpha > 1) { - intersection = sofa::type::Vec<2, T>(std::numeric_limits::min(), std::numeric_limits::min()); + intersectionBaryCoord = sofa::type::Vec<2, T>(0, 0); return false; } else { - intersection = pA + alpha * AB; + intersectionBaryCoord = sofa::type::Vec<2, T>(1-alpha, alpha); return true; } } @@ -286,7 +286,7 @@ struct Edge if (alphaDenom < std::numeric_limits::epsilon()) // alpha == inf, not sure what it means geometrically, colinear? { - intersection = sofa::type::Vec<3, T>(std::numeric_limits::min(), std::numeric_limits::min(), std::numeric_limits::min()); + intersectionBaryCoord = sofa::type::Vec<2, T>(0, 0); return false; } @@ -300,12 +300,12 @@ struct Edge || alpha > 1 || beta > 1 // if alpha > 1 means intersection but after outside from [AB] || (pY - pX).norm2() > EQUALITY_THRESHOLD ) // if pY and pX are not se same means no intersection. { - intersection = sofa::type::Vec<3, T>(std::numeric_limits::min(), std::numeric_limits::min(), std::numeric_limits::min()); + intersectionBaryCoord = sofa::type::Vec<2, T>(0, 0); return false; } else { - intersection = pX; + intersectionBaryCoord = sofa::type::Vec<2, T>(1-alpha, alpha); return true; } } diff --git a/Sofa/framework/Geometry/test/Edge_test.cpp b/Sofa/framework/Geometry/test/Edge_test.cpp index 27831dec74e..50ec5a2c3ca 100644 --- a/Sofa/framework/Geometry/test/Edge_test.cpp +++ b/Sofa/framework/Geometry/test/Edge_test.cpp @@ -321,51 +321,58 @@ TEST(GeometryEdge_test, intersectionWithEdge2f) const sofa::type::Vec2f e11{ 0.f, 2.f }; sofa::type::Vec2f e12{ 2.f, 0.f }; + type::Vec2 baryCoords(type::NOINIT); sofa::type::Vec2f inter{ 0.f, 0.f }; // basic cases // intersection in the middle - auto res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, inter); + auto res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_TRUE(res); EXPECT_FLOAT_EQ(inter[0], 1.0f); EXPECT_FLOAT_EQ(inter[1], 1.0f); // intersection on a node e12 = { 2.f, 2.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_TRUE(res); EXPECT_FLOAT_EQ(inter[0], 2.0f); EXPECT_FLOAT_EQ(inter[1], 2.0f); // no intersection e12 = { -1.f, -1.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_FALSE(res); - EXPECT_FLOAT_EQ(inter[0], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[1], std::numeric_limits::min()); + EXPECT_FLOAT_EQ(inter[0], 0.0f); + EXPECT_FLOAT_EQ(inter[1], 0.0f); // colinear e12 = { 2.f, 4.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_FALSE(res); - EXPECT_FLOAT_EQ(inter[0], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[1], std::numeric_limits::min()); + EXPECT_FLOAT_EQ(inter[0], 0.0f); + EXPECT_FLOAT_EQ(inter[1], 0.0f); // on the same line but no overlapping sofa::type::Vec2f e13{ 2.001f, 2.001f }; sofa::type::Vec2f e14{ 3.f, 3.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e13, e14, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e13, e14, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_FALSE(res); - EXPECT_FLOAT_EQ(inter[0], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[1], std::numeric_limits::min()); + EXPECT_FLOAT_EQ(inter[0], 0.0f); + EXPECT_FLOAT_EQ(inter[1], 0.0f); // on the same line and overlapping e13 = { 1.5f, 1.5f }; e14 = { 3.f, 3.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e13, e14, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e13, e14, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_FALSE(res); - EXPECT_FLOAT_EQ(inter[0], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[1], std::numeric_limits::min()); + EXPECT_FLOAT_EQ(inter[0], 0.0f); + EXPECT_FLOAT_EQ(inter[1], 0.0f); } @@ -378,11 +385,13 @@ TEST(GeometryEdge_test, intersectionWithEdge3f) const sofa::type::Vec3f e11{ 0.f, 0.f, 2.f }; sofa::type::Vec3f e12{ 2.f, 2.f, 0.f }; + type::Vec2 baryCoords(type::NOINIT); sofa::type::Vec3f inter{ 0.f, 0.f, 0.f }; // basic cases // intersection in the middle - auto res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, inter); + auto res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_TRUE(res); EXPECT_FLOAT_EQ(inter[0], 1.0f); EXPECT_FLOAT_EQ(inter[1], 1.0f); @@ -390,7 +399,8 @@ TEST(GeometryEdge_test, intersectionWithEdge3f) // intersection on a node e12 = { 2.f, 2.f, 2.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_TRUE(res); EXPECT_FLOAT_EQ(inter[0], 2.0f); EXPECT_FLOAT_EQ(inter[1], 2.0f); @@ -398,37 +408,41 @@ TEST(GeometryEdge_test, intersectionWithEdge3f) // no intersection e12 = { -1.f, -1.f, -1.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_FALSE(res); - EXPECT_FLOAT_EQ(inter[0], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[1], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[2], std::numeric_limits::min()); + EXPECT_FLOAT_EQ(inter[0], 0.f); + EXPECT_FLOAT_EQ(inter[1], 0.f); + EXPECT_FLOAT_EQ(inter[2], 0.f); // colinear e12 = { 2.f, 2.f, 4.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e11, e12, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_FALSE(res); - EXPECT_FLOAT_EQ(inter[0], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[1], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[2], std::numeric_limits::min()); + EXPECT_FLOAT_EQ(inter[0], 0.f); + EXPECT_FLOAT_EQ(inter[1], 0.f); + EXPECT_FLOAT_EQ(inter[2], 0.f); // on the same line but no overlapping sofa::type::Vec3f e13{ 2.001f, 2.001f, 2.001f }; sofa::type::Vec3f e14{ 3.f, 3.f, 3.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e13, e14, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e13, e14, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_FALSE(res); - EXPECT_FLOAT_EQ(inter[0], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[1], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[2], std::numeric_limits::min()); + EXPECT_FLOAT_EQ(inter[0], 0.f); + EXPECT_FLOAT_EQ(inter[1], 0.f); + EXPECT_FLOAT_EQ(inter[2], 0.f); // on the same line and overlapping e13 = { 1.5f, 1.5f, 1.5f }; e14 = { 3.f, 3.f, 3.f }; - res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e13, e14, inter); + res = sofa::geometry::Edge::intersectionWithEdge(e01, e02, e13, e14, baryCoords); + inter = e01 * baryCoords[0] + e02 * baryCoords[1]; EXPECT_FALSE(res); - EXPECT_FLOAT_EQ(inter[0], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[1], std::numeric_limits::min()); - EXPECT_FLOAT_EQ(inter[2], std::numeric_limits::min()); + EXPECT_FLOAT_EQ(inter[0], 0.f); + EXPECT_FLOAT_EQ(inter[1], 0.f); + EXPECT_FLOAT_EQ(inter[2], 0.f); } TEST(GeometryEdge_test, intersectionWithPlane3f) diff --git a/examples/Component/Topology/Container/Dynamic/IncisionTrianglesProcess.scn b/examples/Component/Topology/Container/Dynamic/IncisionTrianglesProcess.scn index 56ab31ecb70..4332c6f9669 100644 --- a/examples/Component/Topology/Container/Dynamic/IncisionTrianglesProcess.scn +++ b/examples/Component/Topology/Container/Dynamic/IncisionTrianglesProcess.scn @@ -1,3 +1,4 @@ +