MEPP2 Project
Preprocessing.h
Go to the documentation of this file.
1 // Copyright (c) 2012-2022 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 
12 #pragma once
13 
14 #include <boost/graph/graph_traits.hpp>
15 #include <boost/graph/properties.hpp>
16 
17 #include <CGAL/boost/graph/helpers.h> // is_tetrahedron
18 
20 
21 #include <iostream>
22 #include <set>
23 #include <list>
24 #include <vector>
25 #include <tuple> // std::tie
26 #include <utility>
27 
28 
29 namespace FEVV {
30 namespace Filters {
31 
36 template<
37  typename HalfedgeGraph,
38  typename PointMap,
39  typename vertex_descriptor =
41  typename halfedge_descriptor =
42  typename boost::graph_traits< HalfedgeGraph >::halfedge_descriptor,
43  typename edge_iterator =
44  typename boost::graph_traits< HalfedgeGraph >::edge_iterator,
45  typename vertex_iterator =
46  typename boost::graph_traits< HalfedgeGraph >::vertex_iterator,
48  typename Geometry = typename FEVV::Geometry_traits< HalfedgeGraph > >
49 
51 {
52 public:
53  Preprocessing(HalfedgeGraph &g, PointMap &pm)
54  : _g(g), _pm(pm)
55  {
56  }
57 
62  {
64 
65  // does the mesh has borders?
66  bool has_border = this->check_if_mesh_with_borders();
67  std::clog << "process_mesh_before_quantization: does the mesh has borders ? " << has_border << std::endl;
68  }
69 
73  {
74  // process duplicates
76 
77  // check if there are not remainong duplicates
78  bool still_duplicates = this->are_duplicates();
79  if(still_duplicates)
80  std::clog << "Warning: process_mesh_after_quantization: there are still duplicates "
81  << std::endl;
82  }
83 
84 private:
87  {
88  auto iterator_pair = vertices(_g);
89  vertex_iterator vi = iterator_pair.first;
90  vertex_iterator vi_end = iterator_pair.second;
91  std::vector< vertex_descriptor > isolated_vertices;
92  std::vector< halfedge_descriptor > isolated_hedges;
93 
94  for( ; vi != vi_end; ++vi)
95  {
96 
97  typename boost::graph_traits< HalfedgeGraph >::degree_size_type
98  value_type;
99  boost::degree_property_map< HalfedgeGraph > degree_property_map(_g);
100  value_type = degree_property_map[*vi];
101 
102  if(value_type == 0)
103  {
104  // isolated vertex case
105  isolated_vertices.push_back(*vi);
106  }
107 
108  if(value_type == 1)
109  {
110  // isolated edge case
111  isolated_hedges.push_back(halfedge(*vi, _g));
112  }
113  }
114  auto itE = isolated_hedges.begin(),
115  itEe = isolated_hedges.end();
116  for( ; itE != itEe; ++itE)
117  remove_edge(edge(*itE, _g), _g);
118 
119  auto itV = isolated_vertices.begin(),
120  itVe = isolated_vertices.end();
121  for( ; itV != itVe; ++itV)
122  remove_vertex(*itV, _g);
123  }
124 
126  {
127  auto iterator_pair = edges(_g);
128  edge_iterator ei = iterator_pair.first;
129  edge_iterator ei_end = iterator_pair.second;
130 
131  for( ; ei != ei_end; ++ei)
132  {
133  if(CGAL::is_border_edge(halfedge(*ei, _g), _g))
134  return true;
135  }
136  return false;
137  }
138 
139 
141  {
142  auto iterator_pair = vertices(_g);
143  vertex_iterator vi = iterator_pair.first;
144  vertex_iterator vi_end = iterator_pair.second;
145  std::pair< typename std::map< Point,
147  std::less< Point > >::iterator,
148  bool >
149  ret;
150 
151  for( ; vi != vi_end; ++vi)
152  {
153  Point pos = get(_pm, *vi);
154 
155  // move point until position is not occupied anymore
156  while(!(_position.insert(std::pair< Point, vertex_descriptor >(pos, *vi)))
157  .second)
158  {
159  pos = Point(pos[0], pos[1], pos[2] + 1.0);
160  }
161  put(_pm, *vi, pos);
162  }
163  }
164 
165  // Simple test to check if all the duplicates have been removed
166  // return true if there are still duplicates in the mesh and false otherwise.
167  bool are_duplicates() const
168  {
169  auto iterator_pair = vertices(_g);
170  vertex_iterator vi = iterator_pair.first;
171  vertex_iterator vi_end = iterator_pair.second;
172 
173  std::map< Point, vertex_descriptor > map_pos;
174  std::pair< typename std::map< Point, vertex_descriptor >::iterator, bool >
175  ret;
176 
177  for( ; vi != vi_end; ++vi)
178  {
179  const Point& pos = get(_pm, *vi);
180  ret = map_pos.insert(std::pair< Point, vertex_descriptor >(pos, *vi));
181  // The ret.second element in the pair is set to true if a new element
182  // was inserted or false if an equivalent key already existed.
183  if(ret.second == false)
184  return true;
185  }
186  return false;
187  }
188 
189 
191  {
192  const Point& pos = get(_pm, v);
193  Point new_pos;
194  Geometry gt(_g);
195  int px = static_cast< int >(gt.get_x(pos));
196  int py = static_cast< int >(gt.get_y(pos));
197  int pz = static_cast< int >(gt.get_z(pos));
198 
199  switch(cas)
200  {
201  case 0:
202  new_pos = Point(px, py, pz - 1);
203  break;
204 
205  case 1:
206  new_pos = Point(px, py, pz + 1);
207  break;
208 
209  case 2:
210  new_pos = Point(px, py - 1, pz);
211  break;
212 
213  case 3:
214  new_pos = Point(px, py + 1, pz);
215  break;
216 
217  case 4:
218  new_pos = Point(px - 1, py, pz);
219  break;
220 
221  case 5:
222  new_pos = Point(px + 1, py, pz);
223  break;
224  }
225 
226  return new_pos;
227  }
228 
229 
230  //--------------------------coarse mesh
231  //process--------------------------------------------
232  struct P
233  {
234  int x;
235  int y;
236  int z;
237  bool operator<(const P &q) const
238  {
239  // std::tie can be used to introduce lexicographical comparison
240  return std::tie(x, y, z) < std::tie(q.x, q.y, q.z);
241  }
242  };
243 
245  void get_new_pos(const std::vector< vertex_descriptor > &doublons,
246  int size_doublons,
247  std::set< P > &new_pos)
248  {
249  Geometry gt(_g);
250  int x_min = gt.get_x(get(_pm, doublons.front())) + 1;
251  int x_max = gt.get_x(get(_pm, doublons.back())) - 1;
252  int y_min = gt.get_y(get(_pm, doublons.front()));
253  int y_max = gt.get_y(get(_pm, doublons.back()));
254  int z_min = gt.get_z(get(_pm, doublons.front()));
255  int z_max = gt.get_z(get(_pm, doublons.back()));
256  int cas = 0;
257  int counter = 0;
258 
259 
260  if(new_pos.empty())
261  {
262  P value{gt.get_x(get(_pm, doublons[1])),
263  gt.get_y(get(_pm, doublons[1])),
264  gt.get_z(get(_pm, doublons[1]))};
265  new_pos.insert(value);
266  }
267 
268 
269  typename std::set< P >::iterator it_new_pos = new_pos.begin();
270 
271  while(counter != size_doublons)
272  {
273  const P& pos = *it_new_pos;
274  int x_pos = pos.x;
275  int y_pos = pos.y;
276  int z_pos = pos.z;
277  P value;
278 
279  switch(cas)
280  {
281  case 0:
282  if(x_pos + 1 != x_max)
283  {
284  value = {x_pos + 1, y_pos, z_pos};
285  new_pos.insert(value);
286  counter += 1;
287  }
288  break;
289 
290  case 1:
291  value = {x_pos, y_pos + 1, z_pos};
292  new_pos.insert(value);
293  counter += 1;
294  break;
295 
296  case 2:
297  value = {x_pos, y_pos, z_pos + 1};
298  new_pos.insert(value);
299  counter += 1;
300  break;
301 
302  case 3:
303  if(x_pos - 1 != x_min)
304  {
305  value = {x_pos - 1, y_pos, z_pos};
306  new_pos.insert(value);
307  counter += 1;
308  }
309  break;
310 
311  case 4:
312  value = {x_pos, y_pos - 1, z_pos};
313  new_pos.insert(value);
314  counter += 1;
315  break;
316 
317  case 5:
318  value = {x_pos, y_pos, z_pos - 1};
319  new_pos.insert(value);
320  counter += 1;
321  break;
322  }
323 
324 
325  cas += 1;
326  cas %= 6;
327  if(cas == 0)
328  ++it_new_pos;
329  }
330  }
331 
332 
333 private:
334  HalfedgeGraph &_g;
335  PointMap &_pm;
336  std::map< Point, vertex_descriptor, std::less< Point > > _position;
337 };
338 } // namespace Filters
339 } // namespace FEVV
FEVV::Filters::Preprocessing
Preprocessing class is dedicated to provide a list of preprocessings that are needed to guarantee tha...
Definition: Preprocessing.h:51
FEVV::DataStructures::AIF::vertices
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator > vertices(const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the iterator range of the vertices of the mesh.
Definition: Graph_traits_aif.h:172
FEVV::Filters::Preprocessing::check_if_mesh_with_borders
bool check_if_mesh_with_borders()
Definition: Preprocessing.h:125
FEVV::Filters::Preprocessing::P::y
int y
Definition: Preprocessing.h:235
FEVV::Filters::Preprocessing::Preprocessing
Preprocessing(HalfedgeGraph &g, PointMap &pm)
Definition: Preprocessing.h:53
FEVV::DataStructures::AIF::remove_vertex
void remove_vertex(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, FEVV::DataStructures::AIF::AIFMesh &sm)
Removes v from the mesh.
Definition: Graph_traits_aif.h:728
FEVV::Filters::Preprocessing::move_duplicates_after_quantization
void move_duplicates_after_quantization()
Definition: Preprocessing.h:140
FEVV::Filters::Preprocessing::P::x
int x
Definition: Preprocessing.h:234
FEVV::DataStructures::AIF::edges
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_iterator > edges(const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the iterator range of the edges of the mesh.
Definition: Graph_traits_aif.h:238
FEVV::Filters::Preprocessing::move_duplicate
Point move_duplicate(vertex_descriptor v, int cas)
Definition: Preprocessing.h:190
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
FEVV::Geometry_traits
Refer to Geometry_traits_documentation_dummy for further documentation on provided types and algorith...
Definition: Geometry_traits.h:162
Point
AIFMesh::Point Point
Definition: Graph_properties_aif.h:21
FEVV::Filters::Preprocessing::get_new_pos
void get_new_pos(const std::vector< vertex_descriptor > &doublons, int size_doublons, std::set< P > &new_pos)
Definition: Preprocessing.h:245
FEVV::DataStructures::AIF::edge
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor edge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the edge corresponding to h and opposite(h).
Definition: Graph_traits_aif.h:345
FEVV::Filters::Preprocessing::process_mesh_before_quantization
void process_mesh_before_quantization()
Suppress all small connected components (isolated vertices and isolated edges). To apply before quant...
Definition: Preprocessing.h:61
FEVV::Filters::Preprocessing::P::operator<
bool operator<(const P &q) const
Definition: Preprocessing.h:237
FEVV::get
FEVV::PCLPointCloudPointMap::value_type get(const FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key)
Specialization of get(point_map, key) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:117
FEVV::Filters::Preprocessing::_pm
PointMap & _pm
Definition: Preprocessing.h:335
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::Filters::Preprocessing::P
Definition: Preprocessing.h:233
FEVV::DataStructures::AIF::halfedge
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor halfedge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns a halfedge with target v.
Definition: Graph_traits_aif.h:296
Geometry_traits.h
FEVV::Filters::Preprocessing::are_duplicates
bool are_duplicates() const
Definition: Preprocessing.h:167
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
FEVV::put
void put(FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key, const FEVV::PCLPointCloudPointMap::value_type &value)
Specialization of put(point_map, key, value) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:126
FEVV::Filters::Preprocessing::erase_small_connnected_components
void erase_small_connnected_components()
Erase isolated edges and vertices.
Definition: Preprocessing.h:86
FEVV::Filters::Preprocessing::process_mesh_after_quantization
void process_mesh_after_quantization()
Move duplicate vertex positions. To apply after quantization.
Definition: Preprocessing.h:72
FEVV::Filters::Preprocessing::_g
HalfedgeGraph & _g
Definition: Preprocessing.h:334
FEVV::Filters::Preprocessing::_position
std::map< Point, vertex_descriptor, std::less< Point > > _position
Definition: Preprocessing.h:336
FEVV::Filters::Preprocessing::P::z
int z
Definition: Preprocessing.h:236
FEVV::DataStructures::AIF::AIFPoint
Definition: AIFProperties.h:31