From 59223e118db73b4b7dcaa45639f13287f8a48f59 Mon Sep 17 00:00:00 2001 From: oan Date: Wed, 31 Aug 2022 17:40:33 +0300 Subject: [PATCH] 0031926: Shape Healing - ShapeAnalysis::OuterWire() considers next iteration element always to be a wire causing skipping of primal one ShapeAnalysis::OuterWire(): fixed missed logic when TopoDS_Iterator notifies about more objects to iterate, but there are only vertices and no additional wires at all. --- src/ShapeAnalysis/ShapeAnalysis.cxx | 35 +++++++++++--------------- src/ShapeAnalysis/ShapeAnalysis.hxx | 9 +++---- tests/bugs/mesh/bug31144 | 1 - tests/bugs/mesh/bug31926 | 39 +++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 tests/bugs/mesh/bug31926 diff --git a/src/ShapeAnalysis/ShapeAnalysis.cxx b/src/ShapeAnalysis/ShapeAnalysis.cxx index 6e18ddd42c..5517a17b35 100644 --- a/src/ShapeAnalysis/ShapeAnalysis.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis.cxx @@ -229,36 +229,31 @@ Standard_Boolean ShapeAnalysis::IsOuterBound(const TopoDS_Face& face) } //======================================================================= -//function : 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 +//function : OuterWire +//purpose : Returns positively oriented wire in the face. +// If there is no one - returns the last wire of the face. //======================================================================= -TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& face) +TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& theFace) { - TopoDS_Face F = face; - F.Orientation(TopAbs_FORWARD); + TopoDS_Face aF = theFace; + aF.Orientation (TopAbs_FORWARD); - BRep_Builder B; - TopoDS_Iterator anIt (F, Standard_False); + TopExp_Explorer anIt (aF, TopAbs_WIRE); while (anIt.More()) { - TopoDS_Shape aWire = anIt.Value(); + TopoDS_Wire aWire = TopoDS::Wire (anIt.Value()); anIt.Next(); - // skip possible internal vertices in face - if (aWire.ShapeType() != TopAbs_WIRE) - continue; - // if current wire is the last one, return it without analysis - if (! anIt.More()) - return TopoDS::Wire (aWire); + if (!anIt.More()) + return aWire; - TopoDS_Shape aTestFace = F.EmptyCopied(); - B.Add (aTestFace, aWire); - if (ShapeAnalysis::IsOuterBound (TopoDS::Face (aTestFace))) - return TopoDS::Wire (aWire); + // Check if the wire has positive area + Handle(ShapeExtend_WireData) aSEWD = new ShapeExtend_WireData (aWire); + Standard_Real anArea2d = ShapeAnalysis::TotCross2D (aSEWD, aF); + if (anArea2d >= 0.) + return aWire; } return TopoDS_Wire(); } diff --git a/src/ShapeAnalysis/ShapeAnalysis.hxx b/src/ShapeAnalysis/ShapeAnalysis.hxx index be6f228ab5..fc6bdccdd4 100644 --- a/src/ShapeAnalysis/ShapeAnalysis.hxx +++ b/src/ShapeAnalysis/ShapeAnalysis.hxx @@ -51,12 +51,9 @@ public: DEFINE_STANDARD_ALLOC - //! Returns the outer wire on the face . - //! This is replacement of the method BRepTools::OuterWire - //! until it works badly. - //! Returns the first wire oriented as outer according to - //! FClass2d_Classifier. If none, last wire is returned. - Standard_EXPORT static TopoDS_Wire OuterWire (const TopoDS_Face& face); + //! Returns positively oriented wire in the face. + //! If there is no such wire - returns the last wire of the face. + Standard_EXPORT static TopoDS_Wire OuterWire (const TopoDS_Face& theFace); //! Returns a total area of 2d wire Standard_EXPORT static Standard_Real TotCross2D (const Handle(ShapeExtend_WireData)& sewd, const TopoDS_Face& aFace); diff --git a/tests/bugs/mesh/bug31144 b/tests/bugs/mesh/bug31144 index 31f40afbe2..173e6403a7 100644 --- a/tests/bugs/mesh/bug31144 +++ b/tests/bugs/mesh/bug31144 @@ -2,7 +2,6 @@ puts "=======" puts "0031144: Shape Healing - ShapeAnalysis::OuterWire() infinite loop on solid obtained from IFC" puts "=======" puts "" -puts "REQUIRED ALL: Meshing statuses: Failure" cpulimit 10 diff --git a/tests/bugs/mesh/bug31926 b/tests/bugs/mesh/bug31926 new file mode 100644 index 0000000000..edc55f2e0f --- /dev/null +++ b/tests/bugs/mesh/bug31926 @@ -0,0 +1,39 @@ +puts "========" +puts "0031926: Shape Healing - ShapeAnalysis::OuterWire() considers next iteration element always to be a wire causing skipping of primal one" +puts "========" +puts "" + +vertex v11 0 1 0; vertex v12 1 0 0; vertex v13 0 0 0 +edge e11 v11 v12; edge e12 v12 v13; edge e13 v13 v11 +wire w1 e11 e12 e13 +mkplane f1 w1 + +vertex v21 0 0 2; vertex v22 1 0 0; vertex v23 0 0 0 +edge e21 v21 v22; edge e22 v22 v23; edge e23 v23 v21 +wire w2 e21 e22 e23 +mkplane f2 w2 + +vertex v31 0 0 2; vertex v32 0 1 0; vertex v33 1 0 0 +edge e31 v31 v32; edge e32 v32 v33; edge e33 v33 v31 +wire w3 e31 e32 e33 +mkplane f3 w3 + +vertex v41 0 0 2; vertex v42 0 0 0; vertex v43 0 1 0 +edge e41 v41 v42; edge e42 v42 v43; edge e43 v43 v41 +wire w4 e41 e42 e43 +mkplane f4 w4 + +psphere s1 1 +sewing sh2 f1 f2 f3 f4 +ssolid sh2 s2 +bcut result s1 s2 +incmesh result 1 + +checkview -display result -3d -path ${imagedir}/${test_image}.png + +set log [tricheck result] +if { [llength $log] != 0 } { + puts "Error : Invalid mesh" +} else { + puts "Mesh is OK" +}