0023947: Eliminate trivial compiler warnings in MSVC++ with warning level 4
[occt.git] / src / IntTools / IntTools_FClass2d.cxx
1 // Created on: 1995-03-22
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <IntTools_FClass2d.ixx>
23
24 #include <stdio.h>
25
26 #include <Precision.hxx>
27 #include <gp_Pnt.hxx>
28 #include <ElCLib.hxx>
29
30 #include <Geom2dInt_Geom2dCurveTool.hxx>
31 #include <GeomAbs_SurfaceType.hxx>
32
33 #include <BRep_Tool.hxx>
34 #include <BRepTools_WireExplorer.hxx>
35 #include <BRepClass_FaceClassifier.hxx>
36 #include <CSLib_Class2d.hxx>
37 #include <BRepAdaptor_HSurface.hxx>
38 #include <BRepAdaptor_Curve.hxx>
39 #include <BRepAdaptor_Curve2d.hxx>
40
41 #include <TopoDS.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopExp.hxx>
44 #include <TopAbs_Orientation.hxx>
45 #include <TopExp_Explorer.hxx>
46 #include <TColgp_SequenceOfPnt2d.hxx>
47
48 #include <TColgp_Array1OfPnt2d.hxx>
49 #include <TopoDS_Wire.hxx>
50 #include <TColStd_DataMapOfIntegerInteger.hxx>
51 #include <TColgp_SequenceOfVec2d.hxx>
52
53 //=======================================================================
54 //function : IntTools_FClass2d:IntTools:_FClass2d
55 //purpose  : 
56 //=======================================================================
57 IntTools_FClass2d::IntTools_FClass2d()
58 {
59 }
60 //=======================================================================
61 //function : IntTools_FClass2d::IntTools_FClass2d
62 //purpose  : 
63 //=======================================================================
64   IntTools_FClass2d::IntTools_FClass2d(const TopoDS_Face& aFace,
65                                        const Standard_Real TolUV) 
66 : Toluv(TolUV), Face(aFace)  
67 {
68   Init(Face, Toluv);
69 }
70 //=======================================================================
71 //function : IsHole
72 //purpose  : 
73 //=======================================================================
74   Standard_Boolean IntTools_FClass2d::IsHole() const
75 {
76   return myIsHole;
77
78 //=======================================================================
79 //function : Init
80 //purpose  : 
81 //=======================================================================
82   void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
83                                const Standard_Real TolUV) 
84 {
85   Standard_Boolean WireIsNotEmpty, Ancienpnt3dinitialise, degenerated;
86   Standard_Integer nbpnts, firstpoint, NbEdges;
87   Standard_Integer iX, aNbs1, nbs, Avant, BadWire;
88   Standard_Real u, du, Tole, Tol, pfbid, plbid;
89   Standard_Real FlecheU, FlecheV, TolVertex1, TolVertex;
90   Standard_Real uFirst, uLast;
91   Standard_Real aPrCf, aPrCf2;
92   //
93   TopoDS_Edge  edge;
94   TopoDS_Vertex Va,Vb;
95   TopAbs_Orientation Or;
96   BRepTools_WireExplorer aWExp;
97   TopExp_Explorer aExpF, aExp;
98   Handle(Geom2d_Curve) aC2D;
99   gp_Pnt Ancienpnt3d;
100   TColgp_SequenceOfPnt2d SeqPnt2d;
101   TColStd_DataMapOfIntegerInteger anIndexMap;
102   TColgp_SequenceOfVec2d          aD1Prev;
103   TColgp_SequenceOfVec2d          aD1Next;
104   //
105   aPrCf=Precision::Confusion();
106   aPrCf2=aPrCf*aPrCf;
107   myIsHole=Standard_True;
108   //
109   Toluv=TolUV;
110   Face=aFace;
111   Face.Orientation(TopAbs_FORWARD);
112   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
113   surf->ChangeSurface().Initialize(aFace, Standard_False);
114   //
115   Tole = 0.;
116   Tol=0.;
117   Umin = Vmin = RealLast();
118   Umax = Vmax = -Umin;
119   BadWire=0;
120   //
121   //if face has several wires and one of them is bad,
122   //it is necessary to process all of them for correct
123   //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06 
124   //
125   aExpF.Init(Face,TopAbs_WIRE); 
126   for(; aExpF.More();  aExpF.Next()) {
127     const TopoDS_Wire& aW=*((TopoDS_Wire*)&aExpF.Current());
128     //
129     nbpnts = 0;
130     firstpoint =1;
131     FlecheU = 0.;
132     FlecheV = 0.;
133     TolVertex1=0.;
134     TolVertex=0.;
135     WireIsNotEmpty = Standard_False;
136     Ancienpnt3dinitialise=Standard_False;
137     Ancienpnt3d.SetCoord(0.,0.,0.);
138     //
139     SeqPnt2d.Clear();
140     anIndexMap.Clear();
141     aD1Prev.Clear();
142     aD1Next.Clear();
143     //
144     // NbEdges
145     NbEdges=0;
146     aExp.Init(aW, TopAbs_EDGE);
147     for(; aExp.More(); aExp.Next()) { 
148       NbEdges++;
149     }
150     //
151     aWExp.Init(aW, Face);
152     for(;aWExp.More(); aWExp.Next()) {
153       NbEdges--;
154       edge = aWExp.Current();
155       Or = edge.Orientation();
156       if(!(Or==TopAbs_FORWARD || Or==TopAbs_REVERSED)) {
157         continue;
158       }
159       //
160       aC2D=BRep_Tool::CurveOnSurface(edge, Face, pfbid, plbid);
161       if (aC2D.IsNull()) {
162         return;
163       }
164       //
165       BRepAdaptor_Curve2d C(edge,Face);
166       BRepAdaptor_Curve C3d;
167       //------------------------------------------
168       degenerated=Standard_False;
169       if(BRep_Tool::Degenerated(edge) ||
170          BRep_Tool::IsClosed(edge, Face)) {
171         degenerated=Standard_True;
172       }
173       //
174       TopExp::Vertices(edge,Va,Vb);
175       //
176       TolVertex1=0.;
177       TolVertex=0.;
178       if (Va.IsNull()) {
179         degenerated=Standard_True;
180       } 
181       else {
182         TolVertex1=BRep_Tool::Tolerance(Va);
183       }
184       if (Vb.IsNull()){
185         degenerated=Standard_True;
186       } 
187       else {
188         TolVertex=BRep_Tool::Tolerance(Vb);
189       }
190         // 
191       if(TolVertex<TolVertex1) {
192         TolVertex=TolVertex1;
193       } 
194       //
195       //-- Verification of cases when forgotten to code degenereted
196       if(!degenerated) {
197         // check that whole curve is located in vicinity of its middle point
198         // (within sphere of Precision::Confusion() diameter)
199         C3d.Initialize (edge, Face);
200         gp_Pnt P3da = C3d.Value (0.5 * (pfbid + plbid));
201         du = plbid - pfbid;
202         const int NBSTEPS = 10;
203         Standard_Real aPrec2 = 0.25 * Precision::Confusion() * Precision::Confusion();
204         degenerated = Standard_True;
205         for (Standard_Integer i=0; i <= NBSTEPS; i++)
206         {
207           Standard_Real u = pfbid + i * du / NBSTEPS;
208           gp_Pnt P3db = C3d.Value (u);
209           Standard_Real aR2 = P3da.SquareDistance (P3db);
210           if (aR2 > aPrec2) {
211             degenerated = Standard_False;
212             break;
213           }
214         }
215       }//if(!degenerated)
216       //-- ----------------------------------------
217       Tole = BRep_Tool::Tolerance(edge);
218       if(Tole>Tol) {
219         Tol=Tole;
220       }
221       //
222       // NbSamples +> nbs
223       nbs = Geom2dInt_Geom2dCurveTool::NbSamples(C);
224       if (nbs > 2) {
225         nbs*=4;
226       }
227       du = (plbid-pfbid)/(Standard_Real)(nbs-1);
228       //
229       if(Or==TopAbs_FORWARD) { 
230         u = pfbid;
231         uFirst=pfbid;
232         uLast=plbid;
233       }
234       else { 
235         u = plbid;
236         uFirst=plbid;
237         uLast=pfbid;
238         du=-du;
239       }
240       //
241       // aPrms
242       aNbs1=nbs+1;
243       TColStd_Array1OfReal aPrms(1, aNbs1);
244       //
245       if (nbs==2) {
246         Standard_Real aCoef=0.0025;
247         aPrms(1)=uFirst;
248         aPrms(2)=uFirst+aCoef*(uLast-uFirst);
249         aPrms(3)=uLast;
250       }
251       else if (nbs>2) {
252         aNbs1=nbs;
253         aPrms(1)=uFirst;
254         for (iX=2; iX<aNbs1; ++iX) {
255           aPrms(iX)=u+(iX-1)*du;
256         }
257         aPrms(aNbs1)=uLast;
258       }
259       //
260       //-- ------------------------------------------------------------
261       //-- Check distance uv between the start point of the edge
262       //-- and the last point saved in SeqPnt2d
263       //-- To to set the first point of the current 
264       //-- afar from the last saved point
265       Avant = nbpnts;
266       for(iX=firstpoint; iX<=aNbs1; iX++) {
267         Standard_Boolean IsRealCurve3d;
268         Standard_Integer ii;
269         Standard_Real aDstX;
270         gp_Pnt2d P2d;
271         gp_Pnt P3d;
272         //
273         u=aPrms(iX);
274         P2d = C.Value(u);
275         if(P2d.X()<Umin) Umin = P2d.X();
276         if(P2d.X()>Umax) Umax = P2d.X();
277         if(P2d.Y()<Vmin) Vmin = P2d.Y();
278         if(P2d.Y()>Vmax) Vmax = P2d.Y();
279         //
280         aDstX=RealLast();       
281         if(degenerated==Standard_False) { 
282           P3d=C3d.Value(u);
283           if(nbpnts>1) {
284             if(Ancienpnt3dinitialise) { 
285               aDstX=P3d.SquareDistance(Ancienpnt3d);
286             }
287           }
288         }
289         //
290         IsRealCurve3d = Standard_True; 
291         if (aDstX < aPrCf2)  {
292           if(iX>1) {
293             Standard_Real aDstX1;
294             gp_Pnt MidP3d;
295             //
296             MidP3d = C3d.Value(0.5*(u+aPrms(iX-1)));
297             aDstX1=P3d.SquareDistance( MidP3d );
298             if (aDstX1 < aPrCf2){
299               IsRealCurve3d = Standard_False;
300             }
301           }
302         }
303         //
304         if (IsRealCurve3d) {
305           if(degenerated==Standard_False) { 
306             Ancienpnt3d=P3d;
307             Ancienpnt3dinitialise=Standard_True;
308           }
309           nbpnts++;
310           SeqPnt2d.Append(P2d);
311         }
312         //
313         ii=nbpnts;
314         if(ii>(Avant+4)) { 
315           Standard_Real ul, dU, dV;
316           gp_Pnt2d Pp;
317           //
318           gp_Lin2d Lin(SeqPnt2d(ii-2),gp_Dir2d(gp_Vec2d(SeqPnt2d(ii-2),SeqPnt2d(ii))));
319           ul = ElCLib::Parameter(Lin,SeqPnt2d(ii-1));
320           Pp = ElCLib::Value(ul,Lin);
321           dU = Abs(Pp.X()-SeqPnt2d(ii-1).X());
322           dV = Abs(Pp.Y()-SeqPnt2d(ii-1).Y());
323           if(dU>FlecheU) {
324             FlecheU = dU;
325           }
326           if(dV>FlecheV) {
327             FlecheV = dV;
328           }
329         }
330       }// for(iX=firstpoint; iX<=aNbs1; iX++) {
331       //
332       if(BadWire) {
333         continue; //if face has several wires and one of them is bad,
334                   //it is necessary to process all of them for correct
335                   //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06 
336       }
337       //
338       if(firstpoint==1) firstpoint=2;
339       WireIsNotEmpty = Standard_True;
340       // Append the derivative of the first parameter.
341       Standard_Real aU = aPrms(1);
342       gp_Pnt2d      aP;
343       gp_Vec2d      aV;
344
345       C.D1(aU, aP, aV);
346
347       if(Or == TopAbs_REVERSED)
348         aV.Reverse();
349
350       aD1Next.Append(aV);
351
352       // Append the derivative of the last parameter.
353       aU = aPrms(aNbs1);
354       C.D1(aU, aP, aV);
355
356       if(Or == TopAbs_REVERSED)
357         aV.Reverse();
358
359       if (NbEdges > 0)
360         aD1Prev.Append(aV);
361       else
362         aD1Prev.Prepend(aV);
363
364       // Fill the map anIndexMap.
365       if (Avant > 0)
366         anIndexMap.Bind(Avant, aD1Next.Length());
367       else
368         anIndexMap.Bind(1, aD1Next.Length());
369     } //for(;aWExp.More(); aWExp.Next()) {
370     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
371     //
372     if(NbEdges) { 
373       //-- count ++ with normal explorer and -- with Wire Explorer
374       TColgp_Array1OfPnt2d PClass(1,2);
375       gp_Pnt2d anInitPnt(0., 0.);
376       //
377       PClass.Init(anInitPnt);
378       TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
379       BadWire=1;
380       TabOrien.Append(-1);
381     }
382     //
383     else if(WireIsNotEmpty) { 
384       TColgp_Array1OfPnt2d PClass(1,nbpnts);
385       gp_Pnt2d anInitPnt(0., 0.);
386       //
387       PClass.Init(anInitPnt);
388       if(nbpnts>3) { 
389         Standard_Integer im2=nbpnts-2;
390         Standard_Integer im1=nbpnts-1;
391         Standard_Integer im0=1;
392         Standard_Integer ii;
393         Standard_Real    angle = 0.0;
394         Standard_Real aX0, aY0, aX1, aY1, aS;
395         //
396         aS=0.;
397         //
398
399         Standard_Integer iFlag=1;
400         PClass(im2)=SeqPnt2d.Value(im2);
401         PClass(im1)=SeqPnt2d.Value(im1);
402         PClass(nbpnts)=SeqPnt2d.Value(nbpnts);
403         for(ii=1; ii<nbpnts; ii++,im0++,im1++,im2++) { 
404           if(im2>=nbpnts) im2=1;
405           if(im1>=nbpnts) im1=1;
406           PClass(ii)=SeqPnt2d.Value(ii);
407           //
408           const gp_Pnt2d& aP2D1=PClass(im1);
409           const gp_Pnt2d& aP2D0=PClass(im0);
410           //aP2D0 is next to aP2D1
411           aP2D0.Coord(aX0, aY0);
412           aP2D1.Coord(aX1, aY1);
413           aS=aS+(aY0+aY1)*(aX1-aX0); 
414
415           gp_Vec2d A(PClass(im2),PClass(im1));
416           gp_Vec2d B(PClass(im1),PClass(im0));
417
418           Standard_Real N = A.Magnitude() * B.Magnitude();
419           if(N>1e-16) { 
420             Standard_Real a=A.Angle(B);
421             //  
422             if (anIndexMap.IsBound(im1)) {
423               Standard_Integer  anInd  = anIndexMap.Find(im1);
424               const gp_Vec2d   &aVPrev = aD1Prev.Value(anInd);
425               const gp_Vec2d   &aVNext = aD1Next.Value(anInd);
426
427               Standard_Real aN = aVPrev.Magnitude() * aVNext.Magnitude();
428               if(aN > 1e-16) { 
429                 Standard_Real aDerivAngle = aVPrev.Angle(aVNext);
430                 //ifv 23.08.06
431                 if(Abs(aDerivAngle) <= Precision::Angular()) aDerivAngle = 0.; 
432                 //ifv 23.08.06 : if edges continuity > G1, |aDerivAngle| ~0,
433                 //but can has wrong sign and causes condition aDerivAngle * a < 0.
434                 //that is wrong in such situation
435                 if (iFlag && aDerivAngle * a < 0.) {
436                   iFlag=0;
437                   // Bad case.
438                   angle = 0.;
439                 }
440               }
441             }
442             angle+=a;
443           }
444         }//for(ii=1; ii<nbpnts; ii++,im0++,im1++,im2++) { 
445         if (!iFlag) {
446           angle = 0.; 
447         }
448         if(aS>0.){
449           myIsHole=Standard_False;
450         }
451         //
452         if(FlecheU<Toluv)
453           FlecheU = Toluv;
454
455         if(FlecheV<Toluv)
456           FlecheV = Toluv;
457
458         TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
459         //
460         if((angle<2 && angle>-2)||(angle>10)||(angle<-10)) { 
461           BadWire=1;
462           TabOrien.Append(-1);
463         } 
464         else {  
465           TabOrien.Append((angle>0.0)? 1 : 0);
466         }
467       } 
468       else { 
469         BadWire=1;
470         TabOrien.Append(-1);
471         TColgp_Array1OfPnt2d PPClass(1,2);
472         PPClass.Init(anInitPnt);
473         TabClass.Append((void *)new CSLib_Class2d(PPClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
474       }
475     }// else if(WireIsNotEmpty)
476   } // for(; aExpF.More();  aExpF.Next()) {
477   //
478   Standard_Integer nbtabclass = TabClass.Length();
479   //
480   if(nbtabclass>0) { 
481     //-- if an error on a wire was detected : all TabOrien set to -1
482     if(BadWire) {
483       TabOrien(1)=-1;
484     }
485     
486     if(   surf->GetType()==GeomAbs_Cone
487        || surf->GetType()==GeomAbs_Cylinder
488        || surf->GetType()==GeomAbs_Torus
489        || surf->GetType()==GeomAbs_Sphere
490        || surf->GetType()==GeomAbs_SurfaceOfRevolution) { 
491       Standard_Real uuu=M_PI+M_PI-(Umax-Umin);
492       if(uuu<0) uuu=0;
493       U1 = Umin-uuu*0.5;
494       U2 = U1+M_PI+M_PI;
495     }
496     else { 
497       U1=U2=0.0; 
498     } 
499     
500     if(surf->GetType()==GeomAbs_Torus) { 
501       Standard_Real uuu=M_PI+M_PI-(Vmax-Vmin);
502       if(uuu<0) uuu=0;
503       
504       V1 = Vmin-uuu*0.5;
505       V2 = V1+M_PI+M_PI;
506     }
507     else { 
508       V1=V2=0.0; 
509     }   
510   }
511 }
512 //=======================================================================
513 //function : PerformInfinitePoint
514 //purpose  : 
515 //=======================================================================
516   TopAbs_State IntTools_FClass2d::PerformInfinitePoint() const 
517
518   if(Umax==-RealLast() || Vmax==-RealLast() || Umin==RealLast() || Vmin==RealLast()) { 
519     return(TopAbs_IN);
520   }
521   gp_Pnt2d P(Umin-(Umax-Umin),Vmin-(Vmax-Vmin));
522   return(Perform(P,Standard_False));
523 }
524 //=======================================================================
525 //function : Perform
526 //purpose  : 
527 //=======================================================================
528   TopAbs_State IntTools_FClass2d::Perform(const gp_Pnt2d& _Puv,
529                                           const Standard_Boolean RecadreOnPeriodic) const
530
531   Standard_Integer dedans, nbtabclass;
532   
533   nbtabclass = TabClass.Length();
534   
535   if(nbtabclass==0) { 
536     return(TopAbs_IN);
537   }
538   
539   //-- U1 is the First Param and U2 is in this case U1+Period
540   Standard_Real u, v, uu, vv,  uperiod, vperiod;
541   Standard_Boolean IsUPer, IsVPer, urecadre, vrecadre;
542   TopAbs_State Status= TopAbs_UNKNOWN;
543
544   u=_Puv.X();
545   v=_Puv.Y();
546   uu = u, vv = v;
547
548   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
549   surf->ChangeSurface().Initialize( Face, Standard_False );
550   
551   uperiod=0., vperiod=0.;
552   IsUPer = surf->IsUPeriodic();
553   IsVPer = surf->IsVPeriodic();
554
555   if (IsUPer){ 
556     uperiod = surf->UPeriod();
557   }
558
559   if (IsVPer){
560     vperiod = surf->VPeriod();
561   }
562   
563   urecadre = Standard_False;
564   vrecadre = Standard_False;
565
566   if (RecadreOnPeriodic) {
567     
568     if (IsUPer) {
569       if (uu < Umin)
570         while (uu < Umin) {
571           uu += uperiod;
572         }
573       else {
574         while (uu >= Umin){
575           uu -= uperiod;
576         }
577         uu += uperiod;
578       }
579     }// if (IsUPer) {
580     
581     if (IsVPer) {
582       if (vv < Vmin)
583         while (vv < Vmin){
584           vv += vperiod;
585         }
586       else {
587         while (vv >= Vmin) {
588           vv -= vperiod;
589         }
590         vv += vperiod;
591       }
592     }//if (IsVPer) {
593   }
594
595   for(;;) {
596     dedans = 1;
597     gp_Pnt2d Puv(u,v);
598       
599     if(TabOrien(1)!=-1) {
600       Standard_Integer n, cur, TabOrien_n ;
601       for(n=1; n<=nbtabclass; n++) { 
602         cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv);
603         TabOrien_n=TabOrien(n);
604
605         if(cur==1) { 
606           if(TabOrien_n==0) { 
607             dedans = -1; 
608             break;
609           }
610         }
611         else if(cur==-1) { 
612           if(TabOrien_n==1) {  
613             dedans = -1; 
614             break;
615           }
616         }
617         else { 
618           dedans = 0;
619           break;
620         }
621       } // for(n=1; n<=nbtabclass; n++)
622
623       if(dedans==0) { 
624         BRepClass_FaceClassifier aClassifier;
625         aClassifier.Perform(Face,Puv,Toluv);
626         Status = aClassifier.State();
627       }
628       if(dedans == 1) { 
629         Status = TopAbs_IN;
630       }
631       if(dedans == -1) {
632         Status = TopAbs_OUT;
633       }
634     } // if(TabOrien(1)!=-1) {
635     
636     else {  //-- TabOrien(1)=-1   Wrong Wire
637       BRepClass_FaceClassifier aClassifier;
638       aClassifier.Perform(Face,Puv,Toluv);
639       Status = aClassifier.State();
640     }
641     
642     if (!RecadreOnPeriodic || !IsUPer && !IsVPer)
643       return Status;
644     
645     if (Status == TopAbs_IN || Status == TopAbs_ON)
646       return Status;
647     
648     if (!urecadre){
649       u = uu;
650       urecadre = Standard_True;
651     }
652     else {
653       if (IsUPer){
654         u += uperiod;
655       }
656     }
657
658     if (u > Umax || !IsUPer) {
659       if (!vrecadre){
660         v = vv;
661         vrecadre = Standard_True;
662       }
663       else {
664         if (IsVPer){
665           v += vperiod;
666         }
667       }
668
669       u = uu;
670       
671       if (v > Vmax || !IsVPer) {
672         return Status;
673       }
674     }
675   } //while (1)
676 }
677
678 //=======================================================================
679 //function : TestOnRestriction
680 //purpose  : 
681 //=======================================================================
682   TopAbs_State IntTools_FClass2d::TestOnRestriction(const gp_Pnt2d& _Puv,
683                                                     const Standard_Real Tol,
684                                                     const Standard_Boolean RecadreOnPeriodic) const
685
686
687   Standard_Integer dedans, nbtabclass;
688   
689   nbtabclass = TabClass.Length();
690   
691   if(nbtabclass==0) { 
692     return(TopAbs_IN);
693   }
694   
695   //-- U1 is the First Param and U2 in this case is U1+Period
696   Standard_Real u=_Puv.X();
697   Standard_Real v=_Puv.Y();
698   Standard_Real uu = u, vv = v;
699   
700   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
701   surf->ChangeSurface().Initialize( Face, Standard_False );
702   Standard_Boolean IsUPer, IsVPer;
703   Standard_Real uperiod=0, vperiod=0;
704   if ((IsUPer = surf->IsUPeriodic()))
705     uperiod = surf->UPeriod();
706   if ((IsVPer = surf->IsVPeriodic()))
707     vperiod = surf->VPeriod();
708   TopAbs_State Status = TopAbs_UNKNOWN;
709   Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
710   
711   if (RecadreOnPeriodic)
712     {
713       if (IsUPer)
714         {
715           if (uu < Umin)
716             while (uu < Umin)
717               uu += uperiod;
718           else
719             {
720               while (uu >= Umin)
721                 uu -= uperiod;
722               uu += uperiod;
723             }
724         }
725       if (IsVPer)
726         {
727           if (vv < Vmin)
728             while (vv < Vmin)
729               vv += vperiod;
730           else
731             {
732               while (vv >= Vmin)
733                 vv -= vperiod;
734               vv += vperiod;
735             }
736         }
737     }
738   
739   for (;;) {
740     dedans = 1;
741     gp_Pnt2d Puv(u,v);
742     
743     if(TabOrien(1)!=-1) { 
744       for(Standard_Integer n=1; n<=nbtabclass; n++) { 
745         Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans_OnMode(Puv,Tol);
746         if(cur==1) { 
747           if(TabOrien(n)==0) { 
748             dedans = -1; 
749             break;
750           }
751         }
752         else if(cur==-1) { 
753           if(TabOrien(n)==1) {  
754             dedans = -1; 
755             break;
756           }
757         }
758         else { 
759           dedans = 0;
760           break;
761         }
762       }
763       if(dedans==0) {
764         Status = TopAbs_ON;
765       }
766       if(dedans == 1) {
767         Status = TopAbs_IN;
768       }
769       if(dedans == -1) {
770         Status = TopAbs_OUT;
771       }
772     }
773     else {  //-- TabOrien(1)=-1  Wrong  Wire 
774       BRepClass_FaceClassifier aClassifier;
775       aClassifier.Perform(Face,Puv,Tol);
776       Status = aClassifier.State();
777     }
778     
779     if (!RecadreOnPeriodic || !IsUPer && !IsVPer)
780       return Status;
781     if (Status == TopAbs_IN || Status == TopAbs_ON)
782       return Status;
783     
784     if (!urecadre)
785       {
786         u = uu;
787         urecadre = Standard_True;
788       }
789     else
790       if (IsUPer)
791         u += uperiod;
792     if (u > Umax || !IsUPer)
793       {
794         if (!vrecadre)
795           {
796             v = vv;
797             vrecadre = Standard_True;
798           }
799         else
800           if (IsVPer)
801             v += vperiod;
802         
803         u = uu;
804         
805         if (v > Vmax || !IsVPer)
806           return Status;
807       }
808   } //for (;;)
809 }
810
811 //=======================================================================
812 //function : Destroy
813 //purpose  : 
814 //=======================================================================
815   void IntTools_FClass2d::Destroy() 
816
817   Standard_Integer nbtabclass = TabClass.Length(); 
818   for(Standard_Integer d=1; d<=nbtabclass;d++) {
819     if(TabClass(d)) { 
820       delete ((CSLib_Class2d *)TabClass(d));
821       TabClass(d)=NULL;
822     }
823   }
824 }
825
826