16 #ifndef NANOVDB_PRIMITIVES_H_HAS_BEEN_INCLUDED
17 #define NANOVDB_PRIMITIVES_H_HAS_BEEN_INCLUDED
19 #define NANOVDB_PARALLEL_PRIMITIVES
44 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
49 double voxelSize = 1.0,
50 double halfWidth = 3.0,
55 const BufferT&
buffer = BufferT());
57 template<
typename BuildT,
typename BufferT = HostBuffer>
63 double voxelSize = 1.0,
64 double halfWidth = 3.0,
69 bool ditherOn =
false,
70 const BufferT&
buffer = BufferT());
72 template<
typename BuildT,
typename BufferT = HostBuffer>
76 double voxelSize = 1.0,
77 double halfWidth = 3.0,
82 float tolerance = -1.0
f,
83 bool ditherOn =
false,
84 const BufferT&
buffer = BufferT());
108 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
112 double voxelSize = 1.0,
113 double halfWidth = 3.0,
118 const BufferT&
buffer = BufferT());
120 template<
typename BuildT,
typename BufferT = HostBuffer>
124 double voxelSize = 1.0,
125 double halfWidth = 3.0,
130 float tolerance = -1.0
f,
131 bool ditherOn =
false,
132 const BufferT&
buffer = BufferT());
149 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
152 double radius = 100.0,
154 double voxelSize = 1.0,
158 const BufferT&
buffer = BufferT());
180 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
183 double minorRadius = 50.0,
185 double voxelSize = 1.0,
186 double halfWidth = 3.0,
191 const BufferT&
buffer = BufferT());
193 template<
typename BuildT,
typename BufferT = HostBuffer>
196 double minorRadius = 50.0,
198 double voxelSize = 1.0,
199 double halfWidth = 3.0,
204 float tolerance = -1.0
f,
205 bool ditherOn =
false,
206 const BufferT&
buffer = BufferT());
231 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
234 double minorRadius = 50.0,
236 double voxelSize = 1.0,
237 double halfWidth = 3.0,
242 const BufferT&
buffer = BufferT());
244 template<
typename BuildT,
typename BufferT = HostBuffer>
247 double minorRadius = 50.0,
249 double voxelSize = 1.0,
250 double halfWidth = 3.0,
255 float tolerance = -1.0
f,
256 bool ditherOn =
false,
257 const BufferT&
buffer = BufferT());
275 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
278 double majorRadius = 100.0,
279 double minorRadius = 50.0,
281 double voxelSize = 1.0,
285 const BufferT&
buffer = BufferT());
308 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
312 double depth = 100.0,
314 double voxelSize = 1.0,
315 double halfWidth = 3.0,
320 const BufferT&
buffer = BufferT());
322 template<
typename BuildT,
typename BufferT = HostBuffer>
326 double depth = 100.0,
328 double voxelSize = 1.0,
329 double halfWidth = 3.0,
334 float tolerance = -1.0
f,
335 bool ditherOn =
false,
336 const BufferT&
buffer = BufferT());
362 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
366 double depth = 100.0,
368 double voxelSize = 1.0,
369 double halfWidth = 3.0,
374 const BufferT&
buffer = BufferT());
376 template<
typename BuildT,
typename BufferT = HostBuffer>
380 double depth = 100.0,
382 double voxelSize = 1.0,
383 double halfWidth = 3.0,
388 float tolerance = -1.0
f,
389 bool ditherOn =
false,
390 const BufferT&
buffer = BufferT());
411 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
415 double voxelSize = 1.0,
416 double halfWidth = 3.0,
421 const BufferT&
buffer = BufferT());
423 template<
typename BuildT,
typename BufferT = HostBuffer>
427 double voxelSize = 1.0,
428 double halfWidth = 3.0,
433 float tolerance = -1.0
f,
434 bool ditherOn =
false,
435 const BufferT&
buffer = BufferT());
459 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
463 double voxelSize = 1.0,
464 double halfWidth = 3.0,
469 const BufferT&
buffer = BufferT());
471 template<
typename BuildT,
typename BufferT = HostBuffer>
475 double voxelSize = 1.0,
476 double halfWidth = 3.0,
481 float tolerance = -1.0
f,
482 bool ditherOn =
false,
483 const BufferT&
buffer = BufferT());
507 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
511 double depth = 100.0,
512 double thickness = 10.0,
514 double voxelSize = 1.0,
515 double halfWidth = 3.0,
520 const BufferT&
buffer = BufferT());
522 template<
typename BuildT,
typename BufferT = HostBuffer>
526 double depth = 100.0,
527 double thickness = 10.0,
529 double voxelSize = 1.0,
530 double halfWidth = 3.0,
535 float tolerance = -1.0
f,
536 bool ditherOn =
false,
537 const BufferT&
buffer = BufferT());
555 template<
typename BuildT =
float,
typename BufferT = HostBuffer>
560 double depth = 100.0,
562 double voxelSize = 1.0,
566 const BufferT&
buffer = BufferT());
579 template<
typename SrcBuildT =
float,
typename BufferT = HostBuffer>
580 inline GridHandle<BufferT>
582 int pointsPerVoxel = 1,
585 const BufferT&
buffer = BufferT());
599 template<
typename BuildT>
600 std::shared_ptr<build::Grid<BuildT>>
601 initSphere(
double radius,
607 using GridT = build::Grid<BuildT>;
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!");
617 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
618 grid->setTransform(voxelSize, origin);
621 const ValueT r0 = radius / ValueT(voxelSize), rmax = r0 + ValueT(halfWidth);
624 if (r0 < ValueT(1.5
f))
return grid;
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));
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);
636 const Range<1,int>
range(imin, imax+1, 32);
638 auto kernel = [&](
const Range<1,int> &
r) {
639 auto acc = grid->getWriteAccessor();
641 int &i = ijk[0], &
j = ijk[1], &k = ijk[2], m = 1;
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) {
649 const auto v =
Sqrt(x2y2 +
Pow2(ValueT(k) - c[2])) - r0;
650 const auto d =
v < 0 ? -
v :
v;
652 acc.setValue(ijk, ValueT(voxelSize) *
v);
654 m +=
Floor(d - halfWidth);
660 #ifdef NANOVDB_PARALLEL_PRIMITIVES
668 template<
typename BuildT>
669 std::shared_ptr<build::Grid<BuildT>>
670 initTorus(
double radius1,
677 using GridT = build::Grid<BuildT>;
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!");
689 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
690 grid->setTransform(voxelSize, origin);
693 const ValueT r1 = radius1 / ValueT(voxelSize), r2 = radius2 / ValueT(voxelSize), rmax1 = r1 + r2 + ValueT(halfWidth), rmax2 = r2 + ValueT(halfWidth);
696 if (r2 < ValueT(1.5))
return grid;
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));
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);
708 const Range<1,int>
range(imin, imax+1, 32);
709 auto kernel = [&](
const Range<1,int> &
r) {
710 auto acc = grid->getWriteAccessor();
712 int &i = ijk[0], &
j = ijk[1], &k = ijk[2], m = 1;
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) {
718 for (j = jmin; j <= jmax; j += m) {
720 const auto v =
Sqrt(x2z2 +
Pow2(ValueT(j) - c[1])) - r2;
721 const auto d =
v < 0 ? -
v :
v;
723 acc.setValue(ijk, ValueT(voxelSize) *
v);
725 m +=
Floor(d - halfWidth);
732 #ifdef NANOVDB_PARALLEL_PRIMITIVES
741 template<
typename BuildT>
742 std::shared_ptr<build::Grid<BuildT>>
743 initBox(
double width,
751 using GridT = build::Grid<BuildT>;
756 throw std::runtime_error(
"Box: width must be positive!");
758 throw std::runtime_error(
"Box: height must be positive!");
760 throw std::runtime_error(
"Box: depth must be positive!");
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!");
767 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
768 grid->setTransform(voxelSize, origin);
771 const Vec3T
r(width / (2 * ValueT(voxelSize)),
772 height / (2 * ValueT(voxelSize)),
773 depth / (2 * ValueT(voxelSize)));
776 if (r.min() < ValueT(1.5))
return grid;
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));
784 auto Pos = [](ValueT
x) {
return x > 0 ?
x : 0; };
785 auto Neg = [](ValueT
x) {
return x < 0 ?
x : 0; };
788 const BBox<Vec3T>
b(c - r - Vec3T(ValueT(halfWidth)), c + r + Vec3T(ValueT(halfWidth)));
791 const Range<1,int>
range(bbox[0][0], bbox[1][0]+1, 32);
794 auto kernel = [&](
const Range<1,int> &ra) {
795 auto acc = grid->getWriteAccessor();
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) {
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));
808 const auto d =
Abs(
v);
810 acc.setValue(p, ValueT(voxelSize) *
v);
812 m +=
Floor(d - halfWidth);
818 #ifdef NANOVDB_PARALLEL_PRIMITIVES
826 template<
typename BuildT>
827 std::shared_ptr<build::Grid<BuildT>>
828 initBBox(
double width,
837 using GridT = build::Grid<BuildT>;
842 throw std::runtime_error(
"BBox: width must be positive!");
844 throw std::runtime_error(
"BBox: height must be positive!");
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!");
853 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
854 grid->setTransform(voxelSize, origin);
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);
863 if (r.min() < ValueT(1.5) || e < ValueT(1.5))
return grid;
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));
871 auto Pos = [](ValueT
x) {
return x > 0 ?
x : 0; };
872 auto Neg = [](ValueT
x) {
return x < 0 ?
x : 0; };
875 const BBox<Vec3T>
b(c - r - Vec3T(e + ValueT(halfWidth)), c + r + Vec3T(e + ValueT(halfWidth)));
878 const Range<1,int>
range(bbox[0][0], bbox[1][0]+1, 32);
881 auto kernel = [&](
const Range<1,int> &ra) {
882 auto acc = grid->getWriteAccessor();
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) {
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));
906 const ValueT d =
Abs(v);
908 acc.setValue(p, ValueT(voxelSize) * v);
910 m +=
Floor(d - halfWidth);
916 #ifdef NANOVDB_PARALLEL_PRIMITIVES
925 template<
typename BuildT>
926 std::shared_ptr<build::Grid<BuildT>>
927 initOctahedron(
double scale,
933 using GridT = build::Grid<BuildT>;
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!");
941 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
942 grid->setTransform(voxelSize, origin);
945 const ValueT
s = scale / (2 * ValueT(voxelSize));
948 if ( s < ValueT(1.5) )
return grid;
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));
956 auto sdf = [&
s](ValueT
x, ValueT
y, ValueT
z) {
957 const ValueT d = ValueT(0.5)*(
z - y +
s);
959 return Vec3T(x, y - s,
z).length();
961 return Vec3T(x, y,
z - s).length();
963 return Vec3T(x, y - s + d,
z - d).length();
967 const BBox<Vec3T>
b(c - Vec3T(s + ValueT(halfWidth)), c + Vec3T(s + ValueT(halfWidth)));
970 const Range<1,int>
range(bbox[0][0], bbox[1][0]+1, 32);
973 auto kernel = [&](
const Range<1,int> &ra) {
974 auto acc = grid->getWriteAccessor();
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) {
983 const ValueT pz =
Abs(ValueT(p[2]) - c[2]);
984 ValueT d = px + py + pz -
s;
986 if (ValueT(3)*px < d) {
988 }
else if (ValueT(3)*py < d) {
990 }
else if (ValueT(3)*pz < d) {
997 acc.setValue(p, ValueT(voxelSize) * v);
999 m +=
Floor(d - halfWidth);
1005 #ifdef NANOVDB_PARALLEL_PRIMITIVES
1017 template<
typename BuildT,
typename BufferT>
1024 const Vec3d& origin,
1031 auto grid = initSphere<BuildT>(radius,
center, voxelSize, halfWidth, origin);
1038 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1045 template<
typename BuildT,
typename BufferT>
1053 const Vec3d& origin,
1061 auto grid = initSphere<BuildT>(radius,
center, voxelSize, halfWidth, origin);
1069 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1076 template<
typename BuildT,
typename BufferT>
1082 const Vec3d& origin,
1091 auto grid = initSphere<BuildT>(radius,
center, voxelSize, halfWidth, origin);
1100 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1107 template<
typename BuildT,
typename BufferT>
1113 const Vec3d& origin,
1120 auto grid = initSphere<BuildT>(radius,
center, voxelSize, halfWidth, origin);
1128 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1135 template<
typename BuildT,
typename BufferT>
1141 const Vec3d& origin,
1150 auto grid = initSphere<BuildT>(radius,
center, voxelSize, halfWidth, origin);
1160 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1167 template<
typename BuildT,
typename BufferT>
1173 const Vec3d& origin,
1180 assert(sphereHandle);
1181 auto* sphereGrid = sphereHandle.template grid<BuildT>();
1183 auto pointHandle =
createPointScatter(*sphereGrid, pointsPerVoxel, name, cMode, buffer);
1184 assert(pointHandle);
1190 template<
typename BuildT,
typename BufferT>
1197 const Vec3d& origin,
1204 auto grid = initTorus<BuildT>(majorRadius, minorRadius,
center, voxelSize, halfWidth, origin);
1211 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1218 template<
typename BuildT,
typename BufferT>
1225 const Vec3d& origin,
1234 auto grid = initTorus<BuildT>(majorRadius, minorRadius,
center, voxelSize, halfWidth, origin);
1243 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1250 template<
typename BuildT,
typename BufferT>
1257 const Vec3d& origin,
1264 auto grid = initTorus<BuildT>(majorRadius, minorRadius,
center, voxelSize, halfWidth, origin);
1272 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1279 template<
typename BuildT,
typename BufferT>
1286 const Vec3d& origin,
1295 auto grid = initTorus<BuildT>(majorRadius, minorRadius,
center, voxelSize, halfWidth, origin);
1305 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1312 template<
typename BuildT,
typename BufferT>
1319 const Vec3d& origin,
1324 auto torusHandle =
createLevelSetTorus(majorRadius, minorRadius, center, voxelSize, 0.5
f, origin,
1326 assert(torusHandle);
1327 auto* torusGrid = torusHandle.template grid<BuildT>();
1329 auto pointHandle =
createPointScatter(*torusGrid, pointsPerVoxel, name, cMode, buffer);
1330 assert(pointHandle);
1336 template<
typename BuildT,
typename BufferT>
1344 const Vec3d& origin,
1358 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1365 template<
typename BuildT,
typename BufferT>
1373 const Vec3d& origin,
1391 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1398 template<
typename BuildT,
typename BufferT>
1404 const Vec3d& origin,
1411 auto grid = initOctahedron<BuildT>(
scale,
center, voxelSize, halfWidth, origin);
1418 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1425 template<
typename BuildT,
typename BufferT>
1431 const Vec3d& origin,
1440 auto grid = initOctahedron<BuildT>(
scale,
center, voxelSize, halfWidth, origin);
1449 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1456 template<
typename BuildT,
typename BufferT>
1465 const Vec3d& origin,
1479 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1486 template<
typename BuildT,
typename BufferT>
1495 const Vec3d& origin,
1513 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1520 template<
typename BuildT,
typename BufferT>
1528 const Vec3d& origin,
1543 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1550 template<
typename BuildT,
typename BufferT>
1558 const Vec3d& origin,
1577 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1584 template<
typename BuildT,
typename BufferT>
1590 const Vec3d& origin,
1597 auto grid = initOctahedron<BuildT>(
scale,
center, voxelSize, halfWidth, origin);
1605 auto handle = converter.template getHandle<BuildT, BufferT>(
buffer);
1612 template<
typename BuildT,
typename BufferT>
1618 const Vec3d& origin,
1627 auto grid = initOctahedron<BuildT>(
scale,
center, voxelSize, halfWidth, origin);
1637 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle,
buffer);
1644 template<
typename BuildT,
typename BufferT>
1652 const Vec3d& origin,
1657 auto boxHandle =
createLevelSetBox(width, height, depth, center, voxelSize, 0.5, origin,
"dummy",
1660 auto* boxGrid = boxHandle.template grid<BuildT>();
1662 auto pointHandle =
createPointScatter(*boxGrid, pointsPerVoxel, name, cMode, buffer);
1663 assert(pointHandle);
1669 template<
typename SrcBuildT,
typename BufferT>
1670 inline GridHandle<BufferT>
1680 if (pointsPerVoxel < 1) {
1681 throw std::runtime_error(
"createPointScatter: Expected at least one point per voxel");
1684 throw std::runtime_error(
"createPointScatter: Expected a level set grid");
1687 throw std::runtime_error(
"createPointScatter: ActiveVoxelCount is required");
1690 if (pointCount == 0) {
1691 throw std::runtime_error(
"createPointScatter: No particles to scatter");
1693 std::vector<Vec3T> xyz;
1694 xyz.reserve(pointCount);
1697 dstGrid.mMap = srcGrid.
map();
1698 auto dstAcc = dstGrid.getAccessor();
1700 const ValueT
s = 1 / (1 + ValueT(RAND_MAX));
1702 auto randomPoint = [&
s](){
return s * Vec3T(rand(), rand(), rand()) - Vec3T(0.5);};
1703 const auto& srcTree = srcGrid.
tree();
1705 auto *srcMgr = srcMgrHandle.template mgr<SrcBuildT>();
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);
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();
1714 for (
int n = 0;
n < pointsPerVoxel; ++
n) xyz.push_back(srcGrid.
indexToWorld(randomPoint() + ijk));
1715 m += pointsPerVoxel;
1717 dstLeaf->mValues[
j] = m;
1720 assert(pointCount == xyz.size());
1725 converter.addBlindData(name,
1728 mapToGridType<Vec3T>(),
1731 auto handle = converter.template getHandle<uint32_t>(
buffer);
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;
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;
1743 if (Vec3T *blindData = grid->template getBlindData<Vec3T>(0)) {
1744 memcpy(blindData, xyz.data(), xyz.size() *
sizeof(Vec3T));
1746 throw std::runtime_error(
"Blind data pointer was NULL");
1754 #endif // NANOVDB_PRIMITIVES_H_HAS_BEEN_INCLUDED
disable_if< is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createLevelSetTorus(double majorRadius=100.0, double minorRadius=50.0, const Vec3d ¢er=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.
__hostdev__ uint64_t pointCount() const
__hostdev__ const TreeT & tree() const
Return a const reference to the tree.
Compression oracle based on absolute difference.
Creates any nanovdb Grid from any source grid (certain combinations are obviously not allowed) ...
GLsizei const GLchar *const * string
GLsizei const GLfloat * value
GLdouble GLdouble GLdouble z
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
StatsMode
Grid flags which indicate what extra information is present in the grid buffer.
GLboolean GLboolean GLboolean GLboolean a
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
disable_if< is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createLevelSetOctahedron(double scale=100.0, const Vec3d ¢er=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.
__hostdev__ bool hasBBox() const
__hostdev__ const Map & map() const
Return a const reference to the Map for this grid.
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
__hostdev__ bool isLevelSet() const
GA_API const UT_StringHolder scale
GLint GLsizei GLsizei height
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 ¢er=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.
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 ¢er=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...
__hostdev__ Type Min(Type a, Type b)
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
enable_if< is_same< float, BuildT >::value||is_same< double, BuildT >::value, GridHandle< BufferT > >::type createLevelSetSphere(double radius=100.0, const Vec3d ¢er=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.
void levelSetToFog(NodeManagerT &mgr, bool rebuild=true)
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 createFogVolumeSphere(double radius=100.0, const Vec3d ¢er=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...
void setStats(StatsMode mode=StatsMode::Default)
Set the mode used for computing statistics of the destination grid.
GLuint const GLchar * name
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 ...
GLboolean GLboolean GLboolean b
NodeManagerHandle< BufferT > createNodeManager(const NanoGrid< BuildT > &grid, const BufferT &buffer=BufferT())
brief Construct a NodeManager and return its handle
disable_if< is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createFogVolumeOctahedron(double scale=100.0, const Vec3d ¢er=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...
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 ¢er=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) ...
GLint GLint GLsizei GLsizei GLsizei depth
__hostdev__ uint64_t activeVoxelCount() const
Computes a AABB of active values in world space.
__hostdev__ Type Max(Type a, Type b)
void enableDithering(bool on=true)
Enable or disable dithering, i.e. randomization of the quantization error.
disable_if< is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createPointTorus(int pointsPerVoxel=1, double majorRadius=100.0, double minorRadius=50.0, const Vec3d ¢er=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...
ChecksumMode
List of different modes for computing for a checksum.
enable_if< is_floating_point< typename NodeManagerT::ValueType >::value >::type sdfToLevelSet(NodeManagerT &mgr)
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 ¢er=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.
__hostdev__ int32_t Ceil(float x)
__hostdev__ int32_t Floor(float x)
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
void setChecksum(ChecksumMode mode=ChecksumMode::Default)
Set the mode used for computing checksums of the destination grid.
disable_if< is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createPointSphere(int pointsPerVoxel=1, double radius=100.0, const Vec3d ¢er=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...
__hostdev__ Vec3T indexToWorld(const Vec3T &xyz) const
index to world space transformation
__hostdev__ float Sqrt(float x)
Return the square root of a floating-point value.
Convert any grid to a nanovdb grid of the same type, e.g. float->float.
C++11 implementation of std::is_floating_point.
disable_if< is_same< FpN, BuildT >::value, GridHandle< BufferT > >::type createFogVolumeTorus(double majorRadius=100.0, double minorRadius=50.0, const Vec3d ¢er=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...