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