0030052: Data Exchange - STEP import missing surfaces
[occt.git] / src / ShapeFix / ShapeFix_Wire.cxx
index 59334cb..8e407a0 100644 (file)
@@ -394,9 +394,9 @@ Standard_Boolean ShapeFix_Wire::Perform()
     
   if (myFixTailMode != 0)
   {
-    Fixed |= FixTails();
-    if (Fixed)
+    if (FixTails())
     {
+      Fixed =Standard_True;
       FixShifted();
     }
   }
@@ -608,7 +608,7 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
          }
          if ( seq.Length() >0 ) { // supposed that edge is SP
 #ifdef OCCT_DEBUG
-           cout << "Edge going over singularity detected; splitted" << endl;
+           std::cout << "Edge going over singularity detected; splitted" << std::endl;
 #endif
       Standard_Boolean isFwd = ( E.Orientation() == TopAbs_FORWARD );
       E.Orientation ( TopAbs_FORWARD );
@@ -723,7 +723,7 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
        myFixEdge->FixAddPCurve ( sbwd->Edge(overdegen), face, sbwd->IsSeam(overdegen), myAnalyzer->Surface(), Precision());
       }
 #ifdef OCCT_DEBUG
-      cout << "Edge going over singularity detected; pcurve adjusted" << endl;
+      std::cout << "Edge going over singularity detected; pcurve adjusted" << std::endl;
 #endif
     }
   }
@@ -757,7 +757,14 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
           sbwd->Remove ( i-- );
           nb--;
           myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
-          FixConnected (i + 1, Precision());
+          if (i == nb)
+          {
+            FixClosed (Precision());
+          }
+          else
+          {
+            FixConnected (i + 1, Precision());
+          }
         }
        myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL5 );
       }
@@ -794,12 +801,26 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
       if(sae.HasPCurve(sbwd->Edge(i),face)) {
         Handle(Geom2d_Curve) C2d;
         Standard_Real fp2d,lp2d;
-        if(sae.PCurve(sbwd->Edge(i),face,C2d,fp2d,lp2d)) {
+        if(sae.PCurve(sbwd->Edge(i),face,C2d,fp2d,lp2d, Standard_False)) {
           if( fabs(First-fp2d)>Precision::PConfusion() ||
-              fabs(Last-lp2d)>Precision::PConfusion() ) {
+              fabs(Last-lp2d)>Precision::PConfusion()    ) 
+          {
             BRep_Builder B;
             B.SameRange(sbwd->Edge(i),Standard_False);
           }
+          else if(!sae.CheckPCurveRange(First, Last, C2d))
+          {
+            //Replace pcurve
+            TopLoc_Location L;
+            const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
+            ShapeBuild_Edge().RemovePCurve (sbwd->Edge(i),  S, L);
+            myFixEdge->FixAddPCurve ( sbwd->Edge(i), face, sbwd->IsSeam(i), 
+                        myAnalyzer->Surface(), Precision() );
+            if ( myFixEdge->Status ( ShapeExtend_DONE ) ) 
+              myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
+            if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) 
+              myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
+          }
         }
       }
       myFixEdge->FixSameParameter ( sbwd->Edge(i), Face());
@@ -939,7 +960,7 @@ Standard_Boolean ShapeFix_Wire::FixSelfIntersection()
         num = ( myClosedMode ? 1 : 2 );
         nb = sbwd->NbEdges();
 #ifdef OCCT_DEBUG
-        cout << "Warning: ShapeFix_Wire::FixSelfIntersection: Edge removed" << endl;
+        std::cout << "Warning: ShapeFix_Wire::FixSelfIntersection: Edge removed" << std::endl;
 #endif
       }
       else
@@ -975,8 +996,8 @@ Standard_Boolean ShapeFix_Wire::FixSelfIntersection()
     }
 #ifdef OCCT_DEBUG
     if (StatusSelfIntersection (ShapeExtend_DONE5))
