0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / BRepCheck / BRepCheck_Face.cxx
1 // Created on: 1995-12-15
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 under
9 // the terms of the GNU Lesser General Public License 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
18 #include <Bnd_Box2d.hxx>
19 #include <BndLib_Add2dCurve.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_TFace.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepAdaptor_HSurface.hxx>
24 #include <BRepCheck.hxx>
25 #include <BRepCheck_Face.hxx>
26 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
27 #include <BRepCheck_ListOfStatus.hxx>
28 #include <BRepClass_FaceClassifier.hxx>
29 #include <BRepTopAdaptor_FClass2d.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom2dAdaptor_Curve.hxx>
32 #include <Geom2dInt_GInter.hxx>
33 #include <Geom_Curve.hxx>
34 #include <gp_Pnt2d.hxx>
35 #include <GProp_GProps.hxx>
36 #include <IntRes2d_Domain.hxx>
37 #include <IntRes2d_IntersectionPoint.hxx>
38 #include <IntRes2d_IntersectionSegment.hxx>
39 #include <NCollection_DataMap.hxx>
40 #include <Precision.hxx>
41 #include <Standard_Type.hxx>
42 #include <TColgp_SequenceOfPnt.hxx>
43 #include <TopAbs_State.hxx>
44 #include <TopExp.hxx>
45 #include <TopExp_Explorer.hxx>
46 #include <TopoDS.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Shape.hxx>
49 #include <TopoDS_Vertex.hxx>
50 #include <TopoDS_Wire.hxx>
51 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
52 #include <TopTools_DataMapOfShapeListOfShape.hxx>
53 #include <TopTools_ListIteratorOfListOfShape.hxx>
54 #include <TopTools_ListOfShape.hxx>
55 #include <TopTools_MapOfShape.hxx>
56 #include <TopTools_OrientedShapeMapHasher.hxx>
57 #include <TopTools_SequenceOfShape.hxx>
58
59 IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Face,BRepCheck_Result)
60
61 //#include <BRepAdaptor_Curve2d.hxx>
62 //#include <Geom2dInt_GInter.hxx>
63 typedef NCollection_DataMap<TopoDS_Shape, Bnd_Box2d, TopTools_OrientedShapeMapHasher> DataMapOfShapeBox2d;
64
65 static Standard_Boolean Intersect(const TopoDS_Wire&,
66                                   const TopoDS_Wire&,
67                                   const TopoDS_Face&,
68                                   const DataMapOfShapeBox2d&);
69                                   
70
71 static Standard_Boolean IsInside(const TopoDS_Wire& wir,
72                                  const Standard_Boolean Inside,
73                                  const BRepTopAdaptor_FClass2d& FClass2d,
74                                  const TopoDS_Face& F);
75
76 static Standard_Boolean CheckThin(const TopoDS_Shape& w,
77                                   const TopoDS_Shape& f);
78
79 //=======================================================================
80 //function : BRepCheck_Face
81 //purpose  : 
82 //=======================================================================
83
84 BRepCheck_Face::BRepCheck_Face (const TopoDS_Face& F)
85 : myIntres(BRepCheck_NoError),
86   myImbres(BRepCheck_NoError),
87   myOrires(BRepCheck_NoError)
88 {
89   Init(F);
90   myIntdone = Standard_False;
91   myImbdone = Standard_False;
92   myOridone = Standard_False;
93   myGctrl   = Standard_True;
94 }
95
96 //=======================================================================
97 //function : Minimum
98 //purpose  : 
99 //=======================================================================
100
101 void BRepCheck_Face::Minimum()
102 {
103   if (!myMin) {
104     BRepCheck_ListOfStatus thelist;
105     myMap.Bind(myShape, thelist);
106     BRepCheck_ListOfStatus& lst = myMap(myShape);
107
108     Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &myShape.TShape());
109     if (TF->Surface().IsNull()) {
110       BRepCheck::Add(lst,BRepCheck_NoSurface);
111     }
112     else {
113       // Flag natural restriction???
114     }
115     if (lst.IsEmpty()) {
116       lst.Append(BRepCheck_NoError);
117     }
118     myMin = Standard_True;
119   }
120 }
121
122
123 //=======================================================================
124 //function : InContext
125 //purpose  : 
126 //=======================================================================
127
128 void BRepCheck_Face::InContext(const TopoDS_Shape& S)
129 {
130   if (myMap.IsBound(S)) {
131     return;
132   }
133   BRepCheck_ListOfStatus thelist;
134   myMap.Bind(S, thelist);
135
136   BRepCheck_ListOfStatus& lst = myMap(S);
137   
138   TopExp_Explorer exp(S,TopAbs_FACE);
139   for (; exp.More(); exp.Next()) {
140     if (exp.Current().IsSame(myShape)) {
141       break;
142     }
143   }
144   if (!exp.More()) {
145     BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
146     return;
147   }
148
149   if (lst.IsEmpty()) {
150     lst.Append(BRepCheck_NoError);
151   }
152 }
153
154
155 //=======================================================================
156 //function : Blind
157 //purpose  : 
158 //=======================================================================
159
160 void BRepCheck_Face::Blind()
161 {
162   if (!myBlind) {
163     // nothing more than in the minimum
164     myBlind = Standard_True;
165   }
166 }
167
168
169 //=======================================================================
170 //function : IntersectWires
171 //purpose  : 
172 //=======================================================================
173
174 BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
175 {
176   if (myIntdone) {
177     if (Update) {
178       BRepCheck::Add(myMap(myShape),myIntres);
179     }
180     return myIntres;
181   }
182
183   myIntdone = Standard_True;
184   myIntres = BRepCheck_NoError;
185   // This method has to be called by an analyzer. It is assumed that
186   // each edge has a correct 2d representation on the face.
187
188   TopExp_Explorer exp1,exp2;
189
190   // the wires are mapped
191   exp1.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
192   TopTools_ListOfShape theListOfShape;
193   while (exp1.More()) {
194     if (!myMapImb.IsBound(exp1.Current())) {
195       myMapImb.Bind(exp1.Current(), theListOfShape);
196     }
197     else { // the same wire is met twice...
198       myIntres = BRepCheck_RedundantWire;
199       if (Update) {
200         BRepCheck::Add(myMap(myShape),myIntres);
201       }
202       return myIntres;
203     }
204     exp1.Next();
205   }
206
207   Geom2dAdaptor_Curve aC;
208   Standard_Real aFirst, aLast;
209   DataMapOfShapeBox2d aMapShapeBox2d;
210   for (exp1.Init (myShape, TopAbs_WIRE); exp1.More(); exp1.Next()) 
211   {
212     const TopoDS_Wire& aWire = TopoDS::Wire (exp1.Current());
213     // create 2d boxes for all edges from wire
214     Bnd_Box2d aBoxW;
215     for (exp2.Init (aWire, TopAbs_EDGE); exp2.More(); exp2.Next())
216     {
217       const TopoDS_Edge& anEdge = TopoDS::Edge (exp2.Current());
218       aC.Load (BRep_Tool::CurveOnSurface (anEdge, TopoDS::Face (myShape), aFirst, aLast));
219       // To avoid exeption in Segment if C1 is BSpline
220       if (aC.FirstParameter() > aFirst)
221       {
222         aFirst = aC.FirstParameter();
223       }
224       if (aC.LastParameter() < aLast)
225       {
226         aLast = aC.LastParameter();
227       }
228       Bnd_Box2d aBoxE;
229       BndLib_Add2dCurve::Add (aC, aFirst, aLast, 0., aBoxE);
230       aMapShapeBox2d.Bind (anEdge, aBoxE);
231       aBoxW.Add (aBoxE);
232     }
233     aMapShapeBox2d.Bind (aWire, aBoxW);
234   }
235
236   Standard_Integer Nbwire, Index,Indexbis;
237   Nbwire = myMapImb.Extent();
238
239   Index = 1;
240   while (Index < Nbwire) {
241     for (exp1.Init(myShape,TopAbs_WIRE),Indexbis = 0;
242          exp1.More();exp1.Next()) {
243       Indexbis++;
244       if (Indexbis == Index) {
245         break;
246       }
247     }
248     TopoDS_Wire wir1 = TopoDS::Wire(exp1.Current());
249     // to reduce the number of calls Intersect(wir1,wir2)
250     Bnd_Box2d aBox1, aBox2;
251     if (aMapShapeBox2d.IsBound (wir1))
252     {
253       aBox1 = aMapShapeBox2d (wir1);
254     }
255     exp1.Next();
256     for (; exp1.More(); exp1.Next()) {
257       const TopoDS_Wire& wir2 = TopoDS::Wire(exp1.Current());
258       if (aMapShapeBox2d.IsBound (wir2))
259       {
260         aBox2 = aMapShapeBox2d (wir2);
261       }
262       if (!aBox1.IsVoid() && !aBox2.IsVoid() && aBox1.IsOut (aBox2))
263       {
264         continue;
265       }
266       if (Intersect(wir1,wir2,TopoDS::Face(myShape), aMapShapeBox2d)) {
267         myIntres = BRepCheck_IntersectingWires;
268         if (Update) {
269           BRepCheck::Add(myMap(myShape),myIntres);
270         }
271         return myIntres;
272       }
273     }
274     Index++;
275   }
276   if (Update) {
277     BRepCheck::Add(myMap(myShape),myIntres);
278   }
279   return myIntres;
280 }
281
282
283 //=======================================================================
284 //function : ClassifyWires
285 //purpose  : 
286 //=======================================================================
287
288 BRepCheck_Status BRepCheck_Face::ClassifyWires(const Standard_Boolean Update)
289 {
290   // It is assumed that each wire does not intersect any other one.
291   if (myImbdone) {
292     if (Update) {
293       BRepCheck::Add(myMap(myShape),myImbres);
294     }
295     return myImbres;
296   }
297
298   myImbdone = Standard_True;
299   myImbres = IntersectWires();
300   if (myImbres != BRepCheck_NoError) {
301     if (Update) {
302       BRepCheck::Add(myMap(myShape),myImbres);
303     }
304     return myImbres;
305   }
306
307   Standard_Integer Nbwire = myMapImb.Extent();
308   if (Nbwire < 1) {
309     if (Update) {
310       BRepCheck::Add(myMap(myShape),myImbres);
311     }
312     return myImbres;
313   }
314
315   BRep_Builder B;
316   TopExp_Explorer exp1,exp2;
317   TopTools_ListOfShape theListOfShape;
318   for (exp1.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
319        exp1.More();exp1.Next()) {
320
321     const TopoDS_Wire& wir1 = TopoDS::Wire(exp1.Current());
322     TopoDS_Shape aLocalShape = myShape.EmptyCopied();
323     TopoDS_Face newFace = TopoDS::Face(aLocalShape);
324 //    TopoDS_Face newFace = TopoDS::Face(myShape.EmptyCopied());
325
326     newFace.Orientation(TopAbs_FORWARD);
327     B.Add(newFace,wir1);
328
329     BRepTopAdaptor_FClass2d FClass2d(newFace,Precision::PConfusion());
330     Standard_Boolean WireBienOriente = Standard_False;
331     if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) { 
332       WireBienOriente=Standard_True;
333       // the given wire defines a hole
334       myMapImb.UnBind(wir1);
335       myMapImb.Bind(wir1.Reversed(), theListOfShape);
336     }
337
338     for (exp2.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
339          exp2.More();exp2.Next()) {
340       const TopoDS_Wire& wir2 = TopoDS::Wire(exp2.Current());
341       if (!wir2.IsSame(wir1)) {
342         
343         if (IsInside(wir2,WireBienOriente,FClass2d,newFace)) { 
344           myMapImb(wir1).Append(wir2);
345         }
346       }
347     }
348   }
349   // It is required to have 1 wire that contains all others, and the others should not  
350   // contain anything (case solid ended) or
351   // the wires do not contain anything : in this case the wires should be
352   // holes in an infinite face.
353   TopoDS_Wire Wext;
354   for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMapImb);
355        itm.More();
356        itm.Next()) {
357     if (!itm.Value().IsEmpty()) {
358       if (Wext.IsNull()) {
359         Wext = TopoDS::Wire(itm.Key());
360       }
361       else {
362         myImbres = BRepCheck_InvalidImbricationOfWires;
363         if (Update) {
364           BRepCheck::Add(myMap(myShape),myImbres);
365         }
366         return myImbres;
367       }
368     }
369   }
370
371   if (!Wext.IsNull()) {
372     // verifies that the list contains nbwire-1 elements
373     if (myMapImb(Wext).Extent() != Nbwire-1) {
374       myImbres = BRepCheck_InvalidImbricationOfWires;
375       if (Update) {
376         BRepCheck::Add(myMap(myShape),myImbres);
377       }
378       return myImbres;
379     }
380   }
381   // quit without errors
382   if (Update) {
383     BRepCheck::Add(myMap(myShape),myImbres);
384   }
385   return myImbres;
386   
387 }
388
389
390 //=======================================================================
391 //function : OrientationOfWires
392 //purpose  : 
393 //=======================================================================
394
395 BRepCheck_Status BRepCheck_Face::OrientationOfWires
396    (const Standard_Boolean Update)
397 {
398   // WARNING : it is assumed that the edges of a wire are correctly oriented
399
400
401   Standard_Boolean Infinite = myShape.Infinite();
402
403   if (myOridone) {
404     if (Update) {
405       BRepCheck::Add(myMap(myShape),myOrires);
406     }
407     return myOrires;
408   }
409
410   myOridone = Standard_True;
411   myOrires = ClassifyWires();
412   if (myOrires != BRepCheck_NoError) {
413     if (Update) {
414       BRepCheck::Add(myMap(myShape),myOrires);
415     }
416     return myOrires;
417   }
418
419   Standard_Integer Nbwire = myMapImb.Extent();
420   TopoDS_Wire Wext;
421   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMapImb);
422   if (Nbwire == 1) {
423     if (!Infinite) {
424       Wext = TopoDS::Wire(itm.Key());
425     }
426   }
427   else {
428     for (;itm.More();itm.Next()) {
429       if (!itm.Value().IsEmpty()) {
430         Wext = TopoDS::Wire(itm.Key());
431       }
432     }
433   }
434
435   if (Wext.IsNull() && !Infinite) {
436     if (Nbwire>0) myOrires = BRepCheck_InvalidImbricationOfWires;
437     if (Update) {
438       BRepCheck::Add(myMap(myShape),myOrires);
439     }
440     return myOrires;
441   }
442
443   // BRep_Builder B;
444   TopExp_Explorer exp(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
445   for (; exp.More(); exp.Next()) {
446     const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
447     if (!Wext.IsNull() && wir.IsSame(Wext)) {
448       if (wir.Orientation() != Wext.Orientation()) {
449         //the exterior wire defines a hole 
450         if( CheckThin(wir,myShape.Oriented(TopAbs_FORWARD)) )
451           return myOrires;
452         myOrires = BRepCheck_BadOrientationOfSubshape;
453         if (Update) {
454           BRepCheck::Add(myMap(myShape),myOrires);
455         }
456         return myOrires;
457       }
458     }
459     else {
460       for (itm.Reset(); itm.More(); itm.Next()) {
461         if (itm.Key().IsSame(wir)) {
462           break;
463         }
464       }
465       // No control on More()
466       if (itm.Key().Orientation() == wir.Orientation()) {
467         // the given wire does not define a hole
468         myOrires = BRepCheck_BadOrientationOfSubshape;
469         if (Update) {
470           BRepCheck::Add(myMap(myShape),myOrires);
471         }
472         return myOrires;
473       }
474     }
475   }
476   // quit withour error
477   if (Update) {
478     BRepCheck::Add(myMap(myShape),myOrires);
479   }
480   return myOrires;
481 }
482
483
484 //=======================================================================
485 //function : SetUnorientable
486 //purpose  : 
487 //=======================================================================
488
489 void BRepCheck_Face::SetUnorientable()
490 {
491   BRepCheck::Add(myMap(myShape),BRepCheck_UnorientableShape);
492 }
493
494 //=======================================================================
495 //function :   SetStatus
496 //purpose  : 
497 //=======================================================================
498
499 void BRepCheck_Face::SetStatus(const BRepCheck_Status theStatus)
500 {
501     BRepCheck::Add(myMap(myShape),theStatus);
502 }
503
504 //=======================================================================
505 //function : IsUnorientable
506 //purpose  : 
507 //=======================================================================
508
509 Standard_Boolean BRepCheck_Face::IsUnorientable() const
510 {
511   if (myOridone) {
512     return (myOrires != BRepCheck_NoError);
513   }
514   for (BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
515        itl.More();
516        itl.Next()) {
517     if (itl.Value() == BRepCheck_UnorientableShape) {
518       return Standard_True;
519     }
520   }
521   return Standard_False;
522 }
523
524 //=======================================================================
525 //function : GeometricControls
526 //purpose  : 
527 //=======================================================================
528
529 void BRepCheck_Face::GeometricControls(const Standard_Boolean B)
530 {
531   if (myGctrl != B) {
532     if (B) {
533       myIntdone = Standard_False; 
534       myImbdone = Standard_False; 
535       myOridone = Standard_False; 
536     }
537     myGctrl = B;
538   }
539 }
540
541
542 //=======================================================================
543 //function : GeometricControls
544 //purpose  : 
545 //=======================================================================
546
547 Standard_Boolean BRepCheck_Face::GeometricControls() const
548 {
549   return myGctrl;
550 }
551
552
553 //=======================================================================
554 //function : Intersect
555 //purpose  : 
556 //=======================================================================
557
558 static Standard_Boolean Intersect(const TopoDS_Wire& wir1,
559                                   const TopoDS_Wire& wir2,
560                                   const TopoDS_Face& F,
561                                   const DataMapOfShapeBox2d& theMapEdgeBox)
562 {
563   Standard_Real Inter2dTol = 1.e-10;
564   TopExp_Explorer exp1,exp2;
565 //  BRepAdaptor_Curve2d cur1,cur2;
566
567   //Find common vertices of two wires - non-manifold case
568   TopTools_MapOfShape MapW1;
569   TopTools_SequenceOfShape CommonVertices;
570   for (exp1.Init( wir1, TopAbs_VERTEX ); exp1.More(); exp1.Next())
571     MapW1.Add( exp1.Current() );
572   for (exp2.Init( wir2, TopAbs_VERTEX ); exp2.More(); exp2.Next())
573     {
574       TopoDS_Shape V = exp2.Current();
575       if (MapW1.Contains( V ))
576         CommonVertices.Append( V );
577     }
578
579   // MSV 03.04.2002: create pure surface adaptor to avoid UVBounds computation
580   //                 due to performance problem
581   BRepAdaptor_Surface Surf(F,Standard_False);
582
583   TColgp_SequenceOfPnt PntSeq;
584   Standard_Integer i;
585   for (i = 1; i <= CommonVertices.Length(); i++)
586     {
587       TopoDS_Vertex V = TopoDS::Vertex( CommonVertices(i) );
588       gp_Pnt2d P2d = BRep_Tool::Parameters( V, F );
589       gp_Pnt P = Surf.Value( P2d.X(), P2d.Y() );
590       PntSeq.Append( P );
591     }
592
593   Geom2dAdaptor_Curve   C1,C2;
594   gp_Pnt2d              pfirst1,plast1,pfirst2,plast2;
595   Standard_Real         first1,last1,first2,last2;
596   Geom2dInt_GInter      Inter;
597   IntRes2d_Domain myDomain1,myDomain2;
598   Bnd_Box2d Box1, Box2;
599
600   for (exp1.Init(wir1,TopAbs_EDGE); exp1.More(); exp1.Next())
601     {
602       const TopoDS_Edge& edg1 = TopoDS::Edge(exp1.Current());
603       //    cur1.Initialize(edg1,F);
604       C1.Load( BRep_Tool::CurveOnSurface(edg1,F,first1,last1) );
605       // To avoid exeption in Segment if C1 is BSpline - IFV
606       if(C1.FirstParameter() > first1) first1 = C1.FirstParameter();
607       if(C1.LastParameter()  < last1 ) last1  = C1.LastParameter();
608
609       Box1.SetVoid();
610       if (theMapEdgeBox.IsBound (edg1))
611       {
612         Box1 = theMapEdgeBox (edg1);
613       }
614       if (Box1.IsVoid())
615       {
616         BndLib_Add2dCurve::Add( C1, first1, last1, 0., Box1 );
617       }
618       for (exp2.Init(wir2,TopAbs_EDGE); exp2.More(); exp2.Next())
619         {
620           const TopoDS_Edge& edg2 = TopoDS::Edge(exp2.Current());
621           if (!edg1.IsSame(edg2))
622             {
623               //cur2.Initialize(edg2,F);
624               C2.Load( BRep_Tool::CurveOnSurface(edg2,F,first2,last2) );
625               // To avoid exeption in Segment if C2 is BSpline - IFV
626               if(C2.FirstParameter() > first2) first2 = C2.FirstParameter();
627               if(C2.LastParameter()  < last2 ) last2  = C2.LastParameter();
628
629               Box2.SetVoid();
630               if (theMapEdgeBox.IsBound (edg2))
631               {
632           Box2 = theMapEdgeBox (edg2);
633               }
634               if (Box2.IsVoid())
635               {
636           BndLib_Add2dCurve::Add( C2, first2, last2, 0., Box2 );
637               }
638               if (! Box1.IsOut( Box2 ))
639                 {
640                   BRep_Tool::UVPoints(edg1,F,pfirst1,plast1);
641                   myDomain1.SetValues( pfirst1, first1, Inter2dTol, plast1, last1, Inter2dTol );
642                   BRep_Tool::UVPoints(edg2,F,pfirst2,plast2);
643                   myDomain2.SetValues( pfirst2, first2, Inter2dTol, plast2, last2, Inter2dTol );
644                   Inter.Perform( C1, myDomain1, C2, myDomain2, Inter2dTol, Inter2dTol );
645                   if (!Inter.IsDone())
646                     return Standard_True;
647                   if (Inter.NbSegments() > 0)
648                     {
649                       if (PntSeq.IsEmpty())
650                         return Standard_True;
651                       else
652                         {
653                           Standard_Integer NbCoinc = 0;
654                           for (i = 1; i <= Inter.NbSegments(); i++)
655                             {
656                               if (!Inter.Segment(i).HasFirstPoint() || !Inter.Segment(i).HasLastPoint())
657                                 return Standard_True;
658                               gp_Pnt2d FirstP2d = Inter.Segment(i).FirstPoint().Value();
659                               gp_Pnt2d LastP2d = Inter.Segment(i).LastPoint().Value();
660                               gp_Pnt FirstP = Surf.Value( FirstP2d.X(), FirstP2d.Y() );
661                               gp_Pnt LastP = Surf.Value( LastP2d.X(), LastP2d.Y() );
662                               for (Standard_Integer j = 1; j <= PntSeq.Length(); j++)
663                                 {
664                                   Standard_Real tolv = BRep_Tool::Tolerance( TopoDS::Vertex(CommonVertices(j)) );
665                                   if (FirstP.IsEqual( PntSeq(j), tolv ) || LastP.IsEqual( PntSeq(j), tolv ))
666                                     {
667                                       NbCoinc++;
668                                       break;
669                                     }
670                                 }
671                             }
672                           if (NbCoinc == Inter.NbSegments())
673                             return Standard_False;
674                           return Standard_True;
675                         }
676                     }
677                   if (Inter.NbPoints() > 0)
678                     {
679                       if (PntSeq.IsEmpty())
680                         return Standard_True;
681                       else
682                         {
683                           Standard_Integer NbCoinc = 0;
684                           for (i = 1; i <= Inter.NbPoints(); i++)
685                             {
686                               gp_Pnt2d P2d = Inter.Point(i).Value();
687                               gp_Pnt P = Surf.Value( P2d.X(), P2d.Y() );
688                               for (Standard_Integer j = 1; j <= PntSeq.Length(); j++)
689                                 {
690                                   Standard_Real tolv = BRep_Tool::Tolerance( TopoDS::Vertex(CommonVertices(j)) );
691                                   tolv += 1.e-8; //possible tolerance of intersection point
692                                   Standard_Real dd = P.SquareDistance(PntSeq(j));
693                                   if (dd <= tolv * tolv)
694                                     {
695                                       NbCoinc++;
696                                       break;
697                                     }
698                                 }
699                             }
700                           if (NbCoinc == Inter.NbPoints())
701                             return Standard_False;
702                           return Standard_True;
703                         }
704                     }
705                 }
706             }
707         }
708     }
709   return Standard_False;
710 }
711
712
713 //=======================================================================
714 //function : IsInside
715 //purpose  : 
716 //=======================================================================
717
718 static Standard_Boolean IsInside(const TopoDS_Wire& theWire,
719                                  const Standard_Boolean WireBienOriente,
720                                  const BRepTopAdaptor_FClass2d& FClass2d,
721                                  const TopoDS_Face& theFace)
722 {
723   Standard_Real aParameter, aFirst, aLast;
724
725   TopExp_Explorer anExplorer(theWire, TopAbs_EDGE);
726   for( ; anExplorer.More(); anExplorer.Next() )
727   {
728     const TopoDS_Edge& anEdge = TopoDS::Edge( anExplorer.Current() );
729     Handle(Geom2d_Curve) aCurve2D =
730       BRep_Tool::CurveOnSurface( anEdge, theFace, aFirst, aLast );
731
732     // Selects the parameter of point on the curve
733     if( !Precision::IsNegativeInfinite(aFirst) &&
734         !Precision::IsPositiveInfinite(aLast) )
735     {
736       aParameter = (aFirst + aLast) * 0.5;
737
738       // Edge is skipped if its parametric range is too small
739       if( Abs(aParameter - aFirst) < Precision::PConfusion() )
740       {
741         continue;
742       }
743
744           //Edge is skipped if its length is too small
745           Standard_Real aFirst3D, aLast3D;
746           Handle(Geom_Curve) aCurve = BRep_Tool::Curve( anEdge, aFirst3D, aLast3D );      
747       if ( aCurve.IsNull() )
748       {
749         continue;
750       }
751
752       gp_Pnt aPoints[2];
753       // Compute start point of edge
754       aCurve->D0( aFirst, aPoints[0] );
755       // Compute middle point of edge 
756       aCurve->D0( (aFirst3D+aLast3D)/2., aPoints[1] );
757       if( aPoints[0].Distance(aPoints[1]) < Precision::Confusion() )
758       {
759         continue;
760       }
761     }
762     else
763     {
764       if( Precision::IsNegativeInfinite(aFirst) &&
765           Precision::IsPositiveInfinite(aLast) )
766       {
767         aParameter = 0.;
768       }
769       else if( Precision::IsNegativeInfinite(aFirst) )
770       {
771         aParameter = aLast - 1.;
772       }
773       else
774       {
775         aParameter = aFirst + 1.;
776       }
777     }
778
779     // Find point on curve (edge)
780     gp_Pnt2d aPoint2D(aCurve2D->Value(aParameter));
781     // Compute the topological position of a point relative to face
782     TopAbs_State aState = FClass2d.Perform(aPoint2D, Standard_False);
783
784     if( WireBienOriente )
785     {
786       return aState == TopAbs_OUT;
787     }
788     else
789     {
790       return aState == TopAbs_IN;
791     }
792   }
793   return Standard_False;
794 }
795 Standard_Boolean CheckThin(const TopoDS_Shape& w, const TopoDS_Shape& f)
796 {
797   TopoDS_Face aF = TopoDS::Face(f);
798   TopoDS_Wire aW = TopoDS::Wire(w);
799
800   Standard_Integer nbE = 0;
801   TopTools_ListOfShape lE;
802   TopExp_Explorer exp(aW,TopAbs_EDGE);
803   for(; exp.More(); exp.Next()) {
804     const TopoDS_Shape& s = exp.Current();
805     lE.Append(s);
806     nbE++;
807   }
808
809   if( nbE != 2 ) return Standard_False;
810   TopoDS_Edge e1 = TopoDS::Edge(lE.First());
811   TopoDS_Edge e2 = TopoDS::Edge(lE.Last());
812
813   TopoDS_Vertex v1, v2, v3, v4;
814   TopExp::Vertices(e1,v1,v2);
815   TopExp::Vertices(e2,v3,v4);
816
817   if( v1.IsNull() || v2.IsNull() || 
818       v3.IsNull() || v4.IsNull() ) return Standard_False;
819
820   if( v1.IsSame(v2) || v3.IsSame(v4) )
821     return Standard_False;
822
823   Standard_Boolean sF = Standard_False, sL = Standard_False;
824   if( v1.IsSame(v3) || v1.IsSame(v4) ) sF = Standard_True;
825   if( v2.IsSame(v3) || v2.IsSame(v4) ) sL = Standard_True;
826
827   if( !sF || !sL ) return Standard_False;
828
829   TopAbs_Orientation e1or = e1.Orientation();
830   TopAbs_Orientation e2or = e2.Orientation();
831  
832   Standard_Real f1 = 0., l1 = 0., f2 = 0., l2 = 0.;
833   Handle(Geom2d_Curve) pc1 = BRep_Tool::CurveOnSurface(e1,aF,f1,l1);
834   Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface(e2,aF,f2,l2);
835   
836   if( pc1.IsNull() || pc2.IsNull() ) return Standard_False;
837
838   Standard_Real d1 = Abs(l1-f1)/100.;
839   Standard_Real d2 = Abs(l2-f2)/100.;
840   Standard_Real m1 = (l1+f1)*0.5;
841   Standard_Real m2 = (l2+f2)*0.5;
842
843   gp_Pnt2d p1f(pc1->Value(m1-d1));
844   gp_Pnt2d p1l(pc1->Value(m1+d1));
845   gp_Pnt2d p2f(pc2->Value(m2-d2));
846   gp_Pnt2d p2l(pc2->Value(m2+d2));
847
848   gp_Vec2d vc1(p1f,p1l);
849   gp_Vec2d vc2(p2f,p2l);
850   
851   if( (vc1*vc2) >= 0. && e1or == e2or ) return Standard_False;
852
853   return Standard_True;
854 }