0030348: Shape Healing - ShapeFix_Wire::FixEdgeCurves() throws Standard_OutOfRange...
[occt.git] / src / ShapeFix / ShapeFix_Wire.cxx
index 592d644..4bb06b1 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_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()
+ShapeFix_Wire::ShapeFix_Wire() : myMaxTailAngleSine(0), myMaxTailWidth(-1)
 {
   myFixEdge = new ShapeFix_Edge;
   myAnalyzer = new ShapeAnalysis_Wire;
@@ -142,8 +142,10 @@ ShapeFix_Wire::ShapeFix_Wire()
 //purpose  : 
 //=======================================================================
 
-ShapeFix_Wire::ShapeFix_Wire (const TopoDS_Wire& wire, 
-                             const TopoDS_Face &face, const Standard_Real prec)
+ShapeFix_Wire::ShapeFix_Wire (
+  const TopoDS_Wire& wire,
+  const TopoDS_Face &face,
+  const Standard_Real prec) : myMaxTailAngleSine(0), myMaxTailWidth(-1)
 {
   myFixEdge = new ShapeFix_Edge;
   myAnalyzer = new ShapeAnalysis_Wire;
@@ -164,6 +166,25 @@ void ShapeFix_Wire::SetPrecision (const Standard_Real prec)
   myAnalyzer->SetPrecision ( prec );
 }
  
+//=======================================================================
+//function : SetMaxTailAngle
+//purpose  :
+//=======================================================================
+void ShapeFix_Wire::SetMaxTailAngle(const Standard_Real theMaxTailAngle)
+{
+  myMaxTailAngleSine = Sin(theMaxTailAngle);
+  myMaxTailAngleSine = (myMaxTailAngleSine >= 0) ? myMaxTailAngleSine : 0;
+}
+
+//=======================================================================
+//function : SetMaxTailWidth
+//purpose  :
+//=======================================================================
+void ShapeFix_Wire::SetMaxTailWidth(const Standard_Real theMaxTailWidth)
+{
+  myMaxTailWidth = theMaxTailWidth;
+}
+
 //=======================================================================
 //function : ClearModes
 //purpose  : 
@@ -193,6 +214,7 @@ void ShapeFix_Wire::ClearModes()
   myFixSelfIntersectingEdgeMode = -1;
   myFixIntersectingEdgesMode = -1;
   myFixNonAdjacentIntersectingEdgesMode = -1;
+  myFixTailMode = 0;
 
   myFixReorderMode = -1;
   myFixSmallMode = -1;
@@ -226,6 +248,8 @@ void ShapeFix_Wire::ClearStatuses()
   myStatusGaps3d           = emptyStatus; //szv#9:S4244:19Aug99 new method introduced
   myStatusGaps2d           = emptyStatus; //szv#9:S4244:19Aug99 new method introduced
   myStatusClosed           = emptyStatus;
+  myStatusNotches = emptyStatus;
+  myStatusFixTails = emptyStatus;
 }
 
 //=======================================================================
@@ -315,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 
@@ -360,11 +386,21 @@ Standard_Boolean ShapeFix_Wire::Perform()
   }
   
   //pdn - temporary to test
