Developer Documentation
MidpointT.hh
1 #pragma once
2 
3 #include <OpenMesh/Core/Mesh/BaseKernel.hh>
5 #include <OpenMesh/Core/Utils/PropertyManager.hh>
6 
7 #include <algorithm>
8 
9 namespace OpenMesh {
10 namespace Subdivider {
11 namespace Uniform {
12 
26 template<typename MeshType, typename RealType = double>
27 class MidpointT : public SubdividerT<MeshType, RealType>
28 {
29 public:
30  typedef RealType real_t;
31  typedef MeshType mesh_t;
33 
34  // Inherited constructors
35  MidpointT() : parent_t() {}
36  MidpointT(mesh_t& _m) : parent_t(_m) {}
37 
38  const char* name() const { return "midpoint"; }
39 
40 protected: // SubdividerT interface
41  bool prepare(mesh_t& _m)
42  {
43  return true;
44  }
45 
48  bool subdivide(mesh_t& _m, size_t _n, const bool _update_points = true)
49  {
50  _m.request_halfedge_status();
51  _m.request_edge_status();
52  _m.request_vertex_status();
53  _m.request_face_status();
54  PropertyManager<EPropHandleT<typename mesh_t::VertexHandle>> edge_midpoint(_m, "edge_midpoint");
55  PropertyManager<VPropHandleT<bool>> is_original_vertex(_m, "is_original_vertex");
56 
57  for (size_t iteration = 0; iteration < _n; ++iteration) {
58  is_original_vertex.set_range(_m.vertices_begin(), _m.vertices_end(), true);
59  // Create vertices on edge midpoints
60  for (typename mesh_t::EdgeIter it = _m.edges_begin(), end = _m.edges_end(); it != end; ++it) {
61  EdgeHandle eh = *it;
62  VertexHandle new_vh = _m.new_vertex(_m.calc_edge_midpoint(eh));
63  edge_midpoint[eh] = new_vh;
64  is_original_vertex[new_vh] = false;
65  }
66  // Create new faces from original faces
67  for (typename mesh_t::FaceIter it = _m.faces_begin(), end = _m.faces_end(); it != end; ++it) {
68  FaceHandle fh = *it;
69  std::vector<typename mesh_t::VertexHandle> new_corners;
70  for (typename mesh_t::FaceEdgeIter it = _m.fe_begin(fh), end = _m.fe_end(fh); it != end; ++it) {
71  EdgeHandle eh = *it;
72  new_corners.push_back(edge_midpoint[eh]);
73  }
74  _m.add_face(new_corners);
75  }
76  // Create new faces from original vertices
77  for (typename mesh_t::VertexIter it = _m.vertices_begin(), end = _m.vertices_end(); it != end; ++it) {
78  VertexHandle vh = *it;
79  if (is_original_vertex[vh]) {
80  if (!_m.is_boundary(vh)) {
81  std::vector<typename mesh_t::VertexHandle> new_corners;
82  for (typename mesh_t::VertexEdgeIter it = _m.ve_begin(vh), end = _m.ve_end(vh); it != end; ++it) {
83  EdgeHandle eh = *it;
84  new_corners.push_back(edge_midpoint[eh]);
85  }
86  std::reverse(new_corners.begin(), new_corners.end());
87  _m.add_face(new_corners);
88  }
89  }
90  }
91  for (typename mesh_t::VertexIter it = _m.vertices_begin(), end = _m.vertices_end(); it != end; ++it) {
92  VertexHandle vh = *it;
93  if (is_original_vertex[vh]) {
94  _m.delete_vertex(vh);
95  }
96  }
97  _m.garbage_collection();
98  }
99  _m.release_face_status();
100  _m.release_vertex_status();
101  _m.release_edge_status();
102  _m.release_halfedge_status();
103  return true;
104  }
105 
106  bool cleanup(mesh_t& _m)
107  {
108  return true;
109  }
110 };
111 
112 } // namespace Uniform
113 } // namespace Subdivider
114 } // namespace OpenMesh
Handle for a edge entity.
Definition: Handles.hh:134
Handle for a face entity.
Definition: Handles.hh:141
bool prepare(mesh_t &_m)
Prepare mesh, e.g. add properties.
Definition: MidpointT.hh:41
void set_range(HandleTypeIterator begin, HandleTypeIterator end, const PROP_VALUE &value)
Handle for a vertex entity.
Definition: Handles.hh:120
bool subdivide(mesh_t &_m, size_t _n, const bool _update_points=true)
Definition: MidpointT.hh:48
bool cleanup(mesh_t &_m)
Cleanup mesh after usage, e.g. remove added properties.
Definition: MidpointT.hh:106
const char * name() const
Return name of subdivision algorithm.
Definition: MidpointT.hh:38