do not collapse when the cells set for collapse does not represent a manifold surface

trying to make the cells set manifold is not easy, and quite costly, so let's just
check whether the cells set surface is manifold and cancel the collapse if not
This commit is contained in:
Jane Tournois 2020-07-01 06:32:27 +01:00
parent 7929922966
commit 2ae4e28de7
1 changed files with 65 additions and 61 deletions

View File

@ -54,12 +54,14 @@ class CollapseTriangulation
typedef typename C3t3::Cell_handle Cell_handle;
typedef typename C3t3::Vertex_handle Vertex_handle;
typedef typename C3t3::Subdomain_index Subdomain_index;
typedef typename C3t3::Surface_patch_index Surface_patch_index;
typedef typename C3t3::Triangulation::Point Point_3;
typedef typename C3t3::Triangulation::Geom_traits::Vector_3 Vector_3;
public:
CollapseTriangulation(C3t3& c3t3,
const Edge& e,
const std::unordered_set<Cell_handle>& cells_to_insert,
Collapse_type _collapse_type)
: collapse_type(_collapse_type)
, v0_init(e.first->vertex(e.second))
@ -68,14 +70,6 @@ public:
typedef std::array<int, 3> Facet; // 3 = id
typedef std::array<int, 5> Tet_with_ref; // first 4 = id, fifth = reference
std::unordered_set<Cell_handle> cells_to_insert;
c3t3.triangulation().finite_incident_cells(v0_init,
std::inserter(cells_to_insert, cells_to_insert.end()));
c3t3.triangulation().finite_incident_cells(v1_init,
std::inserter(cells_to_insert, cells_to_insert.end()));
make_cells_set_manifold(c3t3, cells_to_insert);
std::unordered_set<Vertex_handle> vertices_to_insert;
for (Cell_handle ch : cells_to_insert)
{
@ -144,58 +138,6 @@ public:
#endif
}
void make_cells_set_manifold(const C3t3& c3t3,
std::unordered_set<Cell_handle>& cells)
{
typedef Vertex_handle Vh;
typedef std::array<Vh, 3> FV;
typedef std::pair<Vh, Vh> EV;
boost::unordered_map<FV, int> facets;
for (Cell_handle c : cells)
{
for (int i = 0; i < 4; ++i)
{
const FV fvi = make_vertex_array(c->vertex((i + 1) % 4),
c->vertex((i + 2) % 4),
c->vertex((i + 3) % 4));
typename boost::unordered_map<FV, int>::iterator fit = facets.find(fvi);
if(fit == facets.end())
facets.insert(std::make_pair(fvi, 1));
else
fit->second++;
}
}
boost::unordered_map<EV, int> edges;
for (const std::pair<FV, int>& fvv : facets)
{
if(fvv.second != 1)
continue;
for (int i = 0; i < 3; ++i)
{
const EV evi = make_vertex_pair(fvv.first[i], fvv.first[(i + 1) % 3]);
typename boost::unordered_map<EV, int>::iterator eit = edges.find(evi);
if (eit == edges.end())
edges.insert(std::make_pair(evi, 1));
else
eit->second++;
}
}
for (const std::pair<EV, int>& evv : edges)
{
if (evv.second != 2)
{
c3t3.triangulation().finite_incident_cells(evv.first.first,
std::inserter(cells, cells.begin()));
c3t3.triangulation().finite_incident_cells(evv.first.second,
std::inserter(cells, cells.begin()));
}
}
}
Result_type collapse()
{
if (not_an_edge)
@ -1036,6 +978,55 @@ typename C3t3::Vertex_handle collapse(typename C3t3::Edge& edge,
return vh;
}
template<typename C3t3>
bool is_cells_set_manifold(const C3t3& c3t3,
std::unordered_set<typename C3t3::Cell_handle>& cells)
{
typedef typename C3t3::Cell_handle Cell_handle;
typedef typename C3t3::Vertex_handle Vh;
typedef std::array<Vh, 3> FV;
typedef std::pair<Vh, Vh> EV;
boost::unordered_map<FV, int> facets;
for (Cell_handle c : cells)
{
for (int i = 0; i < 4; ++i)
{
const FV fvi = make_vertex_array(c->vertex((i + 1) % 4),
c->vertex((i + 2) % 4),
c->vertex((i + 3) % 4));
typename boost::unordered_map<FV, int>::iterator fit = facets.find(fvi);
if (fit == facets.end())
facets.insert(std::make_pair(fvi, 1));
else
fit->second++;
}
}
boost::unordered_map<EV, int> edges;
for (const std::pair<FV, int>& fvv : facets)
{
if (fvv.second != 1)
continue;
for (int i = 0; i < 3; ++i)
{
const EV evi = make_vertex_pair(fvv.first[i], fvv.first[(i + 1) % 3]);
typename boost::unordered_map<EV, int>::iterator eit = edges.find(evi);
if (eit == edges.end())
edges.insert(std::make_pair(evi, 1));
else
eit->second++;
}
}
for (const std::pair<EV, int>& evv : edges)
if (evv.second != 2)
return false;
return true;
}
template<typename C3t3, typename CellSelector, typename Visitor>
typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge,
C3t3& c3t3,
@ -1047,6 +1038,7 @@ typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge,
typedef typename C3t3::Triangulation Tr;
typedef typename Tr::Point Point;
typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Cell_handle Cell_handle;
const Vertex_handle v0 = edge.first->vertex(edge.second);
const Vertex_handle v1 = edge.first->vertex(edge.third);
@ -1119,7 +1111,19 @@ typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge,
CGAL_assertion(c3t3.triangulation().is_edge(edge.first->vertex(edge.second),
edge.first->vertex(edge.third), dc, di, dj));
CollapseTriangulation<C3t3> local_tri(c3t3, edge, collapse_type);
Vertex_handle v0_init = edge.first->vertex(edge.second);
Vertex_handle v1_init = edge.first->vertex(edge.third);
std::unordered_set<Cell_handle> cells_to_insert;
c3t3.triangulation().finite_incident_cells(v0_init,
std::inserter(cells_to_insert, cells_to_insert.end()));
c3t3.triangulation().finite_incident_cells(v1_init,
std::inserter(cells_to_insert, cells_to_insert.end()));
if(!is_cells_set_manifold(c3t3, cells_to_insert))
return Vertex_handle();
CollapseTriangulation<C3t3> local_tri(c3t3, edge, cells_to_insert, collapse_type);
Result_type res = local_tri.collapse();
if (res == VALID)