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