From e11c1bc4330c57d6d95a2b711925003772cf765d Mon Sep 17 00:00:00 2001 From: jgv Date: Thu, 11 Dec 2014 15:43:42 +0300 Subject: [PATCH] 0025557: Draw command "openoffset" fails on customer's shape with big values of offset Test cases for issue CR25557 --- src/BRepFill/BRepFill_OffsetWire.cxx | 94 +++++++++++++++++++++++++--- tests/bugs/modalg_5/bug25557_1 | 30 +++++++++ tests/bugs/modalg_5/bug25557_2 | 30 +++++++++ 3 files changed, 144 insertions(+), 10 deletions(-) create mode 100755 tests/bugs/modalg_5/bug25557_1 create mode 100755 tests/bugs/modalg_5/bug25557_2 diff --git a/src/BRepFill/BRepFill_OffsetWire.cxx b/src/BRepFill/BRepFill_OffsetWire.cxx index c9ed51900d..2806ec1fe7 100644 --- a/src/BRepFill/BRepFill_OffsetWire.cxx +++ b/src/BRepFill/BRepFill_OffsetWire.cxx @@ -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()); @@ -2281,6 +2325,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 index 0000000000..26afc7d66e --- /dev/null +++ b/tests/bugs/modalg_5/bug25557_1 @@ -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 index 0000000000..8003bad42e --- /dev/null +++ b/tests/bugs/modalg_5/bug25557_2 @@ -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 -- 2.20.1