diff --git a/src/Tearing/BaseTearingEngine.h b/src/Tearing/BaseTearingEngine.h
index c853a8d..9d9b8e5 100644
--- a/src/Tearing/BaseTearingEngine.h
+++ b/src/Tearing/BaseTearingEngine.h
@@ -125,16 +125,16 @@ class BaseTearingEngine : public core::DataEngine
virtual void computeFracturePath() = 0;
- void computeFractureDirection(const Coord principleStressDirection, Coord& fracture_direction);
+ Coord computeFractureDirection(const Coord& principleStressDirection);
///
/// compute extremities of fracture Pb and Pc from a start point Pa
///
/// @param Pa - point with maxStress where fracture start
- /// @param direction - direction of maximum principal stress
+ /// @param fractureDirection - direction of fracture
/// @return Pb - one of the extremities of fracture
/// @return Pc - one of the extremities of fracture
- virtual void computeEndPoints(Coord Pa, Coord direction, Coord& Pb, Coord& Pc);
+ virtual void computeEndPoints(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc);
///
/// compute ignored triangle at start of the tearing algo
diff --git a/src/Tearing/BaseTearingEngine.inl b/src/Tearing/BaseTearingEngine.inl
index 5925916..4778232 100644
--- a/src/Tearing/BaseTearingEngine.inl
+++ b/src/Tearing/BaseTearingEngine.inl
@@ -329,19 +329,20 @@ void BaseTearingEngine::updateTriangleInformation()
template
-inline void BaseTearingEngine::computeFractureDirection(const Coord principleStressDirection,Coord & fracture_direction)
+typename DataTypes::Coord BaseTearingEngine::computeFractureDirection(const Coord& principleStressDirection)
{
+ Coord fracture_direction = { 0.0, 0.0, 0.0 };
+
if (m_maxStressTriangleIndex == InvalidID) {
- fracture_direction = { 0.0, 0.0, 0.0 };
- return;
+ return fracture_direction;
}
const Triangle& VertexIndicies = m_topology->getTriangle(m_maxStressTriangleIndex);
- constexpr size_t numVertices = 3;
- Index B_id = -1, C_id = -1;
+ Index B_id = sofa::InvalidID;
+ Index C_id = sofa::InvalidID;
- for (unsigned int vertex_id = 0; vertex_id < numVertices; vertex_id++)
+ for (sofa::Index vertex_id = 0; vertex_id < 3; vertex_id++)
{
if (VertexIndicies[vertex_id] == m_maxStressVertexIndex)
{
@@ -356,27 +357,22 @@ inline void BaseTearingEngine::computeFractureDirection(const Coord p
Coord B = x[B_id];
Coord C = x[C_id];
- Coord AB = B - A;
- Coord AC = C - A;
-
- Coord triangleNormal = sofa::type::cross(AB,AC);
+ Coord triangleNormal = sofa::type::cross(B - A, C - A);
fracture_direction = sofa::type::cross(triangleNormal, principleStressDirection);
+
+ return fracture_direction;
}
template
-void BaseTearingEngine::computeEndPoints(
- Coord Pa,
- Coord direction,
- Coord& Pb, Coord& Pc)
+void BaseTearingEngine::computeEndPoints(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc)
{
- Coord fractureDirection;
- computeFractureDirection(direction, fractureDirection);
Real norm_fractureDirection = fractureDirection.norm();
Pb = Pa + d_fractureMaxLength.getValue() / norm_fractureDirection * fractureDirection;
Pc = Pa - d_fractureMaxLength.getValue() / norm_fractureDirection * fractureDirection;
}
+
template
void BaseTearingEngine::computeTriangleToSkip()
{
diff --git a/src/Tearing/TearingAlgorithms.h b/src/Tearing/TearingAlgorithms.h
index 5bd4157..da4037b 100644
--- a/src/Tearing/TearingAlgorithms.h
+++ b/src/Tearing/TearingAlgorithms.h
@@ -74,6 +74,16 @@ class TearingAlgorithms
void computeFracturePath(FracturePath& my_fracturePath);
+
+ ///
+ /// computes the extremities of the (normalized) fracture PbPa on the edge of the triangle
+ ///
+ /// @param Pa - the point where the fracture starts
+ /// @param normalizedFractureDirection - normalized fracture direction
+ /// @return Pb - one of the extremities of fracture
+ /// @return t - a parameter needed to calculate Pb
+ TriangleID computeIntersectionNeighborTriangle(const Index ptAId, const Coord& ptA, const Coord& normalizedFractureDirection, Coord& Pb);
+
void computeFracturePath(const Coord& pA, Index triId, const Coord pB, const Coord pC);
///
diff --git a/src/Tearing/TearingAlgorithms.inl b/src/Tearing/TearingAlgorithms.inl
index c4fd82e..c010022 100644
--- a/src/Tearing/TearingAlgorithms.inl
+++ b/src/Tearing/TearingAlgorithms.inl
@@ -51,6 +51,67 @@ TearingAlgorithms::~TearingAlgorithms()
}
+template
+inline TriangleID TearingAlgorithms::computeIntersectionNeighborTriangle(const Index ptAId, const Coord& ptA, const Coord& normalizedFractureDirection, Coord& ptB)
+{
+ // Get triangle in the fracture direction
+ TriangleID theTriId = m_triangleGeo->getTriangleInDirection(ptAId, normalizedFractureDirection);
+
+ // If not, could be on the border. Return invalidID
+ if (theTriId > this->m_topology->getNbTriangles() - 1)
+ return sofa::InvalidID;
+
+ // If it exists, get triangle and search for ptAId local index in the triangle
+ const Triangle& theTri = this->m_topology->getTriangle(theTriId);
+ PointID localAId = sofa::InvalidID;
+ for (PointID vertex_id = 0; vertex_id < 3; vertex_id++)
+ {
+ if (theTri[vertex_id] == ptAId)
+ {
+ localAId = vertex_id;
+ break;
+ }
+ }
+
+ // Get the opposite edge
+ EdgeID oppositeEdgeId = this->m_topology->getEdgesInTriangle(theTriId)[localAId];
+ Edge oppositeEdge = this->m_topology->getEdge(oppositeEdgeId);
+
+
+ //Building point B such that to be sure that AB intersects CD, based on "Losange"
+ const Coord pE0 = this->m_triangleGeo->getPointPosition(oppositeEdge[0]);
+ const Coord pE1 = this->m_triangleGeo->getPointPosition(oppositeEdge[1]);
+
+ const Real AC_length = (pE0 - ptA).norm();
+ const Real AD_length = (pE1 - ptA).norm();
+ const Real Length = AC_length + AD_length;
+
+ ptB = ptA + Length * normalizedFractureDirection;
+
+ // Compute intersection on the opposite edge
+ sofa::type::vector intersectedEdges;
+ sofa::type::vector baryCoefs;
+ m_triangleGeo->computeSegmentTriangleIntersectionInPlane(ptA, ptB, theTriId, intersectedEdges, baryCoefs);
+
+ bool found = false;
+ for (unsigned int i=0; i< intersectedEdges.size(); ++i)
+ {
+ if (intersectedEdges[i] == oppositeEdgeId)
+ {
+ found = true;
+ ptB = pE0 * baryCoefs[i] + pE1 * (1 - baryCoefs[i]);
+ break;
+ }
+ }
+
+ if (!found)
+ return sofa::InvalidID;
+ else
+ return theTriId;
+}
+
+
+
template
void TearingAlgorithms::computeFracturePath(const Coord& pA, Index triId, const Coord pB, const Coord pC)
{
diff --git a/src/Tearing/TearingEngine.h b/src/Tearing/TearingEngine.h
index d56342d..6436e8c 100644
--- a/src/Tearing/TearingEngine.h
+++ b/src/Tearing/TearingEngine.h
@@ -81,20 +81,11 @@ class TearingEngine : public BaseTearingEngine
/// computes the extremities of fracture Pb and Pc on the edge of neighboring triangles
///
/// @param Pa - the point where the fracture starts
- /// @param direction - principle stress direction
+ /// @param fractureDirection - fracture direction
/// @return Pb - one of the extremities of fracture
/// @return Pc - one of the extremities of fracture
- bool computeEndPointsNeighboringTriangles(Coord Pa, Coord direction, Coord& Pb, Coord& Pc);
+ bool computeEndPointsNeighboringTriangles(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc);
- ///
- /// computes the extremities of the (normalized) fracture PbPa on the edge of the triangle
- ///
- /// @param Pa - the point where the fracture starts
- /// @param normalizedFractureDirection - normalized fracture direction
- /// @return Pb - one of the extremities of fracture
- /// @return t - a parameter needed to calculate Pb
- bool computeIntersectionNeighborTriangle(Coord normalizedFractureDirection, Coord Pa, Coord& Pb, Real& t);
-
void algoFracturePath() override;
void computeFracturePath() override;
diff --git a/src/Tearing/TearingEngine.inl b/src/Tearing/TearingEngine.inl
index 5206ac6..6e9585c 100644
--- a/src/Tearing/TearingEngine.inl
+++ b/src/Tearing/TearingEngine.inl
@@ -41,85 +41,26 @@ using sofa::type::Vec3;
// --------------------------------------------------------------------------------------
// --- Computation methods
// --------------------------------------------------------------------------------------
-template
-inline bool TearingEngine::computeIntersectionNeighborTriangle(Coord normalizedFractureDirection, Coord Pa, Coord& Pb, Real& t)
-{
- SOFA_UNUSED(Pa);
-
- if (m_maxStressVertexIndex == InvalidID)
- return false;
-
- // Get Geometry Algorithm
- TriangleSetGeometryAlgorithms* _triangleGeo = nullptr;
- this->m_topology->getContext()->get(_triangleGeo);
- if (!_triangleGeo)
- {
- msg_error() << "Missing component: Unable to get TriangleSetGeometryAlgorithms from the current context.";
- sofa::core::objectmodel::BaseObject::d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
- return false;
- }
-
-
- Index triangle_id = _triangleGeo->getTriangleInDirection(m_maxStressVertexIndex, normalizedFractureDirection);
- if (triangle_id > this->m_topology->getNbTriangles() - 1)
- return false;
-
-
- const Triangle& VertexIndicies = this->m_topology->getTriangle(triangle_id);
-
- constexpr size_t numVertices = 3;
- Index B_id = -1, C_id = -1;
-
- for (unsigned int vertex_id = 0; vertex_id < numVertices; vertex_id++)
- {
- if (VertexIndicies[vertex_id] == m_maxStressVertexIndex)
- {
- B_id = VertexIndicies[(vertex_id + 1) % 3];
- C_id = VertexIndicies[(vertex_id + 2) % 3];
- break;
- }
-
- }
-
- helper::ReadAccessor< Data > x(d_input_positions);
- Coord A = x[m_maxStressVertexIndex];
- Coord B = x[B_id];
- Coord C = x[C_id];
-
- if (rayTriangleIntersection(A, B, C, normalizedFractureDirection, t, Pb))
- return true;
- else
- return false;
-
-}
template
-inline bool TearingEngine::computeEndPointsNeighboringTriangles(Coord Pa, Coord direction, Coord& Pb, Coord& Pc)
+inline bool TearingEngine::computeEndPointsNeighboringTriangles(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc)
{
bool t_b_ok = false;
bool t_c_ok = false;
- //compute fracture direction perpendicular to the principal stress direction
- Coord fractureDirection;
- this->computeFractureDirection(direction, fractureDirection);
- Real norm_fractureDirection = fractureDirection.norm();
- Coord dir_b = 1.0 / norm_fractureDirection * fractureDirection;
-
- Real t_b;
- if (computeIntersectionNeighborTriangle(dir_b,Pa, Pb, t_b))
- t_b_ok = true;
+ Coord dir_b = fractureDirection / fractureDirection.norm();
+ TriangleID t_b = this->m_tearingAlgo->computeIntersectionNeighborTriangle(m_maxStressVertexIndex, Pa, dir_b, Pb);
-
Coord dir_c = -dir_b;
- Real t_c;
- if (computeIntersectionNeighborTriangle(dir_c,Pa,Pc, t_c))
- t_c_ok = true;
+ TriangleID t_c = this->m_tearingAlgo->computeIntersectionNeighborTriangle(m_maxStressVertexIndex, Pa, dir_c, Pc);
+
- if (!(t_b_ok && t_c_ok))
+ if (t_b == sofa::InvalidID || t_c == sofa::InvalidID)
{
msg_warning() << "Not able to build the fracture path through neighboring triangles.";
return false;
}
+
return true;
}
@@ -163,33 +104,36 @@ void TearingEngine::computeFracturePath()
// frist clear ereything
this->clearFracturePath();
- if (m_maxStressTriangleIndex != InvalidID) // we have triangle to start and also a vertex id
+ if (m_maxStressTriangleIndex == InvalidID) // no candidate to start fracture
+ return;
+
+ //Recording the endpoints of the fracture segment
+ helper::ReadAccessor< Data > x(d_input_positions);
+
+ const Coord fractureDirection = this->computeFractureDirection(m_triangleInfoTearing[m_maxStressTriangleIndex].principalStressDirection);
+
+ const Coord Pa = x[m_maxStressVertexIndex];
+ Coord Pb, Pc;
+
+ if (this->d_fractureMaxLength.getValue() == 0.0)
+ {
+ bool checkEndsPoints = this->computeEndPointsNeighboringTriangles(Pa, fractureDirection, Pb, Pc);
+ if (!checkEndsPoints)
+ return;
+ }
+ else
{
- //Recording the endpoints of the fracture segment
- helper::ReadAccessor< Data > x(d_input_positions);
-
- Coord principalStressDirection = m_triangleInfoTearing[m_maxStressTriangleIndex].principalStressDirection;
- Coord Pa = x[m_maxStressVertexIndex];
- Coord Pb, Pc;
-
- if (this->d_fractureMaxLength.getValue() == 0.0) {
- computeEndPointsNeighboringTriangles(Pa, principalStressDirection, Pb, Pc);
- }
- else
- {
- this->computeEndPoints(Pa, principalStressDirection, Pb, Pc);
- }
-
- this->m_fracturePath.ptA = type::Vec3(Pa[0], Pa[1], Pa[2]);
- this->m_fracturePath.ptB = type::Vec3(Pb[0], Pb[1], Pb[2]);
- this->m_fracturePath.ptC = type::Vec3(Pc[0], Pc[1], Pc[2]);
- this->m_fracturePath.triIdA = m_maxStressTriangleIndex;
-
- this->m_tearingAlgo->computeFracturePath(this->m_fracturePath);
- this->m_stepCounter++;
-
- //this->m_tearingAlgo->computeFracturePath(Pa, m_maxStressTriangleIndex, Pb, Pc);
+ this->computeEndPoints(Pa, fractureDirection, Pb, Pc); // compute orthogonal fracture using d_fractureMaxLength
}
+
+
+ this->m_fracturePath.ptA = type::Vec3(DataTypes::getCPos(Pa));
+ this->m_fracturePath.ptB = type::Vec3(DataTypes::getCPos(Pb));
+ this->m_fracturePath.ptC = type::Vec3(DataTypes::getCPos(Pc));
+ this->m_fracturePath.triIdA = m_maxStressTriangleIndex;
+
+ this->m_tearingAlgo->computeFracturePath(this->m_fracturePath);
+ this->m_stepCounter++;
}
diff --git a/src/Tearing/TearingScenarioEngine.h b/src/Tearing/TearingScenarioEngine.h
index 59c2d4f..3913d77 100644
--- a/src/Tearing/TearingScenarioEngine.h
+++ b/src/Tearing/TearingScenarioEngine.h
@@ -77,7 +77,7 @@ class TearingScenarioEngine : public BaseTearingEngine
void algoFracturePath() override;
void computeFracturePath() override {};
- void computeEndPoints(Coord Pa, Coord direction, Coord& Pb, Coord& Pc) override;
+ void computeEndPoints(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc) override;
/// Value to store scenario fracture path
Coord m_Pa, m_Pb, m_Pc;
diff --git a/src/Tearing/TearingScenarioEngine.inl b/src/Tearing/TearingScenarioEngine.inl
index 18fce34..0dd17a8 100644
--- a/src/Tearing/TearingScenarioEngine.inl
+++ b/src/Tearing/TearingScenarioEngine.inl
@@ -106,17 +106,14 @@ inline void TearingScenarioEngine::computePerpendicular(Coord dir, Co
}
template
-void TearingScenarioEngine::computeEndPoints(
- Coord Pa,
- Coord dir,
- Coord& Pb, Coord& Pc)
+void TearingScenarioEngine::computeEndPoints(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc)
{
const Real& alpha = d_startLength.getValue();
- Real norm_dir = dir.norm();
+ Real norm_dir = fractureDirection.norm();
- Pb = Pa + alpha/norm_dir * dir;
- Pc = Pa - alpha /norm_dir * dir;
+ Pb = Pa + alpha/norm_dir * fractureDirection;
+ Pc = Pa - alpha /norm_dir * fractureDirection;
}
template