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