43 const scalar nearestDistSqr,
51 for (
direction dir = 0; dir < vector::nComponents; dir++)
53 scalar d0 = p0[dir] - sample[dir];
54 scalar d1 = p1[dir] - sample[dir];
56 if ((d0 > 0) != (d1 > 0))
61 else if (
mag(d0) <
mag(d1))
70 if (distSqr > nearestDistSqr)
85 const scalar nearestDistSqr,
104 if (octant & treeBoundBox::octantBit::rightHalf)
113 if (octant & treeBoundBox::octantBit::topHalf)
122 if (octant & treeBoundBox::octantBit::frontHalf)
133 return overlaps(mid, other, nearestDistSqr, sample);
140 const autoPtr<DynamicList<label>>& indices,
141 const treeBoundBox& bb,
145 for (
direction octant = 0; octant < 8; octant++)
149 autoPtr<DynamicList<label>>
151 new DynamicList<label>(indices().size()/8)
157 FixedList<treeBoundBox, 8> subBbs;
158 for (
direction octant = 0; octant < 8; octant++)
160 subBbs[octant] = bb.subBbox(octant);
165 label shapeI = indices()[i];
167 for (
direction octant = 0; octant < 8; octant++)
169 if (shapes_.overlaps(shapeI, subBbs[octant]))
171 result[octant]().append(shapeI);
182 const treeBoundBox& bb,
183 const label contentI,
184 const label parentNodeIndex,
185 const label octantToBeDivided
188 const autoPtr<DynamicList<label>>& indices = contents_[contentI];
194 bb.min()[0] >= bb.max()[0]
195 || bb.min()[1] >= bb.max()[1]
196 || bb.min()[2] >= bb.max()[2]
200 <<
"Badly formed bounding box:" << bb
208 divide(indices, bb, dividedIndices);
213 bool replaced =
false;
215 for (
direction octant = 0; octant < dividedIndices.size(); octant++)
217 autoPtr<DynamicList<label>>& subIndices = dividedIndices[octant];
219 if (subIndices().size())
223 contents_[contentI]().transfer(subIndices());
224 nod.subNodes_[octant] = contentPlusOctant(contentI, octant);
232 label sz = contents_.size();
236 autoPtr<DynamicList<label>>
238 new DynamicList<label>()
242 contents_[sz]().transfer(subIndices());
244 nod.subNodes_[octant] = contentPlusOctant(sz, octant);
250 nod.subNodes_[octant] = emptyPlusOctant(octant);
255 if (parentNodeIndex != -1)
257 nod.parent_ = parentNodeIndex;
259 label sz = nodes_.size();
263 nodes_[parentNodeIndex].subNodes_[octantToBeDivided]
264 = nodePlusOctant(sz, octantToBeDivided);
274 const treeBoundBox& subBb,
275 const label contentI,
276 const label parentIndex,
283 contents_[contentI]().size() > minSize_
284 && nLevels < maxLevels_
288 node nod =
divide(subBb, contentI, parentIndex, octant);
295 for (
direction subOct = 0; subOct < 8; subOct++)
297 const labelBits& subNodeLabel = nod.subNodes_[subOct];
299 if (isContent(subNodeLabel))
301 const treeBoundBox subBb = nod.bb_.subBbox(subOct);
303 const label subContentI = getContent(subNodeLabel);
305 const label parentNodeIndex = nodes_.size() - 1;
331 const node& nod = nodes_[nodeI];
333 volumeType myType = volumeType::unknown;
335 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
339 labelBits index = nod.subNodes_[octant];
344 subType = calcVolumeType(getNode(index));
346 else if (isContent(index))
350 subType = volumeType::mixed;
356 const treeBoundBox subBb = nod.bb_.subBbox(octant);
360 shapes_.getVolumeType(*
this, subBb.midpoint())
365 nodeTypes_.set((nodeI<<3)+octant, subType);
369 if (myType == volumeType::unknown)
373 else if (subType != myType)
375 myType = volumeType::mixed;
389 const node& nod = nodes_[nodeI];
391 direction octant = nod.bb_.subOctant(sample);
393 volumeType octantType =
volumeType::type(nodeTypes_.get((nodeI<<3)+octant));
395 if (octantType == volumeType::inside)
399 else if (octantType == volumeType::outside)
403 else if (octantType == volumeType::unknown)
408 else if (octantType == volumeType::mixed)
410 labelBits index = nod.subNodes_[octant];
415 volumeType subType = getVolumeType(getNode(index), sample);
419 else if (isContent(index))
422 return volumeType(shapes_.getVolumeType(*
this, sample));
429 <<
"Sample:" << sample <<
" node:" << nodeI
430 <<
" with bb:" << nodes_[nodeI].bb_ <<
nl
431 <<
"Empty subnode has invalid volume type MIXED."
434 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;
454 const vector& outsideNormal,
458 if ((outsideNormal&vec) >= 0)
460 return volumeType::outside;
464 return volumeType::inside;
475 scalar& nearestDistSqr,
476 label& nearestShapeI,
480 const node& nod = nodes_[nodeI];
495 label subNodeI = getNode(index);
499 if (overlaps(subBb.
min(), subBb.
max(), nearestDistSqr, sample))
512 else if (isContent(index))
527 contents_[getContent(index)],
547 label& nearestShapeI,
552 const node& nod = nodes_[nodeI];
557 nod.bb_.searchOrder(
ln.centre(), octantOrder);
584 else if (isContent(index))
586 const treeBoundBox subBb(nodeBb.
subBbox(octant));
592 contents_[getContent(index)],
609 const label parentNodeI,
614 const node& nod = nodes_[parentNodeI];
615 labelBits index = nod.subNodes_[octant];
620 return nodes_[getNode(index)].bb_;
625 return nod.bb_.subBbox(octant);
633 const treeBoundBox& bb,
635 const bool pushInside
642 const vector perturbVec = perturbTol_*bb.span();
644 point perturbedPt(pt);
651 for (
direction dir = 0; dir < vector::nComponents; dir++)
653 if (
mag(pt[dir]-bb.min()[dir]) <
mag(perturbVec[dir]))
656 scalar perturbDist = perturbVec[dir] + rootVSmall;
657 perturbedPt[dir] = bb.min()[dir] + perturbDist;
659 else if (
mag(pt[dir]-bb.max()[dir]) <
mag(perturbVec[dir]))
662 scalar perturbDist = perturbVec[dir] + rootVSmall;
663 perturbedPt[dir] = bb.max()[dir] - perturbDist;
669 for (
direction dir = 0; dir < vector::nComponents; dir++)
671 if (
mag(pt[dir]-bb.min()[dir]) <
mag(perturbVec[dir]))
673 scalar perturbDist = perturbVec[dir] + rootVSmall;
674 perturbedPt[dir] = bb.min()[dir] - perturbDist;
676 else if (
mag(pt[dir]-bb.max()[dir]) <
mag(perturbVec[dir]))
678 scalar perturbDist = perturbVec[dir] + rootVSmall;
679 perturbedPt[dir] = bb.max()[dir] + perturbDist;
686 if (pushInside != bb.contains(perturbedPt))
689 <<
"pushed point:" << pt
690 <<
" to:" << perturbedPt
691 <<
" wanted side:" << pushInside
692 <<
" obtained side:" << bb.contains(perturbedPt)
705 const treeBoundBox& bb,
708 const bool pushInside
715 const vector perturbVec = perturbTol_*bb.span();
717 point perturbedPt(pt);
728 if (faceID & treeBoundBox::faceBit::left)
732 perturbedPt[0] = bb.min()[0] + (perturbVec[0] + rootVSmall);
736 perturbedPt[0] = bb.min()[0] - (perturbVec[0] + rootVSmall);
739 else if (faceID & treeBoundBox::faceBit::right)
743 perturbedPt[0] = bb.max()[0] - (perturbVec[0] + rootVSmall);
747 perturbedPt[0] = bb.max()[0] + (perturbVec[0] + rootVSmall);
751 if (faceID & treeBoundBox::faceBit::bottom)
755 perturbedPt[1] = bb.min()[1] + (perturbVec[1] + rootVSmall);
759 perturbedPt[1] = bb.min()[1] - (perturbVec[1] + rootVSmall);
762 else if (faceID & treeBoundBox::faceBit::top)
766 perturbedPt[1] = bb.max()[1] - (perturbVec[1] + rootVSmall);
770 perturbedPt[1] = bb.max()[1] + (perturbVec[1] + rootVSmall);
774 if (faceID & treeBoundBox::faceBit::back)
778 perturbedPt[2] = bb.min()[2] + (perturbVec[2] + rootVSmall);
782 perturbedPt[2] = bb.min()[2] - (perturbVec[2] + rootVSmall);
785 else if (faceID & treeBoundBox::faceBit::front)
789 perturbedPt[2] = bb.max()[2] - (perturbVec[2] + rootVSmall);
793 perturbedPt[2] = bb.max()[2] + (perturbVec[2] + rootVSmall);
799 if (pushInside != bb.contains(perturbedPt))
802 <<
"pushed point:" << pt <<
" on face:" << faceString(faceID)
803 <<
" to:" << perturbedPt
804 <<
" wanted side:" << pushInside
805 <<
" obtained side:" << bb.contains(perturbedPt)
818 const treeBoundBox& bb,
825 if (bb.posBits(pt) != 0)
828 <<
" bb:" << bb <<
endl
841 FixedList<direction, 3> faceIndices;
843 if (ptFaceID & treeBoundBox::faceBit::left)
845 faceIndices[nFaces++] = treeBoundBox::faceId::left;
847 else if (ptFaceID & treeBoundBox::faceBit::right)
849 faceIndices[nFaces++] = treeBoundBox::faceId::right;
852 if (ptFaceID & treeBoundBox::faceBit::bottom)
854 faceIndices[nFaces++] = treeBoundBox::faceId::bottom;
856 else if (ptFaceID & treeBoundBox::faceBit::top)
858 faceIndices[nFaces++] = treeBoundBox::faceId::top;
861 if (ptFaceID & treeBoundBox::faceBit::back)
863 faceIndices[nFaces++] = treeBoundBox::faceId::back;
865 else if (ptFaceID & treeBoundBox::faceBit::front)
867 faceIndices[nFaces++] = treeBoundBox::faceId::front;
880 else if (nFaces == 1)
883 keepFaceID = faceIndices[0];
890 keepFaceID = faceIndices[0];
891 scalar maxInproduct =
mag(treeBoundBox::faceNormals[keepFaceID] & dir);
896 scalar
s =
mag(treeBoundBox::faceNormals[face] & dir);
897 if (
s > maxInproduct)
913 if (keepFaceID == treeBoundBox::faceId::left)
916 faceID = treeBoundBox::faceBit::left;
918 else if (keepFaceID == treeBoundBox::faceId::right)
921 faceID = treeBoundBox::faceBit::right;
923 else if (keepFaceID == treeBoundBox::faceId::bottom)
926 faceID = treeBoundBox::faceBit::bottom;
928 else if (keepFaceID == treeBoundBox::faceId::top)
931 faceID = treeBoundBox::faceBit::top;
933 else if (keepFaceID == treeBoundBox::faceId::back)
936 faceID = treeBoundBox::faceBit::back;
938 else if (keepFaceID == treeBoundBox::faceId::front)
941 faceID = treeBoundBox::faceBit::front;
950 <<
"Pushed point from " << pt
951 <<
" on face:" << ptFaceID <<
" of bb:" << bb <<
endl
953 <<
" on face:" << faceID
954 <<
" which is not consistent with geometric face "
961 <<
" bb:" << bb <<
endl
962 <<
"does not contain perturbed point "
982 parentNodeI = nodes_[nodeI].parent_;
984 if (parentNodeI == -1)
990 const node& parentNode = nodes_[parentNodeI];
995 for (
direction i = 0; i < parentNode.subNodes_.size(); i++)
997 labelBits index = parentNode.subNodes_[i];
999 if (isNode(index) && getNode(index) == nodeI)
1006 if (parentOctant == 255)
1009 <<
"Problem: no parent found for octant:" << octant
1010 <<
" node:" << nodeI
1019 template<
class Type>
1033 label oldNodeI = nodeI;
1041 const direction X = treeBoundBox::octantBit::rightHalf;
1042 const direction Y = treeBoundBox::octantBit::topHalf;
1043 const direction Z = treeBoundBox::octantBit::frontHalf;
1048 if ((faceID & treeBoundBox::faceBit::left) != 0)
1054 else if ((faceID & treeBoundBox::faceBit::right) != 0)
1059 if ((faceID & treeBoundBox::faceBit::bottom) != 0)
1065 else if ((faceID & treeBoundBox::faceBit::top) != 0)
1071 if ((faceID & treeBoundBox::faceBit::back) != 0)
1076 else if ((faceID & treeBoundBox::faceBit::front) != 0)
1108 while (wantedValue != (octant & octantMask))
1114 if (wantedValue & X)
1134 if (wantedValue &
Y)
1151 if (wantedValue & Z)
1171 walkToParent(nodeI, octant, parentNodeI, parentOctant);
1173 if (parentNodeI == -1)
1188 nodeI = parentNodeI;
1189 octant = parentOctant;
1195 octant ^= octantMask;
1203 const treeBoundBox subBb(subBbox(nodeI, octant));
1209 <<
" ended up in node:" << nodeI
1210 <<
" octant:" << octant
1211 <<
" with bb:" << subBb
1219 labelBits index = nodes_[nodeI].subNodes_[octant];
1223 labelBits node = findNode(getNode(index),
facePoint);
1225 nodeI = getNode(node);
1226 octant = getOctant(node);
1232 const treeBoundBox subBb(subBbox(nodeI, octant));
1234 if (nodeI == oldNodeI && octant == oldOctant)
1237 <<
"Did not go to neighbour when searching for " <<
facePoint
1239 <<
" starting from face:" << faceString(faceID)
1240 <<
" node:" << nodeI
1241 <<
" octant:" << octant
1250 <<
" ended up in node:" << nodeI
1251 <<
" octant:" << octant
1262 template<
class Type>
1274 if (faceID & treeBoundBox::faceBit::left)
1276 if (!desc.empty()) desc +=
"+";
1279 if (faceID & treeBoundBox::faceBit::right)
1281 if (!desc.empty()) desc +=
"+";
1284 if (faceID & treeBoundBox::faceBit::bottom)
1286 if (!desc.empty()) desc +=
"+";
1289 if (faceID & treeBoundBox::faceBit::top)
1291 if (!desc.empty()) desc +=
"+";
1294 if (faceID & treeBoundBox::faceBit::back)
1296 if (!desc.empty()) desc +=
"+";
1299 if (faceID & treeBoundBox::faceBit::front)
1301 if (!desc.empty()) desc +=
"+";
1308 template<
class Type>
1312 const point& treeStart,
1326 const treeBoundBox octantBb(subBbox(nodeI, octant));
1328 if (octantBb.posBits(start) != 0)
1331 <<
"Node:" << nodeI <<
" octant:" << octant
1332 <<
" bb:" << octantBb <<
endl
1338 const node& nod = nodes_[nodeI];
1340 labelBits index = nod.subNodes_[octant];
1342 if (isContent(index))
1344 const labelList& indices = contents_[getContent(index)];
1354 label shapeI = indices[elemI];
1357 bool hit = shapes_.intersects(shapeI, start, end, pt);
1366 hitInfo.setIndex(shapeI);
1367 hitInfo.setPoint(pt);
1376 const treeBoundBox octantBb(subBbox(nodeI, octant));
1378 point nearestPoint(end);
1382 label shapeI = indices[elemI];
1385 bool hit = shapes_.intersects
1398 if (hit && octantBb.contains(pt))
1404 hitInfo.setIndex(shapeI);
1405 hitInfo.setPoint(pt);
1423 const treeBoundBox octantBb(subBbox(nodeI, octant));
1426 bool intersected = octantBb.intersects
1442 hitInfo.setPoint(pt);
1451 point perturbedEnd(pushPoint(octantBb, end,
false));
1470 template<
class Type>
1474 const point& treeStart,
1475 const point& treeEnd,
1476 const label startNodeI,
1481 const vector treeVec(treeEnd - treeStart);
1484 label nodeI = startNodeI;
1489 Pout<<
"findLine : treeStart:" << treeStart
1490 <<
" treeEnd:" << treeEnd <<
endl
1492 <<
" octant:" << octant
1493 <<
" bb:" << subBbox(nodeI, octant) <<
endl;
1501 for (; i < 100000; i++)
1506 const treeBoundBox octantBb(subBbox(nodeI, octant));
1522 <<
" at current:" << hitInfo.rawPoint()
1523 <<
" (perturbed:" << startPoint <<
")" <<
endl
1524 <<
" node:" << nodeI
1525 <<
" octant:" << octant
1526 <<
" bb:" << subBbox(nodeI, octant) <<
endl;
1557 if (hitFaceID == 0 || hitInfo.rawPoint() == treeEnd)
1564 point perturbedPoint
1577 Pout<<
" iter:" << i
1578 <<
" hit face:" << faceString(hitFaceID)
1579 <<
" at:" << hitInfo.rawPoint() <<
nl
1580 <<
" node:" << nodeI
1581 <<
" octant:" << octant
1582 <<
" bb:" << subBbox(nodeI, octant) <<
nl
1583 <<
" walking to neighbour containing:" << perturbedPoint
1592 bool ok = walkToNeighbour
1609 const treeBoundBox octantBb(subBbox(nodeI, octant));
1610 Pout<<
" walked for point:" << hitInfo.rawPoint() <<
endl
1611 <<
" to neighbour node:" << nodeI
1612 <<
" octant:" << octant
1613 <<
" face:" << faceString(octantBb.faceBits(hitInfo.rawPoint()))
1614 <<
" of octantBb:" << octantBb <<
endl
1638 <<
"Got stuck in loop raytracing from:" << treeStart
1639 <<
" to:" << treeEnd <<
endl
1640 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1646 <<
"Got stuck in loop raytracing from:" << treeStart
1647 <<
" to:" << treeEnd <<
endl
1648 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1657 template<
class Type>
1669 const treeBoundBox& treeBb = nodes_[0].bb_;
1674 direction startBit = treeBb.posBits(start);
1677 if ((startBit & endBit) != 0)
1686 point trackStart(start);
1687 point trackEnd(end);
1692 if (!treeBb.intersects(start, end, trackStart))
1701 if (!treeBb.intersects(end, trackStart, trackEnd))
1709 labelBits index = findNode(0, trackStart);
1711 label parentNodeI = getNode(index);
1728 template<
class Type>
1732 const treeBoundBox& searchBox,
1736 const node& nod = nodes_[nodeI];
1737 const treeBoundBox& nodeBb = nod.bb_;
1739 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1741 labelBits index = nod.subNodes_[octant];
1745 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1747 if (subBb.overlaps(searchBox))
1749 findBox(getNode(index), searchBox, elements);
1752 else if (isContent(index))
1754 const treeBoundBox subBb(nodeBb.subBbox(octant));
1756 if (subBb.overlaps(searchBox))
1758 const labelList& indices = contents_[getContent(index)];
1762 label shapeI = indices[i];
1764 if (shapes_.overlaps(shapeI, searchBox))
1766 elements.insert(shapeI);
1775 template<
class Type>
1779 const point& centre,
1780 const scalar radiusSqr,
1784 const node& nod = nodes_[nodeI];
1785 const treeBoundBox& nodeBb = nod.bb_;
1787 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1789 labelBits index = nod.subNodes_[octant];
1793 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1795 if (subBb.overlaps(centre, radiusSqr))
1797 findSphere(getNode(index), centre, radiusSqr, elements);
1800 else if (isContent(index))
1802 const treeBoundBox subBb(nodeBb.subBbox(octant));
1804 if (subBb.overlaps(centre, radiusSqr))
1806 const labelList& indices = contents_[getContent(index)];
1810 label shapeI = indices[i];
1812 if (shapes_.overlaps(shapeI, centre, radiusSqr))
1814 elements.insert(shapeI);
1823 template<
class Type>
1824 template<
class CompareOp>
1827 const scalar nearDist,
1829 const dynamicIndexedOctree<Type>& tree1,
1830 const labelBits index1,
1831 const treeBoundBox& bb1,
1832 const dynamicIndexedOctree<Type>& tree2,
1833 const labelBits index2,
1834 const treeBoundBox& bb2,
1838 const vector nearSpan(nearDist, nearDist, nearDist);
1840 if (tree1.isNode(index1))
1842 const node& nod1 = tree1.nodes()[tree1.getNode(index1)];
1843 const treeBoundBox searchBox
1849 if (tree2.isNode(index2))
1851 if (bb2.overlaps(searchBox))
1853 const node& nod2 = tree2.nodes()[tree2.getNode(index2)];
1855 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
1857 labelBits subIndex2 = nod2.subNodes_[i2];
1858 const treeBoundBox subBb2
1860 tree2.isNode(subIndex2)
1861 ? tree2.nodes()[tree2.getNode(subIndex2)].bb_
1880 else if (tree2.isContent(index2))
1883 for (
direction i1 = 0; i1 < nod1.subNodes_.size(); i1++)
1885 labelBits subIndex1 = nod1.subNodes_[i1];
1886 const treeBoundBox subBb1
1888 tree1.isNode(subIndex1)
1889 ? tree1.nodes()[tree1.getNode(subIndex1)].bb_
1908 else if (tree1.isContent(index1))
1910 const treeBoundBox searchBox
1916 if (tree2.isNode(index2))
1919 tree2.nodes()[tree2.getNode(index2)];
1921 if (bb2.overlaps(searchBox))
1923 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
1925 labelBits subIndex2 = nod2.subNodes_[i2];
1926 const treeBoundBox subBb2
1928 tree2.isNode(subIndex2)
1929 ? tree2.nodes()[tree2.getNode(subIndex2)].bb_
1948 else if (tree2.isContent(index2))
1953 tree1.contents()[tree1.getContent(index1)];
1955 tree2.contents()[tree2.getContent(index2)];
1959 label shape1 = indices1[i];
1963 label shape2 = indices2[j];
1965 if ((&tree1 != &tree2) || (shape1 != shape2))
1997 template<
class Type>
2000 const labelBits index
2008 label nodeI = getNode(index);
2010 const node& nod = nodes_[nodeI];
2012 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
2014 nElems += countElements(nod.subNodes_[octant]);
2017 else if (isContent(index))
2019 nElems += contents_[getContent(index)]().size();
2030 template<
class Type>
2042 labelBits index = nodes_[nodeI].subNodes_[octant];
2048 subBb = nodes_[getNode(index)].bb_;
2050 else if (isContent(index) || isEmpty(index))
2052 subBb = nodes_[nodeI].bb_.subBbox(octant);
2055 Pout<<
"dumpContentNode : writing node:" << nodeI <<
" octant:" << octant
2063 const point& pt = bbPoints[i];
2065 str<<
"v " << pt.
x() <<
' ' << pt.y() <<
' ' << pt.z() <<
endl;
2068 forAll(treeBoundBox::edges, i)
2070 const edge&
e = treeBoundBox::edges[i];
2072 str<<
"l " <<
e[0] + 1 <<
' ' <<
e[1] + 1 <<
nl;
2079 template<
class Type>
2084 const label maxLevels,
2085 const scalar maxLeafRatio,
2086 const scalar maxDuplicity
2091 maxLevels_(maxLevels),
2093 maxLeafRatio_(maxLeafRatio),
2094 minSize_(
label(maxLeafRatio)),
2095 maxDuplicity_(maxDuplicity),
2096 nodes_(
label(shapes.size() / maxLeafRatio_)),
2097 contents_(
label(shapes.size() / maxLeafRatio_)),
2100 if (shapes_.size() == 0)
2105 insert(0, shapes_.size());
2116 template<
class Type>
2123 template<
class Type>
2126 const point& sample,
2127 const scalar startDistSqr
2130 scalar nearestDistSqr = startDistSqr;
2131 label nearestShapeI = -1;
2147 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2151 template<
class Type>
2159 label nearestShapeI = -1;
2177 nearestPoint =
Zero;
2180 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2184 template<
class Type>
2191 return findLine(
false, start, end);
2195 template<
class Type>
2202 return findLine(
true, start, end);
2206 template<
class Type>
2217 findBox(0, searchBox, elements);
2220 return elements.
toc();
2224 template<
class Type>
2227 const point& centre,
2228 const scalar radiusSqr
2236 findSphere(0, centre, radiusSqr, elements);
2239 return elements.
toc();
2243 template<
class Type>
2253 return nodePlusOctant(nodeI, 0);
2256 const node& nod = nodes_[nodeI];
2263 <<
"Cannot find " << sample <<
" in node " << nodeI
2275 return findNode(getNode(index), sample);
2277 else if (isContent(index))
2280 return nodePlusOctant(nodeI, octant);
2285 return nodePlusOctant(nodeI, octant);
2290 template<
class Type>
2298 const node& nod = nodes_[getNode(index)];
2303 if (isContent(contentIndex))
2305 labelList indices = contents_[getContent(contentIndex)];
2309 label shapeI = indices[elemI];
2311 if (shapes_.contains(shapeI, sample))
2322 template<
class Type>
2330 const node& nod = nodes_[getNode(index)];
2335 if (isContent(contentIndex))
2337 return contents_[getContent(contentIndex)];
2341 return emptyList<label>();
2346 template<
class Type>
2357 if (nodeTypes_.size() != 8*nodes_.size())
2361 nodeTypes_.setSize(8*nodes_.size());
2399 Pout<<
"dynamicIndexedOctree<Type>::getVolumeType : "
2401 <<
" nodes_:" << nodes_.size()
2402 <<
" nodeTypes_:" << nodeTypes_.size()
2403 <<
" nUnknown:" << nUnknown
2404 <<
" nMixed:" << nMixed
2405 <<
" nInside:" << nInside
2406 <<
" nOutside:" << nOutside
2411 return getVolumeType(0, sample);
2415 template<
class Type>
2416 template<
class CompareOp>
2419 const scalar nearDist,
2429 nodePlusOctant(0, 0),
2432 nodePlusOctant(0, 0),
2439 template<
class Type>
2442 if (startIndex == endIndex)
2457 contents_[0]().append(0);
2462 nodes_.append(topNode);
2469 for (
label pI = startIndex; pI < endIndex; ++pI)
2473 if (!insertIndex(0, pI, nLevels))
2478 nLevelsMax_ =
max(nLevels, nLevelsMax_);
2485 template<
class Type>
2488 const label nodIndex,
2493 bool shapeInserted =
false;
2495 for (
direction octant = 0; octant < 8; octant++)
2497 const labelBits& subNodeLabel = nodes_[nodIndex].subNodes_[octant];
2499 if (isNode(subNodeLabel))
2501 const treeBoundBox& subBb = nodes_[getNode(subNodeLabel)].bb_;
2503 if (shapes().overlaps(index, subBb))
2507 if (insertIndex(getNode(subNodeLabel), index, nLevels))
2509 shapeInserted =
true;
2513 else if (isContent(subNodeLabel))
2517 if (shapes().overlaps(index, subBb))
2519 const label contentI = getContent(subNodeLabel);
2521 contents_[contentI]().append(index);
2523 recursiveSubDivision
2532 shapeInserted =
true;
2539 if (shapes().overlaps(index, subBb))
2541 label sz = contents_.size();
2548 contents_[sz]().append(index);
2550 nodes_[nodIndex].subNodes_[octant]
2551 = contentPlusOctant(sz, octant);
2554 shapeInserted =
true;
2558 return shapeInserted;
2562 template<
class Type>
2570 removeIndex(0, index);
2576 template<
class Type>
2579 const label nodIndex,
2583 label totalContents = 0;
2585 for (
direction octant = 0; octant < 8; octant++)
2587 const labelBits& subNodeLabel = nodes_[nodIndex].subNodes_[octant];
2589 if (isNode(subNodeLabel))
2591 const treeBoundBox& subBb = nodes_[getNode(subNodeLabel)].bb_;
2593 if (shapes().overlaps(index, subBb))
2596 label childContentsSize
2597 = removeIndex(getNode(subNodeLabel), index);
2599 totalContents += childContentsSize;
2601 if (childContentsSize == 0)
2603 nodes_[nodIndex].subNodes_[octant]
2604 = emptyPlusOctant(octant);
2613 else if (isContent(subNodeLabel))
2617 const label contentI = getContent(subNodeLabel);
2619 if (shapes().overlaps(index, subBb))
2627 const label oldIndex = contentList[pI];
2629 if (oldIndex != index)
2631 newContent.
append(oldIndex);
2635 newContent.shrink();
2637 if (newContent.size() == 0)
2640 nodes_[nodIndex].subNodes_[octant]
2641 = emptyPlusOctant(octant);
2647 totalContents += contents_[contentI]().size();
2655 return totalContents;
2659 template<
class Type>
2663 const bool printContents,
2667 const node& nod = nodes_[nodeI];
2670 os <<
"nodeI:" << nodeI <<
" bb:" << bb <<
nl
2672 <<
"n:" << countElements(nodePlusOctant(nodeI, 0)) <<
nl;
2683 label subNodeI = getNode(index);
2685 os <<
"octant:" << octant
2686 <<
" node: n:" << countElements(index)
2687 <<
" bb:" << subBb <<
endl;
2689 string oldPrefix = os.
prefix();
2690 os.
prefix() =
" " + oldPrefix;
2692 print(os, printContents, subNodeI);
2696 else if (isContent(index))
2698 const labelList& indices = contents_[getContent(index)];
2705 os <<
"octant:" << octant
2706 <<
" content: n:" << indices.
size()
2714 os <<
' ' << indices[j];
2726 os <<
"octant:" << octant <<
" empty:" << subBb <<
endl;
2732 template<
class Type>
2738 nEntries += contents_[i]().size();
2741 Pout<<
"indexedOctree<Type>::indexedOctree"
2742 <<
" : finished construction of tree of:" << shapes().typeName
2744 <<
" bounding box: " << this->bb() <<
nl
2745 <<
" shapes: " << shapes().size() <<
nl
2746 <<
" treeNodes: " << nodes_.size() <<
nl
2747 <<
" nEntries: " << nEntries <<
nl
2748 <<
" levels/maxLevels: " << nLevelsMax_ <<
"/" << maxLevels_ <<
nl
2749 <<
" minSize: " << minSize_ <<
nl
2750 <<
" per treeLeaf: "
2751 << scalar(nEntries)/contents_.size() <<
nl
2752 <<
" per shape (duplicity):"
2753 << scalar(nEntries)/shapes().size() <<
nl
2758 template<
class Type>
2767 template<
class Type>
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
void transfer(List< T > &)
Transfer contents of the argument List into this.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
A 1D vector of objects of type <T> with a fixed size <Size>.
List< Key > toc() const
Return the table of contents.
bool good() const
Return true if next operation might succeed.
void size(const label)
Override size to be inconsistent with allocated storage.
virtual const fileName & name() const
Return the name of the stream.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
const point & min() const
Minimum point defining the bounding box.
const point & max() const
Maximum point defining the bounding box.
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.
const List< node > & nodes() const
List of all nodes.
static scalar & perturbTol()
Get the perturbation tolerance.
label removeIndex(const label nodIndex, const label index)
void print(prefixOSstream &, const bool printContents, const label) const
Print tree. Either print all indices (printContent = true) or.
static volumeType getSide(const vector &outsideNormal, const vector &vec)
Helper function to return the side. Returns outside if.
bool write(Ostream &os) const
dynamicIndexedOctree(const Type &shapes, const treeBoundBox &bb, const label maxLevels, const scalar maxLeafRatio, const scalar maxDuplicity)
Construct from shapes.
const treeBoundBox & bb() const
Top bounding box.
bool remove(const label index)
Remove an object from the tree.
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
const contentListList & contents() const
List of all contents (referenced by those nodes that are.
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.
A 29bits label and 3bits direction packed into single label.
Version of OSstream which prints a prefix on each line.
const string & prefix() const
Return the prefix of the stream.
Standard boundBox + extra functionality for use in octree.
void searchOrder(const point &pt, FixedList< direction, 8 > &octantOrder) const
Calculates optimal order to look for nearest to point.
treeBoundBox subBbox(const direction) const
Sub box given by octant number. Midpoint calculated.
bool overlaps(const boundBox &) const
Overlaps other bounding box?
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 class for handling words, derived from string.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar e
Elementary charge.
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
PointIndexHit< point > pointIndexHit
Ostream & endl(Ostream &os)
Add newline and flush stream.
word name(const bool)
Return a word representation of a bool.
errorManip< error > abort(error &err)
DynamicList< autoPtr< DynamicList< label > > > contentListList
vectorField pointField
pointField is a vectorField.
vector point
Point is a vector.
label facePoint(const int facei, const block &block, const label i, const label j)
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
void divide(FieldField< Field, Type > &f, const FieldField< Field, Type > &f1, const FieldField< Field, scalar > &f2)
Vector< scalar > vector
A scalar version of the templated Vector.
dimensioned< scalar > mag(const dimensioned< Type > &)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
prefixOSstream Pout(cout, "Pout")
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
Ostream & operator<<(Ostream &os, const fvConstraints &constraints)
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
PtrList< volScalarField > & Y