0030052: Data Exchange - STEP import missing surfaces
[occt.git] / src / ShapeFix / ShapeFix_Wire.cxx
index 9f0ca22..8e407a0 100644 (file)
 //                one pcurve we make replace pcurve)
 // PTV 26.06.2002  Remove regressions after fix OCC450
 
-#include <ShapeFix_Wire.ixx>
-
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <Precision.hxx>
-
-#include <Geom_Curve.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom_BSplineCurve.hxx>
-#include <Geom_SphericalSurface.hxx> //S4135
-#include <Geom_SurfaceOfRevolution.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <GeomAdaptor_HSurface.hxx>
-#include <GeomAdaptor_Surface.hxx>  
-#include <GeomConvert_CompCurveToBSplineCurve.hxx>
-#include <GeomAPI.hxx>
-
-#include <Geom2d_Curve.hxx>
-#include <Geom2d_TrimmedCurve.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom2d_BSplineCurve.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <Geom2dConvert.hxx>
-
-#include <Bnd_Box2d.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
 #include <Bnd_Array1OfBox2d.hxx>
+#include <Bnd_Box2d.hxx>
 #include <BndLib_Add2dCurve.hxx>
-#include <IntRes2d_SequenceOfIntersectionPoint.hxx>
-#include <IntRes2d_IntersectionPoint.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColgp_SequenceOfPnt.hxx>
-#include <gp_Pln.hxx>
-
-#include <TopoDS.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopTools_Array1OfShape.hxx>
-#include <TopTools_HSequenceOfShape.hxx>
-#include <TopExp_Explorer.hxx>
-
-#include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
+#include <BRep_GCurve.hxx>
 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
 #include <BRep_TEdge.hxx>
-#include <BRep_GCurve.hxx>
+#include <BRep_Tool.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
 #include <BRepTools.hxx>
-
+#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <Geom2dConvert.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_OffsetCurve.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_SurfaceOfRevolution.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <GeomAPI.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomConvert_CompCurveToBSplineCurve.hxx>
+#include <gp_Pln.hxx>
+#include <IntRes2d_IntersectionPoint.hxx>
+#include <IntRes2d_SequenceOfIntersectionPoint.hxx>
 #include <Message_Msg.hxx>
-#include <ShapeExtend.hxx>
-#include <ShapeBuild_Edge.hxx>
-#include <ShapeBuild_Vertex.hxx>
-#include <ShapeBuild_ReShape.hxx>
+#include <Precision.hxx>
+#include <ShapeAnalysis.hxx>
 #include <ShapeAnalysis_Curve.hxx>
 #include <ShapeAnalysis_Edge.hxx>
 #include <ShapeAnalysis_Surface.hxx>
-#include <ShapeAnalysis.hxx>
-#include <ShapeConstruct_ProjectCurveOnSurface.hxx>  
-#include <ShapeAnalysis_TransferParametersProj.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_OffsetCurve.hxx>
-
-#include <TColStd_HSequenceOfReal.hxx>
-#include <Adaptor3d_CurveOnSurface.hxx>
-#include <Geom2dAdaptor_HCurve.hxx>
-#include <GeomAPI_ProjectPointOnCurve.hxx>
-
 #include <ShapeAnalysis_TransferParameters.hxx>
+#include <ShapeAnalysis_TransferParametersProj.hxx>
+#include <ShapeAnalysis_Wire.hxx>
+#include <ShapeAnalysis_WireOrder.hxx>
+#include <ShapeBuild_Edge.hxx>
+#include <ShapeBuild_ReShape.hxx>
+#include <ShapeBuild_Vertex.hxx>
+#include <ShapeConstruct_ProjectCurveOnSurface.hxx>
+#include <ShapeExtend.hxx>
+#include <ShapeExtend_WireData.hxx>
 #include <ShapeFix.hxx>
+#include <ShapeFix_Edge.hxx>
 #include <ShapeFix_IntersectionTool.hxx>
 #include <ShapeFix_SplitTool.hxx>
-#include <ShapeFix_Edge.hxx>
-#include <ShapeAnalysis_Wire.hxx>
+#include <ShapeFix_Wire.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+#include <Standard_Type.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_SequenceOfPnt.hxx>
+#include <TColStd_Array1OfInteger.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_HSequenceOfReal.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopTools_Array1OfShape.hxx>
+#include <TopTools_HSequenceOfShape.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Wire,ShapeFix_Root)
 