-  if ( NeedFix ( myFixNotchedEdgesMode, ReorderOK ) ) {
+  if (myFixTailMode <= 0 && NeedFix(myFixNotchedEdgesMode, ReorderOK))
+  {
     Fixed |= FixNotchedEdges();
     if(Fixed) FixShifted(); //skl 07.03.2002 for OCC180
   }
     
+  if (myFixTailMode != 0)
+  {
+    Fixed |= FixTails();
+    if (Fixed)
+    {
+      FixShifted();
+    }
+  }
+
   if ( NeedFix ( myFixSelfIntersectionMode, myClosedMode ) ) {
     Standard_Integer savFixIntersectingEdgesMode = myFixIntersectingEdgesMode;
     // switch off FixIntEdges if reorder not done
@@ -382,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;
 }
@@ -494,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
@@ -566,69 +607,95 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
            }
          }
          if ( seq.Length() >0 ) { // supposed that edge is SP
-#ifdef DEB
+#ifdef OCCT_DEBUG
            cout << "Edge going over singularity detected; splitted" << endl;
 #endif
-           Standard_Boolean isFwd = ( E.Orientation() == TopAbs_FORWARD );
-           E.Orientation ( TopAbs_FORWARD );
-
-            //if( BRep_Tool::SameParameter(sbwd->Edge(i)) )
-            //  sbe.RemovePCurve ( E, face );
-
-            //10.04.2003 skl for using trimmed lines as pcurves
-           ShapeAnalysis_Edge sae;
-            if( BRep_Tool::SameParameter(sbwd->Edge(i)) )
-              sbe.RemovePCurve ( E, face );
-            else {
-              if(sae.HasPCurve(E,face)) {
-                Handle(Geom2d_Curve) C2d;
-                Standard_Real fp2d,lp2d;
-                if(sae.PCurve(E,face,C2d,fp2d,lp2d)) {
-                  if( !C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) )
-                    sbe.RemovePCurve(E,face);
-                }
-              }
+      Standard_Boolean isFwd = ( E.Orientation() == TopAbs_FORWARD );
+      E.Orientation ( TopAbs_FORWARD );
+
+      //if( BRep_Tool::SameParameter(sbwd->Edge(i)) )
+      //  sbe.RemovePCurve ( E, face );
+
+      //10.04.2003 skl for using trimmed lines as pcurves
+      ShapeAnalysis_Edge sae;
+      if( BRep_Tool::SameParameter(sbwd->Edge(i)) )
+        sbe.RemovePCurve ( E, face );
+      else {
+        if(sae.HasPCurve(E,face)) {
+          Handle(Geom2d_Curve) C2d;
+          Standard_Real fp2d,lp2d;
+          if(sae.PCurve(E,face,C2d,fp2d,lp2d)) {
+            if( !C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) )
+              sbe.RemovePCurve(E,face);
+          }
+        }
+      }
+
+//    myFixEdge->FixSameParameter ( E ); // to ensure SameRange & SP
+      BRep_Builder B;
+      TopoDS_Vertex V1, V2, V;
+      //ShapeAnalysis_Edge sae;
+      V1 = sae.FirstVertex ( E );
+      V2 = sae.LastVertex ( E );
+        
+      Handle(ShapeExtend_WireData) sw = new ShapeExtend_WireData;
+      for ( Standard_Integer k=0; k <= seq.Length(); k++ )
+      {
+        Standard_Real split = ( k < seq.Length() ? seq(k+1) : b );
+        if ( k < seq.Length() )
+        {
+          B.MakeVertex ( V, C->Value(split), BRep_Tool::Tolerance(E) );
+          //try increase tolerance before splitting
+          Standard_Real aDist = BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V));
+          if (aDist < BRep_Tool::Tolerance(V1) * 1.01) {
+            B.UpdateVertex(V1, Max(aDist, BRep_Tool::Tolerance(V1)));
+            a = split;
+            V1 = V;
+            continue;
+          }
+          else
+          {
+            aDist = BRep_Tool::Pnt(V2).Distance(BRep_Tool::Pnt(V));
+            if (aDist < BRep_Tool::Tolerance(V2) * 1.01) {
+              B.UpdateVertex(V, Max(aDist, BRep_Tool::Tolerance(V2)));
+              b = split;
+              V2 = V;
+              continue;
             }
+          }
+        }
+        else
+        {
+          V = V2;
+        }
 
-//         myFixEdge->FixSameParameter ( E ); // to ensure SameRange & SP
-           BRep_Builder B;
-           TopoDS_Vertex V1, V2, V;
-           //ShapeAnalysis_Edge sae;
-           V1 = sae.FirstVertex ( E );
-           V2 = sae.LastVertex ( E );
-           Handle(ShapeExtend_WireData) sw = new ShapeExtend_WireData;
-           for ( Standard_Integer k=0; k <= seq.Length(); k++ ) {
-             Standard_Real split = ( k < seq.Length() ? seq(k+1) : b );
-             if ( k < seq.Length() ) 
-               B.MakeVertex ( V, C->Value(split), BRep_Tool::Tolerance(E) );
-             else V = V2;
-             TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V );
-              if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) {
-                //TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V );
-                B.Range ( edge, a, split );
-                sw->Add ( edge );
-              }
-              else {
-                //TopoDS_Edge edge = sbe.CopyReplaceVertices(sbwd->Edge(i),V1,V);
-                Handle(ShapeAnalysis_TransferParameters) sftp =
-                  new ShapeAnalysis_TransferParameters(E,face);
-                sftp->TransferRange(edge, a, split, Standard_False);
-                sw->Add(edge);
-              }
-              //sw->Add(edge);
-             a = split;
-             V1 = V;
-           }
-           if ( ! isFwd ) {
-             sw->Reverse();
-             E.Orientation ( TopAbs_REVERSED );
-           }
-           Context()->Replace ( E, sw->Wire() );
-           UpdateWire();
-           nb = sbwd->NbEdges();
-           i--;
-           continue;
-         }
+        TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V );
+        if( BRep_Tool::SameParameter(sbwd->Edge(i)) ) {
+          //TopoDS_Edge edge = sbe.CopyReplaceVertices ( E, V1, V );
+          B.Range ( edge, a, split );
+          sw->Add ( edge );
+        }
+        else {
+          //TopoDS_Edge edge = sbe.CopyReplaceVertices(sbwd->Edge(i),V1,V);
+          Handle(ShapeAnalysis_TransferParameters) sftp =
+            new ShapeAnalysis_TransferParameters(E,face);
+          sftp->TransferRange(edge, a, split, Standard_False);
+          sw->Add(edge);
+        }
+        //sw->Add(edge);
+        a = split;
+        V1 = V;
+      }
+      if ( ! isFwd ) {
+        sw->Reverse();
+        E.Orientation ( TopAbs_REVERSED );
+      }
+      Context()->Replace ( E, sw->Wire() );
+      UpdateWire();
+      nb = sbwd->NbEdges();
+      i--;
+      continue;
+    }
        }
        
        overdegen = i;
@@ -655,7 +722,7 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves()
        myFixEdge->Projector()->AdjustOverDegenMode() = Standard_False;
        myFixEdge->FixAddPCurve ( sbwd->Edge(overdegen), face, sbwd->IsSeam(overdegen), myAnalyzer->Surface(), Precision());
       }
