0031464: BRepOffsetAPI_MakeFilling algorithm increases tolerances of vertices in...
authorjgv <jgv@opencascade.com>
Tue, 31 Mar 2020 15:18:14 +0000 (18:18 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 10 Apr 2020 14:41:39 +0000 (17:41 +0300)
Modify history in BRepFill_Filling: now vertices are also stored in the map.

src/BRepFill/BRepFill_Filling.cxx
src/BRepFill/BRepFill_Filling.hxx
src/BRepTest/BRepTest_FillingCommands.cxx
tests/bugs/modalg_7/bug31464 [new file with mode: 0644]

index dbdc1e6..fedf0c3 100644 (file)
@@ -31,6 +31,7 @@
 #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>
@@ -234,8 +235,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
@@ -258,8 +257,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
@@ -460,7 +457,9 @@ 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();
+                  myOldNewMap.Bind(CurEdge.Oriented(TopAbs_FORWARD),
+                                   NewEdge.Oriented(TopAbs_FORWARD));
                   EdgeList.Remove(Itl);
                   found = Standard_True;
                   break;
@@ -704,25 +703,48 @@ 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))
+      anEdge = TopoDS::Edge(myOldNewMap(anEdge));
+    
     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))
+      NewV1 = TopoDS::Vertex(myOldNewMap(V1));
+    else
+    {
+      gp_Pnt aPnt = BRep_Tool::Pnt(V1);
+      NewV1 = BRepLib_MakeVertex(aPnt);
+      BB.UpdateVertex(NewV1, dmax);
+    }
+
+    if (myOldNewMap.IsBound(V2))
+      NewV2 = TopoDS::Vertex(myOldNewMap(V2));
+    else
+    {
+      gp_Pnt aPnt = BRep_Tool::Pnt(V2);
+      NewV2 = BRepLib_MakeVertex(aPnt);
+      BB.UpdateVertex(NewV2, dmax);
+    }
+
+    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);
+    myOldNewMap.Bind(InitEdge.Oriented(TopAbs_FORWARD), NewEdge.Oriented(TopAbs_FORWARD));
+    myOldNewMap.Bind(V1.Oriented(TopAbs_FORWARD), NewV1.Oriented(TopAbs_FORWARD));
+    if (!V1.IsSame(V2))
+      myOldNewMap.Bind(V2.Oriented(TopAbs_FORWARD), NewV2.Oriented(TopAbs_FORWARD));
   }
   
   TopoDS_Wire FinalWire = WireFromList(FinalEdges);
index e8b8b94..e8797ad 100644 (file)
@@ -25,7 +25,7 @@
 #include <BRepFill_SequenceOfEdgeFaceAndOrder.hxx>
 #include <BRepFill_SequenceOfFaceAndOrder.hxx>
 #include <GeomPlate_SequenceOfPointConstraint.hxx>
-#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopoDS_Face.hxx>
 #include <Standard_Real.hxx>
@@ -207,7 +207,7 @@ private:
   BRepFill_SequenceOfEdgeFaceAndOrder myConstraints;
   BRepFill_SequenceOfFaceAndOrder myFreeConstraints;
   GeomPlate_SequenceOfPointConstraint myPoints;
-  TopTools_DataMapOfShapeListOfShape myOldNewMap;
+  TopTools_DataMapOfShapeShape myOldNewMap;
   TopTools_ListOfShape myGenerated;
   TopoDS_Face myFace;
   TopoDS_Face myInitFace;
index 6ca87e4..99d7b4a 100644 (file)
@@ -97,6 +97,7 @@
 #include <Geom2d_TrimmedCurve.hxx>
 #include <GeomConvert_ApproxSurface.hxx>
 
+#include <BRepTest_Objects.hxx>
 
 #include <stdio.h>
 #include <gp_Pnt.hxx>
@@ -452,13 +453,18 @@ static Standard_Integer approxplate (Draw_Interpretor & di,Standard_Integer n,co
 static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, const char** a )
 {
 #ifdef OCCT_DEBUG
-  // Chronmetrage
+  // Chronometrage
   OSD_Chronometer Chrono;
   Chrono.Reset();
   Chrono.Start();
 #endif
 
-  if (n < 7) return 1;
+  if (n < 7)
+  {
+    di.PrintHelp(a[0]);
+    return 1;
+  }
+  
   Standard_Integer NbBounds = Draw::Atoi( a[2] );
   Standard_Integer NbConstraints = Draw::Atoi( a[3] );
   Standard_Integer NbPoints = Draw::Atoi( a[4] );
@@ -473,8 +479,6 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
                                   TolCurv,
                                   MaxDeg,
                                   MaxSegments );
