]> OCCT Git - occt.git/commitdiff
SENR-22-081 "BRepOffsetAPI_MakeFilling throws an exception building a face (720) CR0_691_FixS
authorifv <ifv@opencascade.com>
Tue, 2 Nov 2021 06:17:07 +0000 (09:17 +0300)
committerifv <ifv@opencascade.com>
Mon, 8 Nov 2021 12:42:51 +0000 (15:42 +0300)
 Adaptation patches from #0023380, #0031464 and #0031558 for 6.9.1

src/BRepFill/BRepFill_Filling.cxx

index 56e108abc193442f84880c8fd57bd620d6cc7334..d8be2729eaababfb2f661855a72b48bcfe7d748c 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <BRepFill_Filling.ixx>
-#include <BRepFill_EdgeFaceAndOrder.hxx>
-#include <BRepFill_FaceAndOrder.hxx>
-#include <BRepAdaptor_HSurface.hxx>
+
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <Adaptor3d_HCurveOnSurface.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
 #include <BRepAdaptor_HCurve.hxx>
 #include <BRepAdaptor_HCurve2d.hxx>
+#include <BRepAdaptor_HSurface.hxx>
 #include <BRepFill_CurveConstraint.hxx>
-
+#include <BRepFill_EdgeFaceAndOrder.hxx>
+#include <BRepFill_FaceAndOrder.hxx>
+#include <BRepFill_Filling.hxx>
+#include <BRepLib.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepLib_MakeEdge.hxx>
+#include <BRepLib_MakeEdge2d.hxx>
+#include <BRepLib_MakeFace.hxx>
+#include <BRepLib_MakeWire.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <Geom2d_BezierCurve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
 #include <Geom2dAdaptor_HCurve.hxx>
+#include <Geom_BSplineSurface.hxx>
 #include <GeomAdaptor_HSurface.hxx>
-#include <Adaptor3d_CurveOnSurface.hxx>
-#include <Adaptor3d_HCurveOnSurface.hxx>
-
-#include <GeomPlate_MakeApprox.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
 #include <GeomPlate_CurveConstraint.hxx>
+#include <GeomPlate_MakeApprox.hxx>
+#include <GeomPlate_PlateG0Criterion.hxx>
 #include <GeomPlate_PointConstraint.hxx>
-
-#include <BRepLib_MakeEdge.hxx>
-#include <BRepLib_MakeEdge2d.hxx>
-#include <BRepLib_MakeWire.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Wire.hxx>
-#include <BRepLib_MakeFace.hxx>
+#include <GeomProjLib.hxx>
+#include <gp_Pnt.hxx>
+#include <Precision.hxx>
+#include <Standard_ConstructionError.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <StdFail_NotDone.hxx>
+#include <TColGeom2d_HArray1OfCurve.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <TColgp_SequenceOfPnt.hxx>
+#include <TColgp_SequenceOfXY.hxx>
 #include <TColStd_HArray1OfReal.hxx>
-#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
-#include <BRep_TEdge.hxx>
-#include <BRep_CurveRepresentation.hxx>
 #include <TopExp.hxx>
-#include <BRep_Tool.hxx>
-#include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
-
-#include <Precision.hxx>
-#include <GeomProjLib.hxx>
-#include <BRepTools.hxx>
-#include <BRep_Builder.hxx>
-#include <BRepLib.hxx>
-#include <TColgp_SequenceOfPnt.hxx>
+#include <TopoDS_Wire.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColGeom2d_HArray1OfCurve.hxx>
-
-#include <Geom2d_BezierCurve.hxx>
-#include <Geom2d_TrimmedCurve.hxx>
 #include <Geom_Surface.hxx>
 
