0025712: Non-deterministic behavior of ShapeFix_Solid
authorRoman Lygin <roman.lygin@gmail.com>
Thu, 29 Jan 2015 10:56:53 +0000 (13:56 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 29 Jan 2015 10:58:05 +0000 (13:58 +0300)
Test-case for issue #25712

src/BRepTools/BRepTools_ReShape.cdl
src/ShapeBuild/ShapeBuild_ReShape.cdl
src/ShapeFix/ShapeFix_Solid.cxx
tests/bugs/heal/bug25712 [new file with mode: 0644]

index 7c2a8d3..639e2d9 100644 (file)
@@ -39,27 +39,31 @@ is
     Create returns ReShape from BRepTools;
        ---Purpose: Returns an empty Reshape
 
-    Clear (me: mutable);
+    Clear (me: mutable) is virtual;
        ---Purpose: Clears all substitutions requests
 
     Remove (me: mutable; shape: Shape from TopoDS;
-           oriented: Boolean = Standard_False);
+           oriented: Boolean = Standard_False)
+       is virtual;
        ---Purpose: Sets a request to Remove a Shape
        --          If <oriented> is True, only for a shape with the SAME
        --          orientation. Else, whatever the orientation
 
     Replace (me: mutable; shape, newshape: Shape from TopoDS;
-            oriented: Boolean = Standard_False);
+            oriented: Boolean = Standard_False)
+       is virtual;
        ---Purpose: Sets a request to Replace a Shape by a new one
        --          If <oriented> is True, only if the orientation is the same
        --          Else, whatever the orientation, and the new shape takes the
        --          same orientation as <newshape> if the replaced one has the
        --          same as <shape>, else it is reversed
 
-    IsRecorded (me; shape: Shape from TopoDS) returns Boolean;
+    IsRecorded (me; shape: Shape from TopoDS)
+       returns Boolean is virtual;
        ---Purpose: Tells if a shape is recorded for Replace/Remove
 
-    Value (me; shape: Shape from TopoDS) returns Shape from TopoDS;
+    Value (me; shape: Shape from TopoDS)
+       returns Shape from TopoDS is virtual;
        ---Purpose: Returns the new value for an individual shape
        --          If not recorded, returns the original shape itself
        --          If to be Removed, returns a Null Shape
@@ -107,12 +111,14 @@ is
        --          If incompatible shape type is encountered, it is ignored
        --          and flag FAIL1 is set in Status.
     
-    ModeConsiderLocation(me: mutable) returns Boolean;
+    ModeConsiderLocation(me: mutable)
+       returns Boolean is virtual;
     ---C++: return &
     ---Purpose:Returns (modifiable) the flag which defines whether Location of shape take into account
     --         during replacing shapes.
 
-    ModeConsiderOrientation(me: mutable) returns Boolean;
+    ModeConsiderOrientation(me: mutable)
+       returns Boolean is virtual;
     ---C++: return &
     ---Purpose:Returns (modifiable) the flag which defines whether Orientation of shape take into account
     --         during replacing shapes.
index f25a1db..170691b 100644 (file)
@@ -81,7 +81,7 @@ is
        --          the map directly for the shape, if True and status > 0 then
        --          recursively searches for the last status and new shape.
 
-    Status (me; status: Status from ShapeExtend) returns Boolean;
+    Status (me; status: Status from ShapeExtend) returns Boolean is virtual;
        ---Purpose: Queries the status of last call to Apply(shape,enum)
        --          OK   : no (sub)shapes replaced or removed
        --          DONE1: source (starting) shape replaced
