46 const scalar nearestDistSqr,
54 for (
direction dir = 0; dir < vector::nComponents; dir++)
57 scalar d1 = p1[dir] -
sample[dir];
59 if ((d0 > 0) != (d1 > 0))
64 else if (
mag(d0) <
mag(d1))
73 if (distSqr > nearestDistSqr)
86 const treeBoundBox& parentBb,
88 const scalar nearestDistSqr,
107 if (octant & treeBoundBox::RIGHTHALF)
116 if (octant & treeBoundBox::TOPHALF)
125 if (octant & treeBoundBox::FRONTHALF)
136 return overlaps(mid, other, nearestDistSqr,
sample);
143 const autoPtr<DynamicList<label>>& indices,
144 const treeBoundBox& bb,
148 for (
direction octant = 0; octant < 8; octant++)
152 autoPtr<DynamicList<label>>
154 new DynamicList<label>(indices().size()/8)
160 FixedList<treeBoundBox, 8> subBbs;
161 for (
direction octant = 0; octant < 8; octant++)
163 subBbs[octant] = bb.subBbox(octant);
168 label shapeI = indices()[i];
170 for (
direction octant = 0; octant < 8; octant++)
172 if (shapes_.overlaps(shapeI, subBbs[octant]))
174 result[octant]().
append(shapeI);
185 const treeBoundBox& bb,
186 const label contentI,
187 const label parentNodeIndex,
188 const label octantToBeDivided
191 const autoPtr<DynamicList<label>>& indices = contents_[contentI];
197 bb.min()[0] >= bb.max()[0]
198 || bb.min()[1] >= bb.max()[1]
199 || bb.min()[2] >= bb.max()[2]
203 <<
"Badly formed bounding box:" << bb
211 divide(indices, bb, dividedIndices);
216 bool replaced =
false;
218 for (
direction octant = 0; octant < dividedIndices.size(); octant++)
220 autoPtr<DynamicList<label>>& subIndices = dividedIndices[octant];
222 if (subIndices().size())
226 contents_[contentI]->transfer(subIndices());
227 nod.subNodes_[octant] = contentPlusOctant(contentI, octant);
235 label sz = contents_.size();
239 autoPtr<DynamicList<label>>
241 new DynamicList<label>()
245 contents_[sz]->transfer(subIndices());
247 nod.subNodes_[octant] = contentPlusOctant(sz, octant);
253 nod.subNodes_[octant] = emptyPlusOctant(octant);
258 if (parentNodeIndex != -1)
260 nod.parent_ = parentNodeIndex;
262 label sz = nodes_.size();
266 nodes_[parentNodeIndex].subNodes_[octantToBeDivided]
267 = nodePlusOctant(sz, octantToBeDivided);
277 const treeBoundBox& subBb,
278 const label contentI,
279 const label parentIndex,
286 contents_[contentI]->size() > minSize_
287 && nLevels < maxLevels_
291 node nod =
divide(subBb, contentI, parentIndex, octant);
298 for (
direction subOct = 0; subOct < 8; subOct++)
300 const labelBits& subNodeLabel = nod.subNodes_[subOct];
302 if (isContent(subNodeLabel))
304 const treeBoundBox subBb = nod.bb_.subBbox(subOct);
306 const label subContentI = getContent(subNodeLabel);
308 const label parentNodeIndex = nodes_.size() - 1;
334 const node& nod = nodes_[nodeI];
336 volumeType myType = volumeType::UNKNOWN;
338 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
342 labelBits index = nod.subNodes_[octant];
347 subType = calcVolumeType(getNode(index));
349 else if (isContent(index))
353 subType = volumeType::MIXED;
359 const treeBoundBox subBb = nod.bb_.subBbox(octant);
363 shapes_.getVolumeType(*
this, subBb.centre())
368 nodeTypes_.set((nodeI<<3)+octant, subType);
372 if (myType == volumeType::UNKNOWN)
376 else if (subType != myType)
378 myType = volumeType::MIXED;
392 const node& nod = nodes_[nodeI];
396 volumeType octantType =
volumeType::type(nodeTypes_.get((nodeI<<3)+octant));
398 if (octantType == volumeType::INSIDE)
402 else if (octantType == volumeType::OUTSIDE)
406 else if (octantType == volumeType::UNKNOWN)
411 else if (octantType == volumeType::MIXED)
413 labelBits index = nod.subNodes_[octant];
418 volumeType subType = getVolumeType(getNode(index),
sample);
422 else if (isContent(index))
425 return volumeType(shapes_.getVolumeType(*
this,
sample));
431 <<
"Sample:" <<
sample <<
" node:" << nodeI
432 <<
" with bb:" << nodes_[nodeI].bb_ <<
nl
433 <<
"Empty subnode has invalid volume type MIXED."
436 return volumeType::UNKNOWN;
440 <<
"Sample:" <<
sample <<
" at node:" << nodeI
441 <<
" octant:" << octant
442 <<
" with bb:" << nod.bb_.subBbox(octant) <<
nl
443 <<
"Node has invalid volume type " << octantType
446 return volumeType::UNKNOWN;
453 const vector& outsideNormal,
457 if ((outsideNormal&vec) >= 0)
459 return volumeType::OUTSIDE;
463 return volumeType::INSIDE;
474 scalar& nearestDistSqr,
475 label& nearestShapeI,
479 const node& nod = nodes_[nodeI];
482 FixedList<direction, 8> octantOrder;
490 labelBits index = nod.subNodes_[octant];
494 label subNodeI = getNode(index);
496 const treeBoundBox& subBb = nodes_[subNodeI].bb_;
498 if (overlaps(subBb.min(), subBb.max(), nearestDistSqr,
sample))
511 else if (isContent(index))
526 *(contents_[getContent(index)]),
545 treeBoundBox& tightest,
546 label& nearestShapeI,
551 const node& nod = nodes_[nodeI];
552 const treeBoundBox& nodeBb = nod.bb_;
555 FixedList<direction, 8> octantOrder;
563 labelBits index = nod.subNodes_[octant];
567 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
569 if (subBb.overlaps(tightest))
583 else if (isContent(index))
585 const treeBoundBox subBb(nodeBb.subBbox(octant));
587 if (subBb.overlaps(tightest))
591 *(contents_[getContent(index)]),
608 const label parentNodeI,
613 const node& nod = nodes_[parentNodeI];
614 labelBits index = nod.subNodes_[octant];
619 return nodes_[getNode(index)].bb_;
624 return nod.bb_.
subBbox(octant);
632 const treeBoundBox& bb,
634 const bool pushInside
641 const vector perturbVec = perturbTol_*bb.span();
643 point perturbedPt(pt);
650 for (
direction dir = 0; dir < vector::nComponents; dir++)
652 if (
mag(pt[dir]-bb.min()[dir]) <
mag(perturbVec[dir]))
655 scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
656 perturbedPt[dir] = bb.min()[dir] + perturbDist;
658 else if (
mag(pt[dir]-bb.max()[dir]) <
mag(perturbVec[dir]))
661 scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
662 perturbedPt[dir] = bb.max()[dir] - perturbDist;
668 for (
direction dir = 0; dir < vector::nComponents; dir++)
670 if (
mag(pt[dir]-bb.min()[dir]) <
mag(perturbVec[dir]))
672 scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
673 perturbedPt[dir] = bb.min()[dir] - perturbDist;
675 else if (
mag(pt[dir]-bb.max()[dir]) <
mag(perturbVec[dir]))
677 scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
678 perturbedPt[dir] = bb.max()[dir] + perturbDist;
685 if (pushInside != bb.contains(perturbedPt))
690 <<
"pushed point:" << pt
691 <<
" to:" << perturbedPt
692 <<
" wanted side:" << pushInside
693 <<
" obtained side:" << bb.contains(perturbedPt)
694 <<
" of bb:" << bb <<
nl;
710 const treeBoundBox& bb,
713 const bool pushInside
720 const vector perturbVec = perturbTol_*bb.span();
722 point perturbedPt(pt);
733 if (faceID & treeBoundBox::LEFTBIT)
737 perturbedPt[0] = bb.min()[0] + (perturbVec[0] + ROOTVSMALL);
741 perturbedPt[0] = bb.min()[0] - (perturbVec[0] + ROOTVSMALL);
744 else if (faceID & treeBoundBox::RIGHTBIT)
748 perturbedPt[0] = bb.max()[0] - (perturbVec[0] + ROOTVSMALL);
752 perturbedPt[0] = bb.max()[0] + (perturbVec[0] + ROOTVSMALL);
756 if (faceID & treeBoundBox::BOTTOMBIT)
760 perturbedPt[1] = bb.min()[1] + (perturbVec[1] + ROOTVSMALL);
764 perturbedPt[1] = bb.min()[1] - (perturbVec[1] + ROOTVSMALL);
767 else if (faceID & treeBoundBox::TOPBIT)
771 perturbedPt[1] = bb.max()[1] - (perturbVec[1] + ROOTVSMALL);
775 perturbedPt[1] = bb.max()[1] + (perturbVec[1] + ROOTVSMALL);
779 if (faceID & treeBoundBox::BACKBIT)
783 perturbedPt[2] = bb.min()[2] + (perturbVec[2] + ROOTVSMALL);
787 perturbedPt[2] = bb.min()[2] - (perturbVec[2] + ROOTVSMALL);
790 else if (faceID & treeBoundBox::FRONTBIT)
794 perturbedPt[2] = bb.max()[2] - (perturbVec[2] + ROOTVSMALL);
798 perturbedPt[2] = bb.max()[2] + (perturbVec[2] + ROOTVSMALL);
804 if (pushInside != bb.contains(perturbedPt))
809 <<
"pushed point:" << pt <<
" on face:" << faceString(faceID)
810 <<
" to:" << perturbedPt
811 <<
" wanted side:" << pushInside
812 <<
" obtained side:" << bb.contains(perturbedPt)
813 <<
" of bb:" << bb <<
nl;
829 const treeBoundBox& bb,
836 if (bb.posBits(pt) != 0)
841 <<
" bb:" << bb <<
endl
842 <<
"does not contain point " << pt <<
nl;
859 FixedList<direction, 3> faceIndices;
861 if (ptFaceID & treeBoundBox::LEFTBIT)
863 faceIndices[nFaces++] = treeBoundBox::LEFT;
865 else if (ptFaceID & treeBoundBox::RIGHTBIT)
867 faceIndices[nFaces++] = treeBoundBox::RIGHT;
870 if (ptFaceID & treeBoundBox::BOTTOMBIT)
872 faceIndices[nFaces++] = treeBoundBox::BOTTOM;
874 else if (ptFaceID & treeBoundBox::TOPBIT)
876 faceIndices[nFaces++] = treeBoundBox::TOP;
879 if (ptFaceID & treeBoundBox::BACKBIT)
881 faceIndices[nFaces++] = treeBoundBox::BACK;
883 else if (ptFaceID & treeBoundBox::FRONTBIT)
885 faceIndices[nFaces++] = treeBoundBox::FRONT;
898 else if (nFaces == 1)
901 keepFaceID = faceIndices[0];
908 keepFaceID = faceIndices[0];
915 if (
s > maxInproduct)
931 if (keepFaceID == treeBoundBox::LEFT)
934 faceID = treeBoundBox::LEFTBIT;
936 else if (keepFaceID == treeBoundBox::RIGHT)
939 faceID = treeBoundBox::RIGHTBIT;
941 else if (keepFaceID == treeBoundBox::BOTTOM)
944 faceID = treeBoundBox::BOTTOMBIT;
946 else if (keepFaceID == treeBoundBox::TOP)
949 faceID = treeBoundBox::TOPBIT;
951 else if (keepFaceID == treeBoundBox::BACK)
954 faceID = treeBoundBox::BACKBIT;
956 else if (keepFaceID == treeBoundBox::FRONT)
959 faceID = treeBoundBox::FRONTBIT;
970 <<
"Pushed point from " << pt
971 <<
" on face:" << ptFaceID <<
" of bb:" << bb <<
nl
973 <<
" on face:" << faceID
974 <<
" which is not consistent with geometric face "
987 <<
" bb:" << bb <<
nl
988 <<
"does not contain perturbed point "
1003 template<
class Type>
1013 parentNodeI = nodes_[nodeI].parent_;
1015 if (parentNodeI == -1)
1021 const node& parentNode = nodes_[parentNodeI];
1026 for (
direction i = 0; i < parentNode.subNodes_.size(); i++)
1028 labelBits index = parentNode.subNodes_[i];
1030 if (isNode(index) && getNode(index) == nodeI)
1037 if (parentOctant == 255)
1040 <<
"Problem: no parent found for octant:" << octant
1041 <<
" node:" << nodeI
1050 template<
class Type>
1064 label oldNodeI = nodeI;
1072 const direction X = treeBoundBox::RIGHTHALF;
1074 const direction Z = treeBoundBox::FRONTHALF;
1079 if ((faceID & treeBoundBox::LEFTBIT) != 0)
1085 else if ((faceID & treeBoundBox::RIGHTBIT) != 0)
1090 if ((faceID & treeBoundBox::BOTTOMBIT) != 0)
1096 else if ((faceID & treeBoundBox::TOPBIT) != 0)
1102 if ((faceID & treeBoundBox::BACKBIT) != 0)
1107 else if ((faceID & treeBoundBox::FRONTBIT) != 0)
1139 while (wantedValue != (octant & octantMask))
1145 if (wantedValue & X)
1165 if (wantedValue &
Y)
1182 if (wantedValue & Z)
1202 walkToParent(nodeI, octant, parentNodeI, parentOctant);
1204 if (parentNodeI == -1)
1219 nodeI = parentNodeI;
1220 octant = parentOctant;
1226 octant ^= octantMask;
1234 const treeBoundBox subBb(subBbox(nodeI, octant));
1242 <<
" ended up in node:" << nodeI
1243 <<
" octant:" << octant
1244 <<
" with bb:" << subBb <<
nl;
1256 labelBits index = nodes_[nodeI].subNodes_[octant];
1260 labelBits node = findNode(getNode(index),
facePoint);
1262 nodeI = getNode(node);
1269 const treeBoundBox subBb(subBbox(nodeI, octant));
1271 if (nodeI == oldNodeI && octant == oldOctant)
1276 <<
"Did not go to neighbour when searching for " <<
facePoint
1278 <<
" starting from face:" << faceString(faceID)
1279 <<
" node:" << nodeI
1280 <<
" octant:" << octant
1281 <<
" bb:" << subBb <<
nl;
1295 <<
" ended up in node:" << nodeI
1296 <<
" octant:" << octant
1297 <<
" bb:" << subBb <<
nl;
1311 template<
class Type>
1323 if (faceID & treeBoundBox::LEFTBIT)
1325 if (!desc.empty()) desc +=
"+";
1328 if (faceID & treeBoundBox::RIGHTBIT)
1330 if (!desc.empty()) desc +=
"+";
1333 if (faceID & treeBoundBox::BOTTOMBIT)
1335 if (!desc.empty()) desc +=
"+";
1338 if (faceID & treeBoundBox::TOPBIT)
1340 if (!desc.empty()) desc +=
"+";
1343 if (faceID & treeBoundBox::BACKBIT)
1345 if (!desc.empty()) desc +=
"+";
1348 if (faceID & treeBoundBox::FRONTBIT)
1350 if (!desc.empty()) desc +=
"+";
1357 template<
class Type>
1361 const point& treeStart,
1375 const treeBoundBox octantBb(subBbox(nodeI, octant));
1377 if (octantBb.posBits(start) != 0)
1382 <<
"Node:" << nodeI <<
" octant:" << octant
1383 <<
" bb:" << octantBb <<
nl
1384 <<
"does not contain point " << start <<
nl;
1394 const node& nod = nodes_[nodeI];
1396 labelBits index = nod.subNodes_[octant];
1398 if (isContent(index))
1400 const labelList& indices = *(contents_[getContent(index)]);
1410 label shapeI = indices[elemI];
1413 bool hit = shapes_.intersects(shapeI, start,
end, pt);
1422 hitInfo.setIndex(shapeI);
1423 hitInfo.setPoint(pt);
1432 const treeBoundBox octantBb(subBbox(nodeI, octant));
1438 label shapeI = indices[elemI];
1441 bool hit = shapes_.intersects
1454 if (hit && octantBb.contains(pt))
1460 hitInfo.setIndex(shapeI);
1461 hitInfo.setPoint(pt);
1479 const treeBoundBox octantBb(subBbox(nodeI, octant));
1482 bool intersected = octantBb.intersects
1498 hitInfo.setPoint(pt);
1507 point perturbedEnd(pushPoint(octantBb,
end,
false));
1526 template<
class Type>
1530 const point& treeStart,
1531 const point& treeEnd,
1532 const label startNodeI,
1537 const vector treeVec(treeEnd - treeStart);
1540 label nodeI = startNodeI;
1545 Pout<<
"findLine : treeStart:" << treeStart
1546 <<
" treeEnd:" << treeEnd <<
endl
1548 <<
" octant:" << octant
1549 <<
" bb:" << subBbox(nodeI, octant) <<
endl;
1557 for (; i < 100000; i++)
1562 const treeBoundBox octantBb(subBbox(nodeI, octant));
1578 <<
" at current:" << hitInfo.rawPoint()
1579 <<
" (perturbed:" << startPoint <<
")" <<
endl
1580 <<
" node:" << nodeI
1581 <<
" octant:" << octant
1582 <<
" bb:" << subBbox(nodeI, octant) <<
endl;
1613 if (hitFaceID == 0 || hitInfo.rawPoint() == treeEnd)
1620 point perturbedPoint
1633 Pout<<
" iter:" << i
1634 <<
" hit face:" << faceString(hitFaceID)
1635 <<
" at:" << hitInfo.rawPoint() <<
nl
1636 <<
" node:" << nodeI
1637 <<
" octant:" << octant
1638 <<
" bb:" << subBbox(nodeI, octant) <<
nl
1639 <<
" walking to neighbour containing:" << perturbedPoint
1648 bool ok = walkToNeighbour
1665 const treeBoundBox octantBb(subBbox(nodeI, octant));
1666 Pout<<
" walked for point:" << hitInfo.rawPoint() <<
endl
1667 <<
" to neighbour node:" << nodeI
1668 <<
" octant:" << octant
1669 <<
" face:" << faceString(octantBb.faceBits(hitInfo.rawPoint()))
1670 <<
" of octantBb:" << octantBb <<
endl
1694 <<
"Got stuck in loop raytracing from:" << treeStart
1695 <<
" to:" << treeEnd <<
endl
1696 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1702 <<
"Got stuck in loop raytracing from:" << treeStart
1703 <<
" to:" << treeEnd <<
endl
1704 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1713 template<
class Type>
1725 const treeBoundBox& treeBb = nodes_[0].bb_;
1730 direction startBit = treeBb.posBits(start);
1733 if ((startBit & endBit) != 0)
1742 point trackStart(start);
1748 if (!treeBb.intersects(start,
end, trackStart))
1757 if (!treeBb.intersects(
end, trackStart, trackEnd))
1765 labelBits index = findNode(0, trackStart);
1767 label parentNodeI = getNode(index);
1784 template<
class Type>
1788 const treeBoundBox& searchBox,
1792 const node& nod = nodes_[nodeI];
1793 const treeBoundBox& nodeBb = nod.bb_;
1795 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1797 labelBits index = nod.subNodes_[octant];
1801 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1803 if (subBb.overlaps(searchBox))
1805 findBox(getNode(index), searchBox, elements);
1808 else if (isContent(index))
1810 const treeBoundBox subBb(nodeBb.subBbox(octant));
1812 if (subBb.overlaps(searchBox))
1814 const labelList& indices = *(contents_[getContent(index)]);
1818 label shapeI = indices[i];
1820 if (shapes_.overlaps(shapeI, searchBox))
1822 elements.insert(shapeI);
1831 template<
class Type>
1835 const point& centre,
1836 const scalar radiusSqr,
1840 const node& nod = nodes_[nodeI];
1841 const treeBoundBox& nodeBb = nod.bb_;
1843 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1845 labelBits index = nod.subNodes_[octant];
1849 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1851 if (subBb.overlaps(centre, radiusSqr))
1853 findSphere(getNode(index), centre, radiusSqr, elements);
1856 else if (isContent(index))
1858 const treeBoundBox subBb(nodeBb.subBbox(octant));
1860 if (subBb.overlaps(centre, radiusSqr))
1862 const labelList& indices = *(contents_[getContent(index)]);
1866 label shapeI = indices[i];
1868 if (shapes_.overlaps(shapeI, centre, radiusSqr))
1870 elements.insert(shapeI);
1879 template<
class Type>
1880 template<
class CompareOp>
1883 const scalar nearDist,
1885 const dynamicIndexedOctree<Type>& tree1,
1886 const labelBits index1,
1887 const treeBoundBox& bb1,
1888 const dynamicIndexedOctree<Type>& tree2,
1889 const labelBits index2,
1890 const treeBoundBox& bb2,
1894 const vector nearSpan(nearDist, nearDist, nearDist);
1896 if (tree1.isNode(index1))
1898 const node& nod1 = tree1.nodes()[tree1.getNode(index1)];
1899 const treeBoundBox searchBox
1905 if (tree2.isNode(index2))
1907 if (bb2.overlaps(searchBox))
1909 const node& nod2 = tree2.nodes()[tree2.getNode(index2)];
1911 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
1913 labelBits subIndex2 = nod2.subNodes_[i2];
1914 const treeBoundBox subBb2
1916 tree2.isNode(subIndex2)
1917 ? tree2.nodes()[tree2.getNode(subIndex2)].bb_
1936 else if (tree2.isContent(index2))
1939 for (
direction i1 = 0; i1 < nod1.subNodes_.size(); i1++)
1941 labelBits subIndex1 = nod1.subNodes_[i1];
1942 const treeBoundBox subBb1
1944 tree1.isNode(subIndex1)
1945 ? tree1.nodes()[tree1.getNode(subIndex1)].bb_
1964 else if (tree1.isContent(index1))
1966 const treeBoundBox searchBox
1972 if (tree2.isNode(index2))
1975 tree2.nodes()[tree2.getNode(index2)];
1977 if (bb2.overlaps(searchBox))
1979 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
1981 labelBits subIndex2 = nod2.subNodes_[i2];
1982 const treeBoundBox subBb2
1984 tree2.isNode(subIndex2)
1985 ? tree2.nodes()[tree2.getNode(subIndex2)].bb_
2004 else if (tree2.isContent(index2))
2009 tree1.contents()[tree1.getContent(index1)];
2011 tree2.contents()[tree2.getContent(index2)];
2015 label shape1 = indices1[i];
2019 label shape2 = indices2[j];
2021 if ((&tree1 != &tree2) || (shape1 != shape2))
2053 template<
class Type>
2056 const labelBits index
2064 label nodeI = getNode(index);
2066 const node& nod = nodes_[nodeI];
2068 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
2070 nElems += countElements(nod.subNodes_[octant]);
2073 else if (isContent(index))
2075 nElems += contents_[getContent(index)]->size();
2086 template<
class Type>
2098 labelBits index = nodes_[nodeI].subNodes_[octant];
2104 subBb = nodes_[getNode(index)].bb_;
2106 else if (isContent(index) || isEmpty(index))
2108 subBb = nodes_[nodeI].bb_.subBbox(octant);
2111 Pout<<
"dumpContentNode : writing node:" << nodeI <<
" octant:" << octant
2119 const point& pt = bbPoints[i];
2121 str<<
"v " << pt.
x() <<
' ' << pt.y() <<
' ' << pt.z() <<
endl;
2124 forAll(treeBoundBox::edges, i)
2126 const edge&
e = treeBoundBox::edges[i];
2128 str<<
"l " <<
e[0] + 1 <<
' ' <<
e[1] + 1 <<
nl;
2135 template<
class Type>
2140 const label maxLevels,
2141 const scalar maxLeafRatio,
2142 const scalar maxDuplicity
2147 maxLevels_(maxLevels),
2149 maxLeafRatio_(maxLeafRatio),
2150 minSize_(label(maxLeafRatio)),
2151 maxDuplicity_(maxDuplicity),
2152 nodes_(label(shapes.size() / maxLeafRatio_)),
2153 contents_(label(shapes.size() / maxLeafRatio_)),
2156 if (shapes_.size() == 0)
2161 insert(0, shapes_.size());
2172 template<
class Type>
2179 template<
class Type>
2183 const scalar startDistSqr
2186 scalar nearestDistSqr = startDistSqr;
2187 label nearestShapeI = -1;
2203 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2207 template<
class Type>
2215 label nearestShapeI = -1;
2233 nearestPoint =
Zero;
2236 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2240 template<
class Type>
2247 return findLine(
false, start,
end);
2251 template<
class Type>
2258 return findLine(
true, start,
end);
2262 template<
class Type>
2265 const treeBoundBox& searchBox
2276 findBox(0, searchBox, elements);
2278 return elements.toc();
2282 template<
class Type>
2285 const point& centre,
2286 const scalar radiusSqr
2297 findSphere(0, centre, radiusSqr, elements);
2299 return elements.toc();
2303 template<
class Type>
2313 return nodePlusOctant(nodeI, 0);
2316 const node& nod = nodes_[nodeI];
2320 if (!nod.bb_.contains(
sample))
2323 <<
"Cannot find " <<
sample <<
" in node " << nodeI
2330 labelBits index = nod.subNodes_[octant];
2335 return findNode(getNode(index),
sample);
2337 else if (isContent(index))
2340 return nodePlusOctant(nodeI, octant);
2345 return nodePlusOctant(nodeI, octant);
2350 template<
class Type>
2356 labelBits index = findNode(0,
sample);
2358 const node& nod = nodes_[getNode(index)];
2360 labelBits contentIndex = nod.subNodes_[
getOctant(index)];
2363 if (isContent(contentIndex))
2365 const labelList& indices = *(contents_[getContent(contentIndex)]);
2369 label shapeI = indices[elemI];
2371 if (shapes_.contains(shapeI,
sample))
2382 template<
class Type>
2390 const node& nod = nodes_[getNode(index)];
2395 if (isContent(contentIndex))
2397 return *(contents_[getContent(contentIndex)]);
2404 template<
class Type>
2415 if (nodeTypes_.size() != 8*nodes_.size())
2419 nodeTypes_.setSize(8*nodes_.size());
2457 Pout<<
"dynamicIndexedOctree<Type>::getVolumeType : "
2459 <<
" nodes_:" << nodes_.size()
2460 <<
" nodeTypes_:" << nodeTypes_.size()
2461 <<
" nUNKNOWN:" << nUNKNOWN
2462 <<
" nMIXED:" << nMIXED
2463 <<
" nINSIDE:" << nINSIDE
2464 <<
" nOUTSIDE:" << nOUTSIDE
2473 template<
class Type>
2474 template<
class CompareOp>
2477 const scalar nearDist,
2487 nodePlusOctant(0, 0),
2490 nodePlusOctant(0, 0),
2497 template<
class Type>
2500 if (startIndex == endIndex)
2509 autoPtr<DynamicList<label>>
2511 new DynamicList<label>(1)
2515 contents_[0]->append(0);
2518 node topNode =
divide(bb_, 0, -1, 0);
2520 nodes_.append(topNode);
2527 for (label pI = startIndex; pI < endIndex; ++pI)
2531 if (!insertIndex(0, pI, nLevels))
2536 nLevelsMax_ =
max(nLevels, nLevelsMax_);
2543 template<
class Type>
2546 const label nodIndex,
2551 bool shapeInserted =
false;
2553 for (
direction octant = 0; octant < 8; octant++)
2555 const labelBits& subNodeLabel = nodes_[nodIndex].subNodes_[octant];
2557 if (isNode(subNodeLabel))
2559 const treeBoundBox& subBb = nodes_[getNode(subNodeLabel)].bb_;
2561 if (shapes().overlaps(index, subBb))
2565 if (insertIndex(getNode(subNodeLabel), index, nLevels))
2567 shapeInserted =
true;
2571 else if (isContent(subNodeLabel))
2575 if (shapes().overlaps(index, subBb))
2577 const label contentI = getContent(subNodeLabel);
2579 contents_[contentI]->append(index);
2581 recursiveSubDivision
2590 shapeInserted =
true;
2597 if (shapes().overlaps(index, subBb))
2599 label sz = contents_.size();
2606 contents_[sz]->append(index);
2608 nodes_[nodIndex].subNodes_[octant]
2609 = contentPlusOctant(sz, octant);
2612 shapeInserted =
true;
2616 return shapeInserted;
2620 template<
class Type>
2628 removeIndex(0, index);
2634 template<
class Type>
2637 const label nodIndex,
2641 label totalContents = 0;
2643 for (
direction octant = 0; octant < 8; octant++)
2645 const labelBits& subNodeLabel = nodes_[nodIndex].subNodes_[octant];
2647 if (isNode(subNodeLabel))
2649 const treeBoundBox& subBb = nodes_[getNode(subNodeLabel)].bb_;
2651 if (shapes().overlaps(index, subBb))
2654 label childContentsSize
2655 = removeIndex(getNode(subNodeLabel), index);
2657 totalContents += childContentsSize;
2659 if (childContentsSize == 0)
2661 nodes_[nodIndex].subNodes_[octant]
2662 = emptyPlusOctant(octant);
2671 else if (isContent(subNodeLabel))
2675 const label contentI = getContent(subNodeLabel);
2677 if (shapes().overlaps(index, subBb))
2685 const label oldIndex = contentList[pI];
2687 if (oldIndex != index)
2689 newContent.
append(oldIndex);
2695 if (newContent.size() == 0)
2698 nodes_[nodIndex].subNodes_[octant]
2699 = emptyPlusOctant(octant);
2705 totalContents += contents_[contentI]->size();
2713 return totalContents;
2717 template<
class Type>
2721 const bool printContents,
2725 const node& nod = nodes_[nodeI];
2728 os <<
"nodeI:" << nodeI <<
" bb:" << bb <<
nl
2729 <<
"parent:" << nod.parent_ <<
nl
2730 <<
"n:" << countElements(nodePlusOctant(nodeI, 0)) <<
nl;
2732 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
2736 labelBits index = nod.subNodes_[octant];
2741 label subNodeI = getNode(index);
2743 os <<
"octant:" << octant
2744 <<
" node: n:" << countElements(index)
2745 <<
" bb:" << subBb <<
endl;
2747 string oldPrefix =
os.prefix();
2748 os.prefix() =
" " + oldPrefix;
2750 print(
os, printContents, subNodeI);
2752 os.prefix() = oldPrefix;
2754 else if (isContent(index))
2756 const labelList& indices = *(contents_[getContent(index)]);
2763 os <<
"octant:" << octant
2764 <<
" content: n:" << indices.size()
2772 os <<
' ' << indices[j];
2784 os <<
"octant:" << octant <<
" empty:" << subBb <<
endl;
2790 template<
class Type>
2796 nEntries += contents_[i]->size();
2799 Pout<<
"indexedOctree<Type>::indexedOctree"
2800 <<
" : finished construction of tree of:" << shapes().typeName
2802 <<
" bounding box: " << this->bb() <<
nl
2803 <<
" shapes: " << shapes().size() <<
nl
2804 <<
" treeNodes: " << nodes_.size() <<
nl
2805 <<
" nEntries: " << nEntries <<
nl
2806 <<
" levels/maxLevels: " << nLevelsMax_ <<
"/" << maxLevels_ <<
nl
2807 <<
" minSize: " << minSize_ <<
nl
2808 <<
" per treeLeaf: "
2809 << scalar(nEntries)/contents_.size() <<
nl
2810 <<
" per shape (duplicity):"
2811 << scalar(nEntries)/shapes().size() <<
nl
2816 template<
class Type>
2825 template<
class Type>
2833 os << t.contents()[cI]() <<
endl;