diff --git a/src/Tearing/BaseTearingEngine.h b/src/Tearing/BaseTearingEngine.h index d7357b9..c853a8d 100644 --- a/src/Tearing/BaseTearingEngine.h +++ b/src/Tearing/BaseTearingEngine.h @@ -101,6 +101,9 @@ class BaseTearingEngine : public core::DataEngine Coord principalStressDirection; }; + + + /// Link to be set to the topology container in the component graph SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; @@ -122,7 +125,7 @@ class BaseTearingEngine : public core::DataEngine virtual void computeFracturePath() = 0; - void computeFractureDirection(Coord principleStressDirection, Coord& fracture_direction); + void computeFractureDirection(const Coord principleStressDirection, Coord& fracture_direction); /// /// compute extremities of fracture Pb and Pc from a start point Pa @@ -169,6 +172,9 @@ class BaseTearingEngine : public core::DataEngine /// void calculate_inverse_distance_weights(std::vector& result, const Index vertex, sofa::type::vector& ValidTrianglesAround); + + void clearFracturePath(); + /// Access to the topology for a drived class sofa::core::topology::BaseMeshTopology* getTopology() const { return m_topology; @@ -194,10 +200,8 @@ class BaseTearingEngine : public core::DataEngine vector m_triangleInfoTearing; ///< vector of TriangleInfo from FEM int m_stepCounter = 0; ///< counter of doUpdate called by the simulation. Used to put gap between consecutives fractures - /// Fracture segment endpoints - std::vector fractureSegmentEndpoints; - - + /// Vector of pointToAdd due to new fracture + FracturePath m_fracturePath; }; }//namespace sofa::component::engine diff --git a/src/Tearing/BaseTearingEngine.inl b/src/Tearing/BaseTearingEngine.inl index b404c99..5925916 100644 --- a/src/Tearing/BaseTearingEngine.inl +++ b/src/Tearing/BaseTearingEngine.inl @@ -329,7 +329,7 @@ void BaseTearingEngine::updateTriangleInformation() template -inline void BaseTearingEngine::computeFractureDirection(Coord principleStressDirection,Coord & fracture_direction) +inline void BaseTearingEngine::computeFractureDirection(const Coord principleStressDirection,Coord & fracture_direction) { if (m_maxStressTriangleIndex == InvalidID) { fracture_direction = { 0.0, 0.0, 0.0 }; @@ -621,6 +621,22 @@ inline void BaseTearingEngine::calculate_inverse_distance_weights(std +template +void BaseTearingEngine::clearFracturePath() +{ + m_fracturePath.ptA = Vec3(); + m_fracturePath.ptB = Vec3(); + m_fracturePath.ptC = Vec3(); + + m_fracturePath.triIdA = InvalidID; + m_fracturePath.triIdB = InvalidID; + m_fracturePath.triIdC = InvalidID; + + m_fracturePath.pointsToAdd.clear(); + m_fracturePath.pathOk = false; +} + + template void BaseTearingEngine::handleEvent(sofa::core::objectmodel::Event* event) { @@ -638,15 +654,17 @@ void BaseTearingEngine::handleEvent(sofa::core::objectmodel::Event* e return; // We only launch computation at end of a simulation step } - if (m_tearingAlgo->getFractureNumber() > d_nbFractureMax.getValue()) + if (m_tearingAlgo->getFractureNumber() > d_nbFractureMax.getValue()) // reach the end of the engine behavior return; - computeFracturePath(); - // Hack: we access one output value to force the engine to call doUpdate() if (d_maxStress.getValue() == Real(0.0)) return; + // main method to compute the possible fracture if a triangle has reached threshold + computeFracturePath(); + + // Perform fracture every d_stepModulo int step = d_stepModulo.getValue(); if (m_stepCounter > step) @@ -721,25 +739,18 @@ void BaseTearingEngine::draw(const core::visual::VisualParams* vparam } - - - if (d_showFracturePath.getValue()) { - if (m_maxStressTriangleIndex != InvalidID && fractureSegmentEndpoints.size() == 2) + if (m_maxStressTriangleIndex != InvalidID && m_fracturePath.pathOk) { helper::ReadAccessor< Data > x(d_input_positions); + Coord principalStressDirection = m_triangleInfoTearing[m_maxStressTriangleIndex].principalStressDirection; Coord Pa = x[m_maxStressVertexIndex]; - //Coord fractureDirection; - //computeFractureDirection(principalStressDirection, fractureDirection); - Coord Pb = fractureSegmentEndpoints[0]; - Coord Pc = fractureSegmentEndpoints[1]; + Coord Pb = m_fracturePath.ptB; + Coord Pc = m_fracturePath.ptC; vector points; - //Real norm_fractureDirection = fractureDirection.norm(); - //Coord Pb = Pa + d_fractureMaxLength.getValue() / norm_fractureDirection * fractureDirection; - //Coord Pc = Pa - d_fractureMaxLength.getValue() / norm_fractureDirection * fractureDirection; points.push_back(Pb); points.push_back(Pa); points.push_back(Pa); @@ -757,11 +768,20 @@ void BaseTearingEngine::draw(const core::visual::VisualParams* vparam vparams->drawTool()->drawPoints(pointsDir, 10, sofa::type::RGBAColor(0, 1, 0.2, 1)); vparams->drawTool()->drawLines(pointsDir, 1, sofa::type::RGBAColor(0, 1, 0.5, 1)); - points.clear(); + std::vector pointsPath; + for (auto ptA : m_fracturePath.pointsToAdd) + { + sofa::type::Vec3 vecG = sofa::type::Vec3(0.0, 0.0, 0.0); + sofa::Size nbr = ptA->m_ancestors.size(); + for (int i = 0; i < nbr; ++i) + { + + vecG += x[ptA->m_ancestors[i]] * ptA->m_coefs[i]; + } + pointsPath.push_back(vecG); + } + vparams->drawTool()->drawSpheres(pointsPath, 0.01, sofa::type::RGBAColor::red()); - const vector& path = m_tearingAlgo->getFracturePath(); - if (!path.empty()) - vparams->drawTool()->drawPoints(path, 10, sofa::type::RGBAColor(0, 0.8, 0.2, 1)); } } } diff --git a/src/Tearing/TearingAlgorithms.h b/src/Tearing/TearingAlgorithms.h index fdcda41..5bd4157 100644 --- a/src/Tearing/TearingAlgorithms.h +++ b/src/Tearing/TearingAlgorithms.h @@ -28,12 +28,29 @@ #include #include #include +#include + namespace sofa::component { using sofa::component::topology::container::dynamic::TriangleSetTopologyModifier; using sofa::component::topology::container::dynamic::TriangleSetGeometryAlgorithms; +using namespace sofa::component::topology::container::dynamic; + +struct FracturePath +{ + TriangleID triIdA = InvalidID; + TriangleID triIdB = InvalidID; + TriangleID triIdC = InvalidID; + sofa::type::Vec3 ptA, ptB, ptC; + + // full point to add vector + type::vector< std::shared_ptr > pointsToAdd; + + bool pathOk = false; +}; + template class TearingAlgorithms @@ -55,6 +72,10 @@ class TearingAlgorithms virtual ~TearingAlgorithms(); + void computeFracturePath(FracturePath& my_fracturePath); + + void computeFracturePath(const Coord& pA, Index triId, const Coord pB, const Coord pC); + /// /// compute fracture path intersection point and cut through them /// @@ -160,6 +181,9 @@ class TearingAlgorithms /// path created by algoFracturePath sofa::type::vector m_fracturePath; + /// Vector of pointToAdd due to new fracture + type::vector< std::shared_ptr > m_pointsToAdd; + }; diff --git a/src/Tearing/TearingAlgorithms.inl b/src/Tearing/TearingAlgorithms.inl index f5673a7..c4fd82e 100644 --- a/src/Tearing/TearingAlgorithms.inl +++ b/src/Tearing/TearingAlgorithms.inl @@ -51,6 +51,22 @@ TearingAlgorithms::~TearingAlgorithms() } +template +void TearingAlgorithms::computeFracturePath(const Coord& pA, Index triId, const Coord pB, const Coord pC) +{ + +} + + + +template +void TearingAlgorithms::computeFracturePath(FracturePath& my_fracturePath) +{ + +} + + + template void TearingAlgorithms::algoFracturePath(Coord Pa, Index indexA, Coord Pb, Coord Pc, const Index indexTriangleMaxStress, const Coord principalStressDirection, const VecCoord& input_position) diff --git a/src/Tearing/TearingEngine.h b/src/Tearing/TearingEngine.h index 928f4e4..d56342d 100644 --- a/src/Tearing/TearingEngine.h +++ b/src/Tearing/TearingEngine.h @@ -71,7 +71,7 @@ class TearingEngine : public BaseTearingEngine using BaseTearingEngine::d_input_positions; using BaseTearingEngine::d_triangleIdsOverThreshold; - using BaseTearingEngine::fractureSegmentEndpoints; + using BaseTearingEngine::m_fracturePath; public: diff --git a/src/Tearing/TearingEngine.inl b/src/Tearing/TearingEngine.inl index cd2f619..5206ac6 100644 --- a/src/Tearing/TearingEngine.inl +++ b/src/Tearing/TearingEngine.inl @@ -160,16 +160,17 @@ void TearingEngine::algoFracturePath() template void TearingEngine::computeFracturePath() { - if (m_maxStressTriangleIndex != InvalidID) + // frist clear ereything + this->clearFracturePath(); + + if (m_maxStressTriangleIndex != InvalidID) // we have triangle to start and also a vertex id { //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 Pa = x[m_maxStressVertexIndex]; Coord Pb, Pc; - fractureSegmentEndpoints.clear(); if (this->d_fractureMaxLength.getValue() == 0.0) { computeEndPointsNeighboringTriangles(Pa, principalStressDirection, Pb, Pc); @@ -179,9 +180,12 @@ void TearingEngine::computeFracturePath() this->computeEndPoints(Pa, principalStressDirection, Pb, Pc); } - fractureSegmentEndpoints.push_back(Pb); - fractureSegmentEndpoints.push_back(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);