0028499: Checkshape incorrectly reports BRepCheck_NotClosed when gap is covered by...
[occt.git] / src / BRepCheck / BRepCheck_Wire.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 9e5384b..06706a7
@@ -1,71 +1,80 @@
-// File:        BRepCheck_Wire.cxx
-// Created:        Tue Dec 12 17:49:08 1995
-// Author:        Jacques GOUSSARD
-//                <jag@bravox>
+// Created on: 1995-12-12
+// Created by: Jacques GOUSSARD
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License 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.
+//
+// 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.
-//
 //  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
-
 //  Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764 
 
-#include <BRepCheck_Wire.ixx>
-#include <BRepCheck_ListOfStatus.hxx>
+#include <Bnd_Array1OfBox2d.hxx>
+#include <BndLib_Add2dCurve.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepCheck.hxx>
 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_MapIteratorOfMapOfShape.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <TopTools_DataMapOfShapeListOfShape.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <TopLoc_Location.hxx>
-#include <TColGeom2d_Array1OfCurve.hxx>
+#include <BRepCheck_ListOfStatus.hxx>
+#include <BRepCheck_Wire.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <ElCLib.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <Geom2dInt_GInter.hxx>
+#include <Geom_Curve.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <IntRes2d_Domain.hxx>
 #include <IntRes2d_Intersection.hxx>
 #include <IntRes2d_IntersectionPoint.hxx>
 #include <IntRes2d_IntersectionSegment.hxx>
 #include <IntRes2d_Transition.hxx>
-#include <IntRes2d_Domain.hxx>
-#include <Geom2dInt_GInter.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Lin.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <Geom2dAdaptor_HCurve.hxx>
-#include <BRep_Tool.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-#include <BRepCheck.hxx>
+#include <Precision.hxx>
+#include <Standard_Type.hxx>
+#include <TColGeom2d_Array1OfCurve.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
 #include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
-#include <TopTools_MapOfOrientedShape.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
 #include <TopTools_HArray1OfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfOrientedShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_MapOfOrientedShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 
-//Patch
-#include <Precision.hxx>
-#include <Bnd_Array1OfBox2d.hxx>
-#include <BndLib_Add2dCurve.hxx>
-
-//#ifdef WNT
 #include <stdio.h>
-#include <BRepTools_WireExplorer.hxx>
-#include <TopExp.hxx>
-//#endif
-
-#include <TopTools_IndexedMapOfOrientedShape.hxx>
-#include <ElCLib.hxx>
-
+IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Wire,BRepCheck_Result)
 
 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape&,
                       const TopoDS_Shape&,   // edge
@@ -98,7 +107,7 @@ inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
 }
 
 static
-  void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
+  void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
                            const Standard_Real aPrm,
                            gp_Pnt2d& Pnt,
                            gp_Vec2d& aVec2d);
