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