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 
19 #include <CGAL/boost/graph/helpers.h> // is_border + is_triangle_mesh
20 
21 #include <cassert>
22 
24 
25 namespace FEVV {
26 namespace Operators {
27 
42 template< typename MutableFaceGraph, typename PointMap >
43 void
45  MutableFaceGraph &g,
46  PointMap pm,
47  typename boost::graph_traits< MutableFaceGraph >::halfedge_descriptor &h)
48 {
49  typedef FEVV::Geometry_traits< MutableFaceGraph > GeometryTraits;
50  typedef typename GeometryTraits::Point Point;
51 
52  typedef boost::graph_traits< MutableFaceGraph > GraphTraits;
53  typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor;
55  typedef typename GraphTraits::face_descriptor face_descriptor;
56  GeometryTraits gt(g);
57 
58  if(h == boost::graph_traits< MutableFaceGraph >::null_halfedge())
59  return;
60 
61  halfedge_descriptor opp_h = opposite(h, g);
62  // ensure the edge is incident to triangles (only)
63  if(CGAL::is_border(h, g))
64  {
65  if(!CGAL::is_triangle(opp_h, g))
66  return;
67  }
68  else if(CGAL::is_border(opp_h, g))
69  {
70  if(!CGAL::is_triangle(h, g))
71  return;
72  }
73  else
74  {
75  if(!CGAL::is_triangle(h, g) || !CGAL::is_triangle(opp_h, g))
76  return;
77  }
78 
79  // deal with vertex geometry
80  vertex_descriptor vs = source(h, g);
81  vertex_descriptor vt = target(h, g);
82 
83  typedef CGAL::Halfedge_around_face_iterator< MutableFaceGraph >
84  Halfedge_around_face_iterator;
85  vertex_descriptor midpoint_vertex;
86  midpoint_vertex = add_vertex(g);
87  put(pm,
88  midpoint_vertex,
89  Point((gt.get_x(get(pm, vs)) + gt.get_x(get(pm, vt))) * 0.5f,
90  (gt.get_y(get(pm, vs)) + gt.get_y(get(pm, vt))) * 0.5f,
91  (gt.get_z(get(pm, vs)) + gt.get_z(get(pm, vt))) * 0.5f));
92 
93  std::vector< vertex_descriptor > face_vertices;
94  // here we assume a 2_manifold context, we thus have 2 cases: border or no
95  // border
96  if(CGAL::is_border(h, g))
97  {
98  // opp_h is not a border
99  vertex_descriptor opp_v = target(next(opp_h, g), g);
100 
101  halfedge_descriptor h1 = next(opp_h, g), h2 = prev(opp_h, g);
102  remove_face(face(opp_h, g), g);
103  // if (halfedge(edge(opp_h, g),g) !=
104  // boost::graph_traits<MutableFaceGraph>::null_halfedge())
105  // remove_edge(edge(opp_h, g), g);
106  CGAL::internal::set_border(h1, g);
107  CGAL::internal::set_border(h2, g);
108 
109  face_vertices.push_back(opp_v);
110  face_vertices.push_back(vt);
111  face_vertices.push_back(midpoint_vertex);
112  CGAL::Euler::add_face(face_vertices, g);
113 
114  face_vertices.clear();
115  face_vertices.push_back(opp_v);
116  face_vertices.push_back(midpoint_vertex);
117  face_vertices.push_back(vs);
118  CGAL::Euler::add_face(face_vertices, g);
119  }
120  else if(CGAL::is_border(opp_h, g))
121  {
122  // h is not a border
123  vertex_descriptor opp_v = target(next(h, g), g);
124 
125  halfedge_descriptor h1 = next(h, g), h2 = prev(h, g);
126  remove_face(face(h, g), g);
127  // if (halfedge(edge(h, g),g) !=
128  // boost::graph_traits<MutableFaceGraph>::null_halfedge())
129  // remove_edge(edge(h, g), g);
130  CGAL::internal::set_border(h1, g);
131  CGAL::internal::set_border(h2, g);
132 
133  face_vertices.push_back(opp_v);
134  face_vertices.push_back(vs);
135  face_vertices.push_back(midpoint_vertex);
136  CGAL::Euler::add_face(face_vertices, g);
137  face_vertices.clear();
138  face_vertices.push_back(opp_v);
139  face_vertices.push_back(midpoint_vertex);
140  face_vertices.push_back(vt);
141  CGAL::Euler::add_face(face_vertices, g);
142  }
143  else
144  { // no border
145  vertex_descriptor opp_v1 = target(next(h, g), g);
146  vertex_descriptor opp_v2 = target(next(opp_h, g), g);
147  halfedge_descriptor h1 = next(h, g), h2 = prev(h, g);
148  halfedge_descriptor h3 = next(opp_h, g), h4 = prev(opp_h, g);
149  remove_face(face(h, g), g);
150  CGAL::internal::set_border(h1, g);
151  CGAL::internal::set_border(h2,
152  g); // CGAL::internal::set_border(prev(h1,g), g);
153 
154  remove_face(face(opp_h, g), g);
155  CGAL::internal::set_border(h3, g);
156  CGAL::internal::set_border(h4, g);
157 
158  face_vertices.push_back(vs);
159  face_vertices.push_back(midpoint_vertex);
160  face_vertices.push_back(
161  opp_v1); // prefer new point in the middle due to CGAL::add_face
162  face_descriptor f1 = CGAL::Euler::add_face(face_vertices, g);
163  face_vertices.clear();
164  face_vertices.push_back(opp_v1);
165  face_vertices.push_back(midpoint_vertex);
166  face_vertices.push_back(vt);
167  face_descriptor f2 = CGAL::Euler::add_face(face_vertices, g);
169  Halfedge_around_face_iterator hi, he;
170  // int cpt=0;
171  for(boost::tie(hi, he) = CGAL::halfedges_around_face(halfedge(f1, g), g);
172  hi != he;
173  ++hi)
174  {
175  if(CGAL::is_border_edge(*hi, g))
176  {
177  // std::cout << "border!" << std::endl;
178  CGAL::internal::set_border(opposite(*hi, g), g);
179  auto h_if_exist = halfedge(vs, opp_v2, g);
180  if(h_if_exist.second && (target(*hi, g) == midpoint_vertex) &&
181  (next(opposite(*hi, g), g) != h_if_exist.first))
182  set_next(opposite(*hi, g), h_if_exist.first, g);
183  //++cpt;
184  }
185  }
186  for(boost::tie(hi, he) = CGAL::halfedges_around_face(halfedge(f2, g), g);
187  hi != he;
188  ++hi)
189  {
190  if(CGAL::is_border_edge(*hi, g))
191  {
192  // std::cout << "border!" << std::endl;
193  CGAL::internal::set_border(opposite(*hi, g), g);
194  auto h_if_exist = halfedge(opp_v2, vt, g);
195  if(h_if_exist.second && (source(*hi, g) == midpoint_vertex) &&
196  (next(h_if_exist.first, g) != opposite(*hi, g)))
197  set_next(h_if_exist.first, opposite(*hi, g), g);
198  //++cpt;
199  }
200  }
201  // assert(cpt==2);
203  face_vertices.clear();
204  face_vertices.push_back(vt);
205  face_vertices.push_back(midpoint_vertex);
206  face_vertices.push_back(
207  opp_v2); // prefer new point in the middle due to CGAL::add_face
208  f1 = CGAL::Euler::add_face(face_vertices, g);
209  for(boost::tie(hi, he) = CGAL::halfedges_around_face(halfedge(f1, g), g);
210  hi != he;
211  ++hi)
212  {
213  if(CGAL::is_border_edge(*hi, g))
214  {
215  // std::cout << "border!" << std::endl;
216  CGAL::internal::set_border(opposite(*hi, g), g);
217  //++cpt;
218  }
219  }
220  // assert(cpt==3);
221 
222  face_vertices.clear();
223  face_vertices.push_back(opp_v2);
224  face_vertices.push_back(midpoint_vertex);
225  face_vertices.push_back(vs);
226  f1 = CGAL::Euler::add_face(face_vertices, g);
227  for(boost::tie(hi, he) = CGAL::halfedges_around_face(halfedge(f1, g), g);
228  hi != he;
229  ++hi)
230  {
231  if(CGAL::is_border_edge(*hi, g))
232  {
233  std::cout << "border!" << std::endl;
234  //++cpt;
235  }
236  }
237  // assert(cpt==3);
238  }
239 }
240 
241 } // namespace Operators
242 } // 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::next
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor next(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the next halfedge around its face.
Definition: Graph_traits_aif.h:599
FEVV::DataStructures::AIF::set_next
void set_next(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h1, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h2, FEVV::DataStructures::AIF::AIFMesh &sm)
Sets the successor of h1 around a face to h2, and the prededecessor of h2 to h1.
Definition: Graph_traits_aif.h:790
FEVV::DataStructures::AIF::opposite
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor opposite(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the halfedge with source and target swapped.
Definition: Graph_traits_aif.h:625
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::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
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
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
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::prev
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor prev(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the previous halfedge around its face.
Definition: Graph_traits_aif.h:612
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::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::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