OpenVDB  3.2.0
LevelSetPlatonic.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2016 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
40 
41 #ifndef OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
42 #define OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
43 
44 #include <vector>
45 #include <openvdb/Grid.h>
46 #include <openvdb/Types.h>
47 #include <openvdb/math/Math.h>
48 #include <openvdb/math/Transform.h>
51 #include <boost/utility.hpp>
52 #include <boost/type_traits/is_floating_point.hpp>
53 
54 namespace openvdb {
56 namespace OPENVDB_VERSION_NAME {
57 namespace tools {
58 
72 template<typename GridType, typename InterruptT>
73 typename GridType::Ptr
74 createLevelSetPlatonic(int faceCount,// 4, 6, 8, 12 or 20
75  float scale = 1.0f,
76  const Vec3f& center = Vec3f(0.0f),
77  float voxelSize = 0.1f,
78  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
79  InterruptT* interrupt = NULL);
80 
93 template<typename GridType>
94 typename GridType::Ptr
95 createLevelSetPlatonic(int faceCount,// 4, 6, 8, 12 or 20
96  float scale = 1.0f,
97  const Vec3f& center = Vec3f(0.0f),
98  float voxelSize = 0.1f,
99  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
100 {
102  return createLevelSetPlatonic<GridType>(faceCount, scale, center, voxelSize, halfWidth, &tmp);
103 }
104 
106 
117 template<typename GridType, typename InterruptT>
118 typename GridType::Ptr
120  const Vec3f& center = Vec3f(0.0f),
121  float voxelSize = 0.1f,
122  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
123  InterruptT* interrupt = NULL)
124 {
125  return createLevelSetPlatonic<GridType, InterruptT>(4, scale, center,
126  voxelSize, halfWidth, interrupt);
127 }
128 
138 template<typename GridType>
139 typename GridType::Ptr
141  const Vec3f& center = Vec3f(0.0f),
142  float voxelSize = 0.1f,
143  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
144 {
146  return createLevelSetPlatonic<GridType>(4, scale, center, voxelSize, halfWidth, &tmp);
147 }
148 
150 
161 template<typename GridType, typename InterruptT>
162 typename GridType::Ptr
164  const Vec3f& center = Vec3f(0.0f),
165  float voxelSize = 0.1f,
166  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
167  InterruptT* interrupt = NULL)
168 {
169  return createLevelSetPlatonic<GridType>(6, scale, center, voxelSize, halfWidth, interrupt);
170 }
171 
181 template<typename GridType>
182 typename GridType::Ptr
184  const Vec3f& center = Vec3f(0.0f),
185  float voxelSize = 0.1f,
186  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
187 {
189  return createLevelSetPlatonic<GridType>(6, scale, center, voxelSize, halfWidth, &tmp);
190 }
191 
193 
204 template<typename GridType, typename InterruptT>
205 typename GridType::Ptr
207  const Vec3f& center = Vec3f(0.0f),
208  float voxelSize = 0.1f,
209  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
210  InterruptT* interrupt = NULL)
211 {
212  return createLevelSetPlatonic<GridType>(8, scale, center, voxelSize, halfWidth, interrupt);
213 }
214 
224 template<typename GridType>
225 typename GridType::Ptr
227  const Vec3f& center = Vec3f(0.0f),
228  float voxelSize = 0.1f,
229  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
230 {
232  return createLevelSetPlatonic<GridType>(8, scale, center, voxelSize, halfWidth, &tmp);
233 }
234 
236 
247 template<typename GridType, typename InterruptT>
248 typename GridType::Ptr
250  const Vec3f& center = Vec3f(0.0f),
251  float voxelSize = 0.1f,
252  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
253  InterruptT* interrupt = NULL)
254 {
255  return createLevelSetPlatonic<GridType>(12, scale, center, voxelSize, halfWidth, interrupt);
256 }
257 
267 template<typename GridType>
268 typename GridType::Ptr
270  const Vec3f& center = Vec3f(0.0f),
271  float voxelSize = 0.1f,
272  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
273 {
275  return createLevelSetPlatonic<GridType>(12, scale, center, voxelSize, halfWidth, &tmp);
276 }
277 
279 
290 template<typename GridType, typename InterruptT>
291 typename GridType::Ptr
293  const Vec3f& center = Vec3f(0.0f),
294  float voxelSize = 0.1f,
295  float halfWidth = float(LEVEL_SET_HALF_WIDTH),
296  InterruptT* interrupt = NULL)
297 {
298  return createLevelSetPlatonic<GridType>(20, scale, center, voxelSize, halfWidth, interrupt);
299 }
300 
310 template<typename GridType>
311 typename GridType::Ptr
313  const Vec3f& center = Vec3f(0.0f),
314  float voxelSize = 0.1f,
315  float halfWidth = float(LEVEL_SET_HALF_WIDTH))
316 {
318  return createLevelSetPlatonic<GridType>(20, scale, center, voxelSize, halfWidth, &tmp);
319 }
320 
322 
323 template<typename GridType, typename InterruptT>
324 typename GridType::Ptr
325 createLevelSetPlatonic(int faceCount,float scale, const Vec3f& center,
326  float voxelSize, float halfWidth, InterruptT *interrupt)
327 {
328  // GridType::ValueType is required to be a floating-point scalar.
329  BOOST_STATIC_ASSERT(boost::is_floating_point<typename GridType::ValueType>::value);
330 
331  const math::Transform::Ptr xform = math::Transform::createLinearTransform( voxelSize );
332 
333  std::vector<Vec3f> vtx;
334  std::vector<Vec3I> tri;
335  std::vector<Vec4I> qua;
336 
337  if (faceCount == 4) {// Tetrahedron
338 
339  vtx.push_back( Vec3f( 0.0f, 1.0f, 0.0f) );
340  vtx.push_back( Vec3f(-0.942810297f, -0.333329707f, 0.0f) );
341  vtx.push_back( Vec3f( 0.471405149f, -0.333329707f, 0.816497624) );
342  vtx.push_back( Vec3f( 0.471405149f, -0.333329707f, -0.816497624f) );
343 
344  tri.push_back( Vec3I(0, 2, 3) );
345  tri.push_back( Vec3I(0, 3, 1) );
346  tri.push_back( Vec3I(0, 1, 2) );
347  tri.push_back( Vec3I(1, 3, 2) );
348 
349  } else if (faceCount == 6) {// Cube
350 
351  vtx.push_back( Vec3f(-0.5f, -0.5f, -0.5f) );
352  vtx.push_back( Vec3f( 0.5f, -0.5f, -0.5f) );
353  vtx.push_back( Vec3f( 0.5f, -0.5f, 0.5f) );
354  vtx.push_back( Vec3f(-0.5f, -0.5f, 0.5f) );
355  vtx.push_back( Vec3f(-0.5f, 0.5f, -0.5f) );
356  vtx.push_back( Vec3f( 0.5f, 0.5f, -0.5f) );
357  vtx.push_back( Vec3f( 0.5f, 0.5f, 0.5f) );
358  vtx.push_back( Vec3f(-0.5f, 0.5f, 0.5f) );
359 
360  qua.push_back( Vec4I(1, 0, 4, 5) );
361  qua.push_back( Vec4I(2, 1, 5, 6) );
362  qua.push_back( Vec4I(3, 2, 6, 7) );
363  qua.push_back( Vec4I(0, 3, 7, 4) );
364  qua.push_back( Vec4I(2, 3, 0, 1) );
365  qua.push_back( Vec4I(5, 4, 7, 6) );
366 
367  } else if (faceCount == 8) {// Octahedron
368 
369  vtx.push_back( Vec3f( 0.0f, 0.0f, -1.0f) );
370  vtx.push_back( Vec3f( 1.0f, 0.0f, 0.0f) );
371  vtx.push_back( Vec3f( 0.0f, 0.0f, 1.0f) );
372  vtx.push_back( Vec3f(-1.0f, 0.0f, 0.0f) );
373  vtx.push_back( Vec3f( 0.0f,-1.0f, 0.0f) );
374  vtx.push_back( Vec3f( 0.0f, 1.0f, 0.0f) );
375 
376  tri.push_back( Vec3I(0, 4, 3) );
377  tri.push_back( Vec3I(0, 1, 4) );
378  tri.push_back( Vec3I(1, 2, 4) );
379  tri.push_back( Vec3I(2, 3, 4) );
380  tri.push_back( Vec3I(0, 3, 5) );
381  tri.push_back( Vec3I(0, 5, 1) );
382  tri.push_back( Vec3I(1, 5, 2) );
383  tri.push_back( Vec3I(2, 5, 3) );
384 
385  } else if (faceCount == 12) {// Dodecahedron
386 
387  vtx.push_back( Vec3f( 0.354437858f, 0.487842113f, -0.789344311f) );
388  vtx.push_back( Vec3f( 0.573492587f, -0.186338872f, -0.78934437f) );
389  vtx.push_back( Vec3f( 0.0f, -0.603005826f, -0.78934443f) );
390  vtx.push_back( Vec3f(-0.573492587f, -0.186338872f, -0.78934437f) );
391  vtx.push_back( Vec3f(-0.354437858f, 0.487842113f, -0.789344311f) );
392  vtx.push_back( Vec3f(-0.573492587f, 0.789345026f, -0.186338797f) );
393  vtx.push_back( Vec3f(-0.927930415f, -0.301502913f, -0.186338872f) );
394  vtx.push_back( Vec3f( 0.0f, -0.975683928f, -0.186338902f) );
395  vtx.push_back( Vec3f( 0.927930415f, -0.301502913f, -0.186338872f) );
396  vtx.push_back( Vec3f( 0.573492587f, 0.789345026f, -0.186338797f) );
397  vtx.push_back( Vec3f( 0.0f, 0.975683868f, 0.186338902f) );
398  vtx.push_back( Vec3f(-0.927930415f, 0.301502913f, 0.186338872f) );
399  vtx.push_back( Vec3f(-0.573492587f, -0.789345026f, 0.186338797f) );
400  vtx.push_back( Vec3f( 0.573492587f, -0.789345026f, 0.186338797f) );
401  vtx.push_back( Vec3f( 0.927930415f, 0.301502913f, 0.186338872f) );
402  vtx.push_back( Vec3f( 0.0f, 0.603005826f, 0.78934443f) );
403  vtx.push_back( Vec3f( 0.573492587f, 0.186338872f, 0.78934437f) );
404  vtx.push_back( Vec3f( 0.354437858f, -0.487842113f, 0.789344311f) );
405  vtx.push_back( Vec3f(-0.354437858f, -0.487842113f, 0.789344311f) );
406  vtx.push_back( Vec3f(-0.573492587f, 0.186338872f, 0.78934437f) );
407 
408  qua.push_back( Vec4I(0, 1, 2, 3) );
409  tri.push_back( Vec3I(0, 3, 4) );
410  qua.push_back( Vec4I(0, 4, 5, 10) );
411  tri.push_back( Vec3I(0, 10, 9) );
412  qua.push_back( Vec4I(0, 9, 14, 8) );
413  tri.push_back( Vec3I(0, 8, 1) );
414  qua.push_back( Vec4I(1, 8, 13, 7) );
415  tri.push_back( Vec3I(1, 7, 2) );
416  qua.push_back( Vec4I(2, 7, 12, 6) );
417  tri.push_back( Vec3I(2, 6, 3) );
418  qua.push_back( Vec4I(3, 6, 11, 5) );
419  tri.push_back( Vec3I(3, 5, 4) );
420  qua.push_back( Vec4I(5, 11, 19, 15) );
421  tri.push_back( Vec3I(5, 15, 10) );
422  qua.push_back( Vec4I(6, 12, 18, 19) );
423  tri.push_back( Vec3I(6, 19, 11) );
424  qua.push_back( Vec4I(7, 13, 17, 18) );
425  tri.push_back( Vec3I(7, 18, 12) );
426  qua.push_back( Vec4I(8, 14, 16, 17) );
427  tri.push_back( Vec3I(8, 17, 13) );
428  qua.push_back( Vec4I(9, 10, 15, 16) );
429  tri.push_back( Vec3I(9, 16, 14) );
430  qua.push_back( Vec4I(15, 19, 18, 17) );
431  tri.push_back( Vec3I(15, 17, 16) );
432 
433  } else if (faceCount == 20) {// Icosahedron
434 
435  vtx.push_back( Vec3f(0.0f, 0.0f, -1.0f) );
436  vtx.push_back( Vec3f(0.0f, 0.894427359f, -0.447213143f) );
437  vtx.push_back( Vec3f(0.850650847f, 0.276393682f, -0.447213203f) );
438  vtx.push_back( Vec3f(0.525731206f, -0.723606944f, -0.447213262f) );
439  vtx.push_back( Vec3f(-0.525731206f, -0.723606944f, -0.447213262f) );
440  vtx.push_back( Vec3f(-0.850650847f, 0.276393682f, -0.447213203f) );
441  vtx.push_back( Vec3f(-0.525731206f, 0.723606944f, 0.447213262f) );
442  vtx.push_back( Vec3f(-0.850650847f, -0.276393682f, 0.447213203f) );
443  vtx.push_back( Vec3f(0.0f, -0.894427359f, 0.447213143f) );
444  vtx.push_back( Vec3f(0.850650847f, -0.276393682f, 0.447213203f) );
445  vtx.push_back( Vec3f(0.525731206f, 0.723606944f, 0.447213262f) );
446  vtx.push_back( Vec3f(0.0f, 0.0f, 1.0f) );
447 
448  tri.push_back( Vec3I( 2, 0, 1) );
449  tri.push_back( Vec3I( 3, 0, 2) );
450  tri.push_back( Vec3I( 4, 0, 3) );
451  tri.push_back( Vec3I( 5, 0, 4) );
452  tri.push_back( Vec3I( 1, 0, 5) );
453  tri.push_back( Vec3I( 6, 1, 5) );
454  tri.push_back( Vec3I( 7, 5, 4) );
455  tri.push_back( Vec3I( 8, 4, 3) );
456  tri.push_back( Vec3I( 9, 3, 2) );
457  tri.push_back( Vec3I(10, 2, 1) );
458  tri.push_back( Vec3I(10, 1, 6) );
459  tri.push_back( Vec3I( 6, 5, 7) );
460  tri.push_back( Vec3I( 7, 4, 8) );
461  tri.push_back( Vec3I( 8, 3, 9) );
462  tri.push_back( Vec3I( 9, 2, 10) );
463  tri.push_back( Vec3I( 6, 11, 10) );
464  tri.push_back( Vec3I(10, 11, 9) );
465  tri.push_back( Vec3I( 9, 11, 8) );
466  tri.push_back( Vec3I( 8, 11, 7) );
467  tri.push_back( Vec3I( 7, 11, 6) );
468 
469  } else {
470  OPENVDB_THROW(RuntimeError, "Invalid face count");
471  }
472 
473  // Apply scale and translation to all the vertices
474  for ( size_t i = 0; i<vtx.size(); ++i ) vtx[i] = scale * vtx[i] + center;
475 
476  typename GridType::Ptr grid;
477 
478  if (interrupt == NULL) {
480  grid = meshToLevelSet<GridType>(tmp, *xform, vtx, tri, qua, halfWidth);
481  } else {
482  grid = meshToLevelSet<GridType>(*interrupt, *xform, vtx, tri, qua, halfWidth);
483  }
484 
485  return grid;
486 }
487 
488 } // namespace tools
489 } // namespace OPENVDB_VERSION_NAME
490 } // namespace openvdb
491 
492 #endif // OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
493 
494 // Copyright (c) 2012-2016 DreamWorks Animation LLC
495 // All rights reserved. This software is distributed under the
496 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
math::Vec4< Index32 > Vec4I
Definition: Types.h:90
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
Definition: Mat.h:146
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:219
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:140
#define OPENVDB_VERSION_NAME
Definition: version.h:43
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:183
Definition: Exceptions.h:86
math::Vec3< Index32 > Vec3I
Definition: Types.h:77
Convert polygonal meshes that consist of quads and/or triangles into signed or unsigned distance fiel...
Definition: Exceptions.h:39
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:226
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:594
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:95
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:312
math::Vec3< float > Vec3f
Definition: Types.h:78
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
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:269
boost::shared_ptr< Transform > Ptr
Definition: Transform.h:69