]> OCCT Git - occt-copy.git/commitdiff
0031778: UnifySameDomain fails in Debug mode
authorjgv <jgv@opencascade.com>
Mon, 5 Oct 2020 20:39:08 +0000 (23:39 +0300)
committerjgv <jgv@opencascade.com>
Tue, 6 Oct 2020 19:26:16 +0000 (22:26 +0300)
Correct unification of circular edges: avoid trying to make an axis with null magnitude.

src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx
tests/bugs/heal/bug31778 [new file with mode: 0644]

index 86b2527d5b2daf10c4e905bfc2f3b2b22a36df5d..b18a0933e2e4d008e3fd42cd84cd6d2c860292a6 100644 (file)
@@ -1500,12 +1500,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();
@@ -1572,7 +1572,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();
@@ -1617,7 +1617,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])) {
@@ -1629,37 +1634,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;
@@ -1678,7 +1675,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 (file)
index 0000000..44af20f
--- /dev/null
@@ -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