OpenVDB: LevelSetPlatonic.h Source File

OpenVDB 5.2.0

LevelSetPlatonic.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 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 //
30
40
41 #ifndef OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
42 #define OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
43
44 #include <openvdb/Grid.h>
45 #include <openvdb/Types.h>
46 #include <openvdb/math/Math.h>
47 #include <openvdb/math/Transform.h>
48 #include <openvdb/tools/MeshToVolume.h>
49 #include <openvdb/util/NullInterrupter.h>
50 #include <type_traits>
51 #include <vector>
52
53
54 namespace openvdb {
55 OPENVDB_USE_VERSION_NAMESPACE
56 namespace OPENVDB_VERSION_NAME {
57 namespace tools {
58
72 template<typename GridType, typename InterruptT>
73 typename GridType::Ptr
74 createLevelSetPlatonic(
75 int faceCount, // 4, 6, 8, 12 or 20
76 float scale = 1.0f,
77 const Vec3f& center = Vec3f(0.0f),
78 float voxelSize = 0.1f,
79 float halfWidth = float(LEVEL_SET_HALF_WIDTH),
80 InterruptT* interrupt = nullptr);
81
94 template<typename GridType>
95 typename GridType::Ptr
96 createLevelSetPlatonic(
97 int faceCount,// 4, 6, 8, 12 or 20
98 float scale = 1.0f,
99 const Vec3f& center = Vec3f(0.0f),
100 float voxelSize = 0.1f,
101 float halfWidth = float(LEVEL_SET_HALF_WIDTH))
102 {
103 util::NullInterrupter tmp;
104 return createLevelSetPlatonic<GridType>(faceCount, scale, center, voxelSize, halfWidth, &tmp);
105 }
106
108
119 template<typename GridType, typename InterruptT>
120 typename GridType::Ptr
121 createLevelSetTetrahedron(
122 float scale = 1.0f,
123 const Vec3f& center = Vec3f(0.0f),
124 float voxelSize = 0.1f,
125 float halfWidth = float(LEVEL_SET_HALF_WIDTH),
126 InterruptT* interrupt = nullptr)
127 {
128 return createLevelSetPlatonic<GridType, InterruptT>(
129 4, scale, center, voxelSize, halfWidth, interrupt);
130 }
131
141 template<typename GridType>
142 typename GridType::Ptr
143 createLevelSetTetrahedron(
144 float scale = 1.0f,
145 const Vec3f& center = Vec3f(0.0f),
146 float voxelSize = 0.1f,
147 float halfWidth = float(LEVEL_SET_HALF_WIDTH))
148 {
149 util::NullInterrupter tmp;
150 return createLevelSetPlatonic<GridType>(4, scale, center, voxelSize, halfWidth, &tmp);
151 }
152
154
165 template<typename GridType, typename InterruptT>
166 typename GridType::Ptr
167 createLevelSetCube(
168 float scale = 1.0f,
169 const Vec3f& center = Vec3f(0.0f),
170 float voxelSize = 0.1f,
171 float halfWidth = float(LEVEL_SET_HALF_WIDTH),
172 InterruptT* interrupt = nullptr)
173 {
174 return createLevelSetPlatonic<GridType>(6, scale, center, voxelSize, halfWidth, interrupt);
175 }
176
186 template<typename GridType>
187 typename GridType::Ptr
188 createLevelSetCube(
189 float scale = 1.0f,
190 const Vec3f& center = Vec3f(0.0f),
191 float voxelSize = 0.1f,
192 float halfWidth = float(LEVEL_SET_HALF_WIDTH))
193 {
194 util::NullInterrupter tmp;
195 return createLevelSetPlatonic<GridType>(6, scale, center, voxelSize, halfWidth, &tmp);
196 }
197
199
210 template<typename GridType, typename InterruptT>
211 typename GridType::Ptr
212 createLevelSetOctahedron(
213 float scale = 1.0f,
214 const Vec3f& center = Vec3f(0.0f),
215 float voxelSize = 0.1f,
216 float halfWidth = float(LEVEL_SET_HALF_WIDTH),
217 InterruptT* interrupt = nullptr)
218 {
219 return createLevelSetPlatonic<GridType>(8, scale, center, voxelSize, halfWidth, interrupt);
220 }
221
231 template<typename GridType>
232 typename GridType::Ptr
233 createLevelSetOctahedron(
234 float scale = 1.0f,
235 const Vec3f& center = Vec3f(0.0f),
236 float voxelSize = 0.1f,
237 float halfWidth = float(LEVEL_SET_HALF_WIDTH))
238 {
239 util::NullInterrupter tmp;
240 return createLevelSetPlatonic<GridType>(8, scale, center, voxelSize, halfWidth, &tmp);
241 }
242
244
255 template<typename GridType, typename InterruptT>
256 typename GridType::Ptr
257 createLevelSetDodecahedron(
258 float scale = 1.0f,
259 const Vec3f& center = Vec3f(0.0f),
260 float voxelSize = 0.1f,
261 float halfWidth = float(LEVEL_SET_HALF_WIDTH),
262 InterruptT* interrupt = nullptr)
263 {
264 return createLevelSetPlatonic<GridType>(12, scale, center, voxelSize, halfWidth, interrupt);
265 }
266
276 template<typename GridType>
277 typename GridType::Ptr
278 createLevelSetDodecahedron(
279 float scale = 1.0f,
280 const Vec3f& center = Vec3f(0.0f),
281 float voxelSize = 0.1f,
282 float halfWidth = float(LEVEL_SET_HALF_WIDTH))
283 {
284 util::NullInterrupter tmp;
285 return createLevelSetPlatonic<GridType>(12, scale, center, voxelSize, halfWidth, &tmp);
286 }
287
289
300 template<typename GridType, typename InterruptT>
301 typename GridType::Ptr
302 createLevelSetIcosahedron(
303 float scale = 1.0f,
304 const Vec3f& center = Vec3f(0.0f),
305 float voxelSize = 0.1f,
306 float halfWidth = float(LEVEL_SET_HALF_WIDTH),
307 InterruptT* interrupt = nullptr)
308 {
309 return createLevelSetPlatonic<GridType>(20, scale, center, voxelSize, halfWidth, interrupt);
310 }
311
321 template<typename GridType>
322 typename GridType::Ptr
323 createLevelSetIcosahedron(
324 float scale = 1.0f,
325 const Vec3f& center = Vec3f(0.0f),
326 float voxelSize = 0.1f,
327 float halfWidth = float(LEVEL_SET_HALF_WIDTH))
328 {
329 util::NullInterrupter tmp;
330 return createLevelSetPlatonic<GridType>(20, scale, center, voxelSize, halfWidth, &tmp);
331 }
332
334
335 template<typename GridType, typename InterruptT>
336 typename GridType::Ptr
337 createLevelSetPlatonic(int faceCount,float scale, const Vec3f& center,
338 float voxelSize, float halfWidth, InterruptT *interrupt)
339 {
340 // GridType::ValueType is required to be a floating-point scalar.
341 static_assert(std::is_floating_point<typename GridType::ValueType>::value,
342 "level set grids must have scalar, floating-point value types");
343
344 const math::Transform::Ptr xform = math::Transform::createLinearTransform( voxelSize );
345
346 std::vector<Vec3f> vtx;
347 std::vector<Vec3I> tri;
348 std::vector<Vec4I> qua;
349
350 if (faceCount == 4) {// Tetrahedron
351
352 vtx.push_back( Vec3f( 0.0f, 1.0f, 0.0f) );
353 vtx.push_back( Vec3f(-0.942810297f, -0.333329707f, 0.0f) );
354 vtx.push_back( Vec3f( 0.471405149f, -0.333329707f, 0.816497624f) );
355 vtx.push_back( Vec3f( 0.471405149f, -0.333329707f, -0.816497624f) );
356
357 tri.push_back( Vec3I(0, 2, 3) );
358 tri.push_back( Vec3I(0, 3, 1) );
359 tri.push_back( Vec3I(0, 1, 2) );
360 tri.push_back( Vec3I(1, 3, 2) );
361
362 } else if (faceCount == 6) {// Cube
363
364 vtx.push_back( Vec3f(-0.5f, -0.5f, -0.5f) );
365 vtx.push_back( Vec3f( 0.5f, -0.5f, -0.5f) );
366 vtx.push_back( Vec3f( 0.5f, -0.5f, 0.5f) );
367 vtx.push_back( Vec3f(-0.5f, -0.5f, 0.5f) );
368 vtx.push_back( Vec3f(-0.5f, 0.5f, -0.5f) );
369 vtx.push_back( Vec3f( 0.5f, 0.5f, -0.5f) );
370 vtx.push_back( Vec3f( 0.5f, 0.5f, 0.5f) );
371 vtx.push_back( Vec3f(-0.5f, 0.5f, 0.5f) );
372
373 qua.push_back( Vec4I(1, 0, 4, 5) );
374 qua.push_back( Vec4I(2, 1, 5, 6) );
375 qua.push_back( Vec4I(3, 2, 6, 7) );
376 qua.push_back( Vec4I(0, 3, 7, 4) );
377 qua.push_back( Vec4I(2, 3, 0, 1) );
378 qua.push_back( Vec4I(5, 4, 7, 6) );
379
380 } else if (faceCount == 8) {// Octahedron
381
382 vtx.push_back( Vec3f( 0.0f, 0.0f, -1.0f) );
383 vtx.push_back( Vec3f( 1.0f, 0.0f, 0.0f) );
384 vtx.push_back( Vec3f( 0.0f, 0.0f, 1.0f) );
385 vtx.push_back( Vec3f(-1.0f, 0.0f, 0.0f) );
386 vtx.push_back( Vec3f( 0.0f,-1.0f, 0.0f) );
387 vtx.push_back( Vec3f( 0.0f, 1.0f, 0.0f) );
388
389 tri.push_back( Vec3I(0, 4, 3) );
390 tri.push_back( Vec3I(0, 1, 4) );
391 tri.push_back( Vec3I(1, 2, 4) );
392 tri.push_back( Vec3I(2, 3, 4) );
393 tri.push_back( Vec3I(0, 3, 5) );
394 tri.push_back( Vec3I(0, 5, 1) );
395 tri.push_back( Vec3I(1, 5, 2) );
396 tri.push_back( Vec3I(2, 5, 3) );
397
398 } else if (faceCount == 12) {// Dodecahedron
399
400 vtx.push_back( Vec3f( 0.354437858f, 0.487842113f, -0.789344311f) );
401 vtx.push_back( Vec3f( 0.573492587f, -0.186338872f, -0.78934437f) );
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.573492587f, 0.789345026f, -0.186338797f) );
406 vtx.push_back( Vec3f(-0.927930415f, -0.301502913f, -0.186338872f) );
407 vtx.push_back( Vec3f( 0.0f, -0.975683928f, -0.186338902f) );
408 vtx.push_back( Vec3f( 0.927930415f, -0.301502913f, -0.186338872f) );
409 vtx.push_back( Vec3f( 0.573492587f, 0.789345026f, -0.186338797f) );
410 vtx.push_back( Vec3f( 0.0f, 0.975683868f, 0.186338902f) );
411 vtx.push_back( Vec3f(-0.927930415f, 0.301502913f, 0.186338872f) );
412 vtx.push_back( Vec3f(-0.573492587f, -0.789345026f, 0.186338797f) );
413 vtx.push_back( Vec3f( 0.573492587f, -0.789345026f, 0.186338797f) );
414 vtx.push_back( Vec3f( 0.927930415f, 0.301502913f, 0.186338872f) );
415 vtx.push_back( Vec3f( 0.0f, 0.603005826f, 0.78934443f) );
416 vtx.push_back( Vec3f( 0.573492587f, 0.186338872f, 0.78934437f) );
417 vtx.push_back( Vec3f( 0.354437858f, -0.487842113f, 0.789344311f) );
418 vtx.push_back( Vec3f(-0.354437858f, -0.487842113f, 0.789344311f) );
419 vtx.push_back( Vec3f(-0.573492587f, 0.186338872f, 0.78934437f) );
420
421 qua.push_back( Vec4I(0, 1, 2, 3) );
422 tri.push_back( Vec3I(0, 3, 4) );
423 qua.push_back( Vec4I(0, 4, 5, 10) );
424 tri.push_back( Vec3I(0, 10, 9) );
425 qua.push_back( Vec4I(0, 9, 14, 8) );
426 tri.push_back( Vec3I(0, 8, 1) );
427 qua.push_back( Vec4I(1, 8, 13, 7) );
428 tri.push_back( Vec3I(1, 7, 2) );
429 qua.push_back( Vec4I(2, 7, 12, 6) );
430 tri.push_back( Vec3I(2, 6, 3) );
431 qua.push_back( Vec4I(3, 6, 11, 5) );
432 tri.push_back( Vec3I(3, 5, 4) );
433 qua.push_back( Vec4I(5, 11, 19, 15) );
434 tri.push_back( Vec3I(5, 15, 10) );
435 qua.push_back( Vec4I(6, 12, 18, 19) );
436 tri.push_back( Vec3I(6, 19, 11) );
437 qua.push_back( Vec4I(7, 13, 17, 18) );
438 tri.push_back( Vec3I(7, 18, 12) );
439 qua.push_back( Vec4I(8, 14, 16, 17) );
440 tri.push_back( Vec3I(8, 17, 13) );
441 qua.push_back( Vec4I(9, 10, 15, 16) );
442 tri.push_back( Vec3I(9, 16, 14) );
443 qua.push_back( Vec4I(15, 19, 18, 17) );
444 tri.push_back( Vec3I(15, 17, 16) );
445
446 } else if (faceCount == 20) {// Icosahedron
447
448 vtx.push_back( Vec3f(0.0f, 0.0f, -1.0f) );
449 vtx.push_back( Vec3f(0.0f, 0.894427359f, -0.447213143f) );
450 vtx.push_back( Vec3f(0.850650847f, 0.276393682f, -0.447213203f) );
451 vtx.push_back( Vec3f(0.525731206f, -0.723606944f, -0.447213262f) );
452 vtx.push_back( Vec3f(-0.525731206f, -0.723606944f, -0.447213262f) );
453 vtx.push_back( Vec3f(-0.850650847f, 0.276393682f, -0.447213203f) );
454 vtx.push_back( Vec3f(-0.525731206f, 0.723606944f, 0.447213262f) );
455 vtx.push_back( Vec3f(-0.850650847f, -0.276393682f, 0.447213203f) );
456 vtx.push_back( Vec3f(0.0f, -0.894427359f, 0.447213143f) );
457 vtx.push_back( Vec3f(0.850650847f, -0.276393682f, 0.447213203f) );
458 vtx.push_back( Vec3f(0.525731206f, 0.723606944f, 0.447213262f) );
459 vtx.push_back( Vec3f(0.0f, 0.0f, 1.0f) );
460
461 tri.push_back( Vec3I( 2, 0, 1) );
462 tri.push_back( Vec3I( 3, 0, 2) );
463 tri.push_back( Vec3I( 4, 0, 3) );
464 tri.push_back( Vec3I( 5, 0, 4) );
465 tri.push_back( Vec3I( 1, 0, 5) );
466 tri.push_back( Vec3I( 6, 1, 5) );
467 tri.push_back( Vec3I( 7, 5, 4) );
468 tri.push_back( Vec3I( 8, 4, 3) );
469 tri.push_back( Vec3I( 9, 3, 2) );
470 tri.push_back( Vec3I(10, 2, 1) );
471 tri.push_back( Vec3I(10, 1, 6) );
472 tri.push_back( Vec3I( 6, 5, 7) );
473 tri.push_back( Vec3I( 7, 4, 8) );
474 tri.push_back( Vec3I( 8, 3, 9) );
475 tri.push_back( Vec3I( 9, 2, 10) );
476 tri.push_back( Vec3I( 6, 11, 10) );
477 tri.push_back( Vec3I(10, 11, 9) );
478 tri.push_back( Vec3I( 9, 11, 8) );
479 tri.push_back( Vec3I( 8, 11, 7) );
480 tri.push_back( Vec3I( 7, 11, 6) );
481
482 } else {
483 OPENVDB_THROW(RuntimeError, "Invalid face count");
484 }
485
486 // Apply scale and translation to all the vertices
487 for ( size_t i = 0; i<vtx.size(); ++i ) vtx[i] = scale * vtx[i] + center;
488
489 typename GridType::Ptr grid;
490
491 if (interrupt == nullptr) {
492 util::NullInterrupter tmp;
493 grid = meshToLevelSet<GridType>(tmp, *xform, vtx, tri, qua, halfWidth);
494 } else {
495 grid = meshToLevelSet<GridType>(*interrupt, *xform, vtx, tri, qua, halfWidth);
496 }
497
498 return grid;
499 }
500
501 } // namespace tools
502 } // namespace OPENVDB_VERSION_NAME
503 } // namespace openvdb
504
505 #endif // OPENVDB_TOOLS_LEVELSETPLATONIC_HAS_BEEN_INCLUDED
506
507 // Copyright (c) 2012-2018 DreamWorks Animation LLC
508 // All rights reserved. This software is distributed under the
509 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v5_2::math::Vec3
Definition: Mat.h:197
Types.h
openvdb::v5_2::tools::createLevelSetCube
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:188
NullInterrupter.h
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v5_2::math::Transform::Ptr
SharedPtr< Transform > Ptr
Definition: Transform.h:69
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
openvdb::v5_2::Vec3f
math::Vec3< float > Vec3f
Definition: Types.h:81
Transform.h
openvdb::v5_2::LEVEL_SET_HALF_WIDTH
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:283
openvdb::v5_2::tools::createLevelSetDodecahedron
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:278
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
MeshToVolume.h
Convert polygonal meshes that consist of quads and/or triangles into signed or unsigned distance fiel...
openvdb::v5_2::math::scale
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:647
openvdb
Definition: Exceptions.h:40
openvdb::v5_2::RuntimeError
Definition: Exceptions.h:90
openvdb::v5_2::tools::createLevelSetIcosahedron
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:323
openvdb::v5_2::tools::createLevelSetPlatonic
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:96
openvdb::v5_2::Vec4I
math::Vec4< Index32 > Vec4I
Definition: Types.h:95
Grid.h
openvdb::v5_2::tools::createLevelSetTetrahedron
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:143
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
openvdb::v5_2::tools::createLevelSetOctahedron
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:233
openvdb::v5_2::util::NullInterrupter
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
openvdb::v5_2::Vec3I
math::Vec3< Index32 > Vec3I
Definition: Types.h:80