diff --git a/src/InfinyToolkit/CarvingTools/BaseCarvingPerformer.h b/src/InfinyToolkit/CarvingTools/BaseCarvingPerformer.h index 8d8ed96..d015faf 100644 --- a/src/InfinyToolkit/CarvingTools/BaseCarvingPerformer.h +++ b/src/InfinyToolkit/CarvingTools/BaseCarvingPerformer.h @@ -55,7 +55,7 @@ class SOFA_INFINYTOOLKIT_API BaseCarvingPerformer virtual ~BaseCarvingPerformer(); - void clearContacts(); + virtual void clearContacts(); const std::string& getType() { return m_performerType; } diff --git a/src/InfinyToolkit/CarvingTools/RefineCarvingPerformer.cpp b/src/InfinyToolkit/CarvingTools/RefineCarvingPerformer.cpp index a650125..288951f 100644 --- a/src/InfinyToolkit/CarvingTools/RefineCarvingPerformer.cpp +++ b/src/InfinyToolkit/CarvingTools/RefineCarvingPerformer.cpp @@ -30,6 +30,7 @@ RefineCarvingPerformer::RefineCarvingPerformer(TetrahedronSetTopologyContainer:: , m_tetraAlgo(nullptr) { m_performerType = "RefineCarvingPerformer"; + m_doRefine = true; } @@ -51,6 +52,14 @@ bool RefineCarvingPerformer::initPerformer() return resInit; } +void RefineCarvingPerformer::clearContacts() +{ + BaseCarvingPerformer::clearContacts(); + m_tetra2Filter.clear(); + m_carvingPositions.clear(); + m_triIdsToFilter.clear(); +} + void RefineCarvingPerformer::filterContacts() { @@ -60,9 +69,11 @@ void RefineCarvingPerformer::filterContacts() const SReal& refineDistance = m_carvingMgr->d_refineDistance.getValue(); const SReal& carvingDistance = m_carvingMgr->d_carvingDistance.getValue(); m_tetra2Filter.clear(); - //m_tetra2Filter2.clear(); m_triIdsToFilter.clear(); + m_carvingPositions.clear(); + m_tetra2Carv.clear(); + // If triangle collision involved (only surface) take tetra behind the triangle, if close enough, for refinement for (contactInfo * cInfo : m_triangleContacts) { if (cInfo->dist > refineDistance) @@ -76,15 +87,17 @@ void RefineCarvingPerformer::filterContacts() continue; } + // Add the tetra behind the triangle to the list of tetra to refine m_tetra2Filter.insert(tetraAT[0]); + m_carvingPositions.push_back(cInfo->pointA); - //if (cInfo->dist <= carvingDistance) - // m_tetra2Filter2.push_back(tetraAT[0]); - - - carvingPosition = cInfo->pointA; + // Add the tetra behind the triangle to the list of tetra to carve if close enough + if (cInfo->dist <= carvingDistance) { + m_tetra2Carv.insert(tetraAT[0]); + } } + // If point collision involved (can be surface or inside) take all tetra around the point, if close enough, for refinement for (contactInfo * cInfo : m_pointContacts) { if (cInfo->dist > refineDistance) @@ -95,46 +108,34 @@ void RefineCarvingPerformer::filterContacts() for (auto tetraId : tetraAV) m_tetra2Filter.insert(tetraId); - if (cInfo->dist <= carvingDistance) { - const core::topology::BaseMeshTopology::TrianglesAroundVertex& triAV = m_topologyCon->getTrianglesAroundVertex(cInfo->elemId); - - for (auto triId : triAV) - m_triIdsToFilter.insert(triId); + if (cInfo->dist <= carvingDistance) + { + for (auto tetraId : tetraAV) + m_tetra2Carv.insert(tetraId); } - carvingPosition = cInfo->pointA; + m_carvingPositions.push_back(cInfo->pointA); } } bool RefineCarvingPerformer::runPerformer() { - if (!m_tetra2Filter.empty()) + // nothin to do if no tetra to refine + if (m_tetra2Filter.empty()) + return false; + + // will try to refine or carve but not the two at the same time for now, to avoid some conflict. + if (m_doRefine) { sofa::Size nbrTetra = m_topologyCon->getNbTetrahedra(); - bool res = m_tetraAlgo->refineTetrahedra(m_tetra2Filter, m_carvingMgr->d_refineCriteria.getValue()); - - if (res) - { -#if 0 - return res; -#else - sofa::Size nbrTetraNew = m_topologyCon->getNbTetrahedra(); - for (sofa::Index tetraId = nbrTetra; tetraId < nbrTetraNew; ++tetraId) - m_tetra2Filter.insert(tetraId); -#endif - } -#if 0 - else - { - surfaceCarving2(); - } -#else - simpleCarving(); -#endif - - - return res; + m_tetraAlgo->refineTetrahedra(m_tetra2Filter, m_carvingMgr->d_refineCriteria.getValue()); + m_doRefine = false; + } + else + { + m_tetraAlgo->removeTetrahedra(m_tetra2Carv); + m_doRefine = true; } return false; @@ -158,10 +159,16 @@ void RefineCarvingPerformer::simpleCarving() bary += vertices[tetra[j]]; } bary *= 0.25; - SReal dist = (carvingPosition - bary).norm(); - if (dist < carvingDistance) - tetraToremove.insert(tetraId); + for (const auto& carvingPos : m_carvingPositions) + { + SReal dist = (carvingPos - bary).norm(); + if (dist < carvingDistance) + { + tetraToremove.insert(tetraId); + break; + } + } } if (!tetraToremove.empty()) @@ -192,15 +199,19 @@ void RefineCarvingPerformer::surfaceCarving() for (auto pointId : pointsToCheck) { Vec3& vertex = vertices[pointId]; - Vec3 dir = vertex - carvingPosition; - const SReal dist = dir.norm(); - if (dist > carvingDistance) - continue; + for (const auto& carvingPos : m_carvingPositions) + { + Vec3 dir = vertex - carvingPos; + const SReal dist = dir.norm(); + + if (dist > carvingDistance) + continue; - SReal factor = (carvingDistance - dist)* invCarv; // ]0, carvingDistance] - msg_info("RefineCarvingPerformer") << "pointId: " << pointId << " | factor: " << factor << " | carvingDistance: " << carvingDistance << " | dist: " << dist; - vertex = vertex + dir * factor; + SReal factor = (carvingDistance - dist) * invCarv; // ]0, carvingDistance] + msg_info("RefineCarvingPerformer") << "pointId: " << pointId << " | factor: " << factor << " | carvingDistance: " << carvingDistance << " | dist: " << dist; + vertex = vertex + dir * factor; + } } } @@ -271,7 +282,7 @@ void RefineCarvingPerformer::surfaceCarving2() { Vec3 vertex = vertices[pId]; Vec3 dir = oppoPCoord - vertex; // normalise?? - const SReal dist = (vertex - carvingPosition).norm(); + const SReal dist = 0.0;// TODO check that (vertex - carvingPosition).norm(); if (dist > carvingDistance) continue; diff --git a/src/InfinyToolkit/CarvingTools/RefineCarvingPerformer.h b/src/InfinyToolkit/CarvingTools/RefineCarvingPerformer.h index 5eb744c..2846582 100644 --- a/src/InfinyToolkit/CarvingTools/RefineCarvingPerformer.h +++ b/src/InfinyToolkit/CarvingTools/RefineCarvingPerformer.h @@ -37,6 +37,8 @@ class SOFA_INFINYTOOLKIT_API RefineCarvingPerformer : public BaseCarvingPerforme bool initPerformer() override; + void clearContacts() override; + void filterContacts(); bool runPerformer() override; @@ -58,8 +60,10 @@ class SOFA_INFINYTOOLKIT_API RefineCarvingPerformer : public BaseCarvingPerforme sofa::type::vector m_tetra2Filter2; std::set m_triIdsToFilter; std::set m_triIds; + std::set m_tetra2Carv; - Vec3 carvingPosition; + std::vector m_carvingPositions; + bool m_doRefine = true; }; } // namespace sofa::infinytoolkit