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