0026219: ShapeUpgrade_UnifySameDomain fails with StdFail_NotDone exception
authorisn <isn@opencascade.com>
Thu, 25 Jun 2015 11:47:00 +0000 (14:47 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 25 Jun 2015 11:47:54 +0000 (14:47 +0300)
Avoid merging edges if the collapsed vertex has a third connected edge.
Fix the problem when merged edges have different location.
Test case for issue CR26219

Additional fix to improve robustness.

Test cases for issue CR26219

Small correction of test cases for issue CR26219

src/BRepOffsetAPI/BRepOffsetAPI_MiddlePath.cxx
src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx
tests/bugs/heal/bug26219_1 [new file with mode: 0644]
tests/bugs/heal/bug26219_gehause_rohteil [new file with mode: 0644]

index df864df..a18ba9a 100644 (file)
@@ -389,7 +389,10 @@ void BRepOffsetAPI_MiddlePath::Build()
         break;
       }
     }
-    myPaths.Append(Edges);
+    if (!Edges.IsEmpty())
+      myPaths.Append(Edges);
+    else
+      return;
   }
 
   //Filling of "myPaths"
index be8cb60..c140ad1 100644 (file)
@@ -77,6 +77,7 @@
 #include <ShapeFix_Edge.hxx>
 #include <ShapeFix_Shell.hxx>
 #include <ShapeUpgrade_RemoveLocations.hxx>
+#include <TopTools_MapOfShape.hxx>
 
 
 //=======================================================================
@@ -568,11 +569,11 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
   }
   // union edges in chain
   // first step: union lines and circles
-  TopLoc_Location Loc;
   Standard_Real fp1,lp1,fp2,lp2;
   for(j=1; j<aChain.Length(); j++) {
     TopoDS_Edge edge1 = TopoDS::Edge(aChain.Value(j));
-    Handle(Geom_Curve) c3d1 = BRep_Tool::Curve(edge1,Loc,fp1,lp1);
+    Handle(Geom_Curve) c3d1 = BRep_Tool::Curve(edge1,fp1,lp1);
+
     if(c3d1.IsNull()) break;
     while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
       Handle(Geom_TrimmedCurve) tc =
@@ -580,7 +581,7 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
       c3d1 = tc->BasisCurve();
     }
     TopoDS_Edge edge2 = TopoDS::Edge(aChain.Value(j+1));
-    Handle(Geom_Curve) c3d2 = BRep_Tool::Curve(edge2,Loc,fp2,lp2);
+    Handle(Geom_Curve) c3d2 = BRep_Tool::Curve(edge2,fp2,lp2);
     if(c3d2.IsNull()) break;
     while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
       Handle(Geom_TrimmedCurve) tc =
@@ -596,7 +597,7 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
       //if(!Dir1.IsEqual(Dir2,Precision::Angular())) { 
       //if(!Dir1.IsParallel(Dir2,Precision::Angular())) { 
       if(!Dir1.IsParallel(Dir2,Tol)) { 
-        continue;
+        return Standard_False;
       }
       // can union lines => create new edge
       TopoDS_Vertex V1 = sae.FirstVertex(edge1);
@@ -625,7 +626,8 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
       Handle(Geom_Circle) C2 = Handle(Geom_Circle)::DownCast(c3d2);
       gp_Pnt P01 = C1->Location();
       gp_Pnt P02 = C2->Location();
-      if (P01.Distance(P02) > Precision::Confusion()) continue;
+      if (P01.Distance(P02) > Precision::Confusion())
+        return Standard_False;
       // can union circles => create new edge
       TopoDS_Vertex V1 = sae.FirstVertex(edge1);
       gp_Pnt PV1 = BRep_Tool::Pnt(V1);
@@ -634,18 +636,18 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
       TopoDS_Vertex VM = sae.LastVertex(edge1);
       gp_Pnt PVM = BRep_Tool::Pnt(VM);
       GC_MakeCircle MC (PV1,PVM,PV2);
-      Handle(Geom_Circle) C = MC.Value();
       TopoDS_Edge E;
