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