Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,34 +53,40 @@ 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;
}

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<container::dynamic::TriangleSetTopologyModifier>(
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.";
}


Expand Down Expand Up @@ -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();
Expand All @@ -162,7 +171,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown()

case core::topology::ENDING_EVENT:
{
m_outTopoModifier->notifyEndingEvent();
l_topologyModifier->notifyEndingEvent();
break;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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<const sofa::core::topology::EdgesAdded*>(*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<const sofa::core::topology::PointsAdded*>(*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;
}

Expand All @@ -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;
}

Expand All @@ -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:
Expand All @@ -467,7 +476,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown()
};

++itBegin;
}
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Tetra2TriangleTopologicalMapping, container::dynamic::TriangleSetTopologyModifier, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topologyModifier;

protected:
Data<bool> d_flipNormals; ///< Flip Normal ? (Inverse point order when creating triangle)
Data<bool> d_noNewTriangles; ///< If true no new triangles are being created
Data<bool> d_noInitialTriangles; ///< If true the list of initial triangles is initially empty. Only additional triangles will be added in the list
sofa::type::vector<Index> addedTriangleIndex;
container::dynamic::TriangleSetTopologyModifier* m_outTopoModifier; ///< Pointer to the output topology modifier
};

} //namespace sofa::component::topology::mapping
27 changes: 25 additions & 2 deletions Sofa/framework/Core/src/sofa/core/topology/TopologicalMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,36 +81,59 @@ 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)
{
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)
{
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading