45 const scalar nearestDistSqr,
51 return bb.
overlaps(sample, nearestDistSqr);
60 const scalar nearestDistSqr,
79 if (octant & treeBoundBox::octantBit::rightHalf)
88 if (octant & treeBoundBox::octantBit::topHalf)
97 if (octant & treeBoundBox::octantBit::frontHalf)
108 return overlaps(mid, other, nearestDistSqr, sample);
116 const treeBoundBox& bb,
120 List<DynamicList<label>> subIndices(8);
121 for (
direction octant = 0; octant < subIndices.size(); octant++)
123 subIndices[octant].setCapacity(indices.size()/8);
127 FixedList<treeBoundBox, 8> subBbs;
128 for (
direction octant = 0; octant < subBbs.size(); octant++)
130 subBbs[octant] = bb.subBbox(octant);
135 label shapeI = indices[i];
137 for (
direction octant = 0; octant < 8; octant++)
139 if (shapes_.overlaps(shapeI, subBbs[octant]))
141 subIndices[octant].append(shapeI);
147 for (
direction octant = 0; octant < subIndices.size(); octant++)
149 result[octant].transfer(subIndices[octant]);
158 const treeBoundBox& bb,
159 DynamicList<labelList>& contents,
163 const labelList& indices = contents[contentI];
169 bb.min()[0] >= bb.max()[0]
170 || bb.min()[1] >= bb.max()[1]
171 || bb.min()[2] >= bb.max()[2]
175 <<
"Badly formed bounding box:" << bb
183 divide(indices, bb, dividedIndices);
188 bool replaced =
false;
190 for (
direction octant = 0; octant < dividedIndices.size(); octant++)
192 labelList& subIndices = dividedIndices[octant];
194 if (subIndices.size())
198 contents[contentI].
transfer(subIndices);
199 nod.subNodes_[octant] = contentPlusOctant(contentI, octant);
206 label sz = contents.size();
208 contents[sz].transfer(subIndices);
209 nod.subNodes_[octant] = contentPlusOctant(sz, octant);
215 nod.subNodes_[octant] = emptyPlusOctant(octant);
227 DynamicList<indexedOctree<Type>::node>& nodes,
228 DynamicList<labelList>& contents
231 label currentSize = nodes.size();
236 for (
label nodeI = 0; nodeI < currentSize; nodeI++)
241 octant < nodes[nodeI].subNodes_.size();
245 labelBits index = nodes[nodeI].subNodes_[octant];
251 else if (isContent(index))
253 label contentI = getContent(index);
255 if (contents[contentI].size() > minSize)
260 const node& nod = nodes[nodeI];
261 const treeBoundBox bb(nod.bb_.subBbox(octant));
263 node subNode(
divide(bb, contents, contentI));
264 subNode.parent_ = nodeI;
265 label sz = nodes.size();
266 nodes.append(subNode);
267 nodes[nodeI].subNodes_[octant] = nodePlusOctant(sz, octant);
278 DynamicList<node>& nodes,
279 DynamicList<labelList>& contents,
280 const label compactLevel,
284 List<labelList>& compactedContents,
288 const node& nod = nodes[nodeI];
292 if (level < compactLevel)
294 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
296 labelBits index = nod.subNodes_[octant];
300 nNodes += compactContents
313 else if (level == compactLevel)
316 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
318 labelBits index = nod.subNodes_[octant];
320 if (isContent(index))
322 label contentI = getContent(index);
324 compactedContents[compactI].transfer(contents[contentI]);
327 nodes[nodeI].subNodes_[octant] =
328 contentPlusOctant(compactI, octant);
332 else if (isNode(index))
352 const node& nod = nodes_[nodeI];
354 volumeType myType = volumeType::unknown;
356 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
360 labelBits index = nod.subNodes_[octant];
365 subType = calcVolumeType(getNode(index));
367 else if (isContent(index))
371 subType = volumeType::mixed;
377 const treeBoundBox subBb = nod.bb_.subBbox(octant);
379 subType = shapes_.getVolumeType(*
this, subBb.midpoint());
383 nodeTypes_.set((nodeI<<3)+octant, subType);
387 if (myType == volumeType::unknown)
391 else if (subType != myType)
393 myType = volumeType::mixed;
407 const node& nod = nodes_[nodeI];
409 direction octant = nod.bb_.subOctant(sample);
413 if (octantType == volumeType::inside)
417 else if (octantType == volumeType::outside)
421 else if (octantType == volumeType::unknown)
426 else if (octantType == volumeType::mixed)
428 labelBits index = nod.subNodes_[octant];
433 volumeType subType = getVolumeType(getNode(index), sample);
437 else if (isContent(index))
440 return volumeType(shapes_.getVolumeType(*
this, sample));
447 <<
"Sample:" << sample <<
" node:" << nodeI
448 <<
" with bb:" << nodes_[nodeI].bb_ <<
nl
449 <<
"Empty subnode has invalid volume type mixed."
452 return volumeType::unknown;
458 <<
"Sample:" << sample <<
" at node:" << nodeI
459 <<
" octant:" << octant
460 <<
" with bb:" << nod.bb_.subBbox(octant) <<
nl
461 <<
"Node has invalid volume type " << octantType
464 return volumeType::unknown;
472 const vector& outsideNormal,
476 if ((outsideNormal&vec) >= 0)
478 return volumeType::outside;
482 return volumeType::inside;
488 template<
class FindNearestOp>
494 scalar& nearestDistSqr,
495 label& nearestShapeI,
498 const FindNearestOp& fnOp
501 const node& nod = nodes_[nodeI];
516 label subNodeI = getNode(index);
520 if (overlaps(subBb.
min(), subBb.
max(), nearestDistSqr, sample))
535 else if (isContent(index))
550 contents_[getContent(index)],
564 template<
class FindNearestOp>
571 label& nearestShapeI,
575 const FindNearestOp& fnOp
578 const node& nod = nodes_[nodeI];
583 nod.bb_.searchOrder(
ln.centre(), octantOrder);
612 else if (isContent(index))
620 contents_[getContent(index)],
642 const node& nod = nodes_[parentNodeI];
648 return nodes_[getNode(index)].bb_;
653 return nod.bb_.subBbox(octant);
663 const bool pushInside
667 const vector perturbVec = perturbTol_*bb.
span();
669 point perturbedPt(pt);
676 for (
direction dir = 0; dir < vector::nComponents; dir++)
678 if (
mag(pt[dir]-bb.
min()[dir]) <
mag(perturbVec[dir]))
681 scalar perturbDist = perturbVec[dir] + rootVSmall;
682 perturbedPt[dir] = bb.
min()[dir] + perturbDist;
684 else if (
mag(pt[dir]-bb.
max()[dir]) <
mag(perturbVec[dir]))
687 scalar perturbDist = perturbVec[dir] + rootVSmall;
688 perturbedPt[dir] = bb.
max()[dir] - perturbDist;
694 for (
direction dir = 0; dir < vector::nComponents; dir++)
696 if (
mag(pt[dir]-bb.
min()[dir]) <
mag(perturbVec[dir]))
698 scalar perturbDist = perturbVec[dir] + rootVSmall;
699 perturbedPt[dir] = bb.
min()[dir] - perturbDist;
701 else if (
mag(pt[dir]-bb.
max()[dir]) <
mag(perturbVec[dir]))
703 scalar perturbDist = perturbVec[dir] + rootVSmall;
704 perturbedPt[dir] = bb.
max()[dir] + perturbDist;
711 if (pushInside != bb.
contains(perturbedPt))
714 <<
"pushed point:" << pt
715 <<
" to:" << perturbedPt
716 <<
" wanted side:" << pushInside
717 <<
" obtained side:" << bb.
contains(perturbedPt)
730 const treeBoundBox& bb,
733 const bool pushInside
737 const vector perturbVec = perturbTol_*bb.span();
739 point perturbedPt(pt);
750 if (faceID & treeBoundBox::faceBit::left)
754 perturbedPt[0] = bb.
min()[0] + (perturbVec[0] + rootVSmall);
758 perturbedPt[0] = bb.
min()[0] - (perturbVec[0] + rootVSmall);
761 else if (faceID & treeBoundBox::faceBit::right)
765 perturbedPt[0] = bb.
max()[0] - (perturbVec[0] + rootVSmall);
769 perturbedPt[0] = bb.
max()[0] + (perturbVec[0] + rootVSmall);
773 if (faceID & treeBoundBox::faceBit::bottom)
777 perturbedPt[1] = bb.
min()[1] + (perturbVec[1] + rootVSmall);
781 perturbedPt[1] = bb.
min()[1] - (perturbVec[1] + rootVSmall);
784 else if (faceID & treeBoundBox::faceBit::top)
788 perturbedPt[1] = bb.
max()[1] - (perturbVec[1] + rootVSmall);
792 perturbedPt[1] = bb.
max()[1] + (perturbVec[1] + rootVSmall);
796 if (faceID & treeBoundBox::faceBit::back)
800 perturbedPt[2] = bb.
min()[2] + (perturbVec[2] + rootVSmall);
804 perturbedPt[2] = bb.
min()[2] - (perturbVec[2] + rootVSmall);
807 else if (faceID & treeBoundBox::faceBit::front)
811 perturbedPt[2] = bb.
max()[2] - (perturbVec[2] + rootVSmall);
815 perturbedPt[2] = bb.
max()[2] + (perturbVec[2] + rootVSmall);
821 if (pushInside != bb.contains(perturbedPt))
824 <<
"pushed point:" << pt <<
" on face:" << faceString(faceID)
825 <<
" to:" << perturbedPt
826 <<
" wanted side:" << pushInside
827 <<
" obtained side:" << bb.contains(perturbedPt)
840 const treeBoundBox& bb,
847 if (bb.posBits(pt) != 0)
850 <<
" bb:" << bb <<
endl
863 FixedList<direction, 3> faceIndices;
865 if (ptFaceID & treeBoundBox::faceBit::left)
867 faceIndices[nFaces++] = treeBoundBox::faceId::left;
869 else if (ptFaceID & treeBoundBox::faceBit::right)
871 faceIndices[nFaces++] = treeBoundBox::faceId::right;
874 if (ptFaceID & treeBoundBox::faceBit::bottom)
876 faceIndices[nFaces++] = treeBoundBox::faceId::bottom;
878 else if (ptFaceID & treeBoundBox::faceBit::top)
880 faceIndices[nFaces++] = treeBoundBox::faceId::top;
883 if (ptFaceID & treeBoundBox::faceBit::back)
885 faceIndices[nFaces++] = treeBoundBox::faceId::back;
887 else if (ptFaceID & treeBoundBox::faceBit::front)
889 faceIndices[nFaces++] = treeBoundBox::faceId::front;
902 else if (nFaces == 1)
905 keepFaceID = faceIndices[0];
912 keepFaceID = faceIndices[0];
913 scalar maxInproduct =
mag(treeBoundBox::faceNormals[keepFaceID] & dir);
918 scalar
s =
mag(treeBoundBox::faceNormals[face] & dir);
919 if (
s > maxInproduct)
935 if (keepFaceID == treeBoundBox::faceId::left)
938 faceID = treeBoundBox::faceBit::left;
940 else if (keepFaceID == treeBoundBox::faceId::right)
943 faceID = treeBoundBox::faceBit::right;
945 else if (keepFaceID == treeBoundBox::faceId::bottom)
948 faceID = treeBoundBox::faceBit::bottom;
950 else if (keepFaceID == treeBoundBox::faceId::top)
953 faceID = treeBoundBox::faceBit::top;
955 else if (keepFaceID == treeBoundBox::faceId::back)
958 faceID = treeBoundBox::faceBit::back;
960 else if (keepFaceID == treeBoundBox::faceId::front)
963 faceID = treeBoundBox::faceBit::front;
972 <<
"Pushed point from " << pt
973 <<
" on face:" << ptFaceID <<
" of bb:" << bb <<
endl
975 <<
" on face:" << faceID
976 <<
" which is not consistent with geometric face "
983 <<
" bb:" << bb <<
endl
984 <<
"does not contain perturbed point "
1004 parentNodeI = nodes_[nodeI].parent_;
1006 if (parentNodeI == -1)
1012 const node& parentNode = nodes_[parentNodeI];
1017 for (
direction i = 0; i < parentNode.subNodes_.size(); i++)
1019 labelBits index = parentNode.subNodes_[i];
1021 if (isNode(index) && getNode(index) == nodeI)
1028 if (parentOctant == 255)
1031 <<
"Problem: no parent found for octant:" << octant
1032 <<
" node:" << nodeI
1040 template<
class Type>
1053 label oldNodeI = nodeI;
1061 const direction X = treeBoundBox::octantBit::rightHalf;
1062 const direction Y = treeBoundBox::octantBit::topHalf;
1063 const direction Z = treeBoundBox::octantBit::frontHalf;
1068 if ((faceID & treeBoundBox::faceBit::left) != 0)
1074 else if ((faceID & treeBoundBox::faceBit::right) != 0)
1079 if ((faceID & treeBoundBox::faceBit::bottom) != 0)
1085 else if ((faceID & treeBoundBox::faceBit::top) != 0)
1091 if ((faceID & treeBoundBox::faceBit::back) != 0)
1096 else if ((faceID & treeBoundBox::faceBit::front) != 0)
1128 while (wantedValue != (octant & octantMask))
1134 if (wantedValue & X)
1154 if (wantedValue &
Y)
1171 if (wantedValue & Z)
1191 walkToParent(nodeI, octant, parentNodeI, parentOctant);
1193 if (parentNodeI == -1)
1208 nodeI = parentNodeI;
1209 octant = parentOctant;
1215 octant ^= octantMask;
1223 const treeBoundBox subBb(subBbox(nodeI, octant));
1229 <<
" ended up in node:" << nodeI
1230 <<
" octant:" << octant
1231 <<
" with bb:" << subBb
1239 labelBits index = nodes_[nodeI].subNodes_[octant];
1243 labelBits node = findNode(getNode(index),
facePoint);
1245 nodeI = getNode(node);
1246 octant = getOctant(node);
1252 const treeBoundBox subBb(subBbox(nodeI, octant));
1254 if (nodeI == oldNodeI && octant == oldOctant)
1257 <<
"Did not go to neighbour when searching for " <<
facePoint
1259 <<
" starting from face:" << faceString(faceID)
1260 <<
" node:" << nodeI
1261 <<
" octant:" << octant
1270 <<
" ended up in node:" << nodeI
1271 <<
" octant:" << octant
1282 template<
class Type>
1294 if (faceID & treeBoundBox::faceBit::left)
1296 if (!desc.empty()) desc +=
"+";
1299 if (faceID & treeBoundBox::faceBit::right)
1301 if (!desc.empty()) desc +=
"+";
1304 if (faceID & treeBoundBox::faceBit::bottom)
1306 if (!desc.empty()) desc +=
"+";
1309 if (faceID & treeBoundBox::faceBit::top)
1311 if (!desc.empty()) desc +=
"+";
1314 if (faceID & treeBoundBox::faceBit::back)
1316 if (!desc.empty()) desc +=
"+";
1319 if (faceID & treeBoundBox::faceBit::front)
1321 if (!desc.empty()) desc +=
"+";
1328 template<
class Type>
1329 template<
class FindIntersectOp>
1333 const point& treeStart,
1344 const FindIntersectOp& fiOp
1357 const treeBoundBox octantBb(subBbox(nodeI, octant));
1359 if (octantBb.posBits(start) != 0)
1362 <<
"Node:" << nodeI <<
" octant:" << octant
1363 <<
" bb:" << octantBb <<
endl
1368 const node& nod = nodes_[nodeI];
1370 labelBits index = nod.subNodes_[octant];
1372 if (isContent(index))
1374 const labelList& indices = contents_[getContent(index)];
1384 label shapeI = indices[elemI];
1387 bool hit = fiOp(shapeI, start, end, pt);
1396 hitInfo.setIndex(shapeI);
1397 hitInfo.setPoint(pt);
1406 const treeBoundBox octantBb(subBbox(nodeI, octant));
1408 point nearestPoint(end);
1412 label shapeI = indices[elemI];
1415 bool hit = fiOp(shapeI, start, nearestPoint, pt);
1422 if (hit && octantBb.contains(pt))
1428 hitInfo.setIndex(shapeI);
1429 hitInfo.setPoint(pt);
1447 const treeBoundBox octantBb(subBbox(nodeI, octant));
1450 bool intersected = octantBb.intersects
1466 hitInfo.setPoint(pt);
1475 point perturbedEnd(pushPoint(octantBb, end,
false));
1496 template<
class Type>
1497 template<
class FindIntersectOp>
1501 const point& treeStart,
1502 const point& treeEnd,
1503 const label startNodeI,
1505 const FindIntersectOp& fiOp,
1509 const vector treeVec(treeEnd - treeStart);
1512 label nodeI = startNodeI;
1517 Pout<<
"findLine : treeStart:" << treeStart
1518 <<
" treeEnd:" << treeEnd <<
endl
1520 <<
" octant:" << octant
1521 <<
" bb:" << subBbox(nodeI, octant) <<
endl;
1529 for (; i < 100000; i++)
1550 <<
" at current:" << hitInfo.
rawPoint()
1551 <<
" (perturbed:" << startPoint <<
")" <<
endl
1552 <<
" node:" << nodeI
1553 <<
" octant:" << octant
1554 <<
" bb:" << subBbox(nodeI, octant) <<
endl;
1587 if (hitFaceID == 0 || hitInfo.
rawPoint() == treeEnd)
1594 point perturbedPoint
1607 Pout<<
" iter:" << i
1608 <<
" hit face:" << faceString(hitFaceID)
1610 <<
" node:" << nodeI
1611 <<
" octant:" << octant
1612 <<
" bb:" << subBbox(nodeI, octant) <<
nl
1613 <<
" walking to neighbour containing:" << perturbedPoint
1622 bool ok = walkToNeighbour
1641 <<
" to neighbour node:" << nodeI
1642 <<
" octant:" << octant
1644 <<
" of octantBb:" << octantBb <<
endl
1669 <<
"Got stuck in loop raytracing from:" << treeStart
1670 <<
" to:" << treeEnd <<
endl
1671 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1677 <<
"Got stuck in loop raytracing from:" << treeStart
1678 <<
" to:" << treeEnd <<
endl
1679 <<
"inside top box:" << subBbox(startNodeI, startOctant)
1688 template<
class Type>
1689 template<
class FindIntersectOp>
1695 const FindIntersectOp& fiOp
1710 if ((startBit & endBit) != 0)
1719 point trackStart(start);
1720 point trackEnd(end);
1725 if (!treeBb.
intersects(start, end, trackStart))
1734 if (!treeBb.
intersects(end, trackStart, trackEnd))
1742 labelBits index = findNode(0, trackStart);
1744 label parentNodeI = getNode(index);
1762 template<
class Type>
1770 const node& nod = nodes_[nodeI];
1773 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1775 labelBits index = nod.subNodes_[octant];
1779 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1783 findBox(getNode(index), searchBox, elements);
1786 else if (isContent(index))
1788 const treeBoundBox subBb(nodeBb.
subBbox(octant));
1792 const labelList& indices = contents_[getContent(index)];
1796 label shapeI = indices[i];
1798 if (shapes_.overlaps(shapeI, searchBox))
1809 template<
class Type>
1813 const point& centre,
1814 const scalar radiusSqr,
1818 const node& nod = nodes_[nodeI];
1819 const treeBoundBox& nodeBb = nod.bb_;
1821 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1823 labelBits index = nod.subNodes_[octant];
1827 const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
1829 if (subBb.overlaps(centre, radiusSqr))
1831 findSphere(getNode(index), centre, radiusSqr, elements);
1834 else if (isContent(index))
1836 const treeBoundBox subBb(nodeBb.subBbox(octant));
1838 if (subBb.overlaps(centre, radiusSqr))
1840 const labelList& indices = contents_[getContent(index)];
1844 label shapeI = indices[i];
1846 if (shapes_.overlaps(shapeI, centre, radiusSqr))
1848 elements.insert(shapeI);
1857 template<
class Type>
1858 template<
class CompareOp>
1861 const scalar nearDist,
1863 const indexedOctree<Type>& tree1,
1864 const labelBits index1,
1865 const treeBoundBox& bb1,
1866 const indexedOctree<Type>& tree2,
1867 const labelBits index2,
1868 const treeBoundBox& bb2,
1872 const vector nearSpan(nearDist, nearDist, nearDist);
1874 if (tree1.isNode(index1))
1876 const node& nod1 = tree1.nodes()[tree1.getNode(index1)];
1877 const treeBoundBox searchBox
1883 if (tree2.isNode(index2))
1885 if (bb2.overlaps(searchBox))
1887 const node& nod2 = tree2.nodes()[tree2.getNode(index2)];
1889 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
1891 labelBits subIndex2 = nod2.subNodes_[i2];
1892 const treeBoundBox subBb2
1894 tree2.isNode(subIndex2)
1895 ? tree2.nodes()[tree2.getNode(subIndex2)].bb_
1914 else if (tree2.isContent(index2))
1917 for (
direction i1 = 0; i1 < nod1.subNodes_.size(); i1++)
1919 labelBits subIndex1 = nod1.subNodes_[i1];
1920 const treeBoundBox subBb1
1922 tree1.isNode(subIndex1)
1923 ? tree1.nodes()[tree1.getNode(subIndex1)].bb_
1942 else if (tree1.isContent(index1))
1944 const treeBoundBox searchBox
1950 if (tree2.isNode(index2))
1953 tree2.nodes()[tree2.getNode(index2)];
1955 if (bb2.overlaps(searchBox))
1957 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
1959 labelBits subIndex2 = nod2.subNodes_[i2];
1960 const treeBoundBox subBb2
1962 tree2.isNode(subIndex2)
1963 ? tree2.nodes()[tree2.getNode(subIndex2)].bb_
1982 else if (tree2.isContent(index2))
1987 tree1.contents()[tree1.getContent(index1)];
1989 tree2.contents()[tree2.getContent(index2)];
1993 label shape1 = indices1[i];
1997 label shape2 = indices2[j];
1999 if ((&tree1 != &tree2) || (shape1 != shape2))
2031 template<
class Type>
2034 const labelBits index
2042 label nodeI = getNode(index);
2044 const node& nod = nodes_[nodeI];
2046 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
2048 nElems += countElements(nod.subNodes_[octant]);
2051 else if (isContent(index))
2053 nElems += contents_[getContent(index)].size();
2064 template<
class Type>
2076 labelBits index = nodes_[nodeI].subNodes_[octant];
2082 subBb = nodes_[getNode(index)].bb_;
2084 else if (isContent(index) || isEmpty(index))
2086 subBb = nodes_[nodeI].bb_.subBbox(octant);
2089 Pout<<
"dumpContentNode : writing node:" << nodeI <<
" octant:" << octant
2097 const point& pt = bbPoints[i];
2099 str<<
"v " << pt.
x() <<
' ' << pt.y() <<
' ' << pt.z() <<
endl;
2102 forAll(treeBoundBox::edges, i)
2104 const edge&
e = treeBoundBox::edges[i];
2106 str<<
"l " <<
e[0] + 1 <<
' ' <<
e[1] + 1 <<
nl;
2113 template<
class Type>
2123 template<
class Type>
2133 contents_(contents),
2138 template<
class Type>
2143 const label maxLevels,
2144 const scalar maxLeafRatio,
2145 const scalar maxDuplicity
2156 Pout<<
"indexedOctree<Type>::indexedOctree:" <<
nl
2157 <<
" shapes:" <<
shapes.size() <<
nl
2158 <<
" bb:" <<
bb <<
nl
2175 nodes.append(topNode);
2183 for (; nLevels < maxLevels; nLevels++)
2194 Pout<<
"indexedOctree<Type>::indexedOctree:" <<
nl
2195 <<
" nLevels:" << nLevels <<
nl
2196 <<
" nEntries per treeLeaf:" << nEntries/
contents.
size()
2198 <<
" nEntries per shape (duplicity):"
2199 << nEntries/
shapes.size()
2208 nEntries > maxDuplicity*
shapes.size()
2219 label(maxLeafRatio),
2224 if (nOldNodes ==
nodes.size())
2245 label nNodes = compactContents
2256 if (compactI == 0 && nNodes == 0)
2262 if (compactI == contents_.
size())
2270 nodes_.transfer(
nodes);
2278 nEntries += contents_[i].
size();
2284 Pout<<
"indexedOctree<Type>::indexedOctree"
2285 <<
" : finished construction of tree of:" <<
shapes.typeName
2287 <<
" bb:" << this->
bb() <<
nl
2288 <<
" shapes:" << shapes.size() <<
nl
2289 <<
" nLevels:" << nLevels <<
nl
2290 <<
" treeNodes:" << nodes_.size() <<
nl
2291 <<
" nEntries:" << nEntries <<
nl
2294 <<
" per shape (duplicity):"
2295 << scalar(nEntries)/
shapes.size() <<
nl
2296 <<
" total memory:" << memSize-oldMemSize
2302 template<
class Type>
2318 template<
class Type>
2325 template<
class Type>
2328 const point& sample,
2329 const scalar startDistSqr
2336 typename Type::findNearestOp(*
this)
2341 template<
class Type>
2342 template<
class FindNearestOp>
2345 const point& sample,
2346 const scalar startDistSqr,
2348 const FindNearestOp& fnOp
2351 scalar nearestDistSqr = startDistSqr;
2352 label nearestShapeI = -1;
2370 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2374 template<
class Type>
2387 typename Type::findNearestOp(*
this)
2392 template<
class Type>
2393 template<
class FindNearestOp>
2400 const FindNearestOp& fnOp
2403 label nearestShapeI = -1;
2422 return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
2426 template<
class Type>
2438 typename Type::findIntersectOp(*
this)
2443 template<
class Type>
2455 typename Type::findIntersectOp(*
this)
2460 template<
class Type>
2461 template<
class FindIntersectOp>
2466 const FindIntersectOp& fiOp
2469 return findLine(
false, start, end, fiOp);
2473 template<
class Type>
2474 template<
class FindIntersectOp>
2479 const FindIntersectOp& fiOp
2482 return findLine(
true, start, end, fiOp);
2486 template<
class Type>
2497 findBox(0, searchBox, elements);
2500 return elements.
toc();
2504 template<
class Type>
2507 const point& centre,
2508 const scalar radiusSqr
2516 findSphere(0, centre, radiusSqr, elements);
2519 return elements.
toc();
2523 template<
class Type>
2533 return nodePlusOctant(nodeI, 0);
2536 const node& nod = nodes_[nodeI];
2543 <<
"Cannot find " << sample <<
" in node " << nodeI
2555 return findNode(getNode(index), sample);
2557 else if (isContent(index))
2560 return nodePlusOctant(nodeI, octant);
2565 return nodePlusOctant(nodeI, octant);
2570 template<
class Type>
2580 const node& nod = nodes_[getNode(index)];
2585 if (isContent(contentIndex))
2587 labelList indices = contents_[getContent(contentIndex)];
2591 label shapeI = indices[elemI];
2593 if (shapes_.contains(shapeI, sample))
2604 template<
class Type>
2612 return emptyList<label>();
2617 const node& nod = nodes_[getNode(index)];
2622 if (isContent(contentIndex))
2624 return contents_[getContent(contentIndex)];
2628 return emptyList<label>();
2633 template<
class Type>
2644 if (nodeTypes_.size() != 8*nodes_.size())
2648 nodeTypes_.setSize(8*nodes_.size());
2686 Pout<<
"indexedOctree<Type>::getVolumeType : "
2688 <<
" nodes_:" << nodes_.size()
2689 <<
" nodeTypes_:" << nodeTypes_.size()
2690 <<
" nUnknown:" << nUnknown
2691 <<
" nMixed:" << nMixed
2692 <<
" nInside:" << nInside
2693 <<
" nOutside:" << nOutside
2698 return getVolumeType(0, sample);
2702 template<
class Type>
2703 template<
class CompareOp>
2706 const scalar nearDist,
2716 nodePlusOctant(0, 0),
2719 nodePlusOctant(0, 0),
2726 template<
class Type>
2730 const bool printContents,
2734 const node& nod = nodes_[nodeI];
2737 os <<
"nodeI:" << nodeI <<
" bb:" << bb <<
nl
2739 <<
"n:" << countElements(nodePlusOctant(nodeI, 0)) <<
nl;
2750 label subNodeI = getNode(index);
2752 os <<
"octant:" << octant
2753 <<
" node: n:" << countElements(index)
2754 <<
" bb:" << subBb <<
endl;
2756 string oldPrefix = os.
prefix();
2757 os.
prefix() =
" " + oldPrefix;
2759 print(os, printContents, subNodeI);
2763 else if (isContent(index))
2765 const labelList& indices = contents_[getContent(index)];
2772 os <<
"octant:" << octant
2773 <<
" content: n:" << indices.
size()
2781 os <<
' ' << indices[j];
2793 os <<
"octant:" << octant <<
" empty:" << subBb <<
endl;
2799 template<
class Type>
2808 template<
class Type>
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
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 size <Size>.
bool insert(const Key &key)
Insert a new entry.
List< Key > toc() const
Return the table of contents.
bool good() const
Return 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 > &)
Transfer the contents of the argument List into this list.
void append(const T &)
Append an element at the end of the list.
void size(const label)
Override size to be inconsistent with allocated storage.
void setSize(const label)
Reset size of List.
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...
const Point & rawPoint() const
Return point with no checking.
bool hit() const
Is there a hit.
A bounding box defined in terms of the points at its extremities.
const point & min() const
Minimum point defining the bounding box.
const point & max() const
Maximum point defining the bounding box.
bool overlaps(const boundBox &) const
Overlaps/touches boundingBox?
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.
const Type & shapes() const
Reference to shape.
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.
indexedOctree(const Type &shapes)
Construct null.
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
const treeBoundBox & bb() const
Top bounding box.
const labelListList & contents() const
List of all contents (referenced by those nodes that are.
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 process running this object.
int size() const
Access the stored memory size (VmSize in /proc/<pid>/status)
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.
direction faceBits(const point &) const
Code position of point on bounding box faces.
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 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,.
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.
direction posBits(const point &) const
Position of point relative to bounding box.
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)
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.
List< labelList > labelListList
A List of labelList.
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)
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
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