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