6b26e1033c025aa3b407d76801a7d574b8e44a6c
[occt.git] / src / BRepCheck / BRepCheck_Wire.cxx
1 // Created on: 1995-12-12
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 // Modified by dpf, Fri Dec 19 15:31:03 1997 
22 //  Processing of closing in 2d.
23 //  modified by eap Tue Dec 18 14:14:25 2001 (bug OCC23)
24 //   Check self-intersection in case of closed edge
25 //  modified by eap Fri Dec 21 17:36:55 2001 (bug OCC35)
26 //   Closed2d() added
27
28 //  Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764 
29
30 #include <BRepCheck_Wire.ixx>
31 #include <BRepCheck_ListOfStatus.hxx>
32 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
33 #include <TopTools_MapOfShape.hxx>
34 #include <TopTools_MapIteratorOfMapOfShape.hxx>
35 #include <TopTools_IndexedMapOfShape.hxx>
36 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
37 #include <TopTools_DataMapOfShapeListOfShape.hxx>
38 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
39 #include <TopTools_ListOfShape.hxx>
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
41 #include <TopExp_Explorer.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <TopLoc_Location.hxx>
44 #include <TColGeom2d_Array1OfCurve.hxx>
45 #include <IntRes2d_Intersection.hxx>
46 #include <IntRes2d_IntersectionPoint.hxx>
47 #include <IntRes2d_IntersectionSegment.hxx>
48 #include <IntRes2d_Transition.hxx>
49 #include <IntRes2d_Domain.hxx>
50 #include <Geom2dInt_GInter.hxx>
51 #include <gp_Pnt2d.hxx>
52 #include <gp_Pnt.hxx>
53 #include <gp_Lin.hxx>
54 #include <Geom2d_Curve.hxx>
55 #include <Geom_Curve.hxx>
56 #include <Geom2dAdaptor_Curve.hxx>
57 #include <Geom2dAdaptor_HCurve.hxx>
58 #include <BRep_Tool.hxx>
59 #include <BRepAdaptor_Curve.hxx>
60 #include <BRepAdaptor_Surface.hxx>
61 #include <BRepAdaptor_HSurface.hxx>
62 #include <BRepCheck.hxx>
63 #include <TopoDS.hxx>
64 #include <TopoDS_Vertex.hxx>
65 #include <TopTools_MapOfOrientedShape.hxx>
66 #include <TopTools_HArray1OfShape.hxx>
67 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
68
69 //Patch
70 #include <Precision.hxx>
71 #include <Bnd_Array1OfBox2d.hxx>
72 #include <BndLib_Add2dCurve.hxx>
73
74 //#ifdef WNT
75 #include <stdio.h>
76 #include <BRepTools_WireExplorer.hxx>
77 #include <TopExp.hxx>
78 //#endif
79
80 #include <TopTools_IndexedMapOfOrientedShape.hxx>
81 #include <ElCLib.hxx>
82
83
84 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape&,
85                       const TopoDS_Shape&,   // edge
86                       TopTools_MapOfShape&); // mapofedge
87
88
89 static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape&,
90                                          const TopoDS_Edge&);
91
92
93 static 
94   void ChoixUV(const TopoDS_Vertex&,
95                const TopoDS_Edge&,
96                const TopoDS_Face&,
97                TopTools_ListOfShape&);
98
99 //      20/03/02 akm vvv (OCC234)
100 // static 
101 //   Standard_Boolean CheckLoopOrientation( const TopoDS_Vertex&,
102 //                                      const TopoDS_Edge&,
103 //                                      const TopoDS_Edge&,
104 //                                      const TopoDS_Face&,
105 //                                      TopTools_ListOfShape&);
106 //      20/03/02 akm ^^^
107
108 inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
109 {
110   return (S.Orientation() == TopAbs_FORWARD ||
111           S.Orientation() == TopAbs_REVERSED);
112 }
113
114 static
115   void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
116                             const Standard_Real aPrm,
117                             gp_Pnt2d& Pnt,
118                             gp_Vec2d& aVec2d);
119
120 //  Modified by Sergey KHROMOV - Thu Jun 20 11:21:51 2002 OCC325 Begin
121 static Standard_Boolean IsClosed2dForPeriodicFace
122                         (const TopoDS_Face   &theFace,
123                          const gp_Pnt2d      &theP1,
124                          const gp_Pnt2d      &theP2,
125                          const TopoDS_Vertex &theVertex);
126
127 static Standard_Boolean GetPnt2d(const TopoDS_Vertex    &theVertex,
128                                  const TopoDS_Edge      &theEdge,
129                                  const TopoDS_Face      &theFace,
130                                        gp_Pnt2d         &aPnt);
131 //  Modified by Sergey KHROMOV - Wed May 22 10:44:08 2002 End
132
133 //=======================================================================
134 //function : BRepCheck_Wire
135 //purpose  : 
136 //=======================================================================
137 BRepCheck_Wire::BRepCheck_Wire(const TopoDS_Wire& W)
138 {
139   Init(W);
140 }
141 //=======================================================================
142 //function : Minimum
143 //purpose  : 
144 //=======================================================================
145 void BRepCheck_Wire::Minimum()
146 {
147   myCdone = Standard_False;
148   myGctrl = Standard_True;
149   if (!myMin) {
150     BRepCheck_ListOfStatus thelist;
151     myMap.Bind(myShape, thelist);
152     BRepCheck_ListOfStatus& lst = myMap(myShape);
153
154     // check that the wire is "connex"
155     TopExp_Explorer exp(myShape,TopAbs_EDGE);
156     Standard_Integer nbedge = 0;
157     myMapVE.Clear();
158     // fill myMapVE
159     for (; exp.More(); exp.Next()) {
160       nbedge++;
161       TopExp_Explorer expv;
162       for (expv.Init(exp.Current(),TopAbs_VERTEX);
163            expv.More(); expv.Next()) {
164         const TopoDS_Shape& vtx = expv.Current();
165         Standard_Integer index = myMapVE.FindIndex(vtx);
166         if (index == 0) {
167           TopTools_ListOfShape theListOfShape;
168           index = myMapVE.Add(vtx, theListOfShape);
169         }
170         myMapVE(index).Append(exp.Current());
171       }
172     }
173     // wire must have at least one edge
174     if (nbedge == 0) {
175       BRepCheck::Add(lst,BRepCheck_EmptyWire);
176     }
177     // check if all edges are connected through vertices
178     else if (nbedge >= 2) {
179       TopTools_MapOfShape mapE;
180       exp.ReInit();
181       Propagate(myMapVE,exp.Current(),mapE);
182       for (exp.ReInit(); exp.More(); exp.Next()) {
183         if (!mapE.Contains(exp.Current())) {
184           BRepCheck::Add(lst,BRepCheck_NotConnected);
185           break;
186         }
187       }
188     }
189     if (lst.IsEmpty()) {
190       lst.Append(BRepCheck_NoError);
191     }
192     myMapVE.Clear();
193     myMin = Standard_True;
194   }
195 }
196 //=======================================================================
197 //function : InContext
198 //purpose  : 
199 //=======================================================================
200 void BRepCheck_Wire::InContext(const TopoDS_Shape& S)
201 {
202
203   if (myMap.IsBound(S)) {
204     return;
205   }
206   BRepCheck_ListOfStatus thelist;
207   myMap.Bind(S, thelist);
208
209   BRepCheck_ListOfStatus& lst = myMap(S);
210
211   // check if my wire is in <S>
212   TopExp_Explorer exp(S,TopAbs_WIRE); 
213   for ( ; exp.More(); exp.Next()) {
214     if (exp.Current().IsSame(myShape)) {
215       break;
216     }
217   }
218   if (!exp.More()) {
219     BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
220     return;
221   }
222
223   BRepCheck_Status st = BRepCheck_NoError;
224   TopAbs_ShapeEnum styp = S.ShapeType();
225   switch (styp) {
226
227   case TopAbs_FACE:
228     {
229       TopoDS_Edge ed1,ed2; 
230       if (myGctrl) 
231         st = SelfIntersect(TopoDS::Face(S),ed1,ed2,Standard_True);
232       if (st != BRepCheck_NoError) break;
233       st = Closed();
234       if (st != BRepCheck_NoError) break;
235       st = Orientation(TopoDS::Face(S));
236       if (st != BRepCheck_NoError) break;
237       st = Closed2d(TopoDS::Face(S));
238     }
239     break;
240   default:
241     break;
242   }
243   
244   if (st != BRepCheck_NoError) 
245     BRepCheck::Add(lst,st);
246       
247   if (lst.IsEmpty()) 
248     lst.Append(BRepCheck_NoError);
249 }
250 //=======================================================================
251 //function : Blind
252 //purpose  : 
253 //=======================================================================
254 void BRepCheck_Wire::Blind()
255 {
256   if (!myBlind) {
257     // nothing more that the minimum
258     myBlind = Standard_True;
259   }
260 }
261 //=======================================================================
262 //function : Closed
263 //purpose  : 
264 //=======================================================================
265 BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
266 {
267
268   if (myCdone) {
269     if (Update) {
270       BRepCheck::Add(myMap(myShape),myCstat);
271     }
272     return myCstat;
273   }
274
275   myCdone = Standard_True;
276
277   BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
278   if (itl.Value() != BRepCheck_NoError) {
279     myCstat = itl.Value();
280     return myCstat; // already saved 
281   }
282
283   myCstat = BRepCheck_NoError;
284
285   TopExp_Explorer exp,expv;
286   TopTools_MapOfShape mapS;
287   TopTools_DataMapOfShapeListOfShape Cradoc;
288   myMapVE.Clear();
289   // Checks if the oriented edges of the wire give a "closed" wire,
290   // i-e if each oriented vertex on oriented edges is found 2 times...
291   // myNbori = 0;
292   for (exp.Init(myShape,TopAbs_EDGE);exp.More(); exp.Next()) {
293     if (IsOriented(exp.Current())) {
294       // myNbori++;
295       if (!Cradoc.IsBound(exp.Current())) {
296         TopTools_ListOfShape theListOfShape;
297         Cradoc.Bind(exp.Current(), theListOfShape);
298       }
299       Cradoc(exp.Current()).Append(exp.Current());
300
301       mapS.Add(exp.Current());
302       for (expv.Init(exp.Current(),TopAbs_VERTEX); expv.More(); expv.Next()) {
303         if (IsOriented(expv.Current())) {
304           Standard_Integer index = myMapVE.FindIndex(expv.Current());
305           if (index == 0) {
306             TopTools_ListOfShape theListOfShape1;
307             index = myMapVE.Add(expv.Current(), theListOfShape1);
308           }
309           myMapVE(index).Append(exp.Current());
310         }
311       }
312     }
313   }
314
315   Standard_Integer theNbori = mapS.Extent();
316   if (theNbori >= 2) {
317     mapS.Clear();
318     for (exp.ReInit(); exp.More(); exp.Next()) {
319       if (IsOriented(exp.Current())) {
320         break;
321       }
322     }
323     Propagate(myMapVE,exp.Current(),mapS);
324   }
325   if (theNbori != mapS.Extent()) {
326     myCstat = BRepCheck_NotConnected;
327     if (Update) {
328       BRepCheck::Add(myMap(myShape),myCstat);
329     }
330     return myCstat;
331   }
332
333   // Checks the number of occurence of an edge : maximum 2, and in this 
334   // case, one time FORWARD and one time REVERSED
335
336   Standard_Boolean yabug = Standard_False;
337   for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm(Cradoc);
338        itdm.More(); itdm.Next()) {
339     if (itdm.Value().Extent() >= 3) {
340       yabug = Standard_True;
341     }
342     else if (itdm.Value().Extent() == 2) {
343       if (itdm.Value().First().Orientation() == 
344           itdm.Value().Last().Orientation()) {
345         yabug = Standard_True;
346       }
347     }
348     if (yabug) {
349       myCstat = BRepCheck_RedundantEdge;
350       if (Update) {
351         BRepCheck::Add(myMap(myShape),myCstat);
352       }
353       return myCstat;
354     }
355   }
356
357   for (Standard_Integer i = 1; i<= myMapVE.Extent(); i++) {
358     if (myMapVE(i).Extent()%2 != 0) {
359       myCstat=BRepCheck_NotClosed;
360       if (Update) {
361         BRepCheck::Add(myMap(myShape),myCstat);
362       }
363       return myCstat;
364     }
365   }
366
367   if (Update) {
368     BRepCheck::Add(myMap(myShape),myCstat);
369   }
370   return myCstat;
371 }
372 //=======================================================================
373 //function : Closed2d
374 //purpose  : for periodic faces
375 //=======================================================================
376 BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
377                                           const Standard_Boolean Update)
378 {
379
380   // 3d closure checked?
381   BRepCheck_Status aClosedStat = Closed();
382   if (aClosedStat != BRepCheck_NoError) {
383     if (Update) 
384       BRepCheck::Add(myMap(myShape),aClosedStat);
385     return aClosedStat;
386   }
387
388   // 20/03/02 akm vvv : (OCC234) Hence this method will be used to check
389   //                    both periodic and non-periodic faces
390   //   // this check is for periodic faces 
391   BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
392   // if (!aFaceSurface.IsUPeriodic() && !aFaceSurface.IsVPeriodic())
393   // {
394   //   if (Update) 
395   //     BRepCheck::Add(myMap(myShape),aClosedStat);
396   //   return aClosedStat;
397   // }
398   // 20/03/02 akm ^^^
399   
400   // count edges having FORWARD or REVERSED orientation
401   Standard_Integer aNbOrirntedEdges = 0;
402   TopExp_Explorer anEdgeExp(myShape,TopAbs_EDGE);
403   for (;anEdgeExp.More(); anEdgeExp.Next()) {
404     if (IsOriented(anEdgeExp.Current())) 
405       aNbOrirntedEdges++;
406   }
407   if (aNbOrirntedEdges==0)
408   {
409     if (Update) 
410       BRepCheck::Add(myMap(myShape),aClosedStat);
411     return aClosedStat;
412   }
413   
414   // all those edges must form a closed 2d contour and be found by WireExplorer
415
416   Standard_Integer aNbFoundEdges = 0;
417
418   BRepTools_WireExplorer aWireExp(TopoDS::Wire(myShape), theFace);
419   TopoDS_Edge aFirstEdge = aWireExp.Current();
420   TopoDS_Vertex aFirstVertex = aWireExp.CurrentVertex();
421   TopoDS_Edge aLastEdge;
422   for (;aWireExp.More(); aWireExp.Next())
423   {
424     aNbFoundEdges++;
425     aLastEdge = aWireExp.Current();
426   }
427
428   if (aNbFoundEdges != aNbOrirntedEdges)
429   {
430     aClosedStat = BRepCheck_NotClosed;
431     if (Update) 
432       BRepCheck::Add(myMap(myShape),aClosedStat);
433     return aClosedStat;
434   }
435     
436   // Check distance between 2d ends of first and last edges
437 //  Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 Begin
438 //   First check if first and last edges are infinite:
439   Standard_Real      aF;
440   Standard_Real      aL;
441   Standard_Boolean   isFirstInfinite = Standard_False;
442   Standard_Boolean   isLastInfinite  = Standard_False;
443   TopAbs_Orientation anOri;
444
445   anOri = aFirstEdge.Orientation();
446   BRep_Tool::Range(aFirstEdge, aF, aL);
447   if ((anOri == TopAbs_FORWARD  && aF == -Precision::Infinite()) ||
448       (anOri == TopAbs_REVERSED && aL ==  Precision::Infinite()))
449     isFirstInfinite = Standard_True;
450
451   anOri = aLastEdge.Orientation();
452   BRep_Tool::Range(aLastEdge, aF, aL);
453   if ((anOri == TopAbs_FORWARD  && aL ==  Precision::Infinite()) ||
454       (anOri == TopAbs_REVERSED && aF == -Precision::Infinite()))
455     isLastInfinite = Standard_True;
456
457   if (isFirstInfinite && isLastInfinite) {
458     if (Update) 
459       BRepCheck::Add(myMap(myShape),aClosedStat);
460     return aClosedStat;
461   } else if (aFirstVertex.IsNull()) {
462     aClosedStat = BRepCheck_NotClosed;
463     if (Update) 
464       BRepCheck::Add(myMap(myShape),aClosedStat);
465     return aClosedStat;
466   }
467 //  Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 End
468
469   gp_Pnt2d p, p1, p2; // ends of prev edge, next edge, bidon
470
471   // get first point
472   BRep_Tool::UVPoints(aLastEdge, theFace, p2, p);
473   if (aLastEdge.Orientation() == TopAbs_REVERSED) p = p2; 
474   
475 //  Modified by Sergey KHROMOV - Mon Apr 22 10:36:33 2002 Begin
476 //   Standard_Real aTol, aUResol, aVResol;
477
478 //   // find 2d tolerance
479 //   aTol  = BRep_Tool::Tolerance(aFirstVertex);
480 //   aUResol = 2*aFaceSurface.UResolution(aTol);
481 //   aVResol = 2*aFaceSurface.VResolution(aTol);
482
483   // get second point
484   if (aFirstEdge.Orientation() == TopAbs_REVERSED)
485     BRep_Tool::UVPoints(aFirstEdge, theFace, p2, p1);
486   else 
487     BRep_Tool::UVPoints(aFirstEdge, theFace, p1, p2);
488
489 //  Modified by Sergey KHROMOV - Thu Jun 20 10:55:42 2002 OCC325 Begin
490 // Check 2d distance for periodic faces with seam edge
491   if (!IsClosed2dForPeriodicFace(theFace, p, p1, aFirstVertex)) {
492     aClosedStat = BRepCheck_NotClosed;
493     if (Update) 
494       BRepCheck::Add(myMap(myShape),aClosedStat);
495     return aClosedStat;
496   }
497 //  Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End
498
499   // check distance
500 //   Standard_Real dfUDist=Abs(p.X()-p1.X());
501 //   Standard_Real dfVDist=Abs(p.Y()-p1.Y());
502 //   if (dfUDist > aUResol || dfVDist > aVResol)
503 //   {
504   Standard_Real aTol3d = BRep_Tool::Tolerance(aFirstVertex);
505   gp_Pnt        aPRef  = BRep_Tool::Pnt(aFirstVertex);
506   gp_Pnt        aP1    = aFaceSurface.Value(p.X(),  p.Y());
507   gp_Pnt        aP2    = aFaceSurface.Value(p1.X(), p1.Y());
508   Standard_Real Dist1  = aPRef.Distance(aP1);
509   Standard_Real Dist2  = aPRef.Distance(aP2);
510
511   if (Dist1 > aTol3d || Dist2 > aTol3d) {
512 //  Modified by Sergey KHROMOV - Mon Apr 22 10:36:44 2002 End
513 #ifdef DEB
514     cout << endl;
515     cout << "------------------------------------------------------"   <<endl;
516     cout << "--- BRepCheck Wire: Closed2d -> Erreur"                   <<endl;
517     if (Dist1 > aTol3d)
518       cout << "--- Dist1 (" << Dist1 << ") > Tol3d (" << aTol3d << ")" <<endl;
519     if (Dist2 > aTol3d)
520       cout << "--- Dist2 (" << Dist2 << ") > Tol3d (" << aTol3d << ")" <<endl;
521     cout << "------------------------------------------------------"   <<endl;
522 #endif
523     aClosedStat = BRepCheck_NotClosed;
524     if (Update) 
525       BRepCheck::Add(myMap(myShape),aClosedStat);
526     return aClosedStat;
527   }
528   
529   if (Update) 
530     BRepCheck::Add(myMap(myShape),aClosedStat);
531   return aClosedStat;
532 }
533 //=======================================================================
534 //function : Orientation
535 //purpose  : 
536 //=======================================================================
537 BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
538                                              const Standard_Boolean Update)
539 {
540   BRepCheck_Status theOstat = Closed();
541   if (theOstat != BRepCheck_NotClosed && theOstat != BRepCheck_NoError) {
542     if (Update) {
543       BRepCheck::Add(myMap(myShape),theOstat);
544     }
545     return theOstat;
546   }
547
548   theOstat = BRepCheck_NoError;
549
550   TopoDS_Vertex VF,VL;
551   TopAbs_Orientation orient, ortmp = TopAbs_FORWARD;
552   TopTools_ListOfShape ledge, ListOfPassedEdge;
553   TopExp_Explorer exp,vte;
554   TopTools_MapOfShape mapS;
555   TopoDS_Edge theEdge,theRef;
556
557   // Checks the orientation of the edges
558   for (exp.Init(myShape,TopAbs_EDGE); exp.More(); exp.Next()) {
559     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
560     orient = edg.Orientation();
561     if (IsOriented(edg)) {
562       mapS.Add(edg);
563       theEdge = edg;
564       theRef = edg;
565       for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
566         TopAbs_Orientation vto = vte.Current().Orientation();
567         if (vto == TopAbs_FORWARD) {
568           VF = TopoDS::Vertex(vte.Current());
569         }
570         else if (vto == TopAbs_REVERSED) {
571           VL = TopoDS::Vertex(vte.Current());
572         }
573         if (!VF.IsNull() && !VL.IsNull()) {
574           break;
575         }
576       }
577       if (VF.IsNull() && VL.IsNull())
578         theOstat = BRepCheck_InvalidDegeneratedFlag;
579       break;
580     }
581   }
582  
583   if (theOstat == BRepCheck_NoError) {
584     Standard_Integer Index = 1;
585     Standard_Integer nbOriNoDegen=myMapVE.Extent();
586 //  Modified by Sergey KHROMOV - Tue May 21 17:12:45 2002 Begin
587     Standard_Boolean isGoFwd     = Standard_True;
588
589     if (VL.IsNull())
590       isGoFwd = Standard_False;
591 //  Modified by Sergey KHROMOV - Tue May 21 17:12:45 2002 End
592
593     while (Index < nbOriNoDegen) {
594       ledge.Clear();
595       ListOfPassedEdge.Clear();
596       // find edges that make a chain on VL if !VL.IsNull 
597       // otherwise on VF.
598       
599       Standard_Integer ind;
600       if (!VL.IsNull()) {
601         ind = myMapVE.FindIndex(VL);
602       }
603       else if (!VF.IsNull()) {
604         ind = myMapVE.FindIndex(VF);
605       }
606       else {
607         theOstat = BRepCheck_InvalidDegeneratedFlag;
608         break;
609       }
610
611       for (TopTools_ListIteratorOfListOfShape itls(myMapVE(ind));
612            itls.More(); itls.Next()) {
613         const TopoDS_Edge & edg = TopoDS::Edge(itls.Value());
614
615         orient = edg.Orientation();
616         if (mapS.Contains(edg)) ortmp = GetOrientation(mapS,edg);
617
618         //Add to list already passed outcoming edges
619         if (mapS.Contains(edg) && ortmp == orient && !edg.IsSame(theEdge))
620           for (vte.Init(edg,TopAbs_VERTEX); vte.More(); vte.Next())
621             {
622               TopAbs_Orientation vto = vte.Current().Orientation();
623               if (!VL.IsNull())
624                 {
625                   if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current()))
626                     {
627                       ListOfPassedEdge.Append(edg);
628                       break;
629                     }
630                 }
631               else // VF is not null
632                 {
633                   if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current()))
634                     {
635                       ListOfPassedEdge.Append(edg);
636                       break;
637                     }
638                 }
639             }
640
641         if (!mapS.Contains(edg) || ortmp != orient) {
642           for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
643             TopAbs_Orientation vto = vte.Current().Orientation();
644             if (!VL.IsNull()) {
645               if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current())) {
646                 // If the processing is in 2d (face not null) or 
647                 // if the edge is not degenerated it is added
648                 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
649                   ledge.Append(edg);
650                 break;
651               }
652             }
653             else { // VF is not null
654               if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
655                 //    // If the processing is in 2d (face not null) or 
656                 // if the edge is not degenerated it is added
657                 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
658                   ledge.Append(edg);
659                 break;
660               }
661             }
662           }
663         }
664       }
665       Standard_Integer nbconnex = ledge.Extent();
666       Standard_Boolean Changedesens = Standard_False;
667       if (nbconnex == 0) {
668         if (myCstat == BRepCheck_NotClosed) {
669           if (VL.IsNull()) {
670             if (Update) {
671               BRepCheck::Add(myMap(myShape),theOstat);
672             }
673             return theOstat; // leave
674           }
675           else {
676             Index--; // because after Index++ and if there is no chain,
677             VL.Nullify(); // chain on VF is forced
678             theEdge = theRef;
679             Changedesens = Standard_True;
680           }
681         }
682         else {
683           theOstat = BRepCheck_BadOrientationOfSubshape;
684           if (Update) {
685             BRepCheck::Add(myMap(myShape),theOstat);
686             }
687           return theOstat;
688         }
689       }
690
691       // JAG 03/07   else if (nbconnex >= 2 && !F.IsNull())  // Try to see in 2d
692       else if (!F.IsNull()) { // Try to see in 2d
693         TopoDS_Vertex pivot;
694         if (!VL.IsNull()) {
695           pivot = VL;
696         }
697         else {
698           pivot = VF;
699         }
700
701         ChoixUV(pivot,theEdge,F,ledge);
702         nbconnex = ledge.Extent();
703 //      20/03/02 akm vvv : (OCC234) - The 2d exploration of wire with necessary
704 //                         checks is performed in Closed2d, here it's useless
705 //         if (nbconnex == 1 && !CheckLoopOrientation( pivot, theEdge, TopoDS::Edge(ledge.First()), F, ListOfPassedEdge ))
706 //         {
707 //           theOstat = BRepCheck_BadOrientationOfSubshape;
708 //           if (Update)
709 //             BRepCheck::Add(myMap(myShape),theOstat);
710 //           return theOstat;
711 //         }
712 //      20/03/02 akm ^^^
713       }
714
715       if (nbconnex >= 2) {
716         theOstat = BRepCheck_BadOrientationOfSubshape;
717         if (Update) {
718           BRepCheck::Add(myMap(myShape),theOstat);
719           }
720         return theOstat;
721       }
722       else if (nbconnex == 1) {
723         // offset the vertex
724         for (vte.Init(ledge.First(),TopAbs_VERTEX);vte.More(); vte.Next()) {
725           TopAbs_Orientation vto = vte.Current().Orientation();
726           if (!VL.IsNull()) {
727             if (vto == TopAbs_REVERSED) {
728               VL = TopoDS::Vertex(vte.Current());
729               break;
730             }
731           }
732           else { // VF is not null
733             if (vto == TopAbs_FORWARD) {
734               VF = TopoDS::Vertex(vte.Current());
735               break;
736             }
737           }
738         }
739         mapS.Add(ledge.First());
740         theEdge = TopoDS::Edge(ledge.First());
741         if (!vte.More()) {
742           if (!VL.IsNull()) {
743             VL.Nullify();
744           }
745           else {
746             VF.Nullify();
747           }
748         }
749       }
750       else if (!Changedesens) { //nbconnex == 0
751         theOstat = BRepCheck_NotClosed;
752         if (Update) {
753           BRepCheck::Add(myMap(myShape),theOstat);
754           }
755         return theOstat;
756       }
757
758       // Check the closure of the wire in 2d (not done in Closed())
759       
760       TopoDS_Vertex    aVRef;
761       Standard_Boolean isCheckClose = Standard_False;
762
763       if (isGoFwd && !VF.IsNull()) {
764         aVRef        = VF;
765         isCheckClose = Standard_True;
766       } else if (!isGoFwd && !VL.IsNull()) {
767         aVRef        = VL;
768         isCheckClose = Standard_True;
769       }
770
771 //       if (Index==1 && myCstat!=BRepCheck_NotClosed && 
772 //        !VF.IsNull() && !F.IsNull()) {
773       if (Index==1 && myCstat!=BRepCheck_NotClosed && 
774           isCheckClose && !F.IsNull()) {
775         ledge.Clear();
776 //      ind = myMapVE.FindIndex(VF);
777         ind = myMapVE.FindIndex(aVRef);
778         for (TopTools_ListIteratorOfListOfShape itlsh(myMapVE(ind));
779              itlsh.More(); itlsh.Next()) {
780           const TopoDS_Edge & edg = TopoDS::Edge(itlsh.Value());
781           orient = edg.Orientation();
782           if (!theRef.IsSame(edg)) {
783             for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
784               TopAbs_Orientation vto = vte.Current().Orientation();
785 //            if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
786               if (vto == TopAbs_REVERSED && aVRef.IsSame(vte.Current())) {
787                 ledge.Append(edg);
788                 break;
789               }
790             }
791           }
792         }
793 //      ChoixUV(VF, theRef, F, ledge);
794         ChoixUV(aVRef, theRef, F, ledge);
795         if (ledge.Extent()==0) {
796           theOstat = BRepCheck_NotClosed;
797           if (Update) {
798             BRepCheck::Add(myMap(myShape),theOstat);
799           }
800           return theOstat;
801         }
802       }
803       // End control closure 2d
804
805       Index ++;
806     }
807   }
808   if (Update) {
809     BRepCheck::Add(myMap(myShape),theOstat);
810   }
811   return theOstat;
812 }
813 //=======================================================================
814 //function : SelfIntersect
815 //purpose  : 
816 //=======================================================================
817 BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
818                                                TopoDS_Edge& retE1,
819                                                TopoDS_Edge& retE2,
820                                                const Standard_Boolean Update)
821 {
822
823
824   Standard_Boolean ok;
825   Standard_Integer i,j,Nbedges;
826   Standard_Real first1,last1,first2,last2, tolint;
827   gp_Pnt2d pfirst1,plast1,pfirst2,plast2;
828   gp_Pnt P3d, P3d2;
829   Handle(BRepAdaptor_HSurface) HS;
830   Geom2dAdaptor_Curve C1, C2;
831   Geom2dInt_GInter      Inter;
832   IntRes2d_Domain myDomain1;
833   TopTools_IndexedMapOfOrientedShape EMap;
834   TopTools_MapOfOrientedShape auxmape;
835   //
836   ok=Standard_True;
837   //-- check with proper tolerances if there is no 
838   //-- point in the tolerance of a vertex.
839   tolint = 1.e-10; 
840   HS = new BRepAdaptor_HSurface();
841   HS->ChangeSurface().Initialize(F,Standard_False);
842   //
843   for (TopoDS_Iterator Iter1(myShape);Iter1.More();Iter1.Next()) {
844     if (Iter1.Value().ShapeType() == TopAbs_EDGE) {
845       EMap.Add(Iter1.Value());
846     }
847   }
848   //
849   Nbedges=EMap.Extent();
850   if (!Nbedges) {
851     if (Update) {
852       BRepCheck::Add(myMap(myShape),BRepCheck_EmptyWire);
853     }
854     return(BRepCheck_EmptyWire);
855   }
856   //
857   IntRes2d_Domain *tabDom = new IntRes2d_Domain[Nbedges];
858   TColGeom2d_Array1OfCurve tabCur(1,Nbedges);
859   Bnd_Array1OfBox2d boxes(1,Nbedges);
860   //
861   for(i = 1; i <= Nbedges; i++) { 
862     const TopoDS_Edge& E1 = TopoDS::Edge(EMap.FindKey(i));
863     if (i == 1) {
864       Handle(Geom2d_Curve) pcu = BRep_Tool::CurveOnSurface(E1, F, first1, last1);
865       if (pcu.IsNull()) {
866         retE1=E1;
867         if (Update) {
868           BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
869         }
870         delete [] tabDom;
871         return(BRepCheck_SelfIntersectingWire);
872       }
873       //
874       C1.Load(pcu);
875       // To avoid exeption in Segment if C1 is BSpline - IFV
876       if(!C1.IsPeriodic()) {
877         if(C1.FirstParameter() > first1) {
878           first1 = C1.FirstParameter();
879         }
880         if(C1.LastParameter()  < last1 ){
881           last1  = C1.LastParameter();
882         }
883       }
884       //
885       BRep_Tool::UVPoints(E1, F, pfirst1, plast1);
886       myDomain1.SetValues(pfirst1,first1,tolint, plast1,last1,tolint);
887       //
888       BndLib_Add2dCurve::Add(C1, first1, last1, Precision::PConfusion(), boxes(i));
889     }//if (i == 1) {
890     else {
891       C1.Load(tabCur(i));
892       myDomain1 = tabDom[i-1];
893     }
894     //
895     // Self intersect of C1
896     Inter.Perform(C1, myDomain1, tolint, tolint);
897     //
898     if(Inter.IsDone()) { 
899       Standard_Integer nbp = Inter.NbPoints();
900       //Standard_Integer nbs = Inter.NbSegments();
901       //
902       for(Standard_Integer p=1;p<=nbp;p++) {
903         const IntRes2d_IntersectionPoint& IP=Inter.Point(p);
904         const IntRes2d_Transition& Tr1 = IP.TransitionOfFirst();
905         const IntRes2d_Transition& Tr2 = IP.TransitionOfSecond();
906         if(   Tr1.PositionOnCurve() == IntRes2d_Middle
907            || Tr2.PositionOnCurve() == IntRes2d_Middle) { 
908           //-- Checking of points with true tolerances (ie Tol in 3d)
909           //-- If the point of intersection is within the tolearnce of a vertex
910           //-- this intersection is considered correct (no error)
911           Standard_Boolean localok = Standard_False;
912           Standard_Real f,l;
913           TopLoc_Location L;
914           const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f,l);
915           if(!ConS.IsNull()) { 
916             //-- try to test in 3d. (ParamOnSecond gives the same result)
917             P3d = ConS->Value(IP.ParamOnFirst()); 
918             P3d.Transform(L.Transformation());
919             //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
920           } 
921           else {
922             gp_Pnt2d aP2d  = C1.Value(IP.ParamOnFirst());
923             P3d = HS->Value(aP2d.X(), aP2d.Y());
924           }
925           //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
926           TopExp_Explorer ExplVtx;
927           for(ExplVtx.Init(E1,TopAbs_VERTEX); 
928               localok==Standard_False && ExplVtx.More();
929               ExplVtx.Next()) { 
930             gp_Pnt p3dvtt;
931             Standard_Real tolvtt, p3dvttDistanceP3d;
932             //
933             const TopoDS_Vertex& vtt = TopoDS::Vertex(ExplVtx.Current());
934             p3dvtt = BRep_Tool::Pnt(vtt);
935             tolvtt =  BRep_Tool::Tolerance(vtt);
936             tolvtt=tolvtt*tolvtt;
937             p3dvttDistanceP3d=p3dvtt.SquareDistance(P3d);
938             if(p3dvttDistanceP3d <=  tolvtt) { 
939               localok=Standard_True;
940             }
941           }
942           if(localok==Standard_False) { 
943             ok=0;
944             retE1=E1;
945             if (Update) {
946               BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
947               }
948             delete [] tabDom;
949 #ifdef DEB
950             static Standard_Integer numpoint=0;
951             cout<<"point p"<<++numpoint<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;cout.flush();
952 #endif
953             return(BRepCheck_SelfIntersectingWire);
954           }
955         }
956       }
957     }// if(Inter.IsDone()) { 
958     //
959     for(j=i+1; j<=Nbedges; j++) {
960       const TopoDS_Edge& E2 = TopoDS::Edge(EMap.FindKey(j));
961       if (i == 1) {
962         tabCur(j) = BRep_Tool::CurveOnSurface(E2,F,first2,last2);
963         if (!tabCur(j).IsNull() && last2 > first2) {
964           C2.Load(tabCur(j));
965           // To avoid exeption in Segment if C2 is BSpline - IFV
966           if(!C2.IsPeriodic()) {
967             if(C2.FirstParameter() > first2) {
968               first2 = C2.FirstParameter();
969             }
970             if(C2.LastParameter()  < last2 ) {
971               last2  = C2.LastParameter();
972             }
973           }
974           //
975           BRep_Tool::UVPoints(E2,F,pfirst2,plast2);
976           tabDom[j-1].SetValues(pfirst2,first2,tolint,plast2,last2,tolint);
977           
978           BndLib_Add2dCurve::Add( C2, first2, last2, Precision::PConfusion(), boxes(j) );
979         }
980         else {
981           delete [] tabDom;
982 #ifdef DEB
983           cout<<"BRepCheck_NoCurveOnSurface or BRepCheck_InvalidRange"<<endl;cout.flush();
984 #endif
985           if(tabCur(j).IsNull()) {
986             return(BRepCheck_NoCurveOnSurface);
987           }
988           return (BRepCheck_InvalidRange);
989         }
990       }// if (i == 1) {
991       else {
992         C2.Load(tabCur(j));
993       }
994       //
995       if (boxes(i).IsOut( boxes(j))) {
996         continue;
997       }
998       //modified by NIZNHY-PKV Fri Oct 29 10:09:01 2010f
999       if (E1.IsSame(E2)) {
1000         continue;
1001       }
1002       //modified by NIZNHY-PKV Fri Oct 29 10:09:02 2010t
1003       //
1004       //-- ************************************************************
1005       //-- ******* I n t e r s e c t i o n   C 1   and   C 2   ********
1006       //-- ************************************************************
1007       Inter.Perform(C1,myDomain1,C2,tabDom[j-1],tolint,tolint);
1008       //
1009       if(Inter.IsDone()) { 
1010         Standard_Integer nbp, nbs;
1011         Standard_Real IP_ParamOnFirst, IP_ParamOnSecond;
1012         IntRes2d_Transition Tr1,Tr2;
1013         TopTools_ListOfShape CommonVertices;
1014         TopTools_ListIteratorOfListOfShape itl;
1015         TopTools_MapOfShape Vmap;
1016         //
1017         TopoDS_Iterator it( E1 );
1018         for (; it.More(); it.Next()) {
1019           Vmap.Add( it.Value() );
1020         }
1021         //
1022         it.Initialize( E2 );
1023         for (; it.More(); it.Next()) {
1024           const TopoDS_Shape& V = it.Value();
1025           if (Vmap.Contains( V )) {
1026             CommonVertices.Append( V );
1027           }
1028         }
1029         //
1030         nbp = Inter.NbPoints();
1031         nbs = Inter.NbSegments();
1032         IP_ParamOnFirst  = 0.;
1033         IP_ParamOnSecond = 0.;
1034         //
1035         //// **** Points of intersection **** ////
1036         for (Standard_Integer p = 1; p <= nbp; p++)  {
1037           const IntRes2d_IntersectionPoint& IP = Inter.Point(p);
1038           IP_ParamOnFirst  = IP.ParamOnFirst();
1039           IP_ParamOnSecond = IP.ParamOnSecond();
1040           Tr1 = IP.TransitionOfFirst();
1041           Tr2 = IP.TransitionOfSecond();
1042           if(   Tr1.PositionOnCurve() == IntRes2d_Middle
1043              || Tr2.PositionOnCurve() == IntRes2d_Middle)   {
1044             //-- Checking of points with true tolerances (ie Tol in 3d)
1045             //-- If the point of intersection is within the tolerance of a vertex
1046             //-- this intersection is considered correct (no error)
1047             Standard_Boolean localok = Standard_False;  
1048             Standard_Real f1,l1, f2, l2;
1049             TopLoc_Location L, L2;
1050             //
1051             const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f1,l1);    
1052             const Handle(Geom_Curve) ConS2 = BRep_Tool::Curve(E2,L2,f2,l2);  
1053             //gka protect against working out of edge range
1054             if ( f1-IP_ParamOnFirst > ::Precision::PConfusion() || 
1055                 IP_ParamOnFirst-l1 > ::Precision::PConfusion() || 
1056                 f2-IP_ParamOnSecond > ::Precision::PConfusion() || 
1057                 IP_ParamOnSecond-l2 > ::Precision::PConfusion() ) 
1058               continue;
1059             Standard_Real tolvtt;
1060             //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1061             if (!ConS.IsNull()) { 
1062               P3d = ConS->Value(IP_ParamOnFirst); 
1063               P3d.Transform(L.Transformation());
1064             } 
1065             else {
1066               gp_Pnt2d aP2d  = C1.Value(IP_ParamOnFirst);
1067               P3d = HS->Value(aP2d.X(), aP2d.Y());
1068             }
1069             //
1070             if (!ConS2.IsNull()) {
1071               P3d2 = ConS2->Value(IP_ParamOnSecond); 
1072               P3d2.Transform(L2.Transformation());
1073             } 
1074             else {
1075               gp_Pnt2d aP2d  = C2.Value(IP_ParamOnSecond);
1076               P3d2 = HS->Value(aP2d.X(), aP2d.Y());
1077             }
1078             //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1079             itl.Initialize( CommonVertices );
1080             for (; itl.More(); itl.Next()) {
1081               Standard_Real p3dvttDistanceP3d, p3dvttDistanceP3d2;
1082               gp_Pnt p3dvtt;
1083               //
1084               const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1085               p3dvtt = BRep_Tool::Pnt(vtt);
1086               tolvtt =  BRep_Tool::Tolerance(vtt);
1087               tolvtt=1.1*tolvtt;
1088               tolvtt=tolvtt*tolvtt;
1089               p3dvttDistanceP3d  = p3dvtt.SquareDistance(P3d);
1090               p3dvttDistanceP3d2 = p3dvtt.SquareDistance(P3d2);
1091               //
1092               if (p3dvttDistanceP3d<=tolvtt && p3dvttDistanceP3d2<=tolvtt)  { 
1093                 localok = Standard_True;
1094                 break;
1095               }
1096             }
1097             
1098             //-- --------------------------------------------------------
1099             //-- Check maximum yawn between 2 edges
1100             //--
1101             //-- Check distance from edges to the curve joining 
1102             //-- the point of intersection with vertex (if exists)
1103             if (localok == Standard_False && !CommonVertices.IsEmpty()) {
1104 #ifdef DEB      
1105               cout << "\n------------------------------------------------------\n" <<endl;
1106               cout << "\n--- BRepCheck Wire: AutoIntersection Phase1 -> Erreur \n" <<endl;
1107               
1108 #endif
1109               Standard_Boolean yaunvtxproche;
1110               Standard_Real distauvtxleplusproche,VParaOnEdge1,VParaOnEdge2;
1111               gp_Pnt VertexLePlusProche;
1112               //
1113               yaunvtxproche=Standard_False;
1114               VParaOnEdge1 =0.;
1115               VParaOnEdge2 =0.;
1116               distauvtxleplusproche=RealLast();
1117               //Find the nearest common vertex
1118               itl.Initialize( CommonVertices );
1119               for (; itl.More(); itl.Next())   {
1120                 Standard_Real tolvtt, disptvtx;
1121                 gp_Pnt p3dvtt;
1122                 //
1123                 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1124                 p3dvtt = BRep_Tool::Pnt(vtt);
1125                 tolvtt = BRep_Tool::Tolerance(vtt);
1126                 disptvtx = P3d.Distance(p3dvtt);
1127                 if (disptvtx < distauvtxleplusproche)   {
1128                   VertexLePlusProche = p3dvtt; 
1129                   distauvtxleplusproche = disptvtx;
1130                   VParaOnEdge1 = BRep_Tool::Parameter(vtt,E1);
1131                   VParaOnEdge2 = BRep_Tool::Parameter(vtt,E2);
1132                 }
1133                 // eap: case of closed edge
1134                 else if (IsEqual(distauvtxleplusproche, disptvtx)) {
1135                   Standard_Real newVParaOnEdge1 = BRep_Tool::Parameter(vtt,E1);
1136                   Standard_Real newVParaOnEdge2 = BRep_Tool::Parameter(vtt,E2);
1137                   if (Abs(IP_ParamOnFirst - VParaOnEdge1) + Abs(IP_ParamOnSecond - VParaOnEdge2)
1138                       >
1139                       Abs(IP_ParamOnFirst - newVParaOnEdge1) + Abs(IP_ParamOnSecond - newVParaOnEdge2)) {
1140                     VertexLePlusProche = p3dvtt;
1141                     VParaOnEdge1 = newVParaOnEdge1;
1142                     VParaOnEdge2 = newVParaOnEdge2;
1143                   }
1144                 }
1145               }
1146               //Patch: extraordinar situation (e.g. tolerance(v) == 0.)
1147               //  Modified by skv - Wed Jul 23 12:28:11 2003 OCC1764 Begin
1148               // if (VertexLePlusProche.Distance( P3d ) <= gp::Resolution())
1149               if (VertexLePlusProche.Distance(P3d)  <= gp::Resolution() ||
1150                   VertexLePlusProche.Distance(P3d2) <= gp::Resolution()) {
1151                     //  Modified by skv - Wed Jul 23 12:28:12 2003 OCC1764 End
1152                 localok = Standard_True;
1153               }
1154               else {
1155                 gp_Lin Lig( VertexLePlusProche, gp_Vec(VertexLePlusProche,P3d) );
1156                 Standard_Real du1 = 0.1*(IP_ParamOnFirst -VParaOnEdge1);
1157                 Standard_Real du2 = 0.1*(IP_ParamOnSecond-VParaOnEdge2);
1158                 Standard_Real maxd1 = 0., maxd2 = 0.;
1159                 Standard_Integer k;
1160                 
1161                 localok = Standard_True;
1162                 Standard_Real tole1 = BRep_Tool::Tolerance(E1);
1163                 for (k = 2; localok && k < 9; k++)      { 
1164                   Standard_Real u = VParaOnEdge1 + k*du1;  // check if it works
1165                   gp_Pnt P1;
1166                   //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1167                   if (!ConS.IsNull()) {
1168                     P1 = ConS->Value(u);
1169                     P1.Transform(L.Transformation());
1170                   } 
1171                   else {
1172                     gp_Pnt2d aP2d  = C1.Value(u);
1173                     P1 = HS->Value(aP2d.X(), aP2d.Y());
1174                   }
1175                   //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1176                   Standard_Real d1 = Lig.Distance(P1);
1177                   if (d1 > maxd1) {
1178                     maxd1 = d1;
1179                   }
1180                   if (d1 > tole1*2.0){
1181                     localok = Standard_False;
1182                   }
1183                 }
1184                 //-- same for edge2
1185                 //  Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764 Begin
1186                 gp_Dir aTmpDir(P3d2.XYZ().Subtracted(VertexLePlusProche.XYZ()));
1187                 
1188                 Lig.SetDirection(aTmpDir);
1189                 //  Modified by skv - Wed Jul 23 12:22:23 2003 OCC1764 End
1190                 Standard_Real tole2 = BRep_Tool::Tolerance(E2);
1191                 for (k = 2; localok && k < 9; k++) {
1192                   Standard_Real u = VParaOnEdge2 + k*du2;  // check if it works
1193                   gp_Pnt        P2;
1194                   //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1195                   if (!ConS2.IsNull()) {
1196                     P2 = ConS2->Value(u);
1197                     P2.Transform(L2.Transformation());
1198                   }
1199                   else {
1200                     gp_Pnt2d aP2d  = C2.Value(u);
1201                     P2 = HS->Value(aP2d.X(), aP2d.Y());
1202                   }
1203                   //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1204                   Standard_Real d2 = Lig.Distance(P2);
1205                   if (d2 > maxd2) {
1206                     maxd2 = d2;
1207                   }
1208                   if (d2 > tole2*2.0){
1209                     localok = Standard_False;
1210                   }
1211                 }
1212 #ifdef DEB
1213                 if(localok) { 
1214                   printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Bon \n");
1215                   printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
1216                   printf("--- Erreur Max sur E1 : %10.7g  Tol_Edge:%10.7g\n",maxd1,tole1);
1217                   printf("--- Erreur Max sur E2 : %10.7g  Tol_Edge:%10.7g\n",maxd2,tole2);
1218                   fflush(stdout);
1219                 }
1220                 else { 
1221                   printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Erreur \n");
1222                   printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
1223                   printf("--- Erreur Max sur E1 : %10.7g  Tol_Edge:%10.7g\n",maxd1,tole1);
1224                   printf("--- Erreur Max sur E2 : %10.7g  Tol_Edge:%10.7g\n",maxd2,tole2);
1225                   fflush(stdout);
1226                 }
1227 #endif
1228               } //end of else (construction of the line Lig)
1229             } //end of if (localok == Standard_False && !CommonVertices.IsEmpty())
1230             //
1231             if(localok==Standard_False)   { 
1232               ok=0;
1233               retE1=E1;
1234               retE2=E2;
1235               if (Update) {
1236                 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1237                 }
1238 #ifdef DEB
1239               static Standard_Integer numpoint1=0;
1240               cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
1241               cout.flush();
1242 #endif
1243               delete [] tabDom;
1244               return(BRepCheck_SelfIntersectingWire);
1245             } //-- localok == False
1246           } //end of if(Tr1.PositionOnCurve() == IntRes2d_Middle || Tr2.PositionOnCurve() == IntRes2d_Middle)
1247         } //end of for (Standard_Integer p=1; p <= nbp; p++)    
1248         ////
1249         //// **** Segments of intersection **** ////
1250         for (Standard_Integer s = 1; s <= nbs; ++s) {
1251           const IntRes2d_IntersectionSegment& Seg = Inter.Segment(s);
1252           if (Seg.HasFirstPoint() && Seg.HasLastPoint())   { 
1253             Standard_Boolean localok;
1254             Standard_Integer k;
1255             IntRes2d_IntersectionPoint PSeg [2];
1256             IntRes2d_Position aPCR1, aPCR2;
1257             //
1258             localok = Standard_False;
1259             PSeg[0] = Seg.FirstPoint();
1260             PSeg[1] = Seg.LastPoint();
1261             // At least one of extremities of the segment must be inside
1262             // the tolerance of a common vertex
1263             for (k = 0; k < 2; ++k) {
1264               IP_ParamOnFirst  = PSeg[k].ParamOnFirst();
1265               IP_ParamOnSecond = PSeg[k].ParamOnSecond();
1266               Tr1 = PSeg[k].TransitionOfFirst();
1267               Tr2 = PSeg[k].TransitionOfSecond();
1268               aPCR1=Tr1.PositionOnCurve();
1269               aPCR2=Tr2.PositionOnCurve();
1270               //
1271               if(aPCR1!=IntRes2d_Middle && aPCR2!=IntRes2d_Middle)  {
1272                 GeomAbs_CurveType aCT1, aCT2;
1273                 //ZZ
1274                 aCT1=C1.GetType();
1275                 aCT2=C2.GetType();
1276                 if (aCT1==GeomAbs_Line && aCT2==GeomAbs_Line) {
1277                   // check for the two lines coincidence
1278                   Standard_Real aPAR_T, aT11, aT12, aT21, aT22, aT1m, aT2m;
1279                   Standard_Real aD2, aTolE1, aTolE2,  aTol2, aDot;
1280                   gp_Lin2d aL1, aL2;
1281                   gp_Pnt2d aP1m;
1282                   //
1283                   aPAR_T=0.43213918;
1284                   //
1285                   aTolE1=BRep_Tool::Tolerance(E1);
1286                   aTolE2=BRep_Tool::Tolerance(E2);
1287                   aTol2=aTolE1+aTolE2;
1288                   aTol2=aTol2*aTol2;
1289                   //
1290                   aL1=C1.Line();
1291                   aL2=C2.Line();
1292                   //
1293                   aT11=PSeg[0].ParamOnFirst();
1294                   aT12=PSeg[1].ParamOnFirst();
1295                   aT21=PSeg[0].ParamOnSecond();
1296                   aT22=PSeg[1].ParamOnSecond();
1297                   //
1298                   aT1m=(1.-aPAR_T)*aT11 + aPAR_T*aT12;
1299                   aP1m=C1.Value(aT1m);
1300                   //
1301                   aD2=aL2.SquareDistance(aP1m);
1302                   if (aD2<aTol2) {
1303                     aT2m=ElCLib::Parameter(aL2, aP1m);
1304                     if (aT2m>aT21 && aT2m<aT22) {
1305                       const gp_Dir2d& aDir1=aL1.Direction();
1306                       const gp_Dir2d& aDir2=aL2.Direction();
1307                       aDot=aDir1*aDir2;
1308                       if (aDot<0.) {
1309                         aDot=-aDot;
1310                       }
1311                       //
1312                       if ((1.-aDot)<5.e-11){//0.00001 rad
1313                         localok = Standard_False;
1314                         break;// from for (k = 0; k < 2; ++k){...
1315                       }
1316                     }//if (aT2m>aT21 && aT2m<aT22) {
1317                   }//if (aD2<aTol2) {
1318                 }//if (aCT1==GeomAbs_Line && aCT2==GeomAbs_Line) {
1319                 //ZZ
1320                 localok = Standard_True;
1321                 break;
1322               }
1323               //
1324               Standard_Real f,l, tolvtt;
1325               TopLoc_Location L, L2;
1326               const Handle(Geom_Curve)& ConS = BRep_Tool::Curve(E1,L,f,l);    
1327               const Handle(Geom_Curve)& ConS2 = BRep_Tool::Curve(E2,L2,f,l);    
1328               //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1329               if (!ConS.IsNull()) { 
1330                 P3d = ConS->Value(IP_ParamOnFirst); 
1331                 P3d.Transform(L.Transformation());
1332               } else {
1333                 gp_Pnt2d aP2d  = C1.Value(IP_ParamOnFirst);
1334                 P3d = HS->Value(aP2d.X(), aP2d.Y());
1335               }
1336               if (!ConS2.IsNull()) {
1337                 P3d2 = ConS2->Value(IP_ParamOnSecond); 
1338                 P3d2.Transform(L2.Transformation());
1339               } else {
1340                 gp_Pnt2d aP2d  = C2.Value(IP_ParamOnSecond);
1341                 P3d2 = HS->Value(aP2d.X(), aP2d.Y());
1342               }
1343               //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1344               itl.Initialize( CommonVertices );
1345               for (; itl.More(); itl.Next()) {
1346                 Standard_Real p3dvttDistanceP3d, p3dvttDistanceP3d2;
1347                 gp_Pnt p3dvtt;
1348                 //
1349                 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1350                 p3dvtt = BRep_Tool::Pnt(vtt);
1351                 tolvtt =  BRep_Tool::Tolerance(vtt);
1352                 tolvtt=1.1*tolvtt;
1353                 tolvtt=tolvtt*tolvtt;
1354                 p3dvttDistanceP3d  = p3dvtt.SquareDistance(P3d);
1355                 p3dvttDistanceP3d2 = p3dvtt.SquareDistance(P3d2);
1356                 if (p3dvttDistanceP3d <= tolvtt && p3dvttDistanceP3d2 <= tolvtt) { 
1357                   localok = Standard_True;
1358                   break;
1359                 }
1360               }
1361               if (localok == Standard_True) {
1362                 break;
1363               }
1364             } //end of for (k = 0; k < 2; k++)
1365             //
1366             if(localok==Standard_False)   { 
1367               ok=0;
1368               retE1=E1;
1369               retE2=E2;
1370               if (Update) {
1371                 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1372               }
1373 #ifdef DEB
1374               static Standard_Integer numpoint1=0;
1375               cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
1376               cout.flush();
1377 #endif
1378               delete [] tabDom;
1379               return(BRepCheck_SelfIntersectingWire);
1380             } //-- localok == False
1381           } //end of if(Seg.HasFirstPoint() && Seg.HasLastPoint())
1382         } //end of for (Standard_Integer s = 1; s <= nbs; p++)
1383       } //-- Inter.IsDone()
1384     } //end of for( j = i+1; j<=Nbedges; j++)
1385   } //end of for(i = 1; i <= Nbedges; i++)
1386   //
1387   delete [] tabDom;
1388   if (Update) {
1389     BRepCheck::Add(myMap(myShape),BRepCheck_NoError);
1390   }
1391   //
1392   return (BRepCheck_NoError);
1393 }
1394 //=======================================================================
1395 //function : GeometricControls
1396 //purpose  : 
1397 //=======================================================================
1398 void BRepCheck_Wire::GeometricControls(const Standard_Boolean B)
1399 {
1400   if (myGctrl != B) {
1401     if (B) {
1402       myCdone = Standard_False;
1403     }
1404     myGctrl = B;
1405   }
1406 }
1407 //=======================================================================
1408 //function : GeometricControls
1409 //purpose  : 
1410 //=======================================================================
1411 Standard_Boolean BRepCheck_Wire::GeometricControls() const
1412 {
1413   return myGctrl;
1414 }
1415
1416
1417 //=======================================================================
1418 //function : Propagate
1419 //purpose  : fill <mapE> with edges connected to <edg> through vertices
1420 //           contained in <mapVE>
1421 //=======================================================================
1422 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape& mapVE,
1423                       const TopoDS_Shape& edg,
1424                       TopTools_MapOfShape& mapE)
1425 {
1426   if (mapE.Contains(edg)) {
1427     return;
1428   }
1429   mapE.Add(edg); // attention, if oriented == Standard_True, edge should
1430                  // be FORWARD or REVERSED. It is not checked.
1431                  // =============
1432                  // attention, if oriented == Standard_True, <edg> must
1433                  // be FORWARD or REVERSED. That is not checked.
1434   
1435   TopExp_Explorer ex;
1436   for (ex.Init(edg,TopAbs_VERTEX); ex.More(); ex.Next()) {
1437     const TopoDS_Vertex& vtx = TopoDS::Vertex(ex.Current());
1438     // debug on vertex
1439     Standard_Integer indv = mapVE.FindIndex(vtx);
1440     if (indv != 0) {
1441       for (TopTools_ListIteratorOfListOfShape itl(mapVE(indv)); itl.More(); itl.Next()) {
1442         if (!itl.Value().IsSame(edg) &&
1443             !mapE.Contains(itl.Value())) {
1444           Propagate(mapVE,itl.Value(),mapE);
1445         }
1446       }
1447     }
1448   }
1449 }
1450 //=======================================================================
1451 //function : GetOrientation
1452 //purpose  : 
1453 //=======================================================================
1454
1455 static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape& mapE,
1456                                          const TopoDS_Edge& edg)
1457 {
1458   TopTools_MapIteratorOfMapOfShape itm(mapE);
1459   for ( ; itm.More(); itm.Next()) {
1460     if (itm.Key().IsSame(edg)) {
1461       break;
1462     }
1463   }
1464   return itm.Key().Orientation();
1465 }
1466 //=======================================================================
1467 //function : ChoixUV
1468 //purpose  : 
1469 //=======================================================================
1470  void ChoixUV(const TopoDS_Vertex& V,
1471               const TopoDS_Edge& Edg,
1472               const TopoDS_Face& F,
1473               TopTools_ListOfShape& L)
1474 {
1475   TopTools_ListIteratorOfListOfShape It( L );
1476   while (It.More())
1477     {
1478       if (Edg.IsSame( It.Value() ))
1479         L.Remove( It );
1480       else
1481         It.Next();
1482     }
1483
1484   Standard_Integer index = 0, imin = 0;
1485   TopoDS_Edge Evois;
1486   gp_Pnt2d PntRef, Pnt;
1487   gp_Vec2d DerRef, Der;
1488   Standard_Real MinAngle, MaxAngle, angle;
1489   Standard_Real gpResolution=gp::Resolution();
1490   TopAbs_Orientation aVOrientation, aEdgOrientation;
1491   Standard_Real dist2d = 0, p = 0;
1492   Standard_Real f, l, parpiv;
1493   Standard_Real tolv = BRep_Tool::Tolerance(V);
1494   BRepAdaptor_Surface Ads(F,Standard_False); // no restriction
1495   Standard_Real ures = Ads.UResolution(tolv);
1496   Standard_Real vres = Ads.VResolution(tolv);
1497   Standard_Real tol = Max(ures,vres);
1498   if(tol<=0.0) { 
1499 #ifdef DEB 
1500
1501     cout<<"BRepCheck_Wire : UResolution and VResolution = 0.0 (Face too small ?)"<<endl;cout.flush();
1502 #endif
1503   }
1504   else {
1505     tol += tol; 
1506   }
1507   //
1508   Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(Edg, F, f, l);
1509   if (C2d.IsNull()) {// JAG 10.12.96
1510     return;
1511   }
1512   
1513   aVOrientation=V.Orientation();
1514   aEdgOrientation=Edg.Orientation();
1515
1516   parpiv =(aVOrientation==aEdgOrientation) ? f : l;
1517       
1518   MinAngle = RealLast();
1519   MaxAngle = RealFirst();
1520
1521   CurveDirForParameter(C2d, parpiv, PntRef, DerRef);
1522
1523   if (aVOrientation != aEdgOrientation){
1524     DerRef.Reverse();
1525   }
1526   //
1527   It.Initialize(L);
1528   for (; It.More(); It.Next()) {
1529     index++;
1530     const TopoDS_Edge& aE=TopoDS::Edge(It.Value());
1531     C2d = BRep_Tool::CurveOnSurface(aE, F, f, l);
1532     if(C2d.IsNull()) {
1533       continue;
1534     }
1535
1536     p =(aVOrientation != aE.Orientation()) ? f : l;
1537     //
1538     Pnt = C2d->Value(p);
1539     dist2d = Pnt.Distance( PntRef );
1540     if (dist2d > tol){
1541       continue;
1542     }
1543     //
1544     CurveDirForParameter(C2d, p, Pnt, Der);
1545     
1546     if (aVOrientation == aE.Orientation()){
1547       Der.Reverse();
1548     }
1549     
1550     if (DerRef.Magnitude() <= gpResolution || 
1551         Der.Magnitude() <= gpResolution){
1552       continue;
1553     }
1554     //
1555     angle = DerRef.Angle( Der );
1556     angle *= -1.;
1557     if (angle < 0.)
1558       angle += 2.*M_PI;
1559     
1560     if (F.Orientation() == TopAbs_FORWARD) { 
1561       if (angle < MinAngle) {
1562         imin = index;
1563         MinAngle = angle;
1564       }
1565     } 
1566     else { //F.Orientation() != TopAbs_FORWARD
1567       if (angle > MaxAngle){
1568         imin = index;
1569         MaxAngle = angle;
1570       }
1571     }
1572   }//end of for
1573   //
1574   // Update edge
1575   if (imin == 0)
1576     if (L.Extent() == 1) {
1577       Standard_Boolean onjette = 0; //all right
1578       Evois = TopoDS::Edge(L.First());
1579       if (dist2d > tol) {
1580 #ifdef DEB 
1581         cout<<"BRepCheckWire : control closure in 2d --> false"<<endl;cout.flush();
1582 #endif
1583         if(Evois.IsNull() || BRep_Tool::Degenerated(Edg) ||
1584            BRep_Tool::Degenerated(Evois)){
1585           onjette = 1; //bad
1586         }
1587         else {
1588           Ads.Initialize(F);
1589           Standard_Real dumax = 0.01 * (Ads.LastUParameter() - Ads.FirstUParameter());
1590           Standard_Real dvmax = 0.01 * (Ads.LastVParameter() - Ads.FirstVParameter());
1591           Standard_Real dumin = Abs(Pnt.X() - PntRef.X());
1592           Standard_Real dvmin = Abs(Pnt.Y() - PntRef.Y());
1593           if(dumin > dumax || dvmin > dvmax){
1594             onjette = 1;
1595           }
1596           else {
1597             BRepAdaptor_Curve bcEdg(Edg,F);
1598             BRepAdaptor_Curve bcEvois(Evois,F);
1599             gp_Pnt pEdg = bcEdg.Value(parpiv);
1600             gp_Pnt pEvois = bcEvois.Value(p);
1601             Standard_Real d3d = pEvois.Distance(pEdg);
1602 #ifdef DEB
1603             cout<<"point P            "<<pEdg.X()<<" "<<pEdg.Y()<<" "<<pEdg.Z()<<endl;
1604             cout<<"distance 3d      : "<<d3d<<endl;
1605             cout<<"tolerance vertex : "<<tolv<<endl;
1606             cout.flush();
1607 #endif
1608             //if(d3d > tolv){
1609             if(d3d > 2.*tolv){
1610               onjette = 1;
1611             }
1612 #ifdef DEB
1613             else
1614               cout<<"control closure in 3d --> ok"<<endl;cout.flush();
1615 #endif
1616           }
1617         }
1618       } //if (dist2d > tol)
1619       else {//angle was not defined but points are close
1620         onjette = 0;
1621       }
1622       if(onjette) {
1623 #ifdef DEB
1624         cout<<"control closure in 3d --> false"<<endl;cout.flush();
1625 #endif
1626         L.Clear();
1627       }
1628     }
1629     else {
1630       L.Clear();
1631     }
1632   else  {
1633     index = 1;
1634     while (index < imin) {
1635       L.RemoveFirst();
1636       index++;
1637     }
1638     It.Initialize(L);
1639     It.Next();
1640     while (It.More())
1641       L.Remove(It);
1642   }
1643 }
1644 //=======================================================================
1645 //function : CurveDirForParameter
1646 //purpose  : 
1647 //=======================================================================
1648 void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
1649                           const Standard_Real aPrm,
1650                           gp_Pnt2d& Pnt,
1651                           gp_Vec2d& aVec2d)
1652 {
1653   Standard_Real aTol=gp::Resolution();
1654   Standard_Integer i;
1655
1656   aC2d->D1(aPrm, Pnt, aVec2d);
1657   //
1658   if (aVec2d.Magnitude() <= aTol) {
1659     for (i = 2; i <= 100; i++){
1660       aVec2d = aC2d->DN(aPrm, i);
1661       if (aVec2d.Magnitude() > aTol) {
1662         break;
1663       }
1664     }
1665   }
1666 }
1667
1668 //  Modified by Sergey KHROMOV - Wed May 22 10:44:06 2002 OCC325 Begin
1669 //=======================================================================
1670 //function : GetPnts2d
1671 //purpose  : this function returns the parametric points of theVertex on theFace.
1672 //           If theVertex is a start and end vertex of theEdge hasSecondPnt
1673 //           becomes Standard_True and aPnt2 returns the second parametric point.
1674 //           Returns Standard_True if paraametric points are successfully found.
1675 //=======================================================================
1676
1677 static Standard_Boolean GetPnt2d(const TopoDS_Vertex    &theVertex,
1678                                  const TopoDS_Edge      &theEdge,
1679                                  const TopoDS_Face      &theFace,
1680                                        gp_Pnt2d         &aPnt)
1681 {
1682   Handle(Geom2d_Curve) aPCurve;
1683   Standard_Real        aFPar;
1684   Standard_Real        aLPar;
1685   Standard_Real        aParOnEdge;
1686   TopoDS_Vertex        aFirstVtx;
1687   TopoDS_Vertex        aLastVtx;
1688
1689   TopExp::Vertices(theEdge, aFirstVtx, aLastVtx);
1690
1691   if (!theVertex.IsSame(aFirstVtx) && !theVertex.IsSame(aLastVtx))
1692     return Standard_False;
1693
1694   aPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFPar, aLPar);
1695
1696   if (aPCurve.IsNull())
1697     return Standard_False;
1698
1699   aParOnEdge = BRep_Tool::Parameter(theVertex, theEdge);
1700   aPnt       = aPCurve->Value(aParOnEdge);
1701
1702   return Standard_True;
1703 }
1704
1705 //=======================================================================
1706 //function : Closed2dForPeriodicFace
1707 //purpose  : Checks the distance between first point of the first edge
1708 //           and last point of the last edge in 2d for periodic face.
1709 //=======================================================================
1710 static Standard_Boolean IsClosed2dForPeriodicFace
1711                         (const TopoDS_Face   &theFace,
1712                          const gp_Pnt2d      &theP1,
1713                          const gp_Pnt2d      &theP2,
1714                          const TopoDS_Vertex &theVertex)
1715 {
1716 // Check 2d distance for periodic faces with seam edge.
1717 // Searching for seam edges
1718   TopTools_ListOfShape aSeamEdges;
1719   TopTools_MapOfShape  NotSeams;
1720   TopTools_MapOfShape  ClosedEdges;
1721   TopExp_Explorer      anExp(theFace, TopAbs_EDGE);
1722
1723   for (;anExp.More(); anExp.Next()) {
1724     TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
1725
1726     if (NotSeams.Contains(anEdge))
1727       continue;
1728
1729     if (!IsOriented(anEdge) ||
1730         !BRep_Tool::IsClosed(anEdge, theFace)) {
1731       NotSeams.Add(anEdge);
1732       continue;
1733     }
1734
1735     if (!ClosedEdges.Add(anEdge))
1736       aSeamEdges.Append(anEdge);
1737   }
1738
1739   if (aSeamEdges.Extent() == 0)
1740     return Standard_True;
1741
1742 // check if theVertex lies on one of the seam edges
1743   BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
1744   Standard_Real       aTol      = BRep_Tool::Tolerance(theVertex);
1745   Standard_Real       aUResol   = aFaceSurface.UResolution(aTol);
1746   Standard_Real       aVResol   = aFaceSurface.VResolution(aTol);
1747   Standard_Real       aVicinity = Sqrt(aUResol*aUResol + aVResol*aVResol);
1748   Standard_Real       aDistP1P2 = theP1.Distance(theP2);
1749
1750
1751   TopTools_ListIteratorOfListOfShape anIter(aSeamEdges);
1752
1753   for (; anIter.More(); anIter.Next()) {
1754     TopoDS_Edge aSeamEdge = TopoDS::Edge(anIter.Value());
1755
1756     anExp.Init(aSeamEdge, TopAbs_VERTEX);
1757     for (; anExp.More(); anExp.Next()) {
1758       const TopoDS_Shape &aVtx = anExp.Current();
1759
1760 // We found an edge. Check the distance between two given points
1761 //  to be lower than the computed tolerance.
1762       if (IsOriented(aVtx) && aVtx.IsSame(theVertex)) {
1763         gp_Pnt2d         aPnt1;
1764         gp_Pnt2d         aPnt2;
1765         Standard_Real    a2dTol;
1766
1767         if (!GetPnt2d(theVertex, aSeamEdge, theFace, aPnt1))
1768           continue;
1769
1770         aSeamEdge = TopoDS::Edge(aSeamEdge.Reversed());
1771
1772         if (!GetPnt2d(theVertex, aSeamEdge, theFace, aPnt2))
1773           continue;
1774
1775         a2dTol = aPnt1.Distance(aPnt2)*1.e-2;
1776         a2dTol = Max(a2dTol, aVicinity);
1777
1778         if (aDistP1P2 > a2dTol)
1779           return Standard_False;
1780       }
1781     }
1782   }
1783
1784   return Standard_True;
1785 }
1786 //  Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End