Foundation, Modeling - NCollection modernization and BRepGraph overhaul (#1212)

- Migrate NCollection map/sequence/array size APIs from int to size_t; Size() returns size_t, Length() remains the int accessor; int overloads delegate through NbBucketsFromInt() with a negative-input guard.
- Add NCollection_LinearVector: contiguous flat-buffer dynamic array with Standard::Reallocate-based growth for trivial types and move-construction for non-trivial types.
- Rewrite NCollection_DynamicArray on top of LinearVector<T*>; switch to power-of-two block sizing with precomputed shift/mask.
- Rework NCollection_BaseMap iterator with a forward findFirst() helper (no negative-bucket arithmetic); unify ReSize/BeginResize/EndResize on size_t.
- Enable thread-safe fast path in NCollection_IncAllocator via std::shared_mutex + CAS bump allocation on atomic AvailableSize; exclusive lock is taken only for new-block allocation and list reordering.
- Remove NCollection_BasePointerVector (superseded by NCollection_LinearVector).
- Remove NCollection_BaseMap::Statistics (unused).
- Add <cstddef> include in NCollection_Primes.hxx so size_t resolves on clean builds.
- Document iterator invalidation contract on NCollection_LinearVector.
- Unify BRepGraph programmatic mutation behind EditorView: delete BuilderView (2648+552 lines); EditorView (3186+930 lines) and EditorView_Mut.cxx own both structural creation (Add*/Remove*) and field-level RAII-scoped mutation (Mut*()) with automatic OwnGen and SubtreeGen propagation.
- Add BRepGraph_MeshCache and BRepGraph_MeshView: two-tier mesh storage separating algorithm-derived caches from persistent (definition) triangulations; freshness is keyed on FaceDef.OwnGen; cache writes do not mutate the model.
- Document the MeshCache invalidation contract in BRepGraph_MeshCache.hxx (which mutations bump Face.OwnGen and how markRepModified closes the loop for Surface/Triangulation reps).
- Add BRepGraph_RefsIterator (generic flat ref scan with RefTraits dispatch) and BRepGraph_ReverseIterator (typed parent-traversal wrappers over reverse-index vectors).
- Rework RefId entity model: replace inline refs with typed RefId vectors; add OccurrenceRef and Kind::Occurrence=7; BRepGraphInc_WireExplorer now requires a VertexRefLookup.
- Rename layers for consistency: BRepGraph_ParamLayer to BRepGraph_LayerParam, BRepGraph_RegularityLayer to BRepGraph_LayerRegularity; rename BRepGraphInc_Usage to BRepGraphInc_Instance.
- Replace RootNodeIds() with RootProductIds() returning product roots only.
- Update BRepGraph and BRepGraphInc READMEs; fix stale RootNodeIds reference.
- Sweep Size() to Length() renames across ~200 callers in TKG2d, TKG3d, TKMath, TKMesh, TKBO, TKOffset, TKShHealing, TKTopAlgo, TKBRep, TKService, TKV3d, TKOpenGl, TKMeshVS, TKDE*, TKXCAF, TKXSBase, TKLCAF, TKStd, and Draw harness.
- Add GTest coverage for new containers and the BRepGraph overhaul: NCollection_DynamicArray_Test, NCollection_LinearVector_Test, BRepGraph_Fuzz_Test, BRepGraph_Iterator_Test, BRepGraph_LayerIterator_Test, BRepGraph_MeshCache_Test, BRepGraph_MutGuard_Test, BRepGraph_ReplaceVertex_Test, BRepGraph_ReverseIterator_Test, BRepGraph_ScenarioMatrix_Test, BRepGraph_TypedIdDispatch_Test, BRepGraph_WireExplorer_Test.
This commit is contained in:
Pasukhin Dmitry
2026-04-19 18:47:54 +01:00
committed by GitHub
parent b3ccf20b1c
commit 0755b6f31d
312 changed files with 23723 additions and 10569 deletions
@@ -13,9 +13,9 @@
#include <BRepGraph_ShapesView.hxx>
#include <BRepGraph_Data.hxx>
#include <BRepGraph_ParamLayer.hxx>
#include <BRepGraph_LayerParam.hxx>
#include <BRepGraph_RefsIterator.hxx>
#include <BRepGraph_RegularityLayer.hxx>
#include <BRepGraph_LayerRegularity.hxx>
#include <BRepGraphInc_Reconstruct.hxx>
#include <BRep_Builder.hxx>
@@ -29,66 +29,106 @@ namespace
{
struct BRepGraph_ReconstructionContext
{
const BRepGraph* Graph = nullptr;
const BRepGraphInc_Storage* Storage = nullptr;
const BRepGraph_ParamLayer* Params = nullptr;
const BRepGraph_RegularityLayer* Regularities = nullptr;
BRepGraphInc_Reconstruct::Cache Cache;
NCollection_Map<int> ActiveProducts;
const BRepGraph* Graph = nullptr;
const BRepGraphInc_Storage* Storage = nullptr;
const BRepGraph_LayerParam* Params = nullptr;
const BRepGraph_LayerRegularity* Regularities = nullptr;
BRepGraphInc_Reconstruct::Cache Cache;
NCollection_Map<BRepGraph_ProductId> ActiveProducts;
};
static TopoDS_Shape reconstructProductLocal(BRepGraph_ReconstructionContext& theContext,
const BRepGraph_ProductId theProduct);
static TopoDS_Shape reconstructProductLocal(
BRepGraph_ReconstructionContext& theContext,
const BRepGraph_ProductId theProduct,
const BRepGraph_OccurrenceId theParentOccurrence = BRepGraph_OccurrenceId(),
const bool theFilterByParentOccurrence = false);
static TopoDS_Shape reconstructOccurrenceLocal(BRepGraph_ReconstructionContext& theContext,
const BRepGraph_OccurrenceId theOccurrence)
const BRepGraph_OccurrenceId theOccurrence,
const TopLoc_Location& theLocalLocation)
{
const BRepGraphInc_Storage& aStorage = *theContext.Storage;
if (!theOccurrence.IsValid(aStorage.NbOccurrences()))
return TopoDS_Shape();
const BRepGraphInc::OccurrenceDef& anOccurrence = aStorage.Occurrence(theOccurrence);
if (anOccurrence.IsRemoved || !anOccurrence.ProductDefId.IsValid(aStorage.NbProducts()))
if (anOccurrence.IsRemoved || !anOccurrence.ChildDefId.IsValid())
return TopoDS_Shape();
TopoDS_Shape aShape = reconstructProductLocal(theContext, anOccurrence.ProductDefId);
if (!aShape.IsNull() && !anOccurrence.Placement.IsIdentity())
aShape.Move(anOccurrence.Placement);
TopoDS_Shape aShape;
if (anOccurrence.ChildDefId.NodeKind == BRepGraph_NodeId::Kind::Product)
{
aShape = reconstructProductLocal(theContext,
BRepGraph_ProductId(anOccurrence.ChildDefId),
theOccurrence,
true);
}
else
{
aShape = BRepGraphInc_Reconstruct::Node(aStorage,
anOccurrence.ChildDefId,
theContext.Cache,
theContext.Params,
theContext.Regularities);
}
if (!aShape.IsNull() && !theLocalLocation.IsIdentity())
aShape.Move(theLocalLocation);
return aShape;
}
static TopoDS_Shape reconstructProductLocal(BRepGraph_ReconstructionContext& theContext,
const BRepGraph_ProductId theProduct)
const BRepGraph_ProductId theProduct,
const BRepGraph_OccurrenceId theParentOccurrence,
const bool theFilterByParentOccurrence)
{
(void)theParentOccurrence; // Reserved for future parent-occurrence filtering.
const BRepGraphInc_Storage& aStorage = *theContext.Storage;
if (!theProduct.IsValid(aStorage.NbProducts()))
return TopoDS_Shape();
const BRepGraph_NodeId aProductNode = BRepGraph_ProductId(theProduct.Index);
if (const TopoDS_Shape* aCached = theContext.Cache.Seek(aProductNode))
return *aCached;
const BRepGraph_NodeId aProductNode = theProduct;
if (!theFilterByParentOccurrence)
{
if (const TopoDS_Shape* aCached = theContext.Cache.Seek(aProductNode))
return *aCached;
}
const BRepGraphInc::ProductDef& aProduct = aStorage.Product(theProduct);
if (aProduct.IsRemoved || theContext.ActiveProducts.Contains(theProduct.Index))
if (aProduct.IsRemoved || theContext.ActiveProducts.Contains(theProduct))
return TopoDS_Shape();
theContext.ActiveProducts.Add(theProduct.Index);
theContext.ActiveProducts.Add(theProduct);
TopoDS_Shape aResult;
if (aProduct.ShapeRootId.IsValid())
// Find the shape root: scan occurrence refs for a topology (non-product) child.
TopoDS_Shape aResult;
BRepGraph_NodeId aShapeRootNode;
TopLoc_Location aRootLocation;
for (int i = 0; i < aProduct.OccurrenceRefIds.Length(); ++i)
{
const BRepGraphInc::OccurrenceRef& aRef = aStorage.OccurrenceRef(aProduct.OccurrenceRefIds(i));
if (aRef.IsRemoved)
continue;
if (!aRef.OccurrenceDefId.IsValid(aStorage.NbOccurrences()))
continue;
const BRepGraphInc::OccurrenceDef& aDef = aStorage.Occurrence(aRef.OccurrenceDefId);
if (aDef.IsRemoved)
continue;
if (aDef.ChildDefId.IsValid() && aDef.ChildDefId.NodeKind != BRepGraph_NodeId::Kind::Product)
{
aShapeRootNode = aDef.ChildDefId;
aRootLocation = aRef.LocalLocation;
break;
}
}
if (aShapeRootNode.IsValid())
{
aResult = BRepGraphInc_Reconstruct::Node(aStorage,
aProduct.ShapeRootId,
aShapeRootNode,
theContext.Cache,
theContext.Params,
theContext.Regularities);
if (!aResult.IsNull())
{
if (aProduct.RootOrientation != TopAbs_FORWARD)
aResult.Compose(aProduct.RootOrientation);
if (!aProduct.RootLocation.IsIdentity())
aResult.Move(aProduct.RootLocation);
}
if (!aResult.IsNull() && !aRootLocation.IsIdentity())
aResult.Move(aRootLocation);
}
else
{
@@ -101,8 +141,21 @@ static TopoDS_Shape reconstructProductLocal(BRepGraph_ReconstructionContext& the
{
const BRepGraphInc::OccurrenceRef& anOccurrenceRef =
aStorage.OccurrenceRef(anOccIt.CurrentId());
if (!anOccurrenceRef.OccurrenceDefId.IsValid(aStorage.NbOccurrences()))
{
continue;
}
TopoDS_Shape aChild = reconstructOccurrenceLocal(theContext, anOccurrenceRef.OccurrenceDefId);
const BRepGraphInc::OccurrenceDef& anOccurrence =
aStorage.Occurrence(anOccurrenceRef.OccurrenceDefId);
if (anOccurrence.IsRemoved)
{
continue;
}
TopoDS_Shape aChild = reconstructOccurrenceLocal(theContext,
anOccurrenceRef.OccurrenceDefId,
anOccurrenceRef.LocalLocation);
if (!aChild.IsNull())
aBuilder.Add(aCompound, aChild);
}
@@ -110,8 +163,8 @@ static TopoDS_Shape reconstructProductLocal(BRepGraph_ReconstructionContext& the
aResult = aCompound;
}
theContext.ActiveProducts.Remove(theProduct.Index);
if (!aResult.IsNull())
theContext.ActiveProducts.Remove(theProduct);
if (!theFilterByParentOccurrence && !aResult.IsNull())
theContext.Cache.Bind(aProductNode, aResult);
return aResult;
}
@@ -126,17 +179,32 @@ static TopoDS_Shape reconstructShape(BRepGraph_ReconstructionContext& theContext
switch (theNode.NodeKind)
{
case BRepGraph_NodeId::Kind::Product:
return reconstructProductLocal(theContext, BRepGraph_ProductId(theNode.Index));
return reconstructProductLocal(theContext, BRepGraph_ProductId(theNode));
case BRepGraph_NodeId::Kind::Occurrence: {
const BRepGraph_OccurrenceId anOccurrence(theNode.Index);
const BRepGraph_OccurrenceId anOccurrence(theNode);
if (!anOccurrence.IsValid(aStorage.NbOccurrences()))
return TopoDS_Shape();
const BRepGraphInc::OccurrenceDef& anOccurrenceDef = aStorage.Occurrence(anOccurrence);
if (anOccurrenceDef.IsRemoved || !anOccurrenceDef.ProductDefId.IsValid(aStorage.NbProducts()))
if (anOccurrenceDef.IsRemoved || !anOccurrenceDef.ChildDefId.IsValid())
return TopoDS_Shape();
TopoDS_Shape aShape = reconstructProductLocal(theContext, anOccurrenceDef.ProductDefId);
TopoDS_Shape aShape;
if (anOccurrenceDef.ChildDefId.NodeKind == BRepGraph_NodeId::Kind::Product)
{
aShape = reconstructProductLocal(theContext,
BRepGraph_ProductId(anOccurrenceDef.ChildDefId),
anOccurrence,
true);
}
else
{
aShape = BRepGraphInc_Reconstruct::Node(aStorage,
anOccurrenceDef.ChildDefId,
theContext.Cache,
theContext.Params,
theContext.Regularities);
}
if (!aShape.IsNull())
{
const TopLoc_Location aGlobalLocation =
@@ -163,10 +231,10 @@ static BRepGraph_ReconstructionContext makeReconstructionContext(
aContext.Graph = theGraph;
aContext.Storage = &theStorage;
const occ::handle<BRepGraph_ParamLayer> aParamLayer =
theGraph->LayerRegistry().FindLayer<BRepGraph_ParamLayer>();
const occ::handle<BRepGraph_RegularityLayer> aRegularityLayer =
theGraph->LayerRegistry().FindLayer<BRepGraph_RegularityLayer>();
const occ::handle<BRepGraph_LayerParam> aParamLayer =
theGraph->LayerRegistry().FindLayer<BRepGraph_LayerParam>();
const occ::handle<BRepGraph_LayerRegularity> aRegularityLayer =
theGraph->LayerRegistry().FindLayer<BRepGraph_LayerRegularity>();
aContext.Params = aParamLayer.get();
aContext.Regularities = aRegularityLayer.get();
return aContext;
@@ -182,9 +250,11 @@ TopoDS_Shape BRepGraph::ShapesView::Shape(const BRepGraph_NodeId theNode) const
// Fast path: if entity was never mutated, return the original shape.
const BRepGraphInc::BaseDef* aDef = myGraph->topoEntity(theNode);
if (aDef != nullptr && aDef->IsRemoved)
return TopoDS_Shape();
if (aDef != nullptr && aDef->SubtreeGen == 0)
{
const TopoDS_Shape* anOrig = myGraph->myData->myIncStorage.FindOriginal(theNode);
const TopoDS_Shape* anOrig = FindOriginal(theNode);
if (anOrig != nullptr)
return *anOrig;
}
@@ -229,14 +299,28 @@ TopoDS_Shape BRepGraph::ShapesView::Shape(const BRepGraph_NodeId theNode) const
bool BRepGraph::ShapesView::HasOriginal(const BRepGraph_NodeId theNode) const
{
return myGraph->myData->myIncStorage.HasOriginal(theNode);
return FindOriginal(theNode) != nullptr;
}
//=================================================================================================
const TopoDS_Shape* BRepGraph::ShapesView::FindOriginal(const BRepGraph_NodeId theNode) const
{
if (!theNode.IsValid())
return nullptr;
const BRepGraphInc::BaseDef* aDef = myGraph->topoEntity(theNode);
if (aDef != nullptr && aDef->IsRemoved)
return nullptr;
return myGraph->myData->myIncStorage.FindOriginal(theNode);
}
//=================================================================================================
const TopoDS_Shape& BRepGraph::ShapesView::OriginalOf(const BRepGraph_NodeId theNode) const
{
const TopoDS_Shape* aShape = myGraph->myData->myIncStorage.FindOriginal(theNode);
const TopoDS_Shape* aShape = FindOriginal(theNode);
if (aShape == nullptr)
throw Standard_ProgramError("BRepGraph::ShapesView::OriginalOf() - no original shape.");
return *aShape;
@@ -246,6 +330,9 @@ const TopoDS_Shape& BRepGraph::ShapesView::OriginalOf(const BRepGraph_NodeId the
TopoDS_Shape BRepGraph::ShapesView::Reconstruct(const BRepGraph_NodeId theRoot) const
{
const BRepGraphInc::BaseDef* aDef = myGraph->topoEntity(theRoot);
if (aDef != nullptr && aDef->IsRemoved)
return TopoDS_Shape();
BRepGraph_ReconstructionContext aContext =
makeReconstructionContext(myGraph, myGraph->myData->myIncStorage);
return reconstructShape(aContext, theRoot);
@@ -263,7 +350,12 @@ BRepGraph_NodeId BRepGraph::ShapesView::FindNode(const TopoDS_Shape& theShape) c
const BRepGraph_NodeId* aNodeId =
myGraph->myData->myIncStorage.FindNodeByTShape(theShape.TShape().get());
if (aNodeId != nullptr)
{
const BRepGraphInc::BaseDef* aDef = myGraph->topoEntity(*aNodeId);
if (aDef == nullptr || aDef->IsRemoved)
return BRepGraph_NodeId();
return *aNodeId;
}
return BRepGraph_NodeId();
}
@@ -274,5 +366,5 @@ bool BRepGraph::ShapesView::HasNode(const TopoDS_Shape& theShape) const
if (theShape.IsNull())
return false;
return myGraph->myData->myIncStorage.HasTShapeBinding(theShape.TShape().get());
return FindNode(theShape).IsValid();
}