From 3e6a4cd02a78598a240a290e955b1d5ca369a991 Mon Sep 17 00:00:00 2001 From: ssv Date: Thu, 5 May 2016 18:01:02 +0300 Subject: [PATCH] 0027463: BRepTools_ReShape ends up with empty shapes 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 | 39 ++++++++----- src/SWDRAW/SWDRAW_ShapeUpgrade.cxx | 89 +++++++++++++++++++++++++++++ tests/heal/grids.list | 1 + tests/heal/reshape/A1 | 64 +++++++++++++++++++++ tests/heal/reshape/begin | 4 ++ tests/heal/reshape/end | 5 ++ 6 files changed, 189 insertions(+), 13 deletions(-) create mode 100644 tests/heal/reshape/A1 create mode 100644 tests/heal/reshape/begin create mode 100644 tests/heal/reshape/end diff --git a/src/BRepTools/BRepTools_ReShape.cxx b/src/BRepTools/BRepTools_ReShape.cxx index c34c0824a8..c59bdf7a8d 100644 --- a/src/BRepTools/BRepTools_ReShape.cxx +++ b/src/BRepTools/BRepTools_ReShape.cxx @@ -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; } diff --git a/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx b/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx index a6fd1a973b..45c39fd7e1 100644 --- a/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx +++ b/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -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); } diff --git a/tests/heal/grids.list b/tests/heal/grids.list index 574cf5ef37..70e7179bc5 100644 --- a/tests/heal/grids.list +++ b/tests/heal/grids.list @@ -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 index 0000000000..a7531857fe --- /dev/null +++ b/tests/heal/reshape/A1 @@ -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 index 0000000000..e063bde0d4 --- /dev/null +++ b/tests/heal/reshape/begin @@ -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 index 0000000000..e94d7ebd69 --- /dev/null +++ b/tests/heal/reshape/end @@ -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 -- 2.20.1