0025557: Draw command "openoffset" fails on customer's shape with big values of offset
authorjgv <jgv@opencascade.com>
Thu, 11 Dec 2014 12:43:42 +0000 (15:43 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 11 Dec 2014 12:44:43 +0000 (15:44 +0300)
Test cases for issue CR25557

src/BRepFill/BRepFill_OffsetWire.cxx
tests/bugs/modalg_5/bug25557_1 [new file with mode: 0755]
tests/bugs/modalg_5/bug25557_2 [new file with mode: 0755]

index c9ed519..2806ec1 100644 (file)
@@ -180,6 +180,8 @@ static void StoreInMap (const TopoDS_Shape& V1,
                        TopTools_IndexedDataMapOfShapeShape& MapVV);
 
 static void TrimEdge (const TopoDS_Edge&              CurrentEdge,
+                      const TopoDS_Shape&             CurrentSpine,
+                      const TopoDS_Face&              AllSpine,
                      const TopTools_ListOfShape&     D,
                       TopTools_SequenceOfShape& Sv,  
                       TColStd_SequenceOfReal&   MapverPar,
@@ -187,6 +189,11 @@ static void TrimEdge (const TopoDS_Edge&              CurrentEdge,
                       TopTools_IndexedDataMapOfShapeShape& MapVV,
                       const Standard_Integer IndOfE);
 
+static Standard_Boolean IsInnerEdge(const TopoDS_Shape& ProE,
+                                    const TopoDS_Face&  AllSpine,
+                                    Standard_Real& TrPar1,
+                                    Standard_Real& TrPar2);
+
 static Standard_Boolean DoubleOrNotInside (const TopTools_ListOfShape& EC,
                                           const TopoDS_Vertex&        V);
 
@@ -238,6 +245,7 @@ static void CheckFace(const TopoDS_Face& theFace)
 static Standard_Boolean KPartCircle
 (const TopoDS_Face&  mySpine,
  const Standard_Real myOffset,
+ const Standard_Boolean IsOpenResult,
  const Standard_Real Alt,
  TopoDS_Shape&       myShape, 
  BRepFill_IndexedDataMapOfOrientedShapeListOfShape& myMap,
@@ -265,8 +273,8 @@ static Standard_Boolean KPartCircle
 
   TopoDS_Vertex V1,V2;
   TopExp::Vertices(E,V1,V2);
-  if (!V1.IsSame(V2) || //open result or closed circle
-      C->IsKind(STANDARD_TYPE(Geom_Circle))) 
+  if ((C->IsKind(STANDARD_TYPE(Geom_Circle)) && V1.IsSame(V2)) || //closed circle
+      IsOpenResult)
   {
     Standard_Real anOffset = myOffset;
     if (E.Orientation() == TopAbs_REVERSED) anOffset *= -1;
@@ -382,7 +390,7 @@ void BRepFill_OffsetWire::Init(const TopoDS_Face&     Spine,
   TopoDS_Shape aShape;
   BRepFill_IndexedDataMapOfOrientedShapeListOfShape aMap;
   Standard_Boolean Done;
-  if (KPartCircle(myWorkSpine,1.,0.,aShape,aMap,Done)) return;
+  if (KPartCircle(myWorkSpine,1.,myIsOpenResult,0.,aShape,aMap,Done)) return;
   
 
   //-----------------------------------------------------
@@ -515,7 +523,7 @@ void BRepFill_OffsetWire::Perform (const Standard_Real Offset,
   {
     OCC_CATCH_SIGNALS
       myCallGen = Standard_False;
-    if (KPartCircle(myWorkSpine,Offset,Alt,myShape,myMap,myIsDone)) return;
+    if (KPartCircle(myWorkSpine,Offset,myIsOpenResult,Alt,myShape,myMap,myIsDone)) return;
 
     TopoDS_Face oldWorkSpain = myWorkSpine;
 
@@ -749,7 +757,7 @@ void BRepFill_OffsetWire::PerformWithBiLo
   //********************************
   // Calculate for a non null offset 
   //********************************
-  if (KPartCircle(myWorkSpine,Offset,Alt,myShape,myMap,myIsDone))
+  if (KPartCircle(myWorkSpine,Offset,myIsOpenResult,Alt,myShape,myMap,myIsDone))
     return;
 
   BRep_Builder myBuilder;
@@ -1026,6 +1034,8 @@ void BRepFill_OffsetWire::PerformWithBiLo
             IndOfE = -1;
         }
        TrimEdge (CurrentEdge,
+                  CurrentSpine,
+                  mySpine,
                  Detromp  (CurrentSpine),
                  MapBis   (CurrentEdge) ,  
                  MapVerPar(CurrentEdge) ,
@@ -2115,6 +2125,8 @@ void StoreInMap (const TopoDS_Shape& V1,
 //=======================================================================
 
 void TrimEdge (const TopoDS_Edge&              E,
+               const TopoDS_Shape&             ProE,
+               const TopoDS_Face&              AllSpine,
               const TopTools_ListOfShape&     Detromp,
                TopTools_SequenceOfShape& TheVer,
                TColStd_SequenceOfReal&   ThePar,
@@ -2198,19 +2210,39 @@ void TrimEdge (const TopoDS_Edge&              E,
     TopoDS_Vertex V1, V2;
     TopExp::Vertices(E, V1, V2);
     Standard_Real fpar, lpar;
-    BRep_Tool::Range(E, fpar, lpar);
+    Handle(Geom_Surface) aPlane;
+    TopLoc_Location aLoc;
+    Handle(Geom2d_Curve) PCurve;
+    BRep_Tool::CurveOnSurface(E, PCurve, aPlane, aLoc, fpar, lpar);
+    //BRep_Tool::Range(E, fpar, lpar);
+
+    Standard_Real TrPar1, TrPar2;
+    Standard_Boolean ToTrimAsOrigin = IsInnerEdge(ProE, AllSpine, TrPar1, TrPar2);
+    
     if (IndOfE == 1) //first edge of open wire
     {
       if (NewEdge.Orientation() == TopAbs_FORWARD)
       {
+        if (ToTrimAsOrigin)
+        {
+          fpar = TrPar1;
+          gp_Pnt2d TrPnt2d = PCurve->Value(fpar);
+          gp_Pnt TrPnt(TrPnt2d.X(), TrPnt2d.Y(), 0.);
+          V1 = BRepLib_MakeVertex(TrPnt);
+        }
         TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_FORWARD));
         TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED));
         TheBuilder.Range(NewEdge, fpar, ThePar.First());
       }
       else
       {
-        //TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_REVERSED));
-        //TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD));
+        if (ToTrimAsOrigin)
+        {
+          lpar = TrPar2;
+          gp_Pnt2d TrPnt2d = PCurve->Value(lpar);
+          gp_Pnt TrPnt(TrPnt2d.X(), TrPnt2d.Y(), 0.);
+          V2 = BRepLib_MakeVertex(TrPnt);
+        }
         TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED));
         TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_FORWARD));
         TheBuilder.Range(NewEdge, ThePar.First(), lpar);
@@ -2220,14 +2252,26 @@ void TrimEdge (const TopoDS_Edge&              E,
     {
       if (NewEdge.Orientation() == TopAbs_FORWARD)
       {
+        if (ToTrimAsOrigin)
+        {
+          lpar = TrPar2;
+          gp_Pnt2d TrPnt2d = PCurve->Value(lpar);
+          gp_Pnt TrPnt(TrPnt2d.X(), TrPnt2d.Y(), 0.);
+          V2 = BRepLib_MakeVertex(TrPnt);
+        }
         TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD));
         TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_REVERSED));
         TheBuilder.Range(NewEdge, ThePar.First(), lpar);
       }
       else
       {
-        //TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED));
-        //TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_FORWARD));
+        if (ToTrimAsOrigin)
+        {
+          fpar = TrPar1;
+          gp_Pnt2d TrPnt2d = PCurve->Value(fpar);
+          gp_Pnt TrPnt(TrPnt2d.X(), TrPnt2d.Y(), 0.);
+          V1 = BRepLib_MakeVertex(TrPnt);
+        }
         TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_REVERSED));
         TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD));
         TheBuilder.Range(NewEdge, fpar, ThePar.First());
