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