-#ifdef DEB
+#ifdef OCCT_DEBUG
       cout << "Edge going over singularity detected; pcurve adjusted" << endl;
 #endif
     }
@@ -690,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 );
       }
@@ -718,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;
@@ -727,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-fp2d)>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 );
 }
 
@@ -827,52 +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 );
-
-      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
-       //FixIntersectingEdges ( num );
-       if ( LastFixStatus ( ShapeExtend_DONE7 ) ) num--;
-       continue;
+        myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 );
+
+      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--;
+          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();
-#ifdef DEB
-       cout << "Warning: ShapeFix_Wire::FixSelfIntersection: Edge removed" << endl;
+           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;
 #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 ) ) num--;
+      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--;
       }
     }
+    if ( !Context().IsNull())
+      UpdateWire();
   }
-  
+
+
   //pdn 17.03.99 S4135 to avoid regression fixing not adjacent intersection
   if ( NeedFix ( myFixNonAdjacentIntersectingEdgesMode ) ) {
 
@@ -889,7 +994,7 @@ Standard_Boolean ShapeFix_Wire::FixSelfIntersection()
       if ( ! Context().IsNull() ) UpdateWire();
       myShape.Nullify();
     }
-#ifdef DEB
+#ifdef OCCT_DEBUG
     if (StatusSelfIntersection (ShapeExtend_DONE5))
       cout<<"Warning: ShapeFix_Wire::FixIntersection: Non-adjacent intersection fixed (split-"
         <<NbSplit<<", cut-"<<NbCut<<", removed-"<<NbRemoved<<")"<<endl;
@@ -936,7 +1041,7 @@ Standard_Boolean ShapeFix_Wire::FixSelfIntersection()
       myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
     if(isDone)
       myStatusSelfIntersection |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
-#ifdef DEB
+#ifdef OCCT_DEBUG
     if (StatusSelfIntersection (ShapeExtend_DONE5))
       cout << "Warning: ShapeFix_Wire::FixSelfIntersection: Non ajacent intersection fixed" << endl;
 #endif   
@@ -1058,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 );
@@ -1282,7 +1387,7 @@ Standard_Boolean ShapeFix_Wire::FixShifted()
       vclosed = Standard_True;
       VRange = aBaseCrv->Period();
       IsVCrvClosed = Standard_True;
-#ifdef DEB
+#ifdef OCCT_DEBUG
       cout << "Warning: ShapeFix_Wire::FixShifted set vclosed True for Surface of Revolution" << endl;
 #endif
     }
@@ -1331,12 +1436,20 @@ Standard_Boolean ShapeFix_Wire::FixShifted()
     TopoDS_Edge E1 = sbwd->Edge ( n1 );
     TopoDS_Edge E2 = sbwd->Edge ( n2 );
 
-    if ( BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2) ) {
-      if ( ! degstop ) { stop = n2; degstop = Standard_True; }
+    if ( BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2) )
+    {
+      if ( ! degstop )
+      {
+        stop = n2;
+        degstop = Standard_True;
+      }
       continue;
     }
 
     TopoDS_Vertex V = sae.FirstVertex ( E2 );
+    if (V.IsNull())
+      continue;
+
     gp_Pnt p = BRep_Tool::Pnt ( V );
   
     Standard_Real a1 = 0., b1 = 0., a2 = 0., b2 = 0.;
@@ -1373,82 +1486,100 @@ Standard_Boolean ShapeFix_Wire::FixShifted()
       }
     }
 
