48 const scalar nearestDistSqr,
61 const treeBoundBox& parentBb,
63 const scalar nearestDistSqr,
82 if (octant & treeBoundBox::RIGHTHALF)
91 if (octant & treeBoundBox::TOPHALF)
100 if (octant & treeBoundBox::FRONTHALF)
111 return overlaps(mid, other, nearestDistSqr,
sample);
119 const treeBoundBox& bb,
123 List<DynamicList<label>> subIndices(8);
124 for (
direction octant = 0; octant < subIndices.size(); octant++)
126 subIndices[octant].setCapacity(indices.size()/8);
130 FixedList<treeBoundBox, 8> subBbs;
131 for (
direction octant = 0; octant < subBbs.size(); octant++)
133 subBbs[octant] = bb.subBbox(octant);
138 label shapeI = indices[i];
140 for (
direction octant = 0; octant < 8; octant++)
142 if (shapes_.overlaps(shapeI, subBbs[octant]))
144 subIndices[octant].append(shapeI);
150 for (
direction octant = 0; octant < subIndices.size(); octant++)
152 result[octant].transfer(subIndices[octant]);
161 const treeBoundBox& bb,
162 DynamicList<labelList>& contents,
166 const labelList& indices = contents[contentI];
172 bb.min()[0] >= bb.max()[0]
173 || bb.min()[1] >= bb.max()[1]
174 || bb.min()[2] >= bb.max()[2]
178 <<
"Badly formed bounding box:" << bb
186 divide(indices, bb, dividedIndices);
191 bool replaced =
false;
193 for (
direction octant = 0; octant < dividedIndices.size(); octant++)
195 labelList& subIndices = dividedIndices[octant];
197 if (subIndices.size())
201 contents[contentI].
transfer(subIndices);
202 nod.subNodes_[octant] = contentPlusOctant(contentI, octant);
209 label sz = contents.size();
211 contents[sz].transfer(subIndices);
212 nod.subNodes_[octant] = contentPlusOctant(sz, octant);
218 nod.subNodes_[octant] = emptyPlusOctant(octant);
230 DynamicList<indexedOctree<Type>::node>& nodes,
231 DynamicList<labelList>& contents
234 label currentSize = nodes.size();
239 for (label nodeI = 0; nodeI < currentSize; nodeI++)
244 octant < nodes[nodeI].subNodes_.size();
248 labelBits index = nodes[nodeI].subNodes_[octant];
254 else if (isContent(index))
256 label contentI = getContent(index);
258 if (contents[contentI].size() > minSize)
263 const node& nod = nodes[nodeI];
264 const treeBoundBox bb(nod.bb_.subBbox(octant));
266 node subNode(
divide(bb, contents, contentI));
267 subNode.parent_ = nodeI;
268 label sz = nodes.size();
270 nodes[nodeI].subNodes_[octant] = nodePlusOctant(sz, octant);
281 DynamicList<node>& nodes,
282 DynamicList<labelList>& contents,
283 const label compactLevel,
287 List<labelList>& compactedContents,
291 const node& nod = nodes[nodeI];
295 if (level < compactLevel)
297 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
299 labelBits index = nod.subNodes_[octant];
303 nNodes += compactContents
316 else if (level == compactLevel)
319 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
321 labelBits index = nod.subNodes_[octant];
323 if (isContent(index))
325 label contentI = getContent(index);
327 compactedContents[compactI].transfer(contents[contentI]);
330 nodes[nodeI].subNodes_[octant] =
331 contentPlusOctant(compactI, octant);
335 else if (isNode(index))
355 const node& nod = nodes_[nodeI];
357 volumeType myType = volumeType::UNKNOWN;
359 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
363 labelBits index = nod.subNodes_[octant];
368 subType = calcVolumeType(getNode(index));
370 else if (isContent(index))
374 subType = volumeType::MIXED;
380 const treeBoundBox subBb = nod.bb_.subBbox(octant);
382 subType = shapes_.getVolumeType(*
this, subBb.centre());
386 nodeTypes_.set((nodeI<<3)+octant, subType);
390 if (myType == volumeType::UNKNOWN)
394 else if (subType != myType)
396 myType = volumeType::MIXED;
410 const node& nod = nodes_[nodeI];
414 volumeType octantType =
volumeType::type(nodeTypes_.get((nodeI<<3)+octant));
416 if (octantType == volumeType::INSIDE)
420 else if (octantType == volumeType::OUTSIDE)
424 else if (octantType == volumeType::UNKNOWN)
429 else if (octantType == volumeType::MIXED)
431 labelBits index = nod.subNodes_[octant];
436 volumeType subType = getVolumeType(getNode(index),
sample);
440 else if (isContent(index))
443 return volumeType(shapes_.getVolumeType(*
this,
sample));
449 <<
"Sample:" <<
sample <<
" node:" << nodeI
450 <<
" with bb:" << nodes_[nodeI].bb_ <<
nl
451 <<
"Empty subnode has invalid volume type MIXED."
454 return volumeType::UNKNOWN;
458 <<
"Sample:" <<
sample <<
" at node:" << nodeI
459 <<
" octant:" << octant
460 <<
" with bb:" << nod.bb_.subBbox(octant) <<
nl
461 <<
"Node has invalid volume type " << octantType
464 return volumeType::UNKNOWN;
471 const vector& outsideNormal,
475 if ((outsideNormal&vec) >= 0)
477 return volumeType::OUTSIDE;
481 return volumeType::INSIDE;
487 template<
class FindNearestOp>
493 scalar& nearestDistSqr,
494 label& nearestShapeI,
497 const FindNearestOp& fnOp
500 const node& nod = nodes_[nodeI];
503 FixedList<direction, 8> octantOrder;
504 nod.bb_.searchOrder(
sample, octantOrder);
511 labelBits index = nod.subNodes_[octant];
515 label subNodeI = getNode(index);
517 const treeBoundBox& subBb = nodes_[subNodeI].bb_;
519 if (overlaps(subBb.min(), subBb.max(), nearestDistSqr,
sample))
534 else if (isContent(index))
549 contents_[getContent(index)],
563 template<
class FindNearestOp>
569 treeBoundBox& tightest,
570 label& nearestShapeI,
574 const FindNearestOp& fnOp
577 const node& nod = nodes_[nodeI];
578 const treeBoundBox& nodeBb = nod.bb_;
581 FixedList<direction, 8> octantOrder;
582 nod.bb_.searchOrder(
ln.centre(), octantOrder);
589 labelBits index = nod.subNodes_[octant];
593 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
595 if (subBb.overlaps(tightest))
611 else if (isContent(index))
613 const treeBoundBox subBb(nodeBb.subBbox(octant));
615 if (subBb.overlaps(tightest))
619 contents_[getContent(index)],
636 const label parentNodeI,
641 const node& nod = nodes_[parentNodeI];
642 labelBits index = nod.subNodes_[octant];
647 return nodes_[getNode(index)].bb_;
652 return nod.bb_.subBbox(octant);
660 const treeBoundBox& bb,
662 const bool pushInside
666 const vector perturbVec = perturbTol_*bb.span();
668 point perturbedPt(pt);
675 for (
direction dir = 0; dir < vector::nComponents; dir++)
677 if (
mag(pt[dir]-bb.min()[dir]) <
mag(perturbVec[dir]))
680 scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
681 perturbedPt[dir] = bb.min()[dir] + perturbDist;
683 else if (
mag(pt[dir]-bb.max()[dir]) <
mag(perturbVec[dir]))
686 scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
687 perturbedPt[dir] = bb.max()[dir] - perturbDist;
693 for (
direction dir = 0; dir < vector::nComponents; dir++)
695 if (
mag(pt[dir]-bb.min()[dir]) <
mag(perturbVec[dir]))
697 scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
698 perturbedPt[dir] = bb.min()[dir] - perturbDist;
700 else if (
mag(pt[dir]-bb.max()[dir]) <
mag(perturbVec[dir]))
702 scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
703 perturbedPt[dir] = bb.max()[dir] + perturbDist;
710 if (pushInside != bb.contains(perturbedPt))
715 <<
"pushed point:" << pt
716 <<
" to:" << perturbedPt
717 <<
" wanted side:" << pushInside
718 <<
" obtained side:" << bb.contains(perturbedPt)
719 <<
" of bb:" << bb <<
nl;
735 const treeBoundBox& bb,
738 const bool pushInside
742 const vector perturbVec = perturbTol_*bb.span();
744 point perturbedPt(pt);
755 if (faceID & treeBoundBox::LEFTBIT)
759 perturbedPt[0] = bb.min()[0] + (perturbVec[0] + ROOTVSMALL);
763 perturbedPt[0] = bb.min()[0] - (perturbVec[0] + ROOTVSMALL);
766 else if (faceID & treeBoundBox::RIGHTBIT)
770 perturbedPt[0] = bb.max()[0] - (perturbVec[0] + ROOTVSMALL);
774 perturbedPt[0] = bb.max()[0] + (perturbVec[0] + ROOTVSMALL);
778 if (faceID & treeBoundBox::BOTTOMBIT)
782 perturbedPt[1] = bb.min()[1] + (perturbVec[1] + ROOTVSMALL);
786 perturbedPt[1] = bb.min()[1] - (perturbVec[1] + ROOTVSMALL);
789 else if (faceID & treeBoundBox::TOPBIT)
793 perturbedPt[1] = bb.max()[1] - (perturbVec[1] + ROOTVSMALL);
797 perturbedPt[1] = bb.max()[1] + (perturbVec[1] + ROOTVSMALL);
801 if (faceID & treeBoundBox::BACKBIT)
805 perturbedPt[2] = bb.min()[2] + (perturbVec[2] + ROOTVSMALL);
809 perturbedPt[2] = bb.min()[2] - (perturbVec[2] + ROOTVSMALL);
812 else if (faceID & treeBoundBox::FRONTBIT)
816 perturbedPt[2] = bb.max()[2] - (perturbVec[2] + ROOTVSMALL);
820 perturbedPt[2] = bb.max()[2] + (perturbVec[2] + ROOTVSMALL);
826 if (pushInside != bb.contains(perturbedPt))
831 <<
"pushed point:" << pt <<
" on face:" << faceString(faceID)
832 <<
" to:" << perturbedPt
833 <<
" wanted side:" << pushInside
834 <<
" obtained side:" << bb.contains(perturbedPt)
835 <<
" of bb:" << bb <<
nl;
851 const treeBoundBox& bb,
858 if (bb.posBits(pt) != 0)
863 <<
" bb:" << bb <<
endl
864 <<
"does not contain point " << pt <<
nl;
881 FixedList<direction, 3> faceIndices;
883 if (ptFaceID & treeBoundBox::LEFTBIT)
885 faceIndices[nFaces++] = treeBoundBox::LEFT;
887 else if (ptFaceID & treeBoundBox::RIGHTBIT)
889 faceIndices[nFaces++] = treeBoundBox::RIGHT;
892 if (ptFaceID & treeBoundBox::BOTTOMBIT)
894 faceIndices[nFaces++] = treeBoundBox::BOTTOM;
896 else if (ptFaceID & treeBoundBox::TOPBIT)
898 faceIndices[nFaces++] = treeBoundBox::TOP;
901 if (ptFaceID & treeBoundBox::BACKBIT)
903 faceIndices[nFaces++] = treeBoundBox::BACK;
905 else if (ptFaceID & treeBoundBox::FRONTBIT)
907 faceIndices[nFaces++] = treeBoundBox::FRONT;
920 else if (nFaces == 1)
923 keepFaceID = faceIndices[0];
930 keepFaceID = faceIndices[0];
937 if (
s > maxInproduct)
953 if (keepFaceID == treeBoundBox::LEFT)
956 faceID = treeBoundBox::LEFTBIT;
958 else if (keepFaceID == treeBoundBox::RIGHT)
961 faceID = treeBoundBox::RIGHTBIT;
963 else if (keepFaceID == treeBoundBox::BOTTOM)
966 faceID = treeBoundBox::BOTTOMBIT;
968 else if (keepFaceID == treeBoundBox::TOP)
971 faceID = treeBoundBox::TOPBIT;
973 else if (keepFaceID == treeBoundBox::BACK)
976 faceID = treeBoundBox::BACKBIT;
978 else if (keepFaceID == treeBoundBox::FRONT)
981 faceID = treeBoundBox::FRONTBIT;
992 <<
"Pushed point from " << pt
993 <<
" on face:" << ptFaceID <<
" of bb:" << bb <<
nl
995 <<
" on face:" << faceID
996 <<
" which is not consistent with geometric face "
1009 <<
" bb:" << bb <<
nl
1010 <<
"does not contain perturbed point "
1025 template<
class Type>
1035 parentNodeI = nodes_[nodeI].parent_;
1037 if (parentNodeI == -1)
1043 const node& parentNode = nodes_[parentNodeI];
1048 for (
direction i = 0; i < parentNode.subNodes_.size(); i++)
1050 labelBits index = parentNode.subNodes_[i];
1052 if (isNode(index) && getNode(index) == nodeI)
1059 if (parentOctant == 255)
1062 <<
"Problem: no parent found for octant:" << octant
1063 <<
" node:" << nodeI
1071 template<
class Type>
1084 label oldNodeI = nodeI;
1092 const direction X = treeBoundBox::RIGHTHALF;
1094 const direction Z = treeBoundBox::FRONTHALF;
1099 if ((faceID & treeBoundBox::LEFTBIT) != 0)
1105 else if ((faceID & treeBoundBox::RIGHTBIT) != 0)
1110 if ((faceID & treeBoundBox::BOTTOMBIT) != 0)
1116 else if ((faceID & treeBoundBox::TOPBIT) != 0)
1122 if ((faceID & treeBoundBox::BACKBIT) != 0)
1127 else if ((faceID & treeBoundBox::FRONTBIT) != 0)
1159 while (wantedValue != (octant & octantMask))
1165 if (wantedValue & X)
1185 if (wantedValue &
Y)
1202 if (wantedValue & Z)
1222 walkToParent(nodeI, octant, parentNodeI, parentOctant);
1224 if (parentNodeI == -1)
1239 nodeI = parentNodeI;
1240 octant = parentOctant;
1246 octant ^= octantMask;
1254 const treeBoundBox subBb(subBbox(nodeI, octant));
1262 <<
" ended up in node:" << nodeI
1263 <<
" octant:" << octant
1264 <<
" with bb:" << subBb <<
nl;
1276 labelBits index = nodes_[nodeI].subNodes_[octant];
1280 labelBits node = findNode(getNode(index),
facePoint);
1282 nodeI = getNode(node);
1289 const treeBoundBox subBb(subBbox(nodeI, octant));
1291 if (nodeI == oldNodeI && octant == oldOctant)
1296 <<
"Did not go to neighbour when searching for " <<
facePoint
1298 <<
" starting from face:" << faceString(faceID)
1299 <<
" node:" << nodeI
1300 <<
" octant:" << octant
1301 <<
" bb:" << subBb <<
nl;
1315 <<
" ended up in node:" << nodeI
1316 <<
" octant:" << octant
1317 <<
" bb:" << subBb <<
nl;
1331 template<
class Type>
1343 if (faceID & treeBoundBox::LEFTBIT)
1345 if (!desc.empty()) desc +=
"+";
1348 if (faceID & treeBoundBox::RIGHTBIT)
1350 if (!desc.empty()) desc +=
"+";
1353 if (faceID & treeBoundBox::BOTTOMBIT)
1355 if (!desc.empty()) desc +=
"+";
1358 if (faceID & treeBoundBox::TOPBIT)
1360 if (!desc.empty()) desc +=
"+";
1363 if (faceID & treeBoundBox::BACKBIT)
1365 if (!desc.empty()) desc +=
"+";
1368 if (faceID & treeBoundBox::FRONTBIT)
1370 if (!desc.empty()) desc +=
"+";
1377 template<
class Type>
1378 template<
class FindIntersectOp>
1382 const point& treeStart,
1393 const FindIntersectOp& fiOp
1406 const treeBoundBox octantBb(subBbox(nodeI, octant));
1408 if (octantBb.posBits(start) != 0)
1413 <<
"Node:" << nodeI <<
" octant:" << octant
1414 <<
" bb:" << octantBb <<
nl
1415 <<
"does not contain point " << start <<
nl;
1424 const node& nod = nodes_[nodeI];
1426 labelBits index = nod.subNodes_[octant];
1428 if (isContent(index))
1430 const labelList& indices = contents_[getContent(index)];
1440 label shapeI = indices[elemI];
1443 bool hit = fiOp(shapeI, start,
end, pt);
1452 hitInfo.setIndex(shapeI);
1453 hitInfo.setPoint(pt);
1462 const treeBoundBox octantBb(subBbox(nodeI, octant));
1468 label shapeI = indices[elemI];
1471 bool hit = fiOp(shapeI, start, nearestPoint, pt);
1478 if (hit && octantBb.contains(pt))
1484 hitInfo.setIndex(shapeI);
1485 hitInfo.setPoint(pt);
1503 const treeBoundBox octantBb(subBbox(nodeI, octant));
1506 bool intersected = octantBb.intersects
1522 hitInfo.setPoint(pt);
1531 point perturbedEnd(pushPoint(octantBb,
end,
false));
1552 template<
class Type>
1553 template<
class FindIntersectOp>
1557 const point& treeStart,
1558 const point& treeEnd,
1559 const label startNodeI,
1561 const FindIntersectOp& fiOp,
1565 const vector treeVec(treeEnd - treeStart);
1568 label nodeI = startNodeI;
1573 Pout<<
"findLine : treeStart:" << treeStart
1574 <<
" treeEnd:" << treeEnd <<
endl
1576 <<
" octant:" << octant
1577 <<
" bb:" << subBbox(nodeI, octant) <<
endl;
1585 for (; i < 100000; i++)
1590 const treeBoundBox octantBb(subBbox(nodeI, octant));
1606 <<
" at current:" << hitInfo.rawPoint()
1607 <<
" (perturbed:" << startPoint <<
")" <<
endl
1608 <<
" node:" << nodeI
1609 <<
" octant:" << octant
1610 <<
" bb:" << subBbox(nodeI, octant) <<
endl;
1643 if (hitFaceID == 0 || hitInfo.rawPoint() == treeEnd)
1650 point perturbedPoint
1663 Pout<<
" iter:" << i
1664 <<
" hit face:" << faceString(hitFaceID)
1665 <<
" at:" << hitInfo.rawPoint() <<
nl
1666 <<
" node:" << nodeI
1667 <<
" octant:" << octant
1668 <<
" bb:" << subBbox(nodeI, octant) <<
nl
1669 <<
" walking to neighbour containing:" << perturbedPoint
1678 bool ok = walkToNeighbour
1695 const treeBoundBox octantBb(subBbox(nodeI, octant));
1696 Pout<<
" walked for point:" << hitInfo.rawPoint() <<
endl
1697 <<
" to neighbour node:" << nodeI
1698 <<
" octant:" << octant
1699 <<
" face:" << faceString(octantBb.faceBits(hitInfo.rawPoint()))
1700 <<
" of octantBb:" << octantBb <<
endl
1725 <<
"Got stuck in loop raytracing from:" << treeStart
1726 <<
" to:" << treeEnd <<
endl
1727 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1733 <<
"Got stuck in loop raytracing from:" << treeStart
1734 <<
" to:" << treeEnd <<
endl
1735 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1744 template<
class Type>
1745 template<
class FindIntersectOp>
1751 const FindIntersectOp& fiOp
1766 if ((startBit & endBit) != 0)
1775 point trackStart(start);
1798 labelBits index = findNode(0, trackStart);
1800 label parentNodeI = getNode(index);
1818 template<
class Type>
1822 const treeBoundBox& searchBox,
1826 const node& nod = nodes_[nodeI];
1827 const treeBoundBox& nodeBb = nod.bb_;
1829 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1831 labelBits index = nod.subNodes_[octant];
1835 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1837 if (subBb.overlaps(searchBox))
1839 findBox(getNode(index), searchBox, elements);
1842 else if (isContent(index))
1844 const treeBoundBox subBb(nodeBb.subBbox(octant));
1846 if (subBb.overlaps(searchBox))
1848 const labelList& indices = contents_[getContent(index)];
1852 label shapeI = indices[i];
1854 if (shapes_.overlaps(shapeI, searchBox))
1856 elements.insert(shapeI);
1865 template<
class Type>
1869 const point& centre,
1870 const scalar radiusSqr,
1874 const node& nod = nodes_[nodeI];
1875 const treeBoundBox& nodeBb = nod.bb_;
1877 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1879 labelBits index = nod.subNodes_[octant];
1883 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1885 if (subBb.overlaps(centre, radiusSqr))
1887 findSphere(getNode(index), centre, radiusSqr, elements);
1890 else if (isContent(index))
1892 const treeBoundBox subBb(nodeBb.subBbox(octant));
1894 if (subBb.overlaps(centre, radiusSqr))
1896 const labelList& indices = contents_[getContent(index)];
1900 label shapeI = indices[i];
1902 if (shapes_.overlaps(shapeI, centre, radiusSqr))
1904 elements.insert(shapeI);
1913 template<
class Type>
1914 template<
class CompareOp>
1917 const scalar nearDist,
1919 const indexedOctree<Type>& tree1,
1920 const labelBits index1,
1921 const treeBoundBox& bb1,
1922 const indexedOctree<Type>& tree2,
1923 const labelBits index2,
1924 const treeBoundBox& bb2,
1928 const vector nearSpan(nearDist, nearDist, nearDist);
1930 if (tree1.isNode(index1))
1932 const node& nod1 = tree1.nodes()[tree1.getNode(index1)];
1933 const treeBoundBox searchBox
1939 if (tree2.isNode(index2))
1941 if (bb2.overlaps(searchBox))
1943 const node& nod2 = tree2.nodes()[tree2.getNode(index2)];
1945 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
1947 labelBits subIndex2 = nod2.subNodes_[i2];
1948 const treeBoundBox subBb2
1950 tree2.isNode(subIndex2)
1951 ? tree2.nodes()[tree2.getNode(subIndex2)].bb_
1970 else if (tree2.isContent(index2))
1973 for (
direction i1 = 0; i1 < nod1.subNodes_.size(); i1++)
1975 labelBits subIndex1 = nod1.subNodes_[i1];
1976 const treeBoundBox subBb1
1978 tree1.isNode(subIndex1)
1979 ? tree1.nodes()[tree1.getNode(subIndex1)].bb_
1998 else if (tree1.isContent(index1))
2000 const treeBoundBox searchBox
2006 if (tree2.isNode(index2))
2009 tree2.nodes()[tree2.getNode(index2)];
2011 if (bb2.overlaps(searchBox))
2013 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
2015 labelBits subIndex2 = nod2.subNodes_[i2];
2016 const treeBoundBox subBb2
2018 tree2.isNode(subIndex2)
2019 ? tree2.nodes()[tree2.getNode(subIndex2)].bb_
2038 else if (tree2.isContent(index2))
2043 tree1.contents()[tree1.getContent(index1)];
2045 tree2.contents()[tree2.getContent(index2)];
2049 label shape1 = indices1[i];
2053 label shape2 = indices2[j];
2055 if ((&tree1 != &tree2) || (shape1 != shape2))
2087 template<
class Type>
2090 const labelBits index
2098 label nodeI = getNode(index);
2100 const node& nod = nodes_[nodeI];
2102 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
2104 nElems += countElements(nod.subNodes_[octant]);
2107 else if (isContent(index))
2109 nElems += contents_[getContent(index)].size();
2120 template<
class Type>
2132 labelBits index = nodes_[nodeI].subNodes_[octant];
2138 subBb = nodes_[getNode(index)].bb_;
2140 else if (isContent(index) || isEmpty(index))
2142 subBb = nodes_[nodeI].bb_.subBbox(octant);
2145 Pout<<
"dumpContentNode : writing node:" << nodeI <<
" octant:" << octant
2153 const point& pt = bbPoints[i];
2155 str<<
"v " << pt.
x() <<
' ' << pt.y() <<
' ' << pt.z() <<
endl;
2158 forAll(treeBoundBox::edges, i)
2160 const edge&
e = treeBoundBox::edges[i];
2162 str<<
"l " <<
e[0] + 1 <<
' ' <<
e[1] + 1 <<
nl;
2169 template<
class Type>
2179 template<
class Type>
2189 contents_(contents),
2194 template<
class Type>
2199 const label maxLevels,
2200 const scalar maxLeafRatio,
2201 const scalar maxDuplicity
2212 Pout<<
"indexedOctree<Type>::indexedOctree:" <<
nl
2213 <<
" shapes:" << shapes.size() <<
nl
2214 <<
" bb:" << bb <<
nl
2219 if (shapes.size() == 0)
2225 DynamicList<node> nodes(label(shapes.size() / maxLeafRatio));
2226 DynamicList<labelList> contents(label(shapes.size() / maxLeafRatio));
2227 contents.append(
identity(shapes.size()));
2230 node topNode(
divide(bb, contents, 0));
2231 nodes.append(topNode);
2239 for (; nLevels < maxLevels; nLevels++)
2243 label maxEntries = 0;
2246 maxEntries =
max(maxEntries, contents[i].size());
2247 nEntries += contents[i].size();
2252 Pout<<
"indexedOctree<Type>::indexedOctree:" <<
nl
2253 <<
" nLevels:" << nLevels <<
nl
2254 <<
" nEntries per treeLeaf:" << nEntries/contents.size()
2256 <<
" nEntries per shape (duplicity):"
2257 << nEntries/shapes.size()
2259 <<
" max nEntries:" << maxEntries
2268 nEntries > maxDuplicity*shapes.size()
2276 label nOldNodes = nodes.size();
2279 label(maxLeafRatio),
2284 if (nOldNodes == nodes.size())
2298 contents_.setSize(contents.size());
2305 label nNodes = compactContents
2316 if (compactI == 0 && nNodes == 0)
2322 if (compactI == contents_.size())
2330 nodes_.transfer(nodes);
2336 label maxEntries = 0;
2339 maxEntries =
max(maxEntries, contents_[i].size());
2340 nEntries += contents_[i].size();
2343 label memSize = memInfo().size();
2346 Pout<<
"indexedOctree<Type>::indexedOctree"
2347 <<
" : finished construction of tree of:" << shapes.typeName
2349 <<
" bb:" << this->bb() <<
nl
2350 <<
" shapes:" << shapes.size() <<
nl
2351 <<
" nLevels:" << nLevels <<
nl
2352 <<
" treeNodes:" << nodes_.size() <<
nl
2353 <<
" nEntries:" << nEntries <<
nl
2355 << scalar(nEntries)/contents.size() <<
nl
2356 <<
" per shape (duplicity):"
2357 << scalar(nEntries)/shapes.size() <<
nl
2358 <<
" max nEntries:" << maxEntries
2360 <<
" total memory:" << memSize-oldMemSize
2366 template<
class Type>
2382 template<
class Type>
2389 template<
class Type>
2393 const scalar startDistSqr
2400 typename Type::findNearestOp(*
this)
2405 template<
class Type>
2406 template<
class FindNearestOp>
2410 const scalar startDistSqr,
2412 const FindNearestOp& fnOp
2415 scalar nearestDistSqr = startDistSqr;
2416 label nearestShapeI = -1;
2434 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2438 template<
class Type>
2451 typename Type::findNearestOp(*
this)
2456 template<
class Type>
2457 template<
class FindNearestOp>
2464 const FindNearestOp& fnOp
2467 label nearestShapeI = -1;
2486 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2490 template<
class Type>
2502 typename Type::findIntersectOp(*
this)
2507 template<
class Type>
2519 typename Type::findIntersectOp(*
this)
2524 template<
class Type>
2525 template<
class FindIntersectOp>
2530 const FindIntersectOp& fiOp
2533 return findLine(
false, start,
end, fiOp);
2537 template<
class Type>
2538 template<
class FindIntersectOp>
2543 const FindIntersectOp& fiOp
2546 return findLine(
true, start,
end, fiOp);
2550 template<
class Type>
2553 const treeBoundBox& searchBox
2564 findBox(0, searchBox, elements);
2566 return elements.toc();
2570 template<
class Type>
2573 const point& centre,
2574 const scalar radiusSqr
2585 findSphere(0, centre, radiusSqr, elements);
2587 return elements.toc();
2591 template<
class Type>
2601 return nodePlusOctant(nodeI, 0);
2604 const node& nod = nodes_[nodeI];
2608 labelBits index = nod.subNodes_[octant];
2613 return findNode(getNode(index),
sample);
2615 else if (isContent(index))
2618 return nodePlusOctant(nodeI, octant);
2623 return nodePlusOctant(nodeI, octant);
2628 template<
class Type>
2636 labelBits index = findNode(0,
sample);
2638 const node& nod = nodes_[getNode(index)];
2640 labelBits contentIndex = nod.subNodes_[
getOctant(index)];
2643 if (isContent(contentIndex))
2645 labelList indices = contents_[getContent(contentIndex)];
2649 label shapeI = indices[elemI];
2651 if (shapes_.contains(shapeI,
sample))
2662 template<
class Type>
2670 return labelList::null();
2673 labelBits index = findNode(0,
sample);
2675 const node& nod = nodes_[getNode(index)];
2677 labelBits contentIndex = nod.subNodes_[
getOctant(index)];
2680 if (isContent(contentIndex))
2682 return contents_[getContent(contentIndex)];
2685 return labelList::null();
2689 template<
class Type>
2697 return volumeType::UNKNOWN;
2700 if (nodeTypes_.size() != 8*nodes_.size())
2704 nodeTypes_.setSize(8*nodes_.size());
2705 nodeTypes_ = volumeType::UNKNOWN;
2720 if (
type == volumeType::UNKNOWN)
2724 else if (
type == volumeType::MIXED)
2728 else if (
type == volumeType::INSIDE)
2732 else if (
type == volumeType::OUTSIDE)
2742 Pout<<
"indexedOctree<Type>::getVolumeType : "
2744 <<
" nodes_:" << nodes_.size()
2745 <<
" nodeTypes_:" << nodeTypes_.size()
2746 <<
" nUNKNOWN:" << nUNKNOWN
2747 <<
" nMIXED:" << nMIXED
2748 <<
" nINSIDE:" << nINSIDE
2749 <<
" nOUTSIDE:" << nOUTSIDE
2758 template<
class Type>
2759 template<
class CompareOp>
2762 const scalar nearDist,
2767 if (!nodes_.empty())
2774 nodePlusOctant(0, 0),
2777 nodePlusOctant(0, 0),
2785 template<
class Type>
2789 const bool printContents,
2798 const node& nod = nodes_[nodeI];
2799 const treeBoundBox& bb = nod.bb_;
2801 os <<
"nodeI:" << nodeI <<
" bb:" << bb <<
nl
2802 <<
"parent:" << nod.parent_ <<
nl
2803 <<
"n:" << countElements(nodePlusOctant(nodeI, 0)) <<
nl;
2805 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
2807 const treeBoundBox subBb(bb.subBbox(octant));
2809 labelBits index = nod.subNodes_[octant];
2814 label subNodeI = getNode(index);
2816 os <<
"octant:" << octant
2817 <<
" node: n:" << countElements(index)
2818 <<
" bb:" << subBb <<
endl;
2820 string oldPrefix =
os.prefix();
2821 os.prefix() =
" " + oldPrefix;
2823 print(
os, printContents, subNodeI);
2825 os.prefix() = oldPrefix;
2827 else if (isContent(index))
2829 const labelList& indices = contents_[getContent(index)];
2836 os <<
"octant:" << octant
2837 <<
" content: n:" << indices.size()
2845 os <<
' ' << indices[j];
2857 os <<
"octant:" << octant <<
" empty:" << subBb <<
endl;
2863 template<
class Type>
2872 template<
class Type>
2876 os << t.bb() << token::SPACE << t.nodes()
2877 << token::SPACE << t.contents();