@@ -355,71 +364,205 @@ 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 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 OCCT_DEBUG
+  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 : IsDistanceIn2DTolerance
+//purpose  : 
+//=======================================================================
+static 
+Standard_Boolean IsDistanceIn2DTolerance (const BRepAdaptor_Surface& aFaceSurface,
+                                          const gp_Pnt2d& thePnt,
+                                          const gp_Pnt2d& thePntRef,
+                                          const Standard_Real aTol3d,
+#ifdef OCCT_DEBUG
+                                          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 OCCT_DEBUG
+  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;
+    }
+#endif
+  dumax = aFaceSurface.UResolution(aTol3d);
+  dvmax = aFaceSurface.VResolution(aTol3d);
+  gp_Pnt aP;
+  gp_Vec aDU, aDV;
+  Standard_Real um = (thePnt.X() + thePntRef.X()) / 2.;
+  Standard_Real vm = (thePnt.Y() + thePntRef.Y()) / 2.;
+  aFaceSurface.D1(um, vm, aP, aDU, aDV);
+  Standard_Real aMDU = aDU.Magnitude();
+  if (aMDU > Precision::Confusion())
+  {
+    dumax = Max((aTol3d / aMDU), dumax);
+  }
+  Standard_Real aMDV = aDV.Magnitude();
+  if (aMDV > Precision::Confusion())
+  {
+    dvmax = Max((aTol3d / aMDV), dvmax);
+  }
+
+#ifdef OCCT_DEBUG
+  if(PrintWarnings)
+    {
+    cout << "aTol3d = " << aTol3d <<"; URes = " << dumax << "; VRes = " << dvmax               << endl;
+    cout << "thePnt(" << thePnt.X() << "; " << thePnt.Y() << ")"                                                                               << endl;
+    cout << "thePntRef(" << thePntRef.X() << "; " << thePntRef.Y() << ")"                                              << endl;
+    }
+#endif
+
+  Standard_Real aTol2d = 2*Max(        dumax, dvmax);
+  
+#ifdef OCCT_DEBUG
+  if((aTol2d <= 0.0) && (PrintWarnings))
+    {
+    cout<<"BRepCheck_Wire : UResolution and VResolution = 0.0 (Face too small ?)"<<endl;
+    cout.flush();
+    }
+#endif
+
+  Standard_Real Dist = Max(dumin, dvmin);
+  
+  if (Dist < aTol2d)
+    return Standard_True;
+
+#ifdef OCCT_DEBUG
+  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 +573,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(aPntRef, aPnt, aTol3d))
+    aClosedStat = BRepCheck_NotClosed;
+
   if (Update) 
     BRepCheck::Add(myMap(myShape),aClosedStat);
+
   return aClosedStat;
-}
+  }
 //=======================================================================
 //function : Orientation
 //purpose  : 
