46 const scalar nearestDistSqr,
57 scalar d1 = p1[dir] -
sample[dir];
59 if ((d0 > 0) != (d1 > 0))
64 else if (
mag(d0) <
mag(d1))
73 if (distSqr > nearestDistSqr)
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,
145 contentListList& result
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
204 <<
abort(FatalError);
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)
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."
434 <<
abort(FatalError);
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
444 <<
abort(FatalError);
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];
494 label subNodeI = getNode(index);
498 if (overlaps(subBb.
min(), subBb.
max(), nearestDistSqr,
sample))
511 else if (isContent(index))
526 *(contents_[getContent(index)]),
546 label& nearestShapeI,
551 const node& nod = nodes_[nodeI];
556 nod.bb_.searchOrder(
ln.centre(), octantOrder);
583 else if (isContent(index))
591 *(contents_[getContent(index)]),
608 const label parentNodeI,
613 const node& nod = nodes_[parentNodeI];
619 return nodes_[getNode(index)].bb_;
624 return nod.bb_.subBbox(octant);
634 const bool pushInside
641 const vector perturbVec = perturbTol_*bb.
span();
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;
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;
698 fatal <<
abort(FatalError);
710 const treeBoundBox& bb,
711 const direction faceID,
713 const bool pushInside
720 const vector perturbVec = perturbTol_*bb.span();
722 point perturbedPt(pt);
730 <<
abort(FatalError);
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;
817 fatal <<
abort(FatalError);
829 const treeBoundBox& bb,
836 if (bb.posBits(pt) != 0)
841 <<
" bb:" << bb <<
endl
842 <<
"does not contain point " << pt <<
nl;
846 fatal <<
abort(FatalError);
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;
901 keepFaceID = faceIndices[0];
908 keepFaceID = faceIndices[0];
909 scalar maxInproduct =
mag(treeBoundBox::faceNormals[keepFaceID] & dir);
911 for (direction i = 1; i <
nFaces; i++)
914 scalar
s =
mag(treeBoundBox::faceNormals[face] & dir);
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;
965 if (faceID != bb.faceBits(facePoint))
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 "
975 << bb.faceBits(facePoint) <<
nl;
979 fatal <<
abort(FatalError);
982 if (bb.posBits(facePoint) != 0)
987 <<
" bb:" << bb <<
nl
988 <<
"does not contain perturbed point "
993 fatal <<
abort(FatalError);
1007 const direction octant,
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
1042 <<
abort(FatalError);
1053 const point& facePoint,
1054 const direction faceID,
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;
1248 fatal <<
abort(FatalError);
1256 labelBits index = nodes_[nodeI].subNodes_[octant];
1260 labelBits node = findNode(getNode(index), facePoint);
1262 nodeI = getNode(node);
1263 octant = getOctant(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;
1285 fatal <<
abort(FatalError);
1295 <<
" ended up in node:" << nodeI
1296 <<
" octant:" << octant
1297 <<
" bb:" << subBb <<
nl;
1301 fatal <<
abort(FatalError);
1314 const direction faceID
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 +=
"+";
1361 const point& treeStart,
1367 const direction octant,
1369 pointIndexHit& hitInfo,
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;
1388 fatal <<
abort(FatalError);
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));
1434 point nearestPoint(end);
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));
1530 const point& treeStart,
1531 const point& treeEnd,
1532 const label startNodeI,
1533 const direction startOctant,
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)
1697 <<
abort(FatalError);
1702 <<
"Got stuck in loop raytracing from:" << treeStart
1703 <<
" to:" << treeEnd <<
endl
1704 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1725 const treeBoundBox& treeBb = nodes_[0].bb_;
1730 direction startBit = treeBb.posBits(start);
1733 if ((startBit & endBit) != 0)
1742 point trackStart(start);
1743 point trackEnd(end);
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);
1788 const treeBoundBox& searchBox,
1789 labelHashSet& elements
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);
1835 const point& centre,
1836 const scalar radiusSqr,
1837 labelHashSet& elements
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);
1880template<
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))
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();
2090 const direction octant
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;
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());
2183 const scalar startDistSqr
2186 scalar nearestDistSqr = startDistSqr;
2187 label nearestShapeI = -1;
2203 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2215 label nearestShapeI = -1;
2233 nearestPoint =
Zero;
2236 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2247 return findLine(
false, start, end);
2258 return findLine(
true, start, end);
2276 findBox(0, searchBox, elements);
2278 return elements.
toc();
2285 const point& centre,
2286 const scalar radiusSqr
2297 findSphere(0, centre, radiusSqr, elements);
2299 return elements.
toc();
2313 return nodePlusOctant(nodeI, 0);
2316 const node& nod = nodes_[nodeI];
2323 <<
"Cannot find " <<
sample <<
" in node " << nodeI
2335 return findNode(getNode(index),
sample);
2337 else if (isContent(index))
2340 return nodePlusOctant(nodeI, octant);
2345 return nodePlusOctant(nodeI, octant);
2358 const node& nod = nodes_[getNode(index)];
2363 if (isContent(contentIndex))
2365 const labelList& indices = *(contents_[getContent(contentIndex)]);
2369 label shapeI = indices[elemI];
2371 if (shapes_.contains(shapeI,
sample))
2390 const node& nod = nodes_[getNode(index)];
2395 if (isContent(contentIndex))
2397 return *(contents_[getContent(contentIndex)]);
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
2469 return getVolumeType(0,
sample);
2474template<
class CompareOp>
2477 const scalar nearDist,
2487 nodePlusOctant(0, 0),
2490 nodePlusOctant(0, 0),
2500 if (startIndex == endIndex)
2515 contents_[0]->append(0);
2520 nodes_.append(topNode);
2527 for (label pI = startIndex; pI < endIndex; ++pI)
2531 if (!insertIndex(0, pI, nLevels))
2536 nLevelsMax_ =
max(nLevels, nLevelsMax_);
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;
2628 removeIndex(0, index);
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;
2721 const bool printContents,
2725 const node& nod = nodes_[nodeI];
2728 os <<
"nodeI:" << nodeI <<
" bb:" << bb <<
nl
2730 <<
"n:" << countElements(nodePlusOctant(nodeI, 0)) <<
nl;
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)]);
2760 writeOBJ(nodeI, octant);
2763 os <<
"octant:" << octant
2764 <<
" content: n:" << indices.
size()
2772 os <<
' ' << indices[j];
2781 writeOBJ(nodeI, octant);
2784 os <<
"octant:" << octant <<
" empty:" << subBb <<
endl;
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
Various functions to operate on Lists.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
DynamicList< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
void transfer(List< T > &list)
Transfer contents of the argument List into this.
void append(const T &val)
Copy append an element to the end of this list.
A 1D vector of objects of type <T> with a fixed length <N>.
Minimal example by using system/controlDict.functions:
List< Key > toc() const
The table of contents (the keys) in unsorted order.
bool good() const noexcept
True if next operation might succeed.
static const List< label > & null()
Return a null List.
virtual const fileName & name() const
Get the name of the stream.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
int overlaps
Flag to control which overlap calculations are performed.
unsigned int remove()
Remove and return the last element.
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
void size(const label n)
Older name for setAddressableSize.
const Cmpt & z() const
Access to the vector z component.
const Cmpt & y() const
Access to the vector y component.
const Cmpt & x() const
Access to the vector x component.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
const point & min() const
Minimum describing the bounding box.
const point & max() const
Maximum describing the bounding box.
vector span() const
The bounding box span (from minimum to maximum)
Tree node. Has up pointer and down pointers.
FixedList< labelBits, 8 > subNodes_
IDs of the 8 nodes on all sides of the mid point.
label parent_
Parent node (index into nodes_ of tree)
treeBoundBox bb_
Bounding box of this node.
Non-pointer based hierarchical recursive searching. Storage is dynamic, so elements can be deleted.
label findInside(const point &) const
Find shape containing point. Only implemented for certain.
const labelList & findIndices(const point &) const
Find the shape indices that occupy the result of findNode.
static scalar & perturbTol()
Get the perturbation tolerance.
const treeBoundBox & bb() const
Top bounding box.
label removeIndex(const label nodIndex, const label index)
const contentListList & contents() const
List of all contents (referenced by those nodes that are.
static volumeType getSide(const vector &outsideNormal, const vector &vec)
Helper function to return the side. Returns outside if.
const List< node > & nodes() const
List of all nodes.
bool insert(label startIndex, label endIndex)
Insert a new object into the tree.
labelBits findNode(const label nodeI, const point &) const
Find deepest node (as parent+octant) containing point. Starts.
void writeTreeInfo() const
bool insertIndex(const label nodIndex, const label index, label &nLevels)
pointIndexHit findLineAny(const point &start, const point &end) const
Find any intersection of line between start and end.
virtual bool write()
Write the output fields.
A 29bits label and 3bits direction packed into single label.
scalar print()
Print to screen.
static constexpr direction nComponents
Number of components in bool is 1.
Version of OSstream that prints a prefix on each line.
Standard boundBox with extra functionality for use in octree.
bool overlaps(const boundBox &bb) const
Overlaps other bounding box?
void searchOrder(const point &pt, FixedList< direction, 8 > &octantOrder) const
Calculates optimal order to look for nearest to point.
treeBoundBox subBbox(const direction octant) const
Sub-box of given octant. Midpoint calculated.
bool contains(const vector &dir, const point &) const
Contains point (inside or on edge) and moving in direction.
direction subOctant(const point &pt) const
Returns octant number given point and the calculated midpoint.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
An enumeration wrapper for classification of a location as being inside/outside of a volume.
type
Volume classification types.
@ OUTSIDE
A location outside the volume.
@ MIXED
A location that is partly inside and outside.
@ INSIDE
A location inside the volume.
A class for handling words, derived from Foam::string.
PtrList< volScalarField > & Y
const volScalarField & p0
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define WarningInFunction
Report a warning using Foam::Warning.
rAUs append(new volScalarField(IOobject::groupName("rAU", phase1.name()), 1.0/(U1Eqn.A()+byDt(max(phase1.residualAlpha() - alpha1, scalar(0)) *rho1))))
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
static unsigned getOctant(const point &p)
List< label > labelList
A List of labels.
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
label facePoint(const int facei, const block &block, const label i, const label j)
vectorField pointField
pointField is a vectorField.
vector point
Point is a vector.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
DynamicList< autoPtr< DynamicList< label > > > contentListList
errorManip< error > abort(error &err)
static constexpr const zero Zero
Global zero (0)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
void divide(FieldField< Field, Type > &f, const FieldField< Field, Type > &f1, const FieldField< Field, scalar > &f2)
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
constexpr char nl
The newline '\n' character (0x0a)
#define forAll(list, i)
Loop across all elements in list.