0024083: BRepCheck_Wire crashes processing a wire consisting of many edges
[occt.git] / src / BRepCheck / BRepCheck_Wire.cxx
index 8c1be90..fb576ed 100755 (executable)
@@ -1,13 +1,27 @@
-// File:        BRepCheck_Wire.cxx
-// Created:        Tue Dec 12 17:49:08 1995
-// Author:        Jacques GOUSSARD
-//                <jag@bravox>
-// Modified by dpf, Fri Dec 19 15:31:03 1997 
-//   Taitement de la fermeture en 2d.
+// Created on: 1995-12-12
+// Created by: Jacques GOUSSARD
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
 //
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+// Modified by dpf, Fri Dec 19 15:31:03 1997 
+//  Processing of closing in 2d.
 //  modified by eap Tue Dec 18 14:14:25 2001 (bug OCC23)
 //   Check self-intersection in case of closed edge
-//
 //  modified by eap Fri Dec 21 17:36:55 2001 (bug OCC35)
 //   Closed2d() added
 
@@ -137,7 +151,7 @@ void BRepCheck_Wire::Minimum()
     myMap.Bind(myShape, thelist);
     BRepCheck_ListOfStatus& lst = myMap(myShape);
 
-    // on verifie que le wire est "connexe" == check that the wire is "connex"
+    // check that the wire is "connex"
     TopExp_Explorer exp(myShape,TopAbs_EDGE);
     Standard_Integer nbedge = 0;
     myMapVE.Clear();
@@ -212,7 +226,7 @@ void BRepCheck_Wire::InContext(const TopoDS_Shape& S)
 
   case TopAbs_FACE:
     {
-      TopoDS_Edge ed1,ed2; // bidon
+      TopoDS_Edge ed1,ed2; 
       if (myGctrl) 
         st = SelfIntersect(TopoDS::Face(S),ed1,ed2,Standard_True);
       if (st != BRepCheck_NoError) break;
@@ -240,7 +254,7 @@ void BRepCheck_Wire::InContext(const TopoDS_Shape& S)
 void BRepCheck_Wire::Blind()
 {
   if (!myBlind) {
-    // rien de plus que dans le minimum
+    // nothing more that the minimum
     myBlind = Standard_True;
   }
 }
@@ -258,12 +272,12 @@ BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
     return myCstat;
   }
 
-  myCdone = Standard_True; // ce sera fait...
+  myCdone = Standard_True;
 
   BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
   if (itl.Value() != BRepCheck_NoError) {
     myCstat = itl.Value();
-    return myCstat; // deja enregistre
+    return myCstat; // already saved 
   }
 
   myCstat = BRepCheck_NoError;
@@ -355,71 +369,190 @@ BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
   }
   return myCstat;
 }
