8 #ifndef OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 9 #define OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 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>
65 static const bool value =
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);
111 #if OPENVDB_ABI_VERSION_NUMBER < 5 130 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
132 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
136 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
140 assert(this->parent().isChildMaskOn(pos));
141 return *(this->parent().getChildNode(pos));
145 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
151 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
153 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
157 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
159 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
162 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
165 template<
typename ModifyOp>
168 op(this->parent().mNodes[pos].getValue());
173 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
175 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
186 if (this->parent().isChildMaskOn(pos)) {
187 child = this->parent().getChildNode(pos);
191 value = this->parent().mNodes[pos].getValue();
198 this->parent().resetChildNode(pos, child);
204 this->parent().unsetChildNode(pos, value);
256 static void getNodeLog2Dims(std::vector<Index>& dims);
266 static void offsetToLocalCoord(
Index n,
Coord& xyz);
276 void nodeCount(std::vector<Index32> &vec)
const;
280 Index64 onLeafVoxelCount()
const;
281 Index64 offLeafVoxelCount()
const;
291 void evalActiveBoundingBox(
CoordBBox& bbox,
bool visitVoxels =
true)
const;
298 bool isEmpty()
const {
return mChildMask.isOff(); }
305 bool isConstant(ValueType& firstValue,
bool& state,
306 const ValueType& tolerance = zeroVal<ValueType>())
const;
322 bool isConstant(ValueType& minValue, ValueType& maxValue,
323 bool& state,
const ValueType& tolerance = zeroVal<ValueType>())
const;
326 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
329 bool isValueOn(
const Coord& xyz)
const;
334 bool hasActiveTiles()
const;
336 const ValueType& getValue(
const Coord& xyz)
const;
337 bool probeValue(
const Coord& xyz, ValueType& value)
const;
345 const ValueType& getFirstValue()
const;
348 const ValueType& getLastValue()
const;
351 void setActiveState(
const Coord& xyz,
bool on);
353 void setValueOnly(
const Coord& xyz,
const ValueType& value);
355 void setValueOn(
const Coord& xyz);
357 void setValueOn(
const Coord& xyz,
const ValueType& value);
359 void setValueOff(
const Coord& xyz);
361 void setValueOff(
const Coord& xyz,
const ValueType& value);
365 template<
typename ModifyOp>
366 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
368 template<
typename ModifyOp>
369 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
375 template<
typename AccessorT>
376 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
382 template<
typename AccessorT>
383 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
389 template<
typename AccessorT>
390 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
396 template<
typename AccessorT>
397 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
404 template<
typename ModifyOp,
typename AccessorT>
405 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
411 template<
typename ModifyOp,
typename AccessorT>
412 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
418 template<
typename AccessorT>
419 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
425 template<
typename AccessorT>
426 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
433 template<
typename AccessorT>
434 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
442 template<
typename AccessorT>
443 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
451 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
452 void readTopology(std::istream&,
bool fromHalf =
false);
453 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
454 void readBuffers(std::istream&,
bool fromHalf =
false);
455 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
473 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
482 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
487 void voxelizeActiveTiles(
bool threaded =
true);
496 template<
typename DenseT>
501 template<MergePolicy Policy>
502 void merge(
InternalNode& other,
const ValueType& background,
const ValueType& otherBackground);
506 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
520 template<
typename OtherChildNodeType>
536 template<
typename OtherChildNodeType>
538 const ValueType& background);
551 template<
typename OtherChildNodeType>
553 const ValueType& background);
555 template<
typename CombineOp>
557 template<
typename CombineOp>
558 void combine(
const ValueType& value,
bool valueIsActive, CombineOp&);
560 template<
typename CombineOp,
typename OtherNodeType >
561 void combine2(
const InternalNode& other0,
const OtherNodeType& other1, CombineOp&);
562 template<
typename CombineOp,
typename OtherNodeType >
563 void combine2(
const ValueType& value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
564 template<
typename CombineOp,
typename OtherValueType>
565 void combine2(
const InternalNode& other,
const OtherValueType&,
bool valIsActive, CombineOp&);
572 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
574 template<
typename VisitorOp>
void visit(VisitorOp&);
575 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
577 template<
typename OtherNodeType,
typename VisitorOp>
578 void visit2Node(OtherNodeType& other, VisitorOp&);
579 template<
typename OtherNodeType,
typename VisitorOp>
580 void visit2Node(OtherNodeType& other, VisitorOp&)
const;
581 template<
typename IterT,
typename VisitorOp>
582 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
583 template<
typename IterT,
typename VisitorOp>
584 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
592 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
596 void addLeaf(LeafNodeType* leaf);
600 template<
typename AccessorT>
601 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
611 template<
typename NodeT>
612 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
620 bool addChild(ChildNodeType* child);
624 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
627 void addTile(
Index offset,
const ValueType& value,
bool state);
631 template<
typename AccessorT>
632 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
635 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
638 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
642 template<
typename NodeType,
typename AccessorT>
645 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
646 template<
typename NodeType,
typename AccessorT>
647 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
651 LeafNodeType* probeLeaf(
const Coord& xyz);
654 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
655 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
659 template<
typename AccessorT>
662 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
663 template<
typename AccessorT>
664 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
665 template<
typename AccessorT>
666 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
675 LeafNodeType* touchLeaf(
const Coord& xyz);
679 template<
typename AccessorT>
680 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
683 template<
typename ArrayT>
706 void getNodes(ArrayT& array);
707 template<
typename ArrayT>
708 void getNodes(ArrayT& array)
const;
734 template<
typename ArrayT>
735 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
739 void resetBackground(
const ValueType& oldBackground,
const ValueType& newBackground);
743 template<
typename OtherChildNodeType, Index OtherLog2Dim>
780 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ? false : on); }
785 void makeChildNodeEmpty(
Index n,
const ValueType& value);
786 void setChildNode(
Index i, ChildNodeType* child);
787 void resetChildNode(
Index i, ChildNodeType* child);
788 ChildNodeType* unsetChildNode(
Index i,
const ValueType& value);
790 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
791 static inline void doVisit(NodeT&, VisitorOp&);
793 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
794 typename ChildAllIterT,
typename OtherChildAllIterT>
795 static inline void doVisit2Node(NodeT&, OtherNodeT&, VisitorOp&);
797 template<
typename NodeT,
typename VisitorOp,
798 typename ChildAllIterT,
typename OtherChildAllIterT>
799 static inline void doVisit2(NodeT&, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
805 ChildNodeType* getChildNode(
Index n);
806 const ChildNodeType* getChildNode(
Index n)
const;
811 struct VoxelizeActiveTiles;
812 template<
typename OtherInternalNode>
struct DeepCopy;
831 template<
typename ChildT1, Index Dim1,
typename NodeT2>
835 static const bool value =
false;
838 template<
typename ChildT1, Index Dim1,
typename ChildT2>
840 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
848 template<
typename ChildT, Index Log2Dim>
852 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
856 template<
typename ChildT, Index Log2Dim>
859 mOrigin(origin[0] & ~(DIM - 1),
860 origin[1] & ~(DIM - 1),
861 origin[2] & ~(DIM - 1))
870 template<
typename ChildT, Index Log2Dim>
874 : mOrigin(origin[0] & ~(DIM-1), origin[1] & ~(DIM-1), origin[2] & ~(DIM-1))
880 template<
typename ChildT, Index Log2Dim>
881 template<
typename OtherInternalNode>
885 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
889 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
890 if (s->mChildMask.isOff(i)) {
891 t->mNodes[i].setValue(
ValueType(s->mNodes[i].getValue()));
893 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild())));
897 const OtherInternalNode*
s;
901 template<
typename ChildT, Index Log2Dim>
904 mChildMask(other.mChildMask),
905 mValueMask(other.mValueMask),
906 mOrigin(other.mOrigin)
913 template<
typename ChildT, Index Log2Dim>
914 template<
typename OtherChildNodeType>
917 : mChildMask(other.mChildMask)
918 , mValueMask(other.mValueMask)
919 , mOrigin(other.mOrigin)
924 template<
typename ChildT, Index Log2Dim>
925 template<
typename OtherInternalNode>
929 const ValueType& background) : s(source), t(target), b(background) {
930 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
934 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
935 if (s->isChildMaskOn(i)) {
936 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
939 t->mNodes[i].setValue(b);
943 const OtherInternalNode*
s;
948 template<
typename ChildT, Index Log2Dim>
949 template<
typename OtherChildNodeType>
953 mChildMask(other.mChildMask),
954 mValueMask(other.mValueMask),
955 mOrigin(other.mOrigin)
960 template<
typename ChildT, Index Log2Dim>
961 template<
typename OtherInternalNode>
966 : s(source), t(target), offV(offValue), onV(onValue) {
967 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
970 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
971 if (s->isChildMaskOn(i)) {
972 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
975 t->mNodes[i].setValue(s->isValueMaskOn(i) ? onV : offV);
979 const OtherInternalNode*
s;
984 template<
typename ChildT, Index Log2Dim>
985 template<
typename OtherChildNodeType>
990 mChildMask(other.mChildMask),
991 mValueMask(other.mValueMask),
992 mOrigin(other.mOrigin)
998 template<
typename ChildT, Index Log2Dim>
1002 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1003 delete mNodes[iter.pos()].getChild();
1011 template<
typename ChildT, Index Log2Dim>
1017 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1018 sum += iter->leafCount();
1023 template<
typename ChildT, Index Log2Dim>
1027 assert(vec.size() > ChildNodeType::LEVEL);
1028 const auto count = mChildMask.countOn();
1029 if (ChildNodeType::LEVEL > 0 && count > 0) {
1030 for (
auto iter = this->cbeginChildOn(); iter; ++iter) iter->nodeCount(vec);
1032 vec[ChildNodeType::LEVEL] += count;
1036 template<
typename ChildT, Index Log2Dim>
1042 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1043 sum += iter->nonLeafCount();
1049 template<
typename ChildT, Index Log2Dim>
1053 Index64 sum = ChildT::NUM_VOXELS * mValueMask.countOn();
1054 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1055 sum += iter->onVoxelCount();
1061 template<
typename ChildT, Index Log2Dim>
1065 Index64 sum = ChildT::NUM_VOXELS * (NUM_VALUES-mValueMask.countOn()-mChildMask.countOn());
1066 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1067 sum += iter->offVoxelCount();
1073 template<
typename ChildT, Index Log2Dim>
1078 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
1079 sum += mNodes[iter.pos()].getChild()->onLeafVoxelCount();
1085 template<
typename ChildT, Index Log2Dim>
1090 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
1091 sum += mNodes[iter.pos()].getChild()->offLeafVoxelCount();
1096 template<
typename ChildT, Index Log2Dim>
1100 Index64 sum = mValueMask.countOn();
1101 for (
ChildOnCIter iter = this->cbeginChildOn(); LEVEL>1 && iter; ++iter) {
1102 sum += iter->onTileCount();
1107 template<
typename ChildT, Index Log2Dim>
1112 + mValueMask.memUsage() +
sizeof(mOrigin);
1113 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1114 sum += iter->memUsage();
1120 template<
typename ChildT, Index Log2Dim>
1124 if (bbox.
isInside(this->getNodeBoundingBox()))
return;
1127 bbox.
expand(i.getCoord(), ChildT::DIM);
1130 i->evalActiveBoundingBox(bbox, visitVoxels);
1138 template<
typename ChildT, Index Log2Dim>
1144 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1145 const Index i = iter.pos();
1146 ChildT* child = mNodes[i].getChild();
1147 child->prune(tolerance);
1148 if (child->isConstant(value, state, tolerance)) {
1150 mChildMask.setOff(i);
1151 mValueMask.set(i, state);
1152 mNodes[i].setValue(value);
1161 template<
typename ChildT, Index Log2Dim>
1162 template<
typename NodeT>
1166 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1167 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1169 const Index n = this->coordToOffset(xyz);
1170 if (mChildMask.isOff(n))
return nullptr;
1171 ChildT* child = mNodes[n].getChild();
1172 if (std::is_same<NodeT, ChildT>::value) {
1173 mChildMask.setOff(n);
1174 mValueMask.set(n, state);
1175 mNodes[n].setValue(value);
1177 return (std::is_same<NodeT, ChildT>::value)
1178 ?
reinterpret_cast<NodeT*
>(child)
1179 : child->template stealNode<NodeT>(xyz, value, state);
1187 template<
typename ChildT, Index Log2Dim>
1188 template<
typename NodeT>
1192 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1193 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1195 const Index n = this->coordToOffset(xyz);
1196 if (mChildMask.isOff(n))
return nullptr;
1197 ChildT* child = mNodes[n].getChild();
1198 return (std::is_same<NodeT, ChildT>::value)
1199 ?
reinterpret_cast<NodeT*
>(child)
1200 : child->template probeNode<NodeT>(xyz);
1205 template<
typename ChildT, Index Log2Dim>
1206 template<
typename NodeT,
typename AccessorT>
1210 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1211 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1213 const Index n = this->coordToOffset(xyz);
1214 if (mChildMask.isOff(n))
return nullptr;
1215 ChildT* child = mNodes[n].getChild();
1216 acc.insert(xyz, child);
1217 return (std::is_same<NodeT, ChildT>::value)
1218 ?
reinterpret_cast<NodeT*
>(child)
1219 : child->template probeNodeAndCache<NodeT>(xyz, acc);
1224 template<
typename ChildT, Index Log2Dim>
1225 template<
typename NodeT>
1229 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1230 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1232 const Index n = this->coordToOffset(xyz);
1233 if (mChildMask.isOff(n))
return nullptr;
1234 const ChildT* child = mNodes[n].getChild();
1235 return (std::is_same<NodeT, ChildT>::value)
1236 ?
reinterpret_cast<const NodeT*
>(child)
1237 : child->template probeConstNode<NodeT>(xyz);
1242 template<
typename ChildT, Index Log2Dim>
1243 template<
typename NodeT,
typename AccessorT>
1247 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1248 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1250 const Index n = this->coordToOffset(xyz);
1251 if (mChildMask.isOff(n))
return nullptr;
1252 const ChildT* child = mNodes[n].getChild();
1253 acc.insert(xyz, child);
1254 return (std::is_same<NodeT, ChildT>::value)
1255 ?
reinterpret_cast<const NodeT*
>(child)
1256 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1264 template<
typename ChildT, Index Log2Dim>
1265 inline typename ChildT::LeafNodeType*
1268 return this->
template probeNode<LeafNodeType>(xyz);
1272 template<
typename ChildT, Index Log2Dim>
1273 template<
typename AccessorT>
1274 inline typename ChildT::LeafNodeType*
1277 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1281 template<
typename ChildT, Index Log2Dim>
1282 template<
typename AccessorT>
1283 inline const typename ChildT::LeafNodeType*
1286 return this->probeConstLeafAndCache(xyz, acc);
1290 template<
typename ChildT, Index Log2Dim>
1291 inline const typename ChildT::LeafNodeType*
1294 return this->
template probeConstNode<LeafNodeType>(xyz);
1298 template<
typename ChildT, Index Log2Dim>
1299 template<
typename AccessorT>
1300 inline const typename ChildT::LeafNodeType*
1303 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1310 template<
typename ChildT, Index Log2Dim>
1314 assert(leaf !=
nullptr);
1315 const Coord& xyz = leaf->origin();
1316 const Index n = this->coordToOffset(xyz);
1317 ChildT* child =
nullptr;
1318 if (mChildMask.isOff(n)) {
1319 if (ChildT::LEVEL>0) {
1320 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1322 child =
reinterpret_cast<ChildT*
>(leaf);
1324 this->setChildNode(n, child);
1326 if (ChildT::LEVEL>0) {
1327 child = mNodes[n].getChild();
1329 delete mNodes[n].getChild();
1330 child =
reinterpret_cast<ChildT*
>(leaf);
1331 mNodes[n].setChild(child);
1334 child->addLeaf(leaf);
1338 template<
typename ChildT, Index Log2Dim>
1339 template<
typename AccessorT>
1343 assert(leaf !=
nullptr);
1344 const Coord& xyz = leaf->origin();
1345 const Index n = this->coordToOffset(xyz);
1346 ChildT* child =
nullptr;
1347 if (mChildMask.isOff(n)) {
1348 if (ChildT::LEVEL>0) {
1349 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1350 acc.insert(xyz, child);
1352 child =
reinterpret_cast<ChildT*
>(leaf);
1354 this->setChildNode(n, child);
1356 if (ChildT::LEVEL>0) {
1357 child = mNodes[n].getChild();
1358 acc.insert(xyz, child);
1360 delete mNodes[n].getChild();
1361 child =
reinterpret_cast<ChildT*
>(leaf);
1362 mNodes[n].setChild(child);
1365 child->addLeafAndCache(leaf, acc);
1372 template<
typename ChildT, Index Log2Dim>
1377 const Coord& xyz = child->origin();
1379 if (
Coord((xyz & ~(DIM-1))) != this->origin())
return false;
1381 const Index n = this->coordToOffset(xyz);
1383 this->resetChildNode(n, child);
1388 template<
typename ChildT, Index Log2Dim>
1392 assert(n < NUM_VALUES);
1393 this->makeChildNodeEmpty(n, value);
1394 mValueMask.set(n, state);
1398 template<
typename ChildT, Index Log2Dim>
1403 if (LEVEL >= level) {
1404 const Index n = this->coordToOffset(xyz);
1405 if (mChildMask.isOff(n)) {
1406 if (LEVEL > level) {
1407 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1408 this->setChildNode(n, child);
1409 child->addTile(level, xyz, value, state);
1411 mValueMask.set(n, state);
1412 mNodes[n].setValue(value);
1415 ChildT* child = mNodes[n].getChild();
1416 if (LEVEL > level) {
1417 child->addTile(level, xyz, value, state);
1420 mChildMask.setOff(n);
1421 mValueMask.set(n, state);
1422 mNodes[n].setValue(value);
1429 template<
typename ChildT, Index Log2Dim>
1430 template<
typename AccessorT>
1433 const ValueType& value,
bool state, AccessorT& acc)
1435 if (LEVEL >= level) {
1436 const Index n = this->coordToOffset(xyz);
1437 if (mChildMask.isOff(n)) {
1438 if (LEVEL > level) {
1439 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1440 this->setChildNode(n, child);
1441 acc.insert(xyz, child);
1442 child->addTileAndCache(level, xyz, value, state, acc);
1444 mValueMask.set(n, state);
1445 mNodes[n].setValue(value);
1448 ChildT* child = mNodes[n].getChild();
1449 if (LEVEL > level) {
1450 acc.insert(xyz, child);
1451 child->addTileAndCache(level, xyz, value, state, acc);
1454 mChildMask.setOff(n);
1455 mValueMask.set(n, state);
1456 mNodes[n].setValue(value);
1466 template<
typename ChildT, Index Log2Dim>
1467 inline typename ChildT::LeafNodeType*
1470 const Index n = this->coordToOffset(xyz);
1471 ChildT* child =
nullptr;
1472 if (mChildMask.isOff(n)) {
1473 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1474 this->setChildNode(n, child);
1476 child = mNodes[n].getChild();
1478 return child->touchLeaf(xyz);
1482 template<
typename ChildT, Index Log2Dim>
1483 template<
typename AccessorT>
1484 inline typename ChildT::LeafNodeType*
1487 const Index n = this->coordToOffset(xyz);
1488 if (mChildMask.isOff(n)) {
1489 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), mValueMask.isOn(n)));
1491 acc.insert(xyz, mNodes[n].getChild());
1492 return mNodes[n].getChild()->touchLeafAndCache(xyz, acc);
1499 template<
typename ChildT, Index Log2Dim>
1504 if (!mChildMask.isOff() || !mValueMask.isConstant(state))
return false;
1506 firstValue = mNodes[0].getValue();
1507 for (
Index i = 1; i < NUM_VALUES; ++i) {
1519 template<
typename ChildT, Index Log2Dim>
1527 if (!mChildMask.isOff() || !mValueMask.isConstant(state))
return false;
1528 minValue = maxValue = mNodes[0].getValue();
1529 for (
Index i = 1; i < NUM_VALUES; ++i) {
1530 const ValueType& v = mNodes[i].getValue();
1532 if ((maxValue - v) > tolerance)
return false;
1534 }
else if (v > maxValue) {
1535 if ((v - minValue) > tolerance)
return false;
1546 template<
typename ChildT, Index Log2Dim>
1551 const bool anyActiveTiles = !mValueMask.isOff();
1552 if (LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1553 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1554 if (iter->hasActiveTiles())
return true;
1561 template<
typename ChildT, Index Log2Dim>
1565 const Index n = this->coordToOffset(xyz);
1566 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1567 return mNodes[n].getChild()->isValueOn(xyz);
1570 template<
typename ChildT, Index Log2Dim>
1571 template<
typename AccessorT>
1575 const Index n = this->coordToOffset(xyz);
1576 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1577 acc.insert(xyz, mNodes[n].getChild());
1578 return mNodes[n].getChild()->isValueOnAndCache(xyz, acc);
1582 template<
typename ChildT, Index Log2Dim>
1583 inline const typename ChildT::ValueType&
1586 const Index n = this->coordToOffset(xyz);
1587 return this->isChildMaskOff(n) ? mNodes[n].getValue()
1588 : mNodes[n].getChild()->getValue(xyz);
1591 template<
typename ChildT, Index Log2Dim>
1592 template<
typename AccessorT>
1593 inline const typename ChildT::ValueType&
1596 const Index n = this->coordToOffset(xyz);
1597 if (this->isChildMaskOn(n)) {
1598 acc.insert(xyz, mNodes[n].getChild());
1599 return mNodes[n].getChild()->getValueAndCache(xyz, acc);
1601 return mNodes[n].getValue();
1605 template<
typename ChildT, Index Log2Dim>
1609 const Index n = this->coordToOffset(xyz);
1610 return this->isChildMaskOff(n) ? LEVEL : mNodes[n].getChild()->getValueLevel(xyz);
1613 template<
typename ChildT, Index Log2Dim>
1614 template<
typename AccessorT>
1618 const Index n = this->coordToOffset(xyz);
1619 if (this->isChildMaskOn(n)) {
1620 acc.insert(xyz, mNodes[n].getChild());
1621 return mNodes[n].getChild()->getValueLevelAndCache(xyz, acc);
1627 template<
typename ChildT, Index Log2Dim>
1631 const Index n = this->coordToOffset(xyz);
1632 if (this->isChildMaskOff(n)) {
1633 value = mNodes[n].getValue();
1634 return this->isValueMaskOn(n);
1636 return mNodes[n].getChild()->probeValue(xyz, value);
1639 template<
typename ChildT, Index Log2Dim>
1640 template<
typename AccessorT>
1645 const Index n = this->coordToOffset(xyz);
1646 if (this->isChildMaskOn(n)) {
1647 acc.insert(xyz, mNodes[n].getChild());
1648 return mNodes[n].getChild()->probeValueAndCache(xyz, value, acc);
1650 value = mNodes[n].getValue();
1651 return this->isValueMaskOn(n);
1655 template<
typename ChildT, Index Log2Dim>
1659 const Index n = this->coordToOffset(xyz);
1660 bool hasChild = this->isChildMaskOn(n);
1661 if (!hasChild && this->isValueMaskOn(n)) {
1665 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
true));
1667 if (hasChild) mNodes[n].getChild()->setValueOff(xyz);
1671 template<
typename ChildT, Index Log2Dim>
1675 const Index n = this->coordToOffset(xyz);
1676 bool hasChild = this->isChildMaskOn(n);
1677 if (!hasChild && !this->isValueMaskOn(n)) {
1681 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
false));
1683 if (hasChild) mNodes[n].getChild()->setValueOn(xyz);
1687 template<
typename ChildT, Index Log2Dim>
1692 bool hasChild = this->isChildMaskOn(n);
1694 const bool active = this->isValueMaskOn(n);
1700 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1703 if (hasChild) mNodes[n].getChild()->setValueOff(xyz, value);
1706 template<
typename ChildT, Index Log2Dim>
1707 template<
typename AccessorT>
1713 bool hasChild = this->isChildMaskOn(n);
1715 const bool active = this->isValueMaskOn(n);
1721 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1725 ChildT* child = mNodes[n].getChild();
1726 acc.insert(xyz, child);
1727 child->setValueOffAndCache(xyz, value, acc);
1732 template<
typename ChildT, Index Log2Dim>
1736 const Index n = this->coordToOffset(xyz);
1737 bool hasChild = this->isChildMaskOn(n);
1739 const bool active = this->isValueMaskOn(n);
1745 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1748 if (hasChild) mNodes[n].getChild()->setValueOn(xyz, value);
1751 template<
typename ChildT, Index Log2Dim>
1752 template<
typename AccessorT>
1757 const Index n = this->coordToOffset(xyz);
1758 bool hasChild = this->isChildMaskOn(n);
1760 const bool active = this->isValueMaskOn(n);
1766 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1770 acc.insert(xyz, mNodes[n].getChild());
1771 mNodes[n].getChild()->setValueAndCache(xyz, value, acc);
1776 template<
typename ChildT, Index Log2Dim>
1780 const Index n = this->coordToOffset(xyz);
1781 bool hasChild = this->isChildMaskOn(n);
1785 const bool active = this->isValueMaskOn(n);
1787 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1789 if (hasChild) mNodes[n].getChild()->setValueOnly(xyz, value);
1792 template<
typename ChildT, Index Log2Dim>
1793 template<
typename AccessorT>
1798 const Index n = this->coordToOffset(xyz);
1799 bool hasChild = this->isChildMaskOn(n);
1803 const bool active = this->isValueMaskOn(n);
1805 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1808 acc.insert(xyz, mNodes[n].getChild());
1809 mNodes[n].getChild()->setValueOnlyAndCache(xyz, value, acc);
1814 template<
typename ChildT, Index Log2Dim>
1818 const Index n = this->coordToOffset(xyz);
1819 bool hasChild = this->isChildMaskOn(n);
1821 if (on != this->isValueMaskOn(n)) {
1826 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1829 if (hasChild) mNodes[n].getChild()->setActiveState(xyz, on);
1832 template<
typename ChildT, Index Log2Dim>
1833 template<
typename AccessorT>
1837 const Index n = this->coordToOffset(xyz);
1838 bool hasChild = this->isChildMaskOn(n);
1840 if (on != this->isValueMaskOn(n)) {
1845 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1849 ChildT* child = mNodes[n].getChild();
1850 acc.insert(xyz, child);
1851 child->setActiveStateAndCache(xyz, on, acc);
1856 template<
typename ChildT, Index Log2Dim>
1860 mValueMask = !mChildMask;
1861 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1862 mNodes[iter.pos()].getChild()->setValuesOn();
1867 template<
typename ChildT, Index Log2Dim>
1868 template<
typename ModifyOp>
1873 bool hasChild = this->isChildMaskOn(n);
1877 const bool active = this->isValueMaskOn(n);
1878 bool createChild = !active;
1882 const ValueType& tileVal = mNodes[n].getValue();
1889 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1892 if (hasChild) mNodes[n].getChild()->modifyValue(xyz, op);
1895 template<
typename ChildT, Index Log2Dim>
1896 template<
typename ModifyOp,
typename AccessorT>
1902 bool hasChild = this->isChildMaskOn(n);
1906 const bool active = this->isValueMaskOn(n);
1907 bool createChild = !active;
1911 const ValueType& tileVal = mNodes[n].getValue();
1918 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1923 acc.insert(xyz, child);
1924 child->modifyValueAndCache(xyz, op, acc);
1929 template<
typename ChildT, Index Log2Dim>
1930 template<
typename ModifyOp>
1935 bool hasChild = this->isChildMaskOn(n);
1937 const bool tileState = this->isValueMaskOn(n);
1938 const ValueType& tileVal = mNodes[n].getValue();
1939 bool modifiedState = !tileState;
1941 op(modifiedVal, modifiedState);
1946 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1949 if (hasChild) mNodes[n].getChild()->modifyValueAndActiveState(xyz, op);
1952 template<
typename ChildT, Index Log2Dim>
1953 template<
typename ModifyOp,
typename AccessorT>
1956 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1959 bool hasChild = this->isChildMaskOn(n);
1961 const bool tileState = this->isValueMaskOn(n);
1962 const ValueType& tileVal = mNodes[n].getValue();
1963 bool modifiedState = !tileState;
1965 op(modifiedVal, modifiedState);
1970 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1975 acc.insert(xyz, child);
1976 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1984 template<
typename ChildT, Index Log2Dim>
1988 CoordBBox nodeBBox = this->getNodeBoundingBox();
1991 this->fill(nodeBBox, background,
false);
1992 }
else if (clipBBox.
isInside(nodeBBox)) {
2001 for (
Index pos = 0; pos < NUM_VALUES; ++pos) {
2002 const Coord xyz = this->offsetToGlobalCoord(pos);
2007 this->makeChildNodeEmpty(pos, background);
2008 mValueMask.setOff(pos);
2009 }
else if (!clipBBox.
isInside(tileBBox)) {
2012 if (this->isChildMaskOn(pos)) {
2013 mNodes[pos].getChild()->clip(clipBBox, background);
2017 tileBBox.intersect(clipBBox);
2018 const ValueType val = mNodes[pos].getValue();
2019 const bool on = this->isValueMaskOn(pos);
2020 mNodes[pos].setValue(background);
2021 mValueMask.setOff(pos);
2022 this->fill(tileBBox, val, on);
2034 template<
typename ChildT, Index Log2Dim>
2038 auto clippedBBox = this->getNodeBoundingBox();
2039 clippedBBox.intersect(bbox);
2040 if (!clippedBBox)
return;
2044 Coord xyz, tileMin, tileMax;
2045 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2047 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2049 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2053 const Index n = this->coordToOffset(xyz);
2054 tileMin = this->offsetToGlobalCoord(n);
2055 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2061 ChildT* child =
nullptr;
2062 if (this->isChildMaskOff(n)) {
2065 child =
new ChildT{xyz, mNodes[n].getValue(), this->isValueMaskOn(n)};
2066 this->setChildNode(n, child);
2068 child = mNodes[n].getChild();
2074 child->fill(
CoordBBox(xyz, tmp), value, active);
2081 this->makeChildNodeEmpty(n, value);
2082 mValueMask.set(n, active);
2090 template<
typename ChildT, Index Log2Dim>
2094 auto clippedBBox = this->getNodeBoundingBox();
2095 clippedBBox.intersect(bbox);
2096 if (!clippedBBox)
return;
2100 Coord xyz, tileMin, tileMax;
2101 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2103 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2105 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2109 const auto n = this->coordToOffset(xyz);
2112 ChildT* child =
nullptr;
2113 if (this->isChildMaskOn(n)) {
2114 child = mNodes[n].getChild();
2118 child =
new ChildT{xyz, mNodes[n].getValue(), this->isValueMaskOn(n)};
2119 this->setChildNode(n, child);
2123 tileMin = this->offsetToGlobalCoord(n);
2124 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2127 child->denseFill(
CoordBBox{xyz, clippedBBox.
max()}, value, active);
2137 template<
typename ChildT, Index Log2Dim>
2138 template<
typename DenseT>
2142 using DenseValueType =
typename DenseT::ValueType;
2144 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2145 const Coord&
min = dense.bbox().min();
2146 for (
Coord xyz = bbox.
min(),
max; xyz[0] <= bbox.
max()[0]; xyz[0] =
max[0] + 1) {
2147 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] =
max[1] + 1) {
2148 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] =
max[2] + 1) {
2149 const Index n = this->coordToOffset(xyz);
2151 max = this->offsetToGlobalCoord(n).offsetBy(ChildT::DIM-1);
2156 if (this->isChildMaskOn(n)) {
2157 mNodes[n].getChild()->copyToDense(sub, dense);
2159 const ValueType value = mNodes[n].getValue();
2161 DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
2162 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
2163 DenseValueType* a1 = a0 + x*xStride;
2164 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
2165 DenseValueType* a2 = a1 + y*yStride;
2167 z < ez; ++z, a2 += zStride)
2169 *a2 = DenseValueType(value);
2183 template<
typename ChildT, Index Log2Dim>
2187 mChildMask.save(os);
2188 mValueMask.save(os);
2192 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[NUM_VALUES]);
2194 const ValueType zero = zeroVal<ValueType>();
2195 for (
Index i = 0; i < NUM_VALUES; ++i) {
2196 values[i] = (mChildMask.isOff(i) ? mNodes[i].getValue() : zero);
2202 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2203 iter->writeTopology(os, toHalf);
2208 template<
typename ChildT, Index Log2Dim>
2215 mChildMask.load(is);
2216 mValueMask.load(is);
2219 for (
Index i = 0; i < NUM_VALUES; ++i) {
2220 if (this->isChildMaskOn(i)) {
2223 mNodes[i].setChild(child);
2224 child->readTopology(is);
2227 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2228 mNodes[i].setValue(value);
2232 const bool oldVersion =
2234 const Index numValues = (oldVersion ? mChildMask.countOff() : NUM_VALUES);
2238 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[numValues]);
2245 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
2246 mNodes[iter.pos()].setValue(values[n++]);
2248 assert(n == numValues);
2250 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
2251 mNodes[iter.pos()].setValue(values[iter.pos()]);
2256 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2258 mNodes[iter.pos()].setChild(child);
2259 child->readTopology(is, fromHalf);
2268 template<
typename ChildT, Index Log2Dim>
2269 inline const typename ChildT::ValueType&
2272 return (this->isChildMaskOn(0) ? mNodes[0].getChild()->getFirstValue() : mNodes[0].getValue());
2276 template<
typename ChildT, Index Log2Dim>
2277 inline const typename ChildT::ValueType&
2280 const Index n = NUM_VALUES - 1;
2281 return (this->isChildMaskOn(n) ? mNodes[n].getChild()->getLastValue() : mNodes[n].getValue());
2288 template<
typename ChildT, Index Log2Dim>
2292 for (
Index i = 0; i < NUM_VALUES; ++i) {
2293 if (this->isChildMaskOn(i)) {
2294 mNodes[i].getChild()->negate();
2306 template<
typename ChildT, Index Log2Dim>
2311 tbb::parallel_for(tbb::blocked_range<Index>(0, NUM_VALUES), *
this);
2318 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2319 if (mNode->mChildMask.isOn(i)) {
2320 mNode->mNodes[i].getChild()->voxelizeActiveTiles(
true);
2321 }
else if (mNode->mValueMask.isOn(i)) {
2322 const Coord &ijk = mNode->offsetToGlobalCoord(i);
2324 child->voxelizeActiveTiles(
true);
2325 mNode->mNodes[i].setChild(child);
2332 template<
typename ChildT, Index Log2Dim>
2339 for (
ValueOnIter iter = this->beginValueOn(); iter; ++iter) {
2340 this->setChildNode(iter.pos(),
2343 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter)
2344 iter->voxelizeActiveTiles(
false);
2352 template<
typename ChildT, Index Log2Dim>
2353 template<MergePolicy Policy>
2366 const Index n = iter.pos();
2367 if (mChildMask.isOn(n)) {
2369 mNodes[n].getChild()->template merge<MERGE_ACTIVE_STATES>(*iter,
2370 background, otherBackground);
2371 }
else if (mValueMask.isOff(n)) {
2378 child->resetBackground(otherBackground, background);
2379 this->setChildNode(n, child);
2385 const Index n = iter.pos();
2386 if (mValueMask.isOff(n)) {
2388 this->makeChildNodeEmpty(n, iter.getValue());
2389 mValueMask.setOn(n);
2398 const Index n = iter.pos();
2399 if (mChildMask.isOn(n)) {
2401 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2409 child->resetBackground(otherBackground, background);
2410 this->setChildNode(n, child);
2420 const Index n = iter.pos();
2421 if (mChildMask.isOn(n)) {
2423 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2430 child->resetBackground(otherBackground, background);
2431 if (mValueMask.isOn(n)) {
2433 child->template merge<Policy>(mNodes[n].getValue(),
true);
2434 mValueMask.setOff(n);
2436 mChildMask.setOn(n);
2437 mNodes[n].setChild(child);
2443 const Index n = iter.pos();
2444 if (mChildMask.isOn(n)) {
2446 mNodes[n].getChild()->template merge<Policy>(iter.getValue(),
true);
2447 }
else if (mValueMask.isOff(n)) {
2449 mNodes[n].setValue(iter.getValue());
2450 mValueMask.setOn(n);
2461 template<
typename ChildT, Index Log2Dim>
2462 template<MergePolicy Policy>
2471 if (!tileActive)
return;
2474 for (
ValueOffIter iter = this->beginValueOff(); iter; ++iter) {
2475 const Index n = iter.pos();
2476 if (mChildMask.isOn(n)) {
2478 mNodes[n].getChild()->template merge<Policy>(tileValue,
true);
2481 iter.setValue(tileValue);
2482 mValueMask.setOn(n);
2492 template<
typename ChildT, Index Log2Dim>
2493 template<
typename OtherInternalNode>
2498 { tV = (tV | sV) & ~tC; }
2502 tbb::parallel_for(tbb::blocked_range<Index>(0, NUM_VALUES), *
this);
2505 t->mChildMask |= s->mChildMask;
2507 t->mValueMask.foreach(s->mValueMask, t->mChildMask, op);
2508 assert((t->mValueMask & t->mChildMask).isOff());
2511 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2512 if (s->mChildMask.isOn(i)) {
2513 const typename OtherInternalNode::ChildNodeType& other = *(s->mNodes[i].getChild());
2514 if (t->mChildMask.isOn(i)) {
2515 t->mNodes[i].getChild()->topologyUnion(other);
2517 ChildT* child =
new ChildT(other, t->mNodes[i].getValue(),
TopologyCopy());
2518 if (t->mValueMask.isOn(i)) child->setValuesOn();
2519 t->mNodes[i].setChild(child);
2521 }
else if (s->mValueMask.isOn(i) && t->mChildMask.isOn(i)) {
2522 t->mNodes[i].getChild()->setValuesOn();
2526 const OtherInternalNode*
s;
2530 template<
typename ChildT, Index Log2Dim>
2531 template<
typename OtherChildT>
2538 template<
typename ChildT, Index Log2Dim>
2539 template<
typename OtherInternalNode>
2540 struct InternalNode<ChildT, Log2Dim>::TopologyIntersection
2544 { tC = (tC & (sC | sV)) | (tV & sC); }
2547 const ValueType& background) : s(source), t(target), b(background) {
2549 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2553 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op);
2555 t->mValueMask &= s->mValueMask;
2556 assert((t->mValueMask & t->mChildMask).isOff());
2559 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2560 if (t->mChildMask.isOn(i)) {
2561 ChildT* child = t->mNodes[i].getChild();
2562 if (s->mChildMask.isOn(i)) {
2563 child->topologyIntersection(*(s->mNodes[i].getChild()), b);
2564 }
else if (s->mValueMask.isOff(i)) {
2566 t->mNodes[i].setValue(b);
2568 }
else if (t->mValueMask.isOn(i) && s->mChildMask.isOn(i)) {
2569 t->mNodes[i].setChild(
new ChildT(*(s->mNodes[i].getChild()),
2574 const OtherInternalNode*
s;
2579 template<
typename ChildT, Index Log2Dim>
2580 template<
typename OtherChildT>
2588 template<
typename ChildT, Index Log2Dim>
2589 template<
typename OtherInternalNode>
2590 struct InternalNode<ChildT, Log2Dim>::TopologyDifference
2594 { tC = (tC & (sC | ~sV)) | (tV & sC); }
2597 { tV &= ~((tC & sV) | (sC | sV)); }
2600 const ValueType& background) : s(source), t(target), b(background) {
2602 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2607 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op1);
2610 t->mValueMask.foreach(t->mChildMask, s->mValueMask, oldChildMask, op2);
2611 assert((t->mValueMask & t->mChildMask).isOff());
2614 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2615 if (t->mChildMask.isOn(i)) {
2616 ChildT* child = t->mNodes[i].getChild();
2617 if (s->mChildMask.isOn(i)) {
2618 child->topologyDifference(*(s->mNodes[i].getChild()), b);
2619 }
else if (s->mValueMask.isOn(i)) {
2621 t->mNodes[i].setValue(b);
2623 }
else if (t->mValueMask.isOn(i)) {
2624 if (s->mChildMask.isOn(i)) {
2625 const typename OtherInternalNode::ChildNodeType& other =
2626 *(s->mNodes[i].getChild());
2627 ChildT* child =
new ChildT(other.origin(), t->mNodes[i].getValue(),
true);
2628 child->topologyDifference(other, b);
2629 t->mNodes[i].setChild(child);
2634 const OtherInternalNode*
s;
2639 template<
typename ChildT, Index Log2Dim>
2640 template<
typename OtherChildT>
2652 template<
typename ChildT, Index Log2Dim>
2653 template<
typename CombineOp>
2657 const ValueType zero = zeroVal<ValueType>();
2661 for (
Index i = 0; i < NUM_VALUES; ++i) {
2665 op(args.setARef(mNodes[i].getValue())
2666 .setAIsActive(isValueMaskOn(i))
2669 mNodes[i].setValue(args.result());
2670 mValueMask.set(i, args.resultIsActive());
2678 }
else if (this->isChildMaskOff(i) && other.
isChildMaskOn(i)) {
2687 child->combine(mNodes[i].getValue(), isValueMaskOn(i), swappedOp);
2692 this->setChildNode(i, child);
2698 *child = mNodes[i].getChild(),
2702 if (child && otherChild) {
2703 child->combine(*otherChild, op);
2710 template<
typename ChildT, Index Log2Dim>
2711 template<
typename CombineOp>
2717 for (
Index i = 0; i < NUM_VALUES; ++i) {
2718 if (this->isChildMaskOff(i)) {
2720 op(args.
setARef(mNodes[i].getValue())
2721 .setAIsActive(isValueMaskOn(i))
2723 .setBIsActive(valueIsActive));
2724 mNodes[i].setValue(args.
result());
2730 if (child) child->combine(value, valueIsActive, op);
2739 template<
typename ChildT, Index Log2Dim>
2740 template<
typename CombineOp,
typename OtherNodeType>
2747 for (
Index i = 0; i < NUM_VALUES; ++i) {
2751 .setBRef(other1.mNodes[i].getValue())
2752 .setBIsActive(other1.isValueMaskOn(i)));
2754 this->makeChildNodeEmpty(i, args.
result());
2757 if (this->isChildMaskOff(i)) {
2761 : other1.mNodes[i].getChild()->origin();
2762 this->setChildNode(i,
new ChildNodeType(childOrigin, mNodes[i].getValue()));
2770 }
else if (other1.isChildMaskOff(i)) {
2774 other1.mNodes[i].getValue(), other1.isValueMaskOn(i), op);
2779 *other1.mNodes[i].getChild(), op);
2786 template<
typename ChildT, Index Log2Dim>
2787 template<
typename CombineOp,
typename OtherNodeType>
2790 bool valueIsActive, CombineOp& op)
2794 for (
Index i = 0; i < NUM_VALUES; ++i) {
2795 if (other.isChildMaskOff(i)) {
2797 .setAIsActive(valueIsActive)
2798 .setBRef(other.mNodes[i].getValue())
2799 .setBIsActive(other.isValueMaskOn(i)));
2801 this->makeChildNodeEmpty(i, args.
result());
2804 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
2806 if (this->isChildMaskOff(i)) {
2813 mNodes[i].getChild()->combine2(value, *otherChild, valueIsActive, op);
2819 template<
typename ChildT, Index Log2Dim>
2820 template<
typename CombineOp,
typename OtherValueType>
2823 bool valueIsActive, CombineOp& op)
2827 for (
Index i = 0; i < NUM_VALUES; ++i) {
2832 .setBIsActive(valueIsActive));
2834 this->makeChildNodeEmpty(i, args.
result());
2839 if (this->isChildMaskOff(i)) {
2841 this->setChildNode(i,
2842 new ChildNodeType(otherChild->origin(), mNodes[i].getValue()));
2846 mNodes[i].getChild()->combine2(*otherChild, value, valueIsActive, op);
2855 template<
typename ChildT, Index Log2Dim>
2856 template<
typename BBoxOp>
2867 if (op.template descent<LEVEL>()) {
2868 for (
ChildOnCIter i = this->cbeginChildOn(); i; ++i) i->visitActiveBBox(op);
2872 op.operator()<LEVEL>(i->getNodeBoundingBox());
2874 op.template operator()<LEVEL>(i->getNodeBoundingBox());
2881 template<
typename ChildT, Index Log2Dim>
2882 template<
typename VisitorOp>
2886 doVisit<InternalNode, VisitorOp, ChildAllIter>(*
this, op);
2890 template<
typename ChildT, Index Log2Dim>
2891 template<
typename VisitorOp>
2895 doVisit<const InternalNode, VisitorOp, ChildAllCIter>(*
this, op);
2899 template<
typename ChildT, Index Log2Dim>
2900 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
2904 typename NodeT::ValueType val;
2905 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2906 if (op(iter))
continue;
2907 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2917 template<
typename ChildT, Index Log2Dim>
2918 template<
typename OtherNodeType,
typename VisitorOp>
2923 typename OtherNodeType::ChildAllIter>(*
this, other, op);
2927 template<
typename ChildT, Index Log2Dim>
2928 template<
typename OtherNodeType,
typename VisitorOp>
2933 typename OtherNodeType::ChildAllCIter>(*
this, other, op);
2937 template<
typename ChildT, Index Log2Dim>
2940 typename OtherNodeT,
2942 typename ChildAllIterT,
2943 typename OtherChildAllIterT>
2948 static_assert(OtherNodeT::NUM_VALUES == NodeT::NUM_VALUES,
2949 "visit2() requires nodes to have the same dimensions");
2950 static_assert(OtherNodeT::LEVEL == NodeT::LEVEL,
2951 "visit2() requires nodes to be at the same tree level");
2953 typename NodeT::ValueType val;
2954 typename OtherNodeT::ValueType otherVal;
2956 ChildAllIterT iter =
self.beginChildAll();
2957 OtherChildAllIterT otherIter = other.beginChildAll();
2959 for ( ; iter && otherIter; ++iter, ++otherIter)
2961 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2963 typename ChildAllIterT::ChildNodeType* child =
2964 (skipBranch & 1U) ?
nullptr : iter.probeChild(val);
2965 typename OtherChildAllIterT::ChildNodeType* otherChild =
2966 (skipBranch & 2U) ?
nullptr : otherIter.probeChild(otherVal);
2968 if (child !=
nullptr && otherChild !=
nullptr) {
2969 child->visit2Node(*otherChild, op);
2970 }
else if (child !=
nullptr) {
2971 child->visit2(otherIter, op);
2972 }
else if (otherChild !=
nullptr) {
2973 otherChild->visit2(iter, op,
true);
2982 template<
typename ChildT, Index Log2Dim>
2983 template<
typename OtherChildAllIterType,
typename VisitorOp>
2986 VisitorOp& op,
bool otherIsLHS)
2988 doVisit2<InternalNode, VisitorOp, ChildAllIter, OtherChildAllIterType>(
2989 *
this, otherIter, op, otherIsLHS);
2993 template<
typename ChildT, Index Log2Dim>
2994 template<
typename OtherChildAllIterType,
typename VisitorOp>
2997 VisitorOp& op,
bool otherIsLHS)
const 2999 doVisit2<const InternalNode, VisitorOp, ChildAllCIter, OtherChildAllIterType>(
3000 *
this, otherIter, op, otherIsLHS);
3004 template<
typename ChildT, Index Log2Dim>
3005 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT,
typename OtherChildAllIterT>
3008 VisitorOp& op,
bool otherIsLHS)
3010 if (!otherIter)
return;
3012 const size_t skipBitMask = (otherIsLHS ? 2U : 1U);
3014 typename NodeT::ValueType val;
3015 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
3016 const size_t skipBranch =
static_cast<size_t>(
3017 otherIsLHS ? op(otherIter, iter) : op(iter, otherIter));
3019 typename ChildAllIterT::ChildNodeType* child =
3020 (skipBranch & skipBitMask) ?
nullptr : iter.probeChild(val);
3022 if (child !=
nullptr) child->visit2(otherIter, op, otherIsLHS);
3030 template<
typename ChildT, Index Log2Dim>
3034 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
3035 iter->writeBuffers(os, toHalf);
3040 template<
typename ChildT, Index Log2Dim>
3044 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3045 iter->readBuffers(is, fromHalf);
3050 template<
typename ChildT, Index Log2Dim>
3053 const CoordBBox& clipBBox,
bool fromHalf)
3055 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3060 iter->readBuffers(is, clipBBox, fromHalf);
3064 ValueType background = zeroVal<ValueType>();
3066 background = *
static_cast<const ValueType*
>(bgPtr);
3068 this->
clip(clipBBox, background);
3075 template<
typename ChildT, Index Log2Dim>
3079 dims.push_back(Log2Dim);
3080 ChildNodeType::getNodeLog2Dims(dims);
3084 template<
typename ChildT, Index Log2Dim>
3088 assert(n<(1<<3*Log2Dim));
3089 xyz.
setX(n >> 2*Log2Dim);
3090 n &= ((1<<2*Log2Dim)-1);
3091 xyz.
setY(n >> Log2Dim);
3092 xyz.
setZ(n & ((1<<Log2Dim)-1));
3096 template<
typename ChildT, Index Log2Dim>
3100 return (((xyz[0] & (DIM-1u)) >> ChildNodeType::TOTAL) << 2*Log2Dim)
3101 + (((xyz[1] & (DIM-1u)) >> ChildNodeType::TOTAL) << Log2Dim)
3102 + ((xyz[2] & (DIM-1u)) >> ChildNodeType::TOTAL);
3106 template<
typename ChildT, Index Log2Dim>
3111 this->offsetToLocalCoord(n, local);
3112 local <<= ChildT::TOTAL;
3113 return local + this->origin();
3120 template<
typename ChildT, Index Log2Dim>
3121 template<
typename ArrayT>
3125 using T =
typename ArrayT::value_type;
3126 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3127 using ArrayChildT =
typename std::conditional<
3128 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3129 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3131 if (std::is_same<T, ArrayChildT*>::value) {
3132 array.push_back(reinterpret_cast<T>(mNodes[iter.pos()].getChild()));
3134 iter->getNodes(array);
3140 template<
typename ChildT, Index Log2Dim>
3141 template<
typename ArrayT>
3145 using T =
typename ArrayT::value_type;
3146 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3147 static_assert(std::is_const<
typename std::remove_pointer<T>::type>::value,
3148 "argument to getNodes() must be an array of const node pointers");
3149 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
3151 if (std::is_same<T, const ChildT*>::value) {
3152 array.push_back(reinterpret_cast<T>(mNodes[iter.pos()].getChild()));
3154 iter->getNodes(array);
3164 template<
typename ChildT, Index Log2Dim>
3165 template<
typename ArrayT>
3169 using T =
typename ArrayT::value_type;
3170 static_assert(std::is_pointer<T>::value,
"argument to stealNodes() must be a pointer array");
3171 using ArrayChildT =
typename std::conditional<
3172 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3174 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3175 const Index n = iter.pos();
3176 if (std::is_same<T, ArrayChildT*>::value) {
3177 array.push_back(reinterpret_cast<T>(mNodes[n].getChild()));
3178 mValueMask.set(n, state);
3179 mNodes[n].setValue(value);
3181 iter->stealNodes(array, value, state);
3184 if (std::is_same<T, ArrayChildT*>::value) mChildMask.setOff();
3192 template<
typename ChildT, Index Log2Dim>
3198 for (
Index i = 0; i < NUM_VALUES; ++i) {
3199 if (this->isChildMaskOn(i)) {
3200 mNodes[i].getChild()->resetBackground(oldBackground, newBackground);
3201 }
else if (this->isValueMaskOff(i)) {
3203 mNodes[i].setValue(newBackground);
3211 template<
typename ChildT, Index Log2Dim>
3212 template<
typename OtherChildNodeType, Index OtherLog2Dim>
3217 if (Log2Dim != OtherLog2Dim || mChildMask != other->
mChildMask ||
3218 mValueMask != other->
mValueMask)
return false;
3219 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
3220 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
3226 template<
typename ChildT, Index Log2Dim>
3231 if (this->isChildMaskOn(i)) {
3232 delete mNodes[i].getChild();
3234 mChildMask.setOn(i);
3235 mValueMask.setOff(i);
3237 mNodes[i].setChild(child);
3240 template<
typename ChildT, Index Log2Dim>
3245 assert(mChildMask.isOff(i));
3246 mChildMask.setOn(i);
3247 mValueMask.setOff(i);
3248 mNodes[i].setChild(child);
3252 template<
typename ChildT, Index Log2Dim>
3256 if (this->isChildMaskOff(i)) {
3257 mNodes[i].setValue(value);
3261 mChildMask.setOff(i);
3262 mNodes[i].setValue(value);
3267 template<
typename ChildT, Index Log2Dim>
3271 delete this->unsetChildNode(n, value);
3274 template<
typename ChildT, Index Log2Dim>
3278 assert(this->isChildMaskOn(n));
3279 return mNodes[n].getChild();
3283 template<
typename ChildT, Index Log2Dim>
3284 inline const ChildT*
3287 assert(this->isChildMaskOn(n));
3288 return mNodes[n].getChild();
3295 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2902
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:114
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:3194
void topologyUnion(const InternalNode< OtherChildNodeType, Log2Dim > &other)
Union this branch's set of active values with the other branch's active values. The value type of the...
ValueIter()
Definition: InternalNode.h:155
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:1312
Int32 y() const
Definition: Coord.h:132
Definition: InternalNode.h:33
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:238
InternalNode * t
Definition: InternalNode.h:898
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:234
ChildIter()
Definition: InternalNode.h:134
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:3276
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1858
typename NodeMaskType::Word W
Definition: InternalNode.h:2542
Definition: version.h:186
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2558
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:295
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:120
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:135
void operator()(W &tV, const W &sV, const W &tC) const
Definition: InternalNode.h:2497
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:351
TopologyCopy2(const OtherInternalNode *source, InternalNode *target, const ValueType &offValue, const ValueType &onValue)
Definition: InternalNode.h:964
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1642
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:29
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2185
static const Index NUM_VALUES
Definition: InternalNode.h:47
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:2355
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:1374
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2858
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
Definition: InternalNode.h:29
InternalNode * t
Definition: InternalNode.h:2635
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:1164
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2543
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:271
static Index getChildDim()
Definition: InternalNode.h:260
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:418
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:228
const OtherInternalNode * s
Definition: InternalNode.h:979
uint32_t Index32
Definition: Types.h:29
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:178
void setValue(const ValueT &val)
Definition: NodeUnion.h:47
InternalNode * mNode
Definition: InternalNode.h:2329
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:229
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:1778
Definition: InternalNode.h:123
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:1122
const OtherInternalNode * s
Definition: InternalNode.h:2574
Definition: NodeMasks.h:251
ChildT * getChild() const
Definition: NodeUnion.h:42
typename ChildNodeType::BuildType BuildType
Definition: InternalNode.h:39
Definition: InternalNode.h:2596
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...
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:817
ValueOnIter beginValueOn()
Definition: InternalNode.h:242
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:1087
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1835
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...
static Index dim()
Definition: InternalNode.h:250
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:176
void translate(const Coord &t)
Translate this bounding box by (tx, ty, tz).
Definition: Coord.h:458
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:1616
Coord & setZ(Int32 z)
Definition: Coord.h:82
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:224
typename NodeMaskType::Word W
Definition: InternalNode.h:2592
TopologyIntersection(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2546
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:209
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:620
const UnionType * getTable() const
Definition: InternalNode.h:777
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:55
Index64 offVoxelCount() const
Definition: InternalNode.h:1063
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:202
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:3086
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1501
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:288
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:159
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:3167
Definition: InternalNode.h:124
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:3108
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:81
Definition: InternalNode.h:131
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:156
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.
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:1400
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:3042
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1932
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:1292
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:225
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:465
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:433
InternalNode * t
Definition: InternalNode.h:944
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2210
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:92
Definition: InternalNode.h:816
void nodeCount(std::vector< Index32 > &vec) const
Definition: InternalNode.h:1025
ChildAllIter beginChildAll()
Definition: InternalNode.h:232
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:438
NodeMaskType mValueMask
Definition: InternalNode.h:821
Definition: InternalNode.h:2543
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:162
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1709
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:240
Definition: InternalNode.h:817
Definition: InternalNode.h:2307
Definition: InternalNode.h:123
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:3098
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:326
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2334
ChildT & getItem(Index pos) const
Definition: InternalNode.h:138
typename BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:178
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:933
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:47
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:226
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:1341
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:823
InternalNode * t
Definition: InternalNode.h:2575
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:166
const Coord & max() const
Definition: Coord.h:322
ValueAllIter beginValueAll()
Definition: InternalNode.h:245
const ValueType & onV
Definition: InternalNode.h:981
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:1109
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:765
int32_t Int32
Definition: Types.h:33
Coord & setX(Int32 x)
Definition: Coord.h:80
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2945
const Coord & min() const
Definition: Coord.h:321
Definition: InternalNode.h:813
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:1075
Definition: InternalNode.h:152
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:400
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1584
typename ChildNodeType::ValueType ValueType
Definition: InternalNode.h:38
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:1140
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:1266
Definition: version.h:195
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2613
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
DeepCopy(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:884
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:236
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:3254
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:412
typename std::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:184
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:2742
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:1432
Definition: Exceptions.h:13
typename ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:37
Definition: InternalNode.h:124
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:273
Index64 onTileCount() const
Definition: InternalNode.h:1098
void visit2Node(OtherNodeType &other, VisitorOp &)
Definition: InternalNode.h:2920
TopologyDifference(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2599
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2655
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1573
typename NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:119
void operator()(W &tV, const W &sC, const W &sV, const W &tC) const
Definition: InternalNode.h:2596
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2316
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:184
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:969
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: InternalNode.h:1986
Definition: NodeMasks.h:220
DenseIter()
Definition: InternalNode.h:180
typename NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:118
const ValueType & b
Definition: InternalNode.h:945
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:64
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:3269
const NodeMaskType & getValueMask() const
Definition: InternalNode.h:768
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:681
Library and file format version numbers.
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:241
const OtherInternalNode * s
Definition: InternalNode.h:2634
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:1607
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3242
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:645
NodeMaskType getValueOffMask() const
Definition: InternalNode.h:770
Int32 x() const
Definition: Coord.h:131
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1754
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1563
InternalNode()
Default constructor.
Definition: InternalNode.h:72
Definition: InternalNode.h:814
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1673
bool isValueMaskOff() const
Definition: InternalNode.h:764
static void getNodeLog2Dims(std::vector< Index > &dims)
Populated an stil::vector with the dimension of all the nodes in the branch starting with this node...
Definition: InternalNode.h:3077
Index32 Index
Definition: Types.h:31
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
Definition: InternalNode.h:815
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:3007
~InternalNode()
Definition: InternalNode.h:1000
Index64 Word
Definition: NodeMasks.h:297
ChildOnIter beginChildOn()
Definition: InternalNode.h:230
Definition: InternalNode.h:812
TopologyUnion(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:2500
const ValueT & getValue() const
Definition: NodeUnion.h:45
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1629
InternalNode * t
Definition: InternalNode.h:2527
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3228
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:248
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:313
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:1898
Index64 onVoxelCount() const
Definition: InternalNode.h:1051
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:2270
const ValueType & b
Definition: InternalNode.h:2576
InternalNode * t
Definition: InternalNode.h:980
ValueOffIter beginValueOff()
Definition: InternalNode.h:244
Coord & setY(Int32 y)
Definition: Coord.h:81
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
void negate()
Change the sign of all the values represented in this node and its child nodes.
Definition: InternalNode.h:2290
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:683
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:3032
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:3214
_ChildNodeType ChildNodeType
Definition: InternalNode.h:36
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:1816
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2593
uint64_t Index64
Definition: Types.h:30
VoxelizeActiveTiles(InternalNode &node)
Definition: InternalNode.h:2309
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:2278
bool isChildMaskOff() const
Definition: InternalNode.h:767
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:388
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:145
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:2140
TopologyCopy1(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:928
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1548
const OtherInternalNode * s
Definition: InternalNode.h:897
Definition: InternalNode.h:174
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:567
const AValueType & result() const
Get the output value.
Definition: Types.h:612
const OtherInternalNode * s
Definition: InternalNode.h:2526
Definition: InternalNode.h:2497
const ValueType & b
Definition: InternalNode.h:2636
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2510
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:1870
NodeMaskType mChildMask
Definition: InternalNode.h:821
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:888
static Index getLevel()
Definition: InternalNode.h:253
Level getLevel()
Return the current logging level.
Definition: logging.h:138
bool isEmpty() const
Definition: InternalNode.h:298
Index32 leafCount() const
Definition: InternalNode.h:1013
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:181
bool resultIsActive() const
Definition: Types.h:631
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:763
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:761
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:1468
bool isValueMaskOn() const
Definition: InternalNode.h:762
typename NodeMaskType::Word W
Definition: InternalNode.h:2496
Definition: NodeMasks.h:189
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:2092
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:766
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1657
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1955
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
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 toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:464
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:196
ChildOffIter beginChildOff()
Definition: InternalNode.h:231
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.
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:331
const OtherInternalNode * s
Definition: InternalNode.h:943
const NodeMaskType & getChildMask() const
Definition: InternalNode.h:769
Int32 z() const
Definition: Coord.h:133
Index32 nonLeafCount() const
Definition: InternalNode.h:1038
void visit(VisitorOp &)
Definition: InternalNode.h:2884
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:227
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...
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:2036
Definition: InternalNode.h:2593
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:237
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1795
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: InternalNode.h:3123