-      cout<<"Warning: ShapeFix_Wire::FixIntersection: Non-adjacent intersection fixed (split-"
-        <<NbSplit<<", cut-"<<NbCut<<", removed-"<<NbRemoved<<")"<<endl;
+      std::cout<<"Warning: ShapeFix_Wire::FixIntersection: Non-adjacent intersection fixed (split-"
+        <<NbSplit<<", cut-"<<NbCut<<", removed-"<<NbRemoved<<")"<<std::endl;
 #endif   
 
 /*
@@ -1022,7 +1043,7 @@ Standard_Boolean ShapeFix_Wire::FixSelfIntersection()
       myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
 #ifdef OCCT_DEBUG
     if (StatusSelfIntersection (ShapeExtend_DONE5))
-      cout << "Warning: ShapeFix_Wire::FixSelfIntersection: Non ajacent intersection fixed" << endl;
+      std::cout << "Warning: ShapeFix_Wire::FixSelfIntersection: Non ajacent intersection fixed" << std::endl;
 #endif   
 */
   }
@@ -1367,7 +1388,7 @@ Standard_Boolean ShapeFix_Wire::FixShifted()
       VRange = aBaseCrv->Period();
       IsVCrvClosed = Standard_True;
 #ifdef OCCT_DEBUG
-      cout << "Warning: ShapeFix_Wire::FixShifted set vclosed True for Surface of Revolution" << endl;
+      std::cout << "Warning: ShapeFix_Wire::FixShifted set vclosed True for Surface of Revolution" << std::endl;
 #endif
     }
   }
@@ -1400,7 +1421,7 @@ Standard_Boolean ShapeFix_Wire::FixShifted()
   
   ShapeBuild_Edge sbe;
   Standard_Integer nb = sbwd->NbEdges();
-  Standard_Boolean end = (nb == 0), degstop = Standard_False;;
+  Standard_Boolean end = (nb == 0), degstop = Standard_False;
   Standard_Integer stop = nb;
   Standard_Integer degn2 = 0;
   gp_Pnt pdeg;
@@ -1551,7 +1572,7 @@ Standard_Boolean ShapeFix_Wire::FixShifted()
             }
             myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
 #ifdef OCCT_DEBUG
-            cout << "Info: ShapeFix_Wire::FixShifted(): bi - meridian case fixed" << endl;
+            std::cout << "Info: ShapeFix_Wire::FixShifted(): bi - meridian case fixed" << std::endl;
 #endif
             continue;
           }