-#include <TColgp_SequenceOfXY.hxx>
-#include <GeomPlate_PlateG0Criterion.hxx>
-#include <BRep_TVertex.hxx>
-
 static gp_Vec MakeFinVec( const TopoDS_Wire aWire, const TopoDS_Vertex aVertex )
 {
   TopoDS_Vertex Vfirst, Vlast, Origin;
   BRepTools_WireExplorer Explo( aWire );
   for (; Explo.More(); Explo.Next())
+  {
+    TopExp::Vertices(Explo.Current(), Vfirst, Vlast);
+    if (Vfirst.IsSame(aVertex))
     {
-      TopExp::Vertices( Explo.Current(), Vfirst, Vlast );
-      if (Vfirst.IsSame( aVertex ))
-       {
-         Origin = Vlast;
-         break;
-       }
-      if (Vlast.IsSame( aVertex ))
-       {
-         Origin = Vfirst;
-         break;
-       }
+      Origin = Vlast;
+      break;
     }
+    if (Vlast.IsSame(aVertex))
+    {
+      Origin = Vfirst;
+      break;
+    }
+  }
   return gp_Vec( BRep_Tool::Pnt( Origin ), BRep_Tool::Pnt( aVertex ) );
 }
 
 static TopoDS_Wire WireFromList(TopTools_ListOfShape& Edges)
 {
-  BRepLib_MakeWire MW;
+  BRep_Builder BB;
+  TopoDS_Wire aWire;
+  BB.MakeWire(aWire);
   TopoDS_Edge anEdge = TopoDS::Edge(Edges.First());
-  MW.Add(anEdge);
+  BB.Add(aWire, anEdge);
   Edges.RemoveFirst();
 
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(anEdge, V1, V2, Standard_True); //with orientation
+
   while (!Edges.IsEmpty())
   {
-    TopoDS_Wire CurWire = MW.Wire();
-    TopoDS_Vertex V1, V2;
-    TopExp::Vertices(CurWire, V1, V2);
     TopTools_ListIteratorOfListOfShape itl(Edges);
     for (; itl.More(); itl.Next())
     {
       anEdge = TopoDS::Edge(itl.Value());
       TopoDS_Vertex V3, V4;
-      TopExp::Vertices(anEdge, V3, V4);
+      TopExp::Vertices(anEdge, V3, V4, Standard_True); //with orientation
       if (V1.IsSame(V3) || V1.IsSame(V4) ||
-          V2.IsSame(V3) || V2.IsSame(V4))
+        V2.IsSame(V3) || V2.IsSame(V4))
+      {
+        if (V1.IsSame(V3))
+        {
+          anEdge.Reverse();
+          V1 = V4;
+        }
+        else if (V1.IsSame(V4))
+          V1 = V3;
+        else if (V2.IsSame(V3))
+          V2 = V4;
+        else
+        {
+          anEdge.Reverse();
+          V2 = V3;
+        }
         break;
+      }
     }
-    MW.Add(anEdge);
+    BB.Add(aWire, anEdge);
     Edges.Remove(itl);
   }
 
-  return (MW.Wire());
+  aWire.Closed(Standard_True);
+  return aWire;
 }
 
 //=======================================================================
@@ -213,8 +231,6 @@ Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
   if (IsBound)
     {
       myBoundary.Append( EdgeFaceAndOrder );
-      TopTools_ListOfShape EmptyList;
-      myOldNewMap.Bind(anEdge, EmptyList);
       return myBoundary.Length();
     }
   else
@@ -237,8 +253,6 @@ Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
   if (IsBound)
     {
       myBoundary.Append( EdgeFaceAndOrder );
-      TopTools_ListOfShape EmptyList;
-      myOldNewMap.Bind(anEdge, EmptyList);
       return myBoundary.Length();
     }
   else
