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