OpenVDB 13.1.0
Loading...
Searching...
No Matches
CreatePrimitives.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5 \file nanovdb/tools/CreatePrimitives.h
6
7 \author Ken Museth
8
9 \date June 26, 2020
10
11 \brief Generates volumetric primitives, e.g. sphere, torus etc, as NanoVDB grid.
12
13 \note This has no dependency on openvdb.
14*/
15
16#ifndef NANOVDB_TOOLS_PRIMITIVES_H_HAS_BEEN_INCLUDED
17#define NANOVDB_TOOLS_PRIMITIVES_H_HAS_BEEN_INCLUDED
18
19#define NANOVDB_PARALLEL_PRIMITIVES
20
21#include <nanovdb/NanoVDB.h>
23#include <nanovdb/util/ForEach.h>// for util::forEach and util::Range
24
25namespace nanovdb {
26
27namespace tools {// ===================================================
28
29/// @brief Returns a handle to a narrow-band level set of a sphere
30///
31/// @param radius Radius of sphere in world units
32/// @param center Center of sphere in world units
33/// @param voxelSize Size of a voxel in world units
34/// @param halfWidth Half-width of narrow band in voxel units
35/// @param origin Origin of grid in world units
36/// @param name Name of the grid
37/// @param sMode Mode of computation for the statistics.
38/// @param cMode Mode of computation for the checksum.
39/// @param buffer Buffer used for memory allocation by the handle
40///
41/// @details The @c BuildT template parameter must be one of the following:
42/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
43/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
44/// FpN overload also takes a @c tolerance argument that sets the
45/// global error tolerance.
46template<typename BuildT = float, typename BufferT = HostBuffer>
47typename util::enable_if<util::is_same<BuildT, float, double>::value, GridHandle<BufferT>>::type
48createLevelSetSphere(double radius = 100.0,
49 const Vec3d& center = Vec3d(0),
50 double voxelSize = 1.0,
51 double halfWidth = 3.0,
52 const Vec3d& origin = Vec3d(0),
53 const std::string& name = "sphere_ls",
56 const BufferT& buffer = BufferT());
57
58template<typename BuildT, typename BufferT = HostBuffer>
59typename util::enable_if<util::is_same<BuildT, Fp4, Fp8, Fp16>::value, GridHandle<BufferT>>::type
60createLevelSetSphere(double radius = 100.0,
61 const Vec3d& center = Vec3d(0),
62 double voxelSize = 1.0,
63 double halfWidth = 3.0,
64 const Vec3d& origin = Vec3d(0),
65 const std::string& name = "sphere_ls",
68 bool ditherOn = false,
69 const BufferT& buffer = BufferT());
70
71template<typename BuildT, typename BufferT = HostBuffer>
72typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
73createLevelSetSphere(double radius = 100.0,
74 const Vec3d& center = Vec3d(0),
75 double voxelSize = 1.0,
76 double halfWidth = 3.0,
77 const Vec3d& origin = Vec3d(0),
78 const std::string& name = "sphere_ls_FpN",
81 float tolerance = -1.0f,
82 bool ditherOn = false,
83 const BufferT& buffer = BufferT());
84
85//================================================================================================
86
87/// @brief Returns a handle to a sparse fog volume of a sphere such
88/// that the exterior is 0 and inactive, the interior is active
89/// with values varying smoothly from 0 at the surface of the
90/// sphere to 1 at the halfWidth and interior of the sphere.
91///
92/// @param radius Radius of sphere in world units
93/// @param center Center of sphere in world units
94/// @param voxelSize Size of a voxel in world units
95/// @param halfWidth Half-width of narrow band in voxel units
96/// @param origin Origin of grid in world units
97/// @param name Name of the grid
98/// @param sMode Mode of computation for the statistics.
99/// @param cMode Mode of computation for the checksum.
100/// @param buffer Buffer used for memory allocation by the handle
101///
102/// @details The @c BuildT template parameter must be one of the following:
103/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
104/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
105/// FpN overload also takes a @c tolerance argument that sets the
106/// global error tolerance.
107template<typename BuildT = float, typename BufferT = HostBuffer>
108typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
109createFogVolumeSphere(double radius = 100.0,
110 const Vec3d& center = Vec3d(0.0),
111 double voxelSize = 1.0,
112 double halfWidth = 3.0,
113 const Vec3d& origin = Vec3d(0.0),
114 const std::string& name = "sphere_fog",
117 const BufferT& buffer = BufferT());
118
119template<typename BuildT, typename BufferT = HostBuffer>
120typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
121createFogVolumeSphere(double radius = 100.0,
122 const Vec3d& center = Vec3d(0.0),
123 double voxelSize = 1.0,
124 double halfWidth = 3.0,
125 const Vec3d& origin = Vec3d(0.0),
126 const std::string& name = "sphere_fog",
129 float tolerance = -1.0f,
130 bool ditherOn = false,
131 const BufferT& buffer = BufferT());
132
133//================================================================================================
134
135/// @brief Returns a handle to a PointDataGrid containing points scattered
136/// on the surface of a sphere.
137///
138/// @param pointsPerVoxel Number of point per voxel on on the surface
139/// @param radius Radius of sphere in world units
140/// @param center Center of sphere in world units
141/// @param voxelSize Size of a voxel in world units
142/// @param origin Origin of grid in world units
143/// @param name Name of the grid
144/// @param mode Mode of computation for the checksum.
145/// @param buffer Buffer used for memory allocation by the handle
146///
147/// @details The @c BuildT template parameter must be float (default) or double.
148template<typename BuildT = float, typename BufferT = HostBuffer>
149typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
150createPointSphere(int pointsPerVoxel = 1,
151 double radius = 100.0,
152 const Vec3d& center = Vec3d(0.0),
153 double voxelSize = 1.0,
154 const Vec3d& origin = Vec3d(0.0),
155 const std::string& name = "sphere_points",
157 const BufferT& buffer = BufferT());
158
159//================================================================================================
160
161/// @brief Returns a handle to a narrow-band level set of a torus in the xz-plane
162///
163/// @param majorRadius Major radius of torus in world units
164/// @param minorRadius Minor radius of torus in world units
165/// @param center Center of torus in world units
166/// @param voxelSize Size of a voxel in world units
167/// @param halfWidth Half-width of narrow band in voxel units
168/// @param origin Origin of grid in world units
169/// @param name Name of the grid
170/// @param sMode Mode of computation for the statistics.
171/// @param cMode Mode of computation for the checksum.
172/// @param buffer Buffer used for memory allocation by the handle
173///
174/// @details The @c BuildT template parameter must be one of the following:
175/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
176/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
177/// FpN overload also takes a @c tolerance argument that sets the
178/// global error tolerance.
179template<typename BuildT = float, typename BufferT = HostBuffer>
180typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
181createLevelSetTorus(double majorRadius = 100.0,
182 double minorRadius = 50.0,
183 const Vec3d& center = Vec3d(0.0),
184 double voxelSize = 1.0,
185 double halfWidth = 3.0,
186 const Vec3d& origin = Vec3d(0.0),
187 const std::string& name = "torus_ls",
190 const BufferT& buffer = BufferT());
191
192template<typename BuildT, typename BufferT = HostBuffer>
193typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
194createLevelSetTorus(double majorRadius = 100.0,
195 double minorRadius = 50.0,
196 const Vec3d& center = Vec3d(0.0),
197 double voxelSize = 1.0,
198 double halfWidth = 3.0,
199 const Vec3d& origin = Vec3d(0.0),
200 const std::string& name = "torus_ls",
203 float tolerance = -1.0f,
204 bool ditherOn = false,
205 const BufferT& buffer = BufferT());
206
207//================================================================================================
208
209/// @brief Returns a handle to a sparse fog volume of a torus in the xz-plane such
210/// that the exterior is 0 and inactive, the interior is active
211/// with values varying smoothly from 0 at the surface of the
212/// torus to 1 at the halfWidth and interior of the torus.
213///
214/// @param majorRadius Major radius of torus in world units
215/// @param minorRadius Minor radius of torus in world units
216/// @param center Center of torus in world units
217/// @param voxelSize Size of a voxel in world units
218/// @param halfWidth Half-width of narrow band in voxel units
219/// @param origin Origin of grid in world units
220/// @param name Name of the grid
221/// @param sMode Mode of computation for the statistics.
222/// @param cMode Mode of computation for the checksum.
223/// @param buffer Buffer used for memory allocation by the handle
224///
225/// @details The @c BuildT template parameter must be one of the following:
226/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
227/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
228/// FpN overload also takes a @c tolerance argument that sets the
229/// global error tolerance.
230template<typename BuildT = float, typename BufferT = HostBuffer>
231typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
232createFogVolumeTorus(double majorRadius = 100.0,
233 double minorRadius = 50.0,
234 const Vec3d& center = Vec3d(0.0),
235 double voxelSize = 1.0,
236 double halfWidth = 3.0,
237 const Vec3d& origin = Vec3d(0.0),
238 const std::string& name = "torus_fog",
241 const BufferT& buffer = BufferT());
242
243template<typename BuildT, typename BufferT = HostBuffer>
244typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
245createFogVolumeTorus(double majorRadius = 100.0,
246 double minorRadius = 50.0,
247 const Vec3d& center = Vec3d(0.0),
248 double voxelSize = 1.0,
249 double halfWidth = 3.0,
250 const Vec3d& origin = Vec3d(0.0),
251 const std::string& name = "torus_fog_FpN",
254 float tolerance = -1.0f,
255 bool ditherOn = false,
256 const BufferT& buffer = BufferT());
257
258//================================================================================================
259
260/// @brief Returns a handle to a PointDataGrid containing points scattered
261/// on the surface of a torus.
262///
263/// @param pointsPerVoxel Number of point per voxel on on the surface
264/// @param majorRadius Major radius of torus in world units
265/// @param minorRadius Minor radius of torus in world units
266/// @param center Center of torus in world units
267/// @param voxelSize Size of a voxel in world units
268/// @param origin Origin of grid in world units
269/// @param name Name of the grid
270/// @param cMode Mode of computation for the checksum.
271/// @param buffer Buffer used for memory allocation by the handle
272//
273/// @details The @c BuildT template parameter must be float (default) or double.
274template<typename BuildT = float, typename BufferT = HostBuffer>
275typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
276createPointTorus(int pointsPerVoxel = 1, // half-width of narrow band in voxel units
277 double majorRadius = 100.0, // major radius of torus in world units
278 double minorRadius = 50.0, // minor radius of torus in world units
279 const Vec3d& center = Vec3d(0.0), // center of torus in world units
280 double voxelSize = 1.0, // size of a voxel in world units
281 const Vec3d& origin = Vec3d(0.0f), // origin of grid in world units
282 const std::string& name = "torus_points", // name of grid
284 const BufferT& buffer = BufferT());
285
286//================================================================================================
287
288/// @brief Returns a handle to a narrow-band level set of a box
289///
290/// @param width Width of box in world units
291/// @param height Height of box in world units
292/// @param depth Depth of box in world units
293/// @param center Center of box in world units
294/// @param voxelSize Size of a voxel in world units
295/// @param halfWidth Half-width of narrow band in voxel units
296/// @param origin Origin of grid in world units
297/// @param name Name of the grid
298/// @param sMode Mode of computation for the statistics.
299/// @param cMode Mode of computation for the checksum.
300/// @param buffer Buffer used for memory allocation by the handle
301///
302/// @details The @c BuildT template parameter must be one of the following:
303/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
304/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
305/// FpN overload also takes a @c tolerance argument that sets the
306/// global error tolerance.
307template<typename BuildT = float, typename BufferT = HostBuffer>
308typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
309createLevelSetBox(double width = 40.0,
310 double height = 60.0,
311 double depth = 100.0,
312 const Vec3d& center = Vec3d(0.0),
313 double voxelSize = 1.0,
314 double halfWidth = 3.0,
315 const Vec3d& origin = Vec3d(0.0),
316 const std::string& name = "box_ls",
319 const BufferT& buffer = BufferT());
320
321template<typename BuildT, typename BufferT = HostBuffer>
322typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
323createLevelSetBox(double width = 40.0,
324 double height = 60.0,
325 double depth = 100.0,
326 const Vec3d& center = Vec3d(0.0),
327 double voxelSize = 1.0,
328 double halfWidth = 3.0,
329 const Vec3d& origin = Vec3d(0.0),
330 const std::string& name = "box_ls_FpN",
333 float tolerance = -1.0f,
334 bool ditherOn = false,
335 const BufferT& buffer = BufferT());
336
337//================================================================================================
338
339/// @brief Returns a handle to a sparse fog volume of a box such
340/// that the exterior is 0 and inactive, the interior is active
341/// with values varying smoothly from 0 at the surface of the
342/// box to 1 at the halfWidth and interior of the box.
343///
344/// @param width Width of box in world units
345/// @param height Height of box in world units
346/// @param depth Depth of box in world units
347/// @param center Center of box in world units
348/// @param voxelSize Size of a voxel in world units
349/// @param halfWidth Half-width of narrow band in voxel units
350/// @param origin Origin of grid in world units
351/// @param name Name of the grid
352/// @param sMode Mode of computation for the statistics.
353/// @param cMode Mode of computation for the checksum.
354/// @param buffer Buffer used for memory allocation by the handle
355///
356/// @details The @c BuildT template parameter must be one of the following:
357/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
358/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
359/// FpN overload also takes a @c tolerance argument that sets the
360/// global error tolerance.
361template<typename BuildT = float, typename BufferT = HostBuffer>
362typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
363createFogVolumeBox(double width = 40.0,
364 double height = 60.0,
365 double depth = 100.0,
366 const Vec3d& center = Vec3d(0.0),
367 double voxelSize = 1.0,
368 double halfWidth = 3.0,
369 const Vec3d& origin = Vec3d(0.0),
370 const std::string& name = "box_fog",
373 const BufferT& buffer = BufferT());
374
375template<typename BuildT, typename BufferT = HostBuffer>
376typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
377createFogVolumeBox(double width = 40.0,
378 double height = 60.0,
379 double depth = 100.0,
380 const Vec3d& center = Vec3d(0.0),
381 double voxelSize = 1.0,
382 double halfWidth = 3.0,
383 const Vec3d& origin = Vec3d(0.0),
384 const std::string& name = "box_fog_FpN",
387 float tolerance = -1.0f,
388 bool ditherOn = false,
389 const BufferT& buffer = BufferT());
390
391//================================================================================================
392
393/// @brief Returns a handle to a narrow-band level set of a octahedron
394///
395/// @param scale Scale of octahedron in world units
396/// @param center Center of octahedron in world units
397/// @param voxelSize Size of a voxel in world units
398/// @param halfWidth Half-width of narrow band in voxel units
399/// @param origin Origin of grid in world units
400/// @param name Name of the grid
401/// @param sMode Mode of computation for the statistics.
402/// @param cMode Mode of computation for the checksum.
403/// @param buffer Buffer used for memory allocation by the handle
404///
405/// @details The @c BuildT template parameter must be one of the following:
406/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
407/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
408/// FpN overload also takes a @c tolerance argument that sets the
409/// global error tolerance.
410template<typename BuildT = float, typename BufferT = HostBuffer>
411typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
412createLevelSetOctahedron(double scale = 100.0,
413 const Vec3d& center = Vec3d(0.0),
414 double voxelSize = 1.0,
415 double halfWidth = 3.0,
416 const Vec3d& origin = Vec3d(0.0),
417 const std::string& name = "octadedron_ls",
420 const BufferT& buffer = BufferT());
421
422template<typename BuildT, typename BufferT = HostBuffer>
423typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
424createLevelSetOctahedron(double scale = 100.0,
425 const Vec3d& center = Vec3d(0.0),
426 double voxelSize = 1.0,
427 double halfWidth = 3.0,
428 const Vec3d& origin = Vec3d(0.0),
429 const std::string& name = "octadedron_ls_FpN",
432 float tolerance = -1.0f,
433 bool ditherOn = false,
434 const BufferT& buffer = BufferT());
435
436//================================================================================================
437
438/// @brief Returns a handle to a sparse fog volume of an octahedron such
439/// that the exterior is 0 and inactive, the interior is active
440/// with values varying smoothly from 0 at the surface of the
441/// octahedron to 1 at the halfWidth and interior of the octahedron.
442///
443/// @param scale Scale of octahedron in world units
444/// @param center Center of box in world units
445/// @param voxelSize Size of a voxel in world units
446/// @param halfWidth Half-width of narrow band in voxel units
447/// @param origin Origin of grid in world units
448/// @param name Name of the grid
449/// @param sMode Mode of computation for the statistics.
450/// @param cMode Mode of computation for the checksum.
451/// @param buffer Buffer used for memory allocation by the handle
452///
453/// @details The @c BuildT template parameter must be one of the following:
454/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
455/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
456/// FpN overload also takes a @c tolerance argument that sets the
457/// global error tolerance.
458template<typename BuildT = float, typename BufferT = HostBuffer>
459typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
460createFogVolumeOctahedron(double scale = 100.0,
461 const Vec3d& center = Vec3d(0.0),
462 double voxelSize = 1.0,
463 double halfWidth = 3.0,
464 const Vec3d& origin = Vec3d(0.0),
465 const std::string& name = "octadedron_fog",
468 const BufferT& buffer = BufferT());
469
470template<typename BuildT, typename BufferT = HostBuffer>
471typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
472createFogVolumeOctahedron(double scale = 100.0,
473 const Vec3d& center = Vec3d(0.0),
474 double voxelSize = 1.0,
475 double halfWidth = 3.0,
476 const Vec3d& origin = Vec3d(0.0),
477 const std::string& name = "octadedron_fog_FpN",
480 float tolerance = -1.0f,
481 bool ditherOn = false,
482 const BufferT& buffer = BufferT());
483
484//================================================================================================
485
486/// @brief Returns a handle to a narrow-band level set of a bounding-box (= wireframe of a box)
487///
488/// @param width Width of box in world units
489/// @param height Height of box in world units
490/// @param depth Depth of box in world units
491/// @param thickness Thickness of the wire in world units
492/// @param center Center of bbox in world units
493/// @param voxelSize Size of a voxel in world units
494/// @param halfWidth Half-width of narrow band in voxel units
495/// @param origin Origin of grid in world units
496/// @param name Name of the grid
497/// @param sMode Mode of computation for the statistics.
498/// @param cMode Mode of computation for the checksum.
499/// @param buffer Buffer used for memory allocation by the handle
500///
501/// @details The @c BuildT template parameter must be one of the following:
502/// float (default), double, Fp4, Fp8, Fp16 or FpN. The Fp4, Fp8,
503/// Fp16 and FpN overloads take an extra @c ditherOn argument, and the
504/// FpN overload also takes a @c tolerance argument that sets the
505/// global error tolerance.
506template<typename BuildT = float, typename BufferT = HostBuffer>
507typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
508createLevelSetBBox(double width = 40.0,
509 double height = 60.0,
510 double depth = 100.0,
511 double thickness = 10.0,
512 const Vec3d& center = Vec3d(0.0),
513 double voxelSize = 1.0,
514 double halfWidth = 3.0,
515 const Vec3d& origin = Vec3d(0.0),
516 const std::string& name = "bbox_ls",
519 const BufferT& buffer = BufferT());
520
521template<typename BuildT, typename BufferT = HostBuffer>
522typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
523createLevelSetBBox(double width = 40.0,
524 double height = 60.0,
525 double depth = 100.0,
526 double thickness = 10.0,
527 const Vec3d& center = Vec3d(0.0),
528 double voxelSize = 1.0,
529 double halfWidth = 3.0,
530 const Vec3d& origin = Vec3d(0.0),
531 const std::string& name = "bbox_ls_FpN",
534 float tolerance = -1.0f,
535 bool ditherOn = false,
536 const BufferT& buffer = BufferT());
537
538
539//================================================================================================
540
541/// @brief Returns a handle to a PointDataGrid containing points scattered
542/// on the surface of a box.
543///
544/// @param pointsPerVoxel Number of point per voxel on on the surface
545/// @param width Width of box in world units
546/// @param height Height of box in world units
547/// @param depth Depth of box in world units
548/// @param center Center of box in world units
549/// @param voxelSize Size of a voxel in world units
550/// @param origin Origin of grid in world units
551/// @param name Name of the grid
552/// @param mode Mode of computation for the checksum.
553/// @param buffer Buffer used for memory allocation by the handle
554template<typename BuildT = float, typename BufferT = HostBuffer>
555typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
556createPointBox(int pointsPerVoxel = 1, // half-width of narrow band in voxel units
557 double width = 40.0, // width of box in world units
558 double height = 60.0, // height of box in world units
559 double depth = 100.0, // depth of box in world units
560 const Vec3d& center = Vec3d(0.0), // center of box in world units
561 double voxelSize = 1.0, // size of a voxel in world units
562 const Vec3d& origin = Vec3d(0.0), // origin of grid in world units
563 const std::string& name = "box_points", // name of grid
565 const BufferT& buffer = BufferT());
566
567//================================================================================================
568
569/// @brief Given an input NanoVDB voxel grid this methods returns a GridHandle to another NanoVDB
570/// PointDataGrid with points scattered in the active leaf voxels of in input grid. Note, the
571/// coordinates of the points are encoded as blind data in world-space.
572///
573/// @param srcGrid Const input grid used to determine the active voxels to scatter points into
574/// @param pointsPerVoxel Number of point per voxel on on the surface
575/// @param name Name of the grid
576/// @param mode Mode of computation for the checksum.
577/// @param buffer Buffer used for memory allocation by the handle
578template<typename SrcBuildT = float, typename BufferT = HostBuffer>
579inline GridHandle<BufferT>
580createPointScatter(const NanoGrid<SrcBuildT>& srcGrid, // source grid used to scatter points into
581 int pointsPerVoxel = 1, // half-width of narrow band in voxel units
582 const std::string& name = "point_scatter", // name of grid
584 const BufferT& buffer = BufferT());
585
586//================================================================================================
587
588namespace {
589
590/// @brief Returns a shared pointer to a build::Grid containing a narrow-band SDF values for a sphere
591///
592/// @brief Note, this is not (yet) a valid level set SDF field since values inside sphere (and outside
593/// the narrow band) are still undefined. Call builder::sdfToLevelSet() to set those
594/// values or alternatively call builder::levelSetToFog to generate a FOG volume.
595///
596/// @details The @c BuildT template parameter must be one of the following:
597/// float (default), double, Fp4, Fp8, Fp16 or FpN.
598template<typename BuildT>
599std::shared_ptr<build::Grid<BuildT>>
600initSphere(double radius, // radius of sphere in world units
601 const Vec3d& center, // center of sphere in world units
602 double voxelSize, // size of a voxel in world units
603 double halfWidth, // half-width of narrow band in voxel units
604 const Vec3d& origin) // origin of grid in world units
605{
606 using GridT = build::Grid<BuildT>;
607 using ValueT = typename BuildToValueMap<BuildT>::type;
608 static_assert(util::is_floating_point<ValueT>::value, "initSphere: expect floating point");
609 if (!(radius > 0))
610 throw std::runtime_error("Sphere: radius must be positive!");
611 if (!(voxelSize > 0))
612 throw std::runtime_error("Sphere: voxelSize must be positive!");
613 if (!(halfWidth > 0))
614 throw std::runtime_error("Sphere: halfWidth must be positive!");
615
616 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
617 grid->setTransform(voxelSize, origin);
618
619 // Define radius of sphere with narrow-band in voxel units
620 const ValueT r0 = ValueT(radius / voxelSize), rmax = r0 + ValueT(halfWidth);
621
622 // Radius below the Nyquist frequency
623 if (r0 < ValueT(1.5f)) return grid;
624
625 // Define center of sphere in voxel units
626 const math::Vec3<ValueT> c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
627 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
628 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
629
630 // Define bounds of the voxel coordinates
631 const int imin = math::Floor(c[0] - rmax), imax = math::Ceil(c[0] + rmax);
632 const int jmin = math::Floor(c[1] - rmax), jmax = math::Ceil(c[1] + rmax);
633 const int kmin = math::Floor(c[2] - rmax), kmax = math::Ceil(c[2] + rmax);
634
635 const util::Range<1,int> range(imin, imax+1, 32);
636
637 auto kernel = [&](const util::Range<1,int> &r) {
638 auto acc = grid->getWriteAccessor();
639 Coord ijk;
640 int &i = ijk[0], &j = ijk[1], &k = ijk[2], m = 1;
641 // Compute signed distances to sphere using leapfrogging in k
642 for (i = r.begin(); i < r.end(); ++i) {
643 const auto x2 = math::Pow2(ValueT(i) - c[0]);
644 for (j = jmin; j <= jmax; ++j) {
645 const auto x2y2 = math::Pow2(ValueT(j) - c[1]) + x2;
646 for (k = kmin; k <= kmax; k += m) {
647 m = 1;
648 const auto v = math::Sqrt(x2y2 + math::Pow2(ValueT(k) - c[2])) - r0; // Distance in voxel units
649 const auto d = v < 0 ? -v : v;
650 if (d < halfWidth) { // inside narrow band
651 acc.setValue(ijk, ValueT(voxelSize) * v); // distance in world units
652 } else { // outside narrow band
653 m += math::Floor(d - halfWidth); // leapfrog
654 }
655 } //end leapfrog over k
656 } //end loop over j
657 } //end loop over i
658 };// kernel
659#ifdef NANOVDB_PARALLEL_PRIMITIVES
660 util::forEach(range, kernel);
661#else
662 kernel(range);
663#endif
664 return grid;
665} // initSphere
666
667template<typename BuildT>
668std::shared_ptr<build::Grid<BuildT>>
669initTorus(double radius1, // major radius of torus in world units
670 double radius2, // minor radius of torus in world units
671 const Vec3d& center, // center of torus in world units
672 double voxelSize, // size of a voxel in world units
673 double halfWidth, // half-width of narrow band in voxel units
674 const Vec3d& origin) // origin of grid in world units
675{
676 using GridT = build::Grid<BuildT>;
677 using ValueT = typename BuildToValueMap<BuildT>::type;
678 static_assert(util::is_floating_point<ValueT>::value, "initTorus: expect floating point");
679 if (!(radius2 > 0))
680 throw std::runtime_error("Torus: radius2 must be positive!");
681 if (!(radius1 > radius2))
682 throw std::runtime_error("Torus: radius1 must be larger than radius2!");
683 if (!(voxelSize > 0))
684 throw std::runtime_error("Torus: voxelSize must be positive!");
685 if (!(halfWidth > 0))
686 throw std::runtime_error("Torus: halfWidth must be positive!");
687
688 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
689 grid->setTransform(voxelSize, origin);
690
691 // Define size of torus with narrow-band in voxel units
692 const ValueT r1 = ValueT(radius1 / voxelSize), r2 = ValueT(radius2 / voxelSize), rmax1 = r1 + r2 + ValueT(halfWidth), rmax2 = r2 + ValueT(halfWidth);
693
694 // Radius below the Nyquist frequency
695 if (r2 < ValueT(1.5)) return grid;
696
697 // Define center of torus in voxel units
698 const math::Vec3<ValueT> c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
699 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
700 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
701
702 // Define bounds of the voxel coordinates
703 const int imin = math::Floor(c[0] - rmax1), imax = math::Ceil(c[0] + rmax1);
704 const int jmin = math::Floor(c[1] - rmax2), jmax = math::Ceil(c[1] + rmax2);
705 const int kmin = math::Floor(c[2] - rmax1), kmax = math::Ceil(c[2] + rmax1);
706
707 const util::Range<1,int> range(imin, imax+1, 32);
708 auto kernel = [&](const util::Range<1,int> &r) {
709 auto acc = grid->getWriteAccessor();
710 Coord ijk;
711 int &i = ijk[0], &j = ijk[1], &k = ijk[2], m = 1;
712 // Compute signed distances to torus using leapfrogging in k
713 for (i = r.begin(); i < r.end(); ++i) {
714 const auto x2 = math::Pow2(ValueT(i) - c[0]);
715 for (k = kmin; k <= kmax; ++k) {
716 const auto x2z2 = math::Pow2(math::Sqrt(math::Pow2(ValueT(k) - c[2]) + x2) - r1);
717 for (j = jmin; j <= jmax; j += m) {
718 m = 1;
719 const auto v = math::Sqrt(x2z2 + math::Pow2(ValueT(j) - c[1])) - r2; // Distance in voxel units
720 const auto d = v < 0 ? -v : v;
721 if (d < halfWidth) { // inside narrow band
722 acc.setValue(ijk, ValueT(voxelSize) * v); // distance in world units
723 } else { // outside narrow band
724 m += math::Floor(d - halfWidth); // leapfrog
725 }
726 } //end leapfrog over k
727 } //end loop over j
728 } //end loop over i
729 }; // kernel
730
731#ifdef NANOVDB_PARALLEL_PRIMITIVES
732 util::forEach(range, kernel);
733#else
734 kernel(range);
735#endif
736
737 return grid;
738} // initTorus
739
740template<typename BuildT>
741std::shared_ptr<build::Grid<BuildT>>
742initBox(double width, // major radius of torus in world units
743 double height, // minor radius of torus in world units
744 double depth,
745 const Vec3d& center, // center of box in world units
746 double voxelSize, // size of a voxel in world units
747 double halfWidth, // half-width of narrow band in voxel units
748 const Vec3d& origin) // origin of grid in world units
749{
750 using GridT = build::Grid<BuildT>;
751 using ValueT = typename BuildToValueMap<BuildT>::type;
752 static_assert(util::is_floating_point<ValueT>::value, "initBox: expect floating point");
753 using Vec3T = math::Vec3<ValueT>;
754 if (!(width > 0))
755 throw std::runtime_error("Box: width must be positive!");
756 if (!(height > 0))
757 throw std::runtime_error("Box: height must be positive!");
758 if (!(depth > 0))
759 throw std::runtime_error("Box: depth must be positive!");
760
761 if (!(voxelSize > 0))
762 throw std::runtime_error("Box: voxelSize must be positive!");
763 if (!(halfWidth > 0))
764 throw std::runtime_error("Box: halfWidth must be positive!");
765
766 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
767 grid->setTransform(voxelSize, origin);
768
769 // Define size of box with narrow-band in voxel units
770 const Vec3T r(width / (2 * ValueT(voxelSize)),
771 height / (2 * ValueT(voxelSize)),
772 depth / (2 * ValueT(voxelSize)));
773
774 // Below the Nyquist frequency
775 if (r.min() < ValueT(1.5)) return grid;
776
777 // Define center of box in voxel units
778 const Vec3T c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
779 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
780 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
781
782 // Define utility functions
783 auto Pos = [](ValueT x) { return x > 0 ? x : 0; };
784 auto Neg = [](ValueT x) { return x < 0 ? x : 0; };
785
786 // Define bounds of the voxel coordinates
787 const math::BBox<Vec3T> b(c - r - Vec3T(ValueT(halfWidth)), c + r + Vec3T(ValueT(halfWidth)));
788 const CoordBBox bbox(Coord(math::Floor(b[0][0]), math::Floor(b[0][1]), math::Floor(b[0][2])),
789 Coord(math::Ceil(b[1][0]), math::Ceil(b[1][1]), math::Ceil(b[1][2])));
790 const util::Range<1,int> range(bbox[0][0], bbox[1][0]+1, 32);
791
792 // Compute signed distances to box using leapfrogging in k
793 auto kernel = [&](const util::Range<1,int> &ra) {
794 auto acc = grid->getWriteAccessor();
795 int m = 1;
796 for (Coord p(ra.begin(),bbox[0][1],bbox[0][2]); p[0] < ra.end(); ++p[0]) {
797 const auto q1 = math::Abs(ValueT(p[0]) - c[0]) - r[0];
798 const auto x2 = math::Pow2(Pos(q1));
799 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
800 const auto q2 = math::Abs(ValueT(p[1]) - c[1]) - r[1];
801 const auto q0 = math::Max(q1, q2);
802 const auto x2y2 = x2 + math::Pow2(Pos(q2));
803 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
804 m = 1;
805 const auto q3 = math::Abs(ValueT(p[2]) - c[2]) - r[2];
806 const auto v = math::Sqrt(x2y2 + math::Pow2(Pos(q3))) + Neg(math::Max(q0, q3)); // Distance in voxel units
807 const auto d = math::Abs(v);
808 if (d < halfWidth) { // inside narrow band
809 acc.setValue(p, ValueT(voxelSize) * v); // distance in world units
810 } else { // outside narrow band
811 m += math::Floor(d - halfWidth); // leapfrog
812 }
813 } //end leapfrog over k
814 } //end loop over j
815 } //end loop over i
816 }; // kernel
817#ifdef NANOVDB_PARALLEL_PRIMITIVES
818 util::forEach(range, kernel);
819#else
820 kernel(range);
821#endif
822 return grid;
823} // initBox
824
825template<typename BuildT>
826std::shared_ptr<build::Grid<BuildT>>
827initBBox(double width, // width of the bbox in world units
828 double height, // height of the bbox in world units
829 double depth, // depth of the bbox in world units
830 double thickness, // thickness of the wire in world units
831 const Vec3d& center, // center of bbox in world units
832 double voxelSize, // size of a voxel in world units
833 double halfWidth, // half-width of narrow band in voxel units
834 const Vec3d& origin) // origin of grid in world units
835{
836 using GridT = build::Grid<BuildT>;
837 using ValueT = typename BuildToValueMap<BuildT>::type;
838 static_assert(util::is_floating_point<ValueT>::value, "initBBox: expect floating point");
839 using Vec3T = math::Vec3<ValueT>;
840 if (!(width > 0))
841 throw std::runtime_error("BBox: width must be positive!");
842 if (!(height > 0))
843 throw std::runtime_error("BBox: height must be positive!");
844 if (!(depth > 0))
845 throw std::runtime_error("BBox: depth must be positive!");
846 if (!(thickness > 0))
847 throw std::runtime_error("BBox: thickness must be positive!");
848 if (!(voxelSize > 0.0))
849 throw std::runtime_error("BBox: voxelSize must be positive!");
850
851
852 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
853 grid->setTransform(voxelSize, origin);
854
855 // Define size of bbox with narrow-band in voxel units
856 const Vec3T r(width / (2 * ValueT(voxelSize)),
857 height / (2 * ValueT(voxelSize)),
858 depth / (2 * ValueT(voxelSize)));
859 const ValueT e = thickness / ValueT(voxelSize);
860
861 // Below the Nyquist frequency
862 if (r.min() < ValueT(1.5) || e < ValueT(1.5)) return grid;
863
864 // Define center of bbox in voxel units
865 const Vec3T c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
866 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
867 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
868
869 // Define utility functions
870 auto Pos = [](ValueT x) { return x > 0 ? x : 0; };
871 auto Neg = [](ValueT x) { return x < 0 ? x : 0; };
872
873 // Define bounds of the voxel coordinates
874 const math::BBox<Vec3T> b(c - r - Vec3T(e + ValueT(halfWidth)), c + r + Vec3T(e + ValueT(halfWidth)));
875 const CoordBBox bbox(Coord(math::Floor(b[0][0]), math::Floor(b[0][1]), math::Floor(b[0][2])),
876 Coord(math::Ceil(b[1][0]), math::Ceil(b[1][1]), math::Ceil(b[1][2])));
877 const util::Range<1,int> range(bbox[0][0], bbox[1][0]+1, 32);
878
879 // Compute signed distances to bbox using leapfrogging in k
880 auto kernel = [&](const util::Range<1,int> &ra) {
881 auto acc = grid->getWriteAccessor();
882 int m = 1;
883 for (Coord p(ra.begin(),bbox[0][1],bbox[0][2]); p[0] < ra.end(); ++p[0]) {
884 const ValueT px = math::Abs(ValueT(p[0]) - c[0]) - r[0];
885 const ValueT qx = math::Abs(ValueT(px) + e) - e;
886 const ValueT px2 = math::Pow2(Pos(px));
887 const ValueT qx2 = math::Pow2(Pos(qx));
888 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
889 const ValueT py = math::Abs(ValueT(p[1]) - c[1]) - r[1];
890 const ValueT qy = math::Abs(ValueT(py) + e) - e;
891 const ValueT qy2 = math::Pow2(Pos(qy));
892 const ValueT px2qy2 = px2 + qy2;
893 const ValueT qx2py2 = qx2 + math::Pow2(Pos(py));
894 const ValueT qx2qy2 = qx2 + qy2;
895 const ValueT a[3] = {math::Max(px, qy), math::Max(qx, py), math::Max(qx, qy)};
896 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
897 m = 1;
898 const ValueT pz = math::Abs(ValueT(p[2]) - c[2]) - r[2];
899 const ValueT qz = math::Abs(ValueT(pz) + e) - e;
900 const ValueT qz2 = math::Pow2(Pos(qz));
901 const ValueT s1 = math::Sqrt(px2qy2 + qz2) + Neg(math::Max(a[0], qz));
902 const ValueT s2 = math::Sqrt(qx2py2 + qz2) + Neg(math::Max(a[1], qz));
903 const ValueT s3 = math::Sqrt(qx2qy2 + math::Pow2(Pos(pz))) + Neg(math::Max(a[2], pz));
904 const ValueT v = math::Min(s1, math::Min(s2, s3)); // Distance in voxel units
905 const ValueT d = math::Abs(v);
906 if (d < halfWidth) { // inside narrow band
907 acc.setValue(p, ValueT(voxelSize) * v); // distance in world units
908 } else { // outside narrow band
909 m += math::Floor(d - halfWidth); // leapfrog
910 }
911 } //end leapfrog over k
912 } //end loop over j
913 } //end loop over i
914 }; //kernel
915#ifdef NANOVDB_PARALLEL_PRIMITIVES
916 util::forEach(range, kernel);
917#else
918 kernel(range);
919#endif
920
921 return grid;
922} // initBBox
923
924template<typename BuildT>
925std::shared_ptr<build::Grid<BuildT>>
926initOctahedron(double scale, // scale of the octahedron in world units
927 const Vec3d& center, // center of octahedron in world units
928 double voxelSize, // size of a voxel in world units
929 double halfWidth, // half-width of narrow band in voxel units
930 const Vec3d& origin) // origin of grid in world units
931{
932 using GridT = build::Grid<BuildT>;
933 using ValueT = typename BuildToValueMap<BuildT>::type;
934 using Vec3T = math::Vec3<ValueT>;
935 static_assert(util::is_floating_point<ValueT>::value, "initOctahedron: expect floating point");
936
937 if (!(scale > 0)) throw std::runtime_error("Octahedron: width must be positive!");
938 if (!(voxelSize > 0)) throw std::runtime_error("Octahedron: voxelSize must be positive!");
939
940 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
941 grid->setTransform(voxelSize, origin);
942
943 // Define size of octahedron with narrow-band in voxel units
944 const ValueT s = scale / (2 * ValueT(voxelSize));
945
946 // Below the Nyquist frequency
947 if ( s < ValueT(1.5) ) return grid;
948
949 // Define center of octahedron in voxel units
950 const Vec3T c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
951 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
952 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
953
954 // Define utility functions
955 auto sdf = [&s](ValueT x, ValueT y, ValueT z) {
956 const ValueT d = ValueT(0.5)*(z - y + s);
957 if (d < ValueT(0)) {
958 return Vec3T(x, y - s, z).length();
959 } else if (d > s) {
960 return Vec3T(x, y, z - s).length();
961 }
962 return Vec3T(x, y - s + d, z - d).length();
963 };
964
965 // Define bounds of the voxel coordinates
966 const math::BBox<Vec3T> b(c - Vec3T(s + ValueT(halfWidth)), c + Vec3T(s + ValueT(halfWidth)));
967 const CoordBBox bbox(Coord(math::Floor(b[0][0]), math::Floor(b[0][1]), math::Floor(b[0][2])),
968 Coord(math::Ceil(b[1][0]), math::Ceil(b[1][1]), math::Ceil(b[1][2])));
969 const util::Range<1,int> range(bbox[0][0], bbox[1][0]+1, 32);
970
971 // Compute signed distances to octahedron using leapfrogging in k
972 auto kernel = [&](const util::Range<1,int> &ra) {
973 auto acc = grid->getWriteAccessor();
974 int m = 1;
975 static const ValueT a = math::Sqrt(ValueT(1)/ValueT(3));
976 for (Coord p(ra.begin(),bbox[0][1],bbox[0][2]); p[0] < ra.end(); ++p[0]) {
977 const ValueT px = math::Abs(ValueT(p[0]) - c[0]);
978 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
979 const ValueT py = math::Abs(ValueT(p[1]) - c[1]);
980 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
981 m = 1;
982 const ValueT pz = math::Abs(ValueT(p[2]) - c[2]);
983 ValueT d = px + py + pz - s;
984 ValueT v;
985 if (ValueT(3)*px < d) {
986 v = sdf(px, py, pz);
987 } else if (ValueT(3)*py < d) {
988 v = sdf(py, pz, px);
989 } else if (ValueT(3)*pz < d) {
990 v = sdf(pz, px, py);
991 } else {
992 v = a * d;
993 }
994 d = math::Abs(v);
995 if (d < halfWidth) { // inside narrow band
996 acc.setValue(p, ValueT(voxelSize) * v); // distance in world units
997 } else { // outside narrow band
998 m += math::Floor(d - halfWidth); // leapfrog
999 }
1000 } //end leapfrog over k
1001 } //end loop over j
1002 } //end loop over i
1003 };// kernel
1004#ifdef NANOVDB_PARALLEL_PRIMITIVES
1005 util::forEach(range, kernel);
1006#else
1007 kernel(range);
1008#endif
1009 return grid;
1010} // initOctahedron
1011
1012} // unnamed namespace
1013
1014//================================================================================================
1015
1016template<typename BuildT, typename BufferT>
1017typename util::enable_if<util::is_same<BuildT, float, double>::value, GridHandle<BufferT>>::type
1018createLevelSetSphere(double radius, // radius of sphere in world units
1019 const Vec3d& center, // center of sphere in world units
1020 double voxelSize, // size of a voxel in world units
1021 double halfWidth, // half-width of narrow band in voxel units
1022 const Vec3d& origin, // origin of grid in world units
1023 const std::string& name, // name of grid
1024 StatsMode sMode, // mode of computation for the statistics
1025 CheckMode cMode, // mode of computation for the checksum
1026 const BufferT& buffer)
1027{
1028 using GridT = build::Grid<BuildT>;
1029 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1030 grid->mName = name;
1031 build::NodeManager<GridT> mgr(*grid);
1033 CreateNanoGrid<GridT> converter(*grid);
1034 converter.setStats(sMode);
1035 converter.setChecksum(cMode);
1036 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1037 assert(handle);
1038 return handle;
1039} // createLevelSetSphere<T>
1040
1041//================================================================================================
1042
1043template<typename BuildT, typename BufferT>
1045createLevelSetSphere(double radius, // radius of sphere in world units
1046 const Vec3d& center, // center of sphere in world units
1047 double voxelSize, // size of a voxel in world units
1048 double halfWidth, // half-width of narrow band in voxel units
1049 const Vec3d& origin, // origin of grid in world units
1050 const std::string& name, // name of grid
1051 StatsMode sMode, // mode of computation for the statistics
1052 CheckMode cMode, // mode of computation for the checksum
1053 bool ditherOn,
1054 const BufferT& buffer)
1055{
1056 using GridT = build::Grid<BuildT>;
1057 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1058 grid->mName = name;
1059 build::NodeManager<GridT> mgr(*grid);
1061 CreateNanoGrid<GridT> converter(*grid);
1062 converter.setStats(sMode);
1063 converter.setChecksum(cMode);
1064 converter.enableDithering(ditherOn);
1065 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1066 assert(handle);
1067 return handle;
1068} // createLevelSetSphere<Fp4 or Fp8 or Fp16>
1069
1070//================================================================================================
1071
1072template<typename BuildT, typename BufferT>
1074createLevelSetSphere(double radius, // radius of sphere in world units
1075 const Vec3d& center, // center of sphere in world units
1076 double voxelSize, // size of a voxel in world units
1077 double halfWidth, // half-width of narrow band in voxel units
1078 const Vec3d& origin, // origin of grid in world units
1079 const std::string& name, // name of grid
1080 StatsMode sMode, // mode of computation for the statistics
1081 CheckMode cMode, // mode of computation for the checksum
1082 float tolerance,// only used if VoxelT = FpN
1083 bool ditherOn,
1084 const BufferT& buffer)
1085{
1086 using GridT = build::Grid<BuildT>;
1087 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1088 grid->mName = name;
1089 build::NodeManager<GridT> mgr(*grid);
1091 CreateNanoGrid<GridT> converter(*grid);
1092 converter.setStats(sMode);
1093 converter.setChecksum(cMode);
1094 converter.enableDithering(ditherOn);
1095 AbsDiff oracle(tolerance);
1096 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1097 assert(handle);
1098 return handle;
1099} // createLevelSetSphere<FpN>
1100
1101//================================================================================================
1102
1103template<typename BuildT, typename BufferT>
1105createFogVolumeSphere(double radius, // radius of sphere in world units
1106 const Vec3d& center, // center of sphere in world units
1107 double voxelSize, // size of a voxel in world units
1108 double halfWidth, // half-width of narrow band in voxel units
1109 const Vec3d& origin, // origin of grid in world units
1110 const std::string& name, // name of grid
1111 StatsMode sMode, // mode of computation for the statistics
1112 CheckMode cMode, // mode of computation for the checksum
1113 const BufferT& buffer)
1114{
1115 using GridT = build::Grid<BuildT>;
1116 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1117 grid->mName = name;
1118 build::NodeManager<GridT> mgr(*grid);
1120 build::levelSetToFog(mgr, false);
1121 CreateNanoGrid<GridT> converter(*grid);
1122 converter.setStats(sMode);
1123 converter.setChecksum(cMode);
1124 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1125 assert(handle);
1126 return handle;
1127} // createFogVolumeSphere<T>
1128
1129//================================================================================================
1130
1131template<typename BuildT, typename BufferT>
1133createFogVolumeSphere(double radius, // radius of sphere in world units
1134 const Vec3d& center, // center of sphere in world units
1135 double voxelSize, // size of a voxel in world units
1136 double halfWidth, // half-width of narrow band in voxel units
1137 const Vec3d& origin, // origin of grid in world units
1138 const std::string& name, // name of grid
1139 StatsMode sMode, // mode of computation for the statistics
1140 CheckMode cMode, // mode of computation for the checksum
1141 float tolerance,// only used if VoxelT = FpN
1142 bool ditherOn,
1143 const BufferT& buffer)
1144{
1145 using GridT = build::Grid<BuildT>;
1146 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1147 grid->mName = name;
1148 build::NodeManager<GridT> mgr(*grid);
1150 build::levelSetToFog(mgr, false);
1151 CreateNanoGrid<GridT> converter(*grid);
1152 converter.setStats(sMode);
1153 converter.setChecksum(cMode);
1154 converter.enableDithering(ditherOn);
1155 AbsDiff oracle(tolerance);
1156 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1157 assert(handle);
1158 return handle;
1159} // createFogVolumeSphere<FpN>
1160
1161//================================================================================================
1162
1163template<typename BuildT, typename BufferT>
1165createPointSphere(int pointsPerVoxel, // number of points to be scattered in each active voxel
1166 double radius, // radius of sphere in world units
1167 const Vec3d& center, // center of sphere in world units
1168 double voxelSize, // size of a voxel in world units
1169 const Vec3d& origin, // origin of grid in world units
1170 const std::string& name, // name of grid
1171 CheckMode cMode, // mode of computation for the checksum
1172 const BufferT& buffer)
1173{
1174 auto sphereHandle = createLevelSetSphere(radius, center, voxelSize, 0.5, origin, "dummy",
1176 assert(sphereHandle);
1177 auto* sphereGrid = sphereHandle.template grid<BuildT>();
1178 assert(sphereGrid);
1179 auto pointHandle = createPointScatter(*sphereGrid, pointsPerVoxel, name, cMode, buffer);
1180 assert(pointHandle);
1181 return pointHandle;
1182} // createPointSphere
1183
1184//================================================================================================
1185
1186template<typename BuildT, typename BufferT>
1188createLevelSetTorus(double majorRadius, // major radius of torus in world units
1189 double minorRadius, // minor radius of torus in world units
1190 const Vec3d& center, // center of torus in world units
1191 double voxelSize, // size of a voxel in world units
1192 double halfWidth, // half-width of narrow band in voxel units
1193 const Vec3d& origin, // origin of grid in world units
1194 const std::string& name, // name of grid
1195 StatsMode sMode, // mode of computation for the statistics
1196 CheckMode cMode, // mode of computation for the checksum
1197 const BufferT& buffer)
1198{
1199 using GridT = build::Grid<BuildT>;
1200 auto grid = initTorus<BuildT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
1201 grid->mName = name;
1202 build::NodeManager<GridT> mgr(*grid);
1204 CreateNanoGrid<GridT> converter(*grid);
1205 converter.setStats(sMode);
1206 converter.setChecksum(cMode);
1207 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1208 assert(handle);
1209 return handle;
1210} // createLevelSetTorus<T>
1211
1212//================================================================================================
1213
1214template<typename BuildT, typename BufferT>
1216createLevelSetTorus(double majorRadius, // major radius of torus in world units
1217 double minorRadius, // minor radius of torus in world units
1218 const Vec3d& center, // center of torus in world units
1219 double voxelSize, // size of a voxel in world units
1220 double halfWidth, // half-width of narrow band in voxel units
1221 const Vec3d& origin, // origin of grid in world units
1222 const std::string& name, // name of grid
1223 StatsMode sMode, // mode of computation for the statistics
1224 CheckMode cMode, // mode of computation for the checksum
1225 float tolerance,
1226 bool ditherOn,
1227 const BufferT& buffer)
1228{
1229 using GridT = build::Grid<BuildT>;
1230 auto grid = initTorus<BuildT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
1231 grid->mName = name;
1232 build::NodeManager<GridT> mgr(*grid);
1234 CreateNanoGrid<GridT> converter(*grid);
1235 converter.setStats(sMode);
1236 converter.setChecksum(cMode);
1237 converter.enableDithering(ditherOn);
1238 AbsDiff oracle(tolerance);
1239 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1240 assert(handle);
1241 return handle;
1242} // createLevelSetTorus<FpN>
1243
1244//================================================================================================
1245
1246template<typename BuildT, typename BufferT>
1248createFogVolumeTorus(double majorRadius, // major radius of torus in world units
1249 double minorRadius, // minor radius of torus in world units
1250 const Vec3d& center, // center of torus in world units
1251 double voxelSize, // size of a voxel in world units
1252 double halfWidth, // half-width of narrow band in voxel units
1253 const Vec3d& origin, // origin of grid in world units
1254 const std::string& name, // name of grid
1255 StatsMode sMode, // mode of computation for the statistics
1256 CheckMode cMode, // mode of computation for the checksum
1257 const BufferT& buffer)
1258{
1259 using GridT = build::Grid<BuildT>;
1260 auto grid = initTorus<BuildT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
1261 grid->mName = name;
1262 build::NodeManager<GridT> mgr(*grid);
1264 build::levelSetToFog(mgr, false);
1265 CreateNanoGrid<GridT> converter(*grid);
1266 converter.setStats(sMode);
1267 converter.setChecksum(cMode);
1268 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1269 assert(handle);
1270 return handle;
1271} // createFogVolumeTorus<T>
1272
1273//================================================================================================
1274
1275template<typename BuildT, typename BufferT>
1277createFogVolumeTorus(double majorRadius, // major radius of torus in world units
1278 double minorRadius, // minor radius of torus in world units
1279 const Vec3d& center, // center of torus in world units
1280 double voxelSize, // size of a voxel in world units
1281 double halfWidth, // half-width of narrow band in voxel units
1282 const Vec3d& origin, // origin of grid in world units
1283 const std::string& name, // name of grid
1284 StatsMode sMode, // mode of computation for the statistics
1285 CheckMode cMode, // mode of computation for the checksum
1286 float tolerance,
1287 bool ditherOn,
1288 const BufferT& buffer)
1289{
1290 using GridT = build::Grid<BuildT>;
1291 auto grid = initTorus<BuildT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
1292 grid->mName = name;
1293 build::NodeManager<GridT> mgr(*grid);
1295 build::levelSetToFog(mgr, false);
1296 CreateNanoGrid<GridT> converter(*grid);
1297 converter.setStats(sMode);
1298 converter.setChecksum(cMode);
1299 converter.enableDithering(ditherOn);
1300 AbsDiff oracle(tolerance);
1301 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1302 assert(handle);
1303 return handle;
1304} // createFogVolumeTorus<FpN>
1305
1306//================================================================================================
1307
1308template<typename BuildT, typename BufferT>
1310createPointTorus(int pointsPerVoxel, // number of points to be scattered in each active voxel
1311 double majorRadius, // major radius of torus in world units
1312 double minorRadius, // minor radius of torus in world units
1313 const Vec3d& center, // center of torus in world units
1314 double voxelSize, // size of a voxel in world units
1315 const Vec3d& origin, // origin of grid in world units
1316 const std::string& name, // name of grid
1317 CheckMode cMode, // mode of computation for the checksum
1318 const BufferT& buffer)
1319{
1320 auto torusHandle = createLevelSetTorus(majorRadius, minorRadius, center, voxelSize, 0.5f, origin,
1321 "dummy", StatsMode::BBox, CheckMode::Disable, buffer);
1322 assert(torusHandle);
1323 auto* torusGrid = torusHandle.template grid<BuildT>();
1324 assert(torusGrid);
1325 auto pointHandle = createPointScatter(*torusGrid, pointsPerVoxel, name, cMode, buffer);
1326 assert(pointHandle);
1327 return pointHandle;
1328} // createPointTorus<T>
1329
1330//================================================================================================
1331
1332template<typename BuildT, typename BufferT>
1334createLevelSetBox(double width, // width of box in world units
1335 double height, // height of box in world units
1336 double depth, // depth of box in world units
1337 const Vec3d& center, // center of box in world units
1338 double voxelSize, // size of a voxel in world units
1339 double halfWidth, // half-width of narrow band in voxel units
1340 const Vec3d& origin, // origin of grid in world units
1341 const std::string& name, // name of grid
1342 StatsMode sMode, // mode of computation for the statistics
1343 CheckMode cMode, // mode of computation for the checksum
1344 const BufferT& buffer)
1345{
1346 using GridT = build::Grid<BuildT>;
1347 auto grid = initBox<BuildT>(width, height, depth, center, voxelSize, halfWidth, origin);
1348 grid->mName = name;
1349 build::NodeManager<GridT> mgr(*grid);
1351 CreateNanoGrid<GridT> converter(*grid);
1352 converter.setStats(sMode);
1353 converter.setChecksum(cMode);
1354 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1355 assert(handle);
1356 return handle;
1357} // createLevelSetBox<T>
1358
1359//================================================================================================
1360
1361template<typename BuildT, typename BufferT>
1363createLevelSetBox(double width, // width of box in world units
1364 double height, // height of box in world units
1365 double depth, // depth of box in world units
1366 const Vec3d& center, // center of box in world units
1367 double voxelSize, // size of a voxel in world units
1368 double halfWidth, // half-width of narrow band in voxel units
1369 const Vec3d& origin, // origin of grid in world units
1370 const std::string& name, // name of grid
1371 StatsMode sMode, // mode of computation for the statistics
1372 CheckMode cMode, // mode of computation for the checksum
1373 float tolerance,
1374 bool ditherOn,
1375 const BufferT& buffer)
1376{
1377 using GridT = build::Grid<BuildT>;
1378 auto grid = initBox<BuildT>(width, height, depth, center, voxelSize, halfWidth, origin);
1379 grid->mName = name;
1380 build::NodeManager<GridT> mgr(*grid);
1382 CreateNanoGrid<GridT> converter(*grid);
1383 converter.setStats(sMode);
1384 converter.setChecksum(cMode);
1385 converter.enableDithering(ditherOn);
1386 AbsDiff oracle(tolerance);
1387 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1388 assert(handle);
1389 return handle;
1390} // createLevelSetBox<FpN>
1391
1392//================================================================================================
1393
1394template<typename BuildT, typename BufferT>
1396createLevelSetOctahedron(double scale, // scale of the octahedron in world units
1397 const Vec3d& center, // center of box in world units
1398 double voxelSize, // size of a voxel in world units
1399 double halfWidth, // half-width of narrow band in voxel units
1400 const Vec3d& origin, // origin of grid in world units
1401 const std::string& name, // name of grid
1402 StatsMode sMode, // mode of computation for the statistics
1403 CheckMode cMode, // mode of computation for the checksum
1404 const BufferT& buffer)
1405{
1406 using GridT = build::Grid<BuildT>;
1407 auto grid = initOctahedron<BuildT>(scale, center, voxelSize, halfWidth, origin);
1408 grid->mName = name;
1409 build::NodeManager<GridT> mgr(*grid);
1411 CreateNanoGrid<GridT> converter(*grid);
1412 converter.setStats(sMode);
1413 converter.setChecksum(cMode);
1414 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1415 assert(handle);
1416 return handle;
1417} // createLevelSetOctahedron<T>
1418
1419//================================================================================================
1420
1421template<typename BuildT, typename BufferT>
1423createLevelSetOctahedron(double scale, // scale of the octahedron in world units
1424 const Vec3d& center, // center of box in world units
1425 double voxelSize, // size of a voxel in world units
1426 double halfWidth, // half-width of narrow band in voxel units
1427 const Vec3d& origin, // origin of grid in world units
1428 const std::string& name, // name of grid
1429 StatsMode sMode, // mode of computation for the statistics
1430 CheckMode cMode, // mode of computation for the checksum
1431 float tolerance,
1432 bool ditherOn,
1433 const BufferT& buffer)
1434{
1435 using GridT = build::Grid<BuildT>;
1436 auto grid = initOctahedron<BuildT>(scale, center, voxelSize, halfWidth, origin);
1437 grid->mName = name;
1438 build::NodeManager<GridT> mgr(*grid);
1440 CreateNanoGrid<GridT> converter(*grid);
1441 converter.setStats(sMode);
1442 converter.setChecksum(cMode);
1443 converter.enableDithering(ditherOn);
1444 AbsDiff oracle(tolerance);
1445 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1446 assert(handle);
1447 return handle;
1448} // createLevelSetOctahedron<FpN>
1449
1450//================================================================================================
1451
1452template<typename BuildT, typename BufferT>
1454createLevelSetBBox(double width, // width of bbox in world units
1455 double height, // height of bbox in world units
1456 double depth, // depth of bbox in world units
1457 double thickness, // thickness of the wire in world units
1458 const Vec3d& center, // center of bbox in world units
1459 double voxelSize, // size of a voxel in world units
1460 double halfWidth, // half-width of narrow band in voxel units
1461 const Vec3d& origin, // origin of grid in world units
1462 const std::string& name, // name of grid
1463 StatsMode sMode, // mode of computation for the statistics
1464 CheckMode cMode, // mode of computation for the checksum
1465 const BufferT& buffer)
1466{
1467 using GridT = build::Grid<BuildT>;
1468 auto grid = initBBox<BuildT>(width, height, depth, thickness, center, voxelSize, halfWidth, origin);
1469 grid->mName = name;
1470 build::NodeManager<GridT> mgr(*grid);
1472 CreateNanoGrid<GridT> converter(*grid);
1473 converter.setStats(sMode);
1474 converter.setChecksum(cMode);
1475 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1476 assert(handle);
1477 return handle;
1478} // createLevelSetBBox<T>
1479
1480//================================================================================================
1481
1482template<typename BuildT, typename BufferT>
1484createLevelSetBBox(double width, // width of bbox in world units
1485 double height, // height of bbox in world units
1486 double depth, // depth of bbox in world units
1487 double thickness, // thickness of the wire in world units
1488 const Vec3d& center, // center of bbox in world units
1489 double voxelSize, // size of a voxel in world units
1490 double halfWidth, // half-width of narrow band in voxel units
1491 const Vec3d& origin, // origin of grid in world units
1492 const std::string& name, // name of grid
1493 StatsMode sMode, // mode of computation for the statistics
1494 CheckMode cMode, // mode of computation for the checksum
1495 float tolerance,
1496 bool ditherOn,
1497 const BufferT& buffer)
1498{
1499 using GridT = build::Grid<BuildT>;
1500 auto grid = initBBox<BuildT>(width, height, depth, thickness, center, voxelSize, halfWidth, origin);
1501 grid->mName = name;
1502 build::NodeManager<GridT> mgr(*grid);
1504 CreateNanoGrid<GridT> converter(*grid);
1505 converter.setStats(sMode);
1506 converter.setChecksum(cMode);
1507 converter.enableDithering(ditherOn);
1508 AbsDiff oracle(tolerance);
1509 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1510 assert(handle);
1511 return handle;
1512} // createLevelSetBBox<FpN>
1513
1514//================================================================================================
1515
1516template<typename BuildT, typename BufferT>
1518createFogVolumeBox(double width, // width of box in world units
1519 double height, // height of box in world units
1520 double depth, // depth of box in world units
1521 const Vec3d& center, // center of box in world units
1522 double voxelSize, // size of a voxel in world units
1523 double halfWidth, // half-width of narrow band in voxel units
1524 const Vec3d& origin, // origin of grid in world units
1525 const std::string& name, // name of grid
1526 StatsMode sMode, // mode of computation for the statistics
1527 CheckMode cMode, // mode of computation for the checksum
1528 const BufferT& buffer)
1529{
1530 using GridT = build::Grid<BuildT>;
1531 auto grid = initBox<BuildT>(width, height, depth, center, voxelSize, halfWidth, origin);
1532 grid->mName = name;
1533 build::NodeManager<GridT> mgr(*grid);
1535 build::levelSetToFog(mgr, false);
1536 CreateNanoGrid<GridT> converter(*grid);
1537 converter.setStats(sMode);
1538 converter.setChecksum(cMode);
1539 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1540 assert(handle);
1541 return handle;
1542} // createFogVolumeBox<T>
1543
1544//================================================================================================
1545
1546template<typename BuildT, typename BufferT>
1548createFogVolumeBox(double width, // width of box in world units
1549 double height, // height of box in world units
1550 double depth, // depth of box in world units
1551 const Vec3d& center, // center of box in world units
1552 double voxelSize, // size of a voxel in world units
1553 double halfWidth, // half-width of narrow band in voxel units
1554 const Vec3d& origin, // origin of grid in world units
1555 const std::string& name, // name of grid
1556 StatsMode sMode, // mode of computation for the statistics
1557 CheckMode cMode, // mode of computation for the checksum
1558 float tolerance,
1559 bool ditherOn,
1560 const BufferT& buffer)
1561{
1562 using GridT = build::Grid<BuildT>;
1563 auto grid = initBox<BuildT>(width, height, depth, center, voxelSize, halfWidth, origin);
1564 grid->mName = name;
1565 build::NodeManager<GridT> mgr(*grid);
1567 build::levelSetToFog(mgr, false);
1568 CreateNanoGrid<GridT> converter(*grid);
1569 converter.setStats(sMode);
1570 converter.setChecksum(cMode);
1571 converter.enableDithering(ditherOn);
1572 AbsDiff oracle(tolerance);
1573 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1574 assert(handle);
1575 return handle;
1576} // createFogVolumeBox<FpN>
1577
1578//================================================================================================
1579
1580template<typename BuildT, typename BufferT>
1582createFogVolumeOctahedron(double scale, // scale of octahedron in world units
1583 const Vec3d& center, // center of box in world units
1584 double voxelSize, // size of a voxel in world units
1585 double halfWidth, // half-width of narrow band in voxel units
1586 const Vec3d& origin, // origin of grid in world units
1587 const std::string& name, // name of grid
1588 StatsMode sMode, // mode of computation for the statistics
1589 CheckMode cMode, // mode of computation for the checksum
1590 const BufferT& buffer)
1591{
1592 using GridT = build::Grid<BuildT>;
1593 auto grid = initOctahedron<BuildT>(scale, center, voxelSize, halfWidth, origin);
1594 grid->mName = name;
1595 build::NodeManager<GridT> mgr(*grid);
1597 build::levelSetToFog(mgr, false);
1598 CreateNanoGrid<GridT> converter(*grid);
1599 converter.setStats(sMode);
1600 converter.setChecksum(cMode);
1601 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1602 assert(handle);
1603 return handle;
1604} // createFogVolumeOctahedron<T>
1605
1606//================================================================================================
1607
1608template<typename BuildT, typename BufferT>
1610createFogVolumeOctahedron(double scale, // scale of octahedron in world units
1611 const Vec3d& center, // center of box in world units
1612 double voxelSize, // size of a voxel in world units
1613 double halfWidth, // half-width of narrow band in voxel units
1614 const Vec3d& origin, // origin of grid in world units
1615 const std::string& name, // name of grid
1616 StatsMode sMode, // mode of computation for the statistics
1617 CheckMode cMode, // mode of computation for the checksum
1618 float tolerance,
1619 bool ditherOn,
1620 const BufferT& buffer)
1621{
1622 using GridT = build::Grid<BuildT>;
1623 auto grid = initOctahedron<BuildT>(scale, center, voxelSize, halfWidth, origin);
1624 grid->mName = name;
1625 build::NodeManager<GridT> mgr(*grid);
1627 build::levelSetToFog(mgr, false);
1628 CreateNanoGrid<GridT> converter(*grid);
1629 converter.setStats(sMode);
1630 converter.setChecksum(cMode);
1631 converter.enableDithering(ditherOn);
1632 AbsDiff oracle(tolerance);
1633 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1634 assert(handle);
1635 return handle;
1636} // createFogVolumeOctahedron<FpN>
1637
1638//================================================================================================
1639
1640template<typename BuildT, typename BufferT>
1642createPointBox(int pointsPerVoxel, // number of points to be scattered in each active voxel
1643 double width, // width of box in world units
1644 double height, // height of box in world units
1645 double depth, // depth of box in world units
1646 const Vec3d& center, // center of box in world units
1647 double voxelSize, // size of a voxel in world units
1648 const Vec3d& origin, // origin of grid in world units
1649 const std::string& name, // name of grid
1650 CheckMode cMode, // mode of computation for the checksum
1651 const BufferT& buffer)
1652{
1653 auto boxHandle = createLevelSetBox(width, height, depth, center, voxelSize, 0.5, origin, "dummy",
1655 assert(boxHandle);
1656 auto* boxGrid = boxHandle.template grid<BuildT>();
1657 assert(boxGrid);
1658 auto pointHandle = createPointScatter(*boxGrid, pointsPerVoxel, name, cMode, buffer);
1659 assert(pointHandle);
1660 return pointHandle;
1661} // createPointBox<T>
1662
1663//================================================================================================
1664
1665template<typename SrcBuildT, typename BufferT>
1667createPointScatter(const NanoGrid<SrcBuildT>& srcGrid, // origin of grid in world units
1668 int pointsPerVoxel, // number of points to be scattered in each active voxel
1669 const std::string& name, // name of grid
1670 CheckMode cMode, // mode of computation for the checksum
1671 const BufferT& buffer)
1672{
1673 using ValueT = typename BuildToValueMap<SrcBuildT>::type;
1674 static_assert(util::is_floating_point<ValueT>::value, "createPointScatter: expect floating point");
1675 using Vec3T = math::Vec3<ValueT>;
1676 if (pointsPerVoxel < 1) {
1677 throw std::runtime_error("createPointScatter: Expected at least one point per voxel");
1678 }
1679 if (!srcGrid.isLevelSet()) {
1680 throw std::runtime_error("createPointScatter: Expected a level set grid");
1681 }
1682 if (!srcGrid.hasBBox()) {
1683 throw std::runtime_error("createPointScatter: ActiveVoxelCount is required");
1684 }
1685 const uint64_t pointCount = pointsPerVoxel * srcGrid.activeVoxelCount();
1686 if (pointCount == 0) {
1687 throw std::runtime_error("createPointScatter: No particles to scatter");
1688 }
1689 std::vector<Vec3T> xyz;
1690 xyz.reserve(pointCount);
1691 using DstGridT = build::Grid<uint32_t>;
1692 DstGridT dstGrid(std::numeric_limits<uint32_t>::max(), name, GridClass::PointData);
1693 dstGrid.mMap = srcGrid.map();
1694 auto dstAcc = dstGrid.getAccessor();
1695 std::srand(1234);
1696 const ValueT s = 1 / (1 + ValueT(RAND_MAX)); // scale so s*rand() is in ] 0, 1 [
1697 // return a point with random local voxel coordinates (-0.5 to +0.5)
1698 auto randomPoint = [&s](){return s * Vec3T(rand(), rand(), rand()) - Vec3T(0.5);};
1699 const auto& srcTree = srcGrid.tree();
1700 auto srcMgrHandle = createNodeManager(srcGrid);
1701 auto *srcMgr = srcMgrHandle.template mgr<SrcBuildT>();
1702 assert(srcMgr);
1703 for (uint32_t i = 0, end = srcTree.nodeCount(0); i < end; ++i) {
1704 auto& srcLeaf = srcMgr->leaf(i);
1705 auto* dstLeaf = dstAcc.setValue(srcLeaf.origin(), pointsPerVoxel); // allocates leaf node
1706 dstLeaf->mValueMask = srcLeaf.valueMask();
1707 for (uint32_t j = 0, m = 0; j < 512; ++j) {
1708 if (dstLeaf->mValueMask.isOn(j)) {
1709 const Vec3f ijk = dstLeaf->offsetToGlobalCoord(j).asVec3s();// floating-point representation of index coordinates
1710 for (int n = 0; n < pointsPerVoxel; ++n) xyz.push_back(srcGrid.indexToWorld(randomPoint() + ijk));
1711 m += pointsPerVoxel;
1712 }// active voxels
1713 dstLeaf->mValues[j] = m;
1714 }// loop over all voxels
1715 }// loop over leaf nodes
1716 assert(pointCount == xyz.size());
1717 CreateNanoGrid<DstGridT> converter(dstGrid);
1718 converter.setStats(StatsMode::MinMax);
1720
1721 converter.addBlindData(name,
1725 pointCount,
1726 sizeof(Vec3T));
1727 auto handle = converter.template getHandle<uint32_t>(buffer);
1728 assert(handle);
1729
1730 auto* grid = handle.template grid<uint32_t>();
1731 assert(grid && grid->template isSequential<0>());
1732 auto &tree = grid->tree();
1733 if (tree.nodeCount(0) == 0) throw std::runtime_error("Expect leaf nodes!");
1734 auto *leafData = tree.getFirstLeaf()->data();
1735 leafData[0].mMinimum = 0; // start of prefix sum
1736 for (uint32_t i = 1, n = tree.nodeCount(0); i < n; ++i) {
1737 leafData[i].mMinimum = leafData[i - 1].mMinimum + leafData[i - 1].mMaximum;
1738 }
1739 if (Vec3T *blindData = grid->template getBlindData<Vec3T>(0)) {
1740 memcpy(blindData, xyz.data(), xyz.size() * sizeof(Vec3T));
1741 } else {
1742 throw std::runtime_error("Blind data pointer was NULL");
1743 }
1744 updateChecksum(grid, cMode);
1745 return handle;
1746} // createPointScatter
1747
1748}// namespace tools
1749
1750} // namespace nanovdb
1751
1752#endif // NANOVDB_TOOLS_PRIMITIVES_H_HAS_BEEN_INCLUDED
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
This class serves to manage a buffer containing one or more NanoVDB Grids.
Definition GridHandle.h:109
Vec3T indexToWorld(const Vec3T &xyz) const
index to world space transformation
Definition NanoVDB.h:2256
uint64_t activeVoxelCount() const
Computes a AABB of active values in world space.
Definition NanoVDB.h:2306
const TreeT & tree() const
Return a const reference to the tree.
Definition NanoVDB.h:2236
const Map & map() const
Return a const reference to the Map for this grid.
Definition NanoVDB.h:2248
bool hasBBox() const
Definition NanoVDB.h:2322
bool isLevelSet() const
Definition NanoVDB.h:2312
A simple vector class with three components, similar to openvdb::math::Vec3.
Definition Math.h:1362
Compression oracle based on absolute difference.
Definition CreateNanoGrid.h:251
Creates any nanovdb Grid from any source grid (certain combinations are obviously not allowed)
Definition CreateNanoGrid.h:532
uint64_t addBlindData(const std::string &name, GridBlindDataSemantic dataSemantic, GridBlindDataClass dataClass, GridType dataType, size_t count, size_t size)
Add blind data to the destination grid.
Definition CreateNanoGrid.h:615
void setStats(StatsMode mode=StatsMode::Default)
Set the mode used for computing statistics of the destination grid.
Definition CreateNanoGrid.h:562
void enableDithering(bool on=true)
Enable or disable dithering, i.e. randomization of the quantization error.
Definition CreateNanoGrid.h:558
void setChecksum(CheckMode mode=CheckMode::Default)
Set the mode used for computing checksums of the destination grid.
Definition CreateNanoGrid.h:566
Definition GridBuilder.h:2055
__hostdev__ T Abs(T x)
Definition Math.h:229
__hostdev__ int32_t Floor(float x)
Definition Math.h:193
__hostdev__ T Pow2(T x)
Definition Math.h:212
__hostdev__ Type Max(Type a, Type b)
Definition Math.h:154
__hostdev__ int32_t Ceil(float x)
Definition Math.h:202
__hostdev__ float Sqrt(float x)
Return the square root of a floating-point value.
Definition Math.h:277
__hostdev__ Type Min(Type a, Type b)
Definition Math.h:133
void levelSetToFog(NodeManagerT &mgr, bool rebuild=true)
Definition GridBuilder.h:2167
util::enable_if< util::is_floating_point< typenameNodeManagerT::ValueType >::value >::type sdfToLevelSet(NodeManagerT &mgr)
Definition GridBuilder.h:2149
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createPointSphere(int pointsPerVoxel=1, double radius=100.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="sphere_points", CheckMode mode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a PointDataGrid containing points scattered on the surface of a sphere.
Definition CreatePrimitives.h:1165
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createFogVolumeSphere(double radius=100.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="sphere_fog", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a sparse fog volume of a sphere such that the exterior is 0 and inactive,...
Definition CreatePrimitives.h:1105
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createLevelSetTorus(double majorRadius=100.0, double minorRadius=50.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="torus_ls", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a torus in the xz-plane.
Definition CreatePrimitives.h:1188
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createPointTorus(int pointsPerVoxel=1, double majorRadius=100.0, double minorRadius=50.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, const Vec3d &origin=Vec3d(0.0f), const std::string &name="torus_points", CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a PointDataGrid containing points scattered on the surface of a torus.
Definition CreatePrimitives.h:1310
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createLevelSetOctahedron(double scale=100.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="octadedron_ls", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a octahedron.
Definition CreatePrimitives.h:1396
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createFogVolumeTorus(double majorRadius=100.0, double minorRadius=50.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="torus_fog", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a sparse fog volume of a torus in the xz-plane such that the exterior is 0 and in...
Definition CreatePrimitives.h:1248
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createLevelSetBox(double width=40.0, double height=60.0, double depth=100.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="box_ls", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a box.
Definition CreatePrimitives.h:1334
void updateChecksum(GridData *gridData, CheckMode mode)
Updates the checksum of a grid.
Definition GridChecksum.h:71
StatsMode
Grid flags which indicate what extra information is present in the grid buffer.
Definition GridStats.h:40
@ BBox
Definition GridStats.h:42
@ Default
Definition GridStats.h:45
@ MinMax
Definition GridStats.h:43
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createLevelSetBBox(double width=40.0, double height=60.0, double depth=100.0, double thickness=10.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="bbox_ls", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a bounding-box (= wireframe of a box)
Definition CreatePrimitives.h:1454
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createPointBox(int pointsPerVoxel=1, double width=40.0, double height=60.0, double depth=100.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="box_points", CheckMode mode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a PointDataGrid containing points scattered on the surface of a box.
Definition CreatePrimitives.h:1642
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createFogVolumeBox(double width=40.0, double height=60.0, double depth=100.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="box_fog", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a sparse fog volume of a box such that the exterior is 0 and inactive,...
Definition CreatePrimitives.h:1518
util::enable_if< util::is_same< BuildT, float, double >::value, GridHandle< BufferT > >::type createLevelSetSphere(double radius=100.0, const Vec3d &center=Vec3d(0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0), const std::string &name="sphere_ls", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a sphere.
Definition CreatePrimitives.h:1018
GridHandle< BufferT > createPointScatter(const NanoGrid< SrcBuildT > &srcGrid, int pointsPerVoxel=1, const std::string &name="point_scatter", CheckMode mode=CheckMode::Default, const BufferT &buffer=BufferT())
Given an input NanoVDB voxel grid this methods returns a GridHandle to another NanoVDB PointDataGrid ...
Definition CreatePrimitives.h:1667
util::disable_if< util::is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createFogVolumeOctahedron(double scale=100.0, const Vec3d &center=Vec3d(0.0), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0.0), const std::string &name="octadedron_fog", StatsMode sMode=StatsMode::Default, CheckMode cMode=CheckMode::Default, const BufferT &buffer=BufferT())
Returns a handle to a sparse fog volume of an octahedron such that the exterior is 0 and inactive,...
Definition CreatePrimitives.h:1582
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition ForEach.h:42
Defines a simple memory pool used to call cub functions that use dynamic temporary storage.
Definition GridHandle.h:31
GridType toGridType()
Maps from a templated build type to a GridType enum.
Definition NanoVDB.h:851
Grid< NanoTree< BuildT > > NanoGrid
Definition NanoVDB.h:4742
math::Vec3< float > Vec3f
Definition Math.h:2230
@ PointData
Definition NanoVDB.h:293
CheckMode
List of different modes for computing for a checksum.
Definition NanoVDB.h:1846
@ Default
Definition NanoVDB.h:1850
@ Disable
Definition NanoVDB.h:1846
@ AttributeArray
Definition NanoVDB.h:412
math::Vec3< double > Vec3d
Definition Math.h:2229
math::BBox< Coord > CoordBBox
Definition Math.h:2241
@ WorldCoords
Definition NanoVDB.h:425
NodeManagerHandle< BufferT > createNodeManager(const NanoGrid< BuildT > &grid, const BufferT &buffer=BufferT())
brief Construct a NodeManager and return its handle
Definition NodeManager.h:307
T type
Definition NanoVDB.h:528
Definition GridBuilder.h:1882
Definition Util.h:364
C++11 implementation of std::enable_if.
Definition Util.h:353
static constexpr bool value
Definition Util.h:344
Convert any grid to a nanovdb grid of the same type, e.g. float->float.