8 #ifndef OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 9 #define OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 15 #include <openvdb/version.h> 19 #include <tbb/parallel_for.h> 21 #include <type_traits> 32 template<
typename _ChildNodeType, Index Log2Dim>
38 using ValueType =
typename ChildNodeType::ValueType;
39 using BuildType =
typename ChildNodeType::BuildType;
45 TOTAL = Log2Dim + ChildNodeType::TOTAL,
47 NUM_VALUES = 1 << (3 * Log2Dim),
48 LEVEL = 1 + ChildNodeType::LEVEL;
50 NUM_VOXELS = uint64_t(1) << (3 * TOTAL);
54 template<
typename OtherValueType>
63 template<
typename OtherNodeType>
82 InternalNode(
const Coord& origin,
const ValueType& fillValue,
bool active =
false);
94 template<
typename OtherChildNodeType>
100 template<
typename OtherChildNodeType>
107 template<
typename OtherChildNodeType>
109 const ValueType& offValue,
const ValueType& onValue,
TopologyCopy);
126 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
128 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
132 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
136 assert(this->parent().isChildMaskOn(pos));
137 return *(this->parent().getChildNode(pos));
141 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
147 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
149 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
153 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
155 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
158 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
161 template<
typename ModifyOp>
164 op(this->parent().mNodes[pos].getValue());
169 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
171 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
182 if (this->parent().isChildMaskOn(pos)) {
183 child = this->parent().getChildNode(pos);
187 value = this->parent().mNodes[pos].getValue();
194 this->parent().resetChildNode(pos,
child);
200 this->parent().unsetChildNode(pos,
value);
252 static void getNodeLog2Dims(std::vector<Index>& dims);
262 static void offsetToLocalCoord(
Index n,
Coord& xyz);
271 #if OPENVDB_ABI_VERSION_NUMBER >= 9 279 void nodeCount(std::vector<Index32> &vec)
const;
284 Index64 onLeafVoxelCount()
const;
285 Index64 offLeafVoxelCount()
const;
295 void evalActiveBoundingBox(
CoordBBox& bbox,
bool visitVoxels =
true)
const;
302 bool isEmpty()
const {
return mChildMask.isOff(); }
309 bool isConstant(ValueType& firstValue,
bool& state,
310 const ValueType& tolerance = zeroVal<ValueType>())
const;
326 bool isConstant(ValueType& minValue, ValueType& maxValue,
327 bool& state,
const ValueType& tolerance = zeroVal<ValueType>())
const;
330 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
333 bool isValueOn(
const Coord& xyz)
const;
338 bool hasActiveTiles()
const;
340 const ValueType& getValue(
const Coord& xyz)
const;
341 bool probeValue(
const Coord& xyz, ValueType&
value)
const;
349 const ValueType& getFirstValue()
const;
352 const ValueType& getLastValue()
const;
355 void setActiveState(
const Coord& xyz,
bool on);
357 void setValueOnly(
const Coord& xyz,
const ValueType&
value);
359 void setValueOn(
const Coord& xyz);
361 void setValueOn(
const Coord& xyz,
const ValueType&
value);
363 void setValueOff(
const Coord& xyz);
365 void setValueOff(
const Coord& xyz,
const ValueType&
value);
369 template<
typename ModifyOp>
370 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
372 template<
typename ModifyOp>
373 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
379 template<
typename AccessorT>
380 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
386 template<
typename AccessorT>
387 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
393 template<
typename AccessorT>
394 void setValueAndCache(
const Coord& xyz,
const ValueType&
value, AccessorT&);
400 template<
typename AccessorT>
401 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType&
value, AccessorT&);
408 template<
typename ModifyOp,
typename AccessorT>
409 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
415 template<
typename ModifyOp,
typename AccessorT>
416 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
422 template<
typename AccessorT>
423 void setValueOffAndCache(
const Coord& xyz,
const ValueType&
value, AccessorT&);
429 template<
typename AccessorT>
430 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
437 template<
typename AccessorT>
438 bool probeValueAndCache(
const Coord& xyz, ValueType&
value, AccessorT&)
const;
446 template<
typename AccessorT>
447 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
455 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
456 void readTopology(std::istream&,
bool fromHalf =
false);
457 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
458 void readBuffers(std::istream&,
bool fromHalf =
false);
459 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
477 void fill(
const CoordBBox& bbox,
const ValueType&
value,
bool active =
true);
486 void denseFill(
const CoordBBox& bbox,
const ValueType&
value,
bool active =
true);
491 void voxelizeActiveTiles(
bool threaded =
true);
500 template<
typename DenseT>
505 template<MergePolicy Policy>
506 void merge(
InternalNode& other,
const ValueType& background,
const ValueType& otherBackground);
510 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
524 template<
typename OtherChildNodeType>
540 template<
typename OtherChildNodeType>
542 const ValueType& background);
555 template<
typename OtherChildNodeType>
557 const ValueType& background);
559 template<
typename CombineOp>
561 template<
typename CombineOp>
562 void combine(
const ValueType&
value,
bool valueIsActive, CombineOp&);
564 template<
typename CombineOp,
typename OtherNodeType >
565 void combine2(
const InternalNode& other0,
const OtherNodeType& other1, CombineOp&);
566 template<
typename CombineOp,
typename OtherNodeType >
567 void combine2(
const ValueType&
value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
568 template<
typename CombineOp,
typename OtherValueType>
569 void combine2(
const InternalNode& other,
const OtherValueType&,
bool valIsActive, CombineOp&);
577 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
581 void addLeaf(LeafNodeType* leaf);
585 template<
typename AccessorT>
586 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
596 template<
typename NodeT>
597 NodeT* stealNode(
const Coord& xyz,
const ValueType&
value,
bool state);
605 bool addChild(ChildNodeType*
child);
609 void addTile(
Index level,
const Coord& xyz,
const ValueType&
value,
bool state);
612 void addTile(
Index offset,
const ValueType&
value,
bool state);
616 template<
typename AccessorT>
617 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
622 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
623 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
629 template<
typename NodeType,
typename AccessorT>
630 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
631 template<
typename NodeType,
typename AccessorT>
632 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
638 LeafNodeType* probeLeaf(
const Coord& xyz);
639 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
640 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
646 template<
typename AccessorT>
647 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
648 template<
typename AccessorT>
649 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
650 template<
typename AccessorT>
651 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
660 LeafNodeType* touchLeaf(
const Coord& xyz);
664 template<
typename AccessorT>
665 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
690 template<
typename ArrayT>
691 void getNodes(ArrayT& array);
692 template<
typename ArrayT>
693 void getNodes(ArrayT& array)
const;
719 template<
typename ArrayT>
720 void stealNodes(ArrayT& array,
const ValueType&
value,
bool state);
724 void resetBackground(
const ValueType& oldBackground,
const ValueType& newBackground);
728 template<
typename OtherChildNodeType, Index OtherLog2Dim>
770 void makeChildNodeEmpty(
Index n,
const ValueType&
value);
771 void setChildNode(
Index i, ChildNodeType*
child);
772 void resetChildNode(
Index i, ChildNodeType*
child);
773 ChildNodeType* unsetChildNode(
Index i,
const ValueType&
value);
779 ChildNodeType* getChildNode(
Index n);
780 const ChildNodeType* getChildNode(
Index n)
const;
785 struct VoxelizeActiveTiles;
786 template<
typename OtherInternalNode>
struct DeepCopy;
798 #if OPENVDB_ABI_VERSION_NUMBER >= 9 811 template<
typename ChildT1, Index Dim1,
typename NodeT2>
816 template<
typename ChildT1, Index Dim1,
typename ChildT2>
826 template<
typename ChildT, Index Log2Dim>
830 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
834 template<
typename ChildT, Index Log2Dim>
837 mOrigin(origin[0] & ~(DIM - 1),
838 origin[1] & ~(DIM - 1),
839 origin[2] & ~(DIM - 1))
848 template<
typename ChildT, Index Log2Dim>
852 : mOrigin(origin[0] & ~(DIM-1), origin[1] & ~(DIM-1), origin[2] & ~(DIM-1))
858 template<
typename ChildT, Index Log2Dim>
859 template<
typename OtherInternalNode>
863 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
867 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
868 if (s->mChildMask.isOff(i)) {
869 t->mNodes[i].setValue(
ValueType(s->mNodes[i].getValue()));
871 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild())));
875 const OtherInternalNode*
s;
879 template<
typename ChildT, Index Log2Dim>
882 : mChildMask(other.mChildMask)
883 , mValueMask(other.mValueMask)
884 , mOrigin(other.mOrigin)
885 #if OPENVDB_ABI_VERSION_NUMBER >= 9
886 , mTransientData(other.mTransientData)
894 template<
typename ChildT, Index Log2Dim>
895 template<
typename OtherChildNodeType>
898 : mChildMask(other.mChildMask)
899 , mValueMask(other.mValueMask)
900 , mOrigin(other.mOrigin)
901 #if OPENVDB_ABI_VERSION_NUMBER >= 9
902 , mTransientData(other.mTransientData)
908 template<
typename ChildT, Index Log2Dim>
909 template<
typename OtherInternalNode>
913 const ValueType& background) : s(source), t(target), b(background) {
914 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
918 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
919 if (s->isChildMaskOn(i)) {
920 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
923 t->mNodes[i].setValue(b);
927 const OtherInternalNode*
s;
932 template<
typename ChildT, Index Log2Dim>
933 template<
typename OtherChildNodeType>
937 : mChildMask(other.mChildMask)
938 , mValueMask(other.mValueMask)
939 , mOrigin(other.mOrigin)
940 #if OPENVDB_ABI_VERSION_NUMBER >= 9
941 , mTransientData(other.mTransientData)
947 template<
typename ChildT, Index Log2Dim>
948 template<
typename OtherInternalNode>
953 : s(source), t(target), offV(offValue), onV(onValue) {
954 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
957 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
958 if (s->isChildMaskOn(i)) {
959 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
962 t->mNodes[i].setValue(s->isValueMaskOn(i) ? onV : offV);
966 const OtherInternalNode*
s;
971 template<
typename ChildT, Index Log2Dim>
972 template<
typename OtherChildNodeType>
977 : mChildMask(other.mChildMask)
978 , mValueMask(other.mValueMask)
979 , mOrigin(other.mOrigin)
980 #if OPENVDB_ABI_VERSION_NUMBER >= 9
981 , mTransientData(other.mTransientData)
988 template<
typename ChildT, Index Log2Dim>
992 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
993 delete mNodes[iter.pos()].getChild();
1001 template<
typename ChildT, Index Log2Dim>
1007 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1008 sum += iter->leafCount();
1013 template<
typename ChildT, Index Log2Dim>
1017 assert(vec.size() > ChildNodeType::LEVEL);
1018 const auto count = mChildMask.countOn();
1019 if (ChildNodeType::LEVEL > 0 && count > 0) {
1020 for (
auto iter = this->cbeginChildOn(); iter; ++iter) iter->nodeCount(vec);
1022 vec[ChildNodeType::LEVEL] += count;
1026 template<
typename ChildT, Index Log2Dim>
1032 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1033 sum += iter->nonLeafCount();
1039 template<
typename ChildT, Index Log2Dim>
1043 return this->getChildMask().countOn();
1047 template<
typename ChildT, Index Log2Dim>
1051 Index64 sum = ChildT::NUM_VOXELS * mValueMask.countOn();
1052 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1053 sum += iter->onVoxelCount();
1059 template<
typename ChildT, Index Log2Dim>
1063 Index64 sum = ChildT::NUM_VOXELS * (NUM_VALUES-mValueMask.countOn()-mChildMask.countOn());
1064 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1065 sum += iter->offVoxelCount();
1071 template<
typename ChildT, Index Log2Dim>
1076 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
1077 sum += mNodes[iter.pos()].getChild()->onLeafVoxelCount();
1083 template<
typename ChildT, Index Log2Dim>
1088 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
1089 sum += mNodes[iter.pos()].getChild()->offLeafVoxelCount();
1094 template<
typename ChildT, Index Log2Dim>
1098 Index64 sum = mValueMask.countOn();
1099 for (
ChildOnCIter iter = this->cbeginChildOn(); LEVEL>1 && iter; ++iter) {
1100 sum += iter->onTileCount();
1105 template<
typename ChildT, Index Log2Dim>
1110 + mValueMask.memUsage() +
sizeof(mOrigin);
1111 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1112 sum += iter->memUsage();
1118 template<
typename ChildT, Index Log2Dim>
1122 if (bbox.
isInside(this->getNodeBoundingBox()))
return;
1125 bbox.
expand(i.getCoord(), ChildT::DIM);
1128 i->evalActiveBoundingBox(bbox, visitVoxels);
1136 template<
typename ChildT, Index Log2Dim>
1142 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1143 const Index i = iter.pos();
1144 ChildT*
child = mNodes[i].getChild();
1145 child->prune(tolerance);
1146 if (
child->isConstant(
value, state, tolerance)) {
1148 mChildMask.setOff(i);
1149 mValueMask.set(i, state);
1150 mNodes[i].setValue(
value);
1159 template<
typename ChildT, Index Log2Dim>
1160 template<
typename NodeT>
1165 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1167 const Index n = this->coordToOffset(xyz);
1168 if (mChildMask.isOff(n))
return nullptr;
1169 ChildT*
child = mNodes[n].getChild();
1171 mChildMask.setOff(n);
1172 mValueMask.set(n, state);
1173 mNodes[n].setValue(
value);
1176 ?
reinterpret_cast<NodeT*
>(
child)
1177 :
child->template stealNode<NodeT>(xyz,
value, state);
1185 template<
typename ChildT, Index Log2Dim>
1186 template<
typename NodeT>
1191 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1193 const Index n = this->coordToOffset(xyz);
1194 if (mChildMask.isOff(n))
return nullptr;
1195 ChildT*
child = mNodes[n].getChild();
1197 ?
reinterpret_cast<NodeT*
>(
child)
1198 :
child->template probeNode<NodeT>(xyz);
1203 template<
typename ChildT, Index Log2Dim>
1204 template<
typename NodeT,
typename AccessorT>
1209 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1211 const Index n = this->coordToOffset(xyz);
1212 if (mChildMask.isOff(n))
return nullptr;
1213 ChildT*
child = mNodes[n].getChild();
1214 acc.insert(xyz,
child);
1216 ?
reinterpret_cast<NodeT*
>(
child)
1217 :
child->template probeNodeAndCache<NodeT>(xyz, acc);
1222 template<
typename ChildT, Index Log2Dim>
1223 template<
typename NodeT>
1228 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1230 const Index n = this->coordToOffset(xyz);
1231 if (mChildMask.isOff(n))
return nullptr;
1232 const ChildT*
child = mNodes[n].getChild();
1234 ?
reinterpret_cast<const NodeT*
>(
child)
1235 :
child->template probeConstNode<NodeT>(xyz);
1240 template<
typename ChildT, Index Log2Dim>
1241 template<
typename NodeT,
typename AccessorT>
1246 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1248 const Index n = this->coordToOffset(xyz);
1249 if (mChildMask.isOff(n))
return nullptr;
1250 const ChildT*
child = mNodes[n].getChild();
1251 acc.insert(xyz,
child);
1253 ?
reinterpret_cast<const NodeT*
>(
child)
1254 :
child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1262 template<
typename ChildT, Index Log2Dim>
1263 inline typename ChildT::LeafNodeType*
1266 return this->
template probeNode<LeafNodeType>(xyz);
1270 template<
typename ChildT, Index Log2Dim>
1271 template<
typename AccessorT>
1272 inline typename ChildT::LeafNodeType*
1275 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1279 template<
typename ChildT, Index Log2Dim>
1280 template<
typename AccessorT>
1281 inline const typename ChildT::LeafNodeType*
1284 return this->probeConstLeafAndCache(xyz, acc);
1288 template<
typename ChildT, Index Log2Dim>
1289 inline const typename ChildT::LeafNodeType*
1292 return this->
template probeConstNode<LeafNodeType>(xyz);
1296 template<
typename ChildT, Index Log2Dim>
1297 template<
typename AccessorT>
1298 inline const typename ChildT::LeafNodeType*
1301 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1308 template<
typename ChildT, Index Log2Dim>
1312 assert(leaf !=
nullptr);
1313 const Coord& xyz = leaf->origin();
1314 const Index n = this->coordToOffset(xyz);
1315 ChildT*
child =
nullptr;
1316 if (mChildMask.isOff(n)) {
1317 if (ChildT::LEVEL>0) {
1318 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1320 child =
reinterpret_cast<ChildT*
>(leaf);
1322 this->setChildNode(n,
child);
1324 if (ChildT::LEVEL>0) {
1325 child = mNodes[n].getChild();
1327 delete mNodes[n].getChild();
1328 child =
reinterpret_cast<ChildT*
>(leaf);
1329 mNodes[n].setChild(
child);
1332 child->addLeaf(leaf);
1336 template<
typename ChildT, Index Log2Dim>
1337 template<
typename AccessorT>
1341 assert(leaf !=
nullptr);
1342 const Coord& xyz = leaf->origin();
1343 const Index n = this->coordToOffset(xyz);
1344 ChildT*
child =
nullptr;
1345 if (mChildMask.isOff(n)) {
1346 if (ChildT::LEVEL>0) {
1347 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1348 acc.insert(xyz,
child);
1350 child =
reinterpret_cast<ChildT*
>(leaf);
1352 this->setChildNode(n,
child);
1354 if (ChildT::LEVEL>0) {
1355 child = mNodes[n].getChild();
1356 acc.insert(xyz,
child);
1358 delete mNodes[n].getChild();
1359 child =
reinterpret_cast<ChildT*
>(leaf);
1360 mNodes[n].setChild(
child);
1363 child->addLeafAndCache(leaf, acc);
1370 template<
typename ChildT, Index Log2Dim>
1377 if (
Coord((xyz & ~(DIM-1))) != this->origin())
return false;
1379 const Index n = this->coordToOffset(xyz);
1381 this->resetChildNode(n,
child);
1386 template<
typename ChildT, Index Log2Dim>
1390 assert(n < NUM_VALUES);
1391 this->makeChildNodeEmpty(n,
value);
1392 mValueMask.set(n, state);
1396 template<
typename ChildT, Index Log2Dim>
1401 if (LEVEL >= level) {
1402 const Index n = this->coordToOffset(xyz);
1403 if (mChildMask.isOff(n)) {
1404 if (LEVEL > level) {
1405 ChildT*
child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1406 this->setChildNode(n,
child);
1409 mValueMask.set(n, state);
1410 mNodes[n].setValue(
value);
1413 ChildT*
child = mNodes[n].getChild();
1414 if (LEVEL > level) {
1418 mChildMask.setOff(n);
1419 mValueMask.set(n, state);
1420 mNodes[n].setValue(
value);
1427 template<
typename ChildT, Index Log2Dim>
1428 template<
typename AccessorT>
1433 if (LEVEL >= level) {
1434 const Index n = this->coordToOffset(xyz);
1435 if (mChildMask.isOff(n)) {
1436 if (LEVEL > level) {
1437 ChildT*
child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1438 this->setChildNode(n,
child);
1439 acc.insert(xyz,
child);
1440 child->addTileAndCache(level, xyz,
value, state, acc);
1442 mValueMask.set(n, state);
1443 mNodes[n].setValue(
value);
1446 ChildT*
child = mNodes[n].getChild();
1447 if (LEVEL > level) {
1448 acc.insert(xyz,
child);
1449 child->addTileAndCache(level, xyz,
value, state, acc);
1452 mChildMask.setOff(n);
1453 mValueMask.set(n, state);
1454 mNodes[n].setValue(
value);
1464 template<
typename ChildT, Index Log2Dim>
1465 inline typename ChildT::LeafNodeType*
1468 const Index n = this->coordToOffset(xyz);
1469 ChildT*
child =
nullptr;
1470 if (mChildMask.isOff(n)) {
1471 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1472 this->setChildNode(n,
child);
1474 child = mNodes[n].getChild();
1476 return child->touchLeaf(xyz);
1480 template<
typename ChildT, Index Log2Dim>
1481 template<
typename AccessorT>
1482 inline typename ChildT::LeafNodeType*
1485 const Index n = this->coordToOffset(xyz);
1486 if (mChildMask.isOff(n)) {
1487 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), mValueMask.isOn(n)));
1489 acc.insert(xyz, mNodes[n].getChild());
1490 return mNodes[n].getChild()->touchLeafAndCache(xyz, acc);
1497 template<
typename ChildT, Index Log2Dim>
1502 if (!mChildMask.isOff() || !mValueMask.isConstant(state))
return false;
1504 firstValue = mNodes[0].getValue();
1505 for (
Index i = 1; i < NUM_VALUES; ++i) {
1517 template<
typename ChildT, Index Log2Dim>
1525 if (!mChildMask.isOff() || !mValueMask.isConstant(state))
return false;
1526 minValue = maxValue = mNodes[0].getValue();
1527 for (
Index i = 1; i < NUM_VALUES; ++i) {
1528 const ValueType& v = mNodes[i].getValue();
1530 if ((maxValue - v) > tolerance)
return false;
1532 }
else if (v > maxValue) {
1533 if ((v - minValue) > tolerance)
return false;
1544 template<
typename ChildT, Index Log2Dim>
1551 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1552 if (iter->hasActiveTiles())
return true;
1559 template<
typename ChildT, Index Log2Dim>
1563 const Index n = this->coordToOffset(xyz);
1564 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1565 return mNodes[n].getChild()->isValueOn(xyz);
1568 template<
typename ChildT, Index Log2Dim>
1569 template<
typename AccessorT>
1573 const Index n = this->coordToOffset(xyz);
1574 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1575 acc.insert(xyz, mNodes[n].getChild());
1576 return mNodes[n].getChild()->isValueOnAndCache(xyz, acc);
1580 template<
typename ChildT, Index Log2Dim>
1581 inline const typename ChildT::ValueType&
1584 const Index n = this->coordToOffset(xyz);
1585 return this->isChildMaskOff(n) ? mNodes[n].getValue()
1586 : mNodes[n].getChild()->getValue(xyz);
1589 template<
typename ChildT, Index Log2Dim>
1590 template<
typename AccessorT>
1591 inline const typename ChildT::ValueType&
1594 const Index n = this->coordToOffset(xyz);
1595 if (this->isChildMaskOn(n)) {
1596 acc.insert(xyz, mNodes[n].getChild());
1597 return mNodes[n].getChild()->getValueAndCache(xyz, acc);
1599 return mNodes[n].getValue();
1603 template<
typename ChildT, Index Log2Dim>
1607 const Index n = this->coordToOffset(xyz);
1608 return this->isChildMaskOff(n) ? LEVEL : mNodes[n].getChild()->getValueLevel(xyz);
1611 template<
typename ChildT, Index Log2Dim>
1612 template<
typename AccessorT>
1616 const Index n = this->coordToOffset(xyz);
1617 if (this->isChildMaskOn(n)) {
1618 acc.insert(xyz, mNodes[n].getChild());
1619 return mNodes[n].getChild()->getValueLevelAndCache(xyz, acc);
1625 template<
typename ChildT, Index Log2Dim>
1629 const Index n = this->coordToOffset(xyz);
1630 if (this->isChildMaskOff(n)) {
1631 value = mNodes[n].getValue();
1632 return this->isValueMaskOn(n);
1634 return mNodes[n].getChild()->probeValue(xyz,
value);
1637 template<
typename ChildT, Index Log2Dim>
1638 template<
typename AccessorT>
1643 const Index n = this->coordToOffset(xyz);
1644 if (this->isChildMaskOn(n)) {
1645 acc.insert(xyz, mNodes[n].getChild());
1646 return mNodes[n].getChild()->probeValueAndCache(xyz,
value, acc);
1648 value = mNodes[n].getValue();
1649 return this->isValueMaskOn(n);
1653 template<
typename ChildT, Index Log2Dim>
1657 const Index n = this->coordToOffset(xyz);
1658 bool hasChild = this->isChildMaskOn(n);
1659 if (!hasChild && this->isValueMaskOn(n)) {
1663 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
true));
1665 if (hasChild) mNodes[n].getChild()->setValueOff(xyz);
1669 template<
typename ChildT, Index Log2Dim>
1673 const Index n = this->coordToOffset(xyz);
1674 bool hasChild = this->isChildMaskOn(n);
1675 if (!hasChild && !this->isValueMaskOn(n)) {
1679 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
false));
1681 if (hasChild) mNodes[n].getChild()->setValueOn(xyz);
1685 template<
typename ChildT, Index Log2Dim>
1690 bool hasChild = this->isChildMaskOn(n);
1692 const bool active = this->isValueMaskOn(n);
1698 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1701 if (hasChild) mNodes[n].getChild()->setValueOff(xyz,
value);
1704 template<
typename ChildT, Index Log2Dim>
1705 template<
typename AccessorT>
1711 bool hasChild = this->isChildMaskOn(n);
1713 const bool active = this->isValueMaskOn(n);
1719 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1723 ChildT*
child = mNodes[n].getChild();
1724 acc.insert(xyz,
child);
1730 template<
typename ChildT, Index Log2Dim>
1734 const Index n = this->coordToOffset(xyz);
1735 bool hasChild = this->isChildMaskOn(n);
1737 const bool active = this->isValueMaskOn(n);
1743 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1746 if (hasChild) mNodes[n].getChild()->setValueOn(xyz,
value);
1749 template<
typename ChildT, Index Log2Dim>
1750 template<
typename AccessorT>
1755 const Index n = this->coordToOffset(xyz);
1756 bool hasChild = this->isChildMaskOn(n);
1758 const bool active = this->isValueMaskOn(n);
1764 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1768 acc.insert(xyz, mNodes[n].getChild());
1769 mNodes[n].getChild()->setValueAndCache(xyz,
value, acc);
1774 template<
typename ChildT, Index Log2Dim>
1778 const Index n = this->coordToOffset(xyz);
1779 bool hasChild = this->isChildMaskOn(n);
1783 const bool active = this->isValueMaskOn(n);
1785 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1787 if (hasChild) mNodes[n].getChild()->setValueOnly(xyz,
value);
1790 template<
typename ChildT, Index Log2Dim>
1791 template<
typename AccessorT>
1796 const Index n = this->coordToOffset(xyz);
1797 bool hasChild = this->isChildMaskOn(n);
1801 const bool active = this->isValueMaskOn(n);
1803 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1806 acc.insert(xyz, mNodes[n].getChild());
1807 mNodes[n].getChild()->setValueOnlyAndCache(xyz,
value, acc);
1812 template<
typename ChildT, Index Log2Dim>
1816 const Index n = this->coordToOffset(xyz);
1817 bool hasChild = this->isChildMaskOn(n);
1819 if (on != this->isValueMaskOn(n)) {
1824 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1827 if (hasChild) mNodes[n].getChild()->setActiveState(xyz, on);
1830 template<
typename ChildT, Index Log2Dim>
1831 template<
typename AccessorT>
1835 const Index n = this->coordToOffset(xyz);
1836 bool hasChild = this->isChildMaskOn(n);
1838 if (on != this->isValueMaskOn(n)) {
1843 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1847 ChildT*
child = mNodes[n].getChild();
1848 acc.insert(xyz,
child);
1849 child->setActiveStateAndCache(xyz, on, acc);
1854 template<
typename ChildT, Index Log2Dim>
1858 mValueMask = !mChildMask;
1859 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1860 mNodes[iter.pos()].getChild()->setValuesOn();
1865 template<
typename ChildT, Index Log2Dim>
1866 template<
typename ModifyOp>
1871 bool hasChild = this->isChildMaskOn(n);
1875 const bool active = this->isValueMaskOn(n);
1876 bool createChild = !active;
1880 const ValueType& tileVal = mNodes[n].getValue();
1887 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1890 if (hasChild) mNodes[n].getChild()->modifyValue(xyz, op);
1893 template<
typename ChildT, Index Log2Dim>
1894 template<
typename ModifyOp,
typename AccessorT>
1900 bool hasChild = this->isChildMaskOn(n);
1904 const bool active = this->isValueMaskOn(n);
1905 bool createChild = !active;
1909 const ValueType& tileVal = mNodes[n].getValue();
1916 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1921 acc.insert(xyz,
child);
1922 child->modifyValueAndCache(xyz, op, acc);
1927 template<
typename ChildT, Index Log2Dim>
1928 template<
typename ModifyOp>
1933 bool hasChild = this->isChildMaskOn(n);
1935 const bool tileState = this->isValueMaskOn(n);
1936 const ValueType& tileVal = mNodes[n].getValue();
1937 bool modifiedState = !tileState;
1939 op(modifiedVal, modifiedState);
1944 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1947 if (hasChild) mNodes[n].getChild()->modifyValueAndActiveState(xyz, op);
1950 template<
typename ChildT, Index Log2Dim>
1951 template<
typename ModifyOp,
typename AccessorT>
1954 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1957 bool hasChild = this->isChildMaskOn(n);
1959 const bool tileState = this->isValueMaskOn(n);
1960 const ValueType& tileVal = mNodes[n].getValue();
1961 bool modifiedState = !tileState;
1963 op(modifiedVal, modifiedState);
1968 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1973 acc.insert(xyz,
child);
1974 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1982 template<
typename ChildT, Index Log2Dim>
1986 CoordBBox nodeBBox = this->getNodeBoundingBox();
1989 this->fill(nodeBBox, background,
false);
1990 }
else if (clipBBox.
isInside(nodeBBox)) {
1999 for (
Index pos = 0; pos < NUM_VALUES; ++pos) {
2000 const Coord xyz = this->offsetToGlobalCoord(pos);
2005 this->makeChildNodeEmpty(pos, background);
2006 mValueMask.setOff(pos);
2007 }
else if (!clipBBox.
isInside(tileBBox)) {
2010 if (this->isChildMaskOn(pos)) {
2011 mNodes[pos].getChild()->clip(clipBBox, background);
2015 tileBBox.intersect(clipBBox);
2016 const ValueType val = mNodes[pos].getValue();
2017 const bool on = this->isValueMaskOn(pos);
2018 mNodes[pos].setValue(background);
2019 mValueMask.setOff(pos);
2020 this->fill(tileBBox, val, on);
2032 template<
typename ChildT, Index Log2Dim>
2036 auto clippedBBox = this->getNodeBoundingBox();
2037 clippedBBox.intersect(bbox);
2038 if (!clippedBBox)
return;
2042 Coord xyz, tileMin, tileMax;
2043 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2045 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2047 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2051 const Index n = this->coordToOffset(xyz);
2052 tileMin = this->offsetToGlobalCoord(n);
2053 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2059 ChildT*
child =
nullptr;
2060 if (this->isChildMaskOff(n)) {
2063 child =
new ChildT{xyz, mNodes[n].getValue(), this->isValueMaskOn(n)};
2064 this->setChildNode(n,
child);
2066 child = mNodes[n].getChild();
2079 this->makeChildNodeEmpty(n,
value);
2080 mValueMask.set(n, active);
2088 template<
typename ChildT, Index Log2Dim>
2092 auto clippedBBox = this->getNodeBoundingBox();
2093 clippedBBox.intersect(bbox);
2094 if (!clippedBBox)
return;
2098 Coord xyz, tileMin, tileMax;
2099 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2101 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2103 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2107 const auto n = this->coordToOffset(xyz);
2110 ChildT*
child =
nullptr;
2111 if (this->isChildMaskOn(n)) {
2112 child = mNodes[n].getChild();
2116 child =
new ChildT{xyz, mNodes[n].getValue(), this->isValueMaskOn(n)};
2117 this->setChildNode(n,
child);
2121 tileMin = this->offsetToGlobalCoord(n);
2122 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2135 template<
typename ChildT, Index Log2Dim>
2136 template<
typename DenseT>
2140 using DenseValueType =
typename DenseT::ValueType;
2142 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2143 const Coord&
min = dense.bbox().min();
2144 for (
Coord xyz = bbox.
min(),
max; xyz[0] <= bbox.
max()[0]; xyz[0] =
max[0] + 1) {
2145 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] =
max[1] + 1) {
2146 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] =
max[2] + 1) {
2147 const Index n = this->coordToOffset(xyz);
2149 max = this->offsetToGlobalCoord(n).offsetBy(ChildT::DIM-1);
2154 if (this->isChildMaskOn(n)) {
2155 mNodes[n].getChild()->copyToDense(sub, dense);
2159 DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
2160 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
2161 DenseValueType* a1 = a0 + x*xStride;
2162 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
2163 DenseValueType* a2 = a1 + y*yStride;
2165 z < ez; ++z, a2 += zStride)
2167 *a2 = DenseValueType(
value);
2181 template<
typename ChildT, Index Log2Dim>
2185 mChildMask.save(os);
2186 mValueMask.save(os);
2190 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[NUM_VALUES]);
2192 const ValueType zero = zeroVal<ValueType>();
2193 for (
Index i = 0; i < NUM_VALUES; ++i) {
2194 values[i] = (mChildMask.isOff(i) ? mNodes[i].getValue() : zero);
2200 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2201 iter->writeTopology(os, toHalf);
2206 template<
typename ChildT, Index Log2Dim>
2213 mChildMask.load(is);
2214 mValueMask.load(is);
2217 for (
Index i = 0; i < NUM_VALUES; ++i) {
2218 if (this->isChildMaskOn(i)) {
2221 mNodes[i].setChild(
child);
2222 child->readTopology(is);
2226 mNodes[i].setValue(
value);
2230 const bool oldVersion =
2232 const Index numValues = (oldVersion ? mChildMask.countOff() : NUM_VALUES);
2236 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[numValues]);
2243 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
2244 mNodes[iter.pos()].setValue(values[n++]);
2246 assert(n == numValues);
2248 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
2249 mNodes[iter.pos()].setValue(values[iter.pos()]);
2254 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2256 mNodes[iter.pos()].setChild(
child);
2257 child->readTopology(is, fromHalf);
2266 template<
typename ChildT, Index Log2Dim>
2267 inline const typename ChildT::ValueType&
2270 return (this->isChildMaskOn(0) ? mNodes[0].getChild()->getFirstValue() : mNodes[0].getValue());
2274 template<
typename ChildT, Index Log2Dim>
2275 inline const typename ChildT::ValueType&
2278 const Index n = NUM_VALUES - 1;
2279 return (this->isChildMaskOn(n) ? mNodes[n].getChild()->getLastValue() : mNodes[n].getValue());
2286 template<
typename ChildT, Index Log2Dim>
2290 for (
Index i = 0; i < NUM_VALUES; ++i) {
2291 if (this->isChildMaskOn(i)) {
2292 mNodes[i].getChild()->negate();
2304 template<
typename ChildT, Index Log2Dim>
2309 tbb::parallel_for(tbb::blocked_range<Index>(0, NUM_VALUES), *
this);
2316 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2317 if (mNode->mChildMask.isOn(i)) {
2318 mNode->mNodes[i].getChild()->voxelizeActiveTiles(
true);
2319 }
else if (mNode->mValueMask.isOn(i)) {
2320 const Coord &ijk = mNode->offsetToGlobalCoord(i);
2322 child->voxelizeActiveTiles(
true);
2323 mNode->mNodes[i].setChild(
child);
2330 template<
typename ChildT, Index Log2Dim>
2337 for (
ValueOnIter iter = this->beginValueOn(); iter; ++iter) {
2338 this->setChildNode(iter.pos(),
2341 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter)
2342 iter->voxelizeActiveTiles(
false);
2350 template<
typename ChildT, Index Log2Dim>
2351 template<MergePolicy Policy>
2364 const Index n = iter.pos();
2365 if (mChildMask.isOn(n)) {
2367 mNodes[n].getChild()->template merge<MERGE_ACTIVE_STATES>(*iter,
2368 background, otherBackground);
2369 }
else if (mValueMask.isOff(n)) {
2376 child->resetBackground(otherBackground, background);
2377 this->setChildNode(n,
child);
2383 const Index n = iter.pos();
2384 if (mValueMask.isOff(n)) {
2386 this->makeChildNodeEmpty(n, iter.getValue());
2387 mValueMask.setOn(n);
2396 const Index n = iter.pos();
2397 if (mChildMask.isOn(n)) {
2399 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2407 child->resetBackground(otherBackground, background);
2408 this->setChildNode(n,
child);
2418 const Index n = iter.pos();
2419 if (mChildMask.isOn(n)) {
2421 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2428 child->resetBackground(otherBackground, background);
2429 if (mValueMask.isOn(n)) {
2431 child->template merge<Policy>(mNodes[n].getValue(),
true);
2432 mValueMask.setOff(n);
2434 mChildMask.setOn(n);
2435 mNodes[n].setChild(
child);
2441 const Index n = iter.pos();
2442 if (mChildMask.isOn(n)) {
2444 mNodes[n].getChild()->template merge<Policy>(iter.getValue(),
true);
2445 }
else if (mValueMask.isOff(n)) {
2447 mNodes[n].setValue(iter.getValue());
2448 mValueMask.setOn(n);
2459 template<
typename ChildT, Index Log2Dim>
2460 template<MergePolicy Policy>
2469 if (!tileActive)
return;
2472 for (
ValueOffIter iter = this->beginValueOff(); iter; ++iter) {
2473 const Index n = iter.pos();
2474 if (mChildMask.isOn(n)) {
2476 mNodes[n].getChild()->template merge<Policy>(tileValue,
true);
2479 iter.setValue(tileValue);
2480 mValueMask.setOn(n);
2490 template<
typename ChildT, Index Log2Dim>
2491 template<
typename OtherInternalNode>
2496 { tV = (tV | sV) & ~tC; }
2499 : s(source), t(target), mPreserveTiles(preserveTiles) {
2501 tbb::parallel_for(tbb::blocked_range<Index>(0, NUM_VALUES), *
this);
2504 if (!mPreserveTiles) t->mChildMask |= s->mChildMask;
2505 else t->mChildMask |= (s->mChildMask & !t->mValueMask);
2508 t->mValueMask.foreach(s->mValueMask, t->mChildMask, op);
2509 assert((t->mValueMask & t->mChildMask).isOff());
2512 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2513 if (s->mChildMask.isOn(i)) {
2514 const typename OtherInternalNode::ChildNodeType& other = *(s->mNodes[i].getChild());
2515 if (t->mChildMask.isOn(i)) {
2516 t->mNodes[i].getChild()->topologyUnion(other, mPreserveTiles);
2518 if (!mPreserveTiles || t->mValueMask.isOff(i)) {
2520 if (t->mValueMask.isOn(i))
child->setValuesOn();
2521 t->mNodes[i].setChild(
child);
2524 }
else if (s->mValueMask.isOn(i) && t->mChildMask.isOn(i)) {
2525 t->mNodes[i].getChild()->setValuesOn();
2529 const OtherInternalNode*
s;
2534 template<
typename ChildT, Index Log2Dim>
2535 template<
typename OtherChildT>
2542 template<
typename ChildT, Index Log2Dim>
2543 template<
typename OtherInternalNode>
2544 struct InternalNode<ChildT, Log2Dim>::TopologyIntersection
2548 { tC = (tC & (sC | sV)) | (tV & sC); }
2551 const ValueType& background) : s(source), t(target), b(background) {
2553 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2557 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op);
2559 t->mValueMask &= s->mValueMask;
2560 assert((t->mValueMask & t->mChildMask).isOff());
2563 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2564 if (t->mChildMask.isOn(i)) {
2565 ChildT*
child = t->mNodes[i].getChild();
2566 if (s->mChildMask.isOn(i)) {
2567 child->topologyIntersection(*(s->mNodes[i].getChild()), b);
2568 }
else if (s->mValueMask.isOff(i)) {
2570 t->mNodes[i].setValue(b);
2572 }
else if (t->mValueMask.isOn(i) && s->mChildMask.isOn(i)) {
2573 t->mNodes[i].setChild(
new ChildT(*(s->mNodes[i].getChild()),
2578 const OtherInternalNode*
s;
2583 template<
typename ChildT, Index Log2Dim>
2584 template<
typename OtherChildT>
2592 template<
typename ChildT, Index Log2Dim>
2593 template<
typename OtherInternalNode>
2594 struct InternalNode<ChildT, Log2Dim>::TopologyDifference
2598 { tC = (tC & (sC | ~sV)) | (tV & sC); }
2601 { tV &= ~((tC & sV) | (sC | sV)); }
2604 const ValueType& background) : s(source), t(target), b(background) {
2606 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2611 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op1);
2614 t->mValueMask.foreach(t->mChildMask, s->mValueMask, oldChildMask, op2);
2615 assert((t->mValueMask & t->mChildMask).isOff());
2618 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2619 if (t->mChildMask.isOn(i)) {
2620 ChildT*
child = t->mNodes[i].getChild();
2621 if (s->mChildMask.isOn(i)) {
2622 child->topologyDifference(*(s->mNodes[i].getChild()), b);
2623 }
else if (s->mValueMask.isOn(i)) {
2625 t->mNodes[i].setValue(b);
2627 }
else if (t->mValueMask.isOn(i)) {
2628 if (s->mChildMask.isOn(i)) {
2629 const typename OtherInternalNode::ChildNodeType& other =
2630 *(s->mNodes[i].getChild());
2631 ChildT*
child =
new ChildT(other.origin(), t->mNodes[i].getValue(),
true);
2632 child->topologyDifference(other, b);
2633 t->mNodes[i].setChild(
child);
2638 const OtherInternalNode*
s;
2643 template<
typename ChildT, Index Log2Dim>
2644 template<
typename OtherChildT>
2656 template<
typename ChildT, Index Log2Dim>
2657 template<
typename CombineOp>
2661 const ValueType zero = zeroVal<ValueType>();
2665 for (
Index i = 0; i < NUM_VALUES; ++i) {
2669 op(args.setARef(mNodes[i].getValue())
2670 .setAIsActive(isValueMaskOn(i))
2673 mNodes[i].setValue(args.result());
2674 mValueMask.set(i, args.resultIsActive());
2682 }
else if (this->isChildMaskOff(i) && other.
isChildMaskOn(i)) {
2691 child->combine(mNodes[i].getValue(), isValueMaskOn(i), swappedOp);
2696 this->setChildNode(i,
child);
2702 *
child = mNodes[i].getChild(),
2706 if (
child && otherChild) {
2707 child->combine(*otherChild, op);
2714 template<
typename ChildT, Index Log2Dim>
2715 template<
typename CombineOp>
2721 for (
Index i = 0; i < NUM_VALUES; ++i) {
2722 if (this->isChildMaskOff(i)) {
2724 op(args.
setARef(mNodes[i].getValue())
2725 .setAIsActive(isValueMaskOn(i))
2727 .setBIsActive(valueIsActive));
2728 mNodes[i].setValue(args.
result());
2743 template<
typename ChildT, Index Log2Dim>
2744 template<
typename CombineOp,
typename OtherNodeType>
2751 for (
Index i = 0; i < NUM_VALUES; ++i) {
2755 .setBRef(other1.mNodes[i].getValue())
2756 .setBIsActive(other1.isValueMaskOn(i)));
2758 this->makeChildNodeEmpty(i, args.
result());
2761 if (this->isChildMaskOff(i)) {
2765 : other1.mNodes[i].getChild()->origin();
2766 this->setChildNode(i,
new ChildNodeType(childOrigin, mNodes[i].getValue()));
2774 }
else if (other1.isChildMaskOff(i)) {
2778 other1.mNodes[i].getValue(), other1.isValueMaskOn(i), op);
2783 *other1.mNodes[i].getChild(), op);
2790 template<
typename ChildT, Index Log2Dim>
2791 template<
typename CombineOp,
typename OtherNodeType>
2794 bool valueIsActive, CombineOp& op)
2798 for (
Index i = 0; i < NUM_VALUES; ++i) {
2799 if (other.isChildMaskOff(i)) {
2801 .setAIsActive(valueIsActive)
2802 .setBRef(other.mNodes[i].getValue())
2803 .setBIsActive(other.isValueMaskOn(i)));
2805 this->makeChildNodeEmpty(i, args.
result());
2808 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
2810 if (this->isChildMaskOff(i)) {
2817 mNodes[i].getChild()->combine2(
value, *otherChild, valueIsActive, op);
2823 template<
typename ChildT, Index Log2Dim>
2824 template<
typename CombineOp,
typename OtherValueType>
2827 bool valueIsActive, CombineOp& op)
2831 for (
Index i = 0; i < NUM_VALUES; ++i) {
2836 .setBIsActive(valueIsActive));
2838 this->makeChildNodeEmpty(i, args.
result());
2843 if (this->isChildMaskOff(i)) {
2845 this->setChildNode(i,
2846 new ChildNodeType(otherChild->origin(), mNodes[i].getValue()));
2850 mNodes[i].getChild()->combine2(*otherChild,
value, valueIsActive, op);
2859 template<
typename ChildT, Index Log2Dim>
2863 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2864 iter->writeBuffers(os, toHalf);
2869 template<
typename ChildT, Index Log2Dim>
2873 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2874 iter->readBuffers(is, fromHalf);
2879 template<
typename ChildT, Index Log2Dim>
2882 const CoordBBox& clipBBox,
bool fromHalf)
2884 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2889 iter->readBuffers(is, clipBBox, fromHalf);
2893 ValueType background = zeroVal<ValueType>();
2895 background = *
static_cast<const ValueType*
>(bgPtr);
2897 this->
clip(clipBBox, background);
2904 template<
typename ChildT, Index Log2Dim>
2908 dims.push_back(Log2Dim);
2909 ChildNodeType::getNodeLog2Dims(dims);
2913 template<
typename ChildT, Index Log2Dim>
2917 assert(n<(1<<3*Log2Dim));
2918 xyz.
setX(n >> 2*Log2Dim);
2919 n &= ((1<<2*Log2Dim)-1);
2920 xyz.
setY(n >> Log2Dim);
2921 xyz.
setZ(n & ((1<<Log2Dim)-1));
2925 template<
typename ChildT, Index Log2Dim>
2929 return (((xyz[0] & (DIM-1u)) >> ChildNodeType::TOTAL) << 2*Log2Dim)
2930 + (((xyz[1] & (DIM-1u)) >> ChildNodeType::TOTAL) << Log2Dim)
2931 + ((xyz[2] & (DIM-1u)) >> ChildNodeType::TOTAL);
2935 template<
typename ChildT, Index Log2Dim>
2940 this->offsetToLocalCoord(n, local);
2941 local <<= ChildT::TOTAL;
2942 return local + this->origin();
2949 template<
typename ChildT, Index Log2Dim>
2950 template<
typename ArrayT>
2954 using T =
typename ArrayT::value_type;
2956 using ArrayChildT =
typename std::conditional<
2957 std::is_const<typename std::remove_pointer<T>::type>
::value,
const ChildT, ChildT>::type;
2958 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2961 array.push_back(reinterpret_cast<T>(mNodes[iter.pos()].getChild()));
2963 iter->getNodes(array);
2969 template<
typename ChildT, Index Log2Dim>
2970 template<
typename ArrayT>
2974 using T =
typename ArrayT::value_type;
2976 static_assert(std::is_const<
typename std::remove_pointer<T>::type>::
value,
2977 "argument to getNodes() must be an array of const node pointers");
2978 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2981 array.push_back(reinterpret_cast<T>(mNodes[iter.pos()].getChild()));
2983 iter->getNodes(array);
2993 template<
typename ChildT, Index Log2Dim>
2994 template<
typename ArrayT>
2998 using T =
typename ArrayT::value_type;
3000 using ArrayChildT =
typename std::conditional<
3001 std::is_const<typename std::remove_pointer<T>::type>
::value,
const ChildT, ChildT>::type;
3003 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3004 const Index n = iter.pos();
3006 array.push_back(reinterpret_cast<T>(mNodes[n].getChild()));
3007 mValueMask.set(n, state);
3008 mNodes[n].setValue(
value);
3010 iter->stealNodes(array,
value, state);
3021 template<
typename ChildT, Index Log2Dim>
3027 for (
Index i = 0; i < NUM_VALUES; ++i) {
3028 if (this->isChildMaskOn(i)) {
3029 mNodes[i].getChild()->resetBackground(oldBackground, newBackground);
3030 }
else if (this->isValueMaskOff(i)) {
3032 mNodes[i].setValue(newBackground);
3040 template<
typename ChildT, Index Log2Dim>
3041 template<
typename OtherChildNodeType, Index OtherLog2Dim>
3046 if (Log2Dim != OtherLog2Dim || mChildMask != other->
mChildMask ||
3047 mValueMask != other->
mValueMask)
return false;
3048 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
3049 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
3055 template<
typename ChildT, Index Log2Dim>
3060 if (this->isChildMaskOn(i)) {
3061 delete mNodes[i].getChild();
3063 mChildMask.setOn(i);
3064 mValueMask.setOff(i);
3066 mNodes[i].setChild(
child);
3069 template<
typename ChildT, Index Log2Dim>
3074 assert(mChildMask.isOff(i));
3075 mChildMask.setOn(i);
3076 mValueMask.setOff(i);
3077 mNodes[i].setChild(
child);
3081 template<
typename ChildT, Index Log2Dim>
3085 if (this->isChildMaskOff(i)) {
3086 mNodes[i].setValue(
value);
3090 mChildMask.setOff(i);
3091 mNodes[i].setValue(
value);
3096 template<
typename ChildT, Index Log2Dim>
3100 delete this->unsetChildNode(n,
value);
3103 template<
typename ChildT, Index Log2Dim>
3107 assert(this->isChildMaskOn(n));
3108 return mNodes[n].getChild();
3112 template<
typename ChildT, Index Log2Dim>
3113 inline const ChildT*
3116 assert(this->isChildMaskOn(n));
3117 return mNodes[n].getChild();
3124 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:791
Index32 Index
Definition: Types.h:54
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:746
ValueOffIter beginValueOff()
Definition: InternalNode.h:240
const OtherInternalNode * s
Definition: InternalNode.h:2529
Definition: InternalNode.h:790
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:29
void addLeaf(LeafNodeType *leaf)
Add the specified leaf to this node, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: InternalNode.h:1310
ChildT * child
Definition: GridBuilder.h:1289
const ValueType & b
Definition: InternalNode.h:929
Tag dispatch class that distinguishes constructors that deep copy.
Definition: Types.h:646
uint64_t Index64
Definition: Types.h:53
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:751
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:192
InternalNode * t
Definition: InternalNode.h:876
TopologyDifference(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2603
Definition: InternalNode.h:2597
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: InternalNode.h:1264
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:457
Definition: InternalNode.h:788
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:248
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:267
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
ValueOnIter beginValueOn()
Definition: InternalNode.h:238
const Coord & max() const
Definition: Coord.h:322
bool hasSameTopology(const InternalNode< OtherChildNodeType, OtherLog2Dim > *other) const
Return true if the given tree branch has the same node and active value topology as this tree branch ...
Definition: InternalNode.h:3043
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2208
void negate()
Change the sign of all the values represented in this node and its child nodes.
Definition: InternalNode.h:2288
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:400
static Index getLevel()
Definition: InternalNode.h:249
Definition: InternalNode.h:127
typename ChildNodeType::BuildType BuildType
Definition: InternalNode.h:39
void setValue(const ValueT &val)
Definition: NodeUnion.h:45
Definition: InternalNode.h:120
static Index getChildDim()
Definition: InternalNode.h:256
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Definition: InternalNode.h:170
InternalNode()
Default constructor.
Definition: InternalNode.h:72
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2562
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:222
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:307
static void getNodeLog2Dims(std::vector< Index > &dims)
Populated an std::vector with the dimension of all the nodes in the branch starting with this node...
Definition: InternalNode.h:2906
typename std::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:184
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1655
const NodeType * probeConstNode(const Coord &xyz) const
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
void setTransientData(Index32 transientData)
Set the transient data value.
Definition: InternalNode.h:275
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:645
Index getValueLevelAndCache(const Coord &xyz, AccessorT &) const
Return the level of the tree (0 = leaf) at which the value at the given coordinates resides...
Definition: InternalNode.h:1614
InternalNode * mNode
Definition: InternalNode.h:2327
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:3083
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1752
typename NodeMaskType::Word W
Definition: InternalNode.h:2494
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:2746
Definition: InternalNode.h:120
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:2927
const ValueType & onV
Definition: InternalNode.h:968
Index32 leafCount() const
Definition: InternalNode.h:1003
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:797
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:24
const ValueType & getFirstValue() const
If the first entry in this node's table is a tile, return the tile's value. Otherwise, return the result of calling getFirstValue() on the child.
Definition: InternalNode.h:2268
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:116
NodeMaskType mValueMask
Definition: InternalNode.h:795
typename BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:174
TopologyUnion(const OtherInternalNode *source, InternalNode *target, const bool preserveTiles)
Definition: InternalNode.h:2498
InternalNode * t
Definition: InternalNode.h:2530
const NodeType * probeConstNodeAndCache(const Coord &xyz, AccessorT &) const
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:236
Definition: NodeMasks.h:270
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:917
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1571
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1671
const UnionType * getTable() const
Definition: InternalNode.h:762
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:128
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:220
Definition: InternalNode.h:786
Definition: version.h.in:256
typename NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:114
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2659
typename ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:37
ValueAllIter beginValueAll()
Definition: InternalNode.h:241
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:237
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3057
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:64
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2332
Definition: InternalNode.h:119
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: InternalNode.h:1984
static void offsetToLocalCoord(Index n, Coord &xyz)
Return the local coordinates for a linear table offset, where offset 0 has coordinates (0...
Definition: InternalNode.h:2915
Index32 nonLeafCount() const
Definition: InternalNode.h:1028
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:443
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2314
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1561
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:152
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2617
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:406
Definition: InternalNode.h:787
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:46
Definition: InternalNode.h:791
const NodeMaskType & getChildMask() const
Definition: InternalNode.h:754
static const Index NUM_VALUES
Definition: InternalNode.h:47
typename NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:115
const OtherInternalNode * s
Definition: InternalNode.h:2638
void addTileAndCache(Index level, const Coord &xyz, const ValueType &, bool state, AccessorT &)
Same as addTile() except, if necessary, update the accessor with pointers to the nodes along the path...
Definition: InternalNode.h:1430
Level getLevel()
Return the current logging level.
Definition: logging.h:141
Definition: InternalNode.h:33
Index64 onTileCount() const
Definition: InternalNode.h:1096
const OtherInternalNode * s
Definition: InternalNode.h:875
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:224
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:866
const ValueType & getLastValue() const
If the last entry in this node's table is a tile, return the tile's value. Otherwise, return the result of calling getLastValue() on the child.
Definition: InternalNode.h:2276
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:582
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:208
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:418
Definition: InternalNode.h:2305
const OtherInternalNode * s
Definition: InternalNode.h:966
const OtherInternalNode * s
Definition: InternalNode.h:2578
Index64 Word
Definition: NodeMasks.h:316
BBox< Coord > CoordBBox
Definition: NanoVDB.h:1809
void copyToDense(const CoordBBox &bbox, DenseT &dense) const
Copy into a dense grid the values of the voxels that lie within a given bounding box.
Definition: InternalNode.h:2138
int32_t Int32
Definition: Types.h:56
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:330
Definition: version.h.in:247
typename ChildNodeType::ValueType ValueType
Definition: InternalNode.h:38
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:750
ValueIter()
Definition: InternalNode.h:151
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1953
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: InternalNode.h:1868
Definition: InternalNode.h:789
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1856
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:131
static Index dim()
Definition: InternalNode.h:246
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:313
const LeafNodeType * probeConstLeafAndCache(const Coord &xyz, AccessorT &acc) const
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
~InternalNode()
Definition: InternalNode.h:990
DenseIter()
Definition: InternalNode.h:176
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:198
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:465
InternalNode * t
Definition: InternalNode.h:2579
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1793
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:3098
Int32 y() const
Definition: Coord.h:131
void topologyUnion(const InternalNode< OtherChildNodeType, Log2Dim > &other, const bool preserveTiles=false)
Union this branch's set of active values with the other branch's active values. The value type of the...
const AValueType & result() const
Get the output value.
Definition: Types.h:574
Index32 transientData() const
Return the transient data value.
Definition: InternalNode.h:273
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
const OtherInternalNode * s
Definition: InternalNode.h:927
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1833
Coord & setX(Int32 x)
Definition: Coord.h:79
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:233
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:158
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:180
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: InternalNode.h:2034
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2183
Int32 x() const
Definition: Coord.h:130
TopologyIntersection(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2550
DeepCopy(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:862
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: InternalNode.h:1896
InternalNode * t
Definition: InternalNode.h:2639
void addLeafAndCache(LeafNodeType *leaf, AccessorT &)
Same as addLeaf() except, if necessary, update the accessor with pointers to the nodes along the path...
Definition: InternalNode.h:1339
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly creating a parent bran...
Definition: InternalNode.h:1398
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:225
TopologyCopy1(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:912
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1546
Definition: Exceptions.h:13
Coord & setY(Int32 y)
Definition: Coord.h:80
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2547
Definition: InternalNode.h:29
Definition: InternalNode.h:119
Coord & setZ(Int32 z)
Definition: Coord.h:81
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:175
ChildIter()
Definition: InternalNode.h:130
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:748
InternalNode * t
Definition: InternalNode.h:928
ValueT value
Definition: GridBuilder.h:1290
LeafNodeType * touchLeaf(const Coord &xyz)
Return the leaf node that contains voxel (x, y, z). If no such node exists, create one...
Definition: InternalNode.h:1466
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:232
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:141
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:1107
void operator()(W &tV, const W &sC, const W &sV, const W &tC) const
Definition: InternalNode.h:2600
void translate(const Coord &t)
Translate this bounding box by (tx, ty, tz).
Definition: Coord.h:458
TopologyCopy2(const OtherInternalNode *source, InternalNode *target, const ValueType &offValue, const ValueType &onValue)
Definition: InternalNode.h:951
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:3105
const ValueT & getValue() const
Definition: NodeUnion.h:43
uint32_t Index32
Definition: Types.h:52
Definition: InternalNode.h:2495
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:956
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:269
Index64 offVoxelCount() const
Definition: InternalNode.h:1061
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1640
typename NodeMaskType::Word W
Definition: InternalNode.h:2546
VoxelizeActiveTiles(InternalNode &node)
Definition: InternalNode.h:2307
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:91
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: InternalNode.h:2952
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1582
Definition: NodeMasks.h:239
Index64 onVoxelCount() const
Definition: InternalNode.h:1049
Definition: InternalNode.h:148
ChildOnIter beginChildOn()
Definition: InternalNode.h:226
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: InternalNode.h:1814
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1707
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1627
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:162
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2861
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:412
bool isEmpty() const
Definition: InternalNode.h:302
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:483
void operator()(W &tV, const W &sV, const W &tC) const
Definition: InternalNode.h:2495
ChildT & getItem(Index pos) const
Definition: InternalNode.h:134
bool addChild(ChildNodeType *child)
Add the given child node at this level deducing the offset from it's origin. If a child node with thi...
Definition: InternalNode.h:1372
InternalNode * t
Definition: InternalNode.h:967
void denseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value and ensure that those voxels are a...
Definition: InternalNode.h:2090
void merge(InternalNode &other, const ValueType &background, const ValueType &otherBackground)
Efficiently merge another tree into this tree using one of several schemes.
Definition: InternalNode.h:2353
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:223
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:1073
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1499
Int32 z() const
Definition: Coord.h:132
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2597
Definition: NodeMasks.h:208
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:177
void topologyIntersection(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background)
Intersects this tree's set of active values with the active values of the other tree, whose ValueType may be different.
const ValueType & b
Definition: InternalNode.h:2640
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1930
const ValueType & b
Definition: InternalNode.h:2580
void setValueMask(Index n, bool on)
Definition: InternalNode.h:767
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:644
void prune(const ValueType &tolerance=zeroVal< ValueType >())
Reduce the memory footprint of this tree by replacing with tiles any nodes whose values are all the s...
Definition: InternalNode.h:1138
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2511
bool isValueMaskOn() const
Definition: InternalNode.h:747
bool isValueMaskOff() const
Definition: InternalNode.h:749
void resetBackground(const ValueType &oldBackground, const ValueType &newBackground)
Change inactive tiles or voxels with value oldBackground to newBackground or -oldBackground to -newBa...
Definition: InternalNode.h:3023
Definition: InternalNode.h:2547
NodeT * stealNode(const Coord &xyz, const ValueType &value, bool state)
Return a pointer to the node of type NodeT that contains voxel (x, y, z) and replace it with a tile o...
Definition: InternalNode.h:1162
bool resultIsActive() const
Definition: Types.h:593
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:335
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don't change its active state.
Definition: InternalNode.h:1776
typename NodeMaskType::Word W
Definition: InternalNode.h:2596
NodeMaskType mChildMask
Definition: InternalNode.h:795
Index32 childCount() const
Definition: InternalNode.h:1041
const bool mPreserveTiles
Definition: InternalNode.h:2531
OPENVDB_API const void * getGridBackgroundValuePtr(std::ios_base &)
Return a pointer to the background value of the grid currently being read from or written to the give...
Definition: InternalNode.h:2600
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:221
bool isChildMaskOff() const
Definition: InternalNode.h:752
ChildOffIter beginChildOff()
Definition: InternalNode.h:227
ChildAllIter beginChildAll()
Definition: InternalNode.h:228
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:155
void nodeCount(std::vector< Index32 > &vec) const
Definition: InternalNode.h:1015
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:2937
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:230
NodeMaskType getValueOffMask() const
Definition: InternalNode.h:755
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3071
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:529
const Coord & min() const
Definition: Coord.h:321
_ChildNodeType ChildNodeType
Definition: InternalNode.h:36
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: InternalNode.h:1290
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:141
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:114
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2871
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:55
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:1085
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:178
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by the node regardless of it...
Definition: InternalNode.h:299
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:234
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
Expand the specified bounding box so that it includes the active tiles of this internal node as well ...
Definition: InternalNode.h:1120
Index getValueLevel(const Coord &xyz) const
Return the level of the tree (0 = leaf) at which the value at the given coordinates resides...
Definition: InternalNode.h:1605
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212
const NodeMaskType & getValueMask() const
Definition: InternalNode.h:753
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:650
ChildT * getChild() const
Definition: NodeUnion.h:40
void topologyDifference(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background)
Difference this node's set of active values with the active values of the other node, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this node and inactive in the other node.
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:452
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:...
Definition: InternalNode.h:2996