-      if (!MC.IsDone() || C.IsNull()) {
+      if (!MC.IsDone() || MC.Value().IsNull()) {
         // jfa for Mantis issue 0020228
-        if (PV1.Distance(PV2) > Precision::Confusion()) continue;
+        if (PV1.Distance(PV2) > Precision::Confusion())
+          return Standard_False;
         // closed chain
-        C = C1;
-        B.MakeEdge (E,C,Precision::Confusion());
+        B.MakeEdge (E,C1,Precision::Confusion());
         B.Add(E,V1);
         B.Add(E,V2);
       }
       else {
+        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));
@@ -691,6 +693,7 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
     bool NeedUnion = true;
     for(j=1; j<=aChain.Length(); j++) {
       TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j));
+      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))) {
@@ -1181,6 +1184,10 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges()
     // creating map of edge faces
     TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
     TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
+   
+    // creating map of vertex edges
+    TopTools_IndexedDataMapOfShapeListOfShape aMapEdgesVertex;
+    TopExp::MapShapesAndAncestors(aSolid, TopAbs_VERTEX, TopAbs_EDGE, aMapEdgesVertex);
 
     //Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
     TopoDS_Shape aRes = aSolid;
@@ -1218,11 +1225,38 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges()
       for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++) {
         const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
         TopTools_SequenceOfShape SeqEdges;
+        ShapeAnalysis_Edge sae;
         TopTools_ListIteratorOfListOfShape anIter(ListEdges);
-        for ( ; anIter.More(); anIter.Next()) {
+        Standard_Boolean IsSharedVertexPresent = Standard_False;
+        for ( ; anIter.More(); anIter.Next())
           SeqEdges.Append(anIter.Value());
+        if (SeqEdges.Length()==1) 
+          continue;  
+        TopTools_SequenceOfShape SeqVertexes;
+        TopTools_MapOfShape  MapVertexes;
+        for (int k = 1; k <= SeqEdges.Length(); k++ )
+        {
+          TopoDS_Vertex aV1 = sae.FirstVertex(TopoDS::Edge(SeqEdges(k)));
+          TopoDS_Vertex aV2 = sae.LastVertex(TopoDS::Edge(SeqEdges(k)));
+          if (!MapVertexes.Add(aV1))
+            SeqVertexes.Append(aV1);
+          if (!MapVertexes.Add(aV2))
+            SeqVertexes.Append(aV2);
+        }
+
+        for (Standard_Integer k = 1; k <= SeqVertexes.Length() && !IsSharedVertexPresent; k++ )
+        {
+          const TopTools_ListOfShape& ListEdgesV1 = aMapEdgesVertex.FindFromKey(SeqVertexes(k));
+          TopTools_MapOfShape aMapOfEdges;
+          TopTools_ListIteratorOfListOfShape iter(ListEdgesV1);
+          for (; iter.More(); iter.Next())
+            aMapOfEdges.Add(iter.Value());
+          if (aMapOfEdges.Extent() > 2)
+            IsSharedVertexPresent = Standard_True;
         }
-        if (SeqEdges.Length()==1) continue;
+
+        if (IsSharedVertexPresent)
+          continue;
         TopoDS_Edge E;
         if ( MergeEdges(SeqEdges,aFace,Tol,myConcatBSplines,E) ) {
           // now we have only one edge - aChain.Value(1)
diff --git a/tests/bugs/heal/bug26219_1 b/tests/bugs/heal/bug26219_1
new file mode 100644 (file)
index 0000000..62f3373
--- /dev/null
@@ -0,0 +1,48 @@
+puts "========================"
+puts " OCC26219"
+puts "========================"
+puts ""
+###########################################################
+## ShapeUpgrade_UnifySameDomain fails with StdFail_NotDone exception
+###########################################################
+
+restore [locate_data_file bug26219_unifysamedomain.valid_input.brep] p
+
+# -----------------------------------------------------------------------------
+# Attempt to simplify the model
+# -----------------------------------------------------------------------------
+
+set nbshapes_before_simplify "
+Number of shapes in shape
+ VERTEX    : 200
+ EDGE      : 348
+ WIRE      : 150
+ FACE      : 150
+ SHELL     : 1
+ SOLID     : 1
+ COMPSOLID : 0
+ COMPOUND  : 1
+ SHAPE     : 851
+"
+checknbshapes p -ref ${nbshapes_before_simplify} -t -m "result before attempt to simplify the model"
+
+axo; donly p; fit
+xwd ${imagedir}/${casename}_1.png
+
+unifysamedom p p
+
+set nbshapes_after_simplify "
+Number of shapes in shape
+ VERTEX    : 132
+ EDGE      : 196
+ WIRE      : 66
+ FACE      : 66
+ SHELL     : 1
+ SOLID     : 1
+ COMPSOLID : 0
+ COMPOUND  : 1
+ SHAPE     : 463
+"
+checknbshapes p -ref ${nbshapes_after_simplify} -t -m "result after attempt to simplify the model"
+
+xwd ${imagedir}/${casename}_2.png
diff --git a/tests/bugs/heal/bug26219_gehause_rohteil b/tests/bugs/heal/bug26219_gehause_rohteil
new file mode 100644 (file)
index 0000000..244eebb
--- /dev/null
@@ -0,0 +1,294 @@
+# The following example constructs (however, not trying to follow the drawings
+# precisely) an airplane part called Gehause Rohteil from MBB Deutsche Aerospace.
+# In this example the planar geometry is combined together with cylindrical parts.
+# There are many ways to create a single mechanical workpiece like the following
+# one. Here we choose Booleans as a main tool for material cutting. Fillets
+# (presented in the original model) are not employed herein as we are focused
+# on BOPs only. However, Gehause Rohteil is a good model to test blendings as well.
+#
+# This model was used as a test part for comparing modeling systems in 1979 and
+# again in 1983. The tests were organized by Computer Aided Manufacturing
+# International (CAM-I).
+
+# -----------------------------------------------------------------------------
+# Prepare base contour
+# -----------------------------------------------------------------------------
+
+point p1  0  0
+point p2  35 0
+point p3  39 4
+point p4  39 10
+point p5  35 13
+point p6  27 13
+point p7  27 10
+point p8  22 10
+point p9  20 8
+point p10 20 4
+point p11 11 4
+point p12 11 3
+point p13 5  3
+point p14 5  13
+point p15 0  13
+point p16 0  9
+point p17 4  9
+point p18 4  4
+point p19 0  4
+
+line l1 0 0 1 0; trim l1 l1 0 35
+line l2 39 4 0 1; trim l2 l2 0 6
+line l3 35 13 -1 0; trim l3 l3 0 8
+line l4 27 13 0 -1; trim l4 l4 0 3
+line l5 27 10 -1 0; trim l5 l5 0 5
+line l6 20 8 0 -1; trim l6 l6 0 4
+line l7 20 4 -1 0; trim l7 l7 0 9
+line l8 11 4 0 -1; trim l8 l8 0 1
+line l9 11 3 -1 0; trim l9 l9 0 6
+line l10 5 3 0 1; trim l10 l10 0 10
+line l11 5 13 -1 0; trim l11 l11 0 5
+line l12 0 13 0 -1; trim l12 l12 0 4
+line l13 0 9 1 0; trim l13 l13 0 4
+line l14 4 9 0 -1; trim l14 l14 0 5
+line l15 4 4 -1 0; trim l15 l15 0 4
+line l16 0 4 0 -1; trim l16 l16 0 4
+
+# We use Bezier curves here instead of circles. This does not make
+# a great sense since we are focused on a principle rather than
+# trying to follow the drawing precisely
+2dbeziercurve c1 3 35 0 1 39 0 1 39 4 1
+2dbeziercurve c2 3 39 10 1 39 13 1 35 13 1
+2dbeziercurve c3 3 22 10 1 20 10 1 20 8 1
+
+# Circle for a big hole
+circle cbig 33 6.5 4.0
+
+# Create topology
+mkedge e1 l1
+mkedge e2 c1
+mkedge e3 l2
+mkedge e4 c2
+mkedge e5 l3
+mkedge e6 l4
+mkedge e7 l5
+mkedge e8 c3
+mkedge e9 l6
+mkedge e10 l7
+mkedge e11 l8
+mkedge e12 l9
+mkedge e13 l10
+mkedge e14 l11
+mkedge e15 l12
+mkedge e16 l13
+mkedge e17 l14
+mkedge e18 l15
+mkedge e19 l16
+wire wout e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 e12 e13 e14 e15 e16 e17 e18 e19
+mkedge ein1 cbig
+wire win1 ein1
+mkplane f wout
+mkplane f1 win1
+fixshape f f
+fixshape f1 f1
+bcut f f f1
+
+# -----------------------------------------------------------------------------
+# Make extrusion
+# -----------------------------------------------------------------------------
+
+prism p f 0 0 3
+
+# -----------------------------------------------------------------------------
+# Prepare a contour on top face
+# -----------------------------------------------------------------------------
+
+point p1  0  0
+point p2  28 0
+point p3  28 13
+point p4  27 13
+point p5  27 10
+point p6  22 10
+point p7  20 8
+point p8  20 4
+point p9  11 4
+point p10 11 3
+point p11 5  3
+point p12 5  13
+point p13 0  13
+line l1 0 0 1 0; trim l1 l1 0 28
+line l2 28 0 0 1; trim l2 l2 0 13
+line l3 28 13 -1 0; trim l3 l3 0 1
+line l4 27 13 0 -1; trim l4 l4 0 3
+line l5 27 10 -1 0; trim l5 l5 0 5
+line l6 20 8 0 -1; trim l6 l6 0 4
+line l7 20 4 -1 0; trim l7 l7 0 9
+line l8 11 4 0 -1; trim l8 l8 0 1
+line l9 11 3 -1 0; trim l9 l9 0 6
+line l10 5 3 0 1; trim l10 l10 0 10
+line l11 5 13 -1 0; trim l11 l11 0 5
+line l12 0 13 0 -1; trim l12 l12 0 13
+2dbeziercurve c3 3 22 10 1 20 10 1 20 8 1
+
+# Create topology on top face
+plane top_pln 0 0 3
+to3d l1 l1 top_pln
+to3d l2 l2 top_pln
+to3d l3 l3 top_pln
+to3d l4 l4 top_pln
+to3d l5 l5 top_pln
+to3d c3 c3 top_pln
+to3d l6 l6 top_pln
+to3d l7 l7 top_pln
+to3d l8 l8 top_pln
+to3d l9 l9 top_pln
+to3d l10 l10 top_pln
+to3d l11 l11 top_pln
+to3d l12 l12 top_pln
+mkedge e1 l1
+mkedge e2 l2
+mkedge e3 l3
+mkedge e4 l4
+mkedge e5 l5
+mkedge e6 c3
+mkedge e7 l6
+mkedge e8 l7
+mkedge e9 l8
+mkedge e10 l9
+mkedge e11 l10
+mkedge e12 l11
+mkedge e13 l12
+wire wout e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 e12 e13
+mkface ftop top_pln wout
+fixshape ftop ftop
+
+# -----------------------------------------------------------------------------
+# Make top extrusion
+# -----------------------------------------------------------------------------
+
+prism ptop ftop 0 0 1.5
+
+# -----------------------------------------------------------------------------
+# Fuse top and bottom parts and make features
+# -----------------------------------------------------------------------------
+
+# Fuse top and bottom
+bfuse p p ptop
+
+# Create a hole
+plane top_pln 0 0 10
+circle csmall 23 6.5 2.0
+to3d hole_top csmall top_pln
+plane bot_pln 0 0 -10
+to3d hole_bot csmall bot_pln
+mkedge ehole_top hole_top
+mkedge ehole_bot hole_bot
+wire whole_top ehole_top
+wire whole_bot ehole_bot
+thrusections tool 1 1 whole_top whole_bot
+bcut p p tool
+
+# Add extrusion around the hole
+plane top_pln 0 0 4.5
+circle csmall_outer 23 6.5 3.0
+circle csmall_inner 23 6.5 2.0
+to3d hole_top_outer csmall_outer top_pln
+to3d hole_top_inner csmall_inner top_pln
+mkedge e_hole_top_outer hole_top_outer
+mkedge e_hole_top_inner hole_top_inner
+wire w_hole_top_outer e_hole_top_outer
+wire w_hole_top_inner e_hole_top_inner
+mkface ftube_outer top_pln w_hole_top_outer
+mkface ftube_inner top_pln w_hole_top_inner
+fixshape ftube_outer ftube_outer
+fixshape ftube_inner ftube_inner
+prism ptube_outer ftube_outer 0 0 3
+prism ptube_inner ftube_inner 0 0 3
+bcut ptube ptube_outer ptube_inner
+bfuse p p ptube
+
+# Build elevation "teeths" near the big hole
+box t1 26 0 0 3 2.5 7
+box t2 26 13 0 3 -3 7
+bfuse p p t1
+bfuse p p t2
+
+# Build elevation "teeths" near the tail
+box t1 0 0 0 5 3 8
+box t2 0 13 0 5 -3 8
+bfuse p p t1
+bfuse p p t2
+
+# Remove some material from tail "teeths"
+box blend_box 0 -5 0 5 25 5
+trotate blend_box blend_box 0 0 0 0 1 0 -10
+ttranslate blend_box blend_box 2.5 0 2.25
+bcut p p blend_box
+
+# Remove some material from "teeths" near big hole
+box blend_box 0 -5 0 5 25 5
+trotate blend_box blend_box 0 0 0 0 1 0 -9
+ttranslate blend_box blend_box 14.5 0 1.5
+bcut p p blend_box
+
+# Hole at the tail
+ellipse tail_hole1 0 0 0.75 0.5
+plane base_pln 2 6.5 0
+to3d tail_hole_3d1 tail_hole1 base_pln
+mkedge e_tail_hole1 tail_hole_3d1
+wire w_tail_hole1 e_tail_hole1
+plane base_pln 2 6.5 20
+to3d tail_hole_3d2 tail_hole1 base_pln
+mkedge e_tail_hole2 tail_hole_3d2
+wire w_tail_hole2 e_tail_hole2
+thrusections tail_tube 1 1 w_tail_hole1 w_tail_hole2
+bcut p p tail_tube
+
+# Chamfer at tail
+box blend_box 0 3 0 5 7 5
+trotate blend_box blend_box 0 0 0 0 1 0 -5
+ttranslate blend_box blend_box 2 0 1.5
+bcut p p blend_box
+
+# -----------------------------------------------------------------------------
+# Extract final solid
+# -----------------------------------------------------------------------------
+
+explode p So
+renamevar p_1 p
+
+# -----------------------------------------------------------------------------
+# Attempt to simplify the model
+# -----------------------------------------------------------------------------
+
+set nbshapes_before_simplify "
+Number of shapes in shape
+ VERTEX    : 124
+ EDGE      : 211
+ WIRE      : 94
+ FACE      : 87
+ SHELL     : 1
+ SOLID     : 1
+ COMPSOLID : 0
+ COMPOUND  : 0
+ SHAPE     : 518
+"
+checknbshapes p -ref ${nbshapes_before_simplify} -t -m "result before attempt to simplify the model"
+
+axo; donly p; fit
+xwd ${imagedir}/${casename}_1.png
+
+unifysamedom p p
+
+set nbshapes_after_simplify "
+Number of shapes in shape
+ VERTEX    : 85
+ EDGE      : 128
+ WIRE      : 51
+ FACE      : 44
+ SHELL     : 1
+ SOLID     : 1
+ COMPSOLID : 0
+ COMPOUND  : 0
+ SHAPE     : 310
+"
+checknbshapes p -ref ${nbshapes_after_simplify} -t -m "result after attempt to simplify the model"
+
+xwd ${imagedir}/${casename}_2.png