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)
106 const point mid(0.5*(min+max));
108 return overlaps(mid, other, nearestDistSqr, sample);
121 for (
direction octant = 0; octant < subIndices.
size(); octant++)
123 subIndices[octant].setCapacity(indices.
size()/8);
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]);
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);
209 nod.subNodes_[octant] = contentPlusOctant(sz, octant);
215 nod.subNodes_[octant] = emptyPlusOctant(octant);
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];
263 node subNode(
divide(bb, contents, contentI));
264 subNode.parent_ = nodeI;
267 nodes[nodeI].subNodes_[octant] = nodePlusOctant(sz, octant);
280 const label compactLevel,
288 const node& nod = nodes[nodeI];
292 if (level < compactLevel)
294 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
300 nNodes += compactContents
313 else if (level == compactLevel)
316 for (
direction octant = 0; octant < nod.subNodes_.size(); 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];
356 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
365 subType = calcVolumeType(getNode(index));
367 else if (isContent(index))
371 subType = volumeType::mixed;
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)
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];
505 nod.bb_.searchOrder(sample, octantOrder);
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))
616 if (subBb.overlaps(tightest))
620 contents_[getContent(index)],
637 const label parentNodeI,
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)
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)
850 <<
" bb:" << bb <<
endl 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)
937 facePoint.
x() = bb.
min().
x();
938 faceID = treeBoundBox::faceBit::left;
940 else if (keepFaceID == treeBoundBox::faceId::right)
942 facePoint.
x() = bb.
max().
x();
943 faceID = treeBoundBox::faceBit::right;
945 else if (keepFaceID == treeBoundBox::faceId::bottom)
947 facePoint.
y() = bb.
min().
y();
948 faceID = treeBoundBox::faceBit::bottom;
950 else if (keepFaceID == treeBoundBox::faceId::top)
952 facePoint.
y() = bb.
max().
y();
953 faceID = treeBoundBox::faceBit::top;
955 else if (keepFaceID == treeBoundBox::faceId::back)
957 facePoint.
z() = bb.
min().
z();
958 faceID = treeBoundBox::faceBit::back;
960 else if (keepFaceID == treeBoundBox::faceId::front)
962 facePoint.
z() = bb.
max().
z();
963 faceID = treeBoundBox::faceBit::front;
969 if (faceID != bb.
faceBits(facePoint))
972 <<
"Pushed point from " << pt
973 <<
" on face:" << ptFaceID <<
" of bb:" << bb <<
endl 974 <<
"onto " << facePoint
975 <<
" on face:" << faceID
976 <<
" which is not consistent with geometric face " 980 if (bb.
posBits(facePoint) != 0)
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>
1043 const point& facePoint,
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;
1228 <<
"When searching for " << facePoint
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);
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
1269 <<
"When searching for " << facePoint
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
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);
1408 point nearestPoint(end);
1412 label shapeI = indices[elemI];
1415 bool hit = fiOp(shapeI, start, nearestPoint, 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))
1790 if (subBb.overlaps(searchBox))
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];
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))
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))
1857 template<
class Type>
1858 template<
class CompareOp>
1861 const scalar nearDist,
1872 const vector nearSpan(nearDist, nearDist, nearDist);
1874 if (tree1.
isNode(index1))
1876 const node& nod1 = tree1.
nodes()[tree1.
getNode(index1)];
1883 if (tree2.
isNode(index2))
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];
1917 for (
direction i1 = 0; i1 < nod1.subNodes_.size(); i1++)
1919 labelBits subIndex1 = nod1.subNodes_[i1];
1950 if (tree2.
isNode(index2))
1957 for (
direction i2 = 0; i2 < nod2.subNodes_.size(); i2++)
1959 labelBits subIndex2 = nod2.subNodes_[i2];
1993 label shape1 = indices1[i];
1997 label shape2 = indices2[j];
1999 if ((&tree1 != &tree2) || (shape1 != shape2))
2031 template<
class Type>
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 2163 if (shapes.size() == 0)
2174 node topNode(
divide(bb, contents, 0));
2183 for (; nLevels < maxLevels; nLevels++)
2189 nEntries += contents[i].
size();
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())
2238 contents_.setSize(contents.
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 2293 << scalar(nEntries)/contents.
size() <<
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];
2540 if (!nod.bb_.contains(sample))
2543 <<
"Cannot find " << sample <<
" in node " << nodeI
2548 direction octant = nod.bb_.subOctant(sample);
2550 labelBits index = nod.subNodes_[octant];
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>
2575 const node& nod = nodes_[getNode(index)];
2577 labelBits contentIndex = nod.subNodes_[getOctant(index)];
2580 if (isContent(contentIndex))
2582 labelList indices = contents_[getContent(contentIndex)];
2586 label shapeI = indices[elemI];
2588 if (shapes_.contains(shapeI, sample))
2599 template<
class Type>
2607 const node& nod = nodes_[getNode(index)];
2609 labelBits contentIndex = nod.subNodes_[getOctant(index)];
2612 if (isContent(contentIndex))
2614 return contents_[getContent(contentIndex)];
2618 return emptyList<label>();
2623 template<
class Type>
2631 return volumeType::unknown;
2634 if (nodeTypes_.size() != 8*nodes_.size())
2638 nodeTypes_.setSize(8*nodes_.size());
2639 nodeTypes_ = volumeType::unknown;
2654 if (type == volumeType::unknown)
2658 else if (type == volumeType::mixed)
2662 else if (type == volumeType::inside)
2666 else if (type == volumeType::outside)
2676 Pout<<
"indexedOctree<Type>::getVolumeType : " 2678 <<
" nodes_:" << nodes_.size()
2679 <<
" nodeTypes_:" << nodeTypes_.size()
2680 <<
" nUnknown:" << nUnknown
2681 <<
" nMixed:" << nMixed
2682 <<
" nInside:" << nInside
2683 <<
" nOutside:" << nOutside
2688 return getVolumeType(0, sample);
2692 template<
class Type>
2693 template<
class CompareOp>
2696 const scalar nearDist,
2706 nodePlusOctant(0, 0),
2709 nodePlusOctant(0, 0),
2716 template<
class Type>
2720 const bool printContents,
2724 const node& nod = nodes_[nodeI];
2727 os <<
"nodeI:" << nodeI <<
" bb:" << bb <<
nl 2728 <<
"parent:" << nod.parent_ <<
nl 2729 <<
"n:" << countElements(nodePlusOctant(nodeI, 0)) <<
nl;
2731 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
2735 labelBits index = nod.subNodes_[octant];
2740 label subNodeI = getNode(index);
2742 os <<
"octant:" << octant
2743 <<
" node: n:" << countElements(index)
2744 <<
" bb:" << subBb <<
endl;
2746 string oldPrefix = os.
prefix();
2747 os.
prefix() =
" " + oldPrefix;
2749 print(os, printContents, subNodeI);
2753 else if (isContent(index))
2755 const labelList& indices = contents_[getContent(index)];
2762 os <<
"octant:" << octant
2763 <<
" content: n:" << indices.
size()
2771 os <<
' ' << indices[j];
2783 os <<
"octant:" << octant <<
" empty:" << subBb <<
endl;
2789 template<
class Type>
2798 template<
class Type>
2799 Foam::Ostream& Foam::operator<<(Ostream& os, const indexedOctree<Type>& t)
2802 os << t.bb() << token::SPACE << t.nodes()
2803 << token::SPACE << t.contents();
void divide(FieldField< Field, Type > &f, const FieldField< Field, Type > &f1, const FieldField< Field, scalar > &f2)
bool overlaps(const boundBox &) const
Overlaps/touches boundingBox?
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
A face is a list of labels corresponding to mesh vertices.
A 1D vector of objects of type <T> with a fixed size <Size>.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
pointIndexHit findLineAny(const point &start, const point &end) const
Find any intersection of line between start and end.
treeBoundBox subBbox(const direction) const
Sub box given by octant number. Midpoint calculated.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
void size(const label)
Override size to be inconsistent with allocated storage.
const labelListList & contents() const
List of all contents (referenced by those nodes that are.
direction faceBits(const point &) const
Code position of point on bounding box faces.
void setIndex(const label index)
Ostream & endl(Ostream &os)
Add newline and flush stream.
static scalar & perturbTol()
Get the perturbation tolerance.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
A bounding box defined in terms of the points at its extremities.
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
PointIndexHit< point > pointIndexHit
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 fileName & name() const
Return the name of the stream.
bool insert(const Key &key)
Insert a new entry.
static bool isNode(const labelBits i)
direction posBits(const point &) const
Position of point relative to bounding box.
void setPoint(const Point &p)
bool good() const
Return true if next operation might succeed.
labelBits findNode(const label nodeI, const point &) const
Find deepest node (as parent+octant) containing point. Starts.
Various functions to operate on Lists.
const string & prefix() const
Return the prefix of the stream.
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.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
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,.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Version of OSstream which prints a prefix on each line.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
A class for handling words, derived from string.
void append(const T &)
Append an element at the end of the list.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
bool hit() const
Is there a hit.
const Type & shapes() const
Reference to shape.
List< label > labelList
A List of labels.
const treeBoundBox & bb() const
Top bounding box.
errorManip< error > abort(error &err)
Tree node. Has up pointer and down pointers.
point midpoint() const
The midpoint of the bounding box.
const Point & rawPoint() const
Return point with no checking.
indexedOctree(const Type &shapes)
Construct null.
bool contains(const vector &dir, const point &) const
Contains point (inside or on edge) and moving in direction.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
void print(prefixOSstream &, const bool printContents, const label) const
Print tree. Either print all indices (printContent = true) or.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
static bool isContent(const labelBits i)
label size() const
Return the number of elements in the FixedList.
label findInside(const point &) const
Find shape containing point. Only implemented for certain.
label facePoint(const int facei, const block &block, const label i, const label j)
Memory usage information for the process running this object.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
word name(const complex &)
Return a string representation of a complex.
static label getContent(const labelBits i)
Point centre() const
Return centre (centroid)
const labelList & findIndices(const point &) const
Find the shape indices that occupy the result of findNode.
void setSize(const label)
Reset size of List.
const point & max() const
Maximum describing the bounding box.
Non-pointer based hierarchical recursive searching.
#define WarningInFunction
Report a warning using Foam::Warning.
prefixOSstream Pout(cout, "Pout")
static label getNode(const labelBits i)
PtrList< volScalarField > & Y
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
tmp< pointField > points() const
Vertex coordinates. In octant coding.
vector span() const
The bounding box span (from minimum to maximum)
Standard boundBox + extra functionality for use in octree.
A 29bits label and 3bits direction packed into single label.
dimensioned< scalar > mag(const dimensioned< Type > &)
const point & min() const
Minimum describing the bounding box.
List< Key > toc() const
Return the table of contents.
void clear()
Clear the addressed list, i.e. set the size to zero.
void transfer(List< T > &)
Transfer contents of the argument List into this.
bool write(Ostream &os) const
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
const dimensionedScalar e
Elementary charge.
int size() const
Access the stored memory size (VmSize in /proc/<pid>/status)