Skip to content
Merged
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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -49,107 +49,112 @@ int SimpleTesselatedTetraTopologicalMappingClass = core::RegisterObject ( "Speci

// Implementation
SimpleTesselatedTetraTopologicalMapping::SimpleTesselatedTetraTopologicalMapping ()
: tetrahedraMappedFromTetra( initData ( &tetrahedraMappedFromTetra, "tetrahedraMappedFromTetra", "Each Tetrahedron of the input topology is mapped to the 8 tetrahedrons in which it can be divided")),
tetraSource( initData ( &tetraSource, "tetraSource", "Which tetra from the input topology map to a given tetra in the output topology (sofa::InvalidID if none)")),
d_pointMappedFromPoint( initData ( &d_pointMappedFromPoint, "pointMappedFromPoint", "Each point of the input topology is mapped to the same point")),
d_pointMappedFromEdge( initData ( &d_pointMappedFromEdge, "pointMappedFromEdge", "Each edge of the input topology is mapped to his midpoint")),
d_pointSource( initData ( &d_pointSource, "pointSource", "Which input topology element map to a given point in the output topology : 0 -> none, > 0 -> point index + 1, < 0 , - edge index -1"))
: sofa::core::topology::TopologicalMapping()
, tetrahedraMappedFromTetra( initData ( &tetrahedraMappedFromTetra, "tetrahedraMappedFromTetra", "Each Tetrahedron of the input topology is mapped to the 8 tetrahedrons in which it can be divided"))
, tetraSource( initData ( &tetraSource, "tetraSource", "Which tetra from the input topology map to a given tetra in the output topology (sofa::InvalidID if none)"))
, d_pointMappedFromPoint( initData ( &d_pointMappedFromPoint, "pointMappedFromPoint", "Each point of the input topology is mapped to the same point"))
, d_pointMappedFromEdge( initData ( &d_pointMappedFromEdge, "pointMappedFromEdge", "Each edge of the input topology is mapped to his midpoint"))
, d_pointSource( initData ( &d_pointSource, "pointSource", "Which input topology element map to a given point in the output topology : 0 -> none, > 0 -> point index + 1, < 0 , - edge index -1"))
{
m_inputType = TopologyElementType::TETRAHEDRON;
m_outputType = TopologyElementType::TETRAHEDRON;
}

void SimpleTesselatedTetraTopologicalMapping::init()
{
if(fromModel)
// Check input/output topology
if (!this->checkTopologyInputTypes()) // method will display error message if false
{
TetrahedronSetTopologyContainer *from_tstc;
fromModel->getContext()->get(from_tstc);
if(toModel)
{
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}

helper::WriteAccessor< Data< sofa::type::vector<Index> > > pointSourceData = d_pointSource;
helper::WriteAccessor< Data< sofa::type::vector<Index> > > pointMappedFromPointData = d_pointMappedFromPoint;
helper::WriteAccessor< Data< sofa::type::vector<Index> > > pointMappedFromEdgeData = d_pointMappedFromEdge;

sofa::type::vector<type::fixed_array<Index, 8> >& tetrahedraMappedFromTetraData = *(tetrahedraMappedFromTetra.beginEdit());
type::vector<Index>& tetraSourceData = *(tetraSource.beginEdit());
TetrahedronSetTopologyContainer *from_tstc;
fromModel->getContext()->get(from_tstc);

TetrahedronSetTopologyContainer *to_tstc;
toModel->getContext()->get(to_tstc);
to_tstc->clear();
if(!from_tstc->hasPos())
{
helper::WriteAccessor< Data< sofa::type::vector<Index> > > pointSourceData = d_pointSource;
helper::WriteAccessor< Data< sofa::type::vector<Index> > > pointMappedFromPointData = d_pointMappedFromPoint;
helper::WriteAccessor< Data< sofa::type::vector<Index> > > pointMappedFromEdgeData = d_pointMappedFromEdge;

sofa::type::vector<type::fixed_array<Index, 8> >& tetrahedraMappedFromTetraData = *(tetrahedraMappedFromTetra.beginEdit());
type::vector<Index>& tetraSourceData = *(tetraSource.beginEdit());

TetrahedronSetTopologyContainer *to_tstc;
toModel->getContext()->get(to_tstc);
to_tstc->clear();
if(!from_tstc->hasPos())
{
// MeshLoader *mshLoader;
// fromModel->getContext()->get(mshLoader);
// from_tstc->loadFromMeshLoader(mshLoader);
}
}

pointSourceData.resize(from_tstc->getNbPoints()+from_tstc->getNbEdges());
pointSourceData.resize(from_tstc->getNbPoints()+from_tstc->getNbEdges());


for (std::size_t i=0; i<from_tstc->getNbPoints(); i++)
{
to_tstc->addPoint(from_tstc->getPX(i), from_tstc->getPY(i), from_tstc->getPZ(i));
for (std::size_t i=0; i<from_tstc->getNbPoints(); i++)
{
to_tstc->addPoint(from_tstc->getPX(i), from_tstc->getPY(i), from_tstc->getPZ(i));

pointMappedFromPointData.push_back(i);
pointSourceData[i] = i+1;
}
pointMappedFromPointData.push_back(i);
pointSourceData[i] = i+1;
}

Index newPointIndex = to_tstc->getNbPoints();
Index newPointIndex = to_tstc->getNbPoints();

for (unsigned int i=0; i<from_tstc->getNbEdges(); i++)
{
Edge e = from_tstc->getEdge(i);
for (unsigned int i=0; i<from_tstc->getNbEdges(); i++)
{
Edge e = from_tstc->getEdge(i);

to_tstc->addPoint(
(from_tstc->getPX(e[0]) + from_tstc->getPX(e[1]))/2,
(from_tstc->getPY(e[0]) + from_tstc->getPY(e[1]))/2,
(from_tstc->getPZ(e[0]) + from_tstc->getPZ(e[1]))/2
);
to_tstc->addPoint(
(from_tstc->getPX(e[0]) + from_tstc->getPX(e[1]))/2,
(from_tstc->getPY(e[0]) + from_tstc->getPY(e[1]))/2,
(from_tstc->getPZ(e[0]) + from_tstc->getPZ(e[1]))/2
);

pointMappedFromEdgeData.push_back(newPointIndex);
pointSourceData[newPointIndex] = -(i+1);
newPointIndex++;
}
pointMappedFromEdgeData.push_back(newPointIndex);
pointSourceData[newPointIndex] = -(i+1);
newPointIndex++;
}

fixed_array <Index, 8> newTetrahedraIndices;
unsigned int newTetraIndex = (unsigned int)to_tstc->getNbTetrahedra();
fixed_array <Index, 8> newTetrahedraIndices;
unsigned int newTetraIndex = (unsigned int)to_tstc->getNbTetrahedra();

tetraSourceData.resize(8*from_tstc->getNbTetrahedra());
tetraSourceData.resize(8*from_tstc->getNbTetrahedra());

for (unsigned int i=0; i<from_tstc->getNbTetrahedra(); i++)
{
core::topology::BaseMeshTopology::Tetra t = from_tstc->getTetrahedron(i);
core::topology::BaseMeshTopology::EdgesInTetrahedron e = from_tstc->getEdgesInTetrahedron(i);
to_tstc->addTetra(t[0], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[1]], pointMappedFromEdgeData[e[2]]);
newTetrahedraIndices[0] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;
for (unsigned int i=0; i<from_tstc->getNbTetrahedra(); i++)
{
core::topology::BaseMeshTopology::Tetra t = from_tstc->getTetrahedron(i);
core::topology::BaseMeshTopology::EdgesInTetrahedron e = from_tstc->getEdgesInTetrahedron(i);
to_tstc->addTetra(t[0], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[1]], pointMappedFromEdgeData[e[2]]);
newTetrahedraIndices[0] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;

to_tstc->addTetra(t[1], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[4]], pointMappedFromEdgeData[e[3]]);
newTetrahedraIndices[1] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;
to_tstc->addTetra(t[1], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[4]], pointMappedFromEdgeData[e[3]]);
newTetrahedraIndices[1] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;

to_tstc->addTetra(t[2], pointMappedFromEdgeData[e[1]], pointMappedFromEdgeData[e[3]], pointMappedFromEdgeData[e[5]]);
newTetrahedraIndices[2] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;
to_tstc->addTetra(t[2], pointMappedFromEdgeData[e[1]], pointMappedFromEdgeData[e[3]], pointMappedFromEdgeData[e[5]]);
newTetrahedraIndices[2] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;

to_tstc->addTetra(t[3], pointMappedFromEdgeData[e[2]], pointMappedFromEdgeData[e[5]], pointMappedFromEdgeData[e[4]]);
newTetrahedraIndices[3] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;
to_tstc->addTetra(t[3], pointMappedFromEdgeData[e[2]], pointMappedFromEdgeData[e[5]], pointMappedFromEdgeData[e[4]]);
newTetrahedraIndices[3] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;

to_tstc->addTetra(pointMappedFromEdgeData[e[1]], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[3]], pointMappedFromEdgeData[e[5]]);
newTetrahedraIndices[4] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;
to_tstc->addTetra(pointMappedFromEdgeData[e[1]], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[3]], pointMappedFromEdgeData[e[5]]);
newTetrahedraIndices[4] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;

