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