64 template<
typename FaceGraph,
66 std::vector<typename boost::graph_traits<FaceGraph>::edge_descriptor>
69 bool forbid_non_satisfying_link_condition,
70 bool forbid_non_manifold_edge,
71 bool forbid_edge_collapse_creating_non_manifold_split,
72 bool forbid_border_edge,
73 bool forbid_inner_edge,
74 bool forbid_non_triangular_incident_face_to_edge,
75 bool forbid_edges_that_are_adjacent_to_collapsed_edges,
76 bool forbid_edges_that_are_one_ring_edges_of_collapsed_edge_vertices,
77 bool forbid_edges_that_are_incident_to_opposite_vertices_of_collapsed_edge_vertices,
78 bool forbid_edges_that_are_incident_to_one_ring_of_collapsed_edge_vertices,
79 const std::set<
typename boost::graph_traits<FaceGraph>::edge_descriptor>& external_forbidden_edges_to_collapse,
80 const GeometryTraits >
84 std::vector<typename boost::graph_traits<FaceGraph>::edge_descriptor> batch_of_edges_to_collapse;
85 std::set<typename boost::graph_traits<FaceGraph>::edge_descriptor> forbidden_edges_to_collapse(external_forbidden_edges_to_collapse.begin(), external_forbidden_edges_to_collapse.end());
87 auto pm =
get(boost::vertex_point, g);
89 for (
auto edge_it = edge_range_mesh.begin(); edge_it != edge_range_mesh.end(); ++edge_it)
91 if (forbidden_edges_to_collapse.find(*edge_it) == forbidden_edges_to_collapse.end())
93 bool is_a_2_manifold_collapse = is_g_2_manifold ||
94 Helpers::is_2_manifold_edge(*edge_it);
95 bool edge_ok_for_collapse = is_g_2_manifold ||
96 !forbid_non_manifold_edge ||
97 ( is_a_2_manifold_collapse &&
98 Helpers::is_one_ring_2_manifold(
source(*edge_it, g)) &&
99 Helpers::is_one_ring_2_manifold(
target(*edge_it, g)));
109 if (forbid_edge_collapse_creating_non_manifold_split && edge_ok_for_collapse)
112 if (Helpers::is_surface_interior_edge(*edge_it) &&
113 Helpers::is_surface_border_vertex(
source(*edge_it, g)) &&
114 Helpers::is_surface_border_vertex(
target(*edge_it, g))
116 edge_ok_for_collapse =
false;
119 if (forbid_border_edge && edge_ok_for_collapse)
122 if (Helpers::is_surface_border_edge(*edge_it))
123 edge_ok_for_collapse =
false;
125 if (forbid_inner_edge && edge_ok_for_collapse)
128 if (Helpers::is_surface_interior_edge(*edge_it))
129 edge_ok_for_collapse =
false;
131 bool is_a_triangular_collapse =
true;
133 if (forbid_non_triangular_incident_face_to_edge && edge_ok_for_collapse )
138 edge_ok_for_collapse =
false;
139 is_a_triangular_collapse =
false;
143 if (forbid_non_triangular_incident_face_to_edge && is_a_2_manifold_collapse && is_a_triangular_collapse && edge_ok_for_collapse)
150 edge_ok_for_collapse =
false;
154 if (forbid_non_satisfying_link_condition && edge_ok_for_collapse)
158 auto iter_v1 = incident_v1_range.begin();
159 for (; (iter_v1 != incident_v1_range.end()) && edge_ok_for_collapse; ++iter_v1)
161 if (*iter_v1 ==
target(*edge_it, g))
163 auto iter_v2 = incident_v2_range.begin();
164 for (; iter_v2 != incident_v2_range.end(); ++iter_v2)
166 if (*iter_v2 ==
source(*edge_it, g))
168 if (*iter_v1 == *iter_v2)
170 typename boost::graph_traits<FaceGraph>::face_descriptor f = Helpers::common_face(Helpers::common_edge(
source(*edge_it, g), *iter_v1),
171 Helpers::common_edge(
target(*edge_it, g), *iter_v2)
175 if (f == Helpers::null_face())
177 edge_ok_for_collapse =
false;
180 else if ((
degree(Helpers::common_edge(
source(*edge_it, g), *iter_v1), g) == 1) &&
181 (
degree(Helpers::common_edge(
target(*edge_it, g), *iter_v2), g) == 1)
184 edge_ok_for_collapse =
false;
191 if (!edge_ok_for_collapse)
193 forbidden_edges_to_collapse.insert(*edge_it);
197 batch_of_edges_to_collapse.push_back(*edge_it);
202 if (forbid_edges_that_are_adjacent_to_collapsed_edges)
204 for (
auto it = v1_ad_container.begin(); it != v1_ad_container.end(); ++it)
206 if (*it == (*edge_it)->get_second_vertex())
208 forbidden_edges_to_collapse.insert(
edge(*it, (*edge_it)->get_first_vertex(), g).first);
211 for (
auto it = v2_ad_container.begin(); it != v2_ad_container.end(); ++it)
213 if (*it == (*edge_it)->get_first_vertex())
215 forbidden_edges_to_collapse.insert(
edge(*it, (*edge_it)->get_second_vertex(), g).first);
219 if (forbid_edges_that_are_one_ring_edges_of_collapsed_edge_vertices)
222 auto edge_set_v1 = Helpers::get_unordered_one_ring_edges((*edge_it)->get_first_vertex());
223 auto edge_set_v2 = Helpers::get_unordered_one_ring_edges((*edge_it)->get_second_vertex());
225 for (
auto it = edge_set_v1.begin(); it != edge_set_v1.end(); ++it)
227 forbidden_edges_to_collapse.insert(*it);
230 for (
auto it = edge_set_v2.begin(); it != edge_set_v2.end(); ++it)
232 forbidden_edges_to_collapse.insert(*it);
236 if (forbid_edges_that_are_incident_to_opposite_vertices_of_collapsed_edge_vertices)
242 auto f_range = Helpers::incident_faces(*edge_it);
243 auto iter_f = f_range.begin();
244 for (; iter_f != f_range.end(); ++iter_f)
246 auto v_range = Helpers::incident_vertices(*iter_f);
247 for (
auto iter_v = v_range.begin(); iter_v != v_range.end(); ++iter_v)
249 if ((*iter_v != (*edge_it)->get_first_vertex()) && (*iter_v != (*edge_it)->get_second_vertex()))
251 auto e_range = Helpers::incident_edges(*iter_v);
252 forbidden_edges_to_collapse.insert(e_range.begin(), e_range.end());
257 if (forbid_edges_that_are_incident_to_one_ring_of_collapsed_edge_vertices)
260 for (
auto it = v1_ad_container.begin(); it != v1_ad_container.end(); ++it)
262 auto edge_range = Helpers::incident_edges(*it);
264 for (
auto it2 = edge_range.begin(); it2 != edge_range.end(); ++it2)
266 forbidden_edges_to_collapse.insert(*it2);
270 for (
auto it = v2_ad_container.begin(); it != v2_ad_container.end(); ++it)
272 auto edge_range = Helpers::incident_edges(*it);
274 for (
auto it2 = edge_range.begin(); it2 != edge_range.end(); ++it2)
276 forbidden_edges_to_collapse.insert(*it2);
282 return batch_of_edges_to_collapse;
319 template<
typename FaceGraph,
321 std::vector<typename boost::graph_traits<FaceGraph>::edge_descriptor>
323 bool is_g_2_manifold,
324 bool forbid_non_satisfying_link_condition,
325 bool forbid_non_manifold_edge,
326 bool forbid_edge_collapse_creating_non_manifold_split,
327 bool forbid_border_edge,
328 bool forbid_inner_edge,
329 bool forbid_non_triangular_incident_face_to_edge,
330 bool forbid_edges_that_are_adjacent_to_collapsed_edges,
331 bool forbid_edges_that_are_one_ring_edges_of_collapsed_edge_vertices,
332 bool forbid_edges_that_are_incident_to_opposite_vertices_of_collapsed_edge_vertices,
333 bool forbid_edges_that_are_incident_to_one_ring_of_collapsed_edge_vertices,
334 const GeometryTraits >
337 std::set<typename boost::graph_traits<FaceGraph>::edge_descriptor> empty_external_forbidden_edges_to_collapse;
341 forbid_non_satisfying_link_condition,
342 forbid_non_manifold_edge,
343 forbid_edge_collapse_creating_non_manifold_split,
346 forbid_non_triangular_incident_face_to_edge,
347 forbid_edges_that_are_adjacent_to_collapsed_edges,
348 forbid_edges_that_are_one_ring_edges_of_collapsed_edge_vertices,
349 forbid_edges_that_are_incident_to_opposite_vertices_of_collapsed_edge_vertices,
350 forbid_edges_that_are_incident_to_one_ring_of_collapsed_edge_vertices,
351 empty_external_forbidden_edges_to_collapse,