to_tstc->addTetra(pointMappedFromEdgeData[e[1]], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[5]], pointMappedFromEdgeData[e[2]]);
newTetrahedraIndices[5] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;
to_tstc->addTetra(pointMappedFromEdgeData[e[1]], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[5]], pointMappedFromEdgeData[e[2]]);
newTetrahedraIndices[5] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;

to_tstc->addTetra(pointMappedFromEdgeData[e[4]], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[5]], pointMappedFromEdgeData[e[3]]);
newTetrahedraIndices[6] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;
to_tstc->addTetra(pointMappedFromEdgeData[e[4]], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[5]], pointMappedFromEdgeData[e[3]]);
newTetrahedraIndices[6] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;

to_tstc->addTetra(pointMappedFromEdgeData[e[4]], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[2]], pointMappedFromEdgeData[e[5]]);
newTetrahedraIndices[7] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;
to_tstc->addTetra(pointMappedFromEdgeData[e[4]], pointMappedFromEdgeData[e[0]], pointMappedFromEdgeData[e[2]], pointMappedFromEdgeData[e[5]]);
newTetrahedraIndices[7] = newTetraIndex; tetraSourceData[newTetraIndex] = i; newTetraIndex++;

tetrahedraMappedFromTetraData.push_back(newTetrahedraIndices);
}
toModel->init();
tetrahedraMappedFromTetra.endEdit();
}
tetrahedraMappedFromTetraData.push_back(newTetrahedraIndices);
}
toModel->init();
tetrahedraMappedFromTetra.endEdit();
}

