OpenMesh: OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh Source File

| OpenMesh

MidpointT.hh
1 #pragma once
2
3 #include <OpenMesh/Core/Mesh/BaseKernel.hh>
4 #include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.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;
32 typedef SubdividerT<MeshType, RealType> parent_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>, mesh_t> edge_midpoint(_m, "edge_midpoint");
55 PropertyManager<VPropHandleT<bool>, mesh_t> 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
OpenMesh::Subdivider::Uniform::SubdividerT
Abstract base class for uniform subdivision algorithms.
Definition: SubdividerT.hh:93
OpenMesh::Subdivider::Uniform::MidpointT::subdivide
bool subdivide(mesh_t &_m, size_t _n, const bool _update_points=true)
Performs one step of Midpoint subdivision.
Definition: MidpointT.hh:48
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:146
OpenMesh::Subdivider::Uniform::MidpointT::name
const char * name() const
Return name of subdivision algorithm.
Definition: MidpointT.hh:38
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:64
OpenMesh::Subdivider::Uniform::MidpointT::cleanup
bool cleanup(mesh_t &_m)
Cleanup mesh after usage, e.g. remove added properties.
Definition: MidpointT.hh:106
OpenMesh::PropertyManager::set_range
void set_range(HandleTypeIterator begin, HandleTypeIterator end, const PROP_VALUE &value)
Conveniently set the property for an entire range of values.
Definition: PropertyManager.hh:407
SubdividerT.hh
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:125
OpenMesh::Subdivider::Uniform::MidpointT::prepare
bool prepare(mesh_t &_m)
Prepare mesh, e.g. add properties.
Definition: MidpointT.hh:41
OpenMesh::PolyMeshT::FaceEdgeIter
Kernel::FaceEdgeIter FaceEdgeIter
Circulator.
Definition: PolyMeshT.hh:172
OpenMesh::EdgeHandle
Handle for a edge entity.
Definition: Handles.hh:139
OpenMesh::Subdivider::Uniform::MidpointT
Midpoint subdivision algorithm.
Definition: MidpointT.hh:27
OpenMesh::PropertyManager
This class is intended to manage the lifecycle of properties.
Definition: PropertyManager.hh:94
OpenMesh::PolyMeshT::VertexEdgeIter
Kernel::VertexEdgeIter VertexEdgeIter
Circulator.
Definition: PolyMeshT.hh:168