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 * *
44  * $Revision$ *
45  * $LastChangedBy$ *
46  * $Date$ *
47  * *
48  \*===========================================================================*/
49 
50 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
51 
52 #include "TetrahedralCuboidGenerator.hh"
53 
54 void TetrahedralCuboidGenerator::add_vertices(Vector const& position, Vector const& length)
55 {
56  vertices_.clear();
57  vertices_.reserve((size_[0] + 1) * (size_[1] + 1) * (size_[2] + 1));
58 
59  Vector h(length[0] / size_[0], length[1] / size_[1], length[2] / size_[2]);
60  Vector origin = position - 0.5 * length;
61 
62  for (std::size_t k = 0; k < size_[2] + 1; ++k)
63  for (std::size_t j = 0; j < size_[1] + 1; ++j)
64  for (std::size_t i = 0; i < size_[0] + 1; ++i)
65  vertices_.push_back(mesh_->add_vertex(Vector(h[0]*i, h[1]*j, h[2]*k) + origin));
66 }
67 
68 void TetrahedralCuboidGenerator::get_cube_vertices(std::size_t i, std::size_t j, std::size_t k,
69  std::vector<OpenVolumeMesh::VertexHandle>& v) const
70 {
71  v[0] = vertices_[k * (size_[0] + 1) * (size_[1] + 1) + j * (size_[0] + 1) + i];
72  v[1] = vertices_[k * (size_[0] + 1) * (size_[1] + 1) + j * (size_[0] + 1) + i + 1];
73  v[2] = vertices_[k * (size_[0] + 1) * (size_[1] + 1) + (j + 1) * (size_[0] + 1) + i];
74  v[3] = vertices_[k * (size_[0] + 1) * (size_[1] + 1) + (j + 1) * (size_[0] + 1) + i + 1];
75  v[4] = vertices_[(k + 1) * (size_[0] + 1) * (size_[1] + 1) + j * (size_[0] + 1) + i];
76  v[5] = vertices_[(k + 1) * (size_[0] + 1) * (size_[1] + 1) + j * (size_[0] + 1) + i + 1];
77  v[6] = vertices_[(k + 1) * (size_[0] + 1) * (size_[1] + 1) + (j + 1) * (size_[0] + 1) + i];
78  v[7] = vertices_[(k + 1) * (size_[0] + 1) * (size_[1] + 1) + (j + 1) * (size_[0] + 1) + i + 1];
79 }
80 
81 void TetrahedralCuboidGenerator::add_faces()
82 {
83  std::vector<OpenVolumeMesh::VertexHandle> v(8);
84 
85  for (std::size_t i = 0; i < size_[0]; ++i)
86  for (std::size_t j = 0; j < size_[1]; ++j)
87  for (std::size_t k = 0; k < size_[2]; ++k)
88  {
89  get_cube_vertices(i, j, k, v);
90 
91  if ((i + j + k) % 2 == 0)
92  add_cube_type_1_faces(i, j, k, v);
93  else
94  add_cube_type_2_faces(i, j, k, v);
95  }
96 }
97 
98 void TetrahedralCuboidGenerator::add_cube_type_1_faces(std::size_t i, std::size_t j, std::size_t k,
99  std::vector<OpenVolumeMesh::VertexHandle> const& v)
100 {
101  std::vector<OpenVolumeMesh::VertexHandle> fv(3);
102 
103  // left side
104  fv[0] = v[0]; fv[1] = v[2]; fv[2] = v[6];
105  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
106  fv[0] = v[0]; fv[1] = v[6]; fv[2] = v[4];
107  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
108 
109  // front side
110  fv[0] = v[0]; fv[1] = v[4]; fv[2] = v[5];
111  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
112  fv[0] = v[0]; fv[1] = v[5]; fv[2] = v[1];
113  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
114 
115  // bottom side
116  fv[0] = v[0]; fv[1] = v[1]; fv[2] = v[3];
117  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
118  fv[0] = v[0]; fv[1] = v[3]; fv[2] = v[2];
119  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
120 
121  // inner faces
122  fv[0] = v[0]; fv[1] = v[5]; fv[2] = v[6];
123  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
124  fv[0] = v[0]; fv[1] = v[3]; fv[2] = v[5];
125  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
126  fv[0] = v[0]; fv[1] = v[6]; fv[2] = v[3];
127  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
128  fv[0] = v[3]; fv[1] = v[6]; fv[2] = v[5];
129  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
130 
131  // right face
132  if (i == size_[0] - 1) {
133  fv[0] = v[3]; fv[1] = v[5]; fv[2] = v[1];
134  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
135  fv[0] = v[3]; fv[1] = v[7]; fv[2] = v[5];
136  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
137  }
138 
139  // back face
140  if (j == size_[1] - 1) {
141  fv[0] = v[3]; fv[1] = v[6]; fv[2] = v[7];
142  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
143  fv[0] = v[3]; fv[1] = v[2]; fv[2] = v[6];
144  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
145  }
146 
147  // top face
148  if (k == size_[2] - 1) {
149  fv[0] = v[5]; fv[1] = v[6]; fv[2] = v[4];
150  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
151  fv[0] = v[5]; fv[1] = v[7]; fv[2] = v[6];
152  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
153  }
154 }
155 
156 void TetrahedralCuboidGenerator::add_cube_type_2_faces(std::size_t i, std::size_t j, std::size_t k,
157  std::vector<OpenVolumeMesh::VertexHandle> const& v)
158 {
159  std::vector<OpenVolumeMesh::VertexHandle> fv(3);
160 
161  // left side
162  fv[0] = v[0]; fv[1] = v[2]; fv[2] = v[4];
163  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
164  fv[0] = v[2]; fv[1] = v[6]; fv[2] = v[4];
165  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
166 
167  // front side
168  fv[0] = v[0]; fv[1] = v[4]; fv[2] = v[1];
169  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
170  fv[0] = v[4]; fv[1] = v[5]; fv[2] = v[1];
171  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
172 
173  // bottom side
174  fv[0] = v[0]; fv[1] = v[1]; fv[2] = v[2];
175  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
176  fv[0] = v[1]; fv[1] = v[3]; fv[2] = v[2];
177  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
178 
179  // inner faces
180  fv[0] = v[1]; fv[1] = v[7]; fv[2] = v[4];
181  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
182  fv[0] = v[1]; fv[1] = v[2]; fv[2] = v[7];
183  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
184  fv[0] = v[2]; fv[1] = v[4]; fv[2] = v[7];
185  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
186  fv[0] = v[1]; fv[1] = v[4]; fv[2] = v[2];
187  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
188 
189  // right face
190  if (i == size_[0] - 1) {
191  fv[0] = v[1]; fv[1] = v[7]; fv[2] = v[5];
192  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
193  fv[0] = v[1]; fv[1] = v[3]; fv[2] = v[7];
194  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
195  }
196 
197  // back face
198  if (j == size_[1] - 1) {
199  fv[0] = v[2]; fv[1] = v[7]; fv[2] = v[3];
200  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
201  fv[0] = v[2]; fv[1] = v[6]; fv[2] = v[7];
202  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
203  }
204 
205  // top face
206  if (k == size_[2] - 1) {
207  fv[0] = v[4]; fv[1] = v[7]; fv[2] = v[6];
208  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
209  fv[0] = v[4]; fv[1] = v[5]; fv[2] = v[7];
210  faces_.insert(std::make_pair(SortedFace(fv), mesh_->add_face(fv)));
211  }
212 }
213 
214 void TetrahedralCuboidGenerator::add_cells()
215 {
216  std::vector<OpenVolumeMesh::VertexHandle> v(8);
217 
218  for (std::size_t i = 0; i < size_[0]; ++i)
219  for (std::size_t j = 0; j < size_[1]; ++j)
220  for (std::size_t k = 0; k < size_[2]; ++k)
221  {
222  get_cube_vertices(i, j, k, v);
223 
224  if ((i + j + k) % 2 == 0)
225  add_cube_type_1_cells(i, j, k, v);
226  else
227  add_cube_type_2_cells(i, j, k, v);
228  }
229 }
230 
231 void TetrahedralCuboidGenerator::add_cube_type_1_cells(std::size_t i, std::size_t j, std::size_t k,
232  std::vector<OpenVolumeMesh::VertexHandle> const& v)
233 {
234  std::vector<OpenVolumeMesh::FaceHandle> f(4);
235  std::vector<OpenVolumeMesh::HalfFaceHandle> hf(4);
236 
237  // inner cell
238  f[0] = faces_[SortedFace(v[0], v[5], v[6])];
239  f[1] = faces_[SortedFace(v[0], v[3], v[5])];
240  f[2] = faces_[SortedFace(v[3], v[5], v[6])];
241  f[3] = faces_[SortedFace(v[0], v[3], v[6])];
242  hf[0] = mesh_->halfface_handle(f[0], 1);
243  hf[1] = mesh_->halfface_handle(f[1], 1);
244  hf[2] = mesh_->halfface_handle(f[2], 1);
245  hf[3] = mesh_->halfface_handle(f[3], 1);
246  mesh_->add_cell(hf);
247 
248  f[0] = faces_[SortedFace(v[0], v[4], v[6])];
249  f[1] = faces_[SortedFace(v[0], v[4], v[5])];
250  f[2] = faces_[SortedFace(v[4], v[5], v[6])];
251  f[3] = faces_[SortedFace(v[0], v[5], v[6])];
252  hf[0] = mesh_->halfface_handle(f[0], 0);
253  hf[1] = mesh_->halfface_handle(f[1], 0);
254  hf[2] = mesh_->halfface_handle(f[2], 1);
255  hf[3] = mesh_->halfface_handle(f[3], 0);
256  mesh_->add_cell(hf);
257 
258  f[0] = faces_[SortedFace(v[1], v[3], v[5])];
259  f[1] = faces_[SortedFace(v[0], v[1], v[5])];
260  f[2] = faces_[SortedFace(v[0], v[1], v[3])];
261  f[3] = faces_[SortedFace(v[0], v[3], v[5])];
262  hf[0] = mesh_->halfface_handle(f[0], 1);
263  hf[1] = mesh_->halfface_handle(f[1], 0);
264  hf[2] = mesh_->halfface_handle(f[2], 0);
265  hf[3] = mesh_->halfface_handle(f[3], 0);
266  mesh_->add_cell(hf);
267 
268  f[0] = faces_[SortedFace(v[3], v[5], v[7])];
269  f[1] = faces_[SortedFace(v[3], v[6], v[7])];
270  f[2] = faces_[SortedFace(v[5], v[6], v[7])];
271  f[3] = faces_[SortedFace(v[3], v[5], v[6])];
272  hf[0] = mesh_->halfface_handle(f[0], 1);
273  hf[1] = mesh_->halfface_handle(f[1], 1);
274  hf[2] = mesh_->halfface_handle(f[2], 1);
275  hf[3] = mesh_->halfface_handle(f[3], 0);
276  mesh_->add_cell(hf);
277 
278  f[0] = faces_[SortedFace(v[0], v[2], v[6])];
279  f[1] = faces_[SortedFace(v[2], v[3], v[6])];
280  f[2] = faces_[SortedFace(v[0], v[2], v[3])];
281  f[3] = faces_[SortedFace(v[0], v[3], v[6])];
282  hf[0] = mesh_->halfface_handle(f[0], 0);
283  hf[1] = mesh_->halfface_handle(f[1], 1);
284  hf[2] = mesh_->halfface_handle(f[2], 0);
285  hf[3] = mesh_->halfface_handle(f[3], 0);
286  mesh_->add_cell(hf);
287 }
288 
289 void TetrahedralCuboidGenerator::add_cube_type_2_cells(std::size_t i, std::size_t j, std::size_t k,
290  std::vector<OpenVolumeMesh::VertexHandle> const& v)
291 {
292  std::vector<OpenVolumeMesh::FaceHandle> f(4);
293  std::vector<OpenVolumeMesh::HalfFaceHandle> hf(4);
294 
295  // inner cell
296  f[0] = faces_[SortedFace(v[1], v[2], v[4])];
297  f[1] = faces_[SortedFace(v[1], v[4], v[7])];
298  f[2] = faces_[SortedFace(v[1], v[2], v[7])];
299  f[3] = faces_[SortedFace(v[2], v[4], v[7])];
300  hf[0] = mesh_->halfface_handle(f[0], 1);
301  hf[1] = mesh_->halfface_handle(f[1], 1);
302  hf[2] = mesh_->halfface_handle(f[2], 1);
303  hf[3] = mesh_->halfface_handle(f[3], 1);
304  mesh_->add_cell(hf);
305 
306  f[0] = faces_[SortedFace(v[0], v[2], v[4])];
307  f[1] = faces_[SortedFace(v[0], v[1], v[4])];
308  f[2] = faces_[SortedFace(v[0], v[1], v[2])];
309  f[3] = faces_[SortedFace(v[1], v[2], v[4])];
310  hf[0] = mesh_->halfface_handle(f[0], 0);
311  hf[1] = mesh_->halfface_handle(f[1], 0);
312  hf[2] = mesh_->halfface_handle(f[2], 0);
313  hf[3] = mesh_->halfface_handle(f[3], 0);
314  mesh_->add_cell(hf);
315 
316  f[0] = faces_[SortedFace(v[1], v[5], v[7])];
317  f[1] = faces_[SortedFace(v[1], v[4], v[5])];
318  f[2] = faces_[SortedFace(v[4], v[5], v[7])];
319  f[3] = faces_[SortedFace(v[1], v[4], v[7])];
320  hf[0] = mesh_->halfface_handle(f[0], 1);
321  hf[1] = mesh_->halfface_handle(f[1], 0);
322  hf[2] = mesh_->halfface_handle(f[2], 1);
323  hf[3] = mesh_->halfface_handle(f[3], 0);
324  mesh_->add_cell(hf);
325 
326  f[0] = faces_[SortedFace(v[1], v[3], v[7])];
327  f[1] = faces_[SortedFace(v[2], v[3], v[7])];
328  f[2] = faces_[SortedFace(v[1], v[2], v[3])];
329  f[3] = faces_[SortedFace(v[1], v[2], v[7])];
330  hf[0] = mesh_->halfface_handle(f[0], 1);
331  hf[1] = mesh_->halfface_handle(f[1], 1);
332  hf[2] = mesh_->halfface_handle(f[2], 0);
333  hf[3] = mesh_->halfface_handle(f[3], 0);
334  mesh_->add_cell(hf);
335 
336  f[0] = faces_[SortedFace(v[2], v[4], v[6])];
337  f[1] = faces_[SortedFace(v[2], v[6], v[7])];
338  f[2] = faces_[SortedFace(v[4], v[6], v[7])];
339  f[3] = faces_[SortedFace(v[2], v[4], v[7])];
340  hf[0] = mesh_->halfface_handle(f[0], 0);
341  hf[1] = mesh_->halfface_handle(f[1], 1);
342  hf[2] = mesh_->halfface_handle(f[2], 1);
343  hf[3] = mesh_->halfface_handle(f[3], 0);
344  mesh_->add_cell(hf);
345 }
346 
347 TetrahedralCuboidGenerator::TetrahedralCuboidGenerator(PolyhedralMesh& mesh,
348  Vector const& position,
349  Vector const& length,
350  unsigned const n_x,
351  unsigned const n_y,
352  unsigned const n_z) :
353  mesh_(&mesh)
354 {
355  mesh_->clear(false);
356 
357  size_[0] = n_x;
358  size_[1] = n_y;
359  size_[2] = n_z;
360 
361  add_vertices(position, length);
362  add_faces();
363  add_cells();
364 
365  vertices_.clear();
366  faces_.clear();
367 }
368 
369 #endif
virtual VertexHandle add_vertex()
Override of empty add_vertex function.