Skip to content

Commit c7ac36e

Browse files
authored
[src] Multiple cleaning in methods conputeFractureDirection, endpoints and Move computeIntersectionNeighborTriangle into TearingAlgorithm to use existing methods from TriangleSetGeometryAlgo (#69)
* [src] Update methods signature of computeFractureDirection, computeEndPoints and computeEndPointsNeighboringTriangles to avoid multiple call to GetReadAccessor to the positions * [src] Move computeIntersectionNeighborTriangle into TearingAlgorithm and use existing methods from TriangleSetGeometryAlgo * [src] Fix bad merge
1 parent 8b673eb commit c7ac36e

8 files changed

Lines changed: 128 additions & 129 deletions

src/Tearing/BaseTearingEngine.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,16 @@ class BaseTearingEngine : public core::DataEngine
125125

126126
virtual void computeFracturePath() = 0;
127127

128-
void computeFractureDirection(const Coord principleStressDirection, Coord& fracture_direction);
128+
Coord computeFractureDirection(const Coord& principleStressDirection);
129129

130130
/// <summary>
131131
/// compute extremities of fracture Pb and Pc from a start point Pa
132132
/// </summary>
133133
/// @param Pa - point with maxStress where fracture start
134-
/// @param direction - direction of maximum principal stress
134+
/// @param fractureDirection - direction of fracture
135135
/// @return Pb - one of the extremities of fracture
136136
/// @return Pc - one of the extremities of fracture
137-
virtual void computeEndPoints(Coord Pa, Coord direction, Coord& Pb, Coord& Pc);
137+
virtual void computeEndPoints(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc);
138138

139139
/// <summary>
140140
/// compute ignored triangle at start of the tearing algo

src/Tearing/BaseTearingEngine.inl

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -329,19 +329,20 @@ void BaseTearingEngine<DataTypes>::updateTriangleInformation()
329329

330330

331331
template<class DataTypes>
332-
inline void BaseTearingEngine<DataTypes>::computeFractureDirection(const Coord principleStressDirection,Coord & fracture_direction)
332+
typename DataTypes::Coord BaseTearingEngine<DataTypes>::computeFractureDirection(const Coord& principleStressDirection)
333333
{
334+
Coord fracture_direction = { 0.0, 0.0, 0.0 };
335+
334336
if (m_maxStressTriangleIndex == InvalidID) {
335-
fracture_direction = { 0.0, 0.0, 0.0 };
336-
return;
337+
return fracture_direction;
337338
}
338339

339340
const Triangle& VertexIndicies = m_topology->getTriangle(m_maxStressTriangleIndex);
340-
constexpr size_t numVertices = 3;
341341

342-
Index B_id = -1, C_id = -1;
342+
Index B_id = sofa::InvalidID;
343+
Index C_id = sofa::InvalidID;
343344

344-
for (unsigned int vertex_id = 0; vertex_id < numVertices; vertex_id++)
345+
for (sofa::Index vertex_id = 0; vertex_id < 3; vertex_id++)
345346
{
346347
if (VertexIndicies[vertex_id] == m_maxStressVertexIndex)
347348
{
@@ -356,27 +357,22 @@ inline void BaseTearingEngine<DataTypes>::computeFractureDirection(const Coord p
356357
Coord B = x[B_id];
357358
Coord C = x[C_id];
358359

359-
Coord AB = B - A;
360-
Coord AC = C - A;
361-
362-
Coord triangleNormal = sofa::type::cross(AB,AC);
360+
Coord triangleNormal = sofa::type::cross(B - A, C - A);
363361
fracture_direction = sofa::type::cross(triangleNormal, principleStressDirection);
362+
363+
return fracture_direction;
364364
}
365365

366366

367367
template <class DataTypes>
368-
void BaseTearingEngine<DataTypes>::computeEndPoints(
369-
Coord Pa,
370-
Coord direction,
371-
Coord& Pb, Coord& Pc)
368+
void BaseTearingEngine<DataTypes>::computeEndPoints(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc)
372369
{
373-
Coord fractureDirection;
374-
computeFractureDirection(direction, fractureDirection);
375370
Real norm_fractureDirection = fractureDirection.norm();
376371
Pb = Pa + d_fractureMaxLength.getValue() / norm_fractureDirection * fractureDirection;
377372
Pc = Pa - d_fractureMaxLength.getValue() / norm_fractureDirection * fractureDirection;
378373
}
379374

375+
380376
template <class DataTypes>
381377
void BaseTearingEngine<DataTypes>::computeTriangleToSkip()
382378
{

src/Tearing/TearingAlgorithms.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ class TearingAlgorithms
7474

7575
void computeFracturePath(FracturePath& my_fracturePath);
7676

77+
78+
/// <summary>
79+
/// computes the extremities of the (normalized) fracture PbPa on the edge of the triangle
80+
/// </summary>
81+
/// @param Pa - the point where the fracture starts
82+
/// @param normalizedFractureDirection - normalized fracture direction
83+
/// @return Pb - one of the extremities of fracture
84+
/// @return t - a parameter needed to calculate Pb
85+
TriangleID computeIntersectionNeighborTriangle(const Index ptAId, const Coord& ptA, const Coord& normalizedFractureDirection, Coord& Pb);
86+
7787
void computeFracturePath(const Coord& pA, Index triId, const Coord pB, const Coord pC);
7888

7989
/// <summary>

src/Tearing/TearingAlgorithms.inl

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,67 @@ TearingAlgorithms<DataTypes>::~TearingAlgorithms()
5151
}
5252

5353

54+
template<class DataTypes>
55+
inline TriangleID TearingAlgorithms<DataTypes>::computeIntersectionNeighborTriangle(const Index ptAId, const Coord& ptA, const Coord& normalizedFractureDirection, Coord& ptB)
56+
{
57+
// Get triangle in the fracture direction
58+
TriangleID theTriId = m_triangleGeo->getTriangleInDirection(ptAId, normalizedFractureDirection);
59+
60+
// If not, could be on the border. Return invalidID
61+
if (theTriId > this->m_topology->getNbTriangles() - 1)
62+
return sofa::InvalidID;
63+
64+
// If it exists, get triangle and search for ptAId local index in the triangle
65+
const Triangle& theTri = this->m_topology->getTriangle(theTriId);
66+
PointID localAId = sofa::InvalidID;
67+
for (PointID vertex_id = 0; vertex_id < 3; vertex_id++)
68+
{
69+
if (theTri[vertex_id] == ptAId)
70+
{
71+
localAId = vertex_id;
72+
break;
73+
}
74+
}
75+
76+
// Get the opposite edge
77+
EdgeID oppositeEdgeId = this->m_topology->getEdgesInTriangle(theTriId)[localAId];
78+
Edge oppositeEdge = this->m_topology->getEdge(oppositeEdgeId);
79+
80+
81+
//Building point B such that to be sure that AB intersects CD, based on "Losange"
82+
const Coord pE0 = this->m_triangleGeo->getPointPosition(oppositeEdge[0]);
83+
const Coord pE1 = this->m_triangleGeo->getPointPosition(oppositeEdge[1]);
84+
85+
const Real AC_length = (pE0 - ptA).norm();
86+
const Real AD_length = (pE1 - ptA).norm();
87+
const Real Length = AC_length + AD_length;
88+
89+
ptB = ptA + Length * normalizedFractureDirection;
90+
91+
// Compute intersection on the opposite edge
92+
sofa::type::vector<EdgeID> intersectedEdges;
93+
sofa::type::vector<Real> baryCoefs;
94+
m_triangleGeo->computeSegmentTriangleIntersectionInPlane(ptA, ptB, theTriId, intersectedEdges, baryCoefs);
95+
96+
bool found = false;
97+
for (unsigned int i=0; i< intersectedEdges.size(); ++i)
98+
{
99+
if (intersectedEdges[i] == oppositeEdgeId)
100+
{
101+
found = true;
102+
ptB = pE0 * baryCoefs[i] + pE1 * (1 - baryCoefs[i]);
103+
break;
104+
}
105+
}
106+
107+
if (!found)
108+
return sofa::InvalidID;
109+
else
110+
return theTriId;
111+
}
112+
113+
114+
54115
template <class DataTypes>
55116
void TearingAlgorithms<DataTypes>::computeFracturePath(const Coord& pA, Index triId, const Coord pB, const Coord pC)
56117
{

src/Tearing/TearingEngine.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,11 @@ class TearingEngine : public BaseTearingEngine<DataTypes>
8181
/// computes the extremities of fracture Pb and Pc on the edge of neighboring triangles
8282
/// </summary>
8383
/// @param Pa - the point where the fracture starts
84-
/// @param direction - principle stress direction
84+
/// @param fractureDirection - fracture direction
8585
/// @return Pb - one of the extremities of fracture
8686
/// @return Pc - one of the extremities of fracture
87-
bool computeEndPointsNeighboringTriangles(Coord Pa, Coord direction, Coord& Pb, Coord& Pc);
87+
bool computeEndPointsNeighboringTriangles(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc);
8888

89-
/// <summary>
90-
/// computes the extremities of the (normalized) fracture PbPa on the edge of the triangle
91-
/// </summary>
92-
/// @param Pa - the point where the fracture starts
93-
/// @param normalizedFractureDirection - normalized fracture direction
94-
/// @return Pb - one of the extremities of fracture
95-
/// @return t - a parameter needed to calculate Pb
96-
bool computeIntersectionNeighborTriangle(Coord normalizedFractureDirection, Coord Pa, Coord& Pb, Real& t);
97-
9889
void algoFracturePath() override;
9990

10091
void computeFracturePath() override;

src/Tearing/TearingEngine.inl

Lines changed: 35 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -41,85 +41,26 @@ using sofa::type::Vec3;
4141
// --------------------------------------------------------------------------------------
4242
// --- Computation methods
4343
// --------------------------------------------------------------------------------------
44-
template<class DataTypes>
45-
inline bool TearingEngine<DataTypes>::computeIntersectionNeighborTriangle(Coord normalizedFractureDirection, Coord Pa, Coord& Pb, Real& t)
46-
{
47-
SOFA_UNUSED(Pa);
48-
49-
if (m_maxStressVertexIndex == InvalidID)
50-
return false;
51-
52-
// Get Geometry Algorithm
53-
TriangleSetGeometryAlgorithms<DataTypes>* _triangleGeo = nullptr;
54-
this->m_topology->getContext()->get(_triangleGeo);
55-
if (!_triangleGeo)
56-
{
57-
msg_error() << "Missing component: Unable to get TriangleSetGeometryAlgorithms from the current context.";
58-
sofa::core::objectmodel::BaseObject::d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
59-
return false;
60-
}
61-
62-
63-
Index triangle_id = _triangleGeo->getTriangleInDirection(m_maxStressVertexIndex, normalizedFractureDirection);
64-
if (triangle_id > this->m_topology->getNbTriangles() - 1)
65-
return false;
66-
67-
68-
const Triangle& VertexIndicies = this->m_topology->getTriangle(triangle_id);
69-
70-
constexpr size_t numVertices = 3;
71-
Index B_id = -1, C_id = -1;
72-
73-
for (unsigned int vertex_id = 0; vertex_id < numVertices; vertex_id++)
74-
{
75-
if (VertexIndicies[vertex_id] == m_maxStressVertexIndex)
76-
{
77-
B_id = VertexIndicies[(vertex_id + 1) % 3];
78-
C_id = VertexIndicies[(vertex_id + 2) % 3];
79-
break;
80-
}
81-
82-
}
83-
84-
helper::ReadAccessor< Data<VecCoord> > x(d_input_positions);
85-
Coord A = x[m_maxStressVertexIndex];
86-
Coord B = x[B_id];
87-
Coord C = x[C_id];
88-
89-
if (rayTriangleIntersection(A, B, C, normalizedFractureDirection, t, Pb))
90-
return true;
91-
else
92-
return false;
93-
94-
}
9544

9645
template<class DataTypes>
97-
inline bool TearingEngine<DataTypes>::computeEndPointsNeighboringTriangles(Coord Pa, Coord direction, Coord& Pb, Coord& Pc)
46+
inline bool TearingEngine<DataTypes>::computeEndPointsNeighboringTriangles(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc)
9847
{
9948
bool t_b_ok = false;
10049
bool t_c_ok = false;
101-
//compute fracture direction perpendicular to the principal stress direction
102-
Coord fractureDirection;
103-
this->computeFractureDirection(direction, fractureDirection);
10450

105-
Real norm_fractureDirection = fractureDirection.norm();
106-
Coord dir_b = 1.0 / norm_fractureDirection * fractureDirection;
107-
108-
Real t_b;
109-
if (computeIntersectionNeighborTriangle(dir_b,Pa, Pb, t_b))
110-
t_b_ok = true;
51+
Coord dir_b = fractureDirection / fractureDirection.norm();
52+
TriangleID t_b = this->m_tearingAlgo->computeIntersectionNeighborTriangle(m_maxStressVertexIndex, Pa, dir_b, Pb);
11153

112-
11354
Coord dir_c = -dir_b;
114-
Real t_c;
115-
if (computeIntersectionNeighborTriangle(dir_c,Pa,Pc, t_c))
116-
t_c_ok = true;
55+
TriangleID t_c = this->m_tearingAlgo->computeIntersectionNeighborTriangle(m_maxStressVertexIndex, Pa, dir_c, Pc);
56+
11757

118-
if (!(t_b_ok && t_c_ok))
58+
if (t_b == sofa::InvalidID || t_c == sofa::InvalidID)
11959
{
12060
msg_warning() << "Not able to build the fracture path through neighboring triangles.";
12161
return false;
12262
}
63+
12364
return true;
12465
}
12566

@@ -163,33 +104,36 @@ void TearingEngine<DataTypes>::computeFracturePath()
163104
// frist clear ereything
164105
this->clearFracturePath();
165106

166-
if (m_maxStressTriangleIndex != InvalidID) // we have triangle to start and also a vertex id
107+
if (m_maxStressTriangleIndex == InvalidID) // no candidate to start fracture
108+
return;
109+
110+
//Recording the endpoints of the fracture segment
111+
helper::ReadAccessor< Data<VecCoord> > x(d_input_positions);
112+
113+
const Coord fractureDirection = this->computeFractureDirection(m_triangleInfoTearing[m_maxStressTriangleIndex].principalStressDirection);
114+
115+
const Coord Pa = x[m_maxStressVertexIndex];
116+
Coord Pb, Pc;
117+
118+
if (this->d_fractureMaxLength.getValue() == 0.0)
119+
{
120+
bool checkEndsPoints = this->computeEndPointsNeighboringTriangles(Pa, fractureDirection, Pb, Pc);
121+
if (!checkEndsPoints)
122+
return;
123+
}
124+
else
167125
{
168-
//Recording the endpoints of the fracture segment
169-
helper::ReadAccessor< Data<VecCoord> > x(d_input_positions);
170-
171-
Coord principalStressDirection = m_triangleInfoTearing[m_maxStressTriangleIndex].principalStressDirection;
172-
Coord Pa = x[m_maxStressVertexIndex];
173-
Coord Pb, Pc;
174-
175-
if (this->d_fractureMaxLength.getValue() == 0.0) {
176-
computeEndPointsNeighboringTriangles(Pa, principalStressDirection, Pb, Pc);
177-
}
178-
else
179-
{
180-
this->computeEndPoints(Pa, principalStressDirection, Pb, Pc);
181-
}
182-
183-
this->m_fracturePath.ptA = type::Vec3(Pa[0], Pa[1], Pa[2]);
184-
this->m_fracturePath.ptB = type::Vec3(Pb[0], Pb[1], Pb[2]);
185-
this->m_fracturePath.ptC = type::Vec3(Pc[0], Pc[1], Pc[2]);
186-
this->m_fracturePath.triIdA = m_maxStressTriangleIndex;
187-
188-
this->m_tearingAlgo->computeFracturePath(this->m_fracturePath);
189-
this->m_stepCounter++;
190-
191-
//this->m_tearingAlgo->computeFracturePath(Pa, m_maxStressTriangleIndex, Pb, Pc);
126+
this->computeEndPoints(Pa, fractureDirection, Pb, Pc); // compute orthogonal fracture using d_fractureMaxLength
192127
}
128+
129+
130+
this->m_fracturePath.ptA = type::Vec3(DataTypes::getCPos(Pa));
131+
this->m_fracturePath.ptB = type::Vec3(DataTypes::getCPos(Pb));
132+
this->m_fracturePath.ptC = type::Vec3(DataTypes::getCPos(Pc));
133+
this->m_fracturePath.triIdA = m_maxStressTriangleIndex;
134+
135+
this->m_tearingAlgo->computeFracturePath(this->m_fracturePath);
136+
this->m_stepCounter++;
193137
}
194138

195139

src/Tearing/TearingScenarioEngine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class TearingScenarioEngine : public BaseTearingEngine<DataTypes>
7777
void algoFracturePath() override;
7878
void computeFracturePath() override {};
7979

80-
void computeEndPoints(Coord Pa, Coord direction, Coord& Pb, Coord& Pc) override;
80+
void computeEndPoints(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc) override;
8181

8282
/// Value to store scenario fracture path
8383
Coord m_Pa, m_Pb, m_Pc;

src/Tearing/TearingScenarioEngine.inl

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,14 @@ inline void TearingScenarioEngine<DataTypes>::computePerpendicular(Coord dir, Co
106106
}
107107

108108
template <class DataTypes>
109-
void TearingScenarioEngine<DataTypes>::computeEndPoints(
110-
Coord Pa,
111-
Coord dir,
112-
Coord& Pb, Coord& Pc)
109+
void TearingScenarioEngine<DataTypes>::computeEndPoints(const Coord& Pa, const Coord& fractureDirection, Coord& Pb, Coord& Pc)
113110
{
114111
const Real& alpha = d_startLength.getValue();
115112

116-
Real norm_dir = dir.norm();
113+
Real norm_dir = fractureDirection.norm();
117114

118-
Pb = Pa + alpha/norm_dir * dir;
119-
Pc = Pa - alpha /norm_dir * dir;
115+
Pb = Pa + alpha/norm_dir * fractureDirection;
116+
Pc = Pa - alpha /norm_dir * fractureDirection;
120117
}
121118

122119
template <class DataTypes>

0 commit comments

Comments
 (0)