16 #ifndef NANOVDB_PRIMITIVES_H_HAS_BEEN_INCLUDED 17 #define NANOVDB_PRIMITIVES_H_HAS_BEEN_INCLUDED 41 template<
typename ValueT = float,
42 typename VoxelT = ValueT,
43 typename BufferT = HostBuffer>
46 const Vec3<ValueT>& center = Vec3<ValueT>(0),
47 double voxelSize = 1.0,
48 double halfWidth = 3.0,
50 const std::string& name =
"sphere_ls",
53 float tolerance = -1.0f,
54 bool ditherOn =
false,
55 const BufferT& buffer = BufferT());
80 template<
typename ValueT = float,
81 typename VoxelT = ValueT,
82 typename BufferT = HostBuffer>
85 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
86 double voxelSize = 1.0f,
87 double halfWidth = 3.0f,
89 const std::string& name =
"sphere_fog",
92 float tolerance = -1.0f,
93 bool ditherOn =
false,
94 const BufferT& buffer = BufferT());
111 template<
typename ValueT = float,
112 typename BufferT = HostBuffer>
113 inline GridHandle<BufferT>
115 ValueT radius = 100.0f,
116 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
117 double voxelSize = 1.0f,
119 const std::string& name =
"sphere_points",
121 const BufferT& buffer = BufferT());
144 template<
typename ValueT = float,
145 typename VoxelT = ValueT,
146 typename BufferT = HostBuffer>
149 ValueT minorRadius = 50.0f,
150 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
151 double voxelSize = 1.0,
152 double halfWidth = 3.0,
154 const std::string& name =
"torus_ls",
157 float tolerance = -1.0f,
158 bool ditherOn =
false,
159 const BufferT& buffer = BufferT());
185 template<
typename ValueT = float,
186 typename VoxelT = ValueT,
187 typename BufferT = HostBuffer>
190 ValueT minorRadius = 50.0f,
191 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
192 double voxelSize = 1.0,
193 double halfWidth = 3.0,
195 const std::string& name =
"torus_fog",
198 float tolerance = -1.0f,
199 bool ditherOn =
false,
200 const BufferT& buffer = BufferT());
218 template<
typename ValueT = float,
219 typename BufferT = HostBuffer>
220 inline GridHandle<BufferT>
222 ValueT majorRadius = 100.0f,
223 ValueT minorRadius = 50.0f,
224 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
225 double voxelSize = 1.0,
227 const std::string& name =
"torus_points",
229 const BufferT& buffer = BufferT());
253 template<
typename ValueT = float,
254 typename VoxelT = ValueT,
255 typename BufferT = HostBuffer>
258 ValueT height = 60.0f,
259 ValueT depth = 100.0f,
260 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
261 double voxelSize = 1.0,
262 double halfWidth = 3.0,
264 const std::string& name =
"box_ls",
267 float tolerance = -1.0f,
268 bool ditherOn =
false,
269 const BufferT& buffer = BufferT());
296 template<
typename ValueT = float,
297 typename VoxelT = ValueT,
298 typename BufferT = HostBuffer>
301 ValueT height = 60.0f,
302 ValueT depth = 100.0f,
303 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
304 double voxelSize = 1.0,
305 double halfWidth = 3.0,
307 const std::string& name =
"box_fog",
310 float tolerance = -1.0f,
311 bool ditherOn =
false,
312 const BufferT& buffer = BufferT());
334 template<
typename ValueT = float,
335 typename VoxelT = ValueT,
336 typename BufferT = HostBuffer>
339 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
340 double voxelSize = 1.0,
341 double halfWidth = 3.0,
343 const std::string& name =
"octadedron_ls",
346 float tolerance = -1.0f,
347 bool ditherOn =
false,
348 const BufferT& buffer = BufferT());
373 template<
typename ValueT = float,
374 typename VoxelT = ValueT,
375 typename BufferT = HostBuffer>
378 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
379 double voxelSize = 1.0,
380 double halfWidth = 3.0,
382 const std::string& name =
"octadedron_fog",
385 float tolerance = -1.0f,
386 bool ditherOn =
false,
387 const BufferT& buffer = BufferT());
412 template<
typename ValueT = float,
413 typename VoxelT = ValueT,
414 typename BufferT = HostBuffer>
417 ValueT height = 60.0f,
418 ValueT depth = 100.0f,
419 ValueT thickness = 10.0f,
420 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
421 double voxelSize = 1.0,
422 double halfWidth = 3.0,
424 const std::string& name =
"bbox_ls",
427 float tolerance = -1.0f,
428 bool ditherOn =
false,
429 const BufferT& buffer = BufferT());
447 template<
typename ValueT = float,
448 typename BufferT = HostBuffer>
449 inline GridHandle<BufferT>
451 ValueT width = 40.0f,
452 ValueT height = 60.0f,
453 ValueT depth = 100.0f,
454 const Vec3<ValueT>& center = Vec3<ValueT>(0.0f),
455 double voxelSize = 1.0,
457 const std::string& name =
"box_points",
459 const BufferT& buffer = BufferT());
471 template<
typename ValueT = float,
472 typename BufferT = HostBuffer>
473 inline GridHandle<BufferT>
475 int pointsPerVoxel = 1,
476 const std::string& name =
"point_scatter",
478 const BufferT& buffer = BufferT());
492 template<
typename ValueT,
typename VoxelT>
493 std::shared_ptr<GridBuilder<ValueT, VoxelT>>
494 initSphere(ValueT radius,
495 const Vec3<ValueT>& center,
503 throw std::runtime_error(
"Sphere: radius must be positive!");
504 if (!(voxelSize > 0))
505 throw std::runtime_error(
"Sphere: voxelSize must be positive!");
506 if (!(halfWidth > 0))
507 throw std::runtime_error(
"Sphere: halfWidth must be positive!");
509 auto builder = std::make_shared<GridBuilder<ValueT, VoxelT>>(ValueT(halfWidth * voxelSize));
510 auto acc = builder->getAccessor();
513 const ValueT r0 = radius / voxelSize, rmax = r0 + halfWidth;
516 if (r0 < ValueT(1.5f)) {
521 const Vec3<ValueT> c(ValueT(center[0] - origin[0]) / voxelSize,
522 ValueT(center[1] - origin[1]) / voxelSize,
523 ValueT(center[2] - origin[2]) / voxelSize);
526 const int imin =
Floor(c[0] - rmax), imax =
Ceil(c[0] + rmax);
527 const int jmin =
Floor(c[1] - rmax), jmax =
Ceil(c[1] + rmax);
528 const int kmin =
Floor(c[2] - rmax), kmax =
Ceil(c[2] + rmax);
531 int & i = ijk[0], &j = ijk[1], &k = ijk[2], m = 1;
533 for (i = imin; i <= imax; ++i) {
534 const auto x2 =
Pow2(ValueT(i) - c[0]);
535 for (j = jmin; j <= jmax; ++j) {
536 const auto x2y2 =
Pow2(ValueT(j) - c[1]) + x2;
537 for (k = kmin; k <= kmax; k += m) {
539 const auto v =
Sqrt(x2y2 +
Pow2(ValueT(k) - c[2])) - r0;
540 const auto d = v < 0 ? -v : v;
542 acc.setValue(ijk, voxelSize * v);
544 m +=
Floor(d - halfWidth);
553 template<
typename ValueT,
typename VoxelT>
554 std::shared_ptr<GridBuilder<ValueT, VoxelT>>
555 initTorus(ValueT radius1,
557 const Vec3<ValueT>& center,
565 throw std::runtime_error(
"Torus: radius2 must be positive!");
566 if (!(radius1 > radius2))
567 throw std::runtime_error(
"Torus: radius1 must be larger than radius2!");
568 if (!(voxelSize > 0))
569 throw std::runtime_error(
"Torus: voxelSize must be positive!");
570 if (!(halfWidth > 0))
571 throw std::runtime_error(
"Torus: halfWidth must be positive!");
573 auto builder = std::make_shared<GridBuilder<ValueT, VoxelT>>(ValueT(halfWidth * voxelSize));
574 auto acc = builder->getAccessor();
577 const ValueT r1 = radius1 / voxelSize, r2 = radius2 / voxelSize, rmax1 = r1 + r2 + halfWidth, rmax2 = r2 + halfWidth;
580 if (r2 < ValueT(1.5))
584 const Vec3<ValueT> c(ValueT(center[0] - origin[0]) / voxelSize,
585 ValueT(center[1] - origin[1]) / voxelSize,
586 ValueT(center[2] - origin[2]) / voxelSize);
589 const int imin =
Floor(c[0] - rmax1), imax =
Ceil(c[0] + rmax1);
590 const int jmin =
Floor(c[1] - rmax2), jmax =
Ceil(c[1] + rmax2);
591 const int kmin =
Floor(c[2] - rmax1), kmax =
Ceil(c[2] + rmax1);
594 int & i = ijk[0], &j = ijk[1], &k = ijk[2], m = 1;
596 for (i = imin; i <= imax; ++i) {
597 const auto x2 =
Pow2(ValueT(i) - c[0]);
598 for (k = kmin; k <= kmax; ++k) {
599 const auto x2z2 =
Pow2(
Sqrt(
Pow2(ValueT(k) - c[2]) + x2) - r1);
600 for (j = jmin; j <= jmax; j += m) {
602 const auto v =
Sqrt(x2z2 +
Pow2(ValueT(j) - c[1])) - r2;
603 const auto d = v < 0 ? -v : v;
605 acc.setValue(ijk, voxelSize * v);
607 m +=
Floor(d - halfWidth);
616 template<
typename ValueT,
typename VoxelT>
617 std::shared_ptr<GridBuilder<ValueT, VoxelT>>
618 initBox(ValueT width,
621 const Vec3<ValueT>& center,
628 using Vec3T = Vec3<ValueT>;
630 throw std::runtime_error(
"Box: width must be positive!");
632 throw std::runtime_error(
"Box: height must be positive!");
634 throw std::runtime_error(
"Box: depth must be positive!");
636 if (!(voxelSize > 0))
637 throw std::runtime_error(
"Box: voxelSize must be positive!");
638 if (!(halfWidth > 0))
639 throw std::runtime_error(
"Box: halfWidth must be positive!");
641 auto builder = std::make_shared<GridBuilder<ValueT, VoxelT>>(ValueT(halfWidth * voxelSize));
642 auto acc = builder->getAccessor();
645 const Vec3T r(width / (2 * voxelSize), height / (2 * voxelSize), depth / (2 * voxelSize));
648 if (r.min() < ValueT(1.5))
652 const Vec3T c(ValueT(center[0] - origin[0]) / voxelSize,
653 ValueT(center[1] - origin[1]) / voxelSize,
654 ValueT(center[2] - origin[2]) / voxelSize);
657 auto Pos = [](ValueT x) {
return x > 0 ? x : 0; };
658 auto Neg = [](ValueT x) {
return x < 0 ? x : 0; };
661 const BBox<Vec3T> b(c - r - Vec3T(halfWidth), c + r + Vec3T(halfWidth));
667 for (Coord p = bbox[0]; p[0] <= bbox[1][0]; ++p[0]) {
668 const auto q1 =
Abs(ValueT(p[0]) - c[0]) - r[0];
669 const auto x2 =
Pow2(Pos(q1));
670 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
671 const auto q2 =
Abs(ValueT(p[1]) - c[1]) - r[1];
672 const auto q0 =
Max(q1, q2);
673 const auto x2y2 = x2 +
Pow2(Pos(q2));
674 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
676 const auto q3 =
Abs(ValueT(p[2]) - c[2]) - r[2];
677 const auto v =
Sqrt(x2y2 +
Pow2(Pos(q3))) + Neg(
Max(q0, q3));
678 const auto d =
Abs(v);
680 acc.setValue(p, voxelSize * v);
682 m +=
Floor(d - halfWidth);
691 template<
typename ValueT,
typename VoxelT>
692 std::shared_ptr<GridBuilder<ValueT, VoxelT>>
693 initBBox(ValueT width,
697 const Vec3<ValueT>& center,
704 using Vec3T = Vec3<ValueT>;
706 throw std::runtime_error(
"BBox: width must be positive!");
708 throw std::runtime_error(
"BBox: height must be positive!");
710 throw std::runtime_error(
"BBox: depth must be positive!");
711 if (!(thickness > 0))
712 throw std::runtime_error(
"BBox: thickness must be positive!");
713 if (!(voxelSize > 0.0))
714 throw std::runtime_error(
"BBox: voxelSize must be positive!");
716 auto builder = std::make_shared<GridBuilder<ValueT, VoxelT>>(ValueT(halfWidth * voxelSize));
717 auto acc = builder->getAccessor();
720 const Vec3T r(width / (2 * voxelSize), height / (2 * voxelSize), depth / (2 * voxelSize));
721 const ValueT e = thickness / voxelSize;
724 if (r.min() < ValueT(1.5) || e < ValueT(1.5))
728 const Vec3T c(ValueT(center[0] - origin[0]) / voxelSize,
729 ValueT(center[1] - origin[1]) / voxelSize,
730 ValueT(center[2] - origin[2]) / voxelSize);
733 auto Pos = [](ValueT x) {
return x > 0 ? x : 0; };
734 auto Neg = [](ValueT x) {
return x < 0 ? x : 0; };
737 const BBox<Vec3T> b(c - r - Vec3T(e + halfWidth), c + r + Vec3T(e + halfWidth));
743 for (Coord p = bbox[0]; p[0] <= bbox[1][0]; ++p[0]) {
744 const ValueT px =
Abs(ValueT(p[0]) - c[0]) - r[0];
745 const ValueT qx =
Abs(ValueT(px) + e) - e;
746 const ValueT px2 =
Pow2(Pos(px));
747 const ValueT qx2 =
Pow2(Pos(qx));
748 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
749 const ValueT py =
Abs(ValueT(p[1]) - c[1]) - r[1];
750 const ValueT qy =
Abs(ValueT(py) + e) - e;
751 const ValueT qy2 =
Pow2(Pos(qy));
753 const ValueT px2qy2 = px2 + qy2;
754 const ValueT qx2py2 = qx2 +
Pow2(Pos(py));
755 const ValueT qx2qy2 = qx2 + qy2;
756 const ValueT a[3] = {
Max(px, qy),
Max(qx, py),
Max(qx, qy)};
757 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
759 const ValueT pz =
Abs(ValueT(p[2]) - c[2]) - r[2];
760 const ValueT qz =
Abs(ValueT(pz) + e) - e;
761 const ValueT qz2 =
Pow2(Pos(qz));
762 const ValueT s1 =
Sqrt(px2qy2 + qz2) + Neg(
Max(a[0], qz));
763 const ValueT s2 =
Sqrt(qx2py2 + qz2) + Neg(
Max(a[1], qz));
764 const ValueT s3 =
Sqrt(qx2qy2 +
Pow2(Pos(pz))) + Neg(
Max(a[2], pz));
765 const ValueT v =
Min(s1,
Min(s2, s3));
766 const ValueT d =
Abs(v);
768 acc.setValue(p, voxelSize * v);
770 m +=
Floor(d - halfWidth);
779 template<
typename ValueT,
typename VoxelT>
780 std::shared_ptr<GridBuilder<ValueT, VoxelT>>
781 initOctahedron(ValueT
scale,
782 const Vec3<ValueT>& center,
789 using Vec3T = Vec3<ValueT>;
791 throw std::runtime_error(
"Octahedron: width must be positive!");
792 if (!(voxelSize > 0))
793 throw std::runtime_error(
"Octahedron: voxelSize must be positive!");
795 auto builder = std::make_shared<GridBuilder<ValueT>>(halfWidth * voxelSize);
796 auto acc = builder->getAccessor();
799 const ValueT s = scale / (2 * voxelSize);
802 if ( s < ValueT(1.5) )
806 const Vec3T c(ValueT(center[0] - origin[0]) / voxelSize,
807 ValueT(center[1] - origin[1]) / voxelSize,
808 ValueT(center[2] - origin[2]) / voxelSize);
811 auto sdf = [&s](ValueT x, ValueT y, ValueT z) {
812 const ValueT d = ValueT(0.5)*(z - y + s);
814 return Vec3T(x, y - s, z).length();
816 return Vec3T(x, y, z - s).length();
818 return Vec3T(x, y - s + d, z - d).length();
822 const BBox<Vec3T> b(c - Vec3T(s + halfWidth), c + Vec3T(s + halfWidth));
828 static const ValueT a =
Sqrt(ValueT(1)/ValueT(3));
829 for (Coord p = bbox[0]; p[0] <= bbox[1][0]; ++p[0]) {
830 const ValueT px =
Abs(ValueT(p[0]) - c[0]);
831 for (p[1] = bbox[0][1]; p[1] <= bbox[1][1]; ++p[1]) {
832 const ValueT py =
Abs(ValueT(p[1]) - c[1]);
833 for (p[2] = bbox[0][2]; p[2] <= bbox[1][2]; p[2] += m) {
835 const ValueT pz =
Abs(ValueT(p[2]) - c[2]);
836 ValueT d = px + py + pz - s;
838 if (ValueT(3)*px < d) {
840 }
else if (ValueT(3)*py < d) {
842 }
else if (ValueT(3)*pz < d) {
849 acc.setValue(p, voxelSize * v);
851 m +=
Floor(d - halfWidth);
864 template<
typename ValueT,
typename VoxelT,
typename BufferT>
865 inline GridHandle<BufferT>
871 const std::string& name,
876 const BufferT& buffer)
878 auto builder = initSphere<ValueT, VoxelT>(radius, center, voxelSize, halfWidth, origin);
879 builder->sdfToLevelSet();
880 builder->setStats(sMode);
881 builder->setChecksum(cMode);
882 builder->enableDithering(ditherOn);
884 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
891 template<
typename ValueT,
typename VoxelT,
typename BufferT>
898 const std::string& name,
903 const BufferT& buffer)
905 auto builder = initSphere<ValueT, VoxelT>(radius, center, voxelSize, halfWidth, origin);
907 builder->setStats(sMode);
908 builder->setChecksum(cMode);
909 builder->enableDithering(ditherOn);
911 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
918 template<
typename ValueT,
typename BufferT>
925 const std::string& name,
927 const BufferT& buffer)
931 assert(sphereHandle);
932 auto* sphereGrid = sphereHandle.template grid<ValueT>();
934 auto pointHandle =
createPointScatter(*sphereGrid, pointsPerVoxel, name, cMode, buffer);
941 template<
typename ValueT,
typename VoxelT,
typename BufferT>
949 const std::string& name,
954 const BufferT& buffer)
956 auto builder = initTorus<ValueT, VoxelT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
957 builder->sdfToLevelSet();
958 builder->setStats(sMode);
959 builder->setChecksum(cMode);
960 builder->enableDithering(ditherOn);
962 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
969 template<
typename ValueT,
typename VoxelT,
typename BufferT>
977 const std::string& name,
982 const BufferT& buffer)
984 auto builder = initTorus<ValueT, VoxelT>(majorRadius, minorRadius, center, voxelSize, halfWidth, origin);
986 builder->setStats(sMode);
987 builder->setChecksum(cMode);
988 builder->enableDithering(ditherOn);
990 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
997 template<
typename ValueT,
typename BufferT>
1004 const Vec3d& origin,
1005 const std::string& name,
1007 const BufferT& buffer)
1009 auto torusHandle =
createLevelSetTorus(majorRadius, minorRadius, center, voxelSize, 0.5f, origin,
1011 assert(torusHandle);
1012 auto* torusGrid = torusHandle.template grid<ValueT>();
1014 auto pointHandle =
createPointScatter(*torusGrid, pointsPerVoxel, name, cMode, buffer);
1015 assert(pointHandle);
1021 template<
typename ValueT,
typename VoxelT,
typename BufferT>
1029 const Vec3d& origin,
1030 const std::string& name,
1035 const BufferT& buffer)
1037 auto builder = initBox<ValueT, VoxelT>(width, height, depth, center, voxelSize, halfWidth, origin);
1038 builder->sdfToLevelSet();
1039 builder->setStats(sMode);
1040 builder->setChecksum(cMode);
1041 builder->enableDithering(ditherOn);
1043 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
1050 template<
typename ValueT,
typename VoxelT,
typename BufferT>
1056 const Vec3d& origin,
1057 const std::string& name,
1062 const BufferT& buffer)
1064 auto builder = initOctahedron<ValueT, VoxelT>(
scale, center, voxelSize, halfWidth, origin);
1065 builder->sdfToLevelSet();
1066 builder->setStats(sMode);
1067 builder->setChecksum(cMode);
1068 builder->enableDithering(ditherOn);
1070 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
1077 template<
typename ValueT,
typename VoxelT,
typename BufferT>
1086 const Vec3d& origin,
1087 const std::string& name,
1092 const BufferT& buffer)
1094 auto builder = initBBox<ValueT, VoxelT>(width, height, depth, thickness, center, voxelSize, halfWidth, origin);
1095 builder->sdfToLevelSet();
1096 builder->setStats(sMode);
1097 builder->setChecksum(cMode);
1098 builder->enableDithering(ditherOn);
1100 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
1107 template<
typename ValueT,
typename VoxelT,
typename BufferT>
1115 const Vec3d& origin,
1116 const std::string& name,
1121 const BufferT& buffer)
1123 auto builder = initBox<ValueT, VoxelT>(width, height, depth, center, voxelSize, halfWidth, origin);
1124 builder->sdfToFog();
1125 builder->setStats(sMode);
1126 builder->setChecksum(cMode);
1127 builder->enableDithering(ditherOn);
1129 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
1136 template<
typename ValueT,
typename VoxelT,
typename BufferT>
1142 const Vec3d& origin,
1143 const std::string& name,
1148 const BufferT& buffer)
1150 auto builder = initOctahedron<ValueT, VoxelT>(
scale, center, voxelSize, halfWidth, origin);
1151 builder->sdfToFog();
1152 builder->setStats(sMode);
1153 builder->setChecksum(cMode);
1154 builder->enableDithering(ditherOn);
1156 auto handle = builder->template getHandle<AbsDiff, BufferT>(voxelSize, origin, name, oracle, buffer);
1163 template<
typename ValueT,
typename BufferT>
1171 const Vec3d& origin,
1172 const std::string& name,
1174 const BufferT& buffer)
1176 auto boxHandle =
createLevelSetBox(width, height, depth, center, voxelSize, 0.5, origin,
"dummy",
1179 auto* boxGrid = boxHandle.template grid<ValueT>();
1181 auto pointHandle =
createPointScatter(*boxGrid, pointsPerVoxel, name, cMode, buffer);
1182 assert(pointHandle);
1189 template<
typename ValueT,
typename BufferT>
1193 const std::string& name,
1195 const BufferT& buffer)
1199 if (pointsPerVoxel < 1) {
1200 throw std::runtime_error(
"createPointScatter: Expected at least one point per voxel");
1203 throw std::runtime_error(
"createPointScatter: Expected a level set grid");
1206 throw std::runtime_error(
"createPointScatter: ActiveVoxelCount is required");
1209 const uint64_t pointSize = AlignUp<NANOVDB_DATA_ALIGNMENT>(pointCount *
sizeof(Vec3T));
1210 if (pointCount == 0) {
1211 throw std::runtime_error(
"createPointScatter: No particles to scatter");
1213 std::vector<Vec3T> xyz;
1214 xyz.reserve(pointCount);
1218 const ValueT s = 1 / (1 + ValueT(RAND_MAX));
1220 auto randomPoint = [&s]() {
1221 return s * Vec3T(rand(), rand(), rand()) - Vec3T(0.5);
1223 const auto& srcTree = srcGrid.
tree();
1225 for (uint32_t i = 0, end = srcTree.nodeCount(0); i < end; ++i) {
1226 auto* srcLeaf = srcMgr[i];
1227 auto* dstLeaf = dstAcc.setValue(srcLeaf->origin(), pointsPerVoxel);
1228 dstLeaf->mValueMask = srcLeaf->valueMask();
1229 for (uint32_t j = 0, m = 0; j < 512; ++j) {
1230 if (dstLeaf->mValueMask.isOn(j)) {
1231 for (
int n = 0; n < pointsPerVoxel; ++n, ++m) {
1232 xyz.push_back(randomPoint());
1235 dstLeaf->mValues[j] = m;
1238 assert(pointCount == xyz.size());
1242 auto handle = builder.template getHandle<AbsDiff, BufferT>(srcGrid.
map(), name, dummy, buffer);
1244 auto* dstGrid = handle.template grid<uint32_t>();
1246 auto& dstTree = dstGrid->tree();
1247 if (dstTree.nodeCount(0) == 0) {
1248 throw std::runtime_error(
"Expect leaf nodes!");
1251 auto* leafData = dstMgr[0]->data();
1252 leafData[0].mMinimum = 0;
1253 for (uint32_t i = 1, n = dstTree.nodeCount(0); i < n; ++i) {
1254 leafData[i].mMinimum = leafData[i - 1].mMinimum + leafData[i - 1].mMaximum;
1263 std::stringstream ss;
1264 ss <<
"Point attribute name \"" << name <<
"\" is more then " 1266 throw std::runtime_error(ss.str());
1268 memcpy(meta.mName, name.c_str(), name.size() + 1);
1274 throw std::runtime_error(
"Unsupported value type");
1276 if (
const auto *p = dstGrid->blindData(0)) {
1277 memcpy(const_cast<void*>(p), xyz.data(), xyz.size() *
sizeof(Vec3T));
1279 throw std::runtime_error(
"Blind data pointer was NULL");
1287 #endif // NANOVDB_PRIMITIVES_H_HAS_BEEN_INCLUDED
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: PointCount.h:88
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition: NanoVDB.h:2307
GridHandle< BufferT > createPointTorus(int pointsPerVoxel=1, ValueT majorRadius=100.0f, ValueT minorRadius=50.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), 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:999
GridHandle< BufferT > createPointBox(int pointsPerVoxel=1, ValueT width=40.0f, ValueT height=60.0f, ValueT depth=100.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), 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:1165
GridHandle< BufferT > createFogVolumeTorus(ValueT majorRadius=100.0f, ValueT minorRadius=50.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), double voxelSize=1.0, double halfWidth=3.0, const Vec3d &origin=Vec3d(0), const std::string &name="torus_fog", StatsMode sMode=StatsMode::Default, ChecksumMode cMode=ChecksumMode::Default, float tolerance=-1.0f, bool ditherOn=false, 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:971
bool isLevelSet() const
Definition: NanoVDB.h:2420
ChecksumMode
List of different modes for computing for a checksum.
Definition: GridChecksum.h:33
static const bool value
Definition: NanoVDB.h:357
T Type
Definition: NanoVDB.h:384
GridHandle< BufferT > createPointScatter(const NanoGrid< ValueT > &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:1191
const TreeT & tree() const
Return a const reference to the tree.
Definition: NanoVDB.h:2344
Type Max(Type a, Type b)
Definition: NanoVDB.h:672
Type Min(Type a, Type b)
Definition: NanoVDB.h:651
uint64_t activeVoxelCount() const
Return the total number of active voxels in this tree.
Definition: NanoVDB.h:2414
int32_t Ceil(float x)
Definition: NanoVDB.h:720
Allows for the construction of NanoVDB grids without any dependecy.
Definition: GridBuilder.h:91
This class serves to manage a raw memory buffer of a NanoVDB Grid.
Definition: GridHandle.h:70
GridHandle< BufferT > createLevelSetOctahedron(ValueT scale=100.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), 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, float tolerance=-1.0f, bool ditherOn=false, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a octahedron.
Definition: Primitives.h:1052
Definition: NanoVDB.h:184
GridHandle< BufferT > createLevelSetSphere(ValueT radius=100, const Vec3< ValueT > ¢er=Vec3< ValueT >(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, float tolerance=-1.0f, bool ditherOn=false, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a sphere.
Definition: Primitives.h:866
BBox< Coord > CoordBBox
Definition: NanoVDB.h:1658
A simple vector class with three double components, similar to openvdb::math::Vec3.
Definition: NanoVDB.h:856
GridHandle< BufferT > createLevelSetTorus(ValueT majorRadius=100.0f, ValueT minorRadius=50.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), 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, float tolerance=-1.0f, bool ditherOn=false, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a torus in the xz-plane.
Definition: Primitives.h:943
ValueAccessor getAccessor()
Definition: GridBuilder.h:180
int32_t Floor(float x)
Definition: NanoVDB.h:711
const Map & map() const
Return a const reference to the Map for this grid.
Definition: NanoVDB.h:2356
T Abs(T x)
Definition: NanoVDB.h:747
Generates a NanoVDB grid from any volume or function.
void setStats(StatsMode mode=StatsMode::Default)
Definition: GridBuilder.h:197
ValueT value
Definition: GridBuilder.h:1287
void updateChecksum(NanoGrid< ValueT > &grid, ChecksumMode mode=ChecksumMode::Default)
Updates the checksum of a grid.
Definition: GridChecksum.h:272
GridHandle< BufferT > createFogVolumeBox(ValueT width=40.0f, ValueT height=60.0f, ValueT depth=100.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), 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, float tolerance=-1.0f, bool ditherOn=false, 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:1109
GridHandle< BufferT > createPointSphere(int pointsPerVoxel=1, ValueT radius=100.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), double voxelSize=1.0f, 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:920
Compression oracle based on absolute difference.
Definition: GridBuilder.h:38
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:637
bool hasBBox() const
Definition: NanoVDB.h:2428
GridHandle< BufferT > createLevelSetBox(ValueT width=40.0f, ValueT height=60.0f, ValueT depth=100.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), 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, float tolerance=-1.0f, bool ditherOn=false, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a box.
Definition: Primitives.h:1023
float Sqrt(float x)
Return the square root of a floating-point value.
Definition: NanoVDB.h:795
StatsMode
Grid flags which indicate what extra information is present in the grid buffer.
Definition: GridStats.h:32
GridHandle< BufferT > createLevelSetBBox(ValueT width=40.0f, ValueT height=60.0f, ValueT depth=100.0f, ValueT thickness=10.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), 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, float tolerance=-1.0f, bool ditherOn=false, const BufferT &buffer=BufferT())
Returns a handle to a narrow-band level set of a bounding-box (= wireframe of a box) ...
Definition: Primitives.h:1079
void setChecksum(ChecksumMode mode=ChecksumMode::Default)
Definition: GridBuilder.h:199
Vec3< double > Vec3d
Definition: NanoVDB.h:1174
T Pow2(T x)
Definition: NanoVDB.h:730
GridHandle< BufferT > createFogVolumeSphere(ValueT radius=100.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), double voxelSize=1.0f, double halfWidth=3.0f, const Vec3d &origin=Vec3d(0.0), const std::string &name="sphere_fog", StatsMode sMode=StatsMode::Default, ChecksumMode cMode=ChecksumMode::Default, float tolerance=-1.0f, bool ditherOn=false, 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:893
GridHandle< BufferT > createFogVolumeOctahedron(ValueT scale=100.0f, const Vec3< ValueT > ¢er=Vec3< ValueT >(0.0f), 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, float tolerance=-1.0f, bool ditherOn=false, 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:1138
LeafManager< GridT > createLeafMgr(GridT &grid)
creates a LeafManager from a grid. Move semantics is used.
Definition: NodeManager.h:394
C++11 implementation of std::is_floating_point.
Definition: NanoVDB.h:355