+
+//=======================================================================
+//function : IsDistanceIn3DTolerance
+//purpose  : Return Standard_True if distance between thePnt_f and
+//           thePnt_l is not more, than aTol3d
+//=======================================================================
+Standard_Boolean IsDistanceIn3DTolerance (const BRepAdaptor_Surface& /*aFaceSurface*/,
+                                          const gp_Pnt& thePnt_f,
+                                          const gp_Pnt& thePnt_l,
+                                          const Standard_Real aTol3d)
+  {
+  Standard_Real Dist           = thePnt_f.Distance(thePnt_l);
+  
+  if (Dist < aTol3d)
+    return Standard_True;
+
+#ifdef DEB
+  cout << endl;
+  cout << "--------Function IsDistanceIn3DTolerance(...)----------"                                                                                            << endl;
+  cout << "--- BRepCheck Wire: Closed3d -> Error"                                                                                                                                                                      << endl;
+  cout << "--- Dist (" << Dist << ") > Tol3d (" << aTol3d << ")"                                                                                                       << endl;
+  cout << "Pnt1(" << thePnt_f.X() << "; " << thePnt_f.Y() << "; " << thePnt_f.Z() << ")"       << endl;
+  cout << "Pnt2(" << thePnt_l.X() << "; " << thePnt_l.Y() << "; " << thePnt_l.Z() << ")"       << endl;
+  cout << "------------------------------------------------------"                                                                                             << endl;
+#endif
+
+  return Standard_False;
+  }
+
+//=======================================================================
+//function : IsDistanceIn3DTolerance
+//purpose  : 
+//=======================================================================
+Standard_Boolean IsDistanceIn2DTolerance (const BRepAdaptor_Surface& aFaceSurface,
+                                          const gp_Pnt2d& thePnt,
+                                          const gp_Pnt2d& thePntRef,
+                                          const Standard_Real aTol3d,
+                                          const Standard_Boolean PrintWarnings = Standard_True)
+  {
+  Standard_Real dumax = 0.01 * (aFaceSurface.LastUParameter() - aFaceSurface.FirstUParameter());
+  Standard_Real dvmax = 0.01 * (aFaceSurface.LastVParameter() -        aFaceSurface.FirstVParameter());
+  Standard_Real dumin = Abs(thePnt.X() - thePntRef.X());
+  Standard_Real dvmin = Abs(thePnt.Y() - thePntRef.Y());
+  
+  if((dumin < dumax) && (dvmin < dvmax))
+    return Standard_True;
+
+#ifdef DEB
+  if(PrintWarnings)
+    {
+    cout << endl;
+    cout << "--------Function IsDistanceIn2DTolerance(...)----------"                                                          << endl;
+    cout << "--- BRepCheck Wire: Not closed in 2d"                                                                                                                               << endl;
+    cout << "*****************************************************"                                                                    << endl;
+    cout << "*dumin = " << dumin << "; dumax = " << dumax                                                                                                              << endl;
+    cout << "* dvmin = " << dvmin << "; dvmax = " << dvmax                                                                                                     << endl;
+    cout << "* (dumin > dumax) or (dvmin > dvmax)."                                                                                                                                    << endl;
+    cout << "*****************************************************"                                                                    << endl;
+    cout << endl;
+    cout << "UFirst = "  << aFaceSurface.FirstUParameter();
+    cout << "; ULast = " << aFaceSurface.LastUParameter()                                                                                                              << endl;
+    cout << "VFirst = " << aFaceSurface.FirstVParameter();
+    cout << "; VLast = " << aFaceSurface.LastVParameter()                                                                                                              << endl;
+    }
+
+  dumax = aFaceSurface.UResolution(aTol3d);
+  dvmax = aFaceSurface.VResolution(aTol3d);
+
+  if(PrintWarnings)
+    {
+    cout << "aTol3d = " << aTol3d <<"; URes = " << dumax << "; VRes = " << dvmax               << endl;
+    cout << "thePnt(" << thePnt.X() << "; " << thePnt.Y() << ")"                                                                               << endl;
+    cout << "thePntRef(" << thePntRef.X() << "; " << thePntRef.Y() << ")"                                              << endl;
+    }
+
+#else
+  dumax = aFaceSurface.UResolution(aTol3d);
+  dvmax = aFaceSurface.VResolution(aTol3d);
+#endif
+
+  Standard_Real aTol2d = 2*Max(        dumax, dvmax);
+  
+#ifdef DEB
+  if((aTol2d <= 0.0) && (PrintWarnings))
+    {
+    cout<<"BRepCheck_Wire : UResolution and VResolution = 0.0 (Face too small ?)"<<endl;
+    cout.flush();
+    }
+#endif
+
+  //Standard_Real Dist = thePntRef.Distance(thePnt);
+  Standard_Real Dist = Max(dumin, dvmin);
+  
+  if (Dist < aTol2d)
+    return Standard_True;
+
+#ifdef DEB
+  if(PrintWarnings)
+    {
+    cout << endl;
+    cout << "--------Function IsDistanceIn2DTolerance(...)----------"                                                  << endl;
+    cout << "--- BRepCheck Wire: Not closed in 2d"                                                                                                                     << endl;
+    cout << "*****************************************************"                                                            << endl;
+    cout << "* Dist = " << Dist        << " > Tol2d = " <<     aTol2d                                                                                          << endl;
+    cout << "*****************************************************"                                                            << endl;
+    cout << "aTol3d = " << aTol3d <<"; URes = " << dumax << "; VRes = " << dvmax       << endl;
+    cout << "thePnt(" << thePnt.X() << "; " << thePnt.Y() << ")"                                                                       << endl;
+    cout << "thePntRef(" << thePntRef.X() << "; " << thePntRef.Y() << ")"                                      << endl;
+    }
+#endif
+
+  return Standard_False;
+  }
+
 //=======================================================================
 //function : Closed2d
 //purpose  : for periodic faces
 //=======================================================================
 BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
                                           const Standard_Boolean Update)
