Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mapping] Implement tetrahedral-topological changes in SubsetTopologicalMapping #5106

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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 @@ -420,7 +420,7 @@ void SubsetTopologicalMapping::updateTopologicalMappingTopDown()
EdgeSetTopologyModifier *toEdgeMod = nullptr;
TriangleSetTopologyModifier *toTriangleMod = nullptr;
//QuadSetTopologyModifier *toQuadMod = nullptr;
//TetrahedronSetTopologyModifier *toTetrahedronMod = nullptr;
TetrahedronSetTopologyModifier *toTetrahedronMod = nullptr;
//HexahedronSetTopologyModifier *toHexahedronMod = nullptr;

toModel->getContext()->get(toPointMod);
Expand Down Expand Up @@ -941,6 +941,106 @@ void SubsetTopologicalMapping::updateTopologicalMappingTopDown()
break;
}

case core::topology::TETRAHEDRAADDED:
{
}

case core::topology::TETRAHEDRAREMOVED:
{
if (!d_handleTetrahedra.getValue()) break;
if (!toTetrahedronMod) toModel->getContext()->get(toTetrahedronMod);
if (!toTetrahedronMod) break;

// teRem is a pointer to the tetra elements that should be removed
// this change comes from the topology container in the source topology.
// So here, we have to update our data that maps between source and destination
// teD2S and teS2D, and also update the topology container of this model (the destination)
const TetrahedraRemoved *teRem = static_cast< const TetrahedraRemoved * >( topoChange );

// each tetra is an integer that specifies it's index in the source topology
sofa::type::vector<Index> tetra_array_buffer_source = teRem->getArray();

// we want to remove the elements in both source and destination
sofa::type::vector<Index> tetra_array_buffer_destination;
tetra_array_buffer_destination.reserve(tetra_array_buffer_source.size());

// for each tetra that should be removed, look up the correct tetra in the destination topology
for (auto &tetra_source : tetra_array_buffer_source)
{
Index tetra_destination = teS2D[tetra_source];
if (tetra_destination == sofa::InvalidID)
continue;
tetra_array_buffer_destination.push_back(tetra_destination);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like you are iterating twice over this array although you could have done it only once latter by appending the tetra_array_buffer_destination in a scoped if line 997

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I can change that. However, right now the changes are not applied correctly.
Do you see anything obvious that is missing? See error messages above.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if that is the reason, but you are working with the datas tS2D ans tD2S but those are for triangles. You should be modifying the datas teS2D and teD2S

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhhhh, I see. That makes much more sense. :D
Thanks! :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That solved some of the issues, but uncovered a much larger issue underneath. :D
See #5127

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thank you about that, we will take a look, this seems quite serious indeed.


msg_info() << "[" << count << "]TETRAHEDRAREMOVED : "
<< tetra_array_buffer_source.size() << " -> "
<< tetra_array_buffer_destination.size() << " : "
<< tetra_array_buffer_source << " -> "
<< tetra_array_buffer_destination;

// remove the tetra in the tS2D data (the mapping from source to destination topology)
// removal is done by looking up the tetra that should be removed,
// replacing the tetra with the tetra that is the last one in the data,
// and finally resizing the data so that the last tetra is dropped.
// So essentially placing the last tetra in the data to overwrite the tetra that should
// be removed from the data.
{
Index last_index = teS2D.size() -1;
for (auto &tetra_source : tetra_array_buffer_source)
{
Index tetra_destination = teS2D[tetra_source];

// we set the source tetra to invalid in the destination to source mapping,
// because we now remove it.
if (tetra_destination != sofa::InvalidID)
teD2S[tetra_destination] = sofa::InvalidID;

// get the tetra of the destination topology, that corresponds to the last tetra
// in the source topology
Index new_tetra_destination = teS2D[last_index];

// replace the destination tetra at the position where we remove a tetra
// in the source topology
teS2D[tetra_source] = new_tetra_destination;

// if that destination tetra is valid, and correctly maps back to the last
// tetra in the source topology, update the mapping from destination to source.
if (new_tetra_destination != sofa::InvalidID && teD2S[new_tetra_destination] == last_index)
teD2S[new_tetra_destination] = tetra_source;
--last_index;
}
teS2D.resize(teS2D.size() - tetra_array_buffer_source.size());
}

// the same for the D2S data, but also update the topology container of this model
if (!tetra_array_buffer_destination.empty())
{
toTetrahedronMod->removeTetrahedra(tetra_array_buffer_destination, false);
{
Index last_index = teD2S.size() -1;

for (auto &tetra_destination : tetra_array_buffer_destination)
{
Index tetra_source = teD2S[tetra_destination];

// now as a sanity check, we check that the source tetra is INVALID, because
// we set it to invalid when we updated the teS2D data
if (tetra_source != sofa::InvalidID)
msg_error() << "Invalid Tetra Remove";

Index new_tetra_source = teD2S[last_index];
teD2S[tetra_destination] = new_tetra_source;
if (new_tetra_source != sofa::InvalidID && teS2D[new_tetra_source] == last_index)
teS2D[new_tetra_source] = tetra_destination;
--last_index;
}
teD2S.resize(teD2S.size() - tetra_array_buffer_destination.size());
}
}
break;
}

default:
msg_error() << "Unknown topological change " << changeType;
break;
Expand Down