Developer Documentation
Loading...
Searching...
No Matches
TetrahedralCuboidGenerator.cc
1/*===========================================================================*\
2* *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42
43#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
44
45#include "TetrahedralCuboidGenerator.hh"
46
47void TetrahedralCuboidGenerator::add_vertices(Vector const& position, Vector const& length)
48{
49 vertices_.clear();
50 vertices_.reserve((size_[0] + 1) * (size_[1] + 1) * (size_[2] + 1));
51
52 Vector h(length[0] / size_[0], length[1] / size_[1], length[2] / size_[2]);
53 Vector origin = position - 0.5 * length;
54
55 for (std::size_t k = 0; k < size_[2] + 1; ++k)
56 for (std::size_t j = 0; j < size_[1] + 1; ++j)
57 for (std::size_t i = 0; i < size_[0] + 1; ++i)
58 vertices_.push_back(mesh_->add_vertex(Vector(h[0]*i, h[1]*j, h[2]*k) + origin));
59}
60
61void TetrahedralCuboidGenerator::get_cube_vertices(std::size_t i, std::size_t j, std::size_t k,
62 std::vector<OpenVolumeMesh::VertexHandle>& v) const
63{
64 v[0] = vertices_[k * (size_[0] + 1) * (size_[1] + 1) + j * (size_[0] + 1) + i];
65 v[1] = vertices_[k * (size_[0] + 1) * (size_[1] + 1) + j * (size_[0] + 1) + i + 1];
66 v[2] = vertices_[k * (size_[0] + 1) * (size_[1] + 1) + (j + 1) * (size_[0] + 1) + i];
67 v[3] = vertices_[k * (size_[0] + 1) * (size_[1] + 1) + (j + 1) * (size_[0] + 1) + i + 1];
68 v[4] = vertices_[(k + 1) * (size_[0] + 1) * (size_[1] + 1) + j * (size_[0] + 1) + i];
69 v[5] = vertices_[(k + 1) * (size_[0] + 1) * (size_[1] + 1) + j * (size_[0] + 1) + i + 1];
70 v[6] = vertices_[(k + 1) * (size_[0] + 1) * (size_[1] + 1) + (j + 1) * (size_[0] + 1) + i];
71 v[7] = vertices_[(k + 1) * (size_[0] + 1) * (size_[1] + 1) + (j + 1) * (size_[0] + 1) + i + 1];
72}
73
74void TetrahedralCuboidGenerator::add_faces()
75{
76 std::vector<OpenVolumeMesh::VertexHandle> v(8);
77
78 for (std::size_t i = 0; i < size_[0]; ++i)
79 for (std::size_t j = 0; j < size_[1]; ++j)
80 for (std::size_t k = 0; k < size_[2]; ++k)
81 {
82 get_cube_vertices(i, j, k, v);
83
84 if ((i + j + k) % 2 == 0)
85 add_cube_type_1_faces(i, j, k, v);
86 else
87 add_cube_type_2_faces(i, j, k, v);
88 }
89}
90
91void TetrahedralCuboidGenerator::add_cube_type_1_faces(std::size_t i, std::size_t j, std::size_t k,
92 std::vector<OpenVolumeMesh::VertexHandle> const& v)
93{
94 std::vector<OpenVolumeMesh::VertexHandle> fv(3);
95
96 // left side
97 fv[0] = v[0]; fv[1] = v[2]; fv[2] = v[6];
98 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
99 fv[0] = v[0]; fv[1] = v[6]; fv[2] = v[4];
100 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
101
102 // front side
103 fv[0] = v[0]; fv[1] = v[4]; fv[2] = v[5];
104 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
105 fv[0] = v[0]; fv[1] = v[5]; fv[2] = v[1];
106 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
107
108 // bottom side
109 fv[0] = v[0]; fv[1] = v[1]; fv[2] = v[3];
110 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
111 fv[0] = v[0]; fv[1] = v[3]; fv[2] = v[2];
112 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
113
114 // inner faces
115 fv[0] = v[0]; fv[1] = v[5]; fv[2] = v[6];
116 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
117 fv[0] = v[0]; fv[1] = v[3]; fv[2] = v[5];
118 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
119 fv[0] = v[0]; fv[1] = v[6]; fv[2] = v[3];
120 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
121 fv[0] = v[3]; fv[1] = v[6]; fv[2] = v[5];
122 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
123
124 // right face
125 if (i == size_[0] - 1) {
126 fv[0] = v[3]; fv[1] = v[5]; fv[2] = v[1];
127 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
128 fv[0] = v[3]; fv[1] = v[7]; fv[2] = v[5];
129 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
130 }
131
132 // back face
133 if (j == size_[1] - 1) {
134 fv[0] = v[3]; fv[1] = v[6]; fv[2] = v[7];
135 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
136 fv[0] = v[3]; fv[1] = v[2]; fv[2] = v[6];
137 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
138 }
139
140 // top face
141 if (k == size_[2] - 1) {
142 fv[0] = v[5]; fv[1] = v[6]; fv[2] = v[4];
143 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
144 fv[0] = v[5]; fv[1] = v[7]; fv[2] = v[6];
145 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
146 }
147}
148
149void TetrahedralCuboidGenerator::add_cube_type_2_faces(std::size_t i, std::size_t j, std::size_t k,
150 std::vector<OpenVolumeMesh::VertexHandle> const& v)
151{
152 std::vector<OpenVolumeMesh::VertexHandle> fv(3);
153
154 // left side
155 fv[0] = v[0]; fv[1] = v[2]; fv[2] = v[4];
156 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
157 fv[0] = v[2]; fv[1] = v[6]; fv[2] = v[4];
158 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
159
160 // front side
161 fv[0] = v[0]; fv[1] = v[4]; fv[2] = v[1];
162 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
163 fv[0] = v[4]; fv[1] = v[5]; fv[2] = v[1];
164 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
165
166 // bottom side
167 fv[0] = v[0]; fv[1] = v[1]; fv[2] = v[2];
168 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
169 fv[0] = v[1]; fv[1] = v[3]; fv[2] = v[2];
170 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
171
172 // inner faces
173 fv[0] = v[1]; fv[1] = v[7]; fv[2] = v[4];
174 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
175 fv[0] = v[1]; fv[1] = v[2]; fv[2] = v[7];
176 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
177 fv[0] = v[2]; fv[1] = v[4]; fv[2] = v[7];
178 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
179 fv[0] = v[1]; fv[1] = v[4]; fv[2] = v[2];
180 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
181
182 // right face
183 if (i == size_[0] - 1) {
184 fv[0] = v[1]; fv[1] = v[7]; fv[2] = v[5];
185 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
186 fv[0] = v[1]; fv[1] = v[3]; fv[2] = v[7];
187 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
188 }
189
190 // back face
191 if (j == size_[1] - 1) {
192 fv[0] = v[2]; fv[1] = v[7]; fv[2] = v[3];
193 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
194 fv[0] = v[2]; fv[1] = v[6]; fv[2] = v[7];
195 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
196 }
197
198 // top face
199 if (k == size_[2] - 1) {
200 fv[0] = v[4]; fv[1] = v[7]; fv[2] = v[6];
201 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
202 fv[0] = v[4]; fv[1] = v[5]; fv[2] = v[7];
203 faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
204 }
205}
206
207void TetrahedralCuboidGenerator::add_cells()
208{
209 std::vector<OpenVolumeMesh::VertexHandle> v(8);
210
211 for (std::size_t i = 0; i < size_[0]; ++i)
212 for (std::size_t j = 0; j < size_[1]; ++j)
213 for (std::size_t k = 0; k < size_[2]; ++k)
214 {
215 get_cube_vertices(i, j, k, v);
216
217 if ((i + j + k) % 2 == 0)
218 add_cube_type_1_cells(i, j, k, v);
219 else
220 add_cube_type_2_cells(i, j, k, v);
221 }
222}
223
224void TetrahedralCuboidGenerator::add_cube_type_1_cells(std::size_t i, std::size_t j, std::size_t k,
225 std::vector<OpenVolumeMesh::VertexHandle> const& v)
226{
227 std::vector<OpenVolumeMesh::FaceHandle> f(4);
228 std::vector<OpenVolumeMesh::HalfFaceHandle> hf(4);
229
230 // inner cell
231 f[0] = faces_[SortedFace(v[0], v[5], v[6])];
232 f[1] = faces_[SortedFace(v[0], v[3], v[5])];
233 f[2] = faces_[SortedFace(v[3], v[5], v[6])];
234 f[3] = faces_[SortedFace(v[0], v[3], v[6])];
235 hf[0] = mesh_->halfface_handle(f[0], 1);
236 hf[1] = mesh_->halfface_handle(f[1], 1);
237 hf[2] = mesh_->halfface_handle(f[2], 1);
238 hf[3] = mesh_->halfface_handle(f[3], 1);
239 mesh_->add_cell(hf);
240
241 f[0] = faces_[SortedFace(v[0], v[4], v[6])];
242 f[1] = faces_[SortedFace(v[0], v[4], v[5])];
243 f[2] = faces_[SortedFace(v[4], v[5], v[6])];
244 f[3] = faces_[SortedFace(v[0], v[5], v[6])];
245 hf[0] = mesh_->halfface_handle(f[0], 0);
246 hf[1] = mesh_->halfface_handle(f[1], 0);
247 hf[2] = mesh_->halfface_handle(f[2], 1);
248 hf[3] = mesh_->halfface_handle(f[3], 0);
249 mesh_->add_cell(hf);
250
251 f[0] = faces_[SortedFace(v[1], v[3], v[5])];
252 f[1] = faces_[SortedFace(v[0], v[1], v[5])];
253 f[2] = faces_[SortedFace(v[0], v[1], v[3])];
254 f[3] = faces_[SortedFace(v[0], v[3], v[5])];
255 hf[0] = mesh_->halfface_handle(f[0], 1);
256 hf[1] = mesh_->halfface_handle(f[1], 0);
257 hf[2] = mesh_->halfface_handle(f[2], 0);
258 hf[3] = mesh_->halfface_handle(f[3], 0);
259 mesh_->add_cell(hf);
260
261 f[0] = faces_[SortedFace(v[3], v[5], v[7])];
262 f[1] = faces_[SortedFace(v[3], v[6], v[7])];
263 f[2] = faces_[SortedFace(v[5], v[6], v[7])];
264 f[3] = faces_[SortedFace(v[3], v[5], v[6])];
265 hf[0] = mesh_->halfface_handle(f[0], 1);
266 hf[1] = mesh_->halfface_handle(f[1], 1);
267 hf[2] = mesh_->halfface_handle(f[2], 1);
268 hf[3] = mesh_->halfface_handle(f[3], 0);
269 mesh_->add_cell(hf);
270
271 f[0] = faces_[SortedFace(v[0], v[2], v[6])];
272 f[1] = faces_[SortedFace(v[2], v[3], v[6])];
273 f[2] = faces_[SortedFace(v[0], v[2], v[3])];
274 f[3] = faces_[SortedFace(v[0], v[3], v[6])];
275 hf[0] = mesh_->halfface_handle(f[0], 0);
276 hf[1] = mesh_->halfface_handle(f[1], 1);
277 hf[2] = mesh_->halfface_handle(f[2], 0);
278 hf[3] = mesh_->halfface_handle(f[3], 0);
279 mesh_->add_cell(hf);
280}
281
282void TetrahedralCuboidGenerator::add_cube_type_2_cells(std::size_t i, std::size_t j, std::size_t k,
283 std::vector<OpenVolumeMesh::VertexHandle> const& v)
284{
285 std::vector<OpenVolumeMesh::FaceHandle> f(4);
286 std::vector<OpenVolumeMesh::HalfFaceHandle> hf(4);
287
288 // inner cell
289 f[0] = faces_[SortedFace(v[1], v[2], v[4])];
290 f[1] = faces_[SortedFace(v[1], v[4], v[7])];
291 f[2] = faces_[SortedFace(v[1], v[2], v[7])];
292 f[3] = faces_[SortedFace(v[2], v[4], v[7])];
293 hf[0] = mesh_->halfface_handle(f[0], 1);
294 hf[1] = mesh_->halfface_handle(f[1], 1);
295 hf[2] = mesh_->halfface_handle(f[2], 1);
296 hf[3] = mesh_->halfface_handle(f[3], 1);
297 mesh_->add_cell(hf);
298
299 f[0] = faces_[SortedFace(v[0], v[2], v[4])];
300 f[1] = faces_[SortedFace(v[0], v[1], v[4])];
301 f[2] = faces_[SortedFace(v[0], v[1], v[2])];
302 f[3] = faces_[SortedFace(v[1], v[2], v[4])];
303 hf[0] = mesh_->halfface_handle(f[0], 0);
304 hf[1] = mesh_->halfface_handle(f[1], 0);
305 hf[2] = mesh_->halfface_handle(f[2], 0);
306 hf[3] = mesh_->halfface_handle(f[3], 0);
307 mesh_->add_cell(hf);
308
309 f[0] = faces_[SortedFace(v[1], v[5], v[7])];
310 f[1] = faces_[SortedFace(v[1], v[4], v[5])];
311 f[2] = faces_[SortedFace(v[4], v[5], v[7])];
312 f[3] = faces_[SortedFace(v[1], v[4], v[7])];
313 hf[0] = mesh_->halfface_handle(f[0], 1);
314 hf[1] = mesh_->halfface_handle(f[1], 0);
315 hf[2] = mesh_->halfface_handle(f[2], 1);
316 hf[3] = mesh_->halfface_handle(f[3], 0);
317 mesh_->add_cell(hf);
318
319 f[0] = faces_[SortedFace(v[1], v[3], v[7])];
320 f[1] = faces_[SortedFace(v[2], v[3], v[7])];
321 f[2] = faces_[SortedFace(v[1], v[2], v[3])];
322 f[3] = faces_[SortedFace(v[1], v[2], v[7])];
323 hf[0] = mesh_->halfface_handle(f[0], 1);
324 hf[1] = mesh_->halfface_handle(f[1], 1);
325 hf[2] = mesh_->halfface_handle(f[2], 0);
326 hf[3] = mesh_->halfface_handle(f[3], 0);
327 mesh_->add_cell(hf);
328
329 f[0] = faces_[SortedFace(v[2], v[4], v[6])];
330 f[1] = faces_[SortedFace(v[2], v[6], v[7])];
331 f[2] = faces_[SortedFace(v[4], v[6], v[7])];
332 f[3] = faces_[SortedFace(v[2], v[4], v[7])];
333 hf[0] = mesh_->halfface_handle(f[0], 0);
334 hf[1] = mesh_->halfface_handle(f[1], 1);
335 hf[2] = mesh_->halfface_handle(f[2], 1);
336 hf[3] = mesh_->halfface_handle(f[3], 0);
337 mesh_->add_cell(hf);
338}
339
340TetrahedralCuboidGenerator::TetrahedralCuboidGenerator(PolyhedralMesh& mesh,
341 Vector const& position,
342 Vector const& length,
343 unsigned const n_x,
344 unsigned const n_y,
345 unsigned const n_z) :
346 mesh_(&mesh)
347{
348 mesh_->clear(false);
349
350 size_[0] = n_x;
351 size_[1] = n_y;
352 size_[2] = n_z;
353
354 add_vertices(position, length);
355 add_faces();
356 add_cells();
357
358 vertices_.clear();
359 faces_.clear();
360}
361
362#endif
VertexHandle add_vertex(const VecT &_p)
Add a geometric point to the mesh.
virtual FaceHandle add_face(std::vector< HalfEdgeHandle > _halfedges, bool _topologyCheck=false)
Add face via incident edges.
static HalfFaceHandle halfface_handle(FaceHandle _h, const unsigned char _subIdx)
Conversion function.
virtual CellHandle add_cell(std::vector< HalfFaceHandle > _halffaces, bool _topologyCheck=false)
Add cell via incident halffaces.