-{
-
-  // 3d closure checked?
+  {
+  // 3d closure checked too
   BRepCheck_Status aClosedStat = Closed();
-  if (aClosedStat != BRepCheck_NoError) {
-    if (Update) 
+  if (aClosedStat != BRepCheck_NoError)
+    {
+    if (Update)
       BRepCheck::Add(myMap(myShape),aClosedStat);
+
     return aClosedStat;
-  }
+    }
 
-  // 20/03/02 akm vvv : (OCC234) Hence this method will be used to check
-  //                    both periodic and non-periodic faces
-  //   // this check is for periodic faces 
+// 20/03/02 akm vvv : (OCC234) Hence this method will be used to check
+//                    both periodic and non-periodic faces
+//   // this check is for periodic faces 
   BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
-  // if (!aFaceSurface.IsUPeriodic() && !aFaceSurface.IsVPeriodic())
-  // {
-  //   if (Update) 
-  //     BRepCheck::Add(myMap(myShape),aClosedStat);
-  //   return aClosedStat;
-  // }
-  // 20/03/02 akm ^^^
-  
-  // count edges having FORWARD or REVERSED orientation
+// if (!aFaceSurface.IsUPeriodic() && !aFaceSurface.IsVPeriodic())
+// {
+//   if (Update) 
+//     BRepCheck::Add(myMap(myShape),aClosedStat);
+//   return aClosedStat;
+// }
+// 20/03/02 akm ^^^
+
+// count edges having FORWARD or REVERSED orientation
   Standard_Integer aNbOrirntedEdges = 0;
   TopExp_Explorer anEdgeExp(myShape,TopAbs_EDGE);
-  for (;anEdgeExp.More(); anEdgeExp.Next()) {
+  for (;anEdgeExp.More(); anEdgeExp.Next())
+    {
     if (IsOriented(anEdgeExp.Current())) 
       aNbOrirntedEdges++;
-  }
+    }
+
   if (aNbOrirntedEdges==0)
-  {
-    if (Update) 
+    {
+    if (Update)
       BRepCheck::Add(myMap(myShape),aClosedStat);
+
     return aClosedStat;
-  }
-  
-  // all those edges must form a closed 2d contour and be found by WireExplorer
+    }
 
-  Standard_Integer aNbFoundEdges = 0;
+// all those edges must form a closed 2d contour and be found by WireExplorer
 
+  Standard_Integer aNbFoundEdges = 0;
   BRepTools_WireExplorer aWireExp(TopoDS::Wire(myShape), theFace);
   TopoDS_Edge aFirstEdge = aWireExp.Current();
   TopoDS_Vertex aFirstVertex = aWireExp.CurrentVertex();
   TopoDS_Edge aLastEdge;
+
   for (;aWireExp.More(); aWireExp.Next())
-  {
+    {
     aNbFoundEdges++;
     aLastEdge = aWireExp.Current();
-  }
+    }
 
   if (aNbFoundEdges != aNbOrirntedEdges)
-  {
+    {
     aClosedStat = BRepCheck_NotClosed;
     if (Update) 
       BRepCheck::Add(myMap(myShape),aClosedStat);
-    return aClosedStat;
-  }
     
-  // Check distance between 2d ends of first and last edges
+    return aClosedStat;
+    }
+
+// Check distance between 2d ends of first and last edges
 //  Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 Begin
 //   First check if first and last edges are infinite:
   Standard_Real      aF;
@@ -430,92 +563,89 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
 
   anOri = aFirstEdge.Orientation();
   BRep_Tool::Range(aFirstEdge, aF, aL);
-  if ((anOri == TopAbs_FORWARD  && aF == -Precision::Infinite()) ||
-      (anOri == TopAbs_REVERSED && aL ==  Precision::Infinite()))
+  if ((anOri == TopAbs_FORWARD  && Precision::IsNegativeInfinite( aF )) ||
+         (anOri == TopAbs_REVERSED && Precision::IsPositiveInfinite( aL )))
     isFirstInfinite = Standard_True;
 
   anOri = aLastEdge.Orientation();
   BRep_Tool::Range(aLastEdge, aF, aL);
-  if ((anOri == TopAbs_FORWARD  && aL ==  Precision::Infinite()) ||
-      (anOri == TopAbs_REVERSED && aF == -Precision::Infinite()))
+  
+  if ((anOri == TopAbs_FORWARD  && Precision::IsPositiveInfinite( aL )) ||
+         (anOri == TopAbs_REVERSED && Precision::IsNegativeInfinite( aF )))
     isLastInfinite = Standard_True;
 
-  if (isFirstInfinite && isLastInfinite) {
-    if (Update) 
+  if (isFirstInfinite && isLastInfinite)
+    {
+    if (Update)
       BRepCheck::Add(myMap(myShape),aClosedStat);
+
     return aClosedStat;
-  } else if (aFirstVertex.IsNull()) {
+    }
+  else if (aFirstVertex.IsNull())
+    {
     aClosedStat = BRepCheck_NotClosed;
+    
     if (Update) 
       BRepCheck::Add(myMap(myShape),aClosedStat);
+    
     return aClosedStat;
-  }
+    }
 //  Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 End
 
-  gp_Pnt2d p, p1, p2; // ends of prev edge, next edge, bidon
-
-  // get first point
-  BRep_Tool::UVPoints(aLastEdge, theFace, p2, p);
-  if (aLastEdge.Orientation() == TopAbs_REVERSED) p = p2; 
+  gp_Pnt2d aP_first, aP_last, aP_temp; // ends of prev edge, next edge, bidon
   
+// get last point
+  BRep_Tool::UVPoints(aLastEdge, theFace, aP_temp, aP_last);
+  if (aLastEdge.Orientation() == TopAbs_REVERSED)
+    aP_last = aP_temp;
+
 //  Modified by Sergey KHROMOV - Mon Apr 22 10:36:33 2002 Begin
 //   Standard_Real aTol, aUResol, aVResol;
-
 //   // find 2d tolerance
 //   aTol  = BRep_Tool::Tolerance(aFirstVertex);
 //   aUResol = 2*aFaceSurface.UResolution(aTol);
 //   aVResol = 2*aFaceSurface.VResolution(aTol);
 
-  // get second point
+// get first point
   if (aFirstEdge.Orientation() == TopAbs_REVERSED)
-    BRep_Tool::UVPoints(aFirstEdge, theFace, p2, p1);
+    BRep_Tool::UVPoints(aFirstEdge, theFace, aP_temp, aP_first);
   else 
-    BRep_Tool::UVPoints(aFirstEdge, theFace, p1, p2);
+    BRep_Tool::UVPoints(aFirstEdge, theFace, aP_first, aP_temp);
 
 //  Modified by Sergey KHROMOV - Thu Jun 20 10:55:42 2002 OCC325 Begin
 // Check 2d distance for periodic faces with seam edge
-  if (!IsClosed2dForPeriodicFace(theFace, p, p1, aFirstVertex)) {
+  if (!IsClosed2dForPeriodicFace(theFace, aP_first, aP_last, aFirstVertex))
+    {
     aClosedStat = BRepCheck_NotClosed;
-    if (Update) 
+    if (Update)
       BRepCheck::Add(myMap(myShape),aClosedStat);
+    
     return aClosedStat;
-  }
+    }
 //  Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End
 
-  // check distance
+// check distance
 //   Standard_Real dfUDist=Abs(p.X()-p1.X());
 //   Standard_Real dfVDist=Abs(p.Y()-p1.Y());
 //   if (dfUDist > aUResol || dfVDist > aVResol)
 //   {
-  Standard_Real aTol3d = BRep_Tool::Tolerance(aFirstVertex);
-  gp_Pnt        aPRef  = BRep_Tool::Pnt(aFirstVertex);
-  gp_Pnt        aP1    = aFaceSurface.Value(p.X(),  p.Y());
-  gp_Pnt        aP2    = aFaceSurface.Value(p1.X(), p1.Y());
-  Standard_Real Dist1  = aPRef.Distance(aP1);
-  Standard_Real Dist2  = aPRef.Distance(aP2);
-
-  if (Dist1 > aTol3d || Dist2 > aTol3d) {
-//  Modified by Sergey KHROMOV - Mon Apr 22 10:36:44 2002 End
-#ifdef DEB
-    cout << endl;
-    cout << "------------------------------------------------------"   <<endl;
-    cout << "--- BRepCheck Wire: Closed2d -> Erreur"                   <<endl;
-    if (Dist1 > aTol3d)
-      cout << "--- Dist1 (" << Dist1 << ") > Tol3d (" << aTol3d << ")" <<endl;
-    if (Dist2 > aTol3d)
-      cout << "--- Dist2 (" << Dist2 << ") > Tol3d (" << aTol3d << ")" <<endl;
-    cout << "------------------------------------------------------"   <<endl;
-#endif
+
+  Standard_Real aTol3d = Max(BRep_Tool::Tolerance(aFirstVertex),BRep_Tool::Tolerance(aWireExp.CurrentVertex()));
+
+  gp_Pnt aPntRef = BRep_Tool::Pnt(aFirstVertex);
+  gp_Pnt aPnt           = BRep_Tool::Pnt(aWireExp.CurrentVertex());
+
+  if (!(IsDistanceIn2DTolerance(aFaceSurface, aP_first, aP_last, aTol3d)))
     aClosedStat = BRepCheck_NotClosed;
-    if (Update) 
-      BRepCheck::Add(myMap(myShape),aClosedStat);
-    return aClosedStat;
-  }
-  
+
+  if(!IsDistanceIn3DTolerance(aFaceSurface, aPntRef, aPnt, aTol3d))
+    aClosedStat = BRepCheck_NotClosed;
+
   if (Update) 
     BRepCheck::Add(myMap(myShape),aClosedStat);
+
   return aClosedStat;
-}
+  }
 //=======================================================================
 //function : Orientation
 //purpose  : 
