Developer Documentation

MeshGenerator.hpp
1 /*
2 * MeshGenerator.hh
3 *
4 * Created on: Mar 15, 2012
5 * Author: kremer
6 */
7
8 #ifndef MESHGENERATOR_HH_
9 #define MESHGENERATOR_HH_
10
11 #include <vector>
12 #include <set>
13 #include <map>
14 #include <algorithm>
15
16 #include <boost/shared_ptr.hpp>
17 #include <boost/progress.hpp>
18 #include <boost/tuple/tuple.hpp>
19 #include <boost/tuple/tuple_comparison.hpp>
20
21 #include <OpenVolumeMesh/Mesh/PolyhedralMesh.hh>
22 #include <OpenVolumeMesh/Geometry/VectorT.hh>
23
24 class MeshGenerator {
25 private:
26
27 typedef OpenVolumeMesh::VertexHandle VertexHandle;
28 typedef OpenVolumeMesh::EdgeHandle EdgeHandle;
29 typedef OpenVolumeMesh::HalfEdgeHandle HalfEdgeHandle;
30 typedef OpenVolumeMesh::FaceHandle FaceHandle;
31 typedef OpenVolumeMesh::HalfFaceHandle HalfFaceHandle;
32 typedef OpenVolumeMesh::CellHandle CellHandle;
33
34 typedef boost::tuple<VertexHandle, VertexHandle, VertexHandle> FaceTuple;
35
36 public:
37
38 typedef OpenVolumeMesh::GeometricPolyhedralMeshV3d PolyhedralMesh;
39
40 typedef OpenVolumeMesh::Geometry::Vec3d Vec3d;
41
42 explicit MeshGenerator(PolyhedralMesh& _mesh) : v_component_(0), mesh_(_mesh), progress_() {}
43 MeshGenerator(const MeshGenerator& _cpy) :
44 v_component_(_cpy.v_component_),
45 vertex_(0.0, 0.0, 0.0),
46 c_vertices_(),
47 faceMap_(),
48 mesh_(_cpy.mesh_),
49 progress_() {}
50
51 void add_vertex_component(double _comp) {
52
53 if(v_component_ > 2) {
54 std::cerr << "Vertices of dimension higher than three not supported!" << std::endl;
55 return;
56 }
57 vertex_[v_component_] = _comp;
58 ++v_component_;
59 if(v_component_ == 3) {
60 add_vertex();
61 }
62 }
63
64 void add_vertex() {
65
66 OpenVolumeMesh::VertexHandle vh = mesh_.add_vertex(vertex_);
67 //std::cerr << "Added vertex " << mesh_.vertex(vh) << std::endl;
68 v_component_ = 0;
69 }
70
71 void add_cell_vertex(unsigned int _idx) {
72
73 assert(_idx > 0);
74
75 c_vertices_.push_back(OpenVolumeMesh::VertexHandle((int)_idx - 1));
76 if(c_vertices_.size() == 4) {
77
78 add_tetrahedral_cell();
79 // std::cerr << "Adding cell (" << c_vertices_[0] << ", " << c_vertices_[1] <<
80 // ", " << c_vertices_[2] << ", " << c_vertices_[3] << ")" << std::endl;
81 c_vertices_.clear();
82 }
83 }
84
85 void set_num_cells(unsigned int _n) {
86
87 if(progress_.get() == NULL) {
88 progress_.reset(new boost::progress_display(_n));
89 }
90 }
91
92 void add_tetrahedral_cell() {
93
94 if(c_vertices_.size() != 4) {
95 std::cerr << "The specified cell is not incident to four vertices!" << std::endl;
96 return;
97 }
98
99 // Get cell's mid-point
100 Vec3d midP(0.0, 0.0, 0.0);
101 double valence = 0.0;
102 for(std::vector<OpenVolumeMesh::VertexHandle>::const_iterator it = c_vertices_.begin();
103 it != c_vertices_.end(); ++it) {
104 midP += mesh_.vertex(*it);
105 valence += 1.0;
106 }
107 midP /= valence;
108
109 // Sort vertex vector
110 std::sort(c_vertices_.begin(), c_vertices_.end());
111
112 std::vector<FaceTuple> tuples;
113
114 // Create face tuple for all vertex combinations
115 tuples.push_back(FaceTuple(c_vertices_[0], c_vertices_[1], c_vertices_[2]));
116 tuples.push_back(FaceTuple(c_vertices_[1], c_vertices_[2], c_vertices_[3]));
117 tuples.push_back(FaceTuple(c_vertices_[0], c_vertices_[2], c_vertices_[3]));
118 tuples.push_back(FaceTuple(c_vertices_[0], c_vertices_[1], c_vertices_[3]));
119
120 // Collect cell's half-faces in here
121 std::vector<HalfFaceHandle> cell_halffaces;
122
123 for(std::vector<FaceTuple>::const_iterator it = tuples.begin();
124 it != tuples.end(); ++it) {
125
126 // Check if face exists for current tuple
127 FaceMap::iterator f = faceMap_.find(*it);
128 if(f == faceMap_.end()) {
129 // Face does not exist, create it
130
131 // Find right orientation, s.t. normal
132 // points inside the cell
133
134 Vec3d e1 = mesh_.vertex(it->get<1>()) - mesh_.vertex(it->get<0>());
135 Vec3d e2 = mesh_.vertex(it->get<2>()) - mesh_.vertex(it->get<1>());
136
137 // Get face normal (cross product)
138 Vec3d n = (e1 % e2).normalize();
139
140 std::vector<VertexHandle> v_vec;
141 v_vec.push_back(it->get<0>());
142 v_vec.push_back(it->get<1>());
143 v_vec.push_back(it->get<2>());
144 FaceHandle fh = mesh_.add_face(v_vec);
145
146 // Add face to face map
147 faceMap_[*it] = fh;
148
149 // Check whether normal points inside cell
150 if(((midP - mesh_.vertex(it->get<0>())) | n) > 0.0) {
151
152 // Normal points inside cell, just add half-face 0
153 // Add corresponding half-face to cell definition
154 cell_halffaces.push_back(mesh_.halfface_handle(fh, 0));
155
156 } else {
157
158 // Normal points outside cell, just add half-face 1
159 // Add corresponding half-face to cell definition
160 cell_halffaces.push_back(mesh_.halfface_handle(fh, 1));
161 }
162
163 } else {
164
165 // Face exists, find right orientation
166 FaceHandle fh = f->second;
167
168 std::vector<HalfEdgeHandle> hes = mesh_.face(fh).halfedges();
169
170 assert(hes.size() == 3);
171
172 Vec3d e1 = mesh_.vertex(mesh_.halfedge(hes[0]).to_vertex()) -
173 mesh_.vertex(mesh_.halfedge(hes[0]).from_vertex());
174 Vec3d e2 = mesh_.vertex(mesh_.halfedge(hes[1]).to_vertex()) -
175 mesh_.vertex(mesh_.halfedge(hes[1]).from_vertex());
176
177 Vec3d n = (e1 % e2).normalize();
178
179 if(((midP - mesh_.vertex(mesh_.halfedge(hes[0]).from_vertex())) | n) > 0.0) {
180 // Normal points inside cell
181 cell_halffaces.push_back(mesh_.halfface_handle(fh, 0));
182 } else {
183 // Normal points outisde cell
184 cell_halffaces.push_back(mesh_.halfface_handle(fh, 1));
185 }
186 }
187 }
188
189 // Check whether cell definition contains four half-faces
190 assert(cell_halffaces.size() == 4);
191
192 // Finally, add cell
193 #ifndef NDEBUG
194 mesh_.add_cell(cell_halffaces, true);
195 #else
196 mesh_.add_cell(cell_halffaces, false);
197 #endif
198
199 // Increase progress counter
200 if((progress_.get() != NULL) && (progress_->expected_count() != 0))
201 ++(*progress_);
202 }
203
204 private:
205
206 typedef std::map<FaceTuple, OpenVolumeMesh::FaceHandle> FaceMap;
207
208 unsigned int v_component_;
209 OpenVolumeMesh::Geometry::Vec3d vertex_;
210
211 std::vector<VertexHandle> c_vertices_;
212
213 FaceMap faceMap_;
214
215 PolyhedralMesh& mesh_;
216
217 boost::shared_ptr<boost::progress_display> progress_;
218 };
219
220 #endif /* MESHGENERATOR_HH_ */
OpenVolumeMesh::Geometry::VectorT
Definition: Vector11T.hh:78
OpenVolumeMesh::GeometryKernel::add_vertex
virtual VertexHandle add_vertex()
Override of empty add_vertex function.
Definition: GeometryKernel.hh:68
OpenVolumeMesh::GeometryKernel
Definition: GeometryKernel.hh:55
OpenVolumeMesh::HandleT< Entity::Vertex >
MeshGenerator
Definition: MeshGenerator.hpp:24
OpenVolumeMesh::GeometryKernel::vertex
const VecT & vertex(const VertexHandle &_vh) const
Get point _vh&#39;s coordinates.
Definition: GeometryKernel.hh:89