-    if ( isDeg ) {
-      if ( ! degstop ) { stop = n2; degstop = Standard_True; }
-      if ( ! degn2 ) { degn2 = n2; pdeg = p; }
-      else if ( pdeg.SquareDistance(p) < Precision()*Precision() ) {
-        degn2 = n2;    
-//     if ( stop < n2 ) { stop = n2; degstop = Standard_True; }
+    if ( isDeg )
+    {
+      if ( ! degstop )
+      {
+        stop = n2;
+        degstop = Standard_True;
       }
-      else {
-       Standard_Real ax1 = 0., bx1 = 0., ax2 = 0., bx2 = 0.;
-       Handle(Geom2d_Curve) cx1, cx2;
-       if ( ( c2d1.IsNull() && ! sae.PCurve ( E1, Face(), c2d1, a1, b1, Standard_True ) ) ||
-            ( c2d2.IsNull() && ! sae.PCurve ( E2, Face(), c2d2, a2, b2, Standard_True ) ) ||
-            ! sae.PCurve ( sbwd->Edge ( degn2 >1 ? degn2-1 : nb ), Face(), cx1, ax1, bx1, Standard_True ) ||
-            ! sae.PCurve ( sbwd->Edge ( degn2 ), Face(), cx2, ax2, bx2, Standard_True ) ) {
-         myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
-         continue;
-       }
-       gp_Pnt2d pd1 = cx1->Value ( bx1 );
-       gp_Pnt2d pd2 = cx2->Value ( ax2 );
-       gp_Pnt2d pn1 = c2d1->Value ( b1 );
-       gp_Pnt2d pn2 = c2d2->Value ( a2 );
-       gp_Vec2d x(0.,0.); // shift vector
-       Standard_Real period;
-       if ( uclosed ) { x.SetX ( 1. ); period = URange; }
-       else { x.SetY ( 1. ); period = VRange; }
-       Standard_Real rot1 = ( pn1.XY() - pd2.XY() ) ^ x.XY();
-       Standard_Real rot2 = ( pd1.XY() - pn2.XY() ) ^ x.XY();
-       Standard_Real scld = ( pd2.XY() - pd1.XY() ) * x.XY();
-       Standard_Real scln = ( pn2.XY() - pn1.XY() ) * x.XY();
-       if ( rot1 * rot2 < -::Precision::PConfusion() && 
-            scld * scln < -::Precision::PConfusion() && 
-            Abs ( scln ) > 0.1 * period && Abs ( scld ) > 0.1 * period && 
-            rot1 * scld > ::Precision::PConfusion() && 
-            rot2 * scln > ::Precision::PConfusion() ) {
-         // abv 02 Mar 00: trying more sophisticated analysis (ie_exhaust-A.stp #37520)
-         Standard_Real sign = ( rot2 >0 ? 1. : -1. );
-         Standard_Real deep1 = Min ( sign * ( pn2.XY() * x.XY() ),
-                               Min ( sign * ( pd1.XY() * x.XY() ),
-                               Min ( sign * ( c2d2->Value(b2 ).XY() * x.XY() ),
-                               Min ( sign * (  cx1->Value(ax1).XY() * x.XY() ),
-                               Min ( sign * ( c2d2->Value(0.5*(a2 +b2 )).XY() * x.XY() ),
-                                     sign * (  cx1->Value(0.5*(ax1+bx1)).XY() * x.XY() ) ) ) ) ) );
-         Standard_Real deep2 = Max ( sign * ( pn1.XY() * x.XY() ),
-                               Max ( sign * ( pd2.XY() * x.XY() ),
-                               Max ( sign * ( c2d1->Value(a1 ).XY() * x.XY() ),
-                               Max ( sign * (  cx2->Value(bx2).XY() * x.XY() ),
-                               Max ( sign * ( c2d1->Value(0.5*(a1 +b1 )).XY() * x.XY() ),
-                                     sign * (  cx2->Value(0.5*(ax2+bx2)).XY() * x.XY() ) ) ) ) ) );
-         Standard_Real deep = deep2 - deep1; // estimated current size of wire by x
-         // pdn 30 Oct 00: trying correct period [0,period] (trj5_k1-tc-203.stp #4698)
-         Standard_Real dx = ShapeAnalysis::AdjustToPeriod ( deep, ::Precision::PConfusion(), period+::Precision::PConfusion()); 
-         x *= ( scld >0 ? -dx : dx );
-//       x *= ( Abs(scld-scln) > 1.5 * period ? 2. : 1. ) *
-//            ( scld >0 ? -period : period );
-         gp_Trsf2d Shift;
-         Shift.SetTranslation ( x );
-         for ( Standard_Integer k=degn2; ; k++ ) {
-           if ( k > nb ) k = 1;
-           if ( k == n2 ) break;
-           TopoDS_Edge edge = sbwd->Edge ( k );
-           if ( ! sae.PCurve ( edge, Face(), cx1, ax1, bx1, Standard_True ) ) continue;
-           //cx1->Transform ( Shift );
-            // skl 15.05.2002 for OCC208 (if few edges have reference to one pcurve)
-            Handle(Geom2d_Curve) cx1new = Handle(Geom2d_Curve)::DownCast(cx1->Transformed(Shift));
-            sbe.ReplacePCurve(edge,cx1new,Face());
-           UpdateEdgeUVPoints ( edge, Face() );
-         }
-         myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
-#ifdef DEB
-         cout << "Info: ShapeFix_Wire::FixShifted(): bi - meridian case fixed" << endl;
+
+      if ( ! degn2 )
+      {
+        degn2 = n2;
+        pdeg = p;
+      }
+      else
+      {
+        if ( pdeg.SquareDistance(p) < Precision() * Precision() )
+        {
+          degn2 = n2;
+          //if ( stop < n2 ) { stop = n2; degstop = Standard_True; }
+        }
+        else
+        {
+          Standard_Real ax1 = 0., bx1 = 0., ax2 = 0., bx2 = 0.;
+          Handle(Geom2d_Curve) cx1, cx2;
+          if (  ( c2d1.IsNull() && ! sae.PCurve ( E1, Face(), c2d1, a1, b1, Standard_True ) ) ||
+                ( c2d2.IsNull() && ! sae.PCurve ( E2, Face(), c2d2, a2, b2, Standard_True ) ) ||
+                ! sae.PCurve ( sbwd->Edge ( degn2 >1 ? degn2-1 : nb ), Face(), cx1, ax1, bx1, Standard_True ) ||
+                ! sae.PCurve ( sbwd->Edge ( degn2 ), Face(), cx2, ax2, bx2, Standard_True ) )
+          {
+            myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
+            continue;
+          }
+          gp_Pnt2d pd1 = cx1->Value ( bx1 );
+          gp_Pnt2d pd2 = cx2->Value ( ax2 );
+          gp_Pnt2d pn1 = c2d1->Value ( b1 );
+          gp_Pnt2d pn2 = c2d2->Value ( a2 );
+          gp_Vec2d x(0.,0.); // shift vector
+          Standard_Real period;
+          if ( uclosed ) { x.SetX ( 1. ); period = URange; }
+          else { x.SetY ( 1. ); period = VRange; }
+          Standard_Real rot1 = ( pn1.XY() - pd2.XY() ) ^ x.XY();
+          Standard_Real rot2 = ( pd1.XY() - pn2.XY() ) ^ x.XY();
+          Standard_Real scld = ( pd2.XY() - pd1.XY() ) * x.XY();
+          Standard_Real scln = ( pn2.XY() - pn1.XY() ) * x.XY();
+          if (  rot1 * rot2 < -::Precision::PConfusion() && 
+                scld * scln < -::Precision::PConfusion() && 
+                Abs ( scln ) > 0.1 * period && Abs ( scld ) > 0.1 * period && 
+                rot1 * scld > ::Precision::PConfusion() && 
+                rot2 * scln > ::Precision::PConfusion() )
+          {
+            // abv 02 Mar 00: trying more sophisticated analysis (ie_exhaust-A.stp #37520)
+            Standard_Real sign = ( rot2 >0 ? 1. : -1. );
+            Standard_Real deep1 = Min ( sign * ( pn2.XY() * x.XY() ),
+                                  Min ( sign * ( pd1.XY() * x.XY() ),
+                                  Min ( sign * ( c2d2->Value(b2 ).XY() * x.XY() ),
+                                  Min ( sign * (  cx1->Value(ax1).XY() * x.XY() ),
+                                  Min ( sign * ( c2d2->Value(0.5*(a2 +b2 )).XY() * x.XY() ),
+                                        sign * (  cx1->Value(0.5*(ax1+bx1)).XY() * x.XY() ) ) ) ) ) );
+            Standard_Real deep2 = Max ( sign * ( pn1.XY() * x.XY() ),
+                                  Max ( sign * ( pd2.XY() * x.XY() ),
+                                  Max ( sign * ( c2d1->Value(a1 ).XY() * x.XY() ),
+                                  Max ( sign * (  cx2->Value(bx2).XY() * x.XY() ),
+                                  Max ( sign * ( c2d1->Value(0.5*(a1 +b1 )).XY() * x.XY() ),
+                                        sign * (  cx2->Value(0.5*(ax2+bx2)).XY() * x.XY() ) ) ) ) ) );
+            Standard_Real deep = deep2 - deep1; // estimated current size of wire by x
+            // pdn 30 Oct 00: trying correct period [0,period] (trj5_k1-tc-203.stp #4698)
+            Standard_Real dx = ShapeAnalysis::AdjustToPeriod ( deep, ::Precision::PConfusion(), period+::Precision::PConfusion()); 
+            x *= ( scld >0 ? -dx : dx );
+            //x *= ( Abs(scld-scln) > 1.5 * period ? 2. : 1. ) *
+            //     ( scld >0 ? -period : period );
+            gp_Trsf2d Shift;
+            Shift.SetTranslation ( x );
+            for ( Standard_Integer k=degn2; ; k++ )
+            {
+              if ( k > nb ) k = 1;
+              if ( k == n2 ) break;
+              TopoDS_Edge edge = sbwd->Edge ( k );
+              if ( ! sae.PCurve ( edge, Face(), cx1, ax1, bx1, Standard_True ) ) continue;
+              //cx1->Transform ( Shift );
+              // skl 15.05.2002 for OCC208 (if few edges have reference to one pcurve)
+              Handle(Geom2d_Curve) cx1new = Handle(Geom2d_Curve)::DownCast(cx1->Transformed(Shift));
+              sbe.ReplacePCurve(edge,cx1new,Face());
+              UpdateEdgeUVPoints ( edge, Face() );
+            }
+            myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
+#ifdef OCCT_DEBUG
+            cout << "Info: ShapeFix_Wire::FixShifted(): bi - meridian case fixed" << endl;
 #endif
-          continue;
-       }
-//     degn2 = n2; pdeg = p; // ie_exhaust-A.stp #37520
+            continue;
+          }
+          //degn2 = n2; pdeg = p; // ie_exhaust-A.stp #37520
+        }
       }
-/*     
+/*
       // pdn to fix half sphere
       TopoDS_Vertex VE = sae.LastVertex ( E2 );
       gp_Pnt pe = BRep_Tool::Pnt ( VE );
@@ -1678,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;
@@ -1737,14 +1868,14 @@ static Standard_Boolean RemoveLoop (TopoDS_Edge &E, const TopoDS_Face &face,
   if ( ! sae.PCurve ( E, face, c2d, a, b, Standard_False ) ) 
     return Standard_False;
 
-#ifdef DEB
+#ifdef OCCT_DEBUG
   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 DEB
+#ifdef OCCT_DEBUG
   cout << ") -> (" << t1 << ", " << t2 << ")" << endl;
 #endif
       
@@ -1814,7 +1945,7 @@ static Standard_Boolean RemoveLoop (TopoDS_Edge &E, const TopoDS_Face &face,
       if ( ! TryNewPCurve ( E, face, bs, a, b, newtol ) ) return Standard_False;
   
     Standard_Real tol = BRep_Tool::Tolerance ( E );
-#ifdef DEB
+#ifdef OCCT_DEBUG
     cout << "Cut Loop: tol orig " << tol << ", prec " << prec << ", new tol " << newtol << endl;
 #endif
     if ( newtol > Max ( prec, tol ) ) return Standard_False;
@@ -1849,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)));
@@ -1924,7 +2054,7 @@ static Standard_Boolean RemoveLoop (TopoDS_Edge &E, const TopoDS_Face &face,
                                     TopoDS_Edge &E1,
                                     TopoDS_Edge &E2)
 {
-#ifdef DEB
+#ifdef OCCT_DEBUG
   cout<<"Info: ShapeFix_Wire::FixSelfIntersection : Try insert vertex"<<endl;
 #endif
 
@@ -1982,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)));
@@ -2082,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 ) ) {
@@ -2277,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 ) ) {
@@ -2295,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 );
@@ -2313,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);
@@ -2330,91 +2466,185 @@ Standard_Boolean ShapeFix_Wire::FixIntersectingEdges (const Standard_Integer num
     Standard_Real rad = errors.Value(i);
     Standard_Real newtol = 1.0001 * ( pnt.Distance ( pint ) + rad );
 
-//    GeomAdaptor_Surface& Ads = myAnalyzer->Surface()->Adaptor3d()->ChangeSurface();
+    //GeomAdaptor_Surface& Ads = myAnalyzer->Surface()->Adaptor3d()->ChangeSurface();
 
     //:r8 abv 12 Apr 99: try increasing tolerance of edge
-    if ( ! myTopoMode && newtol > tol ) {
+
+    Standard_Boolean locMayEdit = myTopoMode;
+    // Always try to modify the tolerance firstly as a better solution
+    if ( /*! myTopoMode &&*/ newtol > tol )
+    {
       Standard_Real te1 = rad + ComputeLocalDeviation (E1, pint, pnt,
-                                                param1, ( isForward1 ? b1 : a1 ), Face() );
+        param1, ( isForward1 ? b1 : a1 ), Face() );
       Standard_Real te2 = rad + ComputeLocalDeviation (E2, pint, pnt, 
-                                                ( isForward2 ? a2 : b2 ), param2, Face() );
+        ( 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 ) {
-//#ifdef DEB
-//       cout << "Warning: ShapeFix_Wire::FixIE: edges tolerance increased: (" <<
-//         te1 << ", " << te2 << ") / " << newtol << endl;
-//#endif
-         B.UpdateEdge ( E1, 1.000001 * te1 );
-         B.UpdateVertex ( sae.FirstVertex ( E1 ), 1.000001 * te1 );
-         B.UpdateVertex ( sae.LastVertex  ( E1 ), 1.000001 * te1 );
-         B.UpdateEdge ( E2, 1.000001 * te2 );
-         B.UpdateVertex ( sae.FirstVertex ( E2 ), 1.000001 * te2 );
-         B.UpdateVertex ( sae.LastVertex  ( E2 ), 1.000001 * te2 );
-         myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 );
-       }
-       newtol = 1.000001 * maxte;
+      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;
+#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 );
+          B.UpdateEdge ( E2, 1.000001 * te2 );
+          B.UpdateVertex ( sae.FirstVertex ( E2 ), 1.000001 * te2 );
+          B.UpdateVertex ( sae.LastVertex  ( E2 ), 1.000001 * te2 );
+
+          myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE6 );
+          locMayEdit = Standard_False;
+        }
+        newtol = 1.000001 * maxte;
       }
     }
     