@@ -1848,14 +1869,14 @@ static Standard_Boolean RemoveLoop (TopoDS_Edge &E, const TopoDS_Face &face,
     return Standard_False;
 
 #ifdef OCCT_DEBUG
-  cout << "Cut Loop: params (" << t1 << ", " << t2;
+  std::cout << "Cut Loop: params (" << t1 << ", " << t2;
 #endif
   GeomAdaptor_Curve GAC ( crv, f, l );
   Standard_Real dt = tolfact * GAC.Resolution(prec);
   t1 -= dt; //1e-3;//::Precision::PConfusion();
   t2 += dt; //1e-3;//::Precision::PConfusion();
 #ifdef OCCT_DEBUG
-  cout << ") -> (" << t1 << ", " << t2 << ")" << endl;
+  std::cout << ") -> (" << t1 << ", " << t2 << ")" << std::endl;
 #endif
       
   if ( t1 <= a || t2 >= b ) { // should not be so, but to be sure ..
@@ -1925,7 +1946,7 @@ static Standard_Boolean RemoveLoop (TopoDS_Edge &E, const TopoDS_Face &face,
   
     Standard_Real tol = BRep_Tool::Tolerance ( E );
 #ifdef OCCT_DEBUG
-    cout << "Cut Loop: tol orig " << tol << ", prec " << prec << ", new tol " << newtol << endl;
+    std::cout << "Cut Loop: tol orig " << tol << ", prec " << prec << ", new tol " << newtol << std::endl;
 #endif
     if ( newtol > Max ( prec, tol ) ) return Standard_False;
     //:s2  bs = BRep_Tool::CurveOnSurface ( edge, face, a, b );
@@ -2034,7 +2055,7 @@ static Standard_Boolean RemoveLoop (TopoDS_Edge &E, const TopoDS_Face &face,
                                     TopoDS_Edge &E2)
 {
 #ifdef OCCT_DEBUG
-  cout<<"Info: ShapeFix_Wire::FixSelfIntersection : Try insert vertex"<<endl;
+  std::cout<<"Info: ShapeFix_Wire::FixSelfIntersection : Try insert vertex"<<std::endl;
 #endif
 
   if ( BRep_Tool::IsClosed ( E, face ) ) return Standard_False;
@@ -2218,7 +2239,7 @@ Standard_Boolean ShapeFix_Wire::FixSelfIntersectingEdge (const Standard_Integer
 
   if (myRemoveLoopMode<1) {
     for ( Standard_Integer iter=0; iter < 30; iter++ ) { 
-      Standard_Boolean loopRemoved = Standard_False;;
+      Standard_Boolean loopRemoved = Standard_False;
       Standard_Real prevFirst = 0 , prevLast = 0; 
       for ( Standard_Integer i=1; i<=points2d.Length(); i++ ) {
         gp_Pnt pint = points3d.Value(i);
@@ -2463,8 +2484,8 @@ Standard_Boolean ShapeFix_Wire::FixIntersectingEdges (const Standard_Integer num
         if ( BRep_Tool::Tolerance(E1) < te1 || BRep_Tool::Tolerance(E2) < te2 )
         {
 #ifdef OCCT_DEBUG
-          cout << "Warning: ShapeFix_Wire::FixIE: edges tolerance increased: (" <<
-            te1 << ", " << te2 << ") / " << newtol << endl;
+          std::cout << "Warning: ShapeFix_Wire::FixIE: edges tolerance increased: (" <<
+            te1 << ", " << te2 << ") / " << newtol << std::endl;
 #endif
 
           // Make copy of edges.
@@ -2892,9 +2913,9 @@ static Standard_Boolean TryBendingPCurve (const TopoDS_Edge &E, const TopoDS_Fac
 
     if ( ! TryNewPCurve ( E, face, c2d, first, last, tol ) ) return Standard_False;
   }
-  catch ( Standard_Failure ) {
+  catch ( Standard_Failure const& ) {
 #ifdef OCCT_DEBUG
-    cout << "Warning: ShapeFix_Wire::FixLacking: Exception in Geom2d_BSplineCurve::Segment()" << endl;
+    std::cout << "Warning: ShapeFix_Wire::FixLacking: Exception in Geom2d_BSplineCurve::Segment()" << std::endl;
 #endif
     return Standard_False;
   }
@@ -3125,7 +3146,7 @@ Standard_Boolean ShapeFix_Wire::FixLacking (const Standard_Integer num,
     if ( doAddDegen ) {
       myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
 #ifdef OCCT_DEBUG
-      cout << "Warning: ShapeFix_Wire::FixLacking: degenerated edge added" << endl;
+      std::cout << "Warning: ShapeFix_Wire::FixLacking: degenerated edge added" << std::endl;
 #endif
     }
     else if ( ! doAddLong ) {
@@ -3158,7 +3179,7 @@ Standard_Boolean ShapeFix_Wire::FixLacking (const Standard_Integer num,
     FixSelfIntersectingEdge ( n2 );
     FixIntersectingEdges ( n2 ); //skl 24.04.2003 for OCC58
 #ifdef OCCT_DEBUG
-    cout << "Info: ShapeFix_Wire::FixLacking: Bending pcurves" << endl;
+    std::cout << "Info: ShapeFix_Wire::FixLacking: Bending pcurves" << std::endl;
 #endif
     myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
   }
@@ -3204,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;
@@ -3265,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