0024428: Implementation of LGPL license
[occt.git] / src / BRepCheck / BRepCheck_Wire.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 057959d..a9eb715
@@ -1,22 +1,18 @@
 // Created on: 1995-12-12
 // Created by: Jacques GOUSSARD
 // Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 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.
+// This file is part of Open CASCADE Technology software library.
 //
-// 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.
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// 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.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 // Modified by dpf, Fri Dec 19 15:31:03 1997 
 //  Processing of closing in 2d.
@@ -369,71 +365,195 @@ 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  : 
+//=======================================================================
+static 
+Standard_Boolean IsDistanceIn2DTolerance (const BRepAdaptor_Surface& aFaceSurface,
+                                          const gp_Pnt2d& thePnt,
+                                          const gp_Pnt2d& thePntRef,
+                                          const Standard_Real aTol3d,
+#ifdef DEB
+                                          const Standard_Boolean PrintWarnings = Standard_True)
+#else
+                                          const Standard_Boolean = Standard_True)
+#endif
+{
+  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;
@@ -444,92 +564,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  : 
@@ -548,11 +665,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;
@@ -1060,7 +1173,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); 
@@ -1417,40 +1530,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, if oriented == Standard_True, edge should
-                 // be FORWARD or REVERSED. It is not checked.
-                 // =============
-                 // 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 on 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  : 
@@ -1469,186 +1593,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 
-
-    cout<<"BRepCheck_Wire : UResolution and VResolution = 0.0 (Face too small ?)"<<endl;cout.flush();
-#endif
-  }
-  else {
-    tol += tol; 
-  }
-  //
-  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.*M_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
-  //
-  // Update edge
-  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 : control closure in 2d --> false"<<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<<"control closure in 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<<"control closure in 3d --> false"<<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  :