+//S4135
 //#######################################################################
 //  Constructors, initializations, modes, querying
 //#######################################################################
-
 //=======================================================================
 //function : ShapeFix_Wire
 //purpose  : 
 //=======================================================================
-
 ShapeFix_Wire::ShapeFix_Wire() : myMaxTailAngleSine(0), myMaxTailWidth(-1)
 {
   myFixEdge = new ShapeFix_Edge;
@@ -341,9 +339,11 @@ Standard_Boolean ShapeFix_Wire::Perform()
 {
   ClearStatuses();
   if ( ! IsLoaded() ) return Standard_False;
-  
 
-  Standard_Integer Fixed = Standard_False;
+  if ( !Context().IsNull() )
+    myFixEdge->SetContext( Context() );
+
+  Standard_Boolean Fixed = Standard_False;
   
   // FixReorder is first, because as a rule wire is required to be ordered
   // We shall analyze the order of edges in the wire and set appropriate 
@@ -394,9 +394,9 @@ Standard_Boolean ShapeFix_Wire::Perform()
     
   if (myFixTailMode != 0)
   {
-    Fixed |= FixTails();
-    if (Fixed)
+    if (FixTails())
     {
+      Fixed =Standard_True;
       FixShifted();
     }
   }
@@ -418,8 +418,13 @@ Standard_Boolean ShapeFix_Wire::Perform()
   // TEMPORARILY without special mode !!!
   Handle(ShapeExtend_WireData) sbwd = WireData();
   for (Standard_Integer iedge = 1; iedge <= sbwd->NbEdges(); iedge++)
-    if ( myFixEdge->FixVertexTolerance (sbwd->Edge (iedge)) ) 
+    if ( myFixEdge->FixVertexTolerance (sbwd->Edge (iedge), Face()) ) 
+    {
       Fixed = Standard_True;
+    }
+
+  if (  !Context().IsNull() )
+    UpdateWire();
 
   return Fixed;
 }
@@ -530,7 +535,7 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
   Handle(ShapeExtend_WireData) sbwd = WireData();
   Standard_Integer i, nb = sbwd->NbEdges();
   TopoDS_Face face = Face();
-  Handle(ShapeFix_Edge) theAdvFixEdge = Handle(ShapeFix_Edge)::DownCast(myFixEdge);
+  Handle(ShapeFix_Edge) theAdvFixEdge = myFixEdge;
   if (theAdvFixEdge.IsNull()) myFixReversed2dMode = Standard_False;
 
   // fix revesred 2d / 3d curves
@@ -603,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 );
@@ -718,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
     }
   }
@@ -752,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 );
       }
@@ -780,7 +792,7 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
   }
 
   // fix same parameter
-  if ( isReady && NeedFix ( myFixSameParameterMode ) ) {
+  if ( isReady && NeedFix ( myFixSameParameterMode ) ){
     for ( i=1; i <= nb; i++ ) {
       // skl 28.10.2004 for OCC6366 - check SameRange
       ShapeAnalysis_Edge sae;
@@ -789,34 +801,53 @@ 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) );
+      myFixEdge->FixSameParameter ( sbwd->Edge(i), Face());
       if ( myFixEdge->Status ( ShapeExtend_DONE ) ) 
        myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
       if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) 
        myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
     }
   }
-    
+
   //:abv 10.06.02: porting C40 -> dev (CC670-12608.stp): moved from Perform()
   // Update with face is needed for plane surfaces (w/o stored pcurves)
-  if ( NeedFix ( myFixVertexToleranceMode ) ) {
-    for ( i=1; i <= nb; i++) {
-      myFixEdge->FixVertexTolerance (sbwd->Edge (i), face);
+  if ( NeedFix ( myFixVertexToleranceMode ) )
+  {
+    for ( i=1; i <= nb; i++)
+    {
+      myFixEdge->FixVertexTolerance (sbwd->Edge (i), Face());
       if ( myFixEdge->Status ( ShapeExtend_DONE ) ) 
-       myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
+        myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
       if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) 
-       myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
+        myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL8 );
     }
+    if (!Context().IsNull() )
+      UpdateWire();
   }
   