@@ -534,11 +664,7 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
   theOstat = BRepCheck_NoError;
 
   TopoDS_Vertex VF,VL;
-#ifndef DEB
   TopAbs_Orientation orient, ortmp = TopAbs_FORWARD;
-#else
-  TopAbs_Orientation orient, ortmp;
-#endif
   TopTools_ListOfShape ledge, ListOfPassedEdge;
   TopExp_Explorer exp,vte;
   TopTools_MapOfShape mapS;
@@ -583,8 +709,8 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
     while (Index < nbOriNoDegen) {
       ledge.Clear();
       ListOfPassedEdge.Clear();
-      // on cherche les edges qui s`enchainent sur VL si !VL.IsNull 
-      // sinon sur VF.
+      // find edges that make a chain on VL if !VL.IsNull 
+      // otherwise on VF.
       
       Standard_Integer ind;
       if (!VL.IsNull()) {
@@ -633,17 +759,17 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
             TopAbs_Orientation vto = vte.Current().Orientation();
             if (!VL.IsNull()) {
               if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current())) {
-                // Si on travaille en 2d (face non nulle) ou 
-                // si l'edge n'est pas degenere on l'ajoute
+                // If the processing is in 2d (face not null) or 
+                // if the edge is not degenerated it is added
                 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
                   ledge.Append(edg);
                 break;
               }
             }
-            else { // VF n`est pas nul
+            else { // VF is not null
               if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
-                // Si on travaille en 2d (face non nulle) ou 
-                // si l'edge n'est pas degenere on l'ajoute
+                //    // If the processing is in 2d (face not null) or 
+                // if the edge is not degenerated it is added
                 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
                   ledge.Append(edg);
                 break;
@@ -660,11 +786,11 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
             if (Update) {
               BRepCheck::Add(myMap(myShape),theOstat);
             }
-            return theOstat; // on sort
+            return theOstat; // leave
           }
           else {
-            Index--; // parce que apres Index++ et on n`a pas enchaine
-            VL.Nullify(); // on force a enchainer sur VF
+            Index--; // because after Index++ and if there is no chain,
+            VL.Nullify(); // chain on VF is forced
             theEdge = theRef;
             Changedesens = Standard_True;
           }
@@ -678,8 +804,8 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
         }
       }
 
