Modeling Algorithms - Optimize properties computation for complex compounds (#1091)

Optimized exact vprops path for OCC28402 by reducing TopLoc_Location
composition overhead in edge pcurve lookup.

Changes:
- added fast-path exits in TopLoc_Location::Predivided() for identity and
  equal-location cases;
- cached face surface/location in BRepGProp_Face and reused this context in
  Load(const TopoDS_Edge&);
- in BRep_Tool::CurveOnSurface(...), compute Predivided() only when edge
  has curve representations to iterate.

This keeps algorithmic behavior unchanged and targets the performance
regression reported by tests/bugs/modalg_7/bug28402.
This commit is contained in:
Pasukhin Dmitry
2026-02-15 09:24:57 +00:00
committed by GitHub
parent c31fc654b1
commit c9bdc4b9f1
5 changed files with 51 additions and 21 deletions

View File

@@ -125,6 +125,18 @@ TopLoc_Location TopLoc_Location::Divided(const TopLoc_Location& Other) const
TopLoc_Location TopLoc_Location::Predivided(const TopLoc_Location& Other) const
{
if (Other.IsIdentity())
{
return *this;
}
if (IsIdentity())
{
return Other.Inverted();
}
if (*this == Other)
{
return TopLoc_Location();
}
return Other.Inverted().Multiplied(*this);
}

View File

@@ -159,8 +159,12 @@ void BRepGProp_Face::Bounds(double& U1, double& U2, double& V1, double& V2) cons
bool BRepGProp_Face::Load(const TopoDS_Edge& E)
{
double a, b;
occ::handle<Geom2d_Curve> C = BRep_Tool::CurveOnSurface(E, mySurface.Face(), a, b);
double a, b;
if (!myIsFaceContextReady)
{
return false;
}
occ::handle<Geom2d_Curve> C = BRep_Tool::CurveOnSurface(E, myFaceSurface, myFaceLocation, a, b);
if (C.IsNull())
{
return false;
@@ -182,6 +186,8 @@ void BRepGProp_Face::Load(const TopoDS_Face& F)
{
TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
mySurface.Initialize(TopoDS::Face(aLocalShape));
myFaceSurface = BRep_Tool::Surface(mySurface.Face(), myFaceLocation);
myIsFaceContextReady = !myFaceSurface.IsNull();
// mySurface.Initialize(TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
mySReverse = (F.Orientation() == TopAbs_REVERSED);
}

View File

@@ -28,12 +28,15 @@
#include <NCollection_Array1.hxx>
#include <GeomAbs_IsoType.hxx>
#include <NCollection_HArray1.hxx>
#include <TopLoc_Location.hxx>
class TopoDS_Face;
class gp_Pnt;
class gp_Vec;
class TopoDS_Edge;
class gp_Pnt2d;
class gp_Vec2d;
class Geom_Surface;
class BRepGProp_Face
{
@@ -149,10 +152,13 @@ public:
occ::handle<NCollection_HArray1<double>>& theTKnots) const;
private:
BRepAdaptor_Surface mySurface;
Geom2dAdaptor_Curve myCurve;
bool mySReverse;
bool myIsUseSpan;
BRepAdaptor_Surface mySurface;
Geom2dAdaptor_Curve myCurve;
occ::handle<Geom_Surface> myFaceSurface;
TopLoc_Location myFaceLocation;
bool myIsFaceContextReady;
bool mySReverse;
bool myIsUseSpan;
};
#include <BRepGProp_Face.lxx>

View File

@@ -21,7 +21,8 @@
//=======================================================================
inline BRepGProp_Face::BRepGProp_Face(const bool IsUseSpan)
: mySReverse(false),
: myIsFaceContextReady(false),
mySReverse(false),
myIsUseSpan(IsUseSpan)
{
}
@@ -33,7 +34,9 @@ inline BRepGProp_Face::BRepGProp_Face(const bool IsUseSpan)
//=======================================================================
inline BRepGProp_Face::BRepGProp_Face(const TopoDS_Face& F, const bool IsUseSpan)
: myIsUseSpan(IsUseSpan)
: myIsFaceContextReady(false),
mySReverse(false),
myIsUseSpan(IsUseSpan)
{
Load(F);
}

View File

@@ -321,28 +321,31 @@ occ::handle<Geom2d_Curve> BRep_Tool::CurveOnSurface(const TopoDS_Edge&
double& Last,
bool* theIsStored)
{
TopLoc_Location loc = L.Predivided(E.Location());
bool Eisreversed = (E.Orientation() == TopAbs_REVERSED);
bool Eisreversed = (E.Orientation() == TopAbs_REVERSED);
if (theIsStored)
*theIsStored = true;
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
if (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurveOnSurface(S, loc))
const TopLoc_Location loc = L.Predivided(E.Location());
while (itcr.More())
{
const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
GC->Range(First, Last);
if (GC->IsCurveOnClosedSurface() && Eisreversed)
return GC->PCurve2();
else
return GC->PCurve();
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurveOnSurface(S, loc))
{
const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
GC->Range(First, Last);
if (GC->IsCurveOnClosedSurface() && Eisreversed)
return GC->PCurve2();
else
return GC->PCurve();
}
itcr.Next();
}
itcr.Next();
}
// Curve is not found. Try projection on plane