@@ -2282,6 +2326,36 @@ void TrimEdge (const TopoDS_Edge&              E,
 }
 
 //=======================================================================
+//function : IsInnerEdge
+//purpose  :
+//=======================================================================
+
+static Standard_Boolean IsInnerEdge(const TopoDS_Shape& ProE,
+                                    const TopoDS_Face&  AllSpine,
+                                    Standard_Real& TrPar1,
+                                    Standard_Real& TrPar2)
+{
+  if (ProE.ShapeType() != TopAbs_EDGE)
+    return Standard_False;
+
+  TopoDS_Edge anEdge = TopoDS::Edge(ProE);
+
+  TopTools_IndexedDataMapOfShapeListOfShape VEmap;
+  TopExp::MapShapesAndAncestors(AllSpine, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
+  for (Standard_Integer i = 1; i <= VEmap.Extent(); i++)
+  {
+    const TopTools_ListOfShape& LE = VEmap(i);
+    if (LE.Extent() == 1 && anEdge.IsSame(LE.First()))
+      return Standard_False;
+  }
+
+  BRep_Tool::Range(anEdge, TrPar1, TrPar2);
+  return Standard_True;
+}
+
+
+
+//=======================================================================
 //function : DoubleOrNotInside
 //purpose  : return True if V appears twice in LV or is not inside.
 //=======================================================================
diff --git a/tests/bugs/modalg_5/bug25557_1 b/tests/bugs/modalg_5/bug25557_1
new file mode 100755 (executable)
index 0000000..26afc7d
--- /dev/null
@@ -0,0 +1,30 @@
+puts "========"
+puts "OCC25557"
+puts "========"
+puts ""
+##########################################################################################################
+# Draw command "openoffset" fails on customer's shape with big values of offset
+##########################################################################################################
+
+restore [locate_data_file bug25557_offset_lines_option.brep] a
+
+smallview
+
+openoffset res a 1 -5
+renamevar res_1 result
+
+fit
+
+set length 97.766
+
+set nb_v_good 3
+set nb_e_good 2
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 6
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25557_2 b/tests/bugs/modalg_5/bug25557_2
new file mode 100755 (executable)
index 0000000..8003bad
--- /dev/null
@@ -0,0 +1,30 @@
+puts "========"
+puts "OCC25557"
+puts "========"
+puts ""
+##########################################################################################################
+# Draw command "openoffset" fails on customer's shape with big values of offset
+##########################################################################################################
+
+restore [locate_data_file bug25557_offset_lines_option.brep] a
+
+smallview
+
+openoffset res a 1 -10
+renamevar res_1 result
+
+fit
+
+set length 87.7041
+
+set nb_v_good 3
+set nb_e_good 2
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 6
+
+set only_screen_axo 1