diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.cpp b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.cpp index 11f6ebbe178..a35827f6d7b 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.cpp +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.cpp @@ -53,10 +53,10 @@ void registerTetra2TriangleTopologicalMapping(sofa::core::ObjectFactory* factory Tetra2TriangleTopologicalMapping::Tetra2TriangleTopologicalMapping() : sofa::core::topology::TopologicalMapping() + , l_topologyModifier(initLink("modifier", "Optional link to a topology modifier")) , d_flipNormals(initData(&d_flipNormals, bool(false), "flipNormals", "Flip Normal ? (Inverse point order when creating triangle)")) , d_noNewTriangles(initData(&d_noNewTriangles, bool(false), "noNewTriangles", "If true no new triangles are being created")) , d_noInitialTriangles(initData(&d_noInitialTriangles, bool(false), "noInitialTriangles", "If true the list of initial triangles is initially empty. Only additional triangles will be added in the list")) - , m_outTopoModifier(nullptr) { m_inputType = geometry::ElementType::TETRAHEDRON; m_outputType = geometry::ElementType::TRIANGLE; @@ -64,23 +64,29 @@ Tetra2TriangleTopologicalMapping::Tetra2TriangleTopologicalMapping() void Tetra2TriangleTopologicalMapping::init() { - if (!this->checkTopologyInputTypes()) // method will display error message if false + sofa::core::topology::TopologicalMapping::init(); + + if (!this->checkMappingInputType() || !this->checkMappingOutputType()) { this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); return; } - container::dynamic::TriangleSetTopologyModifier* to_tstm; - toModel->getContext()->get(to_tstm); - if (!to_tstm) + if (!l_topologyModifier) { - msg_error() << "No TriangleSetTopologyModifier found in the output topology node '" - << toModel->getContext()->getName() << "'."; - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; + msg_info() << "Looking for a component of type TriangleSetTopologyModifier " + "in the output topology context (" + << toModel->getContext()->getName() <<")."; + + l_topologyModifier.set(toModel->getContext()->get( + core::objectmodel::BaseContext::SearchDirection::SearchUp)); } - else { - m_outTopoModifier = to_tstm; + + if (!l_topologyModifier) + { + msg_warning() << "No TriangleSetTopologyModifier found in output topology context (" + << toModel->getContext()->getName() << ") but has not been found. Dynamic " + "topological changes will not be supported."; } @@ -144,6 +150,9 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() if (this->d_componentState.getValue() != sofa::core::objectmodel::ComponentState::Valid) return; + if (!l_topologyModifier) + return; + SCOPED_TIMER("Update Tetra2TriangleTopologicalMapping"); auto itBegin=fromModel->beginChange(); @@ -162,7 +171,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() case core::topology::ENDING_EVENT: { - m_outTopoModifier->notifyEndingEvent(); + l_topologyModifier->notifyEndingEvent(); break; } @@ -227,7 +236,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() Loc2GlobVec.pop_back(); //pop last } - m_outTopoModifier->removeTriangles(triangles_to_remove, true, false); + l_topologyModifier->removeTriangles(triangles_to_remove, true, false); break; } @@ -279,7 +288,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() } // add new elements to output topology - m_outTopoModifier->addTriangles(triangles_to_create); + l_topologyModifier->addTriangles(triangles_to_create); // remove elements not anymore on part of the border sofa::type::vector< BaseMeshTopology::TriangleID > local_triangleId_to_remove; @@ -312,7 +321,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() } // remove old triangles - m_outTopoModifier->removeTriangles(local_triangleId_to_remove, true, false); + l_topologyModifier->removeTriangles(local_triangleId_to_remove, true, false); break; } case core::topology::TETRAHEDRAREMOVED: @@ -404,21 +413,21 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() } } - m_outTopoModifier->addTriangles(triangles_to_create); + l_topologyModifier->addTriangles(triangles_to_create); break; } case core::topology::EDGESADDED: { const auto* edgeAdded = static_cast(*itBegin); - m_outTopoModifier->addEdges(edgeAdded->edgeArray, edgeAdded->ancestorsList, edgeAdded->coefs); + l_topologyModifier->addEdges(edgeAdded->edgeArray, edgeAdded->ancestorsList, edgeAdded->coefs); break; } case core::topology::POINTSADDED: { const auto* pointAdded = static_cast(*itBegin); - m_outTopoModifier->addPoints(sofa::Size(pointAdded->getNbAddedVertices()), pointAdded->ancestorsList, pointAdded->coefs, true); + l_topologyModifier->addPoints(sofa::Size(pointAdded->getNbAddedVertices()), pointAdded->ancestorsList, pointAdded->coefs, true); break; } @@ -436,7 +445,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() Topology::SetIndices & tab_indices = indices; - m_outTopoModifier->removePoints(tab_indices, false); + l_topologyModifier->removePoints(tab_indices, false); break; } @@ -458,7 +467,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() Topology::SetIndices & tab_indices = indices; Topology::SetIndices & inv_tab_indices = inv_indices; - m_outTopoModifier->renumberPoints(tab_indices, inv_tab_indices, false); + l_topologyModifier->renumberPoints(tab_indices, inv_tab_indices, false); break; } default: @@ -467,7 +476,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() }; ++itBegin; - } + } } diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.h b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.h index e4b0f935cb8..976322f52fd 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.h +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.h @@ -80,12 +80,13 @@ class SOFA_COMPONENT_TOPOLOGY_MAPPING_API Tetra2TriangleTopologicalMapping : pub /// Method to check the topology mapping maps regarding the upper topology bool checkTopologies() override; + SingleLink l_topologyModifier; + protected: Data d_flipNormals; ///< Flip Normal ? (Inverse point order when creating triangle) Data d_noNewTriangles; ///< If true no new triangles are being created Data d_noInitialTriangles; ///< If true the list of initial triangles is initially empty. Only additional triangles will be added in the list sofa::type::vector addedTriangleIndex; - container::dynamic::TriangleSetTopologyModifier* m_outTopoModifier; ///< Pointer to the output topology modifier }; } //namespace sofa::component::topology::mapping diff --git a/Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.cpp b/Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.cpp index 72fb7de7b00..d46a347a7c1 100644 --- a/Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.cpp +++ b/Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.cpp @@ -81,21 +81,39 @@ void TopologicalMapping::dumpLoc2GlobVec() bool TopologicalMapping::checkTopologyInputTypes() +{ + bool res = checkMappingInputType(); + res = res && checkMappingOutputType(); + + res = res && compareInputTopologyType(); + res = res && compareOutputTopologyType(); + + return res; +} + +bool TopologicalMapping::checkMappingInputType() const { if (m_inputType == geometry::ElementType::UNKNOWN) { dmsg_error() << "The input ElementType has not been set. Define 'm_inputType' to the correct ElementType in the constructor."; return false; } + return true; +} +bool TopologicalMapping::checkMappingOutputType() const +{ if (m_outputType == geometry::ElementType::UNKNOWN) { dmsg_error() << "The output ElementType has not been set. Define 'm_outputType' to the correct ElementType in the constructor."; return false; } + return true; +} +bool TopologicalMapping::compareInputTopologyType() const +{ assert(fromModel.get()); - assert(toModel.get()); const ElementType inputTopologyType = fromModel->getTopologyType(); if (inputTopologyType != m_inputType) @@ -103,6 +121,12 @@ bool TopologicalMapping::checkTopologyInputTypes() msg_error() << "The type of the input topology '" << fromModel.getPath() << "' (" << elementTypeToString(inputTopologyType) << ") does not correspond to a valid '" << elementTypeToString(m_inputType) << "' topology."; return false; } + return true; +} + +bool TopologicalMapping::compareOutputTopologyType() const +{ + assert(toModel.get()); const ElementType outputTopologyType = toModel->getTopologyType(); if (outputTopologyType != m_outputType) @@ -110,7 +134,6 @@ bool TopologicalMapping::checkTopologyInputTypes() msg_error() << "The type of the output topology '" << toModel.getPath() << "' (" << elementTypeToString(outputTopologyType) << ") does not correspond to a valid '" << elementTypeToString(m_outputType) << "' topology."; return false; } - return true; } diff --git a/Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.h b/Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.h index b64096f1b01..3ec6f29fbf2 100644 --- a/Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.h +++ b/Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.h @@ -191,6 +191,11 @@ class SOFA_CORE_API TopologicalMapping : public virtual objectmodel::BaseObject protected: [[nodiscard]] bool checkTopologyInputTypes(); + [[nodiscard]] bool checkMappingInputType() const; + [[nodiscard]] bool checkMappingOutputType() const; + [[nodiscard]] bool compareInputTopologyType() const; + [[nodiscard]] bool compareOutputTopologyType() const; + public: /// Input source BaseTopology