-  //TopoDS_Shape aLocalFace(DBRep::Get( a[5], TopAbs_FACE ) );
-  //TopoDS_Face InitFace = TopoDS::Face( aLocalFace);
   TopoDS_Face InitFace = TopoDS::Face( DBRep::Get(a[5], TopAbs_FACE) );
   if (! InitFace.IsNull())
     MakeFilling.LoadInitSurface( InitFace );
@@ -484,104 +488,94 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
   TopoDS_Face F;
   gp_Pnt Point;
   Standard_Integer Order;
+  TopTools_ListOfShape ListForHistory;
   for (k = 1; k <= NbBounds; k++)
-    { 
-      E.Nullify();
-      F.Nullify();
-      //TopoDS_Shape aLocalEdge(DBRep::Get( a[i], TopAbs_EDGE ));
-      //E = TopoDS::Edge(aLocalEdge);
-      E = TopoDS::Edge( DBRep::Get(a[i], TopAbs_EDGE) );
-      if (! E.IsNull())
-       i++;
-      //aLocalFace =  DBRep::Get( a[i], TopAbs_FACE ) ;
-      //F = TopoDS::Face(aLocalFace);
-      F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
-      if (! F.IsNull())
-       i++;
-
-      Order = Draw::Atoi( a[i++] );
-      
-      if (! E.IsNull() && ! F.IsNull())
-       MakeFilling.Add( E, F, (GeomAbs_Shape)Order );
-      else if (E.IsNull())
-       {
-         if (F.IsNull())
-           {
-             //std::cout<<std::endl<<"Wrong parameters"<<std::endl<<std::endl;
-             di<<"\nWrong parameters\n\n";
-             return 1;
-           }
-         else
-           MakeFilling.Add( F, (GeomAbs_Shape)Order );
-       }
+  { 
+    E.Nullify();
+    F.Nullify();
+    E = TopoDS::Edge( DBRep::Get(a[i], TopAbs_EDGE) );
+    if (! E.IsNull())
+      i++;
+    F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
+    if (! F.IsNull())
+      i++;
+    
+    Order = Draw::Atoi( a[i++] );
+    
+    if (! E.IsNull() && ! F.IsNull())
+      MakeFilling.Add( E, F, (GeomAbs_Shape)Order );
+    else if (E.IsNull())
+    {
+      if (F.IsNull())
+      {
+        di<<"\nWrong parameters\n\n";
+        return 1;
+      }
       else
-       MakeFilling.Add( E, (GeomAbs_Shape)Order );
+        MakeFilling.Add( F, (GeomAbs_Shape)Order );
     }
+    else
+      MakeFilling.Add( E, (GeomAbs_Shape)Order );
+
+    //History 
+    if (!E.IsNull())
+      ListForHistory.Append(E);
+  }
   for (k = 1; k <= NbConstraints; k++)
-    { 
-      E.Nullify();
-      F.Nullify();
-      //TopoDS_Shape aLocalEdge(DBRep::Get( a[i++], TopAbs_EDGE ));
-      //E = TopoDS::Edge( aLocalEdge);
-      E = TopoDS::Edge( DBRep::Get(a[i++], TopAbs_EDGE) );
-      if (E.IsNull())
-       {
-         //std::cout<<"Wrong parameters"<<std::endl;
-         di<<"Wrong parameters\n";
-         return 1;
-       }
-      //TopoDS_Shape alocalFace(DBRep::Get( a[i], TopAbs_FACE ) );
-      //F = TopoDS::Face( alocalFace);
-      F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
-      if (! F.IsNull())
-       i++;
-      
-      Order = Draw::Atoi( a[i++] );
-      
-      if (F.IsNull())
-       MakeFilling.Add( E, (GeomAbs_Shape)Order, Standard_False );
-      else
-       MakeFilling.Add( E, F, (GeomAbs_Shape)Order, Standard_False );
+  { 
+    E.Nullify();
+    F.Nullify();
+    E = TopoDS::Edge( DBRep::Get(a[i++], TopAbs_EDGE) );
+    if (E.IsNull())
+    {
+      di<<"Wrong parameters\n";
+      return 1;
     }
+    F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
+    if (! F.IsNull())
+      i++;
+    
+    Order = Draw::Atoi( a[i++] );
+    
+    if (F.IsNull())
+      MakeFilling.Add( E, (GeomAbs_Shape)Order, Standard_False );
+    else
+      MakeFilling.Add( E, F, (GeomAbs_Shape)Order, Standard_False );
+  }
   for (k = 1; k <= NbPoints; k++)
+  {
+    if (DrawTrSurf::GetPoint( a[i], Point )) 
     {
-      if (DrawTrSurf::GetPoint( a[i], Point )) 
-       {
-         MakeFilling.Add( Point );
-         i++;
-       }
-      else
-       {
-         Standard_Real U = Draw::Atof( a[i++] ), V = Draw::Atof( a[i++] );
-         //aLocalFace = DBRep::Get( a[i++], TopAbs_FACE );
-         //F = TopoDS::Face( aLocalFace);
-         F = TopoDS::Face( DBRep::Get(a[i++], TopAbs_FACE));
-         if (F.IsNull()) 
-           {
-             //std::cout<<"Wrong parameters"<<std::endl;
-             di<<"Wrong parameters\n";
-             return 1;
-           }
-         Order = Draw::Atoi( a[i++] );
-
-         MakeFilling.Add( U, V, F, (GeomAbs_Shape)Order );
-       }
+      MakeFilling.Add( Point );
+      i++;
     }
-
-  MakeFilling.Build();
-  if (! MakeFilling.IsDone())
+    else
     {
-      //std::cout<<"filling failed"<<std::endl;
-      di<<"filling failed\n";
-      return 0;
+      Standard_Real U = Draw::Atof( a[i++] ), V = Draw::Atof( a[i++] );
+      F = TopoDS::Face( DBRep::Get(a[i++], TopAbs_FACE));
+      if (F.IsNull()) 
+      {
+        di<<"Wrong parameters\n";
+        return 1;
+      }
+      Order = Draw::Atoi( a[i++] );
+      
+      MakeFilling.Add( U, V, F, (GeomAbs_Shape)Order );
     }
-
+  }
+  
+  MakeFilling.Build();
+  if (! MakeFilling.IsDone())
+  {
+    di<<"filling failed\n";
+    return 0;
+  }
+  
   Standard_Real dmax = MakeFilling.G0Error(),
-                angmax = MakeFilling.G1Error(),
-                curvmax = MakeFilling.G2Error();
-  //std::cout<<" dist. max = "<<dmax<<" ; angle max = "<<angmax<<" ; diffcurv max = "<<curvmax<<std::endl;
+    angmax = MakeFilling.G1Error(),
+    curvmax = MakeFilling.G2Error();
   di<<" dist. max = "<<dmax<<" ; angle max = "<<angmax<<" ; diffcurv max = "<<curvmax<<"\n";
-
+  
   TopoDS_Face ResFace= TopoDS::Face( MakeFilling.Shape() );
   DBRep::Set( a[1], ResFace );
 
@@ -589,12 +583,14 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
   Chrono.Stop();
   Standard_Real Tps;
   Chrono.Show(Tps);
-  //std::cout<<"*** FIN DE FILLING ***"<<std::endl;
-  //std::cout<<"Temps de calcul  : "<<Tps<<std::endl;
   di<<"*** FIN DE FILLING ***\n";
   di<<"Temps de calcul  : "<<Tps<<"\n";
 #endif
 
+  //History 
+  if (BRepTest_Objects::IsHistoryNeeded())
+    BRepTest_Objects::SetHistory(ListForHistory, MakeFilling);
+
   return 0;
 }
 
diff --git a/tests/bugs/modalg_7/bug31464 b/tests/bugs/modalg_7/bug31464
new file mode 100644 (file)
index 0000000..400c0ee
--- /dev/null
@@ -0,0 +1,58 @@
+puts "============================================================================================="
+puts "OCC31464: BRepOffsetAPI_MakeFilling algorithm increases tolerances of vertices in input edges"
+puts "============================================================================================="
+puts ""
+
+brestore [locate_data_file bug31464.brep] a
+
+set tol [checkmaxtol a]
+
+explode a f
+explode a_1 e
+
+filling result 3 0 1  a_1_1 0 a_1_2 0 a_1_4 0  0.0785398166 0.0196349541 a_1 1
+savehistory hh
+
+set tol2 [checkmaxtol a]
+
+if { ${tol} != ${tol2}} {
+   puts "Error: tolerance of input shape changed"
+}
+
+generated e2 hh a_1_2
+
+explode a_1_3
+generated vv hh a_1_3_1
+
+distmini distvv a_1_3_1 vv
+if {[dval distvv_val] > 0.} {
+  puts "Error: generated vertex is wrong"
+}
+
+mkcurve oldc a_1_2
+mkcurve newc e2
+set log [xdistcc oldc newc -3.92699082e-14 0.0392699082 10]
+
+regexp {Max Distance = +([-0-9.+eE]+)} ${log} full dist
+
+if { [dval dist] != 0. } {
+  puts "Error: generated edge is wrong"
+}
+
+smallview
+donly result e2 vv
+fit
+
+checkshape result
+
+checknbshapes result -face 1 -wire 1 -edge 3 -vertex 3
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 0.0007} {
+   puts "Error: bad tolerance of result"
+}
+
+checkprops result -s 0.00190371
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png