@@ -312,8 +326,8 @@ void BRepFill_Filling::AddConstraints( const BRepFill_SequenceOfEdgeFaceAndOrder
        if (CurOrder == GeomAbs_C0) {
          Handle( BRepAdaptor_HCurve ) HCurve = new BRepAdaptor_HCurve();
          HCurve->ChangeCurve().Initialize( CurEdge );
-         
-         Constr = new BRepFill_CurveConstraint(HCurve,
+         const Handle(Adaptor3d_HCurve)& aHCurve = HCurve; // to avoid ambiguity
+         Constr = new BRepFill_CurveConstraint(aHCurve,
                                                CurOrder,
                                                myNbPtsOnCur,
                                                myTol3d );
@@ -326,7 +340,7 @@ void BRepFill_Filling::AddConstraints( const BRepFill_SequenceOfEdgeFaceAndOrder
          Standard_Real f, l;
          BRep_Tool::CurveOnSurface( CurEdge, C2d, Surface, loc, f, l);
          if (Surface.IsNull()) {
-           Standard_Failure::Raise( "Add" );
+           throw Standard_Failure( "Add" );
            return;
          }
          Surface = Handle(Geom_Surface)::DownCast(Surface->Copy());
@@ -385,8 +399,6 @@ void BRepFill_Filling::AddConstraints( const BRepFill_SequenceOfEdgeFaceAndOrder
 //======================================================================
 void BRepFill_Filling::BuildWires( TopTools_ListOfShape& EdgeList, TopTools_ListOfShape& WireList )
 {
-  TopoDS_Wire CurWire;
-  TopoDS_Edge CurEdge;
   TopTools_ListIteratorOfListOfShape Itl;
   Standard_Integer i, j;
 
@@ -441,7 +453,10 @@ void BRepFill_Filling::BuildWires( TopTools_ListOfShape& EdgeList, TopTools_List
                     aDist < BRep_Tool::Tolerance(V_edge[j]))
                 {
                   MW.Add(CurEdge);
-                  myOldNewMap(CurEdge).Append(MW.Edge());
+                  TopoDS_Edge NewEdge = MW.Edge();
+                                 TopTools_ListOfShape anLOS;
+                                 anLOS.Append(NewEdge.Oriented(TopAbs_FORWARD));
+                  myOldNewMap.Bind(CurEdge.Oriented(TopAbs_FORWARD), anLOS);
                   EdgeList.Remove(Itl);
                   found = Standard_True;
                   break;
@@ -479,11 +494,20 @@ void BRepFill_Filling::FindExtremitiesOfHoles(const TopTools_ListOfShape& WireLi
   theWire = TopoDS::Wire(WireSeq(1));
   WireSeq.Remove(1);
 
-  if (theWire.Closed())
+  if (BRep_Tool::IsClosed(theWire))
     return;
 
   TopoDS_Vertex Vfirst, Vlast;
   TopExp::Vertices( theWire, Vfirst, Vlast );
+
+  if (Vfirst.IsSame(Vlast))
+  {
+    // The Wire is closed indeed despite its 
+    // being not detected earlier.
+
+    return;
+  }
+
   gp_Vec FinVec = MakeFinVec( theWire, Vlast );
   TopoDS_Vertex theVertex = Vlast;
   VerSeq.Append( Vlast );
@@ -567,7 +591,7 @@ void BRepFill_Filling::Build()
   for (j = 1; j <= myFreeConstraints.Length(); j++)
     {
       GeomAPI_ProjectPointOnSurf Projector;
-      Quantity_Parameter U1, V1, U2, V2;
+      Standard_Real U1, V1, U2, V2;
 
       CurFace = myFreeConstraints(j).myFace;
       Handle( BRepAdaptor_HSurface ) HSurf = new BRepAdaptor_HSurface();
@@ -676,30 +700,76 @@ void BRepFill_Filling::Build()
   {
     const TopoDS_Edge& InitEdge = myBoundary(i).myEdge;
     TopoDS_Edge anEdge = InitEdge;
-    if (!myOldNewMap(anEdge).IsEmpty())
-      anEdge = TopoDS::Edge( myOldNewMap(anEdge).First() );
+    anEdge.Orientation(TopAbs_FORWARD);
+    if (myOldNewMap.IsBound(anEdge))
+       {
+         const TopTools_ListOfShape& anLOS = myOldNewMap(anEdge);
+         anEdge = TopoDS::Edge(anLOS.First());
+       }
+
     Handle(Geom2d_Curve) aCurveOnPlate = CurvesOnPlate->Value(i);
 
     TopoDS_Edge NewEdge = TopoDS::Edge(anEdge.EmptyCopied());
 
-    TopoDS_Vertex V1, V2;
-    TopExp::Vertices(anEdge, V1, V2, Standard_True); //with orientation
-    BB.UpdateVertex(V1, dmax);
-    BB.UpdateVertex(V2, dmax);
-    BB.Add(NewEdge, V1);
-    BB.Add(NewEdge, V2);
+    TopoDS_Vertex V1, V2, NewV1, NewV2;
+    TopExp::Vertices(anEdge, V1, V2);
+
+    if (myOldNewMap.IsBound(V1))
+       {
+         const TopTools_ListOfShape& anLOS = myOldNewMap(V1);
+      NewV1 = TopoDS::Vertex(anLOS.First());
+       }
+    else
+    {
+      gp_Pnt aPnt = BRep_Tool::Pnt(V1);
+      NewV1 = BRepLib_MakeVertex(aPnt);
+      BB.UpdateVertex(NewV1, dmax);
+      TopTools_ListOfShape anLOS;
+      anLOS.Append(NewV1);
+      myOldNewMap.Bind(V1.Oriented(TopAbs_FORWARD), anLOS);
+    }
+
+    if (myOldNewMap.IsBound(V2))
+    {
+      const TopTools_ListOfShape& anLOS = myOldNewMap(V2);
+      NewV2 = TopoDS::Vertex(anLOS.First());
+    }
+    else
+    {
+      gp_Pnt aPnt = BRep_Tool::Pnt(V2);
+      NewV2 = BRepLib_MakeVertex(aPnt);
+      BB.UpdateVertex(NewV2, dmax);
+      TopTools_ListOfShape anLOS;
+      anLOS.Append(NewV2);
+      myOldNewMap.Bind(V2.Oriented(TopAbs_FORWARD), anLOS);
+    }
+
+    NewV1.Orientation(TopAbs_FORWARD);
+    BB.Add(NewEdge, NewV1);
+    NewV2.Orientation(TopAbs_REVERSED);
+    BB.Add(NewEdge, NewV2);
     TopLoc_Location Loc;
     BB.UpdateEdge(NewEdge, aCurveOnPlate, Surface, Loc, dmax);
     //BRepLib::SameRange(NewEdge);
     BRepLib::SameParameter(NewEdge, dmax, Standard_True);
     FinalEdges.Append(NewEdge);
-    myOldNewMap(InitEdge).Clear();
-    myOldNewMap(InitEdge).Append(NewEdge);
+    TopTools_ListOfShape anLOS1;
+    anLOS1.Append(NewEdge.Oriented(TopAbs_FORWARD));
+    myOldNewMap.Bind(InitEdge.Oriented(TopAbs_FORWARD), anLOS1);
+    TopTools_ListOfShape anLOS2;
+    anLOS2.Append(NewV1.Oriented(TopAbs_FORWARD));
+    myOldNewMap.Bind(V1.Oriented(TopAbs_FORWARD), anLOS2);
+    if (!V1.IsSame(V2))
+    {
+      TopTools_ListOfShape anLOS;
+      anLOS.Append(NewV2.Oriented(TopAbs_FORWARD));
+      myOldNewMap.Bind(V2.Oriented(TopAbs_FORWARD), anLOS);
+    }
   }
   
   TopoDS_Wire FinalWire = WireFromList(FinalEdges);
   if (!(FinalWire.Closed()))
-    Standard_Failure::Raise("Wire is not closed");
+    throw Standard_Failure("Wire is not closed");
   
   myFace = BRepLib_MakeFace( Surface, FinalWire );
 }