@@ -534,11 +674,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;
@@ -811,7 +947,6 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
 {
 
 
-  Standard_Boolean ok;
   Standard_Integer i,j,Nbedges;
   Standard_Real first1,last1,first2,last2, tolint;
   gp_Pnt2d pfirst1,plast1,pfirst2,plast2;
@@ -823,7 +958,6 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
   TopTools_IndexedMapOfOrientedShape EMap;
   TopTools_MapOfOrientedShape auxmape;
   //
-  ok=Standard_True;
   //-- check with proper tolerances if there is no 
   //-- point in the tolerance of a vertex.
   tolint = 1.e-10; 
@@ -930,13 +1064,12 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
            }
          }
          if(localok==Standard_False) { 
-           ok=0;
            retE1=E1;
            if (Update) {
              BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
              }
            delete [] tabDom;
-#ifdef DEB
+#ifdef OCCT_DEBUG
            static Standard_Integer numpoint=0;
            cout<<"point p"<<++numpoint<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;cout.flush();
 #endif
@@ -969,7 +1102,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
        }
        else {
          delete [] tabDom;
-#ifdef DEB
+#ifdef OCCT_DEBUG
          cout<<"BRepCheck_NoCurveOnSurface or BRepCheck_InvalidRange"<<endl;cout.flush();
 #endif
          if(tabCur(j).IsNull()) {
@@ -1046,7 +1179,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); 
@@ -1091,28 +1224,25 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
            //-- Check distance from edges to the curve joining 
            //-- the point of intersection with vertex (if exists)
            if (localok == Standard_False && !CommonVertices.IsEmpty()) {
-#ifdef DEB     
+#ifdef OCCT_DEBUG
              cout << "\n------------------------------------------------------\n" <<endl;
              cout << "\n--- BRepCheck Wire: AutoIntersection Phase1 -> Erreur \n" <<endl;
              
 #endif
-             Standard_Boolean yaunvtxproche;
              Standard_Real distauvtxleplusproche,VParaOnEdge1,VParaOnEdge2;
              gp_Pnt VertexLePlusProche;
              //
-             yaunvtxproche=Standard_False;
              VParaOnEdge1 =0.;
              VParaOnEdge2 =0.;
              distauvtxleplusproche=RealLast();
              //Find the nearest common vertex
              itl.Initialize( CommonVertices );
              for (; itl.More(); itl.Next())   {
-               Standard_Real tolvtt, disptvtx;
+               Standard_Real disptvtx;
                gp_Pnt p3dvtt;
                //
                const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
                p3dvtt = BRep_Tool::Pnt(vtt);
-               tolvtt = BRep_Tool::Tolerance(vtt);
                disptvtx = P3d.Distance(p3dvtt);
                if (disptvtx < distauvtxleplusproche)   {
                  VertexLePlusProche = p3dvtt; 
@@ -1199,7 +1329,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
                    localok = Standard_False;
                  }
                }
-#ifdef DEB
+#ifdef OCCT_DEBUG
                if(localok) { 
                  printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Bon \n");
                  printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
@@ -1219,13 +1349,12 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
            } //end of if (localok == Standard_False && !CommonVertices.IsEmpty())
            //
            if(localok==Standard_False)   { 
-             ok=0;
              retE1=E1;
              retE2=E2;
              if (Update) {
                BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
                }
-#ifdef DEB
+#ifdef OCCT_DEBUG
              static Standard_Integer numpoint1=0;
              cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
              cout.flush();
@@ -1354,13 +1483,12 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
            } //end of for (k = 0; k < 2; k++)
            //
            if(localok==Standard_False)   { 
-             ok=0;
              retE1=E1;
              retE2=E2;
              if (Update) {
                BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
              }
-#ifdef DEB
+#ifdef OCCT_DEBUG
              static Standard_Integer numpoint1=0;
              cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
              cout.flush();
@@ -1381,6 +1509,17 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
   //
   return (BRepCheck_NoError);
 }
+
+//=======================================================================
+//function :   SetStatus
+//purpose  : 
+//=======================================================================
+
+void BRepCheck_Wire::SetStatus(const BRepCheck_Status theStatus)
+{
+    BRepCheck::Add(myMap(myShape),theStatus);
+}
+
 //=======================================================================
 //function : GeometricControls
 //purpose  : 
@@ -1403,40 +1542,55 @@ 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();
+      if (!mapE.Contains(Edge)) 
+        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))
+            {
+              mapE.Add(E);
+              nextEdges.Append(E);
+            }
+          }
+        }
       }
     }
+    currentEdges = nextEdges;
   }
+  while (!currentEdges.IsEmpty());
 }
+
 //=======================================================================
 //function : GetOrientation
 //purpose  : 
@@ -1455,205 +1609,176 @@ 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;
-    }
+    Geom2dAdaptor_Curve aCA(C2d);
 
-    p =(aVOrientation != aE.Orientation()) ? f : l;
-    //
-    Pnt = C2d->Value(p);
-    dist2d = Pnt.Distance( PntRef );
-    if (dist2d > tol){
+    aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam;
+    aPnt = aCA.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(aCA, 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(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  : 
 //=======================================================================
-void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
-                         const Standard_Real aPrm,
-                         gp_Pnt2d& Pnt,
-                         gp_Vec2d& aVec2d)
+void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
+                          const Standard_Real aPrm,
+                          gp_Pnt2d& Pnt,
+                          gp_Vec2d& aVec2d)
 {
   Standard_Real aTol=gp::Resolution();
   Standard_Integer i;
 
-  aC2d->D1(aPrm, Pnt, aVec2d);
+  aC2d.D1(aPrm, Pnt, aVec2d);
   //
   if (aVec2d.Magnitude() <= aTol) {
     for (i = 2; i <= 100; i++){
-      aVec2d = aC2d->DN(aPrm, i);
+      aVec2d = aC2d.DN(aPrm, i);
       if (aVec2d.Magnitude() > aTol) {
-       break;
+        break;
       }
     }
   }