OpenVDB  7.0.0
LevelSetPlatonic.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
13 
14 #ifndef OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
15 #define OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
16 
17 #include <openvdb/Grid.h>
18 #include <openvdb/Types.h>
19 #include <openvdb/math/Math.h>
20 #include <openvdb/math/Transform.h>
23 #include <type_traits>
24 #include <vector>
25 
26 
27 namespace openvdb {
29 namespace OPENVDB_VERSION_NAME {
30 namespace tools {
31 
45 template<typename GridType, typename InterruptT>
46 typename GridType::Ptr
48  int faceCount, // 4, 6, 8, 12 or 20
49  float scale = 1.0f,
50  const Vec3f& center = Vec3f(0.0f),
51  float voxelSize = 0.1f,
52  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
53  InterruptT* interrupt = nullptr);
54 
67 template<typename GridType>
68 typename GridType::Ptr
70  int faceCount,// 4, 6, 8, 12 or 20
71  float scale = 1.0f,
72  const Vec3f& center = Vec3f(0.0f),
73  float voxelSize = 0.1f,
74  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
75 {
77  return createLevelSetPlatonic<GridType>(faceCount, scale, center, voxelSize, halfWidth, &tmp);
78 }
79 
81 
92 template<typename GridType, typename InterruptT>
93 typename GridType::Ptr
95  float scale = 1.0f,
96  const Vec3f& center = Vec3f(0.0f),
97  float voxelSize = 0.1f,
98  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
99  InterruptT* interrupt = nullptr)
100 {
101  return createLevelSetPlatonic<GridType, InterruptT>(
102  4, scale, center, voxelSize, halfWidth, interrupt);
103 }
104 
114 template<typename GridType>
115 typename GridType::Ptr
117  float scale = 1.0f,
118  const Vec3f& center = Vec3f(0.0f),
119  float voxelSize = 0.1f,
120  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
121 {
123  return createLevelSetPlatonic<GridType>(4, scale, center, voxelSize, halfWidth, &tmp);
124 }
125 
127 
138 template<typename GridType, typename InterruptT>
139 typename GridType::Ptr
141  float scale = 1.0f,
142  const Vec3f& center = Vec3f(0.0f),
143  float voxelSize = 0.1f,
144  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
145  InterruptT* interrupt = nullptr)
146 {
147  return createLevelSetPlatonic<GridType>(6, scale, center, voxelSize, halfWidth, interrupt);
148 }
149 
159 template<typename GridType>
160 typename GridType::Ptr
162  float scale = 1.0f,
163  const Vec3f& center = Vec3f(0.0f),
164  float voxelSize = 0.1f,
165  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
166 {
168  return createLevelSetPlatonic<GridType>(6, scale, center, voxelSize, halfWidth, &tmp);
169 }
170 
172 
183 template<typename GridType, typename InterruptT>
184 typename GridType::Ptr
186  float scale = 1.0f,
187  const Vec3f& center = Vec3f(0.0f),
188  float voxelSize = 0.1f,
189  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
190  InterruptT* interrupt = nullptr)
191 {
192  return createLevelSetPlatonic<GridType>(8, scale, center, voxelSize, halfWidth, interrupt);
193 }
194 
204 template<typename GridType>
205 typename GridType::Ptr
207  float scale = 1.0f,
208  const Vec3f& center = Vec3f(0.0f),
209  float voxelSize = 0.1f,
210  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
211 {
213  return createLevelSetPlatonic<GridType>(8, scale, center, voxelSize, halfWidth, &tmp);
214 }
215 
217 
228 template<typename GridType, typename InterruptT>
229 typename GridType::Ptr
231  float scale = 1.0f,
232  const Vec3f& center = Vec3f(0.0f),
233  float voxelSize = 0.1f,
234  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
235  InterruptT* interrupt = nullptr)
236 {
237  return createLevelSetPlatonic<GridType>(12, scale, center, voxelSize, halfWidth, interrupt);
238 }
239 
249 template<typename GridType>
250 typename GridType::Ptr
252  float scale = 1.0f,
253  const Vec3f& center = Vec3f(0.0f),
254  float voxelSize = 0.1f,
255  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
256 {
258  return createLevelSetPlatonic<GridType>(12, scale, center, voxelSize, halfWidth, &tmp);
259 }
260 
262 
273 template<typename GridType, typename InterruptT>
274 typename GridType::Ptr
276  float scale = 1.0f,
277  const Vec3f& center = Vec3f(0.0f),
278  float voxelSize = 0.1f,
279  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
280  InterruptT* interrupt = nullptr)
281 {
282  return createLevelSetPlatonic<GridType>(20, scale, center, voxelSize, halfWidth, interrupt);
283 }
284 
294 template<typename GridType>
295 typename GridType::Ptr
297  float scale = 1.0f,
298  const Vec3f& center = Vec3f(0.0f),
299  float voxelSize = 0.1f,
300  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
301 {
303  return createLevelSetPlatonic<GridType>(20, scale, center, voxelSize, halfWidth, &tmp);
304 }
305 
307 
308 template<typename GridType, typename InterruptT>
309 typename GridType::Ptr
310 createLevelSetPlatonic(int faceCount,float scale, const Vec3f& center,
311  float voxelSize, float halfWidth, InterruptT *interrupt)
312 {
313  // GridType::ValueType is required to be a floating-point scalar.
314  static_assert(std::is_floating_point<typename GridType::ValueType>::value,
315  "level set grids must have scalar, floating-point value types");
316 
317  const math::Transform::Ptr xform = math::Transform::createLinearTransform( voxelSize );
318 
319  std::vector<Vec3f> vtx;
320  std::vector<Vec3I> tri;
321  std::vector<Vec4I> qua;
322 
323  if (faceCount == 4) {// Tetrahedron
324 
325  vtx.push_back( Vec3f( 0.0f, 1.0f, 0.0f) );
326  vtx.push_back( Vec3f(-0.942810297f, -0.333329707f, 0.0f) );
327  vtx.push_back( Vec3f( 0.471405149f, -0.333329707f, 0.816497624f) );
328  vtx.push_back( Vec3f( 0.471405149f, -0.333329707f, -0.816497624f) );
329 
330  tri.push_back( Vec3I(0, 2, 3) );
331  tri.push_back( Vec3I(0, 3, 1) );
332  tri.push_back( Vec3I(0, 1, 2) );
333  tri.push_back( Vec3I(1, 3, 2) );
334 
335  } else if (faceCount == 6) {// Cube
336 
337  vtx.push_back( Vec3f(-0.5f, -0.5f, -0.5f) );
338  vtx.push_back( Vec3f( 0.5f, -0.5f, -0.5f) );
339  vtx.push_back( Vec3f( 0.5f, -0.5f, 0.5f) );
340  vtx.push_back( Vec3f(-0.5f, -0.5f, 0.5f) );
341  vtx.push_back( Vec3f(-0.5f, 0.5f, -0.5f) );
342  vtx.push_back( Vec3f( 0.5f, 0.5f, -0.5f) );
343  vtx.push_back( Vec3f( 0.5f, 0.5f, 0.5f) );
344  vtx.push_back( Vec3f(-0.5f, 0.5f, 0.5f) );
345 
346  qua.push_back( Vec4I(1, 0, 4, 5) );
347  qua.push_back( Vec4I(2, 1, 5, 6) );
348  qua.push_back( Vec4I(3, 2, 6, 7) );
349  qua.push_back( Vec4I(0, 3, 7, 4) );
350  qua.push_back( Vec4I(2, 3, 0, 1) );
351  qua.push_back( Vec4I(5, 4, 7, 6) );
352 
353  } else if (faceCount == 8) {// Octahedron
354 
355  vtx.push_back( Vec3f( 0.0f, 0.0f, -1.0f) );
356  vtx.push_back( Vec3f( 1.0f, 0.0f, 0.0f) );
357  vtx.push_back( Vec3f( 0.0f, 0.0f, 1.0f) );
358  vtx.push_back( Vec3f(-1.0f, 0.0f, 0.0f) );
359  vtx.push_back( Vec3f( 0.0f,-1.0f, 0.0f) );
360  vtx.push_back( Vec3f( 0.0f, 1.0f, 0.0f) );
361 
362  tri.push_back( Vec3I(0, 4, 3) );
363  tri.push_back( Vec3I(0, 1, 4) );
364  tri.push_back( Vec3I(1, 2, 4) );
365  tri.push_back( Vec3I(2, 3, 4) );
366  tri.push_back( Vec3I(0, 3, 5) );
367  tri.push_back( Vec3I(0, 5, 1) );
368  tri.push_back( Vec3I(1, 5, 2) );
369  tri.push_back( Vec3I(2, 5, 3) );
370 
371  } else if (faceCount == 12) {// Dodecahedron
372 
373  vtx.push_back( Vec3f( 0.354437858f, 0.487842113f, -0.789344311f) );
374  vtx.push_back( Vec3f( 0.573492587f, -0.186338872f, -0.78934437f) );
375  vtx.push_back( Vec3f( 0.0f, -0.603005826f, -0.78934443f) );
376  vtx.push_back( Vec3f(-0.573492587f, -0.186338872f, -0.78934437f) );
377  vtx.push_back( Vec3f(-0.354437858f, 0.487842113f, -0.789344311f) );
378  vtx.push_back( Vec3f(-0.573492587f, 0.789345026f, -0.186338797f) );
379  vtx.push_back( Vec3f(-0.927930415f, -0.301502913f, -0.186338872f) );
380  vtx.push_back( Vec3f( 0.0f, -0.975683928f, -0.186338902f) );
381  vtx.push_back( Vec3f( 0.927930415f, -0.301502913f, -0.186338872f) );
382  vtx.push_back( Vec3f( 0.573492587f, 0.789345026f, -0.186338797f) );
383  vtx.push_back( Vec3f( 0.0f, 0.975683868f, 0.186338902f) );
384  vtx.push_back( Vec3f(-0.927930415f, 0.301502913f, 0.186338872f) );
385  vtx.push_back( Vec3f(-0.573492587f, -0.789345026f, 0.186338797f) );
386  vtx.push_back( Vec3f( 0.573492587f, -0.789345026f, 0.186338797f) );
387  vtx.push_back( Vec3f( 0.927930415f, 0.301502913f, 0.186338872f) );
388  vtx.push_back( Vec3f( 0.0f, 0.603005826f, 0.78934443f) );
389  vtx.push_back( Vec3f( 0.573492587f, 0.186338872f, 0.78934437f) );
390  vtx.push_back( Vec3f( 0.354437858f, -0.487842113f, 0.789344311f) );
391  vtx.push_back( Vec3f(-0.354437858f, -0.487842113f, 0.789344311f) );
392  vtx.push_back( Vec3f(-0.573492587f, 0.186338872f, 0.78934437f) );
393 
394  qua.push_back( Vec4I(0, 1, 2, 3) );
395  tri.push_back( Vec3I(0, 3, 4) );
396  qua.push_back( Vec4I(0, 4, 5, 10) );
397  tri.push_back( Vec3I(0, 10, 9) );
398  qua.push_back( Vec4I(0, 9, 14, 8) );
399  tri.push_back( Vec3I(0, 8, 1) );
400  qua.push_back( Vec4I(1, 8, 13, 7) );
401  tri.push_back( Vec3I(1, 7, 2) );
402  qua.push_back( Vec4I(2, 7, 12, 6) );
403  tri.push_back( Vec3I(2, 6, 3) );
404  qua.push_back( Vec4I(3, 6, 11, 5) );
405  tri.push_back( Vec3I(3, 5, 4) );
406  qua.push_back( Vec4I(5, 11, 19, 15) );
407  tri.push_back( Vec3I(5, 15, 10) );
408  qua.push_back( Vec4I(6, 12, 18, 19) );
409  tri.push_back( Vec3I(6, 19, 11) );
410  qua.push_back( Vec4I(7, 13, 17, 18) );
411  tri.push_back( Vec3I(7, 18, 12) );
412  qua.push_back( Vec4I(8, 14, 16, 17) );
413  tri.push_back( Vec3I(8, 17, 13) );
414  qua.push_back( Vec4I(9, 10, 15, 16) );
415  tri.push_back( Vec3I(9, 16, 14) );
416  qua.push_back( Vec4I(15, 19, 18, 17) );
417  tri.push_back( Vec3I(15, 17, 16) );
418 
419  } else if (faceCount == 20) {// Icosahedron
420 
421  vtx.push_back( Vec3f(0.0f, 0.0f, -1.0f) );
422  vtx.push_back( Vec3f(0.0f, 0.894427359f, -0.447213143f) );
423  vtx.push_back( Vec3f(0.850650847f, 0.276393682f, -0.447213203f) );
424  vtx.push_back( Vec3f(0.525731206f, -0.723606944f, -0.447213262f) );
425  vtx.push_back( Vec3f(-0.525731206f, -0.723606944f, -0.447213262f) );
426  vtx.push_back( Vec3f(-0.850650847f, 0.276393682f, -0.447213203f) );
427  vtx.push_back( Vec3f(-0.525731206f, 0.723606944f, 0.447213262f) );
428  vtx.push_back( Vec3f(-0.850650847f, -0.276393682f, 0.447213203f) );
429  vtx.push_back( Vec3f(0.0f, -0.894427359f, 0.447213143f) );
430  vtx.push_back( Vec3f(0.850650847f, -0.276393682f, 0.447213203f) );
431  vtx.push_back( Vec3f(0.525731206f, 0.723606944f, 0.447213262f) );
432  vtx.push_back( Vec3f(0.0f, 0.0f, 1.0f) );
433 
434  tri.push_back( Vec3I( 2, 0, 1) );
435  tri.push_back( Vec3I( 3, 0, 2) );
436  tri.push_back( Vec3I( 4, 0, 3) );
437  tri.push_back( Vec3I( 5, 0, 4) );
438  tri.push_back( Vec3I( 1, 0, 5) );
439  tri.push_back( Vec3I( 6, 1, 5) );
440  tri.push_back( Vec3I( 7, 5, 4) );
441  tri.push_back( Vec3I( 8, 4, 3) );
442  tri.push_back( Vec3I( 9, 3, 2) );
443  tri.push_back( Vec3I(10, 2, 1) );
444  tri.push_back( Vec3I(10, 1, 6) );
445  tri.push_back( Vec3I( 6, 5, 7) );
446  tri.push_back( Vec3I( 7, 4, 8) );
447  tri.push_back( Vec3I( 8, 3, 9) );
448  tri.push_back( Vec3I( 9, 2, 10) );
449  tri.push_back( Vec3I( 6, 11, 10) );
450  tri.push_back( Vec3I(10, 11, 9) );
451  tri.push_back( Vec3I( 9, 11, 8) );
452  tri.push_back( Vec3I( 8, 11, 7) );
453  tri.push_back( Vec3I( 7, 11, 6) );
454 
455  } else {
456  OPENVDB_THROW(RuntimeError, "Invalid face count");
457  }
458 
459  // Apply scale and translation to all the vertices
460  for ( size_t i = 0; i<vtx.size(); ++i ) vtx[i] = scale * vtx[i] + center;
461 
462  typename GridType::Ptr grid;
463 
464  if (interrupt == nullptr) {
466  grid = meshToLevelSet<GridType>(tmp, *xform, vtx, tri, qua, halfWidth);
467  } else {
468  grid = meshToLevelSet<GridType>(*interrupt, *xform, vtx, tri, qua, halfWidth);
469  }
470 
471  return grid;
472 }
473 
474 } // namespace tools
475 } // namespace OPENVDB_VERSION_NAME
476 } // namespace openvdb
477 
478 #endif // OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
GridType::Ptr createLevelSetOctahedron(float scale=1.0f, const Vec3f &center=Vec3f(0.0f), float voxelSize=0.1f, float halfWidth=float(LEVEL_SET_HALF_WIDTH))
Return a grid of type GridType containing a narrow-band level set representation of an octahedron...
Definition: LevelSetPlatonic.h:206
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:460
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
math::Vec3< float > Vec3f
Definition: Types.h:51
GridType::Ptr createLevelSetCube(float scale=1.0f, const Vec3f &center=Vec3f(0.0f), float voxelSize=0.1f, float halfWidth=float(LEVEL_SET_HALF_WIDTH))
Return a grid of type GridType containing a narrow-band level set representation of a cube...
Definition: LevelSetPlatonic.h:161
GridType::Ptr createLevelSetIcosahedron(float scale=1.0f, const Vec3f &center=Vec3f(0.0f), float voxelSize=0.1f, float halfWidth=float(LEVEL_SET_HALF_WIDTH))
Return a grid of type GridType containing a narrow-band level set representation of an icosahedron...
Definition: LevelSetPlatonic.h:296
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
math::Vec3< Index32 > Vec3I
Definition: Types.h:50
Convert polygonal meshes that consist of quads and/or triangles into signed or unsigned distance fiel...
GridType::Ptr createLevelSetDodecahedron(float scale=1.0f, const Vec3f &center=Vec3f(0.0f), float voxelSize=0.1f, float halfWidth=float(LEVEL_SET_HALF_WIDTH))
Return a grid of type GridType containing a narrow-band level set representation of a dodecahedron...
Definition: LevelSetPlatonic.h:251
Definition: Exceptions.h:13
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:25
GridType::Ptr createLevelSetPlatonic(int faceCount, float scale=1.0f, const Vec3f &center=Vec3f(0.0f), float voxelSize=0.1f, float halfWidth=float(LEVEL_SET_HALF_WIDTH))
Return a grid of type GridType containing a narrow-band level set representation of a platonic solid...
Definition: LevelSetPlatonic.h:69
Definition: Exceptions.h:63
math::Vec4< Index32 > Vec4I
Definition: Types.h:65
Definition: Mat.h:170
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
GridType::Ptr createLevelSetTetrahedron(float scale=1.0f, const Vec3f &center=Vec3f(0.0f), float voxelSize=0.1f, float halfWidth=float(LEVEL_SET_HALF_WIDTH))
Return a grid of type GridType containing a narrow-band level set representation of a tetrahedron...
Definition: LevelSetPlatonic.h:116
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:620
SharedPtr< Transform > Ptr
Definition: Transform.h:42