void SimpleTesselatedTetraTopologicalMapping::updateTopologicalMappingBottomUp()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -540,20 +540,21 @@ void MeshTopology::init()
const auto triangles = sofa::helper::getReadAccessor(seqTriangles);
const auto edges = sofa::helper::getReadAccessor(seqEdges);

if (nbPoints==0)
{
// looking for upper topology
if (!hexahedra.empty())
m_upperElementType = core::topology::TopologyElementType::HEXAHEDRON;
else if (!tetrahedra.empty())
m_upperElementType = sofa::core::topology::TopologyElementType::TETRAHEDRON;
else if (!quads.empty())
m_upperElementType = sofa::core::topology::TopologyElementType::QUAD;
else if (!triangles.empty())
m_upperElementType = sofa::core::topology::TopologyElementType::TRIANGLE;
else
m_upperElementType = sofa::core::topology::TopologyElementType::EDGE;
}

// looking for upper topology
if (!hexahedra.empty())
m_upperElementType = core::topology::TopologyElementType::HEXAHEDRON;
else if (!tetrahedra.empty())
m_upperElementType = sofa::core::topology::TopologyElementType::TETRAHEDRON;
else if (!quads.empty())
m_upperElementType = sofa::core::topology::TopologyElementType::QUAD;
else if (!triangles.empty())
m_upperElementType = sofa::core::topology::TopologyElementType::TRIANGLE;
else if (!edges.empty())
m_upperElementType = sofa::core::topology::TopologyElementType::EDGE;
else
m_upperElementType = sofa::core::topology::TopologyElementType::POINT;


