From 85f78ac11072de6694d3a60343640bb7eef90526 Mon Sep 17 00:00:00 2001 From: jgv Date: Mon, 5 Oct 2020 23:39:08 +0300 Subject: [PATCH] 0031778: UnifySameDomain fails in Debug mode Correct unification of circular edges: avoid trying to make an axis with null magnitude. --- .../ShapeUpgrade_UnifySameDomain.cxx | 63 +++++++++---------- tests/bugs/heal/bug31778 | 28 +++++++++ 2 files changed, 58 insertions(+), 33 deletions(-) create mode 100644 tests/bugs/heal/bug31778 diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx index 661ba42527..a72e9ab9e6 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx @@ -1298,12 +1298,12 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, if(c3d1.IsNull() || c3d2.IsNull()) return Standard_False; - while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + if (c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d1); c3d1 = tc->BasisCurve(); } - while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + if (c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d2); c3d2 = tc->BasisCurve(); @@ -1370,7 +1370,7 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, TopoDS_Edge FE = TopoDS::Edge(theChain.First()); Handle(Geom_Curve) c3d = BRep_Tool::Curve(FE,f,l); - while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + if (c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d); c3d = tc->BasisCurve(); @@ -1415,7 +1415,12 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, B.Add(E,V[1]); } } - else { + else //open chain + { + Standard_Real ParamFirst = BRep_Tool::Parameter(V[0], FE); + TopoDS_Vertex VertexLastOnFE = sae.LastVertex(FE); + Standard_Real ParamLast = BRep_Tool::Parameter(VertexLastOnFE, FE); + if (isSafeInputMode) { for (int k = 0; k < 2; k++) { if (!theContext->IsRecorded(V[k])) { @@ -1427,37 +1432,29 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, V[k] = TopoDS::Vertex(theContext->Apply(V[k])); } } - gp_Pnt PV1 = BRep_Tool::Pnt(V[0]); - gp_Pnt PV2 = BRep_Tool::Pnt(V[1]); - TopoDS_Vertex VM = sae.LastVertex(FE); - gp_Pnt PVM = BRep_Tool::Pnt(VM); - GC_MakeCircle MC (PV1,PVM,PV2); - Handle(Geom_Circle) C = MC.Value(); - gp_Pnt P0 = C->Location(); - gp_Dir D1(gp_Vec(P0,PV1)); - gp_Dir D2(gp_Vec(P0,PV2)); - Standard_Real fpar = C->XAxis().Direction().Angle(D1); - if(fabs(fpar)>Precision::Confusion()) { - // check orientation - gp_Dir ND = C->XAxis().Direction().Crossed(D1); - if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { - fpar = -fpar; - } - } - Standard_Real lpar = C->XAxis().Direction().Angle(D2); - if(fabs(lpar)>Precision::Confusion()) { - // check orientation - gp_Dir ND = C->XAxis().Direction().Crossed(D2); - if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { - lpar = -lpar; - } - } - if (lpar < fpar) lpar += 2*M_PI; - Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar); + + gp_Pnt PointFirst = BRep_Tool::Pnt(V[0]); + while (Abs(ParamLast - ParamFirst) > 7*M_PI/8) + ParamLast = (ParamFirst + ParamLast)/2; + BRepAdaptor_Curve BAcurveFE(FE); + gp_Pnt PointLast = BAcurveFE.Value(ParamLast); + gp_Pnt Origin = Cir->Circ().Location(); + gp_Dir Dir1 = gp_Vec(Origin, PointFirst); + gp_Dir Dir2 = gp_Vec(Origin, PointLast); + gp_Dir Vdir = Dir1 ^ Dir2; + gp_Ax2 anAx2(Origin, Vdir, Dir1); + Handle(Geom_Circle) aNewCircle = new Geom_Circle(anAx2, Cir->Radius()); + gp_Pnt PointLastInChain = BRep_Tool::Pnt(V[1]); + gp_Dir DirLastInChain = gp_Vec(Origin, PointLastInChain); + Standard_Real lpar = Dir1.AngleWithRef(DirLastInChain, Vdir); + if (lpar < 0.) + lpar += 2*M_PI; + + Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(aNewCircle,0.,lpar); B.MakeEdge (E,tc,Precision::Confusion()); B.Add(E,V[0]); B.Add(E,V[1]); - B.UpdateVertex(V[0], fpar, E, 0.); + B.UpdateVertex(V[0], 0., E, 0.); B.UpdateVertex(V[1], lpar, E, 0.); } OutEdge = E; @@ -1476,7 +1473,7 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, TopLoc_Location Loc; Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,Loc,fp1,lp1); if(c3d.IsNull()) continue; - while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { + if (c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d); c3d = tc->BasisCurve(); diff --git a/tests/bugs/heal/bug31778 b/tests/bugs/heal/bug31778 new file mode 100644 index 0000000000..44af20ff4a --- /dev/null +++ b/tests/bugs/heal/bug31778 @@ -0,0 +1,28 @@ +puts "=============================================" +puts "OCC31778: UnifySameDomain fails in Debug mode" +puts "=============================================" +puts "" + +brestore [locate_data_file bug31778.brep] s +explode s +bclearobjects +bcleartools +baddobjects s_1 +baddtools s_2 s_3 +bfillds +bbop q 1 +explode q + +unifysamedom result q_1 + +checkshape result + +checknbshapes result -solid 1 -shell 1 -face 19 -wire 21 -edge 51 -vertex 34 + +set tolres [checkmaxtol result] + +if { ${tolres} > 5.e-5} { + puts "Error: bad tolerance of result" +} + +checkprops result -v 15173.9