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