]> OCCT Git - occt.git/commitdiff
Modeling - General Fuse (BOPAlgo_PaveFiller) optimization #514
authorDmitrii Kulikov <164657232+AtheneNoctuaPt@users.noreply.github.com>
Thu, 15 May 2025 23:03:44 +0000 (00:03 +0100)
committerGitHub <noreply@github.com>
Thu, 15 May 2025 23:03:44 +0000 (00:03 +0100)
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.

src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/ModelingAlgorithms/TKBO/BOPDS/BOPDS_DS.cxx
src/ModelingData/TKBRep/BRep/BRep_Tool.cxx

index c40d67e7ee2e53479bda69793c9d382415338057..99022a516829d9a555326b15b2f3ce7ade022efa 100644 (file)
@@ -47,6 +47,9 @@
 #include <BRepLib.hxx>
 #include <BRepTools.hxx>
 #include <Geom_Curve.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_OffsetSurface.hxx>
 #include <Geom2d_Curve.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <GeomAPI_ProjectPointOnSurf.hxx>
 #include <TopTools_DataMapOfShapeInteger.hxx>
 #include <TopTools_ListOfShape.hxx>
 
-//
 static Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
                                  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
@@ -225,11 +279,10 @@ protected:
   gp_Trsf          myTrsf;
 };
 
-//
-//=======================================================================
+//=================================================================================================
+
 typedef NCollection_Vector<BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
 
-/////////////////////////////////////////////////////////////////////////
 //=================================================================================================
 
 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)
       {
-
-        Standard_Boolean isFound = Standard_False;
-        for (TopExp_Explorer aExp1(aF1, TopAbs_EDGE); !isFound && aExp1.More(); aExp1.Next())
+        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);
+
+        TopLoc_Location                   aLocation2;
+        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());
-          const Standard_Integer nE1 = myDS->Index(aE1);
-
-          for (TopExp_Explorer aExp2(aF2, TopAbs_EDGE); !isFound && aExp2.More(); aExp2.Next())
+          for (TopoDS_Iterator aItE1(aItW1.Value()); !anIsFound && aItE1.More(); aItE1.Next())
           {
-            const TopoDS_Edge&     aE2 = TopoDS::Edge(aExp2.Current());
-            const Standard_Integer nE2 = myDS->Index(aE2);
+            const TopoDS_Edge&     anEdge1      = TopoDS::Edge(aItE1.Value());
+            const Standard_Integer anEdgeIndex1 = myDS->Index(anEdge1);
 
-            Standard_Boolean bIsClosed1 = BRep_Tool::IsClosed(aE1, aF1);
-            Standard_Boolean bIsClosed2 = BRep_Tool::IsClosed(aE2, aF2);
-            if (!bIsClosed1 && !bIsClosed2)
+            for (TopoDS_Iterator aItW2(aF2); !anIsFound && aItW2.More(); aItW2.Next())
             {
-              continue;
-            }
+              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;
+                }
 
-            const TColStd_ListOfInteger* pPoints = aEEMap.Seek(BOPDS_Pair(nE1, nE2));
-            if (!pPoints)
-            {
-              continue;
-            }
+                const TColStd_ListOfInteger* aVertexIndices =
+                  aEEMap.Seek(BOPDS_Pair(anEdgeIndex1, anEdgeIndex2));
+                if (!aVertexIndices)
+                {
+                  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;
-              }
-              gp_Pnt aP1 = aProjPC1.NbPoints() > 0 ? aProjPC1.NearestPoint() : aPnt;
-              gp_Pnt aP2 = aProjPC2.NbPoints() > 0 ? aProjPC2.NearestPoint() : aPnt;
+                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;
 
-              Standard_Real aShiftDist = aP1.Distance(aP2);
-              if (aShiftDist > BRep_Tool::Tolerance(aVN))
-              {
-                // Move one of the faces to the point of exact intersection of edges
-                gp_Trsf aTrsf;
-                aTrsf.SetTranslation(bIsClosed1 ? gp_Vec(aP1, aP2) : gp_Vec(aP2, aP1));
-                TopLoc_Location aLoc(aTrsf);
-                (bIsClosed1 ? &aFShifted1 : &aFShifted2)->Move(aLoc);
-                aShiftValue = aShiftDist;
-                isFound     = Standard_True;
+                  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;
+                  }
+                }
               }
             }
           }
index 195b8c54b283634b325865faab39dadffd888452..deb09c4b06f98eefe13419080ef93dec203e158e 100644 (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 iRet;
-  //
-  iRet = -1;
-  if (myMapShapeIndex.IsBound(theS))
-  {
-    iRet = myMapShapeIndex.Find(theS);
-  }
-  return iRet;
+  Standard_Integer anIndex = -1;
+  myMapShapeIndex.Find(theS, anIndex);
+  return anIndex;
 }
 
 //=================================================================================================
index a6e5fb8893dd2f6fed195b93cdd0ba98be376386..d43cab782902b3a8a54f618165d2ff5c3685ac89 100644 (file)
@@ -795,6 +795,11 @@ Standard_Boolean BRep_Tool::IsClosed(const TopoDS_Edge&                E,
                                      const Handle(Poly_Triangulation)& T,
                                      const TopLoc_Location&            L)
 {
+  if (T.IsNull())
+  {
+    return Standard_False;
+  }
+
   TopLoc_Location l = L.Predivided(E.Location());
 
   // find the representation