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:
parent
bdad8f51b4
commit
86c72171bf
@ -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)
|
|
||||||
{
|
{
|
||||||
continue;
|
for (TopoDS_Iterator aItE2(aItW2.Value()); !anIsFound && aItE2.More(); aItE2.Next())
|
||||||
}
|
|
||||||
|
|
||||||
const TColStd_ListOfInteger* pPoints = aEEMap.Seek(BOPDS_Pair(nE1, nE2));
|
|
||||||
if (!pPoints)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TColStd_ListOfInteger::Iterator itEEP(*pPoints); itEEP.More(); itEEP.Next())
|
|
||||||
{
|
|
||||||
const Standard_Integer& nVN = itEEP.Value();
|
|
||||||
const TopoDS_Vertex& aVN = TopoDS::Vertex(myDS->Shape(nVN));
|
|
||||||
const gp_Pnt& aPnt = BRep_Tool::Pnt(aVN);
|
|
||||||
|
|
||||||
// Compute points exactly on the edges
|
|
||||||
GeomAPI_ProjectPointOnCurve& aProjPC1 = myContext->ProjPC(aE1);
|
|
||||||
GeomAPI_ProjectPointOnCurve& aProjPC2 = myContext->ProjPC(aE2);
|
|
||||||
aProjPC1.Perform(aPnt);
|
|
||||||
aProjPC2.Perform(aPnt);
|
|
||||||
if (!aProjPC1.NbPoints() && !aProjPC2.NbPoints())
|
|
||||||
{
|
{
|
||||||
continue;
|
const TopoDS_Edge& anEdge2 = TopoDS::Edge(aItE2.Value());
|
||||||
}
|
const Standard_Integer anEdgeIndex2 = myDS->Index(anEdge2);
|
||||||
gp_Pnt aP1 = aProjPC1.NbPoints() > 0 ? aProjPC1.NearestPoint() : aPnt;
|
|
||||||
gp_Pnt aP2 = aProjPC2.NbPoints() > 0 ? aProjPC2.NearestPoint() : aPnt;
|
|
||||||
|
|
||||||
Standard_Real aShiftDist = aP1.Distance(aP2);
|
const Standard_Boolean anIsClosed1 =
|
||||||
if (aShiftDist > BRep_Tool::Tolerance(aVN))
|
IsClosedFF(anEdge1, aSurface1, aTriangulation1, aLocation1, anIsPlane1);
|
||||||
{
|
const Standard_Boolean anIsClosed2 =
|
||||||
// Move one of the faces to the point of exact intersection of edges
|
IsClosedFF(anEdge2, aSurface2, aTriangulation2, aLocation2, anIsPlane2);
|
||||||
gp_Trsf aTrsf;
|
if (!anIsClosed1 && !anIsClosed2)
|
||||||
aTrsf.SetTranslation(bIsClosed1 ? gp_Vec(aP1, aP2) : gp_Vec(aP2, aP1));
|
{
|
||||||
TopLoc_Location aLoc(aTrsf);
|
continue;
|
||||||
(bIsClosed1 ? &aFShifted1 : &aFShifted2)->Move(aLoc);
|
}
|
||||||
aShiftValue = aShiftDist;
|
|
||||||
isFound = Standard_True;
|
const TColStd_ListOfInteger* aVertexIndices =
|
||||||
|
aEEMap.Seek(BOPDS_Pair(anEdgeIndex1, anEdgeIndex2));
|
||||||
|
if (!aVertexIndices)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TColStd_ListOfInteger::Iterator itEEP(*aVertexIndices); itEEP.More();
|
||||||
|
itEEP.Next())
|
||||||
|
{
|
||||||
|
const Standard_Integer aVertexIndex = itEEP.Value();
|
||||||
|
const TopoDS_Vertex& aVertex = TopoDS::Vertex(myDS->Shape(aVertexIndex));
|
||||||
|
const gp_Pnt& aVertexPoint = BRep_Tool::Pnt(aVertex);
|
||||||
|
|
||||||
|
// Compute points exactly on the edges
|
||||||
|
GeomAPI_ProjectPointOnCurve& aProjPC1 = myContext->ProjPC(anEdge1);
|
||||||
|
GeomAPI_ProjectPointOnCurve& aProjPC2 = myContext->ProjPC(anEdge2);
|
||||||
|
aProjPC1.Perform(aVertexPoint);
|
||||||
|
aProjPC2.Perform(aVertexPoint);
|
||||||
|
if (!aProjPC1.NbPoints() && !aProjPC2.NbPoints())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const gp_Pnt aP1 =
|
||||||
|
aProjPC1.NbPoints() > 0 ? aProjPC1.NearestPoint() : aVertexPoint;
|
||||||
|
const gp_Pnt aP2 =
|
||||||
|
aProjPC2.NbPoints() > 0 ? aProjPC2.NearestPoint() : aVertexPoint;
|
||||||
|
|
||||||
|
const Standard_Real aShiftDist = aP1.Distance(aP2);
|
||||||
|
if (aShiftDist > BRep_Tool::Tolerance(aVertex))
|
||||||
|
{
|
||||||
|
// Move one of the faces to the point of exact intersection of edges
|
||||||
|
gp_Trsf aTrsf;
|
||||||
|
aTrsf.SetTranslation(anIsClosed1 ? gp_Vec(aP1, aP2) : gp_Vec(aP2, aP1));
|
||||||
|
TopLoc_Location aLoc(aTrsf);
|
||||||
|
(anIsClosed1 ? &aFShifted1 : &aFShifted2)->Move(aLoc);
|
||||||
|
aShiftValue = aShiftDist;
|
||||||
|
anIsFound = Standard_True;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================================================================================================
|
//=================================================================================================
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user