MEPP2 Project
split_edge.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 <CGAL/boost/graph/internal/helpers.h> // set_border
14 #include <boost/graph/graph_traits.hpp>
15 #include <CGAL/boost/graph/iterator.h>
16 
17 #include <CGAL/boost/graph/Euler_operations.h> // for add_face(vr,g)
18 //#include <CGAL/boost/graph/helpers.h> // is_border + is_triangle_mesh
19 
22 
23 #include <cassert>
24 
25 namespace FEVV {
26 namespace Operators {
27 
40 template< typename MutableFaceIncidentGraph // similar concept to
41  // MutableCellIncidentGraph, but
42  // limited to 0, 1 and 2
43  // dimensional cells
44  >
45 typename boost::graph_traits<MutableFaceIncidentGraph>::edge_descriptor
47  MutableFaceIncidentGraph &g,
48  typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor
49  e,
51  midpoint_vertex)
52 {
54  //typedef typename GeometryTraits::Point Point;
55 
56  typedef boost::graph_traits< MutableFaceIncidentGraph > GraphTraits;
57  typedef typename GraphTraits::edge_descriptor edge_descriptor;
59  typedef typename GraphTraits::face_descriptor face_descriptor;
60  GeometryTraits gt(g);
61 
62  if(e == boost::graph_traits< MutableFaceIncidentGraph >::null_edge())
63  return boost::graph_traits<MutableFaceIncidentGraph>::null_edge();
64 
65  // ensure the edge is incident to triangles (only)
67  {
68  return boost::graph_traits<MutableFaceIncidentGraph>::null_edge();
69  }
70 
71  // deal with vertex geometry
72  vertex_descriptor vs = source(e, g);
73  vertex_descriptor vt = target(e, g);
74 
75  // when a topological modication is done over an edge, better to remove that
76  // edge than to reuse it because we have to make sure the final user will
77  // update edge properties accordingly.
78  if (degree(e, g) == 0)
79  {// one dangling edge is tranformed into 2 successive dangling edges
80 #ifdef USE_ADD_EDGE_AIF // conflict with function in Euler_operations.h (CGAL)
81  std::pair<edge_descriptor, bool> p = add_edge(vs, midpoint_vertex, g);
82  add_edge(midpoint_vertex, vt, g);
83 #else
84  edge_descriptor p = CGAL::Euler::add_edge(vs, midpoint_vertex, g);
85  CGAL::Euler::add_edge(midpoint_vertex, vt, g);
86 #endif
87  remove_edge(e, g); // remove at the end, to make sure no vertex is removed
88 #ifdef USE_ADD_EDGE_AIF
89  return p.first;
90 #else
91  return p;
92 #endif
93  }
94  else
95  {
96  std::vector< vertex_descriptor > face1_vertices, face2_vertices;
97  auto face_range_pair = in_edges(e, g); // get incident faces
98  std::vector< face_descriptor > copy_f(
99  face_range_pair.first,
100  face_range_pair
101  .second); // copy to not invalidate iterator while iterating
102  typename std::vector< face_descriptor >::iterator iter_f(copy_f.begin()),
103  iter_fe(copy_f.end());
104  for(; iter_f != iter_fe; ++iter_f)
105  {
106  auto edge_range_pair = out_edges(*iter_f, g);
107  auto iter_e = edge_range_pair.first;
108  vertex_descriptor third_v;
110  while(*iter_e != e)
111  ++iter_e;
113  edge_descriptor prev_e = *iter_e;
114  ++iter_e;
115  if(iter_e == edge_range_pair.second)
116  iter_e = edge_range_pair.first;
118  if(source(prev_e, g) == source(*iter_e, g))
119  {
120  face1_vertices.push_back(target(*iter_e, g));
121  face1_vertices.push_back(target(prev_e, g));
122  face1_vertices.push_back(midpoint_vertex);
123 
124  face2_vertices.push_back(source(prev_e, g));
125  face2_vertices.push_back(target(*iter_e, g));
126  face2_vertices.push_back(midpoint_vertex);
127  }
128  else if(target(prev_e, g) == source(*iter_e, g))
129  {
130  face1_vertices.push_back(target(*iter_e, g));
131  face1_vertices.push_back(source(prev_e, g));
132  face1_vertices.push_back(midpoint_vertex);
133 
134  face2_vertices.push_back(target(prev_e, g));
135  face2_vertices.push_back(target(*iter_e, g));
136  face2_vertices.push_back(midpoint_vertex);
137  }
138  else if(source(prev_e, g) == target(*iter_e, g))
139  {
140  face1_vertices.push_back(source(*iter_e, g));
141  face1_vertices.push_back(target(prev_e, g));
142  face1_vertices.push_back(midpoint_vertex);
143 
144  face2_vertices.push_back(source(prev_e, g));
145  face2_vertices.push_back(source(*iter_e, g));
146  face2_vertices.push_back(midpoint_vertex);
147  }
148  else if(target(prev_e, g) == target(*iter_e, g))
149  {
150  face1_vertices.push_back(source(*iter_e, g));
151  face1_vertices.push_back(source(prev_e, g));
152  face1_vertices.push_back(midpoint_vertex);
153 
154  face2_vertices.push_back(target(prev_e, g));
155  face2_vertices.push_back(source(*iter_e, g));
156  face2_vertices.push_back(midpoint_vertex);
157  }
158 
159  CGAL::Euler::add_face(face1_vertices, g);
160  CGAL::Euler::add_face(face2_vertices, g);
161  face1_vertices.clear();
162  face2_vertices.clear();
163 
164  remove_face(*iter_f,
165  g); // remove at the end, to make sure no vertex or edge is
166  // removed while still needing by new geometries
167  }
168 
169  std::pair<edge_descriptor, bool> p2 = edge(vs, midpoint_vertex, g);
170  return p2.first;
171  }
172 }
173 
186 template< typename MutableFaceIncidentGraph // similar concept to MutableCellIncidentGraph, but limited to 0, 1 and 2 dimensional cells
187  >
188 typename boost::graph_traits<MutableFaceIncidentGraph>::edge_descriptor
189  split_edge(MutableFaceIncidentGraph& g, typename boost::graph_traits<MutableFaceIncidentGraph>::edge_descriptor e)
190 {
191  typedef boost::graph_traits<MutableFaceIncidentGraph> GraphTraits;
193 
194  vertex_descriptor midpoint_vertex;
195  midpoint_vertex = add_vertex(g);
196 
197  return split_edge<MutableFaceIncidentGraph>(g, e, midpoint_vertex);
198 }
199 
216 template< typename MutableFaceIncidentGraph, // similar concept to MutableCellIncidentGraph, but limited to 0, 1 and 2 dimensional cells
217  typename PointMap,
218  typename GeometryTraits = FEVV::Geometry_traits<MutableFaceIncidentGraph>
219  >
220 typename boost::graph_traits<MutableFaceIncidentGraph>::edge_descriptor
221  split_edge(MutableFaceIncidentGraph& g, PointMap pm, typename boost::graph_traits<MutableFaceIncidentGraph>::edge_descriptor e)
222 {
223  typedef typename GeometryTraits::Point Point;
224 
225  typedef boost::graph_traits<MutableFaceIncidentGraph> GraphTraits;
226  typedef typename GraphTraits::edge_descriptor edge_descriptor;
228  GeometryTraits gt(g);
229 
230  vertex_descriptor vs = source(e, g);
231  vertex_descriptor vt = target(e, g);
232  edge_descriptor res = split_edge<MutableFaceIncidentGraph>(g, e);
233 
234  if (res == boost::graph_traits<MutableFaceIncidentGraph>::null_edge())
235  return boost::graph_traits<MutableFaceIncidentGraph>::null_edge();
236 
237  // deal with vertex geometry
238  vertex_descriptor midpoint_vertex = target(res, g);
239 
240  put(pm, midpoint_vertex, Point( (gt.get_x(get(pm, vs)) + gt.get_x(get(pm, vt)))*0.5f,
241  (gt.get_y(get(pm, vs)) + gt.get_y(get(pm, vt)))*0.5f,
242  (gt.get_z(get(pm, vs)) + gt.get_z(get(pm, vt)))*0.5f));
243  return res ;
244 }
245 
246 } // namespace Operators
247 } // namespace FEVV
CGAL::Euler::add_face
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_descriptor add_face(const VertexRange &vr, FEVV::DataStructures::AIF::AIFMesh &g)
Definition: Graph_traits_aif.h:1104
FEVV::DataStructures::AIF::degree
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::degree_size_type degree(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor u, const FEVV::DataStructures::AIF::AIFMesh &)
Definition: Graph_traits_aif.h:548
CGAL::Euler::add_edge
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor add_edge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor s, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor t, FEVV::DataStructures::AIF::AIFMesh &g)
Definition: Graph_traits_aif.h:1079
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
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::DataStructures::AIF::source
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor source(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the source vertex of e.
Definition: Graph_traits_aif.h:387
FEVV::DataStructures::AIF::add_edge
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor add_edge(FEVV::DataStructures::AIF::AIFMesh &sm)
Adds two opposite halfedges to the graph without initializing the connectivity.
Definition: Graph_traits_aif.h:827
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::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
topology_predicates.hpp
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::Operators::has_only_incident_triangular_faces
bool has_only_incident_triangular_faces(const typename boost::graph_traits< IncidentMutableFaceGraph >::edge_descriptor e, const IncidentMutableFaceGraph &g)
Function determining if the incident faces to e are all triangles.
Definition: topology_predicates.hpp:234
FEVV::DataStructures::AIF::target
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor target(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the target vertex of e.
Definition: Graph_traits_aif.h:400
Geometry_traits.h
FEVV::DataStructures::AIF::add_vertex
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor add_vertex(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_property_type vp, FEVV::DataStructures::AIF::AIFMesh &sm)
Definition: Graph_properties_aif.h:263
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::split_edge
boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor split_edge(MutableFaceIncidentGraph &g, typename boost::graph_traits< MutableFaceIncidentGraph >::edge_descriptor e, typename boost::graph_traits< MutableFaceIncidentGraph >::vertex_descriptor midpoint_vertex)
Split an edge of the graph.
Definition: split_edge.hpp:46
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::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