From 0cdaa8a4a5910bfae9bd3ed864790c88f24a7109 Mon Sep 17 00:00:00 2001 From: agv Date: Wed, 3 Jul 2019 20:04:16 +0300 Subject: [PATCH] 0030831: ShapeFix algorithm (creation of seam edge) takes too long time with thin faces In class ShapeFix_ComposeShell the U- and V-closedness of input face is taken immediately avoiding the error when the face is small in any of these dimensions. Test case for bug 0030831 --- src/ShapeFix/ShapeFix_ComposeShell.cxx | 48 +++++++++++++++----------- tests/bugs/heal/bug30831 | 12 +++++++ 2 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 tests/bugs/heal/bug30831 diff --git a/src/ShapeFix/ShapeFix_ComposeShell.cxx b/src/ShapeFix/ShapeFix_ComposeShell.cxx index 9eb487d4f0..3d3709e344 100644 --- a/src/ShapeFix/ShapeFix_ComposeShell.cxx +++ b/src/ShapeFix/ShapeFix_ComposeShell.cxx @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include @@ -118,26 +118,32 @@ void ShapeFix_ComposeShell::Init (const Handle(ShapeExtend_CompositeSurface) &Gr // DTK-CKY 100531 : protection against very thin face // Test "isclosed" should be filtered on the overall (non trimmed) surface, must be closed Handle(Geom_Surface) theSurface = BRep_Tool::Surface(Face,myLoc); - Standard_Real U0,U1,V0,V1,GU0 = 0.,GU1 = 0.,GV0 = 0.,GV1 = 0.; - theSurface->Bounds(U0,U1,V0,V1); - if (::Precision::IsInfinite (U0) || ::Precision::IsInfinite (U1) || - ::Precision::IsInfinite (V0) || ::Precision::IsInfinite (V1)) - BRepTools::UVBounds(Face, GU0, GU1, GV0, GV1); - if (myUClosed) { - if (::Precision::IsInfinite (V0)) V0 = GV0; - if (::Precision::IsInfinite (V1)) V1 = GV1; - gp_Pnt P0 = theSurface->Value(U0,(V0+V1)/2.); - gp_Pnt P1 = theSurface->Value(U1,(V0+V1)/2.); - if (P0.Distance(P1) > Precision::Confusion()*10) - myUClosed = Standard_False; - } - if (myVClosed) { - if (::Precision::IsInfinite (U0)) U0 = GU0; - if (::Precision::IsInfinite (U1)) U1 = GU1; - gp_Pnt P0 = theSurface->Value((U0+U1)/2.,V0); - gp_Pnt P1 = theSurface->Value((U0+U1)/2.,V1); - if (P0.Distance(P1) > Precision::Confusion()*10) - myVClosed = Standard_False; + // avoid false detection of 'Closed' on very thin faces + if (theSurface->IsKind(STANDARD_TYPE(Geom_ElementarySurface))) { + myUClosed = myUClosed && theSurface->IsUClosed(); + myVClosed = myVClosed && theSurface->IsVClosed(); + } else { + Standard_Real U0,U1,V0,V1,GU0 = 0.,GU1 = 0.,GV0 = 0.,GV1 = 0.; + theSurface->Bounds(U0,U1,V0,V1); + if (::Precision::IsInfinite (U0) || ::Precision::IsInfinite (U1) || + ::Precision::IsInfinite (V0) || ::Precision::IsInfinite (V1)) + BRepTools::UVBounds(Face, GU0, GU1, GV0, GV1); + if (myUClosed) { + if (::Precision::IsInfinite (V0)) V0 = GV0; + if (::Precision::IsInfinite (V1)) V1 = GV1; + gp_Pnt P0 = theSurface->Value(U0,(V0+V1)/2.); + gp_Pnt P1 = theSurface->Value(U1,(V0+V1)/2.); + if (P0.Distance(P1) > Precision::Confusion()*10) + myUClosed = Standard_False; + } + if (myVClosed) { + if (::Precision::IsInfinite (U0)) U0 = GU0; + if (::Precision::IsInfinite (U1)) U1 = GU1; + gp_Pnt P0 = theSurface->Value((U0+U1)/2.,V0); + gp_Pnt P1 = theSurface->Value((U0+U1)/2.,V1); + if (P0.Distance(P1) > Precision::Confusion()*10) + myVClosed = Standard_False; + } } // DTK-CKY 100531 end diff --git a/tests/bugs/heal/bug30831 b/tests/bugs/heal/bug30831 new file mode 100644 index 0000000000..cd21c66d3b --- /dev/null +++ b/tests/bugs/heal/bug30831 @@ -0,0 +1,12 @@ +puts "========================" +puts "0030831: Shape Healing - ShapeFix algorithm (creation of seam edge) takes too long time with thin faces" +puts "========================" + +cpulimit 10 +binrestore [locate_data_file bug30831.bin] a + +fixshape r a 1.e-7 1. +checkshape r a +tolerance r + +checkview -display r -2d -path ${imagedir}/${test_image}.png