-    if ( myTopoMode || newtol <= MaxTolerance() ) {
+    if ( locMayEdit || newtol <= MaxTolerance() )
+    {
       prevRange1 = newRange1; 
       prevRange2 = newRange2;
-      Standard_Boolean locMayEdit = myTopoMode;
-      if ( myTopoMode ) { //:j6 abv 7 Dec 98: ProSTEP TR10 r0601_id.stp #57676 & #58586: do not cut edges because of influence on adjacent faces
+      if ( locMayEdit )
+      {
+        newtol = 1.0001 * ( pnt.Distance ( pint ) + rad );
+        //:j6 abv 7 Dec 98: ProSTEP TR10 r0601_id.stp #57676 & #58586: do not cut edges because of influence on adjacent faces
         ShapeFix_SplitTool aTool;
-        //if ( ! ShapeFix::CutEdge ( E1, ( isForward1 ? a1 : b1 ), param1, Face(), IsCutLine ) ) {
-       if ( ! aTool.CutEdge ( E1, ( isForward1 ? a1 : b1 ), param1, Face(), IsCutLine ) ) {
-         if ( V1.IsSame ( Vp ) )
-           myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
-         else locMayEdit = Standard_False;
-       }
-       else cutEdge1 = Standard_True; //:h4
-       //if ( ! ShapeFix::CutEdge ( E2, ( isForward2 ? b2 : a2 ), param2, Face(), IsCutLine ) ) {
-       if ( ! aTool.CutEdge ( E2, ( isForward2 ? b2 : a2 ), param2, Face(), IsCutLine ) ) {
-         if ( V2.IsSame ( Vn ) ) 
-           myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
-         else locMayEdit = Standard_False;
-       }
-       else cutEdge2 = Standard_True; //:h4
-      }
-      if ( locMayEdit &&
-          newRange1 <= prevRange1 && newRange2 <= prevRange2 && //rln 09/01/98
-          BRep_Tool::SameParameter ( E1 ) &&
-          BRep_Tool::SameParameter ( E2 ) ) {
-       myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
-       pnt = pint;
-       if ( tol <= rad ) {
-         myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
-         tol = 1.001 * rad;
-       }
+        
+        if ( ! aTool.CutEdge ( E1, ( isForward1 ? a1 : b1 ), param1, Face(), IsCutLine ) ) {
+          if ( V1.IsSame ( Vp ) )
+            myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
+          else locMayEdit = Standard_False;
+        }
+        else cutEdge1 = Standard_True; //:h4
+        
+        if ( ! aTool.CutEdge ( E2, ( isForward2 ? b2 : a2 ), param2, Face(), IsCutLine ) ) {
+          if ( V2.IsSame ( Vn ) ) 
+            myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
+          else locMayEdit = Standard_False;
+        }
+        else cutEdge2 = Standard_True; //:h4
       }
-      else if(IsCutLine) {
-       myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
-       pnt = pint;
-       if ( tol <= rad ) {
-         myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
-         tol = 1.001 * rad;
-       }
+
+      if (  locMayEdit &&
+            newRange1 <= prevRange1 && newRange2 <= prevRange2 && //rln 09/01/98
+            BRep_Tool::SameParameter ( E1 ) &&
+            BRep_Tool::SameParameter ( E2 ) )
+      {
+        myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
+        pnt = pint;
+        if ( tol <= rad ) {
+          myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
+          tol = 1.001 * rad;
+        }
       }
-      else { // else increase tolerance
-       if (tol < newtol) { //rln 07.04.99 CCI60005-brep.igs
-         myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
-         tol = newtol;
-       }
+      else
+      {
+        if(IsCutLine)
+        {
+          myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
+          pnt = pint;
+          if ( tol <= rad ) {
+            myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
+            tol = 1.001 * rad;
+          }
+        }
+        else
+        { // else increase tolerance
+          if (tol < newtol)
+          { //rln 07.04.99 CCI60005-brep.igs
+            myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
+            tol = newtol;
+          }
+        }
       }
     }
-    else myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
+    else
+    {
+      myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
+    }
   }
 
   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 );
   }
@@ -2438,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 ) ) {
@@ -2680,16 +2910,17 @@ static Standard_Boolean TryBendingPCurve (const TopoDS_Edge &E, const TopoDS_Fac
       else return Standard_False;
     }
     c2d = bs;
+
+    if ( ! TryNewPCurve ( E, face, c2d, first, last, tol ) ) return Standard_False;
   }
   catch ( Standard_Failure ) {
-#ifdef DEB
+#ifdef OCCT_DEBUG
     cout << "Warning: ShapeFix_Wire::FixLacking: Exception in Geom2d_BSplineCurve::Segment()" << endl;
 #endif
     return Standard_False;
   }
   }
