mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: reduce some internal overhead when splitting octree nodes (#2609)
- don't need separate scratch arrays (avoids possible reallocations when split is imbalanced) ENH: upgrade dynamicIndexedOctree to use DynamicList directly - with C++11 move semantics don't need lists of autoPtr for efficient transfers
This commit is contained in:
committed by
Andrew Heather
parent
b129446221
commit
3d7dc6a870
@ -41,38 +41,27 @@ Foam::scalar Foam::dynamicIndexedOctree<Type>::perturbTol_ = 10*SMALL;
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::dynamicIndexedOctree<Type>::divide
|
void Foam::dynamicIndexedOctree<Type>::divide
|
||||||
(
|
(
|
||||||
const autoPtr<DynamicList<label>>& indices,
|
const labelUList& indices,
|
||||||
const treeBoundBox& bb,
|
const treeBoundBox& bb,
|
||||||
contentListList& result
|
FixedList<DynamicList<label>, 8>& dividedIndices
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
for (direction octant = 0; octant < 8; octant++)
|
const label presize = (indices.size()/8);
|
||||||
{
|
|
||||||
result.append
|
|
||||||
(
|
|
||||||
autoPtr<DynamicList<label>>
|
|
||||||
(
|
|
||||||
new DynamicList<label>(indices().size()/8)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Precalculate bounding boxes.
|
for (direction octant = 0; octant < 8; ++octant)
|
||||||
FixedList<treeBoundBox, 8> subBbs;
|
|
||||||
for (direction octant = 0; octant < 8; octant++)
|
|
||||||
{
|
{
|
||||||
subBbs[octant] = bb.subBbox(octant);
|
const treeBoundBox subBbs(bb.subBbox(octant));
|
||||||
}
|
|
||||||
|
|
||||||
forAll(indices(), i)
|
auto& contains = dividedIndices[octant];
|
||||||
{
|
|
||||||
label shapeI = indices()[i];
|
|
||||||
|
|
||||||
for (direction octant = 0; octant < 8; octant++)
|
contains.clear();
|
||||||
|
contains.reserve_nocopy(presize);
|
||||||
|
|
||||||
|
for (const label index : indices)
|
||||||
{
|
{
|
||||||
if (shapes_.overlaps(shapeI, subBbs[octant]))
|
if (shapes_.overlaps(index, subBbs))
|
||||||
{
|
{
|
||||||
result[octant]().append(shapeI);
|
contains.append(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,20 +73,16 @@ Foam::dynamicIndexedOctreeBase::node
|
|||||||
Foam::dynamicIndexedOctree<Type>::divide
|
Foam::dynamicIndexedOctree<Type>::divide
|
||||||
(
|
(
|
||||||
const treeBoundBox& bb,
|
const treeBoundBox& bb,
|
||||||
const label contentI,
|
label contentIndex,
|
||||||
const label parentNodeIndex,
|
const label parentNodeIndex,
|
||||||
const label octantToBeDivided
|
const label octantToBeDivided
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const autoPtr<DynamicList<label>>& indices = contents_[contentI];
|
|
||||||
|
|
||||||
node nod;
|
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
bb.min()[0] >= bb.max()[0]
|
bb.min().x() >= bb.max().x()
|
||||||
|| bb.min()[1] >= bb.max()[1]
|
|| bb.min().y() >= bb.max().y()
|
||||||
|| bb.min()[2] >= bb.max()[2]
|
|| bb.min().z() >= bb.max().z()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
@ -105,48 +90,42 @@ Foam::dynamicIndexedOctree<Type>::divide
|
|||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Divide the indices into 8 (possibly empty) subsets.
|
||||||
|
// Replace current contentIndex with the first (non-empty) subset.
|
||||||
|
// Append the rest.
|
||||||
|
|
||||||
|
const DynamicList<label>& indices = contents_[contentIndex];
|
||||||
|
|
||||||
|
FixedList<DynamicList<label>, 8> dividedIndices;
|
||||||
|
divide(indices, bb, dividedIndices);
|
||||||
|
|
||||||
|
node nod;
|
||||||
nod.bb_ = bb;
|
nod.bb_ = bb;
|
||||||
nod.parent_ = -1;
|
nod.parent_ = -1;
|
||||||
|
|
||||||
contentListList dividedIndices(8);
|
bool replaceNode = true;
|
||||||
divide(indices, bb, dividedIndices);
|
|
||||||
|
|
||||||
// Have now divided the indices into 8 (possibly empty) subsets.
|
for (direction octant = 0; octant < 8; ++octant)
|
||||||
// Replace current contentI with the first (non-empty) subset.
|
|
||||||
// Append the rest.
|
|
||||||
bool replaced = false;
|
|
||||||
|
|
||||||
for (direction octant = 0; octant < dividedIndices.size(); octant++)
|
|
||||||
{
|
{
|
||||||
autoPtr<DynamicList<label>>& subIndices = dividedIndices[octant];
|
auto& subIndices = dividedIndices[octant];
|
||||||
|
|
||||||
if (subIndices().size())
|
if (subIndices.size())
|
||||||
{
|
{
|
||||||
if (!replaced)
|
if (replaceNode)
|
||||||
{
|
{
|
||||||
contents_[contentI]->transfer(subIndices());
|
// Replace existing
|
||||||
nod.subNodes_[octant] = contentPlusOctant(contentI, octant);
|
contents_[contentIndex] = std::move(subIndices);
|
||||||
|
replaceNode = false;
|
||||||
replaced = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Store at end of contents.
|
// Append to contents
|
||||||
// note dummy append + transfer trick
|
contentIndex = contents_.size();
|
||||||
label sz = contents_.size();
|
contents_.append(std::move(subIndices));
|
||||||
|
|
||||||
contents_.append
|
|
||||||
(
|
|
||||||
autoPtr<DynamicList<label>>
|
|
||||||
(
|
|
||||||
new DynamicList<label>()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
contents_[sz]->transfer(subIndices());
|
|
||||||
|
|
||||||
nod.subNodes_[octant] = contentPlusOctant(sz, octant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nod.subNodes_[octant] = contentPlusOctant(contentIndex, octant);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -160,12 +139,12 @@ Foam::dynamicIndexedOctree<Type>::divide
|
|||||||
{
|
{
|
||||||
nod.parent_ = parentNodeIndex;
|
nod.parent_ = parentNodeIndex;
|
||||||
|
|
||||||
label sz = nodes_.size();
|
const label newNodeId = nodes_.size();
|
||||||
|
|
||||||
nodes_.append(nod);
|
nodes_.append(nod);
|
||||||
|
|
||||||
nodes_[parentNodeIndex].subNodes_[octantToBeDivided]
|
nodes_[parentNodeIndex].subNodes_[octantToBeDivided]
|
||||||
= nodePlusOctant(sz, octantToBeDivided);
|
= nodePlusOctant(newNodeId, octantToBeDivided);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nod;
|
return nod;
|
||||||
@ -184,7 +163,7 @@ void Foam::dynamicIndexedOctree<Type>::recursiveSubDivision
|
|||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
contents_[contentI]->size() > minSize_
|
contents_[contentI].size() > minSize_
|
||||||
&& nLevels < maxLevels_
|
&& nLevels < maxLevels_
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -415,7 +394,7 @@ void Foam::dynamicIndexedOctree<Type>::findNearest
|
|||||||
{
|
{
|
||||||
shapes_.findNearest
|
shapes_.findNearest
|
||||||
(
|
(
|
||||||
*(contents_[getContent(index)]),
|
contents_[getContent(index)],
|
||||||
sample,
|
sample,
|
||||||
|
|
||||||
nearestDistSqr,
|
nearestDistSqr,
|
||||||
@ -474,7 +453,7 @@ void Foam::dynamicIndexedOctree<Type>::findNearest
|
|||||||
{
|
{
|
||||||
shapes_.findNearest
|
shapes_.findNearest
|
||||||
(
|
(
|
||||||
*(contents_[getContent(index)]),
|
contents_[getContent(index)],
|
||||||
ln,
|
ln,
|
||||||
|
|
||||||
tightest,
|
tightest,
|
||||||
@ -1265,7 +1244,7 @@ void Foam::dynamicIndexedOctree<Type>::traverseNode
|
|||||||
|
|
||||||
if (isContent(index))
|
if (isContent(index))
|
||||||
{
|
{
|
||||||
const labelList& indices = *(contents_[getContent(index)]);
|
const labelList& indices = contents_[getContent(index)];
|
||||||
|
|
||||||
if (indices.size())
|
if (indices.size())
|
||||||
{
|
{
|
||||||
@ -1675,7 +1654,7 @@ void Foam::dynamicIndexedOctree<Type>::findBox
|
|||||||
{
|
{
|
||||||
if (nodeBb.subOverlaps(octant, searchBox))
|
if (nodeBb.subOverlaps(octant, searchBox))
|
||||||
{
|
{
|
||||||
const labelList& indices = *(contents_[getContent(index)]);
|
const labelList& indices = contents_[getContent(index)];
|
||||||
|
|
||||||
forAll(indices, i)
|
forAll(indices, i)
|
||||||
{
|
{
|
||||||
@ -1721,7 +1700,7 @@ void Foam::dynamicIndexedOctree<Type>::findSphere
|
|||||||
{
|
{
|
||||||
if (nodeBb.subOverlaps(octant, centre, radiusSqr))
|
if (nodeBb.subOverlaps(octant, centre, radiusSqr))
|
||||||
{
|
{
|
||||||
const labelList& indices = *(contents_[getContent(index)]);
|
const labelList& indices = contents_[getContent(index)];
|
||||||
|
|
||||||
forAll(indices, i)
|
forAll(indices, i)
|
||||||
{
|
{
|
||||||
@ -1934,7 +1913,7 @@ Foam::label Foam::dynamicIndexedOctree<Type>::countElements
|
|||||||
}
|
}
|
||||||
else if (isContent(index))
|
else if (isContent(index))
|
||||||
{
|
{
|
||||||
nElems += contents_[getContent(index)]->size();
|
nElems += contents_[getContent(index)].size();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2049,7 +2028,7 @@ Foam::dynamicIndexedOctree<Type>::dynamicIndexedOctree
|
|||||||
maxDuplicity_(maxDuplicity),
|
maxDuplicity_(maxDuplicity),
|
||||||
nodes_(label(shapes.size() / maxLeafRatio_)),
|
nodes_(label(shapes.size() / maxLeafRatio_)),
|
||||||
contents_(label(shapes.size() / maxLeafRatio_)),
|
contents_(label(shapes.size() / maxLeafRatio_)),
|
||||||
nodeTypes_(0)
|
nodeTypes_()
|
||||||
{
|
{
|
||||||
if (shapes_.size() == 0)
|
if (shapes_.size() == 0)
|
||||||
{
|
{
|
||||||
@ -2111,7 +2090,7 @@ Foam::pointIndexHit Foam::dynamicIndexedOctree<Type>::findNearest
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
label nearestShapeI = -1;
|
label nearestShapeI = -1;
|
||||||
point nearestPoint;
|
point nearestPoint(Zero);
|
||||||
|
|
||||||
if (nodes_.size())
|
if (nodes_.size())
|
||||||
{
|
{
|
||||||
@ -2126,10 +2105,6 @@ Foam::pointIndexHit Foam::dynamicIndexedOctree<Type>::findNearest
|
|||||||
nearestPoint
|
nearestPoint
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
nearestPoint = Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
|
return pointIndexHit(nearestShapeI != -1, nearestPoint, nearestShapeI);
|
||||||
}
|
}
|
||||||
@ -2260,7 +2235,7 @@ Foam::label Foam::dynamicIndexedOctree<Type>::findInside
|
|||||||
// Need to check for the presence of content, in-case the node is empty
|
// Need to check for the presence of content, in-case the node is empty
|
||||||
if (isContent(contentIndex))
|
if (isContent(contentIndex))
|
||||||
{
|
{
|
||||||
const labelList& indices = *(contents_[getContent(contentIndex)]);
|
const labelList& indices = contents_[getContent(contentIndex)];
|
||||||
|
|
||||||
forAll(indices, elemI)
|
forAll(indices, elemI)
|
||||||
{
|
{
|
||||||
@ -2292,7 +2267,7 @@ const Foam::labelList& Foam::dynamicIndexedOctree<Type>::findIndices
|
|||||||
// Need to check for the presence of content, in-case the node is empty
|
// Need to check for the presence of content, in-case the node is empty
|
||||||
if (isContent(contentIndex))
|
if (isContent(contentIndex))
|
||||||
{
|
{
|
||||||
return *(contents_[getContent(contentIndex)]);
|
return contents_[getContent(contentIndex)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return labelList::null();
|
return labelList::null();
|
||||||
@ -2402,15 +2377,8 @@ bool Foam::dynamicIndexedOctree<Type>::insert(label startIndex, label endIndex)
|
|||||||
|
|
||||||
if (nodes_.empty())
|
if (nodes_.empty())
|
||||||
{
|
{
|
||||||
contents_.append
|
contents_.append(DynamicList<label>(1));
|
||||||
(
|
contents_[0].append(0);
|
||||||
autoPtr<DynamicList<label>>
|
|
||||||
(
|
|
||||||
new DynamicList<label>(1)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
contents_[0]->append(0);
|
|
||||||
|
|
||||||
// Create topnode.
|
// Create topnode.
|
||||||
node topNode = divide(bb_, 0, -1, 0);
|
node topNode = divide(bb_, 0, -1, 0);
|
||||||
@ -2474,7 +2442,7 @@ bool Foam::dynamicIndexedOctree<Type>::insertIndex
|
|||||||
{
|
{
|
||||||
const label contentI = getContent(subNodeLabel);
|
const label contentI = getContent(subNodeLabel);
|
||||||
|
|
||||||
contents_[contentI]->append(index);
|
contents_[contentI].append(index);
|
||||||
|
|
||||||
recursiveSubDivision
|
recursiveSubDivision
|
||||||
(
|
(
|
||||||
@ -2496,12 +2464,9 @@ bool Foam::dynamicIndexedOctree<Type>::insertIndex
|
|||||||
{
|
{
|
||||||
label sz = contents_.size();
|
label sz = contents_.size();
|
||||||
|
|
||||||
contents_.append
|
contents_.append(DynamicList<label>(1));
|
||||||
(
|
|
||||||
autoPtr<DynamicList<label>>(new DynamicList<label>(1))
|
|
||||||
);
|
|
||||||
|
|
||||||
contents_[sz]->append(index);
|
contents_[sz].append(index);
|
||||||
|
|
||||||
nodes_[nodIndex].subNodes_[octant]
|
nodes_[nodIndex].subNodes_[octant]
|
||||||
= contentPlusOctant(sz, octant);
|
= contentPlusOctant(sz, octant);
|
||||||
@ -2574,7 +2539,7 @@ Foam::label Foam::dynamicIndexedOctree<Type>::removeIndex
|
|||||||
|
|
||||||
if (shapes().overlaps(index, subBb))
|
if (shapes().overlaps(index, subBb))
|
||||||
{
|
{
|
||||||
DynamicList<label>& contentList = *(contents_[contentI]);
|
DynamicList<label>& contentList = contents_[contentI];
|
||||||
|
|
||||||
DynamicList<label> newContent(contentList.size());
|
DynamicList<label> newContent(contentList.size());
|
||||||
|
|
||||||
@ -2590,7 +2555,7 @@ Foam::label Foam::dynamicIndexedOctree<Type>::removeIndex
|
|||||||
|
|
||||||
newContent.shrink();
|
newContent.shrink();
|
||||||
|
|
||||||
if (newContent.size() == 0)
|
if (newContent.empty())
|
||||||
{
|
{
|
||||||
// Set to empty.
|
// Set to empty.
|
||||||
nodes_[nodIndex].subNodes_[octant]
|
nodes_[nodIndex].subNodes_[octant]
|
||||||
@ -2600,7 +2565,7 @@ Foam::label Foam::dynamicIndexedOctree<Type>::removeIndex
|
|||||||
contentList.transfer(newContent);
|
contentList.transfer(newContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
totalContents += contents_[contentI]->size();
|
totalContents += contents_[contentI].size();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2651,7 +2616,7 @@ void Foam::dynamicIndexedOctree<Type>::print
|
|||||||
}
|
}
|
||||||
else if (isContent(index))
|
else if (isContent(index))
|
||||||
{
|
{
|
||||||
const labelList& indices = *(contents_[getContent(index)]);
|
const labelList& indices = contents_[getContent(index)];
|
||||||
|
|
||||||
if (false) //debug)
|
if (false) //debug)
|
||||||
{
|
{
|
||||||
@ -2689,9 +2654,9 @@ template<class Type>
|
|||||||
void Foam::dynamicIndexedOctree<Type>::writeTreeInfo() const
|
void Foam::dynamicIndexedOctree<Type>::writeTreeInfo() const
|
||||||
{
|
{
|
||||||
label nEntries = 0;
|
label nEntries = 0;
|
||||||
forAll(contents_, i)
|
for (const auto& subContents : contents_)
|
||||||
{
|
{
|
||||||
nEntries += contents_[i]->size();
|
nEntries += subContents.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Pout<< "indexedOctree::indexedOctree"
|
Pout<< "indexedOctree::indexedOctree"
|
||||||
@ -2726,9 +2691,9 @@ Foam::operator<<(Ostream& os, const dynamicIndexedOctree<Type>& t)
|
|||||||
{
|
{
|
||||||
os << t.bb() << token::SPACE << t.nodes() << endl;
|
os << t.bb() << token::SPACE << t.nodes() << endl;
|
||||||
|
|
||||||
forAll(t.contents(), cI)
|
for (const auto& subContents : t.contents())
|
||||||
{
|
{
|
||||||
os << t.contents()[cI]() << endl;
|
os << subContents << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
|
|||||||
@ -47,8 +47,6 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef DynamicList<autoPtr<DynamicList<label>>> contentListList;
|
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
class Istream;
|
class Istream;
|
||||||
template<class Type> class dynamicIndexedOctree;
|
template<class Type> class dynamicIndexedOctree;
|
||||||
@ -122,7 +120,7 @@ class dynamicIndexedOctree
|
|||||||
DynamicList<node> nodes_;
|
DynamicList<node> nodes_;
|
||||||
|
|
||||||
//- List of all contents (referenced by those nodes that are contents)
|
//- List of all contents (referenced by those nodes that are contents)
|
||||||
contentListList contents_;
|
DynamicList<DynamicList<label>> contents_;
|
||||||
|
|
||||||
//- Per node per octant whether is fully inside/outside/mixed.
|
//- Per node per octant whether is fully inside/outside/mixed.
|
||||||
mutable PackedList<2> nodeTypes_;
|
mutable PackedList<2> nodeTypes_;
|
||||||
@ -136,9 +134,9 @@ class dynamicIndexedOctree
|
|||||||
// according to where they are in relation to mid.
|
// according to where they are in relation to mid.
|
||||||
void divide
|
void divide
|
||||||
(
|
(
|
||||||
const autoPtr<DynamicList<label>>& indices,
|
const labelUList& indices,
|
||||||
const treeBoundBox& bb,
|
const treeBoundBox& bb,
|
||||||
contentListList& result
|
FixedList<DynamicList<label>, 8>& dividedIndices
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Subdivide the contents node at position contentI.
|
//- Subdivide the contents node at position contentI.
|
||||||
@ -146,7 +144,7 @@ class dynamicIndexedOctree
|
|||||||
node divide
|
node divide
|
||||||
(
|
(
|
||||||
const treeBoundBox& bb,
|
const treeBoundBox& bb,
|
||||||
const label contentI,
|
label contentIndex,
|
||||||
const label parentNodeIndex,
|
const label parentNodeIndex,
|
||||||
const label octantToBeDivided
|
const label octantToBeDivided
|
||||||
);
|
);
|
||||||
@ -371,7 +369,7 @@ public:
|
|||||||
|
|
||||||
//- List of all contents
|
//- List of all contents
|
||||||
//- (referenced by those nodes that are contents)
|
//- (referenced by those nodes that are contents)
|
||||||
const contentListList& contents() const
|
const DynamicList<DynamicList<label>>& contents() const noexcept
|
||||||
{
|
{
|
||||||
return contents_;
|
return contents_;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,41 +43,30 @@ Foam::scalar Foam::indexedOctree<Type>::perturbTol_ = 10*SMALL;
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::indexedOctree<Type>::divide
|
void Foam::indexedOctree<Type>::divide
|
||||||
(
|
(
|
||||||
const labelList& indices,
|
const labelUList& indices,
|
||||||
const treeBoundBox& bb,
|
const treeBoundBox& bb,
|
||||||
labelListList& result
|
FixedList<labelList, 8>& dividedIndices
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
List<DynamicList<label>> subIndices(8);
|
// Scratch array
|
||||||
for (direction octant = 0; octant < subIndices.size(); octant++)
|
DynamicList<label> contains(indices.size());
|
||||||
{
|
|
||||||
subIndices[octant].setCapacity(indices.size()/8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Precalculate bounding boxes.
|
for (direction octant = 0; octant < 8; ++octant)
|
||||||
FixedList<treeBoundBox, 8> subBbs;
|
|
||||||
for (direction octant = 0; octant < subBbs.size(); octant++)
|
|
||||||
{
|
{
|
||||||
subBbs[octant] = bb.subBbox(octant);
|
const treeBoundBox subBbs(bb.subBbox(octant));
|
||||||
}
|
|
||||||
|
|
||||||
forAll(indices, i)
|
contains.clear();
|
||||||
{
|
|
||||||
label shapeI = indices[i];
|
|
||||||
|
|
||||||
for (direction octant = 0; octant < 8; octant++)
|
for (const label index : indices)
|
||||||
{
|
{
|
||||||
if (shapes_.overlaps(shapeI, subBbs[octant]))
|
if (shapes_.overlaps(index, subBbs))
|
||||||
{
|
{
|
||||||
subIndices[octant].append(shapeI);
|
contains.append(index);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.setSize(8);
|
// The sub-divided indices:
|
||||||
for (direction octant = 0; octant < subIndices.size(); octant++)
|
dividedIndices[octant] = contains;
|
||||||
{
|
|
||||||
result[octant].transfer(subIndices[octant]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,18 +77,14 @@ Foam::indexedOctree<Type>::divide
|
|||||||
(
|
(
|
||||||
const treeBoundBox& bb,
|
const treeBoundBox& bb,
|
||||||
DynamicList<labelList>& contents,
|
DynamicList<labelList>& contents,
|
||||||
const label contentI
|
label contentIndex
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const labelList& indices = contents[contentI];
|
|
||||||
|
|
||||||
node nod;
|
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
bb.min()[0] >= bb.max()[0]
|
bb.min().x() >= bb.max().x()
|
||||||
|| bb.min()[1] >= bb.max()[1]
|
|| bb.min().y() >= bb.max().y()
|
||||||
|| bb.min()[2] >= bb.max()[2]
|
|| bb.min().z() >= bb.max().z()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
@ -107,38 +92,41 @@ Foam::indexedOctree<Type>::divide
|
|||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Divide the indices into 8 (possibly empty) subsets.
|
||||||
|
// Replace current contentIndex with the first (non-empty) subset.
|
||||||
|
// Append the rest.
|
||||||
|
|
||||||
|
const labelList& indices = contents[contentIndex];
|
||||||
|
|
||||||
|
FixedList<labelList, 8> dividedIndices;
|
||||||
|
divide(indices, bb, dividedIndices);
|
||||||
|
|
||||||
|
node nod;
|
||||||
nod.bb_ = bb;
|
nod.bb_ = bb;
|
||||||
nod.parent_ = -1;
|
nod.parent_ = -1;
|
||||||
|
|
||||||
labelListList dividedIndices(8);
|
bool replaceNode = true;
|
||||||
divide(indices, bb, dividedIndices);
|
|
||||||
|
|
||||||
// Have now divided the indices into 8 (possibly empty) subsets.
|
for (direction octant = 0; octant < 8; ++octant)
|
||||||
// Replace current contentI with the first (non-empty) subset.
|
|
||||||
// Append the rest.
|
|
||||||
bool replaced = false;
|
|
||||||
|
|
||||||
for (direction octant = 0; octant < dividedIndices.size(); octant++)
|
|
||||||
{
|
{
|
||||||
labelList& subIndices = dividedIndices[octant];
|
auto& subIndices = dividedIndices[octant];
|
||||||
|
|
||||||
if (subIndices.size())
|
if (subIndices.size())
|
||||||
{
|
{
|
||||||
if (!replaced)
|
if (replaceNode)
|
||||||
{
|
{
|
||||||
contents[contentI].transfer(subIndices);
|
// Replace existing
|
||||||
nod.subNodes_[octant] = contentPlusOctant(contentI, octant);
|
contents[contentIndex] = std::move(subIndices);
|
||||||
replaced = true;
|
replaceNode = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Store at end of contents.
|
// Append to contents
|
||||||
// note dummy append + transfer trick
|
contentIndex = contents.size();
|
||||||
label sz = contents.size();
|
contents.append(std::move(subIndices));
|
||||||
contents.append(labelList(0));
|
|
||||||
contents[sz].transfer(subIndices);
|
|
||||||
nod.subNodes_[octant] = contentPlusOctant(sz, octant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nod.subNodes_[octant] = contentPlusOctant(contentIndex, octant);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2089,9 +2077,9 @@ template<class Type>
|
|||||||
Foam::indexedOctree<Type>::indexedOctree(const Type& shapes)
|
Foam::indexedOctree<Type>::indexedOctree(const Type& shapes)
|
||||||
:
|
:
|
||||||
shapes_(shapes),
|
shapes_(shapes),
|
||||||
nodes_(0),
|
nodes_(),
|
||||||
contents_(0),
|
contents_(),
|
||||||
nodeTypes_(0)
|
nodeTypes_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -2100,13 +2088,13 @@ Foam::indexedOctree<Type>::indexedOctree
|
|||||||
(
|
(
|
||||||
const Type& shapes,
|
const Type& shapes,
|
||||||
const List<node>& nodes,
|
const List<node>& nodes,
|
||||||
const labelListList& contents
|
const List<labelList>& contents
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
shapes_(shapes),
|
shapes_(shapes),
|
||||||
nodes_(nodes),
|
nodes_(nodes),
|
||||||
contents_(contents),
|
contents_(contents),
|
||||||
nodeTypes_(0)
|
nodeTypes_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -2121,9 +2109,9 @@ Foam::indexedOctree<Type>::indexedOctree
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
shapes_(shapes),
|
shapes_(shapes),
|
||||||
nodes_(0),
|
nodes_(),
|
||||||
contents_(0),
|
contents_(),
|
||||||
nodeTypes_(0)
|
nodeTypes_()
|
||||||
{
|
{
|
||||||
int oldMemSize = 0;
|
int oldMemSize = 0;
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -2299,7 +2287,7 @@ Foam::indexedOctree<Type>::indexedOctree
|
|||||||
shapes_(shapes),
|
shapes_(shapes),
|
||||||
nodes_(is),
|
nodes_(is),
|
||||||
contents_(is),
|
contents_(is),
|
||||||
nodeTypes_(0)
|
nodeTypes_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -254,7 +254,7 @@ class indexedOctree
|
|||||||
List<node> nodes_;
|
List<node> nodes_;
|
||||||
|
|
||||||
//- List of all contents (referenced by those nodes that are contents)
|
//- List of all contents (referenced by those nodes that are contents)
|
||||||
labelListList contents_;
|
List<labelList> contents_;
|
||||||
|
|
||||||
//- Per node per octant whether is fully inside/outside/mixed.
|
//- Per node per octant whether is fully inside/outside/mixed.
|
||||||
mutable PackedList<2> nodeTypes_;
|
mutable PackedList<2> nodeTypes_;
|
||||||
@ -268,9 +268,9 @@ class indexedOctree
|
|||||||
// according to where they are in relation to mid.
|
// according to where they are in relation to mid.
|
||||||
void divide
|
void divide
|
||||||
(
|
(
|
||||||
const labelList& indices,
|
const labelUList& indices,
|
||||||
const treeBoundBox& bb,
|
const treeBoundBox& bb,
|
||||||
labelListList& result
|
FixedList<labelList, 8>& dividedIndices
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Subdivide the contents node at position contentI.
|
//- Subdivide the contents node at position contentI.
|
||||||
@ -279,7 +279,7 @@ class indexedOctree
|
|||||||
(
|
(
|
||||||
const treeBoundBox& bb,
|
const treeBoundBox& bb,
|
||||||
DynamicList<labelList>& contents,
|
DynamicList<labelList>& contents,
|
||||||
const label contentI
|
label contentIndex
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Split any contents node with more than minSize elements.
|
//- Split any contents node with more than minSize elements.
|
||||||
@ -503,7 +503,7 @@ public:
|
|||||||
(
|
(
|
||||||
const Type& shapes,
|
const Type& shapes,
|
||||||
const List<node>& nodes,
|
const List<node>& nodes,
|
||||||
const labelListList& contents
|
const List<labelList>& contents
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from shapes
|
//- Construct from shapes
|
||||||
|
|||||||
Reference in New Issue
Block a user