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);
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());
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