-      // JAG 03/07   else if (nbconnex >= 2 && !F.IsNull())  // On essaie de voir en 2d
-      else if (!F.IsNull()) { // On essaie de voir en 2d
+      // JAG 03/07   else if (nbconnex >= 2 && !F.IsNull())  // Try to see in 2d
+      else if (!F.IsNull()) { // Try to see in 2d
         TopoDS_Vertex pivot;
         if (!VL.IsNull()) {
           pivot = VL;
@@ -710,7 +836,7 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
         return theOstat;
       }
       else if (nbconnex == 1) {
-        // decaler le vertex
+        // offset the vertex
         for (vte.Init(ledge.First(),TopAbs_VERTEX);vte.More(); vte.Next()) {
           TopAbs_Orientation vto = vte.Current().Orientation();
           if (!VL.IsNull()) {
@@ -719,7 +845,7 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
               break;
             }
           }
-          else { // VF n`est pas nul
+          else { // VF is not null
             if (vto == TopAbs_FORWARD) {
               VF = TopoDS::Vertex(vte.Current());
               break;
@@ -745,7 +871,7 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
        return theOstat;
       }
 
-      // On verifie la fermeture du wire en 2d (pas fait dans Closed())
+      // Check the closure of the wire in 2d (not done in Closed())
       
       TopoDS_Vertex    aVRef;
       Standard_Boolean isCheckClose = Standard_False;
@@ -790,7 +916,7 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
          return theOstat;
        }
       }
-      // Fin controle fermeture 2d
+      // End control closure 2d
 
       Index ++;
     }
@@ -824,8 +950,8 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
   TopTools_MapOfOrientedShape auxmape;
   //
   ok=Standard_True;
-  //-- on verifie plus loin avec les bonnes tolerances si on n a 
-  //-- pas un point dans la tolerance d un vertex.
+  //-- check with proper tolerances if there is no 
+  //-- point in the tolerance of a vertex.
   tolint = 1.e-10; 
   HS = new BRepAdaptor_HSurface();
   HS->ChangeSurface().Initialize(F,Standard_False);
@@ -887,7 +1013,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
     //
     if(Inter.IsDone()) { 
       Standard_Integer nbp = Inter.NbPoints();
-      Standard_Integer nbs = Inter.NbSegments();
+      //Standard_Integer nbs = Inter.NbSegments();
       //
       for(Standard_Integer p=1;p<=nbp;p++) {
        const IntRes2d_IntersectionPoint& IP=Inter.Point(p);
@@ -895,15 +1021,15 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
        const IntRes2d_Transition& Tr2 = IP.TransitionOfSecond();
        if(   Tr1.PositionOnCurve() == IntRes2d_Middle
           || Tr2.PositionOnCurve() == IntRes2d_Middle) { 
-         //-- Verification des points avec les vraies tolerances (ie Tol en 3d)
-         //-- Si le point d intersection est dans la tolearnce d un des vertex
-         //-- on considere que cette intersection est bonne (pas d erreur)
+         //-- Checking of points with true tolerances (ie Tol in 3d)
+         //-- If the point of intersection is within the tolearnce of a vertex
+         //-- this intersection is considered correct (no error)
          Standard_Boolean localok = Standard_False;
          Standard_Real f,l;
          TopLoc_Location L;
          const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f,l);
          if(!ConS.IsNull()) { 
-           //-- on va tester en 3d. (ParamOnSecond donne le m resultat)
+           //-- try to test in 3d. (ParamOnSecond gives the same result)
            P3d = ConS->Value(IP.ParamOnFirst()); 
            P3d.Transform(L.Transformation());
            //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
@@ -992,7 +1118,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
       //modified by NIZNHY-PKV Fri Oct 29 10:09:02 2010t
       //
       //-- ************************************************************
-      //-- ******* I n t e r s e c t i o n   C 1   e t   C 2   ********
+      //-- ******* I n t e r s e c t i o n   C 1   and   C 2   ********
       //-- ************************************************************
       Inter.Perform(C1,myDomain1,C2,tabDom[j-1],tolint,tolint);
       //
@@ -1031,9 +1157,9 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
          Tr2 = IP.TransitionOfSecond();
          if(   Tr1.PositionOnCurve() == IntRes2d_Middle
             || Tr2.PositionOnCurve() == IntRes2d_Middle)   {
-           //-- Verification des points avec les vraies tolerances (ie Tol en 3d)
-           //-- Si le point d intersection est dans la tolearnce d un des vertex
-           //-- on considere que cette intersection est bonne (pas d erreur)
+           //-- Checking of points with true tolerances (ie Tol in 3d)
+           //-- If the point of intersection is within the tolerance of a vertex
+           //-- this intersection is considered correct (no error)
            Standard_Boolean localok = Standard_False;  
            Standard_Real f1,l1, f2, l2;
            TopLoc_Location L, L2;
@@ -1046,7 +1172,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
                f2-IP_ParamOnSecond > ::Precision::PConfusion() || 
                IP_ParamOnSecond-l2 > ::Precision::PConfusion() ) 
              continue;
-           Standard_Real tolvtt;
+           Standard_Real tolvtt = 0.;
            //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
            if (!ConS.IsNull()) { 
              P3d = ConS->Value(IP_ParamOnFirst); 
@@ -1086,10 +1212,10 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
            }
            
            //-- --------------------------------------------------------
-           //-- Verification sur le baillement maximum entre les 2 edges
+           //-- Check maximum yawn between 2 edges
            //--
-           //-- On verifie la distance des edges a la courbe joignant 
-           //-- le point d intersection au vertex (s il existe)
+           //-- Check distance from edges to the curve joining 
+           //-- the point of intersection with vertex (if exists)
            if (localok == Standard_False && !CommonVertices.IsEmpty()) {
 #ifdef DEB     
              cout << "\n------------------------------------------------------\n" <<endl;
@@ -1151,7 +1277,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
                localok = Standard_True;
                Standard_Real tole1 = BRep_Tool::Tolerance(E1);
                for (k = 2; localok && k < 9; k++)      { 
-                 Standard_Real u = VParaOnEdge1 + k*du1;  // voyons deja voir si ca marche
+                 Standard_Real u = VParaOnEdge1 + k*du1;  // check if it works
                  gp_Pnt P1;
                  //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
                  if (!ConS.IsNull()) {
@@ -1171,7 +1297,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
                    localok = Standard_False;
                  }
                }
-               //-- meme chose pour edge2
+               //-- same for edge2
                //  Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764 Begin
                gp_Dir aTmpDir(P3d2.XYZ().Subtracted(VertexLePlusProche.XYZ()));
                
@@ -1179,7 +1305,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
                //  Modified by skv - Wed Jul 23 12:22:23 2003 OCC1764 End
                Standard_Real tole2 = BRep_Tool::Tolerance(E2);
                for (k = 2; localok && k < 9; k++) {
-                 Standard_Real u = VParaOnEdge2 + k*du2;  // voyons deja voir si ca marche
+                 Standard_Real u = VParaOnEdge2 + k*du2;  // check if it works
                  gp_Pnt        P2;
                  //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
                  if (!ConS2.IsNull()) {
@@ -1403,40 +1529,51 @@ Standard_Boolean BRepCheck_Wire::GeometricControls() const
   return myGctrl;
 }
 
-
 //=======================================================================
 //function : Propagate
 //purpose  : fill <mapE> with edges connected to <edg> through vertices
 //           contained in <mapVE>
 //=======================================================================
 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape& mapVE,
-                     const TopoDS_Shape& edg,
-                     TopTools_MapOfShape& mapE)
+                      const TopoDS_Shape& edg,
+                      TopTools_MapOfShape& mapE)
 {
-  if (mapE.Contains(edg)) {
-    return;
-  }
-  mapE.Add(edg); // attention, si oriented == Standard_True, edg doit
-                 // etre FORWARD ou REVERSED. Ce n`est pas verifie.
-                 // =============
-                 // attention, if oriented == Standard_True, <edg> must
-                 // be FORWARD or REVERSED. That is not checked.
-  
-  TopExp_Explorer ex;
-  for (ex.Init(edg,TopAbs_VERTEX); ex.More(); ex.Next()) {
-    const TopoDS_Vertex& vtx = TopoDS::Vertex(ex.Current());
-    // debug jag sur vertex
-    Standard_Integer indv = mapVE.FindIndex(vtx);
-    if (indv != 0) {
-      for (TopTools_ListIteratorOfListOfShape itl(mapVE(indv)); itl.More(); itl.Next()) {
-       if (!itl.Value().IsSame(edg) &&
-           !mapE.Contains(itl.Value())) {
-         Propagate(mapVE,itl.Value(),mapE);
-       }
+  TopTools_ListOfShape currentEdges;
+  currentEdges.Append(edg);
+
+  do
+  {
+    TopTools_ListOfShape nextEdges;
+    TopTools_ListIteratorOfListOfShape itrc(currentEdges);
+    for (; itrc.More(); itrc.Next())
+    {
+      const TopoDS_Shape& Edge = itrc.Value();
+      mapE.Add(Edge);
+
+      TopExp_Explorer ex(Edge, TopAbs_VERTEX);
+      for (; ex.More(); ex.Next())
+      {
+        const TopoDS_Vertex& vtx = TopoDS::Vertex(ex.Current());
+        Standard_Integer indv = mapVE.FindIndex(vtx);
+        if (indv != 0)
+        {
+          const TopTools_ListOfShape& edges = mapVE(indv);
+
+          TopTools_ListIteratorOfListOfShape itl(edges);
+          for (; itl.More(); itl.Next())
+          {
+            const TopoDS_Shape& E = itl.Value();
+            if (!Edge.IsSame(E) && !mapE.Contains(E))
+              nextEdges.Append(E);
+          }
+        }
       }
     }
+    currentEdges = nextEdges;
   }
+  while (!currentEdges.IsEmpty());
 }
+
 //=======================================================================
 //function : GetOrientation
 //purpose  : 
@@ -1455,186 +1592,156 @@ static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape& mapE,
 }
 //=======================================================================
 //function : ChoixUV
-//purpose  : 
+//purpose  : For vertex theVertex given function find an edge along 
+//           that we should go further.
 //=======================================================================
- void ChoixUV(const TopoDS_Vertex& V,
-             const TopoDS_Edge& Edg,
-             const TopoDS_Face& F,
-             TopTools_ListOfShape& L)
-{
-  TopTools_ListIteratorOfListOfShape It( L );
+void ChoixUV(const TopoDS_Vertex& theVertex,
+             const TopoDS_Edge& theEdge,
+             const TopoDS_Face& theFace,
+             TopTools_ListOfShape& theLOfShape)
+  {
+  TopTools_ListIteratorOfListOfShape It( theLOfShape );
   while (It.More())
     {
-      if (Edg.IsSame( It.Value() ))
-       L.Remove( It );
-      else
-       It.Next();
+    if (theEdge.IsSame( It.Value() ))
+      theLOfShape.Remove( It );
+    else
+      It.Next();
     }
 
-  Standard_Integer index = 0, imin = 0;
-  TopoDS_Edge Evois;
-  gp_Pnt2d PntRef, Pnt;
-  gp_Vec2d DerRef, Der;
-  Standard_Real MinAngle, MaxAngle, angle;
-  Standard_Real gpResolution=gp::Resolution();
-  TopAbs_Orientation aVOrientation, aEdgOrientation;
-#ifndef DEB
-  Standard_Real dist2d = 0, p = 0;
-#else
-  Standard_Real dist2d, p;
-#endif
-  Standard_Real f, l, parpiv;
-  Standard_Real tolv = BRep_Tool::Tolerance(V);
-  BRepAdaptor_Surface Ads(F,Standard_False); // no restriction
-  Standard_Real ures = Ads.UResolution(tolv);
-  Standard_Real vres = Ads.VResolution(tolv);
-  Standard_Real tol = Max(ures,vres);
-  if(tol<=0.0) { 
-#ifdef DEB 
-    //-- lbr le 29 jan 98 
-    cout<<"BRepCheck_Wire : UResolution et VResolution = 0.0 (Face trop petite ?)"<<endl;cout.flush();
-#endif
-  }
-  else {
-    tol += tol; //pour YFR.
-  }
-  //
-  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(Edg, F, f, l);
-  if (C2d.IsNull()) {// JAG 10.12.96
+  Standard_Real aTol3d = BRep_Tool::Tolerance(theVertex);
+
+  Standard_Integer anIndex = 0, anIndMin = 0;
+  TopoDS_Edge anEFound;
+  gp_Pnt2d aPntRef, aPnt;
+  gp_Vec2d aDerRef, aDer;
+  Standard_Real aMinAngle, aMaxAngle, anAngle;
+  Standard_Real a_gpResolution=gp::Resolution();
+  TopAbs_Orientation aVOrientation, anEdgOrientation;
+  Standard_Real aParam = 0.0, aFirstParam = 0.0, aLastParam = 0.0, aParPiv = 0.0;
+  BRepAdaptor_Surface aFaceSurface(theFace,Standard_False); // no restriction
+  
+  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirstParam, aLastParam);
+  if (C2d.IsNull())// JAG 10.12.96
     return;
-  }
+
+  aVOrientation = theVertex.Orientation();
+  anEdgOrientation = theEdge.Orientation();
   
-  aVOrientation=V.Orientation();
-  aEdgOrientation=Edg.Orientation();
+  aParPiv =(aVOrientation==anEdgOrientation) ? aFirstParam : aLastParam;
+  aMinAngle = RealLast();
+  aMaxAngle = RealFirst();
 
-  parpiv =(aVOrientation==aEdgOrientation) ? f : l;
-      
-  MinAngle = RealLast();
-  MaxAngle = RealFirst();
+  CurveDirForParameter(C2d, aParPiv, aPntRef, aDerRef);
+  
+  if (aVOrientation != anEdgOrientation)
+    aDerRef.Reverse();
 
-  CurveDirForParameter(C2d, parpiv, PntRef, DerRef);
+  It.Initialize(theLOfShape);
 
-  if (aVOrientation != aEdgOrientation){
-    DerRef.Reverse();
-  }
-  //
-  It.Initialize(L);
-  for (; It.More(); It.Next()) {
-    index++;
-    const TopoDS_Edge& aE=TopoDS::Edge(It.Value());
-    C2d = BRep_Tool::CurveOnSurface(aE, F, f, l);
-    if(C2d.IsNull()) {
+  for (; It.More(); It.Next())
+    {
+    anIndex++;
+    const TopoDS_Edge& anE=TopoDS::Edge(It.Value());
+    C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam);
+    if(C2d.IsNull())
       continue;
-    }
 
-    p =(aVOrientation != aE.Orientation()) ? f : l;
-    //
-    Pnt = C2d->Value(p);
-    dist2d = Pnt.Distance( PntRef );
-    if (dist2d > tol){
+    aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam;
+    aPnt = C2d->Value(aParam);
+
+    if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False))
       continue;
-    }
-    //
-    CurveDirForParameter(C2d, p, Pnt, Der);
-    
-    if (aVOrientation == aE.Orientation()){
-      Der.Reverse();
-    }
-    
-    if (DerRef.Magnitude() <= gpResolution || 
-       Der.Magnitude() <= gpResolution){
+
+    CurveDirForParameter(C2d, aParam, aPnt, aDer);
+
+    if (aVOrientation == anE.Orientation())
+      aDer.Reverse();
+
+    if ((aDerRef.Magnitude() <= a_gpResolution) || 
+                 (aDer.Magnitude() <= a_gpResolution))
+//Vector length is too small
       continue;
-    }
-    //
-    angle = DerRef.Angle( Der );
-    angle *= -1.;
-    if (angle < 0.)
-      angle += 2.*PI;
-    
-    if (F.Orientation() == TopAbs_FORWARD) { 
-      if (angle < MinAngle) {
-       imin = index;
-       MinAngle = angle;
+
+    anAngle = -aDerRef.Angle( aDer );
+
+    if ( anAngle < 0. )
+      anAngle += 2.*M_PI;
+
+    if ( theFace.Orientation() == TopAbs_FORWARD )
+      {
+      if ( anAngle < aMinAngle )
+        {
+        anIndMin = anIndex;
+        aMinAngle = anAngle;
+        }
       }
-    } 
-    else { //F.Orientation() != TopAbs_FORWARD
-      if (angle > MaxAngle){
-       imin = index;
-       MaxAngle = angle;
+    else //theFace.Orientation() != TopAbs_FORWARD
+      {
+      if ( anAngle > aMaxAngle )
+        {
+        anIndMin = anIndex;
+        aMaxAngle = anAngle;
+        }
       }
-    }
-  }//end of for
-  //
-  // Mise a jour ledge
-  if (imin == 0)
-    if (L.Extent() == 1) {
-      Standard_Boolean onjette = 0; //all right
-      Evois = TopoDS::Edge(L.First());
-      if (dist2d > tol) {
-#ifdef DEB 
-       cout<<"BRepCheckWire : controle fermeture en 2d --> faux"<<endl;cout.flush();
-#endif
-       if(Evois.IsNull() || BRep_Tool::Degenerated(Edg) ||
-          BRep_Tool::Degenerated(Evois)){
-         onjette = 1; //bad
-       }
-       else {
-         Ads.Initialize(F);
-         Standard_Real dumax = 0.01 * (Ads.LastUParameter() - Ads.FirstUParameter());
-         Standard_Real dvmax = 0.01 * (Ads.LastVParameter() - Ads.FirstVParameter());
-         Standard_Real dumin = Abs(Pnt.X() - PntRef.X());
-         Standard_Real dvmin = Abs(Pnt.Y() - PntRef.Y());
-         if(dumin > dumax || dvmin > dvmax){
-           onjette = 1;
-         }
-         else {
-           BRepAdaptor_Curve bcEdg(Edg,F);
-           BRepAdaptor_Curve bcEvois(Evois,F);
-           gp_Pnt pEdg = bcEdg.Value(parpiv);
-           gp_Pnt pEvois = bcEvois.Value(p);
-           Standard_Real d3d = pEvois.Distance(pEdg);
-#ifdef DEB
-           cout<<"point P            "<<pEdg.X()<<" "<<pEdg.Y()<<" "<<pEdg.Z()<<endl;
-           cout<<"distance 3d      : "<<d3d<<endl;
-           cout<<"tolerance vertex : "<<tolv<<endl;
-           cout.flush();
-#endif
-           //if(d3d > tolv){
-           if(d3d > 2.*tolv){
-             onjette = 1;
-           }
-#ifdef DEB
-           else
-             cout<<"controle fermeture en 3d --> ok"<<endl;cout.flush();
-#endif
-         }
-       }
-      } //if (dist2d > tol)
-      else {//angle was not defined but points are close
-       onjette = 0;
+    }//end of for
+
+// Update edge
+  if (anIndMin == 0)
+    if (theLOfShape.Extent() == 1)
+      {
+      Standard_Boolean IsFound = Standard_True; //all right
+      anEFound = TopoDS::Edge(theLOfShape.First());
+
+      if(anEFound.IsNull() || BRep_Tool::Degenerated(theEdge) ||
+                                  BRep_Tool::Degenerated(anEFound))
+        IsFound = Standard_False; //bad
+      else if (!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d))
+        IsFound = Standard_False; //bad
+      else 
+        // clousureness in 3D
+        {
+//IsDistanceIn3DTolerance
+        BRepAdaptor_Curve bcEdg(theEdge, theFace);
+        BRepAdaptor_Curve bcEvois(anEFound, theFace);
+        gp_Pnt pEdg = bcEdg.Value(aParPiv);
+        gp_Pnt pEFound = bcEvois.Value(aParam);
+
+        if(!IsDistanceIn3DTolerance(theFace, pEdg, pEFound, aTol3d))
+          IsFound = Standard_False;
+        else
+//angle was not defined but points are close
+          IsFound = Standard_True; //all right
+        }
+
+      if(!IsFound)
+        {
+        theLOfShape.Clear();
+        }
+      }//if (theLOfShape.Extent() == 1)
+    else //if (anIndMin == 0)
+      {
+      theLOfShape.Clear();
       }
-      if(onjette) {
-#ifdef DEB
-       cout<<"controle fermeture en 3d --> faux"<<endl;cout.flush();
-#endif
-       L.Clear();
+  else
+    {
+    anIndex = 1;
+
+    while (anIndex < anIndMin)
+      {
+      theLOfShape.RemoveFirst();
+      anIndex++;
       }
-    }
-    else {
-      L.Clear();
-    }
-  else  {
-    index = 1;
-    while (index < imin) {
-      L.RemoveFirst();
-      index++;
-    }
-    It.Initialize(L);
+
+    It.Initialize(theLOfShape);
     It.Next();
+
     while (It.More())
-      L.Remove(It);
-  }
-}
+      theLOfShape.Remove(It);
+    }
+  }//End of function
+
+
 //=======================================================================
 //function : CurveDirForParameter
 //purpose  :