48 const scalar nearestDistSqr,
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);
118 const labelList& indices,
119 const treeBoundBox& bb,
120 labelListList& result
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
179 <<
abort(FatalError);
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++)
243 direction octant = 0;
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();
269 nodes.append(subNode);
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];
416 if (octantType == volumeType::INSIDE)
420 else if (octantType == volumeType::OUTSIDE)
424 else if (octantType == volumeType::UNKNOWN)
429 else if (octantType == volumeType::MIXED)
440 else if (isContent(index))
449 <<
"Sample:" <<
sample <<
" node:" << nodeI
450 <<
" with bb:" << nodes_[nodeI].bb_ << nl
451 <<
"Empty subnode has invalid volume type MIXED."
452 << abort(FatalError);
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
462 <<
abort(FatalError);
464 return volumeType::UNKNOWN;
471 const vector& outsideNormal,
475 if ((outsideNormal&vec) >= 0)
477 return volumeType::OUTSIDE;
481 return volumeType::INSIDE;
487template<
class FindNearestOp>
493 scalar& nearestDistSqr,
494 label& nearestShapeI,
497 const FindNearestOp& fnOp
500 const node& nod = nodes_[nodeI];
515 label subNodeI = getNode(index);
519 if (overlaps(subBb.
min(), subBb.
max(), nearestDistSqr,
sample))
534 else if (isContent(index))
549 contents_[getContent(index)],
563template<
class FindNearestOp>
570 label& nearestShapeI,
574 const FindNearestOp& fnOp
577 const node& nod = nodes_[nodeI];
582 nod.bb_.searchOrder(
ln.centre(), octantOrder);
611 else if (isContent(index))
615 if (subBb.overlaps(tightest))
619 contents_[getContent(index)],
636 const label parentNodeI,
641 const node& nod = nodes_[parentNodeI];
647 return nodes_[getNode(index)].bb_;
652 return nod.bb_.subBbox(octant);
662 const bool pushInside
666 const vector perturbVec = perturbTol_*bb.
span();
668 point perturbedPt(pt);
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;
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;
723 fatal <<
abort(FatalError);
735 const treeBoundBox& bb,
736 const direction faceID,
738 const bool pushInside
742 const vector perturbVec = perturbTol_*bb.span();
744 point perturbedPt(pt);
752 <<
abort(FatalError);
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;
839 fatal <<
abort(FatalError);
851 const treeBoundBox& bb,
858 if (bb.posBits(pt) != 0)
863 <<
" bb:" << bb <<
endl
864 <<
"does not contain point " << pt <<
nl;
868 fatal <<
abort(FatalError);
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;
923 keepFaceID = faceIndices[0];
930 keepFaceID = faceIndices[0];
931 scalar maxInproduct =
mag(treeBoundBox::faceNormals[keepFaceID] & dir);
933 for (direction i = 1; i <
nFaces; i++)
936 scalar
s =
mag(treeBoundBox::faceNormals[face] & dir);
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;
987 if (faceID != bb.faceBits(facePoint))
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 "
997 << bb.faceBits(facePoint) <<
nl;
1001 fatal <<
abort(FatalError);
1004 if (bb.posBits(facePoint) != 0)
1009 <<
" bb:" << bb <<
nl
1010 <<
"does not contain perturbed point "
1015 fatal <<
abort(FatalError);
1029 const direction octant,
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
1064 <<
abort(FatalError);
1074 const point& facePoint,
1075 const direction faceID,
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));
1256 if (!subBb.contains(facePoint))
1262 <<
" ended up in node:" << nodeI
1263 <<
" octant:" << octant
1264 <<
" with bb:" << subBb <<
nl;
1268 fatal <<
abort(FatalError);
1276 labelBits index = nodes_[nodeI].subNodes_[octant];
1280 labelBits node = findNode(getNode(index), facePoint);
1282 nodeI = getNode(node);
1283 octant = getOctant(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;
1305 fatal <<
abort(FatalError);
1309 if (!subBb.contains(facePoint))
1315 <<
" ended up in node:" << nodeI
1316 <<
" octant:" << octant
1317 <<
" bb:" << subBb <<
nl;
1321 fatal <<
abort(FatalError);
1334 const direction faceID
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 +=
"+";
1378template<
class FindIntersectOp>
1382 const point& treeStart,
1388 const direction octant,
1390 pointIndexHit& hitInfo,
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;
1419 fatal <<
abort(FatalError);
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));
1464 point nearestPoint(end);
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));
1553template<
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++)
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)
1666 <<
" node:" << nodeI
1667 <<
" octant:" << octant
1668 <<
" bb:" << subBbox(nodeI, octant) <<
nl
1669 <<
" walking to neighbour containing:" << perturbedPoint
1678 bool ok = walkToNeighbour
1697 <<
" to neighbour node:" << nodeI
1698 <<
" octant:" << octant
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)
1745template<
class FindIntersectOp>
1751 const FindIntersectOp& fiOp
1766 if ((startBit & endBit) != 0)
1775 point trackStart(start);
1776 point trackEnd(end);
1781 if (!treeBb.
intersects(start, end, trackStart))
1790 if (!treeBb.
intersects(end, trackStart, trackEnd))
1798 labelBits index = findNode(0, trackStart);
1800 label parentNodeI = getNode(index);
1826 const node& nod = nodes_[nodeI];
1829 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1831 labelBits index = nod.subNodes_[octant];
1835 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1839 findBox(getNode(index), searchBox, elements);
1842 else if (isContent(index))
1844 const treeBoundBox subBb(nodeBb.
subBbox(octant));
1848 const labelList& indices = contents_[getContent(index)];
1852 label shapeI = indices[i];
1854 if (shapes_.overlaps(shapeI, searchBox))
1869 const point& centre,
1870 const scalar radiusSqr,
1871 labelHashSet& elements
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);
1914template<
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))
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();
2124 const direction octant
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;
2189 contents_(contents),
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
2231 nodes.append(topNode);
2239 for (; nLevels < maxLevels; nLevels++)
2243 label maxEntries = 0;
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())
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();
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
2356 <<
" per shape (duplicity):"
2357 << scalar(nEntries)/
shapes.size() <<
nl
2358 <<
" max nEntries:" << maxEntries
2360 <<
" total memory:" << memSize-oldMemSize
2393 const scalar startDistSqr
2400 typename Type::findNearestOp(*
this)
2406template<
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);
2451 typename Type::findNearestOp(*
this)
2457template<
class FindNearestOp>
2464 const FindNearestOp& fnOp
2467 label nearestShapeI = -1;
2486 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2502 typename Type::findIntersectOp(*
this)
2519 typename Type::findIntersectOp(*
this)
2525template<
class FindIntersectOp>
2530 const FindIntersectOp& fiOp
2533 return findLine(
false, start, end, fiOp);
2538template<
class FindIntersectOp>
2543 const FindIntersectOp& fiOp
2546 return findLine(
true, start, end, fiOp);
2564 findBox(0, searchBox, elements);
2566 return elements.
toc();
2573 const point& centre,
2574 const scalar radiusSqr
2585 findSphere(0, centre, radiusSqr, elements);
2587 return elements.
toc();
2601 return nodePlusOctant(nodeI, 0);
2604 const node& nod = nodes_[nodeI];
2613 return findNode(getNode(index),
sample);
2615 else if (isContent(index))
2618 return nodePlusOctant(nodeI, octant);
2623 return nodePlusOctant(nodeI, octant);
2638 const node& nod = nodes_[getNode(index)];
2643 if (isContent(contentIndex))
2645 labelList indices = contents_[getContent(contentIndex)];
2649 label shapeI = indices[elemI];
2651 if (shapes_.contains(shapeI,
sample))
2675 const node& nod = nodes_[getNode(index)];
2680 if (isContent(contentIndex))
2682 return contents_[getContent(contentIndex)];
2700 if (nodeTypes_.size() != 8*nodes_.size())
2704 nodeTypes_.setSize(8*nodes_.size());
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
2754 return getVolumeType(0,
sample);
2759template<
class CompareOp>
2762 const scalar nearDist,
2767 if (!nodes_.empty())
2774 nodePlusOctant(0, 0),
2777 nodePlusOctant(0, 0),
2789 const bool printContents,
2798 const node& nod = nodes_[nodeI];
2801 os <<
"nodeI:" << nodeI <<
" bb:" << bb <<
nl
2803 <<
"n:" << countElements(nodePlusOctant(nodeI, 0)) <<
nl;
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)];
2833 writeOBJ(nodeI, octant);
2836 os <<
"octant:" << octant
2837 <<
" content: n:" << indices.
size()
2845 os <<
' ' << indices[j];
2854 writeOBJ(nodeI, octant);
2857 os <<
"octant:" << octant <<
" empty:" << subBb <<
endl;
Various functions to operate on Lists.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
A 1D vector of objects of type <T> with a fixed length <N>.
Minimal example by using system/controlDict.functions:
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
bool good() const noexcept
True if next operation might succeed.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void transfer(List< T > &list)
void setSize(const label n)
Alias for resize()
void append(const T &val)
Append an element at the end of the list.
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.
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
const point_type & rawPoint() const noexcept
The point, no checks. Same as point()
bool hit() const noexcept
Is there a hit?
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.
A bounding box defined in terms of min/max extrema points.
bool overlaps(const boundBox &bb) const
Overlaps/touches boundingBox?
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)
virtual bool write()
Write the output fields.
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.
const labelListList & contents() const
List of all contents (referenced by those nodes that are.
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.
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.
const Type & shapes() const
Reference to shape.
labelBits findNode(const label nodeI, const point &) const
Find deepest node (as parent+octant) containing point. Starts.
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.
Memory usage information for the current process, and the system memory that is free.
int size() const
Memory size (VmSize in /proc/PID/status) at last update()
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 intersects(const point &overallStart, const vector &overallVec, const point &start, const point &end, point &pt, direction &ptBits) const
Intersects segment; set point to intersection position and face,.
direction faceBits(const point &pt) const
Code position of point on bounding box faces.
bool contains(const vector &dir, const point &) const
Contains point (inside or on edge) and moving in direction.
direction posBits(const point &pt) const
Position of point relative to bounding box.
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.
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)
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
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)
List< labelList > labelListList
A List of labelList.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
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.