f8319712e0d2198d01e22077abe5d760fbe74586
[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 nbtabclass = TabClass.Length();
532   if (nbtabclass == 0)
533   {
534     return TopAbs_IN;
535   }
536
537   //-- U1 is the First Param and U2 is in this case U1+Period
538   Standard_Real u = _Puv.X();
539   Standard_Real v = _Puv.Y();
540   Standard_Real uu = u;
541   Standard_Real vv = v;
542   TopAbs_State Status = TopAbs_UNKNOWN;
543
544   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
545   surf->ChangeSurface().Initialize( Face, Standard_False );
546   
547   const Standard_Boolean IsUPer  = surf->IsUPeriodic();
548   const Standard_Boolean IsVPer  = surf->IsVPeriodic();
549   const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
550   const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
551
552   Standard_Boolean urecadre = Standard_False;
553   Standard_Boolean vrecadre = Standard_False;
554   Standard_Integer dedans = 1;
555
556   if (RecadreOnPeriodic) {
557     
558     if (IsUPer) {
559       if (uu < Umin)
560         while (uu < Umin) {
561           uu += uperiod;
562         }
563       else {
564         while (uu >= Umin){
565           uu -= uperiod;
566         }
567         uu += uperiod;
568       }
569     }// if (IsUPer) {
570     
571     if (IsVPer) {
572       if (vv < Vmin)
573         while (vv < Vmin){
574           vv += vperiod;
575         }
576       else {
577         while (vv >= Vmin) {
578           vv -= vperiod;
579         }
580         vv += vperiod;
581       }
582     }//if (IsVPer) {
583   }
584
585   for(;;) {
586     dedans = 1;
587     gp_Pnt2d Puv(u,v);
588       
589     if(TabOrien(1)!=-1) {
590       Standard_Integer n, cur, TabOrien_n ;
591       for(n=1; n<=nbtabclass; n++) { 
592         cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv);
593         TabOrien_n=TabOrien(n);
594
595         if(cur==1) { 
596           if(TabOrien_n==0) { 
597             dedans = -1; 
598             break;
599           }
600         }
601         else if(cur==-1) { 
602           if(TabOrien_n==1) {  
603             dedans = -1; 
604             break;
605           }
606         }
607         else { 
608           dedans = 0;
609           break;
610         }
611       } // for(n=1; n<=nbtabclass; n++)
612
613       if(dedans==0) { 
614         BRepClass_FaceClassifier aClassifier;
615         aClassifier.Perform(Face,Puv,Toluv);
616         Status = aClassifier.State();
617       }
618       if(dedans == 1) { 
619         Status = TopAbs_IN;
620       }
621       if(dedans == -1) {
622         Status = TopAbs_OUT;
623       }
624     } // if(TabOrien(1)!=-1) {
625     
626     else {  //-- TabOrien(1)=-1   Wrong Wire
627       BRepClass_FaceClassifier aClassifier;
628       aClassifier.Perform(Face,Puv,Toluv);
629       Status = aClassifier.State();
630     }
631     
632     if (!RecadreOnPeriodic || !IsUPer && !IsVPer)
633       return Status;
634     
635     if (Status == TopAbs_IN || Status == TopAbs_ON)
636       return Status;
637     
638     if (!urecadre){
639       u = uu;
640       urecadre = Standard_True;
641     }
642     else {
643       if (IsUPer){
644         u += uperiod;
645       }
646     }
647
648     if (u > Umax || !IsUPer) {
649       if (!vrecadre){
650         v = vv;
651         vrecadre = Standard_True;
652       }
653       else {
654         if (IsVPer){
655           v += vperiod;
656         }
657       }
658
659       u = uu;
660       
661       if (v > Vmax || !IsVPer) {
662         return Status;
663       }
664     }
665   } //while (1)
666 }
667
668 //=======================================================================
669 //function : TestOnRestriction
670 //purpose  : 
671 //=======================================================================
672   TopAbs_State IntTools_FClass2d::TestOnRestriction(const gp_Pnt2d& _Puv,
673                                                     const Standard_Real Tol,
674                                                     const Standard_Boolean RecadreOnPeriodic) const
675
676   Standard_Integer nbtabclass = TabClass.Length();
677   if (nbtabclass == 0)
678   {
679     return TopAbs_IN;
680   }
681
682   //-- U1 is the First Param and U2 in this case is U1+Period
683   Standard_Real u=_Puv.X();
684   Standard_Real v=_Puv.Y();
685   Standard_Real uu = u, vv = v;
686
687   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
688   surf->ChangeSurface().Initialize( Face, Standard_False );
689   const Standard_Boolean IsUPer  = surf->IsUPeriodic();
690   const Standard_Boolean IsVPer  = surf->IsVPeriodic();
691   const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
692   const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
693   TopAbs_State Status = TopAbs_UNKNOWN;
694   Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
695   Standard_Integer dedans = 1;
696
697   if (RecadreOnPeriodic)
698     {
699       if (IsUPer)
700         {
701           if (uu < Umin)
702             while (uu < Umin)
703               uu += uperiod;
704           else
705             {
706               while (uu >= Umin)
707                 uu -= uperiod;
708               uu += uperiod;
709             }
710         }
711       if (IsVPer)
712         {
713           if (vv < Vmin)
714             while (vv < Vmin)
715               vv += vperiod;
716           else
717             {
718               while (vv >= Vmin)
719                 vv -= vperiod;
720               vv += vperiod;
721             }
722         }
723     }
724   
725   for (;;) {
726     dedans = 1;
727     gp_Pnt2d Puv(u,v);
728     
729     if(TabOrien(1)!=-1) { 
730       for(Standard_Integer n=1; n<=nbtabclass; n++) { 
731         Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans_OnMode(Puv,Tol);
732         if(cur==1) { 
733           if(TabOrien(n)==0) { 
734             dedans = -1; 
735             break;
736           }
737         }
738         else if(cur==-1) { 
739           if(TabOrien(n)==1) {  
740             dedans = -1; 
741             break;
742           }
743         }
744         else { 
745           dedans = 0;
746           break;
747         }
748       }
749       if(dedans==0) {
750         Status = TopAbs_ON;
751       }
752       if(dedans == 1) {
753         Status = TopAbs_IN;
754       }
755       if(dedans == -1) {
756         Status = TopAbs_OUT;
757       }
758     }
759     else {  //-- TabOrien(1)=-1  Wrong  Wire 
760       BRepClass_FaceClassifier aClassifier;
761       aClassifier.Perform(Face,Puv,Tol);
762       Status = aClassifier.State();
763     }
764     
765     if (!RecadreOnPeriodic || !IsUPer && !IsVPer)
766       return Status;
767     if (Status == TopAbs_IN || Status == TopAbs_ON)
768       return Status;
769     
770     if (!urecadre)
771       {
772         u = uu;
773         urecadre = Standard_True;
774       }
775     else
776       if (IsUPer)
777         u += uperiod;
778     if (u > Umax || !IsUPer)
779       {
780         if (!vrecadre)
781           {
782             v = vv;
783             vrecadre = Standard_True;
784           }
785         else
786           if (IsVPer)
787             v += vperiod;
788         
789         u = uu;
790         
791         if (v > Vmax || !IsVPer)
792           return Status;
793       }
794   } //for (;;)
795 }
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