0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / BRepTopAdaptor / BRepTopAdaptor_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 #define AFFICHAGE 0
18
19 #define No_Standard_OutOfRange
20
21
22 #include <BRep_Tool.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <BRepAdaptor_Curve2d.hxx>
25 #include <BRepAdaptor_HSurface.hxx>
26 #include <BRepClass_FaceClassifier.hxx>
27 #include <BRepTools_WireExplorer.hxx>
28 #include <BRepTopAdaptor_FClass2d.hxx>
29 #include <CSLib_Class2d.hxx>
30 #include <ElCLib.hxx>
31 #include <Geom2dInt_Geom2dCurveTool.hxx>
32 #include <GeomAbs_SurfaceType.hxx>
33 #include <GCPnts_QuasiUniformDeflection.hxx>
34 #include <gp_Pnt.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <Precision.hxx>
37 #include <TColgp_Array1OfPnt2d.hxx>
38 #include <TColgp_SequenceOfPnt2d.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
46 #ifdef _MSC_VER
47 #include <stdio.h>
48 #endif
49
50
51 #ifdef OCCT_DEBUG
52 #define LBRCOMPT 0
53 #else
54 #define LBRCOMPT 0
55 #endif
56
57
58 #if LBRCOMPT  
59 class StatistiquesFClass2d { 
60 public:
61   long unsigned NbConstrShape;
62   long unsigned NbPerformInfinitePoint;
63   long unsigned NbPerform;
64   long unsigned NbTestOnRestriction;
65   long unsigned NbDestroy;
66 public:
67   StatistiquesFClass2d() { 
68     NbConstrShape=NbPerform=NbPerformInfinitePoint=NbDestroy=0;
69   }
70   ~StatistiquesFClass2d() { 
71     printf("\n--- Statistiques BRepTopAdaptor:\n");
72     printf("\nConstructeur(Shape) : %10lu",NbConstrShape);
73     printf("\nPerformInfinitePoint: %10lu",NbPerformInfinitePoint);
74     printf("\nTestOnRestriction   : %10lu",NbTestOnRestriction);
75     printf("\nPerform(pnt2d)      : %10lu",NbPerform);
76     printf("\nDestroy             : %10lu",NbDestroy);
77   }
78 };
79
80 static StatistiquesFClass2d STAT;
81 #endif
82
83
84
85
86 BRepTopAdaptor_FClass2d::BRepTopAdaptor_FClass2d(const TopoDS_Face& aFace,const Standard_Real TolUV) 
87 : Toluv(TolUV), Face(aFace)  { 
88   
89 #if LBRCOMPT 
90   STAT.NbConstrShape++;
91 #endif
92
93   //-- dead end on surfaces defined on more than one period
94
95   Face.Orientation(TopAbs_FORWARD);
96   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
97   surf->ChangeSurface().Initialize(aFace,Standard_False);
98   
99   TopoDS_Edge  edge;
100   TopAbs_Orientation Or;
101   Standard_Real u,du,Tole = 0.0,Tol=0.0;
102   BRepTools_WireExplorer WireExplorer;
103   TopExp_Explorer FaceExplorer;
104
105   Umin = Vmin = 0.0; //RealLast();
106   Umax = Vmax = -Umin;
107
108   Standard_Integer aNbE = 0;
109   Standard_Real eps = 1.e-10;
110   Standard_Integer BadWire=0;
111   for( FaceExplorer.Init(Face,TopAbs_WIRE); (FaceExplorer.More() && BadWire==0); FaceExplorer.Next() )
112     {
113       Standard_Integer nbpnts = 0;
114       TColgp_SequenceOfPnt2d SeqPnt2d;
115       Standard_Integer firstpoint = 1;
116       Standard_Real FlecheU = 0.0;
117       Standard_Real FlecheV = 0.0;
118       Standard_Boolean WireIsNotEmpty = Standard_False;
119       Standard_Integer NbEdges = 0;
120
121       TopExp_Explorer Explorer;
122       for( Explorer.Init(FaceExplorer.Current(),TopAbs_EDGE); Explorer.More(); Explorer.Next() ) NbEdges++;
123       aNbE = NbEdges;
124         
125       gp_Pnt Ancienpnt3d(0,0,0);
126       Standard_Boolean Ancienpnt3dinitialise = Standard_False;
127
128       for( WireExplorer.Init(TopoDS::Wire(FaceExplorer.Current()),Face); WireExplorer.More(); WireExplorer.Next() )
129         {
130           
131           NbEdges--;
132           edge = WireExplorer.Current();
133           Or = edge.Orientation();
134           if(Or == TopAbs_FORWARD || Or == TopAbs_REVERSED)
135             {
136               Standard_Real pfbid,plbid;
137               if(BRep_Tool::CurveOnSurface(edge,Face,pfbid,plbid).IsNull()) return;
138               BRepAdaptor_Curve2d C(edge,Face);
139         
140               //-- ----------------------------------------
141               Standard_Boolean degenerated=Standard_False;
142               if(BRep_Tool::Degenerated(edge))   degenerated=Standard_True;
143               if(BRep_Tool::IsClosed(edge,Face)) degenerated=Standard_True;
144               TopoDS_Vertex Va,Vb;
145               TopExp::Vertices(edge,Va,Vb);
146               Standard_Real TolVertex1=0.,TolVertex=0.;
147               if (Va.IsNull()) degenerated=Standard_True;
148               else TolVertex1=BRep_Tool::Tolerance(Va);
149               if (Vb.IsNull()) degenerated=Standard_True;
150               else TolVertex=BRep_Tool::Tolerance(Vb);
151               if(TolVertex<TolVertex1) TolVertex=TolVertex1;
152               BRepAdaptor_Curve C3d;
153         
154               if(Abs(plbid-pfbid) < 1.e-9) continue;
155
156               //if(degenerated==Standard_False)
157               //  C3d.Initialize(edge,Face);
158
159               //-- Check cases when it was forgotten to code degenerated :  PRO17410 (janv 99)
160               if(degenerated == Standard_False)
161                 {
162                   C3d.Initialize(edge,Face);
163                   du=(plbid-pfbid)*0.1;
164                   u=pfbid+du;
165                   gp_Pnt P3da=C3d.Value(u);
166                   degenerated=Standard_True;
167                   u+=du;
168                   do
169                     {
170                       
171                       gp_Pnt P3db=C3d.Value(u);
172                       //                      if(P3da.SquareDistance(P3db)) { degenerated=Standard_False; break; }
173                       if(P3da.SquareDistance(P3db) > Precision::Confusion()) { degenerated=Standard_False; break; }
174                       u+=du;
175                     }
176                   while(u<plbid);
177                 }
178               
179               //-- ----------------------------------------
180
181               Tole = BRep_Tool::Tolerance(edge);
182               if(Tole>Tol) Tol=Tole;
183               
184               //Standard_Integer nbs = 1 + Geom2dInt_Geom2dCurveTool::NbSamples(C);
185               Standard_Integer nbs = Geom2dInt_Geom2dCurveTool::NbSamples(C);
186               //-- Attention to rational bsplines of degree 3. (ends of circles among others)
187               if (nbs > 2) nbs*=4;
188               du = (plbid-pfbid)/(Standard_Real)(nbs-1);
189
190               if(Or==TopAbs_FORWARD) u = pfbid;
191               else { u = plbid; du=-du; }
192         
193               //-- ------------------------------------------------------------
194               //-- Check distance uv between the start point of the edge
195               //-- and the last point registered in SeqPnt2d
196               //-- Try to remote the first point of the current edge 
197               //-- from the last saved point
198 #ifdef OCCT_DEBUG
199               gp_Pnt2d Pnt2dDebutEdgeCourant = C.Value(u); (void)Pnt2dDebutEdgeCourant;
200 #endif
201
202               //Standard_Real Baillement2dU=0;
203               //Standard_Real Baillement2dV=0;
204 #if AFFICHAGE
205               if(nbpnts>1) printf("\nTolVertex %g ",TolVertex);
206 #endif
207
208               if(firstpoint==2) u+=du;
209               Standard_Integer Avant = nbpnts;
210               for(Standard_Integer e = firstpoint; e<=nbs; e++)
211                 {
212                   gp_Pnt2d P2d = C.Value(u);
213                   if(P2d.X()<Umin) Umin = P2d.X();
214                   if(P2d.X()>Umax) Umax = P2d.X();
215                   if(P2d.Y()<Vmin) Vmin = P2d.Y();
216                   if(P2d.Y()>Vmax) Vmax = P2d.Y();
217           
218                   Standard_Real dist3dptcourant_ancienpnt=1e+20;//RealLast();
219                   gp_Pnt P3d;
220                   if(degenerated==Standard_False)
221                     {
222                       P3d=C3d.Value(u);
223                       if(nbpnts>1 && Ancienpnt3dinitialise) dist3dptcourant_ancienpnt = P3d.Distance(Ancienpnt3d);
224                     }
225                   Standard_Boolean IsRealCurve3d = Standard_True; //patch
226                   if(dist3dptcourant_ancienpnt < Precision::Confusion())
227                     {
228                       gp_Pnt MidP3d = C3d.Value( u-du/2. );
229                       if (P3d.Distance( MidP3d ) < Precision::Confusion()) IsRealCurve3d = Standard_False;
230                     }
231                   if(IsRealCurve3d)
232                     {
233                       if(degenerated==Standard_False) { Ancienpnt3d=P3d;  Ancienpnt3dinitialise=Standard_True; }
234                       nbpnts++;
235                       SeqPnt2d.Append(P2d);
236                     }
237 #if AFFICHAGE
238                   else { static int mm=0; printf("\npoint p%d  %g %g %g",++mm,P3d.X(),P3d.Y(),P3d.Z()); }
239 #endif
240                   u+=du;
241                   Standard_Integer ii = nbpnts;
242                   //-- printf("\n nbpnts:%4d  u=%7.5g   FlecheU=%7.5g  FlecheV=%7.5g  ii=%3d  Avant=%3d ",nbpnts,u,FlecheU,FlecheV,ii,Avant);
243 //                if(ii>(Avant+4))
244 //  Modified by Sergey KHROMOV - Fri Apr 19 09:46:12 2002 Begin
245                   if(ii>(Avant+4) && SeqPnt2d(ii-2).SquareDistance(SeqPnt2d(ii)))
246 //  Modified by Sergey KHROMOV - Fri Apr 19 09:46:13 2002 End
247                     {
248                       gp_Lin2d Lin(SeqPnt2d(ii-2),gp_Dir2d(gp_Vec2d(SeqPnt2d(ii-2),SeqPnt2d(ii))));
249                       Standard_Real ul = ElCLib::Parameter(Lin,SeqPnt2d(ii-1));
250                       gp_Pnt2d Pp = ElCLib::Value(ul,Lin);
251                       Standard_Real dU = Abs(Pp.X()-SeqPnt2d(ii-1).X());
252                       Standard_Real dV = Abs(Pp.Y()-SeqPnt2d(ii-1).Y());
253                       //-- printf(" (du=%7.5g   dv=%7.5g)",dU,dV);
254                       if(dU>FlecheU) FlecheU = dU;
255                       if(dV>FlecheV) FlecheV = dV;
256                     }
257                 }//for(e=firstpoint
258               if(firstpoint==1) firstpoint=2;
259               WireIsNotEmpty = Standard_True;
260             }//if(Or==FORWARD,REVERSED
261         } //-- Edges -> for(Ware.Explorer
262
263       if(NbEdges)
264         { //-- on compte ++ with a normal explorer and with the Wire Explorer
265 /*
266 #ifdef OCCT_DEBUG
267
268           std::cout << std::endl;
269           std::cout << "*** BRepTopAdaptor_Fclass2d  ** Wire Probablement FAUX **" << std::endl;
270           std::cout << "*** WireExplorer does not find all edges " << std::endl;
271           std::cout << "*** Connect old classifier" << std::endl;
272 #endif
273 */
274           TColgp_Array1OfPnt2d PClass(1,2);
275           //// modified by jgv, 28.04.2009 ////
276           PClass.Init(gp_Pnt2d(0.,0.));
277           /////////////////////////////////////
278           TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
279           BadWire=1;
280           TabOrien.Append(-1);
281         }
282       else if(WireIsNotEmpty)
283         {
284           //Standard_Real anglep=0,anglem=0;
285           TColgp_Array1OfPnt2d PClass(1,nbpnts);
286           Standard_Real square = 0.0;
287
288           //-------------------------------------------------------------------
289           //-- ** The mode of calculation was somewhat changed 
290           //-- Before Oct 31 97 , the total angle of  
291           //-- rotation of the wire was evaluated on all angles except for the last 
292           //-- ** Now, exactly the angle of rotation is evaluated
293           //-- If a value remote from 2PI or -2PI is found, it means that there is 
294           //-- an uneven number of loops
295
296           if(nbpnts>3)
297             {
298 //            Standard_Integer im2=nbpnts-2;
299               Standard_Integer im1=nbpnts-1;
300               Standard_Integer im0=1;
301 //            PClass(im2)=SeqPnt2d.Value(im2);
302               PClass(im1)=SeqPnt2d.Value(im1);
303               PClass(nbpnts)=SeqPnt2d.Value(nbpnts);
304
305               Standard_Real aPer = 0.;
306 //            for(Standard_Integer ii=1; ii<nbpnts; ii++,im0++,im1++,im2++)
307               for(Standard_Integer ii=1; ii<nbpnts; ii++,im0++,im1++)
308                 { 
309 //                if(im2>=nbpnts) im2=1;
310                   if(im1>=nbpnts) im1=1;
311                   PClass(ii)=SeqPnt2d.Value(ii);
312 //                gp_Vec2d A(PClass(im2),PClass(im1));
313 //                gp_Vec2d B(PClass(im1),PClass(im0));
314 //                Standard_Real N = A.Magnitude() * B.Magnitude();
315
316                   square += (PClass(im0).X()-PClass(im1).X())*(PClass(im0).Y()+PClass(im1).Y())*.5; 
317                   aPer += (PClass(im0).XY() - PClass(im1).XY()).Modulus();
318
319 //                if(N>1e-16){ Standard_Real a=A.Angle(B); angle+=a; }
320                 }
321
322               Standard_Real anExpThick = Max(2. * Abs(square) / aPer, 1e-7);
323               Standard_Real aDefl = Max(FlecheU, FlecheV);
324               Standard_Real aDiscrDefl = Min(aDefl*0.1, anExpThick * 10.);
325               while (aDefl > anExpThick && aDiscrDefl > 1e-7)
326               {
327                 // Deflection of the polygon is too much for this ratio of area and perimeter,
328                 // and this might lead to self-intersections.
329                 // Discretize the wire more tightly to eliminate the error.
330                 firstpoint = 1;
331                 SeqPnt2d.Clear();
332                 FlecheU = 0.0;
333                 FlecheV = 0.0;
334                 for (WireExplorer.Init(TopoDS::Wire(FaceExplorer.Current()), Face);
335                   WireExplorer.More(); WireExplorer.Next())
336                 {
337                   edge = WireExplorer.Current();
338                   Or = edge.Orientation();
339                   if (Or == TopAbs_FORWARD || Or == TopAbs_REVERSED)
340                   {
341                     Standard_Real pfbid, plbid;
342                     BRep_Tool::Range(edge, Face, pfbid, plbid);
343                     if (Abs(plbid - pfbid) < 1.e-9) continue;
344                     BRepAdaptor_Curve2d C(edge, Face);
345                     GCPnts_QuasiUniformDeflection aDiscr(C, aDiscrDefl);
346                     if (!aDiscr.IsDone())
347                       break;
348                     Standard_Integer nbp = aDiscr.NbPoints();
349                     Standard_Integer iStep = 1, i = 1, iEnd = nbp + 1;
350                     if (Or == TopAbs_REVERSED)
351                     {
352                       iStep = -1;
353                       i = nbp;
354                       iEnd = 0;
355                     }
356                     if (firstpoint == 2)
357                       i += iStep;
358                     for (; i != iEnd; i += iStep)
359                     {
360                       gp_Pnt2d aP2d = C.Value(aDiscr.Parameter(i));
361                       SeqPnt2d.Append(aP2d);
362                     }
363                     if (nbp > 2)
364                     {
365                       Standard_Integer ii = SeqPnt2d.Length();
366                       gp_Lin2d Lin(SeqPnt2d(ii - 2), gp_Dir2d(gp_Vec2d(SeqPnt2d(ii - 2), SeqPnt2d(ii))));
367                       Standard_Real ul = ElCLib::Parameter(Lin, SeqPnt2d(ii - 1));
368                       gp_Pnt2d Pp = ElCLib::Value(ul, Lin);
369                       Standard_Real dU = Abs(Pp.X() - SeqPnt2d(ii - 1).X());
370                       Standard_Real dV = Abs(Pp.Y() - SeqPnt2d(ii - 1).Y());
371                       if (dU > FlecheU) FlecheU = dU;
372                       if (dV > FlecheV) FlecheV = dV;
373                     }
374                     firstpoint = 2;
375                   }
376                 }
377                 nbpnts = SeqPnt2d.Length();
378                 PClass.Resize(1, nbpnts, Standard_False);
379                 im1 = nbpnts - 1;
380                 im0 = 1;
381                 PClass(im1) = SeqPnt2d.Value(im1);
382                 PClass(nbpnts) = SeqPnt2d.Value(nbpnts);
383                 square = 0.;
384                 aPer = 0.;
385                 for (Standard_Integer ii = 1; ii<nbpnts; ii++, im0++, im1++)
386                 {
387                   if (im1 >= nbpnts) im1 = 1;
388                   PClass(ii) = SeqPnt2d.Value(ii);
389                   square += (PClass(im0).X() - PClass(im1).X())*(PClass(im0).Y() + PClass(im1).Y())*.5;
390                   aPer += (PClass(im0).XY() - PClass(im1).XY()).Modulus();
391                 }
392
393                 anExpThick = Max(2. * Abs(square) / aPer, 1e-7);
394                 aDefl = Max(FlecheU, FlecheV);
395                 aDiscrDefl = Min(aDiscrDefl * 0.1, anExpThick * 10.);
396               }
397       
398               //-- FlecheU*=10.0;
399               //-- FlecheV*=10.0;
400               if (aNbE == 1 && FlecheU < eps && FlecheV < eps && Abs(square) < eps)
401               {
402                 TabOrien.Append(1);
403               }
404               else
405               { 
406                 TabOrien.Append(((square < 0.0)? 1 : 0));
407               }
408               
409               if(FlecheU<Toluv) FlecheU = Toluv;
410               if(FlecheV<Toluv) FlecheV = Toluv;
411               //-- std::cout<<" U:"<<FlecheU<<" V:"<<FlecheV<<std::endl;
412               TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
413
414 //            if((angle<2 && angle>-2)||(angle>10)||(angle<-10))
415 //              {
416 //                BadWire=1;
417 //                TabOrien.Append(-1);
418 //#ifdef OCCT_DEBUG
419 //                std::cout << std::endl;
420 //                std::cout << "*** BRepTopAdaptor_Fclass2d  ** Wire Probably FALSE **" << std::endl;
421 //                std::cout << "*** Total rotation angle of the wire : " << angle << std::endl;
422 //                std::cout << "*** Connect the old classifier" << std::endl;
423 //#endif
424 //              } 
425 //            else TabOrien.Append(((angle>0.0)? 1 : 0));
426             }//if(nbpoints>3
427           else
428             { 
429 #ifdef OCCT_DEBUG
430               std::cout << std::endl;
431               std::cout << "*** BRepTopAdaptor_Fclass2d  ** Wire Probably FALSE **" << std::endl;
432               std::cout << "*** The sample wire contains less than 3 points" << std::endl;
433               std::cout << "*** Connect the old classifier" << std::endl;
434 #endif       
435               BadWire=1;
436               TabOrien.Append(-1);
437               TColgp_Array1OfPnt2d xPClass(1,2);
438               xPClass(1) = SeqPnt2d(1); 
439               xPClass(2) = SeqPnt2d(2);
440               TabClass.Append((void *)new CSLib_Class2d(xPClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
441             }
442         }//else if(WareIsNotEmpty
443   }//for(FaceExplorer
444
445   Standard_Integer nbtabclass = TabClass.Length();
446
447   if(nbtabclass>0)
448     {
449       //-- If an error was detected on a wire: set all TabOrien to -1
450       if(BadWire) TabOrien(1)=-1;
451
452       if(   surf->GetType()==GeomAbs_Cone
453          || surf->GetType()==GeomAbs_Cylinder
454          || surf->GetType()==GeomAbs_Torus
455          || surf->GetType()==GeomAbs_Sphere
456          || surf->GetType()==GeomAbs_SurfaceOfRevolution)
457         
458         {
459           Standard_Real uuu=M_PI+M_PI-(Umax-Umin);
460           if(uuu<0) uuu=0;
461           U1 = 0.0;  // modified by NIZHNY-OFV  Thu May 31 14:24:10 2001 ---> //Umin-uuu*0.5;
462           U2 = 2*M_PI; // modified by NIZHNY-OFV  Thu May 31 14:24:35 2001 ---> //U1+M_PI+M_PI;
463         }
464       else { U1=U2=0.0; } 
465     
466       if(surf->GetType()==GeomAbs_Torus)
467         { 
468           Standard_Real uuu=M_PI+M_PI-(Vmax-Vmin);
469           if(uuu<0) uuu=0;
470           V1 = 0.0;  // modified by NIZHNY-OFV  Thu May 31 14:24:55 2001 ---> //Vmin-uuu*0.5;
471           V2 = 2*M_PI; // modified by NIZHNY-OFV  Thu May 31 14:24:59 2001 ---> //V1+M_PI+M_PI;
472         }
473       else { V1=V2=0.0; }   
474     }
475 }
476
477 TopAbs_State BRepTopAdaptor_FClass2d::PerformInfinitePoint() const { 
478 #if LBRCOMPT 
479   STAT.NbPerformInfinitePoint++;
480 #endif
481   
482   if(Umax==-RealLast() || Vmax==-RealLast() || Umin==RealLast() || Vmin==RealLast()) { 
483     return(TopAbs_IN);
484   }
485   gp_Pnt2d P(Umin-(Umax-Umin),Vmin-(Vmax-Vmin));
486   return(Perform(P,Standard_False));
487 }
488
489 TopAbs_State BRepTopAdaptor_FClass2d::Perform(const gp_Pnt2d& _Puv,
490                                               const Standard_Boolean RecadreOnPeriodic) const
491
492 #if LBRCOMPT 
493   STAT.NbPerform++;
494 #endif
495   
496   Standard_Integer dedans;
497   Standard_Integer nbtabclass = TabClass.Length();
498   
499   if(nbtabclass==0) { 
500     return(TopAbs_IN);
501   }
502   
503   //-- U1 is the First Param and U2 in this case is U1+Period
504   Standard_Real u=_Puv.X();
505   Standard_Real v=_Puv.Y();
506   Standard_Real uu = u, vv = v;
507
508   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
509   surf->ChangeSurface().Initialize( Face, Standard_False );
510   const Standard_Boolean IsUPer  = surf->IsUPeriodic();
511   const Standard_Boolean IsVPer  = surf->IsVPeriodic();
512   const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
513   const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
514   TopAbs_State aStatus = TopAbs_UNKNOWN;
515   Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
516
517   if (RecadreOnPeriodic)
518     {
519       if (IsUPer)
520         {
521           if (uu < Umin)
522             while (uu < Umin)
523               uu += uperiod;
524           else
525             {
526               while (uu >= Umin)
527                 uu -= uperiod;
528               uu += uperiod;
529             }
530         }
531       if (IsVPer)
532         {
533           if (vv < Vmin)
534             while (vv < Vmin)
535               vv += vperiod;
536           else
537             {
538               while (vv >= Vmin)
539                 vv -= vperiod;
540               vv += vperiod;
541             }
542         }
543     }
544
545   for (;;)
546     {
547       dedans = 1;
548       gp_Pnt2d Puv(u,v);
549       
550       if(TabOrien(1)!=-1) { 
551         for(Standard_Integer n=1; n<=nbtabclass; n++) { 
552           Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv);
553           if(cur==1) { 
554             if(TabOrien(n)==0) { 
555               dedans = -1; 
556               break;
557             }
558           }
559           else if(cur==-1) { 
560             if(TabOrien(n)==1) {  
561               dedans = -1; 
562               break;
563             }
564           }
565           else { 
566             dedans = 0;
567             break;
568           }
569         }
570         if(dedans==0) { 
571           BRepClass_FaceClassifier aClassifier;
572           Standard_Real m_Toluv = (Toluv > 4.0) ? 4.0 : Toluv;
573           //aClassifier.Perform(Face,Puv,Toluv);
574           aClassifier.Perform(Face,Puv,m_Toluv);
575           aStatus = aClassifier.State();
576         }
577         if(dedans == 1) { 
578           aStatus = TopAbs_IN;
579         }
580         if(dedans == -1) {
581           aStatus = TopAbs_OUT;
582         }
583       }
584       else {  //-- TabOrien(1)=-1    False Wire
585         BRepClass_FaceClassifier aClassifier;
586         aClassifier.Perform(Face,Puv,Toluv);
587         aStatus = aClassifier.State();
588       }
589
590       if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
591         return aStatus;
592       if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
593         return aStatus;
594
595       if (!urecadre)
596         {
597           u = uu;
598           urecadre = Standard_True;
599         }
600       else
601         if (IsUPer)
602           u += uperiod;
603       if (u > Umax || !IsUPer)
604         {
605           if (!vrecadre)
606             {
607               v = vv;
608               vrecadre = Standard_True;
609             }
610           else
611             if (IsVPer)
612               v += vperiod;
613
614           u = uu;
615
616           if (v > Vmax || !IsVPer)
617             return aStatus;
618         }
619     } //for (;;)
620 }
621
622 TopAbs_State BRepTopAdaptor_FClass2d::TestOnRestriction(const gp_Pnt2d& _Puv,
623                                                         const Standard_Real Tol,
624                                                         const Standard_Boolean RecadreOnPeriodic) const
625
626 #if LBRCOMPT 
627   STAT.NbConstrShape++;
628 #endif
629   
630   Standard_Integer dedans;
631   Standard_Integer nbtabclass = TabClass.Length();
632   
633   if(nbtabclass==0) { 
634     return(TopAbs_IN);
635   }
636   
637   //-- U1 is the First Param and U2 in this case is U1+Period
638   Standard_Real u=_Puv.X();
639   Standard_Real v=_Puv.Y();
640   Standard_Real uu = u, vv = v;
641   
642   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
643   surf->ChangeSurface().Initialize( Face, Standard_False );
644   const Standard_Boolean IsUPer  = surf->IsUPeriodic();
645   const Standard_Boolean IsVPer  = surf->IsVPeriodic();
646   const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
647   const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
648   TopAbs_State aStatus = TopAbs_UNKNOWN;
649   Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
650   
651   if (RecadreOnPeriodic)
652     {
653       if (IsUPer)
654         {
655           if (uu < Umin)
656             while (uu < Umin)
657               uu += uperiod;
658           else
659             {
660               while (uu >= Umin)
661                 uu -= uperiod;
662               uu += uperiod;
663             }
664         }
665       if (IsVPer)
666         {
667           if (vv < Vmin)
668             while (vv < Vmin)
669               vv += vperiod;
670           else
671             {
672               while (vv >= Vmin)
673                 vv -= vperiod;
674               vv += vperiod;
675             }
676         }
677     }
678   
679   for (;;)
680     {
681       dedans = 1;
682       gp_Pnt2d Puv(u,v);
683       
684       if(TabOrien(1)!=-1) { 
685         for(Standard_Integer n=1; n<=nbtabclass; n++) { 
686           Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans_OnMode(Puv,Tol);
687           if(cur==1) { 
688             if(TabOrien(n)==0) { 
689               dedans = -1; 
690               break;
691             }
692           }
693           else if(cur==-1) { 
694             if(TabOrien(n)==1) {  
695               dedans = -1; 
696               break;
697             }
698           }
699           else { 
700             dedans = 0;
701             break;
702           }
703         }
704         if(dedans==0) {
705           aStatus = TopAbs_ON;
706         }
707         if(dedans == 1) {
708           aStatus = TopAbs_IN;
709         }
710         if(dedans == -1) {
711           aStatus = TopAbs_OUT;
712         }
713       }
714       else {  //-- TabOrien(1)=-1    False Wire
715         BRepClass_FaceClassifier aClassifier;
716         aClassifier.Perform(Face,Puv,Tol);
717         aStatus = aClassifier.State();
718       }
719       
720       if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
721         return aStatus;
722       if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
723         return aStatus;
724       
725       if (!urecadre)
726         {
727           u = uu;
728           urecadre = Standard_True;
729         }
730       else
731         if (IsUPer)
732           u += uperiod;
733       if (u > Umax || !IsUPer)
734         {
735           if (!vrecadre)
736             {
737               v = vv;
738               vrecadre = Standard_True;
739             }
740           else
741             if (IsVPer)
742               v += vperiod;
743           
744           u = uu;
745           
746           if (v > Vmax || !IsVPer)
747             return aStatus;
748         }
749     } //for (;;)
750 }
751
752
753 void BRepTopAdaptor_FClass2d::Destroy() { 
754 #if LBRCOMPT
755   STAT.NbDestroy++;
756 #endif
757   
758   Standard_Integer nbtabclass = TabClass.Length(); 
759   for(Standard_Integer d=1; d<=nbtabclass;d++) {
760     if(TabClass(d)) { 
761       delete ((CSLib_Class2d *)TabClass(d));
762       TabClass(d)=NULL;
763     }
764   }
765 }
766
767
768
769 #include <Standard_ConstructionError.hxx>
770
771
772 //const BRepTopAdaptor_FClass2d &  BRepTopAdaptor_FClass2d::Copy(const BRepTopAdaptor_FClass2d& Other) const { 
773 const BRepTopAdaptor_FClass2d &  BRepTopAdaptor_FClass2d::Copy(const BRepTopAdaptor_FClass2d& ) const { 
774 #ifdef OCCT_DEBUG
775   std::cerr<<"Copy not allowed in BRepTopAdaptor_FClass2d"<<std::endl;
776 #endif
777   throw Standard_ConstructionError();
778 }