From 31a5a359bb1bef38ac0e3d1380dcce91e8631958 Mon Sep 17 00:00:00 2001 From: abv Date: Tue, 12 Nov 2019 19:10:14 +0300 Subject: [PATCH] 0031144: Shape Healing - ShapeAnalysis::OuterWire() infinite loop on solid obtained from IFC Implementation of ShapeAnalysis::OuterWire() is revised to avoid infinite cycle if face contains internal vertex. --- src/ShapeAnalysis/ShapeAnalysis.cxx | 36 +++++++++++++++++------------ tests/bugs/mesh/bug31144 | 17 ++++++++++++++ 2 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 tests/bugs/mesh/bug31144 diff --git a/src/ShapeAnalysis/ShapeAnalysis.cxx b/src/ShapeAnalysis/ShapeAnalysis.cxx index fdc65a7b5f..3efe42d207 100644 --- a/src/ShapeAnalysis/ShapeAnalysis.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis.cxx @@ -241,9 +241,10 @@ Standard_Boolean ShapeAnalysis::IsOuterBound(const TopoDS_Face& face) //======================================================================= //function : OuterBound -//purpose : replacement of bad BRepTools::OuterBound() +//purpose : replacement of bad BRepTools::OuterBound(), to be merged +// - skips internal vertices in face, if any, without exception +// - returns positively oriented wire rather than greater one //======================================================================= -//:n3 TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& face) { @@ -251,21 +252,26 @@ TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& face) F.Orientation(TopAbs_FORWARD); BRep_Builder B; - TopoDS_Wire W; - TopoDS_Iterator exp (F, Standard_False); - while ( exp.More() ) { - if(exp.Value().ShapeType() != TopAbs_WIRE) + TopoDS_Iterator anIt (F, Standard_False); + while (anIt.More()) + { + TopoDS_Shape aWire = anIt.Value(); + anIt.Next(); + + // skip possible internal vertices in face + if (aWire.ShapeType() != TopAbs_WIRE) continue; - W = TopoDS::Wire ( exp.Value() ); - exp.Next(); - if ( ! exp.More() ) return W; - //szv#4:S4163:12Mar99 SGI warns - TopoDS_Shape sh = F.EmptyCopied(); - TopoDS_Face fc = TopoDS::Face( sh ); - B.Add ( fc, W ); - if ( ShapeAnalysis::IsOuterBound ( fc ) ) return W; + + // if current wire is the last one, return it without analysis + if (! anIt.More()) + return TopoDS::Wire (aWire); + + TopoDS_Shape aTestFace = F.EmptyCopied(); + B.Add (aTestFace, aWire); + if (ShapeAnalysis::IsOuterBound (TopoDS::Face (aTestFace))) + return TopoDS::Wire (aWire); } - return W; + return TopoDS_Wire(); } //======================================================================= diff --git a/tests/bugs/mesh/bug31144 b/tests/bugs/mesh/bug31144 new file mode 100644 index 0000000000..31f40afbe2 --- /dev/null +++ b/tests/bugs/mesh/bug31144 @@ -0,0 +1,17 @@ +puts "=======" +puts "0031144: Shape Healing - ShapeAnalysis::OuterWire() infinite loop on solid obtained from IFC" +puts "=======" +puts "" +puts "REQUIRED ALL: Meshing statuses: Failure" + +cpulimit 10 + +restore [locate_data_file bug31144.brep] a + +checkshape a +tolerance a + +puts "Note: incmesh is called because this is the only known way to call problematic method" +incmesh a 1. + +trinfo a \ No newline at end of file -- 2.39.5