-  
-  if ( ! TryNewPCurve ( E, face, c2d, first, last, tol ) ) return Standard_False;
+
   return Standard_True;
 }
 
@@ -2708,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 );
   }
@@ -2914,7 +3145,7 @@ Standard_Boolean ShapeFix_Wire::FixLacking (const Standard_Integer num,
     // insert new edge
     if ( doAddDegen ) {
       myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
-#ifdef DEB
+#ifdef OCCT_DEBUG
       cout << "Warning: ShapeFix_Wire::FixLacking: degenerated edge added" << endl;
 #endif
     }
@@ -2947,7 +3178,7 @@ Standard_Boolean ShapeFix_Wire::FixLacking (const Standard_Integer num,
     FixSelfIntersectingEdge ( n1 );
     FixSelfIntersectingEdge ( n2 );
     FixIntersectingEdges ( n2 ); //skl 24.04.2003 for OCC58
-#ifdef DEB
+#ifdef OCCT_DEBUG
     cout << "Info: ShapeFix_Wire::FixLacking: Bending pcurves" << endl;
 #endif
     myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
@@ -2976,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();
@@ -3056,7 +3287,11 @@ Standard_Boolean ShapeFix_Wire::FixNotchedEdges()
        myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
       }
       else 
-       FixDummySeam(n1);
+      {
+        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
@@ -3242,3 +3477,171 @@ void ShapeFix_Wire::UpdateWire ()
     sbwd->Remove ( i-- );
   }
 }
