0027463: BRepTools_ReShape ends up with empty shapes
authorssv <ssv@opencascade.com>
Thu, 5 May 2016 15:01:02 +0000 (18:01 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 12 May 2016 09:02:49 +0000 (12:02 +0300)
Add check on empty topological containers.

Add empty shapes to the replacement map.

Add Draw command for Re-Shape.

Add a test grid for reshape with a single use case for starters.

src/BRepTools/BRepTools_ReShape.cxx
src/SWDRAW/SWDRAW_ShapeUpgrade.cxx
tests/heal/grids.list
tests/heal/reshape/A1 [new file with mode: 0644]
tests/heal/reshape/begin [new file with mode: 0644]
tests/heal/reshape/end [new file with mode: 0644]

index c34c082..c59bdf7 100644 (file)
@@ -495,18 +495,21 @@ TopoDS_Shape BRepTools_ReShape::Apply (const TopoDS_Shape& shape,
   Standard_Integer locStatus = myStatus;
   
   // apply recorded modifications to subshapes
+  Standard_Boolean isEmpty = Standard_True;
   for ( TopoDS_Iterator it(shape,Standard_False); it.More(); it.Next() ) {
     TopoDS_Shape sh = it.Value();
     newsh = Apply ( sh, until );
     if ( newsh != sh ) {
       if ( myStatus & EncodeStatus(4)) //ShapeExtend::DecodeStatus ( myStatus, ShapeExtend_DONE4 ) )
-       locStatus |= EncodeStatus(4); //|= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
+        locStatus |= EncodeStatus(4); //|= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
       modif = 1;
     }
     if ( newsh.IsNull() ) {
       locStatus |= EncodeStatus(4); //ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
       continue;
     }
+    if ( isEmpty )
+      isEmpty = Standard_False;
     locStatus |= EncodeStatus(3);//ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
     if ( st == TopAbs_COMPOUND || newsh.ShapeType() == sh.ShapeType()) { //fix for SAMTECH bug OCC322 about abcense internal vertices after sewing.
       B.Add ( result, newsh );
@@ -522,23 +525,33 @@ TopoDS_Shape BRepTools_ReShape::Apply (const TopoDS_Shape& shape,
   }
   if ( ! modif ) return shape;
 
-  // restore Range on edge broken by EmptyCopied()
-  if ( st == TopAbs_EDGE ) {
-    CopyRanges (result, shape, 0, 1);
+  // For empty topological containers (any kind of shape except vertex, edge
+  // and face) we have to produce an empty result
+  if ( isEmpty && st != TopAbs_VERTEX && st != TopAbs_EDGE && st != TopAbs_FACE )
+  {
+    result = TopoDS_Shape();
   }
-  else if (st == TopAbs_FACE)  {
-    TopoDS_Face face = TopoDS::Face ( shape );
-    if( BRep_Tool::NaturalRestriction( face ) ) {
-      BRep_Builder aB;
-      aB.NaturalRestriction( TopoDS::Face (  result ), Standard_True );
+  else
+  {
+    // restore Range on edge broken by EmptyCopied()
+    if ( st == TopAbs_EDGE ) {
+      CopyRanges (result, shape, 0, 1);
+    }
+    else if (st == TopAbs_FACE)  {
+      TopoDS_Face face = TopoDS::Face ( shape );
+      if( BRep_Tool::NaturalRestriction( face ) ) {
+        BRep_Builder aB;
+        aB.NaturalRestriction( TopoDS::Face (  result ), Standard_True );
+      }
     }
+    else if (st == TopAbs_WIRE || st == TopAbs_SHELL)
+      result.Closed (BRep_Tool::IsClosed (result));
+
+    result.Orientation(orien);
   }
-  else if (st == TopAbs_WIRE || st == TopAbs_SHELL)
-    result.Closed (BRep_Tool::IsClosed (result));
 
-  result.Orientation(orien);
-  myStatus = locStatus;
   Replace ( shape, result );
+  myStatus = locStatus;
 
   return result;
 }
index a6fd1a9..45c39fd 100644 (file)
@@ -22,6 +22,7 @@
 #include <BRepBuilderAPI.hxx>
 #include <BRepBuilderAPI_Transform.hxx>
 #include <BRepTools.hxx>
+#include <BRepTools_ReShape.hxx>
 #include <DBRep.hxx>
 #include <Draw.hxx>
 #include <Draw_Interpretor.hxx>
@@ -1376,6 +1377,87 @@ static Standard_Integer copytranslate(Draw_Interpretor& di,
   
 }
 
+Standard_Integer reshape(Draw_Interpretor& di,
+                         Standard_Integer n,
+                         const char** a)
+{
+  if ( n < 3 )
+  {
+    di << "Error: wrong number of arguments. Type 'help " << a[0] << "'\n";
+    return 1;
+  }
+
+  TopoDS_Shape source = DBRep::Get(a[2]);
+  if ( source.IsNull() )
+  {
+    di << "Error: source shape ('" << a[2] << "') is null\n";
+    return 1;
+  }
+
+  Handle(BRepTools_ReShape) ReShaper = new BRepTools_ReShape;
+
+  // Record the requested modifications
+  for ( Standard_Integer i = 1; i < n; ++i )
+  {
+    Standard_CString        arg = a[i];
+    TCollection_AsciiString opt(arg);
+    opt.LowerCase();
+
+    if ( opt == "-replace" )
+    {
+      if ( n - i < 3 )
+      {
+        di << "Error: not enough arguments for replacement\n";
+        return 1;
+      }
+
+      TopoDS_Shape what = DBRep::Get(a[++i]);
+      if ( what.IsNull() )
+      {
+        di << "Error: argument shape ('" << a[i] << "') is null\n";
+        return 1;
+      }
+
+      TopoDS_Shape with = DBRep::Get(a[++i]);
+      if ( with.IsNull() )
+      {
+        di << "Error: replacement shape ('" << a[i] << "') is null\n";
+        return 1;
+      }
+
+      ReShaper->Replace(what, with);
+    }
+    else if ( opt == "-remove" )
+    {
+      if ( n - i < 2 )
+      {
+        di << "Error: not enough arguments for removal\n";
+        return 1;
+      }
+
+      TopoDS_Shape what = DBRep::Get(a[++i]);
+      if ( what.IsNull() )
+      {
+        di << "Error: shape to remove ('" << a[i] << "') is null\n";
+        return 1;
+      }
+
+      ReShaper->Remove(what);
+    }
+  }
+
+  // Apply all the recorded modifications
+  TopoDS_Shape result = ReShaper->Apply(source);
+  if ( result.IsNull() )
+  {
+    di << "Error: result shape is null\n";
+    return 1;
+  }
+
+  DBRep::Set(a[1], result);
+  return 0;
+}
+
 //=======================================================================
 //function : InitCommands
 //purpose  : 
@@ -1482,4 +1564,11 @@ static Standard_Integer copytranslate(Draw_Interpretor& di,
                    __FILE__,unifysamedomgen,g);
   
   theCommands.Add ("copytranslate","result shape dx dy dz",__FILE__,copytranslate,g);
+
+  theCommands.Add ("reshape",
+    "\n    Basic utility for topological modification: "
+    "\n      '-replace what with'   Replaces 'what' sub-shape with 'with' sub-shape"
+    "\n      '-remove what'         Removes 'what' sub-shape"
+    "\n    Requests '-replace' and '-remove' can be repeated many times.",
+    __FILE__, reshape, g);
 }
index 574cf5e..70e7179 100644 (file)
@@ -19,3 +19,4 @@
 019 drop_small_solids
 020 wire_tails_composed
 021 wire_tails_real
+022 reshape
diff --git a/tests/heal/reshape/A1 b/tests/heal/reshape/A1
new file mode 100644 (file)
index 0000000..a753185
--- /dev/null
@@ -0,0 +1,64 @@
+restore [locate_data_file bug26243_anc101.brep] model
+
+#-----------------------------------------------------------------------------#
+# Prepare feature faces
+#-----------------------------------------------------------------------------#
+
+explode model f
+
+set hole_bottom_faces {35 36 37 38 39 40 41 42 43}
+set hole_side_faces {11 12 13 14 15 16 17 18 19}
+
+set feature_faces [concat $hole_bottom_faces $hole_side_faces]
+
+#-----------------------------------------------------------------------------#
+# Prepare the argument list for suppression
+#-----------------------------------------------------------------------------#
+
+set request ""
+foreach fidx $feature_faces {
+
+  renamevar model_${fidx} feature_face_${fidx}
+  set request [concat $request " -remove feature_face_${fidx}"]
+
+  set wires [explode feature_face_${fidx} w]
+  set widx 0
+  foreach w $wires {
+    incr widx
+    renamevar $w feature_wire_${fidx}_${widx}
+    set request [concat $request " -remove feature_wire_${fidx}_${widx}"]
+  }
+
+  set edges [explode feature_face_${fidx} e]
+  set eidx 0
+  foreach e $edges {
+    incr eidx
+    renamevar $e feature_edge_${fidx}_${eidx}
+    set request [concat $request " -remove feature_edge_${fidx}_${eidx}"]
+  }
+
+  set vertices [explode feature_face_${fidx} v]
+  set vidx 0
+  foreach v $vertices {
+    incr vidx
+    renamevar $v feature_vertex_${fidx}_${vidx}
+    set request [concat $request " -remove feature_vertex_${fidx}_${vidx}"]
+  }
+}
+
+set request [concat "reshape result model" $request]
+
+#-----------------------------------------------------------------------------#
+# Re-Shape!
+#-----------------------------------------------------------------------------#
+
+eval $request
+
+#-----------------------------------------------------------------------------#
+# Set reference counts for topological entities (the ones expected)
+#-----------------------------------------------------------------------------#
+
+set ref_num_faces    86
+set ref_num_wires    107
+set ref_num_edges    201
+set ref_num_vertices 121
diff --git a/tests/heal/reshape/begin b/tests/heal/reshape/begin
new file mode 100644 (file)
index 0000000..e063bde
--- /dev/null
@@ -0,0 +1,4 @@
+set ref_num_faces    0
+set ref_num_wires    0
+set ref_num_edges    0
+set ref_num_vertices 0
diff --git a/tests/heal/reshape/end b/tests/heal/reshape/end
new file mode 100644 (file)
index 0000000..e94d7eb
--- /dev/null
@@ -0,0 +1,5 @@
+if { [isdraw result] } {
+  puts [checkshape result]
+}
+
+checknbshapes result -face $ref_num_faces -wire $ref_num_wires -edge $ref_num_edges -vertex $ref_num_vertices