Developer Documentation
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 
47 void 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 
61 void 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 
74 void 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 
91 void 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 
149 void 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 
207 void 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 
224 void 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 
282 void 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 
340 TetrahedralCuboidGenerator::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() override
Override of empty add_vertex function.