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