// compute the number of points, if the topology is charged from the scene or if it was loaded from a MeshLoader without any points data.
if (nbPoints==0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ Edge2QuadTopologicalMapping::Edge2QuadTopologicalMapping()
, d_edgeList(initData(&d_edgeList, "edgeList", "list of input edges for the topological mapping: by default, all considered"))
, d_flipNormals(initData(&d_flipNormals, bool(false), "flipNormals", "Flip Normal ? (Inverse point order when creating quad)"))
{
m_inputType = TopologyElementType::EDGE;
m_outputType = TopologyElementType::QUAD;
}

void Edge2QuadTopologicalMapping::init()
Expand Down Expand Up @@ -98,6 +100,14 @@ void Edge2QuadTopologicalMapping::init()

unsigned int N = d_nbPointsOnEachCircle.getValue();

// Check input/output topology
if (!this->checkTopologyInputTypes()) // method will display error message if false
{
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}


// INITIALISATION of QUADULAR mesh from EDGE mesh :
core::behavior::MechanicalState<Rigid3Types>* from_mstate = dynamic_cast<core::behavior::MechanicalState<Rigid3Types>*>(fromModel->getContext()->getMechanicalState());
core::behavior::MechanicalState<Vec3Types>* to_mstate = dynamic_cast<core::behavior::MechanicalState<Vec3Types>*>(toModel->getContext()->getMechanicalState());
Expand Down Expand Up @@ -266,6 +276,12 @@ void Edge2QuadTopologicalMapping::init()
}

}
else
{
// Check type Rigid3 of input mechanical object (required)
msg_error() << "Mechanical object associated with the input is not of type Rigid. Edge2QuadTopologicalMapping only supports Rigid3Types to Vec3Types";
d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,50 +54,29 @@ int Hexa2QuadTopologicalMappingClass = core::RegisterObject("Special case of map
// Implementation

Hexa2QuadTopologicalMapping::Hexa2QuadTopologicalMapping()
: flipNormals(initData(&flipNormals, bool(false), "flipNormals", "Flip Normal ? (Inverse point order when creating triangle)"))
: sofa::core::topology::TopologicalMapping()
, flipNormals(initData(&flipNormals, bool(false), "flipNormals", "Flip Normal ? (Inverse point order when creating triangle)"))
{
m_inputType = TopologyElementType::HEXAHEDRON;
m_outputType = TopologyElementType::QUAD;
}

void Hexa2QuadTopologicalMapping::init()
{
using namespace container::dynamic;

bool modelsOk = true;
if (!fromModel)
if (!this->checkTopologyInputTypes()) // method will display error message if false
{
// If the input topology link isn't set by the user, the TopologicalMapping::create method tries to find it.
// If it is null at this point, it means no input mesh topology could be found.
msg_error() << "No input mesh topology found. Consider setting the '" << fromModel.getName() << "' data attribute.";
modelsOk = false;
}

if (!toModel)
{
// If the output topology link isn't set by the user, the TopologicalMapping::create method tries to find it.
// If it is null at this point, it means no output mesh topology could be found.
msg_error() << "No output mesh topology found. Consider setting the '" << toModel.getName() << "' data attribute.";
modelsOk = false;
}

// Making sure the output topology is derived from the quad topology container
if (!dynamic_cast<QuadSetTopologyContainer *>(toModel.get())) {
msg_error() << "The output topology '" << toModel.getPath() << "' is not a derived class of QuadSetTopologyContainer. "
<< "Consider setting the '" << toModel.getName() << "' data attribute to a valid"
" QuadSetTopologyContainer derived object.";
modelsOk = false;
} else {
// Making sure a topology modifier exists at the same level as the output topology
QuadSetTopologyModifier *to_tstm;
toModel->getContext()->get(to_tstm);
if (!to_tstm) {
msg_error() << "No QuadSetTopologyModifier found in the output topology node '"
<< toModel->getContext()->getName() << "'.";
modelsOk = false;
}
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}

if (!modelsOk)
{
// Making sure a topology modifier exists at the same level as the output topology
QuadSetTopologyModifier *to_tstm;
toModel->getContext()->get(to_tstm);
if (!to_tstm) {
msg_error() << "No QuadSetTopologyModifier found in the output topology node '"
<< toModel->getContext()->getName() << "'.";
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ int Hexa2TetraTopologicalMappingClass = core::RegisterObject("Special case of ma
// Implementation

Hexa2TetraTopologicalMapping::Hexa2TetraTopologicalMapping()
: swapping(initData(&swapping, false, "swapping","Boolean enabling to swapp hexa-edges\n in order to avoid bias effect"))
: sofa::core::topology::TopologicalMapping()
, swapping(initData(&swapping, false, "swapping","Boolean enabling to swapp hexa-edges\n in order to avoid bias effect"))
{
m_inputType = TopologyElementType::HEXAHEDRON;
m_outputType = TopologyElementType::TETRAHEDRON;
}

Hexa2TetraTopologicalMapping::~Hexa2TetraTopologicalMapping()
Expand All @@ -67,38 +70,23 @@ void Hexa2TetraTopologicalMapping::init()
{
using namespace container::dynamic;

// INITIALISATION of TETRAHEDRAL mesh from HEXAHEDRAL mesh :

// recheck models
bool modelsOk = true;
if (!fromModel)
{
msg_error() << "Pointer to input topology is invalid.";
modelsOk = false;
}

if (!toModel)
{
msg_error() << "Pointer to output topology is invalid.";
modelsOk = false;
}
else
if (!this->checkTopologyInputTypes()) // method will display error message if false
{
TetrahedronSetTopologyModifier *to_tstm;
toModel->getContext()->get(to_tstm);
if (!to_tstm)
{
msg_error() << "No TetrahedronSetTopologyModifier found in the Tetrahedron topology Node.";
modelsOk = false;
}
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}

if (!modelsOk)
TetrahedronSetTopologyModifier* to_tstm;
toModel->getContext()->get(to_tstm);
if (!to_tstm)
{
msg_error() << "No TetrahedronSetTopologyModifier found in the Tetrahedron topology Node.";
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}

// INITIALISATION of TETRAHEDRAL mesh from HEXAHEDRAL mesh :

TetrahedronSetTopologyContainer *to_tstc;
toModel->getContext()->get(to_tstc);
// Clear output topology
Expand Down
Loading