16#ifndef NANOVDB_TOOLS_PRIMITIVES_H_HAS_BEEN_INCLUDED
17#define NANOVDB_TOOLS_PRIMITIVES_H_HAS_BEEN_INCLUDED
19#define NANOVDB_PARALLEL_PRIMITIVES
46template<
typename BuildT =
float,
typename BufferT = HostBuffer>
47typename util::enable_if<util::is_same<BuildT, float, double>::value, GridHandle<BufferT>>::type
50 double voxelSize = 1.0,
51 double halfWidth = 3.0,
53 const std::string& name =
"sphere_ls",
56 const BufferT& buffer = BufferT());
58template<
typename BuildT,
typename BufferT = HostBuffer>
59typename util::enable_if<util::is_same<BuildT, Fp4, Fp8, Fp16>::value, GridHandle<BufferT>>::type
62 double voxelSize = 1.0,
63 double halfWidth = 3.0,
65 const std::string& name =
"sphere_ls",
68 bool ditherOn =
false,
69 const BufferT& buffer = BufferT());
71template<
typename BuildT,
typename BufferT = HostBuffer>
72typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
75 double voxelSize = 1.0,
76 double halfWidth = 3.0,
78 const std::string& name =
"sphere_ls_FpN",
81 float tolerance = -1.0f,
82 bool ditherOn =
false,
83 const BufferT& buffer = BufferT());
107template<
typename BuildT =
float,
typename BufferT = HostBuffer>
108typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
111 double voxelSize = 1.0,
112 double halfWidth = 3.0,
114 const std::string& name =
"sphere_fog",
117 const BufferT& buffer = BufferT());
119template<
typename BuildT,
typename BufferT = HostBuffer>
120typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
123 double voxelSize = 1.0,
124 double halfWidth = 3.0,
126 const std::string& name =
"sphere_fog",
129 float tolerance = -1.0f,
130 bool ditherOn =
false,
131 const BufferT& buffer = BufferT());
148template<
typename BuildT =
float,
typename BufferT = HostBuffer>
149typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
151 double radius = 100.0,
153 double voxelSize = 1.0,
155 const std::string& name =
"sphere_points",
157 const BufferT& buffer = BufferT());
179template<
typename BuildT =
float,
typename BufferT = HostBuffer>
180typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
182 double minorRadius = 50.0,
184 double voxelSize = 1.0,
185 double halfWidth = 3.0,
187 const std::string& name =
"torus_ls",
190 const BufferT& buffer = BufferT());
192template<
typename BuildT,
typename BufferT = HostBuffer>
193typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
195 double minorRadius = 50.0,
197 double voxelSize = 1.0,
198 double halfWidth = 3.0,
200 const std::string& name =
"torus_ls",
203 float tolerance = -1.0f,
204 bool ditherOn =
false,
205 const BufferT& buffer = BufferT());
230template<
typename BuildT =
float,
typename BufferT = HostBuffer>
231typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
233 double minorRadius = 50.0,
235 double voxelSize = 1.0,
236 double halfWidth = 3.0,
238 const std::string& name =
"torus_fog",
241 const BufferT& buffer = BufferT());
243template<
typename BuildT,
typename BufferT = HostBuffer>
244typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
246 double minorRadius = 50.0,
248 double voxelSize = 1.0,
249 double halfWidth = 3.0,
251 const std::string& name =
"torus_fog_FpN",
254 float tolerance = -1.0f,
255 bool ditherOn =
false,
256 const BufferT& buffer = BufferT());
274template<
typename BuildT =
float,
typename BufferT = HostBuffer>
275typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
277 double majorRadius = 100.0,
278 double minorRadius = 50.0,
280 double voxelSize = 1.0,
282 const std::string& name =
"torus_points",
284 const BufferT& buffer = BufferT());
307template<
typename BuildT =
float,
typename BufferT = HostBuffer>
308typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
310 double height = 60.0,
311 double depth = 100.0,
313 double voxelSize = 1.0,
314 double halfWidth = 3.0,
316 const std::string& name =
"box_ls",
319 const BufferT& buffer = BufferT());
321template<
typename BuildT,
typename BufferT = HostBuffer>
322typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
324 double height = 60.0,
325 double depth = 100.0,
327 double voxelSize = 1.0,
328 double halfWidth = 3.0,
330 const std::string& name =
"box_ls_FpN",
333 float tolerance = -1.0f,
334 bool ditherOn =
false,
335 const BufferT& buffer = BufferT());
361template<
typename BuildT =
float,
typename BufferT = HostBuffer>
362typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
364 double height = 60.0,
365 double depth = 100.0,
367 double voxelSize = 1.0,
368 double halfWidth = 3.0,
370 const std::string& name =
"box_fog",
373 const BufferT& buffer = BufferT());
375template<
typename BuildT,
typename BufferT = HostBuffer>
376typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
378 double height = 60.0,
379 double depth = 100.0,
381 double voxelSize = 1.0,
382 double halfWidth = 3.0,
384 const std::string& name =
"box_fog_FpN",
387 float tolerance = -1.0f,
388 bool ditherOn =
false,
389 const BufferT& buffer = BufferT());
410template<
typename BuildT =
float,
typename BufferT = HostBuffer>
411typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
414 double voxelSize = 1.0,
415 double halfWidth = 3.0,
417 const std::string& name =
"octadedron_ls",
420 const BufferT& buffer = BufferT());
422template<
typename BuildT,
typename BufferT = HostBuffer>
423typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
426 double voxelSize = 1.0,
427 double halfWidth = 3.0,
429 const std::string& name =
"octadedron_ls_FpN",
432 float tolerance = -1.0f,
433 bool ditherOn =
false,
434 const BufferT& buffer = BufferT());
458template<
typename BuildT =
float,
typename BufferT = HostBuffer>
459typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
462 double voxelSize = 1.0,
463 double halfWidth = 3.0,
465 const std::string& name =
"octadedron_fog",
468 const BufferT& buffer = BufferT());
470template<
typename BuildT,
typename BufferT = HostBuffer>
471typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
474 double voxelSize = 1.0,
475 double halfWidth = 3.0,
477 const std::string& name =
"octadedron_fog_FpN",
480 float tolerance = -1.0f,
481 bool ditherOn =
false,
482 const BufferT& buffer = BufferT());
506template<
typename BuildT =
float,
typename BufferT = HostBuffer>
507typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
509 double height = 60.0,
510 double depth = 100.0,
511 double thickness = 10.0,
513 double voxelSize = 1.0,
514 double halfWidth = 3.0,
516 const std::string& name =
"bbox_ls",
519 const BufferT& buffer = BufferT());
521template<
typename BuildT,
typename BufferT = HostBuffer>
522typename util::enable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
524 double height = 60.0,
525 double depth = 100.0,
526 double thickness = 10.0,
528 double voxelSize = 1.0,
529 double halfWidth = 3.0,
531 const std::string& name =
"bbox_ls_FpN",
534 float tolerance = -1.0f,
535 bool ditherOn =
false,
536 const BufferT& buffer = BufferT());
554template<
typename BuildT =
float,
typename BufferT = HostBuffer>
555typename util::disable_if<util::is_same<FpN, BuildT>::value, GridHandle<BufferT>>::type
558 double height = 60.0,
559 double depth = 100.0,
561 double voxelSize = 1.0,
563 const std::string& name =
"box_points",
565 const BufferT& buffer = BufferT());
578template<
typename SrcBuildT =
float,
typename BufferT = HostBuffer>
579inline GridHandle<BufferT>
581 int pointsPerVoxel = 1,
582 const std::string& name =
"point_scatter",
584 const BufferT& buffer = BufferT());
598template<
typename BuildT>
599std::shared_ptr<build::Grid<BuildT>>
600initSphere(
double radius,
606 using GridT = build::Grid<BuildT>;
610 throw std::runtime_error(
"Sphere: radius must be positive!");
611 if (!(voxelSize > 0))
612 throw std::runtime_error(
"Sphere: voxelSize must be positive!");
613 if (!(halfWidth > 0))
614 throw std::runtime_error(
"Sphere: halfWidth must be positive!");
616 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
617 grid->setTransform(voxelSize, origin);
620 const ValueT r0 = ValueT(radius / voxelSize), rmax = r0 + ValueT(halfWidth);
623 if (r0 < ValueT(1.5f))
return grid;
626 const math::Vec3<ValueT> c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
627 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
628 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
635 const util::Range<1,int> range(imin, imax+1, 32);
637 auto kernel = [&](
const util::Range<1,int> &r) {
638 auto acc = grid->getWriteAccessor();
640 int &i = ijk[0], &j = ijk[1], &k = ijk[2], m = 1;
642 for (i = r.begin(); i < r.end(); ++i) {
644 for (j = jmin; j <= jmax; ++j) {
645 const auto x2y2 =
math::Pow2(ValueT(j) - c[1]) + x2;
646 for (k = kmin; k <= kmax; k += m) {
649 const auto d = v < 0 ? -v : v;
651 acc.setValue(ijk, ValueT(voxelSize) * v);
659#ifdef NANOVDB_PARALLEL_PRIMITIVES
667template<
typename BuildT>
668std::shared_ptr<build::Grid<BuildT>>
669initTorus(
double radius1,
676 using GridT = build::Grid<BuildT>;
680 throw std::runtime_error(
"Torus: radius2 must be positive!");
681 if (!(radius1 > radius2))
682 throw std::runtime_error(
"Torus: radius1 must be larger than radius2!");
683 if (!(voxelSize > 0))
684 throw std::runtime_error(
"Torus: voxelSize must be positive!");
685 if (!(halfWidth > 0))
686 throw std::runtime_error(
"Torus: halfWidth must be positive!");
688 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
689 grid->setTransform(voxelSize, origin);
692 const ValueT r1 = ValueT(radius1 / voxelSize), r2 = ValueT(radius2 / voxelSize), rmax1 = r1 + r2 + ValueT(halfWidth), rmax2 = r2 + ValueT(halfWidth);
695 if (r2 < ValueT(1.5))
return grid;
698 const math::Vec3<ValueT> c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
699 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
700 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
707 const util::Range<1,int> range(imin, imax+1, 32);
708 auto kernel = [&](
const util::Range<1,int> &r) {
709 auto acc = grid->getWriteAccessor();
711 int &i = ijk[0], &j = ijk[1], &k = ijk[2], m = 1;
713 for (i = r.begin(); i < r.end(); ++i) {
715 for (k = kmin; k <= kmax; ++k) {
717 for (j = jmin; j <= jmax; j += m) {
720 const auto d = v < 0 ? -v : v;
722 acc.setValue(ijk, ValueT(voxelSize) * v);
731#ifdef NANOVDB_PARALLEL_PRIMITIVES
740template<
typename BuildT>
741std::shared_ptr<build::Grid<BuildT>>
750 using GridT = build::Grid<BuildT>;
753 using Vec3T = math::Vec3<ValueT>;
755 throw std::runtime_error(
"Box: width must be positive!");
757 throw std::runtime_error(
"Box: height must be positive!");
759 throw std::runtime_error(
"Box: depth must be positive!");
761 if (!(voxelSize > 0))
762 throw std::runtime_error(
"Box: voxelSize must be positive!");
763 if (!(halfWidth > 0))
764 throw std::runtime_error(
"Box: halfWidth must be positive!");
766 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
767 grid->setTransform(voxelSize, origin);
770 const Vec3T r(width / (2 * ValueT(voxelSize)),
771 height / (2 * ValueT(voxelSize)),
772 depth / (2 * ValueT(voxelSize)));
775 if (r.min() < ValueT(1.5))
return grid;
778 const Vec3T c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
779 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
780 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
783 auto Pos = [](ValueT x) {
return x > 0 ? x : 0; };
784 auto Neg = [](ValueT x) {
return x < 0 ? x : 0; };
787 const math::BBox<Vec3T> b(c - r - Vec3T(ValueT(halfWidth)), c + r + Vec3T(ValueT(halfWidth)));
790 const util::Range<1,int> range(bbox[0][0], bbox[1][0]+1, 32);
793 auto kernel = [&](
const util::Range<1,int> &ra) {
794 auto acc = grid->getWriteAccessor();
796 for (Coord p(ra.begin(),bbox[0][1],bbox[0][2]); p[0] < ra.end(); ++p[0]) {
797 const auto q1 =
math::Abs(ValueT(p[0]) - c[0]) - r[0];
799 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
800 const auto q2 =
math::Abs(ValueT(p[1]) - c[1]) - r[1];
803 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
805 const auto q3 =
math::Abs(ValueT(p[2]) - c[2]) - r[2];
809 acc.setValue(p, ValueT(voxelSize) * v);
817#ifdef NANOVDB_PARALLEL_PRIMITIVES
825template<
typename BuildT>
826std::shared_ptr<build::Grid<BuildT>>
827initBBox(
double width,
836 using GridT = build::Grid<BuildT>;
839 using Vec3T = math::Vec3<ValueT>;
841 throw std::runtime_error(
"BBox: width must be positive!");
843 throw std::runtime_error(
"BBox: height must be positive!");
845 throw std::runtime_error(
"BBox: depth must be positive!");
846 if (!(thickness > 0))
847 throw std::runtime_error(
"BBox: thickness must be positive!");
848 if (!(voxelSize > 0.0))
849 throw std::runtime_error(
"BBox: voxelSize must be positive!");
852 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
853 grid->setTransform(voxelSize, origin);
856 const Vec3T r(width / (2 * ValueT(voxelSize)),
857 height / (2 * ValueT(voxelSize)),
858 depth / (2 * ValueT(voxelSize)));
859 const ValueT e = thickness / ValueT(voxelSize);
862 if (r.min() < ValueT(1.5) || e < ValueT(1.5))
return grid;
865 const Vec3T c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
866 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
867 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
870 auto Pos = [](ValueT x) {
return x > 0 ? x : 0; };
871 auto Neg = [](ValueT x) {
return x < 0 ? x : 0; };
874 const math::BBox<Vec3T> b(c - r - Vec3T(e + ValueT(halfWidth)), c + r + Vec3T(e + ValueT(halfWidth)));
877 const util::Range<1,int> range(bbox[0][0], bbox[1][0]+1, 32);
880 auto kernel = [&](
const util::Range<1,int> &ra) {
881 auto acc = grid->getWriteAccessor();
883 for (Coord p(ra.begin(),bbox[0][1],bbox[0][2]); p[0] < ra.end(); ++p[0]) {
884 const ValueT px =
math::Abs(ValueT(p[0]) - c[0]) - r[0];
885 const ValueT qx =
math::Abs(ValueT(px) + e) - e;
888 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
889 const ValueT py =
math::Abs(ValueT(p[1]) - c[1]) - r[1];
890 const ValueT qy =
math::Abs(ValueT(py) + e) - e;
892 const ValueT px2qy2 = px2 + qy2;
893 const ValueT qx2py2 = qx2 +
math::Pow2(Pos(py));
894 const ValueT qx2qy2 = qx2 + qy2;
896 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
898 const ValueT pz =
math::Abs(ValueT(p[2]) - c[2]) - r[2];
899 const ValueT qz =
math::Abs(ValueT(pz) + e) - e;
907 acc.setValue(p, ValueT(voxelSize) * v);
915#ifdef NANOVDB_PARALLEL_PRIMITIVES
924template<
typename BuildT>
925std::shared_ptr<build::Grid<BuildT>>
926initOctahedron(
double scale,
932 using GridT = build::Grid<BuildT>;
934 using Vec3T = math::Vec3<ValueT>;
937 if (!(scale > 0))
throw std::runtime_error(
"Octahedron: width must be positive!");
938 if (!(voxelSize > 0))
throw std::runtime_error(
"Octahedron: voxelSize must be positive!");
940 auto grid = std::make_shared<GridT>(ValueT(halfWidth * voxelSize));
941 grid->setTransform(voxelSize, origin);
944 const ValueT s = scale / (2 * ValueT(voxelSize));
947 if ( s < ValueT(1.5) )
return grid;
950 const Vec3T c(ValueT(center[0] - origin[0]) / ValueT(voxelSize),
951 ValueT(center[1] - origin[1]) / ValueT(voxelSize),
952 ValueT(center[2] - origin[2]) / ValueT(voxelSize));
955 auto sdf = [&s](ValueT x, ValueT y, ValueT z) {
956 const ValueT d = ValueT(0.5)*(z - y + s);
958 return Vec3T(x, y - s, z).length();
960 return Vec3T(x, y, z - s).length();
962 return Vec3T(x, y - s + d, z - d).length();
966 const math::BBox<Vec3T> b(c - Vec3T(s + ValueT(halfWidth)), c + Vec3T(s + ValueT(halfWidth)));
969 const util::Range<1,int> range(bbox[0][0], bbox[1][0]+1, 32);
972 auto kernel = [&](
const util::Range<1,int> &ra) {
973 auto acc = grid->getWriteAccessor();
975 static const ValueT a =
math::Sqrt(ValueT(1)/ValueT(3));
976 for (Coord p(ra.begin(),bbox[0][1],bbox[0][2]); p[0] < ra.end(); ++p[0]) {
977 const ValueT px =
math::Abs(ValueT(p[0]) - c[0]);
978 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
979 const ValueT py =
math::Abs(ValueT(p[1]) - c[1]);
980 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
982 const ValueT pz =
math::Abs(ValueT(p[2]) - c[2]);
983 ValueT d = px + py + pz - s;
985 if (ValueT(3)*px < d) {
987 }
else if (ValueT(3)*py < d) {
989 }
else if (ValueT(3)*pz < d) {
996 acc.setValue(p, ValueT(voxelSize) * v);
1004#ifdef NANOVDB_PARALLEL_PRIMITIVES
1016template<
typename BuildT,
typename BufferT>
1017typename util::enable_if<util::is_same<BuildT, float, double>::value, GridHandle<BufferT>>::type
1019 const Vec3d& center,
1022 const Vec3d& origin,
1023 const std::string& name,
1026 const BufferT& buffer)
1029 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1036 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1043template<
typename BuildT,
typename BufferT>
1046 const Vec3d& center,
1049 const Vec3d& origin,
1050 const std::string& name,
1054 const BufferT& buffer)
1057 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1065 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1072template<
typename BuildT,
typename BufferT>
1075 const Vec3d& center,
1078 const Vec3d& origin,
1079 const std::string& name,
1084 const BufferT& buffer)
1087 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1096 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1103template<
typename BuildT,
typename BufferT>
1106 const Vec3d& center,
1109 const Vec3d& origin,
1110 const std::string& name,
1113 const BufferT& buffer)
1116 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1124 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1131template<
typename BuildT,
typename BufferT>
1134 const Vec3d& center,
1137 const Vec3d& origin,
1138 const std::string& name,
1143 const BufferT& buffer)
1146 auto grid = initSphere<BuildT>(radius, center, voxelSize, halfWidth, origin);
1156 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1163template<
typename BuildT,
typename BufferT>
1167 const Vec3d& center,
1169 const Vec3d& origin,
1170 const std::string& name,
1172 const BufferT& buffer)
1176 assert(sphereHandle);
1177 auto* sphereGrid = sphereHandle.template grid<BuildT>();
1179 auto pointHandle =
createPointScatter(*sphereGrid, pointsPerVoxel, name, cMode, buffer);
1180 assert(pointHandle);
1186template<
typename BuildT,
typename BufferT>
1190 const Vec3d& center,
1193 const Vec3d& origin,
1194 const std::string& name,
1197 const BufferT& buffer)
1200 auto grid = initTorus<BuildT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
1207 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1214template<
typename BuildT,
typename BufferT>
1218 const Vec3d& center,
1221 const Vec3d& origin,
1222 const std::string& name,
1227 const BufferT& buffer)
1230 auto grid = initTorus<BuildT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
1239 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1246template<
typename BuildT,
typename BufferT>
1250 const Vec3d& center,
1253 const Vec3d& origin,
1254 const std::string& name,
1257 const BufferT& buffer)
1260 auto grid = initTorus<BuildT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
1268 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1275template<
typename BuildT,
typename BufferT>
1279 const Vec3d& center,
1282 const Vec3d& origin,
1283 const std::string& name,
1288 const BufferT& buffer)
1291 auto grid = initTorus<BuildT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
1301 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1308template<
typename BuildT,
typename BufferT>
1313 const Vec3d& center,
1315 const Vec3d& origin,
1316 const std::string& name,
1318 const BufferT& buffer)
1320 auto torusHandle =
createLevelSetTorus(majorRadius, minorRadius, center, voxelSize, 0.5f, origin,
1322 assert(torusHandle);
1323 auto* torusGrid = torusHandle.template grid<BuildT>();
1325 auto pointHandle =
createPointScatter(*torusGrid, pointsPerVoxel, name, cMode, buffer);
1326 assert(pointHandle);
1332template<
typename BuildT,
typename BufferT>
1337 const Vec3d& center,
1340 const Vec3d& origin,
1341 const std::string& name,
1344 const BufferT& buffer)
1347 auto grid = initBox<BuildT>(width, height, depth, center, voxelSize, halfWidth, origin);
1354 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1361template<
typename BuildT,
typename BufferT>
1366 const Vec3d& center,
1369 const Vec3d& origin,
1370 const std::string& name,
1375 const BufferT& buffer)
1378 auto grid = initBox<BuildT>(width, height, depth, center, voxelSize, halfWidth, origin);
1387 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1394template<
typename BuildT,
typename BufferT>
1397 const Vec3d& center,
1400 const Vec3d& origin,
1401 const std::string& name,
1404 const BufferT& buffer)
1407 auto grid = initOctahedron<BuildT>(scale, center, voxelSize, halfWidth, origin);
1414 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1421template<
typename BuildT,
typename BufferT>
1424 const Vec3d& center,
1427 const Vec3d& origin,
1428 const std::string& name,
1433 const BufferT& buffer)
1436 auto grid = initOctahedron<BuildT>(scale, center, voxelSize, halfWidth, origin);
1445 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1452template<
typename BuildT,
typename BufferT>
1458 const Vec3d& center,
1461 const Vec3d& origin,
1462 const std::string& name,
1465 const BufferT& buffer)
1468 auto grid = initBBox<BuildT>(width, height, depth, thickness, center, voxelSize, halfWidth, origin);
1475 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1482template<
typename BuildT,
typename BufferT>
1488 const Vec3d& center,
1491 const Vec3d& origin,
1492 const std::string& name,
1497 const BufferT& buffer)
1500 auto grid = initBBox<BuildT>(width, height, depth, thickness, center, voxelSize, halfWidth, origin);
1509 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1516template<
typename BuildT,
typename BufferT>
1521 const Vec3d& center,
1524 const Vec3d& origin,
1525 const std::string& name,
1528 const BufferT& buffer)
1531 auto grid = initBox<BuildT>(width, height, depth, center, voxelSize, halfWidth, origin);
1539 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1546template<
typename BuildT,
typename BufferT>
1551 const Vec3d& center,
1554 const Vec3d& origin,
1555 const std::string& name,
1560 const BufferT& buffer)
1563 auto grid = initBox<BuildT>(width, height, depth, center, voxelSize, halfWidth, origin);
1573 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1580template<
typename BuildT,
typename BufferT>
1583 const Vec3d& center,
1586 const Vec3d& origin,
1587 const std::string& name,
1590 const BufferT& buffer)
1593 auto grid = initOctahedron<BuildT>(scale, center, voxelSize, halfWidth, origin);
1601 auto handle = converter.template getHandle<BuildT, BufferT>(buffer);
1608template<
typename BuildT,
typename BufferT>
1611 const Vec3d& center,
1614 const Vec3d& origin,
1615 const std::string& name,
1620 const BufferT& buffer)
1623 auto grid = initOctahedron<BuildT>(scale, center, voxelSize, halfWidth, origin);
1633 auto handle = converter.template getHandle<BuildT, AbsDiff, BufferT>(oracle, buffer);
1640template<
typename BuildT,
typename BufferT>
1646 const Vec3d& center,
1648 const Vec3d& origin,
1649 const std::string& name,
1651 const BufferT& buffer)
1653 auto boxHandle =
createLevelSetBox(width, height, depth, center, voxelSize, 0.5, origin,
"dummy",
1656 auto* boxGrid = boxHandle.template grid<BuildT>();
1658 auto pointHandle =
createPointScatter(*boxGrid, pointsPerVoxel, name, cMode, buffer);
1659 assert(pointHandle);
1665template<
typename SrcBuildT,
typename BufferT>
1669 const std::string& name,
1671 const BufferT& buffer)
1676 if (pointsPerVoxel < 1) {
1677 throw std::runtime_error(
"createPointScatter: Expected at least one point per voxel");
1680 throw std::runtime_error(
"createPointScatter: Expected a level set grid");
1683 throw std::runtime_error(
"createPointScatter: ActiveVoxelCount is required");
1686 if (pointCount == 0) {
1687 throw std::runtime_error(
"createPointScatter: No particles to scatter");
1689 std::vector<Vec3T> xyz;
1690 xyz.reserve(pointCount);
1693 dstGrid.mMap = srcGrid.
map();
1694 auto dstAcc = dstGrid.getAccessor();
1696 const ValueT s = 1 / (1 + ValueT(RAND_MAX));
1698 auto randomPoint = [&s](){
return s * Vec3T(rand(), rand(), rand()) - Vec3T(0.5);};
1699 const auto& srcTree = srcGrid.
tree();
1701 auto *srcMgr = srcMgrHandle.template mgr<SrcBuildT>();
1703 for (uint32_t i = 0, end = srcTree.nodeCount(0); i < end; ++i) {
1704 auto& srcLeaf = srcMgr->leaf(i);
1705 auto* dstLeaf = dstAcc.setValue(srcLeaf.origin(), pointsPerVoxel);
1706 dstLeaf->mValueMask = srcLeaf.valueMask();
1707 for (uint32_t j = 0, m = 0; j < 512; ++j) {
1708 if (dstLeaf->mValueMask.isOn(j)) {
1709 const Vec3f ijk = dstLeaf->offsetToGlobalCoord(j).asVec3s();
1710 for (
int n = 0; n < pointsPerVoxel; ++n) xyz.push_back(srcGrid.
indexToWorld(randomPoint() + ijk));
1711 m += pointsPerVoxel;
1713 dstLeaf->mValues[j] = m;
1716 assert(pointCount == xyz.size());
1727 auto handle = converter.template getHandle<uint32_t>(buffer);
1730 auto* grid = handle.template grid<uint32_t>();
1731 assert(grid && grid->template isSequential<0>());
1732 auto &tree = grid->tree();
1733 if (tree.nodeCount(0) == 0)
throw std::runtime_error(
"Expect leaf nodes!");
1734 auto *leafData = tree.getFirstLeaf()->data();
1735 leafData[0].mMinimum = 0;
1736 for (uint32_t i = 1, n = tree.nodeCount(0); i < n; ++i) {
1737 leafData[i].mMinimum = leafData[i - 1].mMinimum + leafData[i - 1].mMaximum;
1739 if (Vec3T *blindData = grid->template getBlindData<Vec3T>(0)) {
1740 memcpy(blindData, xyz.data(), xyz.size() *
sizeof(Vec3T));
1742 throw std::runtime_error(
"Blind data pointer was NULL");
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
This class serves to manage a buffer containing one or more NanoVDB Grids.
Definition GridHandle.h:109
Vec3T indexToWorld(const Vec3T &xyz) const
index to world space transformation
Definition NanoVDB.h:2256
uint64_t activeVoxelCount() const
Computes a AABB of active values in world space.
Definition NanoVDB.h:2306
const TreeT & tree() const
Return a const reference to the tree.
Definition NanoVDB.h:2236
const Map & map() const
Return a const reference to the Map for this grid.
Definition NanoVDB.h:2248
bool hasBBox() const
Definition NanoVDB.h:2322
bool isLevelSet() const
Definition NanoVDB.h:2312
A simple vector class with three components, similar to openvdb::math::Vec3.
Definition Math.h:1362
__hostdev__ T Abs(T x)
Definition Math.h:229
__hostdev__ int32_t Floor(float x)
Definition Math.h:193
__hostdev__ T Pow2(T x)
Definition Math.h:212
__hostdev__ Type Max(Type a, Type b)
Definition Math.h:154
__hostdev__ int32_t Ceil(float x)
Definition Math.h:202
__hostdev__ float Sqrt(float x)
Return the square root of a floating-point value.
Definition Math.h:277
__hostdev__ Type Min(Type a, Type b)
Definition Math.h:133
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition ForEach.h:42
Defines a simple memory pool used to call cub functions that use dynamic temporary storage.
Definition GridHandle.h:31
GridType toGridType()
Maps from a templated build type to a GridType enum.
Definition NanoVDB.h:851
Grid< NanoTree< BuildT > > NanoGrid
Definition NanoVDB.h:4742
math::Vec3< float > Vec3f
Definition Math.h:2230
@ PointData
Definition NanoVDB.h:293
CheckMode
List of different modes for computing for a checksum.
Definition NanoVDB.h:1846
@ Default
Definition NanoVDB.h:1850
@ Disable
Definition NanoVDB.h:1846
@ AttributeArray
Definition NanoVDB.h:412
math::Vec3< double > Vec3d
Definition Math.h:2229
math::BBox< Coord > CoordBBox
Definition Math.h:2241
@ WorldCoords
Definition NanoVDB.h:425
NodeManagerHandle< BufferT > createNodeManager(const NanoGrid< BuildT > &grid, const BufferT &buffer=BufferT())
brief Construct a NodeManager and return its handle
Definition NodeManager.h:307
T type
Definition NanoVDB.h:528
C++11 implementation of std::enable_if.
Definition Util.h:353
static constexpr bool value
Definition Util.h:344