1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-06-05 11:24:17 +03:00

Modeling - General Fuse (BOPAlgo_PaveFiller) optimization #514

Adding a null check for the triangulation in BRep_Tool::IsClosed.
Simplifying index lookup logic in BOPDS_DS.
Introducing helper functions (IsPlaneFF and IsClosedFF) and updating iteration loops in BOPAlgo_PaveFiller_6 for improved clarity and robustness.
This commit is contained in:
Dmitrii Kulikov 2025-05-16 00:03:44 +01:00 committed by dpasukhi
parent bdad8f51b4
commit 86c72171bf
3 changed files with 135 additions and 59 deletions

View File

@ -47,6 +47,9 @@
#include <BRepLib.hxx> #include <BRepLib.hxx>
#include <BRepTools.hxx> #include <BRepTools.hxx>
#include <Geom_Curve.hxx> #include <Geom_Curve.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_OffsetSurface.hxx>
#include <Geom2d_Curve.hxx> #include <Geom2d_Curve.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx> #include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx> #include <GeomAPI_ProjectPointOnSurf.hxx>
@ -76,11 +79,62 @@
#include <TopTools_DataMapOfShapeInteger.hxx> #include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_ListOfShape.hxx> #include <TopTools_ListOfShape.hxx>
//
static Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1, static Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
const BRepAdaptor_Surface& aBAS2); const BRepAdaptor_Surface& aBAS2);
///////////////////////////////////////////////////////////////////////// //=================================================================================================
static Standard_Boolean IsPlaneFF(const Handle(Geom_Surface)& theSurface)
{
if (theSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
{
return Standard_True;
}
else if (const Handle(Geom_OffsetSurface) anOffsetSurface =
Handle(Geom_OffsetSurface)::DownCast(theSurface))
{
return anOffsetSurface->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane));
}
else if (const Handle(Geom_RectangularTrimmedSurface) aTrimmedSurface =
Handle(Geom_RectangularTrimmedSurface)::DownCast(theSurface))
{
return aTrimmedSurface->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane));
}
return Standard_False;
}
//=================================================================================================
static Standard_Boolean IsClosedFF(const TopoDS_Edge& theEdge,
const Handle(Geom_Surface)& theSurface,
const Handle(Poly_Triangulation)& theTriangulation,
const TopLoc_Location& theLocation,
Standard_Boolean theIsPlane)
{
if (!theIsPlane)
{
// Check surface
const TopLoc_Location aLocation = theLocation.Predivided(theEdge.Location());
// find the representation
const BRep_TEdge* aTEdge = static_cast<const BRep_TEdge*>(theEdge.TShape().get());
for (BRep_ListIteratorOfListOfCurveRepresentation anIter(aTEdge->Curves()); anIter.More();
anIter.Next())
{
const Handle(BRep_CurveRepresentation)& aCurveRepresentation = anIter.Value();
if (aCurveRepresentation->IsCurveOnSurface(theSurface, aLocation)
&& aCurveRepresentation->IsCurveOnClosedSurface())
{
return Standard_True;
}
}
}
// Check triangulation
return BRep_Tool::IsClosed(theEdge, theTriangulation, theLocation);
}
//================================================================================================= //=================================================================================================
class BOPAlgo_FaceFace : public IntTools_FaceFace, public BOPAlgo_ParallelAlgo class BOPAlgo_FaceFace : public IntTools_FaceFace, public BOPAlgo_ParallelAlgo
@ -225,11 +279,10 @@ protected:
gp_Trsf myTrsf; gp_Trsf myTrsf;
}; };
// //=================================================================================================
//=======================================================================
typedef NCollection_Vector<BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace; typedef NCollection_Vector<BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
/////////////////////////////////////////////////////////////////////////
//================================================================================================= //=================================================================================================
void BOPAlgo_PaveFiller::PerformFF(const Message_ProgressRange& theRange) void BOPAlgo_PaveFiller::PerformFF(const Message_ProgressRange& theRange)
@ -354,59 +407,82 @@ void BOPAlgo_PaveFiller::PerformFF(const Message_ProgressRange& theRange)
if (aBAS1.GetType() != GeomAbs_Plane || aBAS2.GetType() != GeomAbs_Plane) if (aBAS1.GetType() != GeomAbs_Plane || aBAS2.GetType() != GeomAbs_Plane)
{ {
TopLoc_Location aLocation1;
const Handle(Geom_Surface)& aSurface1 = BRep_Tool::Surface(aF1, aLocation1);
const Handle(Poly_Triangulation)& aTriangulation1 =
BRep_Tool::Triangulation(aF1, aLocation1);
const Standard_Boolean anIsPlane1 = IsPlaneFF(aSurface1);
Standard_Boolean isFound = Standard_False; TopLoc_Location aLocation2;
for (TopExp_Explorer aExp1(aF1, TopAbs_EDGE); !isFound && aExp1.More(); aExp1.Next()) const Handle(Geom_Surface)& aSurface2 = BRep_Tool::Surface(aF2, aLocation2);
const Handle(Poly_Triangulation)& aTriangulation2 =
BRep_Tool::Triangulation(aF2, aLocation2);
const Standard_Boolean anIsPlane2 = IsPlaneFF(aSurface2);
Standard_Boolean anIsFound = Standard_False;
for (TopoDS_Iterator aItW1(aF1); !anIsFound && aItW1.More(); aItW1.Next())
{ {
const TopoDS_Edge& aE1 = TopoDS::Edge(aExp1.Current()); for (TopoDS_Iterator aItE1(aItW1.Value()); !anIsFound && aItE1.More(); aItE1.Next())
const Standard_Integer nE1 = myDS->Index(aE1);
for (TopExp_Explorer aExp2(aF2, TopAbs_EDGE); !isFound && aExp2.More(); aExp2.Next())
{ {
const TopoDS_Edge& aE2 = TopoDS::Edge(aExp2.Current()); const TopoDS_Edge& anEdge1 = TopoDS::Edge(aItE1.Value());
const Standard_Integer nE2 = myDS->Index(aE2); const Standard_Integer anEdgeIndex1 = myDS->Index(anEdge1);
Standard_Boolean bIsClosed1 = BRep_Tool::IsClosed(aE1, aF1); for (TopoDS_Iterator aItW2(aF2); !anIsFound && aItW2.More(); aItW2.Next())
Standard_Boolean bIsClosed2 = BRep_Tool::IsClosed(aE2, aF2); {
if (!bIsClosed1 && !bIsClosed2) for (TopoDS_Iterator aItE2(aItW2.Value()); !anIsFound && aItE2.More(); aItE2.Next())
{
const TopoDS_Edge& anEdge2 = TopoDS::Edge(aItE2.Value());
const Standard_Integer anEdgeIndex2 = myDS->Index(anEdge2);
const Standard_Boolean anIsClosed1 =
IsClosedFF(anEdge1, aSurface1, aTriangulation1, aLocation1, anIsPlane1);
const Standard_Boolean anIsClosed2 =
IsClosedFF(anEdge2, aSurface2, aTriangulation2, aLocation2, anIsPlane2);
if (!anIsClosed1 && !anIsClosed2)
{ {
continue; continue;
} }
const TColStd_ListOfInteger* pPoints = aEEMap.Seek(BOPDS_Pair(nE1, nE2)); const TColStd_ListOfInteger* aVertexIndices =
if (!pPoints) aEEMap.Seek(BOPDS_Pair(anEdgeIndex1, anEdgeIndex2));
if (!aVertexIndices)
{ {
continue; continue;
} }
for (TColStd_ListOfInteger::Iterator itEEP(*pPoints); itEEP.More(); itEEP.Next()) for (TColStd_ListOfInteger::Iterator itEEP(*aVertexIndices); itEEP.More();
itEEP.Next())
{ {
const Standard_Integer& nVN = itEEP.Value(); const Standard_Integer aVertexIndex = itEEP.Value();
const TopoDS_Vertex& aVN = TopoDS::Vertex(myDS->Shape(nVN)); const TopoDS_Vertex& aVertex = TopoDS::Vertex(myDS->Shape(aVertexIndex));
const gp_Pnt& aPnt = BRep_Tool::Pnt(aVN); const gp_Pnt& aVertexPoint = BRep_Tool::Pnt(aVertex);
// Compute points exactly on the edges // Compute points exactly on the edges
GeomAPI_ProjectPointOnCurve& aProjPC1 = myContext->ProjPC(aE1); GeomAPI_ProjectPointOnCurve& aProjPC1 = myContext->ProjPC(anEdge1);
GeomAPI_ProjectPointOnCurve& aProjPC2 = myContext->ProjPC(aE2); GeomAPI_ProjectPointOnCurve& aProjPC2 = myContext->ProjPC(anEdge2);
aProjPC1.Perform(aPnt); aProjPC1.Perform(aVertexPoint);
aProjPC2.Perform(aPnt); aProjPC2.Perform(aVertexPoint);
if (!aProjPC1.NbPoints() && !aProjPC2.NbPoints()) if (!aProjPC1.NbPoints() && !aProjPC2.NbPoints())
{ {
continue; continue;
} }
gp_Pnt aP1 = aProjPC1.NbPoints() > 0 ? aProjPC1.NearestPoint() : aPnt; const gp_Pnt aP1 =
gp_Pnt aP2 = aProjPC2.NbPoints() > 0 ? aProjPC2.NearestPoint() : aPnt; aProjPC1.NbPoints() > 0 ? aProjPC1.NearestPoint() : aVertexPoint;
const gp_Pnt aP2 =
aProjPC2.NbPoints() > 0 ? aProjPC2.NearestPoint() : aVertexPoint;
Standard_Real aShiftDist = aP1.Distance(aP2); const Standard_Real aShiftDist = aP1.Distance(aP2);
if (aShiftDist > BRep_Tool::Tolerance(aVN)) if (aShiftDist > BRep_Tool::Tolerance(aVertex))
{ {
// Move one of the faces to the point of exact intersection of edges // Move one of the faces to the point of exact intersection of edges
gp_Trsf aTrsf; gp_Trsf aTrsf;
aTrsf.SetTranslation(bIsClosed1 ? gp_Vec(aP1, aP2) : gp_Vec(aP2, aP1)); aTrsf.SetTranslation(anIsClosed1 ? gp_Vec(aP1, aP2) : gp_Vec(aP2, aP1));
TopLoc_Location aLoc(aTrsf); TopLoc_Location aLoc(aTrsf);
(bIsClosed1 ? &aFShifted1 : &aFShifted2)->Move(aLoc); (anIsClosed1 ? &aFShifted1 : &aFShifted2)->Move(aLoc);
aShiftValue = aShiftDist; aShiftValue = aShiftDist;
isFound = Standard_True; anIsFound = Standard_True;
}
}
} }
} }
} }

View File

@ -277,14 +277,9 @@ const TopoDS_Shape& BOPDS_DS::Shape(const Standard_Integer theI) const
Standard_Integer BOPDS_DS::Index(const TopoDS_Shape& theS) const Standard_Integer BOPDS_DS::Index(const TopoDS_Shape& theS) const
{ {
Standard_Integer iRet; Standard_Integer anIndex = -1;
// myMapShapeIndex.Find(theS, anIndex);
iRet = -1; return anIndex;
if (myMapShapeIndex.IsBound(theS))
{
iRet = myMapShapeIndex.Find(theS);
}
return iRet;
} }
//================================================================================================= //=================================================================================================

View File

@ -795,6 +795,11 @@ Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Edge& E,
const Handle(Poly_Triangulation)& T, const Handle(Poly_Triangulation)& T,
const TopLoc_Location& L) const TopLoc_Location& L)
{ {
if (T.IsNull())
{
return Standard_False;
}
TopLoc_Location l = L.Predivided(E.Location()); TopLoc_Location l = L.Predivided(E.Location());
// find the representation // find the representation