From 258a844b63a2cca59043dd33eab09e4b588fd8bc Mon Sep 17 00:00:00 2001
From: gka <gka@opencascade.com>
Date: Mon, 16 Sep 2019 16:59:52 +0300
Subject: [PATCH] 0029780: [REGRESSION] Shape Healing - Operator FixShape
 failed with exception

Method ShapeFix_Wire::FixNotchedEdges() is corrected to handle the case of closed notched edges: on such edges split parameter may fall to wrong end of the curve due to projection.
---
 src/Draw/Draw_BasicCommands.cxx |  4 ++--
 src/ShapeFix/ShapeFix_Wire.cxx  | 23 +++++++++++++----------
 tests/bugs/step/bug29780        | 10 ++++++++++
 3 files changed, 25 insertions(+), 12 deletions(-)
 create mode 100644 tests/bugs/step/bug29780

diff --git a/src/Draw/Draw_BasicCommands.cxx b/src/Draw/Draw_BasicCommands.cxx
index 2ef68c331c..4b5e06007b 100644
--- a/src/Draw/Draw_BasicCommands.cxx
+++ b/src/Draw/Draw_BasicCommands.cxx
@@ -490,7 +490,7 @@ static unsigned int __stdcall CpuFunc (void * /*param*/)
       aTimer.Stop();
       if (IsDebuggerPresent())
       {
-        std::cout << "ERROR: CPU limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl;
+        std::cout << "Info: CPU limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl;
         return 0;
       }
       else
@@ -504,7 +504,7 @@ static unsigned int __stdcall CpuFunc (void * /*param*/)
       aTimer.Stop();
       if (IsDebuggerPresent())
       {
-        std::cout << "ERROR: Elapsed limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl;
+        std::cout << "Info: Elapsed limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl;
         return 0;
       }
       else
diff --git a/src/ShapeFix/ShapeFix_Wire.cxx b/src/ShapeFix/ShapeFix_Wire.cxx
index 0152fef800..b1d8eb45cb 100644
--- a/src/ShapeFix/ShapeFix_Wire.cxx
+++ b/src/ShapeFix/ShapeFix_Wire.cxx
@@ -3225,12 +3225,21 @@ Standard_Boolean ShapeFix_Wire::FixNotchedEdges()
       Handle(Geom2d_Curve) c2d;
       Standard_Real a, b;
       sae.PCurve ( splitE, face, c2d, a, b, Standard_True );
-      Standard_Real ppar = (isRemoveFirst ? b : a);
       ShapeBuild_Edge sbe;
       TopAbs_Orientation orient = splitE.Orientation();
-      if ( Abs(param - ppar) > ::Precision::PConfusion() ) {
-	//pdn perform splitting of the edge and adding to wire
-	
+
+      // check whether the whole edges should be removed - this is the case
+      // when split point coincides with the end of the edge;
+      // for closed edges split point may fall at the other end (see issue #0029780)
+      if (Abs(param - (isRemoveFirst ? b : a)) <= ::Precision::PConfusion() ||
+          (sae.IsClosed3d(splitE) && Abs(param - (isRemoveFirst ? a : b)) <= ::Precision::PConfusion()))
+      {
+        FixDummySeam(n1);
+        // The seam edge is removed from the list. So, need to step back to avoid missing of edge processing
+        i--;
+      }
+      else // perform splitting of the edge and adding to wire
+      {
 	//pdn check if it is necessary
 	if( Abs((isRemoveFirst ? a : b)-param) < ::Precision::PConfusion() ) {
 	  continue;
@@ -3286,12 +3295,6 @@ Standard_Boolean ShapeFix_Wire::FixNotchedEdges()
 	FixDummySeam(isRemoveLast ? NbEdges() : toRemove);
 	myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
       }
-      else 
-      {
-        FixDummySeam(n1);
-        // The seam edge is removed from the list. So, need to step back to avoid missing of edge processing
-        i--;
-      }
   
       i--;
       if(!Context().IsNull()) //skl 07.03.2002 for OCC180
diff --git a/tests/bugs/step/bug29780 b/tests/bugs/step/bug29780
new file mode 100644
index 0000000000..9268812b21
--- /dev/null
+++ b/tests/bugs/step/bug29780
@@ -0,0 +1,10 @@
+puts "========================"
+puts "0029780 "
+puts "========================"
+
+
+stepread [locate_data_file bug29780.stp] a *
+
+checkshape a_1
+checknbshapes a_1 -shell 1 -face 244
+checkview -display result -2d -path ${imagedir}/${test_image}.png