index 7d14865..cdd009c 100644 (file)
@@ -140,10 +140,11 @@ static void GetMiddlePoint(const TopoDS_Shape& aShape, gp_Pnt& pmid)
 //purpose  : 
 //=======================================================================
 static void CollectSolids(const TopTools_SequenceOfShape& aSeqShells , 
-                          TopTools_DataMapOfShapeListOfShape& aMapShellHoles,
+                          TopTools_IndexedDataMapOfShapeListOfShape& anIndexedMapShellHoles,
                           TopTools_DataMapOfShapeInteger& theMapStatus)
 {
   TopTools_MapOfShape aMapHoles;
+  TopTools_DataMapOfShapeListOfShape aMapShellHoles;
   for ( Standard_Integer i1 = 1; i1 <= aSeqShells.Length(); i1++ ) {
     TopoDS_Shell aShell1 = TopoDS::Shell(aSeqShells.Value(i1));
     TopTools_ListOfShape lshells;
@@ -244,8 +245,15 @@ static void CollectSolids(const TopTools_SequenceOfShape& aSeqShells ,
     }
   }
   for(TopTools_MapIteratorOfMapOfShape aIterHoles(aMapHoles);aIterHoles.More(); aIterHoles.Next())
-    aMapShellHoles.UnBind(aIterHoles.Key());
-    
+    aMapShellHoles.UnBind (aIterHoles.Key());
+
+  for (Standard_Integer i = 1; i <= aSeqShells.Length(); ++i) {
+    const TopoDS_Shape& aShell1 = aSeqShells.Value (i);
+    if (aMapShellHoles.IsBound (aShell1)) {
+      const TopTools_ListOfShape& ls = aMapShellHoles.Find (aShell1);
+      anIndexedMapShellHoles.Add (aShell1, ls);
+    }
+  }
 }
 //=======================================================================
 //function : CreateSolids
@@ -260,14 +268,13 @@ static Standard_Boolean CreateSolids(const TopoDS_Shape aShape,TopTools_IndexedM
   for(TopExp_Explorer aExpShell(aShape,TopAbs_SHELL); aExpShell.More(); aExpShell.Next()) {
     aSeqShells.Append(aExpShell.Current());
   }
-  TopTools_DataMapOfShapeListOfShape aMapShellHoles;
+  TopTools_IndexedDataMapOfShapeListOfShape aMapShellHoles;
   TopTools_DataMapOfShapeInteger aMapStatus;
   CollectSolids(aSeqShells,aMapShellHoles,aMapStatus);
   TopTools_IndexedDataMapOfShapeShape ShellSolid;
-  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItShellHoles( aMapShellHoles);
   //Defines correct orientation of shells
-  for(; aItShellHoles.More();aItShellHoles.Next()) {
-    TopoDS_Shell aShell = TopoDS::Shell(aItShellHoles.Key());
+  for (Standard_Integer i = 1; i <= aMapShellHoles.Extent(); ++i) {
+    TopoDS_Shell aShell = TopoDS::Shell(aMapShellHoles.FindKey(i));
     TopExp_Explorer aExpEdges(aShell,TopAbs_EDGE);
     if(!BRep_Tool::IsClosed(aShell) || !aExpEdges.More()) {
       ShellSolid.Add(aShell,aShell);
@@ -311,7 +318,7 @@ static Standard_Boolean CreateSolids(const TopoDS_Shape aShape,TopTools_IndexedM
     aSolid = aTmpSolid;
   }
     
-    const TopTools_ListOfShape& lHoles = aItShellHoles.Value();
+    const TopTools_ListOfShape& lHoles = aMapShellHoles (i);
     for(TopTools_ListIteratorOfListOfShape lItHoles(lHoles); lItHoles.More();lItHoles.Next()) {
       TopoDS_Shell aShellHole = TopoDS::Shell(lItHoles.Value());
       if(aMapStatus.IsBound(aShellHole)) {
diff --git a/tests/bugs/heal/bug25712 b/tests/bugs/heal/bug25712
new file mode 100644 (file)
index 0000000..7e06e2e
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC25712"
+puts "========"
+puts ""
+################################################
+# Non-deterministic behavior of ShapeFix_Solid
+################################################
+
+set OK_shapes_1 177
+set OK_shapes_2 9
+
+for {set i 1} {$i <= 100} {incr i} {
+  restore [locate_data_file OCC25712_comp16.brep] c
+  fixshape rc c
+  explode rc
+  explode rc_2
+  set bug_info_1 [numshapes rc_2_1]
+  set bug_info_2 [numshapes rc_2_2]
+  if {[lindex $bug_info_1 31] != $OK_shapes_1} {
+    puts "ERROR: OCC25712 is reprodced. rc_2_1 should has $OK_shapes_1 shapes, but has [lindex $bug_info_1 31] shapes."
+  }
+  if {[lindex $bug_info_2 31] != $OK_shapes_2} {
+    puts "ERROR: OCC25712 is reprodced. rc_2_2 should has $OK_shapes_2 shapes, but has [lindex $bug_info_2 31] shapes."
+  }
+}