MEPP2 Project
similarity.hpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 #pragma once
12 
13 #include <boost/graph/graph_traits.hpp>
15 
16 #include <vector>
17 #include <set>
18 
19 namespace FEVV {
20 namespace Operators {
21 
34 template< typename MutableFaceIncidentGraph >
35 static void
36 replace_similar_edges(typename boost::graph_traits<
37  MutableFaceIncidentGraph >::face_descriptor face,
38  const typename boost::graph_traits<
39  MutableFaceIncidentGraph >::edge_descriptor old_edge,
40  const typename boost::graph_traits<
41  MutableFaceIncidentGraph >::edge_descriptor new_edge,
42  MutableFaceIncidentGraph &g)
43 {
44  if(Operators::are_similar_edges(old_edge, new_edge, g))
45  {
46  auto edges_range_pair = out_edges(face, g);
47  auto iter_e = edges_range_pair.first;
48  for(; iter_e != edges_range_pair.second; ++iter_e)
49  if(*iter_e == old_edge)
50  *iter_e = new_edge;
51  }
52 }
53 
67 template< typename MutableFaceIncidentGraph >
68 static void
70  typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor
71  e_to_keep,
72  typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor
73  e_to_remove,
74  MutableFaceIncidentGraph &g)
75 {
76  auto faces_range_pair = in_edges(e_to_remove, g);
77  auto iter_f = faces_range_pair.first;
78  for(; iter_f != faces_range_pair.second;
79  ++iter_f) // for each face *iter_f incident to e_to_remove
80  {
81  // each time e_to_remove appears into a face *iter_f, it is replaced by
82  // e_to_keep
83  replace_similar_edges(*iter_f, e_to_remove, e_to_keep, g);
84  // the kept edge must be linked to former faces incident to e_to_remove
85  add_in_edge(e_to_keep, *iter_f);
86  }
87 }
88 
100 template< typename MutableFaceIncidentGraph >
101 static void
104  v_to_keep,
105  MutableFaceIncidentGraph &g)
106 {
107  typedef
108  typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor
109  edge_descriptor;
110  std::vector< edge_descriptor > edges_to_remove;
112  auto edges_range_pair = in_edges(v_to_keep, g);
113  auto iter_e = edges_range_pair.first;
114  for(; iter_e != edges_range_pair.second; ++iter_e)
115  {
116  auto iter_e_bis = iter_e;
117  ++iter_e_bis;
118  for(; iter_e_bis != edges_range_pair.second; ++iter_e_bis)
119  {
120  if(Operators::are_similar_edges(*iter_e, *iter_e_bis, g))
121  {
122  edges_to_remove.push_back(*iter_e_bis);
123  merge_similar_edges(*iter_e, *iter_e_bis, g);
124  }
125  }
126  }
128  typename std::vector< edge_descriptor >::iterator it_e(
129  edges_to_remove.begin()),
130  it_ee(edges_to_remove.end());
131  for(; it_e != it_ee; ++it_e)
132  remove_edge(*it_e, g);
133  edges_to_remove.clear();
134 }
135 
148 template< typename MutableFaceIncidentGraph >
149 static void
152  v_to_keep,
153  MutableFaceIncidentGraph &g,
154  bool take_into_account_face_rientation = false)
155 {
156  typedef
157  typename boost::graph_traits< MutableFaceIncidentGraph >::face_descriptor
158  face_descriptor;
159  std::vector< face_descriptor > faces_to_remove;
160  std::set< face_descriptor > incident_faces;
162  auto edges_range_pair = in_edges(v_to_keep, g); // incident edges
163  auto iter_e = edges_range_pair.first;
164  for(; iter_e != edges_range_pair.second; ++iter_e)
165  {
166  auto faces_range_pair = in_edges(*iter_e, g); // incident faces
167  incident_faces.insert(faces_range_pair.first, faces_range_pair.second);
168  }
170  auto iter_f = incident_faces.begin();
171  for(; iter_f != incident_faces.end(); ++iter_f)
172  {
173  if(std::find(faces_to_remove.begin(), faces_to_remove.end(), *iter_f) !=
174  faces_to_remove.end())
175  continue;
176  auto iter_f_bis = iter_f;
177  ++iter_f_bis;
178  for(; iter_f_bis != incident_faces.end(); ++iter_f_bis)
179  {
181  *iter_f, *iter_f_bis, g, take_into_account_face_rientation))
182  {
183  if(std::find(
184  faces_to_remove.begin(), faces_to_remove.end(), *iter_f_bis) ==
185  faces_to_remove
186  .end()) // ensure to suppress each similar face only once
187  faces_to_remove.push_back(*iter_f_bis);
188  }
189  }
190  }
192  typename std::vector< face_descriptor >::iterator it_f(
193  faces_to_remove.begin()),
194  it_fe(faces_to_remove.end());
195  for(; it_f != it_fe; ++it_f)
196  remove_face(*it_f, g); // REDUNDANT FACES ARE REMOVED
197  faces_to_remove.clear();
198 }
199 
214 template<typename MutableFaceIncidentGraph>
215 static std::vector<std::pair<typename boost::graph_traits<MutableFaceIncidentGraph>::face_descriptor, bool>>
217  MutableFaceIncidentGraph& g,
218  const std::set<typename boost::graph_traits<MutableFaceIncidentGraph>::face_descriptor>&
219  faces_to_preserve_range,
220  bool take_into_account_face_rientation)
221 {
222  typedef
223  typename boost::graph_traits< MutableFaceIncidentGraph >::face_descriptor
224  face_descriptor;
225  std::vector< face_descriptor > faces_to_remove;
226  std::set< face_descriptor > incident_faces;
228  auto edges_range_pair = in_edges(v_to_keep, g); // incident edges
229  auto iter_e = edges_range_pair.first;
230  for(; iter_e != edges_range_pair.second; ++iter_e)
231  {
232  auto faces_range_pair = in_edges(*iter_e, g); // incident faces
233  incident_faces.insert(faces_range_pair.first, faces_range_pair.second);
234  }
236  std::vector< std::pair<face_descriptor, bool> > faces_to_duplicate ;
237  auto iter_f = incident_faces.begin();
238  for (; iter_f != incident_faces.end(); ++iter_f)
239  {
240  if (std::find(faces_to_remove.begin(), faces_to_remove.end(), *iter_f) != faces_to_remove.end())
241  continue;
242  auto iter_f_bis = iter_f;
243  ++iter_f_bis;
244  for (; iter_f_bis != incident_faces.end(); ++iter_f_bis)
245  {
246  if (FEVV::Operators::are_similar_faces(*iter_f, *iter_f_bis, g, take_into_account_face_rientation))
247  {
248  bool inverse_orientation = !FEVV::Operators::are_similar_faces(*iter_f, *iter_f_bis, g, true);
249  if (std::find(faces_to_remove.begin(), faces_to_remove.end(), *iter_f_bis) == faces_to_remove.end()) // ensure to suppress each similar face only once
250  {
251  // to chose between the removal of *iter_f and *iter_f_bis, we use faces_to_preserve_range
252  if (std::find(faces_to_preserve_range.begin(), faces_to_preserve_range.end(), *iter_f_bis) == faces_to_preserve_range.end())
253  {
254  faces_to_duplicate.push_back(std::make_pair(*iter_f, inverse_orientation));
255  faces_to_remove.push_back(*iter_f_bis);
256  }
257  else
258  {
259  faces_to_duplicate.push_back(std::make_pair(*iter_f_bis, inverse_orientation));
260  faces_to_remove.push_back(*iter_f);
261  }
262  }
263  }
264  }
265  }
267  typename std::vector<face_descriptor>::iterator itF(faces_to_remove.begin()),
268  itFe(faces_to_remove.end());
269  unsigned int cpt = 0;
270  for (; itF != itFe; ++itF)
271  {
272  remove_face(*itF, g); // REDUNDANT FACES ARE REMOVED
273  ++cpt;
274  }
275  faces_to_remove.clear();
276 
277  return faces_to_duplicate;
278 }
279 
280 } // namespace Operators
281 } // namespace FEVV
FEVV::DataStructures::AIF::add_in_edge
void add_in_edge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_descriptor f)
Definition: Graph_traits_aif.h:995
FEVV::Operators::are_similar_faces
static bool are_similar_faces(const typename boost::graph_traits< FaceIncidentGraph >::face_descriptor f1, const typename boost::graph_traits< FaceIncidentGraph >::face_descriptor f2, const FaceIncidentGraph &g, bool take_into_account_face_rientation=false)
Function determining if the arguments are similar faces (parallel faces).
Definition: topology_predicates.hpp:99
FEVV::Operators::resolve_similar_incident_faces
static void resolve_similar_incident_faces(typename boost::graph_traits< MutableFaceIncidentGraph >::vertex_descriptor v_to_keep, MutableFaceIncidentGraph &g, bool take_into_account_face_rientation=false)
Remove/resolve similar faces for all incident faces of v_to_keep vertex.
Definition: similarity.hpp:150
FEVV::DataStructures::AIF::out_edges
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::out_edge_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::out_edge_iterator > out_edges(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor u, const FEVV::DataStructures::AIF::AIFMesh &)
Definition: Graph_traits_aif.h:416
FEVV::DataStructures::AIF::remove_edge
void remove_edge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, FEVV::DataStructures::AIF::AIFMesh &sm)
Remove edge e.
Definition: Graph_traits_aif.h:858
topology_predicates.hpp
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::Operators::merge_similar_edges
static void merge_similar_edges(typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor e_to_keep, typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor e_to_remove, MutableFaceIncidentGraph &g)
For all faces incident to e_to_remove, if e_to_keep and e_to_remove were similar/parallel edges then ...
Definition: similarity.hpp:69
FEVV::DataStructures::AIF::in_edges
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::in_edge_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::in_edge_iterator > in_edges(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor u, const FEVV::DataStructures::AIF::AIFMesh &)
Definition: Graph_traits_aif.h:451
FEVV::Operators::resolve_similar_incident_edges
static void resolve_similar_incident_edges(typename boost::graph_traits< MutableFaceIncidentGraph >::vertex_descriptor v_to_keep, MutableFaceIncidentGraph &g)
Remove/resolve similar/parallel edges for all incident edges of v_to_keep vertex.
Definition: similarity.hpp:102
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
FEVV::Operators::are_similar_edges
static bool are_similar_edges(const typename boost::graph_traits< FaceIncidentGraph >::edge_descriptor edge1, const typename boost::graph_traits< FaceIncidentGraph >::edge_descriptor edge2, const FaceIncidentGraph &g)
Function determining if the arguments are similar edges (parallel edges).
Definition: topology_predicates.hpp:33
FEVV::DataStructures::AIF::face
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_descriptor face(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the face incident to halfedge h.
Definition: Graph_traits_aif.h:664
FEVV::Operators::replace_similar_edges
static void replace_similar_edges(typename boost::graph_traits< MutableFaceIncidentGraph >::face_descriptor face, const typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor old_edge, const typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor new_edge, MutableFaceIncidentGraph &g)
Replace the old_edge incident edge of face by the new_edge if old_edge and new_edge were similar/para...
Definition: similarity.hpp:36
FEVV::DataStructures::AIF::remove_face
void remove_face(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_descriptor f, FEVV::DataStructures::AIF::AIFMesh &sm)
Removes f from the mesh.
Definition: Graph_traits_aif.h:971