+
   return StatusEdgeCurves ( ShapeExtend_DONE );
 }
 
@@ -889,55 +920,64 @@ Standard_Boolean ShapeFix_Wire::FixSelfIntersection()
     }
   }
   
-  if ( NeedFix ( myFixIntersectingEdgesMode ) ) {
+  if ( NeedFix ( myFixIntersectingEdgesMode ) )
+  {
     Standard_Integer num = ( myClosedMode ? 1 : 2 );
-    for ( ; nb >1 && num <= nb; num++ ) {
+    for ( ; nb >1 && num <= nb; num++ )
+    {
       FixIntersectingEdges ( num );
       if ( LastFixStatus ( ShapeExtend_FAIL1 ) ) 
-       myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
+        myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
       if ( LastFixStatus ( ShapeExtend_FAIL2 ) ) 
-       myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
+        myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
       if ( ! LastFixStatus ( ShapeExtend_DONE ) ) continue;
 
       if ( LastFixStatus ( ShapeExtend_DONE1 ) ) 
-       myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
+        myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
       if ( LastFixStatus ( ShapeExtend_DONE2 ) ) 
-       myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
+        myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
       if(LastFixStatus (ShapeExtend_DONE6))
-  myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 );
+        myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 );
 
-      if ( /*! myTopoMode ||*/ nb < 3 ) {
+      if ( /*! myTopoMode ||*/ nb < 3 )
+      {
         //#86 rln 22.03.99 sim2.igs, entity 4292: After fixing of self-intersecting
         //BRepCheck finds one more self-intersection not found by ShapeAnalysis
         //%15 pdn 06.04.99 repeat until fixed CTS18546-2 entity 777
         
         // if the tolerance was modified we should recheck the result, if it was enough
-        if ( LastFixStatus ( ShapeExtend_DONE7 ) ) num--;
+        if ( LastFixStatus ( ShapeExtend_DONE7 ) ) //num--;
+          FixIntersectingEdges ( num );
         continue;
       }
 
       if ( LastFixStatus ( ShapeExtend_DONE4 ) ) sbwd->Remove ( num );
       if ( LastFixStatus ( ShapeExtend_DONE3 ) ) sbwd->Remove ( num >1 ? num-1 : nb+num-1 );
       if ( LastFixStatus ( ShapeExtend_DONE4 ) ||
-           LastFixStatus ( ShapeExtend_DONE3 ) ) {
-       myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
-       num = ( myClosedMode ? 1 : 2 );
-       nb = sbwd->NbEdges();
+           LastFixStatus ( ShapeExtend_DONE3 ) )
+      {
+        myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
+        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 {
-       //#86 rln 22.03.99
-       //%15 pdn 06.04.99 repeat until fixed CTS18546-2 entity 777
-       //FixIntersectingEdges ( num );
-       /*if ( LastFixStatus ( ShapeExtend_DONE7 ) )*/
+      else
+      {
+        //#86 rln 22.03.99
+        //%15 pdn 06.04.99 repeat until fixed CTS18546-2 entity 777
+        FixIntersectingEdges ( num );
+        /*if ( LastFixStatus ( ShapeExtend_DONE7 ) )*/
         // Always revisit the fixed edge
-        num--;
+        //num--;
       }
     }
+    if ( !Context().IsNull())
+      UpdateWire();
   }
-  
+
+
   //pdn 17.03.99 S4135 to avoid regression fixing not adjacent intersection
   if ( NeedFix ( myFixNonAdjacentIntersectingEdgesMode ) ) {
 
@@ -956,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   
 
 /*
@@ -1003,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   
 */
   }
@@ -1123,7 +1163,7 @@ Standard_Boolean ShapeFix_Wire::FixSmall (const Standard_Integer num,
   if ( ! IsLoaded() || NbEdges() <=1 ) return Standard_False;
 
   // analysis:
-  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = Handle(ShapeAnalysis_Wire)::DownCast(myAnalyzer);
+  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = myAnalyzer;
   if (theAdvAnalyzer.IsNull()) return Standard_False;
   Standard_Integer n = ( num >0 ? num : NbEdges() );
   theAdvAnalyzer->CheckSmall ( n, precsmall );
@@ -1348,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
     }
   }
@@ -1381,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;
@@ -1532,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;
           }
@@ -1769,7 +1809,7 @@ static Standard_Boolean TryNewPCurve (const TopoDS_Edge &E, const TopoDS_Face &f
 // no call to BRepLib:  B.SameParameter ( edge, Standard_False );
 
   Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
-  sfe->FixSameParameter ( edge ); 
+  sfe->FixSameParameter ( edge, face ); 
   c2d = BRep_Tool::CurveOnSurface ( edge, face, first, last );
   tol = BRep_Tool::Tolerance ( edge );
   return Standard_True;
@@ -1829,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 ..
@@ -1906,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 );
@@ -1940,8 +1980,7 @@ static Standard_Boolean RemoveLoop (TopoDS_Edge &E, const TopoDS_Face &face,
   Seq2d->Append(t1);
   Seq2d->Append(t2);
   Seq2d->Append((t1+t2)/2);
-  Handle(TColStd_HSequenceOfReal) Seq3d = new TColStd_HSequenceOfReal;
-  Seq3d->Append(SFTP.Perform(Seq2d,Standard_False));
+  Handle(TColStd_HSequenceOfReal) Seq3d = SFTP.Perform(Seq2d,Standard_False);
   
   Standard_Real dist1 = pcurPnt.Distance(crv->Value(Seq3d->Value(1)));// correting Seq3d already project 
   Standard_Real dist2 = pcurPnt.Distance(crv->Value(Seq3d->Value(2)));
@@ -2016,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;
@@ -2073,8 +2112,7 @@ static Standard_Boolean RemoveLoop (TopoDS_Edge &E, const TopoDS_Face &face,
   Seq2d->Append(t1);
   Seq2d->Append(t2);
   Seq2d->Append((t1+t2)/2);
-  Handle (TColStd_HSequenceOfReal) Seq3d = new TColStd_HSequenceOfReal;
-  Seq3d->Append(SFTP.Perform(Seq2d,Standard_False));
+  Handle (TColStd_HSequenceOfReal) Seq3d = SFTP.Perform(Seq2d,Standard_False);
   
   Standard_Real dist1 = pcurPnt.Distance(crv->Value(Seq3d->Value(1)));// correting Seq3d already project 
   Standard_Real dist2 = pcurPnt.Distance(crv->Value(Seq3d->Value(2)));
@@ -2173,7 +2211,7 @@ Standard_Boolean ShapeFix_Wire::FixSelfIntersectingEdge (const Standard_Integer
   // analysis
   IntRes2d_SequenceOfIntersectionPoint points2d;
   TColgp_SequenceOfPnt points3d;
-  Handle(ShapeAnalysis_Wire) theAdvAnalyzer =  Handle(ShapeAnalysis_Wire)::DownCast(myAnalyzer);
+  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = myAnalyzer;
   if (theAdvAnalyzer.IsNull()) return Standard_False;
   theAdvAnalyzer->CheckSelfIntersectingEdge ( num, points2d, points3d ); 
   if ( theAdvAnalyzer->LastCheckStatus ( ShapeExtend_FAIL ) ) {
@@ -2201,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);
@@ -2368,7 +2406,7 @@ Standard_Boolean ShapeFix_Wire::FixIntersectingEdges (const Standard_Integer num
   IntRes2d_SequenceOfIntersectionPoint points2d;
   TColgp_SequenceOfPnt points3d;
   TColStd_SequenceOfReal errors;
-  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = Handle(ShapeAnalysis_Wire)::DownCast(myAnalyzer);
+  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = myAnalyzer;
   if (theAdvAnalyzer.IsNull()) return Standard_False;
   theAdvAnalyzer->CheckIntersectingEdges ( num, points2d, points3d, errors );
   if ( theAdvAnalyzer->LastCheckStatus ( ShapeExtend_FAIL ) ) {
@@ -2386,12 +2424,18 @@ Standard_Boolean ShapeFix_Wire::FixIntersectingEdges (const Standard_Integer num
   Standard_Integer n1 = ( n2  >1 ? n2-1 : sbwd->NbEdges() );
   TopoDS_Edge E1 = sbwd->Edge(n1);
   TopoDS_Edge E2 = sbwd->Edge(n2);
+  if ( !Context().IsNull() )
+  {
+    E1 = TopoDS::Edge(Context()->Apply(sbwd->Edge(n1))); 
+    E2 = TopoDS::Edge(Context()->Apply(sbwd->Edge(n2))); 
+  }
+
   Standard_Boolean isForward1 = ( E1.Orientation() == TopAbs_FORWARD );
   Standard_Boolean isForward2 = ( E2.Orientation() == TopAbs_FORWARD );
   Standard_Real a1, b1, a2, b2;
   BRep_Tool::Range ( E1, Face(), a1, b1 );
   BRep_Tool::Range ( E2, Face(), a2, b2 );
-  
+
   ShapeAnalysis_Edge sae;
   TopoDS_Vertex Vp = sae.FirstVertex ( E1 );
   TopoDS_Vertex V1 = sae.LastVertex  ( E1 );
@@ -2404,9 +2448,10 @@ Standard_Boolean ShapeFix_Wire::FixIntersectingEdges (const Standard_Integer num
   Standard_Real prevRange1 = RealLast(), prevRange2 = RealLast();
   Standard_Boolean cutEdge1 = Standard_False, cutEdge2 = Standard_False;
   Standard_Boolean IsCutLine = Standard_False;
+  Standard_Boolean isChangedEdge = Standard_False;
 
   BRep_Builder B;
-  
+
   Standard_Integer nb = points3d.Length();
   for ( Standard_Integer i=1; i <= nb; i++ ) {
     const IntRes2d_IntersectionPoint &IP = points2d.Value(i);
@@ -2427,18 +2472,60 @@ Standard_Boolean ShapeFix_Wire::FixIntersectingEdges (const Standard_Integer num
 
     Standard_Boolean locMayEdit = myTopoMode;
     // Always try to modify the tolerance firstly as a better solution
-    if ( /*! myTopoMode &&*/ newtol > tol ) {
+    if ( /*! myTopoMode &&*/ newtol > tol )
+    {
       Standard_Real te1 = rad + ComputeLocalDeviation (E1, pint, pnt,
         param1, ( isForward1 ? b1 : a1 ), Face() );
       Standard_Real te2 = rad + ComputeLocalDeviation (E2, pint, pnt, 
         ( isForward2 ? a2 : b2 ), param2, Face() );
       Standard_Real maxte = Max ( te1, te2 );
-      if ( maxte < MaxTolerance() && maxte < newtol ) {
-        if ( BRep_Tool::Tolerance(E1) < te1 || BRep_Tool::Tolerance(E2) < te2 ) {
+      if ( maxte < MaxTolerance() && maxte < newtol )
+      {
+        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.
+          if (!Context().IsNull())
+          {
+             isChangedEdge = Standard_True; // To avoid double copying of vertexes.
+
+            // Intersection point of two base edges.
+            ShapeBuild_Edge aSBE;
+            TopoDS_Vertex VV1 = Context()->CopyVertex(V1);
+
+            TopoDS_Vertex VVp = Vp;
+            TopoDS_Vertex VVn = Vn;
+            if (Vp.IsSame(Vn))
+            {
+              // Should modify only one vertex.
+              VVp = Context()->CopyVertex(Vp);
+              VVn = VVp;
+            }
+            else
+            {
+              VVp = Context()->CopyVertex(Vp);
+              VVn = Context()->CopyVertex(Vn);
+            }
+
+            TopoDS_Edge EE1 = aSBE.CopyReplaceVertices(E1, VVp, VV1);
+            TopoDS_Edge EE2 = aSBE.CopyReplaceVertices(E2, VV1, VVn);
+
+            Context()->Replace(E1, EE1);
+            Context()->Replace(E2, EE2);
+
+            UpdateWire();
+            E1 = sbwd->Edge(n1);
+            E2 = sbwd->Edge(n2);
+            Vp = sae.FirstVertex ( E1 );
+            V1 = sae.LastVertex  ( E1 );
+            V2 = sae.FirstVertex ( E2 );
+            Vn = sae.LastVertex  ( E2 );
+          }
+
           B.UpdateEdge ( E1, 1.000001 * te1 );
           B.UpdateVertex ( sae.FirstVertex ( E1 ), 1.000001 * te1 );
           B.UpdateVertex ( sae.LastVertex  ( E1 ), 1.000001 * te1 );
@@ -2519,12 +2606,45 @@ Standard_Boolean ShapeFix_Wire::FixIntersectingEdges (const Standard_Integer num
 
   if ( ! LastFixStatus ( ShapeExtend_DONE ) ) return Standard_False;
 
-  B.UpdateVertex ( V1, pnt, tol );
-  B.UpdateVertex ( V2, pnt, tol );
+  if (isChangedEdge)
+  {
+    B.UpdateVertex ( V1, pnt, tol );
+    B.UpdateVertex ( V2, pnt, tol );
+  }
+  else
+  {
+    if ( !Context().IsNull() )
+    {
+      if (V1.IsSame(V2) )
+      {
+        Context()->CopyVertex(V1, pnt, tol);
+      }
+      else
+      {
+        Context()->CopyVertex(V1, pnt, tol);
+        Context()->CopyVertex(V2, pnt, tol);
+      }
+    }
+    else
+    {
+      B.UpdateVertex ( V1, pnt, tol );
+      B.UpdateVertex ( V2, pnt, tol );
+    }
+  }
 
   //:h4: make edges SP (after all cuts: t4mug.stp #3730+#6460)
-  if ( cutEdge1 ) myFixEdge->FixSameParameter ( E1 );
-  if ( cutEdge2 && !IsCutLine ) myFixEdge->FixSameParameter ( E2 );
+  if ( cutEdge1 ) 
+  {
+    if ( !Context().IsNull() )
+      E1 = TopoDS::Edge(Context()->Apply(E1));
+    myFixEdge->FixSameParameter ( E1 );
+  }
+  if ( cutEdge2 && !IsCutLine )
+  {
+    if ( !Context().IsNull() )
+      E2 = TopoDS::Edge(Context()->Apply(E2));
+    myFixEdge->FixSameParameter ( E2 );
+  }
   if ( cutEdge1 || cutEdge2 ) {
     myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE7 );
   }
@@ -2548,7 +2668,7 @@ Standard_Boolean ShapeFix_Wire::FixIntersectingEdges (const Standard_Integer num
   IntRes2d_SequenceOfIntersectionPoint points2d;
   TColgp_SequenceOfPnt points3d;
   TColStd_SequenceOfReal errors;
-  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = Handle(ShapeAnalysis_Wire)::DownCast(myAnalyzer);
+  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = myAnalyzer;
   if (theAdvAnalyzer.IsNull()) return Standard_False;
   theAdvAnalyzer->CheckIntersectingEdges ( num1, num2, points2d, points3d, errors);
   if ( theAdvAnalyzer->LastCheckStatus ( ShapeExtend_FAIL ) ) {
@@ -2793,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;
   }
@@ -2819,7 +2939,7 @@ Standard_Boolean ShapeFix_Wire::FixLacking (const Standard_Integer num,
   //=============
   // First phase: analysis whether the problem (gap) exists
   gp_Pnt2d p2d1, p2d2;
-  Handle(ShapeAnalysis_Wire)::DownCast(myAnalyzer)->CheckLacking ( num, ( force ? Precision() : 0. ), p2d1, p2d2 );
+  myAnalyzer->CheckLacking ( num, ( force ? Precision() : 0. ), p2d1, p2d2 );
   if ( myAnalyzer->LastCheckStatus ( ShapeExtend_FAIL ) ) {
     myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
   }
@@ -3026,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 ) {
@@ -3059,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 );
   }
@@ -3087,7 +3207,7 @@ Standard_Boolean ShapeFix_Wire::FixNotchedEdges()
   myLastFixStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
   if ( ! IsReady() ) return Standard_False;
   
-  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = Handle(ShapeAnalysis_Wire)::DownCast(myAnalyzer);
+  Handle(ShapeAnalysis_Wire) theAdvAnalyzer = myAnalyzer;
   TopoDS_Face face = Face();
   if ( ! Context().IsNull() ) UpdateWire();
   Handle(ShapeExtend_WireData) sewd = WireData();
@@ -3105,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;
@@ -3166,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