0026635: UnifySameDomain loses internal edges
authormsv <msv@opencascade.com>
Thu, 10 Sep 2015 12:02:41 +0000 (15:02 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 10 Sep 2015 12:03:39 +0000 (15:03 +0300)
Treat internal edges in proper way to save them in the result.

The test "bugs heal bug26489_4" has been modified to reflect the actual behavior.

Test-case for issue #26635

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

index 5b1d742..23d6603 100644 (file)
@@ -85,6 +85,7 @@
 #include <TopTools_SequenceOfShape.hxx>
 #include <gp_Circ.hxx>
 #include <BRepAdaptor_Curve.hxx>
+#include <BRepClass_FaceClassifier.hxx>
 
 struct SubSequenceOfEdges
 {
@@ -1007,6 +1008,37 @@ void ShapeUpgrade_UnifySameDomain::Initialize(const TopoDS_Shape& aShape,
 }
 
 //=======================================================================
+//function : putIntWires
+//purpose  : Add internal wires that are classified inside the face as a subshape,
+//           and remove them from the sequence
+//=======================================================================
+static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWires)
+{
+  TopoDS_Face& aFace = TopoDS::Face(theFace);
+  for (Standard_Integer i=1; i <= theWires.Length(); i++)
+  {
+    TopoDS_Shape aWire = theWires(i);
+    gp_Pnt2d aP2d;
+    Standard_Boolean isP2d = Standard_False;
+    for (TopoDS_Iterator it(aWire); it.More() && !isP2d; it.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(it.Value());
+      Standard_Real aFirst, aLast;
+      Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aFace, aFirst, aLast);
+      aC2d->D0((aFirst + aLast) * 0.5, aP2d);
+      isP2d = Standard_True;
+    }
+    BRepClass_FaceClassifier aClass(aFace, aP2d, Precision::PConfusion());
+    if (aClass.State() == TopAbs_IN)
+    {
+      BRep_Builder().Add(aFace, aWire);
+      theWires.Remove(i);
+      i--;
+    }
+  }
+}
+
+//=======================================================================
 //function : UnifyFaces
 //purpose  : 
 //=======================================================================
@@ -1124,6 +1156,8 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
 
           TopoDS_Edge anEdge = TopoDS::Edge(edges(1));
           edges.Remove(1);
+          // collect internal edges in separate wires
+          Standard_Boolean isInternal = (anEdge.Orientation() == TopAbs_INTERNAL);
 
           isEdge3d |= !BRep_Tool::Degenerated(anEdge);
           B.Add(aWire,anEdge);
@@ -1137,6 +1171,10 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
             isNewFound = Standard_False;
             for(Standard_Integer j = 1; j <= edges.Length(); j++) {
               anEdge = TopoDS::Edge(edges(j));
+              // check if the current edge orientation corresponds to the first one
+              Standard_Boolean isCurrInternal = (anEdge.Orientation() == TopAbs_INTERNAL);
+              if (isCurrInternal != isInternal)
+                continue;
               TopExp::Vertices(anEdge,V1,V2);
               if(aVertices.Contains(V1) || aVertices.Contains(V2)) {
                 isEdge3d |= !BRep_Tool::Degenerated(anEdge);
@@ -1283,13 +1321,26 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
           //CompShell.SetContext( aContext );
           CompShell.SetContext( myContext );
 
-          TopTools_SequenceOfShape parts;
+          TopTools_SequenceOfShape parts, anIntWires;
           ShapeFix_SequenceOfWireSegment wires;
           for(TopExp_Explorer W_Exp(aCurrent,TopAbs_WIRE);W_Exp.More();W_Exp.Next()) {
-            Handle(ShapeExtend_WireData) sbwd =
-              new ShapeExtend_WireData ( TopoDS::Wire(W_Exp.Current() ));
-            ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
-            wires.Append(seg);
+            const TopoDS_Wire& aWire = TopoDS::Wire(W_Exp.Current());
+            // check if the wire is ordinary (contains non-internal edges)
+            Standard_Boolean isInternal = Standard_True;
+            for (TopoDS_Iterator it(aWire); it.More() && isInternal; it.Next())
+              isInternal = (it.Value().Orientation() == TopAbs_INTERNAL);
+            if (isInternal)
+            {
+              // place internal wire separately
+              anIntWires.Append(aWire);
+            }
+            else
+            {
+              Handle(ShapeExtend_WireData) sbwd =
+                new ShapeExtend_WireData (aWire);
+              ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
+              wires.Append(seg);
+            }
           }
 
           CompShell.DispatchWires ( parts,wires );
@@ -1298,10 +1349,12 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
             //aFixOrient.SetContext(aContext);
             aFixOrient.SetContext(myContext);
             aFixOrient.FixOrientation();
+            // put internal wires to faces
+            putIntWires(parts(j), anIntWires);
           }
 
           TopoDS_Shape CompRes;
-          if ( faces.Length() !=1 ) {
+          if ( parts.Length() !=1 ) {
             TopoDS_Shell S;
             B.MakeShell ( S );
             for ( i=1; i <= parts.Length(); i++ )
index 3c48723..5d3af85 100755 (executable)
@@ -39,11 +39,11 @@ Number of shapes in shape
  EDGE      : 4
  WIRE      : 1
  FACE      : 1
- SHELL     : 1
+ SHELL     : 0
  SOLID     : 0
  COMPSOLID : 0
  COMPOUND  : 0
- SHAPE     : 11
+ SHAPE     : 10
 "
 checknbshapes x1 -ref ${nbshapes_expected} -t -m "x1 result provided by the class ShapeUpgrade_UnifySameDomain"
 checknbshapes x2 -ref ${nbshapes_expected} -t -m "x2 result provided by the class ShapeUpgrade_UnifySameDomain"
diff --git a/tests/bugs/heal/bug26635 b/tests/bugs/heal/bug26635
new file mode 100644 (file)
index 0000000..a4db759
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC26635"
+puts "========"
+puts ""
+########################################
+# UnifySameDomain loses internal edges
+########################################
+
+restore [locate_data_file OCC26635_t0.brep] t0
+restore [locate_data_file OCC26635_t1.brep] t1
+restore [locate_data_file OCC26635_t2.brep] t2
+
+bclear
+baddobjects t0 t1
+baddtools t2
+bfillds
+bbop r 1
+
+unifysamedom ru r
+set bug_info [bopargcheck ru #F]
+
+if {$bug_info != "Shape(s) seem(s) to be valid for BOP.\n"} {
+  puts "ERROR: OCC26635 is reproduced."
+}
+