+
+//=======================================================================
+//function : FixTails
+//purpose  :
+//=======================================================================
+Standard_Boolean ShapeFix_Wire::FixTails()
+{
+  if (myMaxTailWidth < 0 || !IsReady())
+  {
+    return Standard_False;
+  }
+
+  myLastFixStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
+  if (!Context().IsNull())
+  {
+    UpdateWire();
+  }
+  Handle(ShapeExtend_WireData) aSEWD = WireData();
+  Standard_Integer aECount = NbEdges(), aENs[] = {aECount, 1};
+  Standard_Boolean aCheckAngle = Standard_True;
+  while (aECount >= 2 && aENs[1] <= aECount)
+  {
+    const TopoDS_Edge aEs[] = {aSEWD->Edge(aENs[0]), aSEWD->Edge(aENs[1])};
+    TopoDS_Edge aEParts[2][2];
+    if (!myAnalyzer->CheckTail(aEs[0], aEs[1],
+      aCheckAngle ? myMaxTailAngleSine : -1, myMaxTailWidth, MaxTolerance(),
+      aEParts[0][0], aEParts[0][1], aEParts[1][0], aEParts[1][1]))
+    {
+      aENs[0] = aENs[1]++;
+      aCheckAngle = Standard_True;
+      continue;
+    }
+
+    // Provide not less than 1 edge in the result wire.
+    Standard_Integer aSplitCounts[] =
+      {aEParts[0][1].IsNull() ? 0 : 1, aEParts[1][1].IsNull() ? 0 : 1};
+    const Standard_Integer aRemoveCount =
+      (aEParts[0][0].IsNull() ? 0 : 1) + (aEParts[1][0].IsNull() ? 0 : 1);
+    if (aECount + aSplitCounts[0] + aSplitCounts[1] < 1 + aRemoveCount)
+    {
+      aENs[0] = aENs[1]++;
+      aCheckAngle = Standard_True;
+      continue;
+    }
+
+    // Split the edges.
+    for (Standard_Integer aEI = 0; aEI < 2; ++aEI)
+    {
+      if (aSplitCounts[aEI] == 0)
+      {
+        continue;
+      }
+
+      // Replace the edge by the wire of its parts in the shape.
+      const TopoDS_Edge aE = aEs[aEI];
+      if (!Context().IsNull())
+      {
+        TopoDS_Wire aEWire;
+        BRep_Builder().MakeWire(aEWire);
+        BRep_Builder().Add(aEWire, aEParts[aEI][0]);
+        BRep_Builder().Add(aEWire, aEParts[aEI][1]);
+        TopoDS_Edge aFE = TopoDS::Edge(aE.Oriented(TopAbs_FORWARD));
+        Context()->Replace(aFE, aEWire);
+      }
+
+      // Replace the edge by its parts in the edge wire.
+      const TopAbs_Orientation aOrient = aE.Orientation();
+      aEParts[aEI][0].Orientation(aOrient);
+      aEParts[aEI][1].Orientation(aOrient);
+      const Standard_Integer aFirstPI = (aOrient != TopAbs_REVERSED) ? 0 : 1;
+      const Standard_Integer aAdd =
+        (aEI == 0 || aENs[1] < aENs[0]) ? 0 : aSplitCounts[0];
+      aSEWD->Set(aEParts[aEI][aFirstPI], aENs[aEI] + aAdd);
+      aSEWD->Add(aEParts[aEI][1 - aFirstPI], aENs[aEI] + 1 + aAdd);
+    }
+
+    // Remove the tail.
+    if (aRemoveCount == 2)
+    {
+      aCheckAngle = Standard_True;
+      FixDummySeam(aENs[0] + aSplitCounts[0] +
+        ((aENs[0] < aENs[1]) ? 0 : aSplitCounts[1]));
+      if (!Context().IsNull())
+      {
+        UpdateWire();
+      }
+      myLastFixStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE);
+
+      if (aSplitCounts[0] + aSplitCounts[1] == 2)
+      {
+        aENs[0] = aENs[1]++;
+        continue;
+      }
+
+      if (aSplitCounts[0] == aSplitCounts[1])
+      {
+        aECount -= 2;
+        if (aENs[1] >= 3)
+        {
+          --aENs[0];
+          --aENs[1];
+        }
+        else
+        {
+          aENs[0] = aECount;
+          aENs[1] = 1;
+        }
+        aCheckAngle = Standard_False;
+      }
+      else
+      {
+        --aECount;
+        if (aSplitCounts[0] != 0)
+        {
+          aENs[0] = (aENs[0] <= aECount) ? aENs[0] : aECount;
+        }
+        else
+        {
+          if (aENs[1] >= 3)
+          {
+            --aENs[0];
+            --aENs[1];
+          }
+          else
+          {
+            aENs[0] = aECount;
+            aENs[1] = 1;
+          }
+        }
+      }
+    }
+    else
+    {
+      aCheckAngle = Standard_False;
+      --aECount;
+      const Standard_Integer aRI = aEParts[0][0].IsNull() ? 1 : 0;
+      if (aSplitCounts[aRI] != 0)
+      {
+        if (aRI == 0)
+        {
+          if (aENs[1] >= 3)
+          {
+            --aENs[0];
+            --aENs[1];
+          }
+          else
+          {
+            aENs[0] = aECount;
+            aENs[1] = 1;
+          }
+        }
+        else
+        {
+          aENs[0] = (aENs[1] > 1) ? aENs[0] : aECount;
+        }
+      }
+      aSEWD->Remove(aENs[aRI] + ((aRI != 0 || aSplitCounts[0] == 0) ? 0 : 1));
+      if (!Context().IsNull())
+      {
+        Context()->Remove(aEs[aRI].Oriented(TopAbs_FORWARD));
+        UpdateWire();
+      }
+      myLastFixStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE);
+    }
+  }
+  myStatusNotches = myLastFixStatus;
+  return ShapeExtend::DecodeStatus(myLastFixStatus, ShapeExtend_DONE);
+}