Modeling - Optimize exact face classification fallback (#1400)

- Add a thread-safe lazy grid to CSLib_Class2d for constant-time
  classification away from polygon boundaries while preserving the exact
  tolerance path for boundary cells.
- Normalize coordinates and explicit tolerances robustly, handle invalid and
  extreme input values, and preserve cache state correctly across copy and
  move operations.
- Cache face wires, edge occurrences, pcurves, parameter ranges, and optional
  2D bounding boxes in BRepClass_FaceExplorer to avoid repeated topology and
  geometry traversal during exact classification.
- Introduce explicit cached-geometry and bounding-box states in
  BRepClass_Edge, invalidate derived data on topology changes, and isolate
  bounding-box construction failures per edge.
- Reuse a lazily constructed exact face explorer in
  BRepTopAdaptor_FClass2d, cache periodic surface properties, and serialize
  access to mutable exact-classification traversal state.
- Replace node-based classifier and point sequences with contiguous linear
  vectors, remove intermediate polygon copies, and make tighter wire
  discretization transactional.
- Consolidate Perform() and TestOnRestriction() through a shared
  classification path while preserving their boundary and periodic
  recadrement semantics.
This commit is contained in:
Pasukhin Dmitry
2026-08-07 19:05:46 +01:00
committed by GitHub
parent caad597813
commit 1cb09f481b
15 changed files with 2164 additions and 607 deletions
@@ -1657,7 +1657,7 @@ static bool AreFacesCoincideInArea(const TopoDS_Shape& theBase
double tol2d = Precision::PConfusion();
BRepClass_Intersector anInter;
BRepClass_Edge aBCE;
aBCE.Face() = aBaseFace;
aBCE.SetFace(aBaseFace);
double maxDist = std::max(BRep_Tool::Tolerance(aBaseFace), BRep_Tool::Tolerance(aFace));
bool isError = false;
@@ -1687,7 +1687,7 @@ static bool AreFacesCoincideInArea(const TopoDS_Shape& theBase
}
BB.UpdateEdge(aE, PC, aBaseFace, tolE);
}
aBCE.Edge() = aE;
aBCE.SetEdge(aE);
anInter.Perform(aLin, pLinMin, tol2d, aBCE);
if (anInter.IsDone())
{
@@ -54,7 +54,7 @@ TopOpeBRepBuild_WireEdgeClassifier::TopOpeBRepBuild_WireEdgeClassifier(
const TopOpeBRepBuild_BlockBuilder& BB)
: TopOpeBRepBuild_CompositeClassifier(BB)
{
myBCEdge.Face() = TopoDS::Face(F);
myBCEdge.SetFace(TopoDS::Face(F));
}
//=================================================================================================
@@ -509,7 +509,7 @@ bool TopOpeBRepBuild_WireEdgeClassifier::CompareElement(const TopoDS_Shape& EE)
myFirstCompare = false;
}
myBCEdge.Edge() = E;
myBCEdge.SetEdge(E);
TopAbs_Orientation Eori = E.Orientation();
myFPC.Compare(myBCEdge, Eori);
#ifdef OCCT_DEBUG