1 // Created on: 1995-03-22
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <BRepAdaptor_Curve2d.hxx>
21 #include <BRepAdaptor_Surface.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 <GCPnts_QuasiUniformDeflection.hxx>
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>
39 #include <TopAbs_Orientation.hxx>
40 #include <TopExp.hxx>
41 #include <TopExp_Explorer.hxx>
42 #include <TopoDS.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Wire.hxx>
46 #include <GeomLib.hxx>
47 #include <Poly.hxx>
48
49 #include <stdio.h>
50
51 //#define DEBUG_PCLASS_POLYGON
52 #ifdef DEBUG_PCLASS_POLYGON
53 #include <DrawTrSurf.hxx>
54 #include <Geom2d_BSplineCurve.hxx>
55 #endif
56
57 //=======================================================================
58 //function : IntTools_FClass2d:IntTools:_FClass2d
59 //purpose :
60 //=======================================================================
IntTools_FClass2d()61 IntTools_FClass2d::IntTools_FClass2d()
62 {
63 }
64 //=======================================================================
65 //function : IntTools_FClass2d::IntTools_FClass2d
66 //purpose :
67 //=======================================================================
IntTools_FClass2d(const TopoDS_Face & aFace,const Standard_Real TolUV)68 IntTools_FClass2d::IntTools_FClass2d(const TopoDS_Face& aFace,
69 const Standard_Real TolUV)
70 : Toluv(TolUV), Face(aFace)
71 {
72 Init(Face, Toluv);
73 }
74 //=======================================================================
75 //function : IsHole
76 //purpose :
77 //=======================================================================
IsHole() const78 Standard_Boolean IntTools_FClass2d::IsHole() const
79 {
80 return myIsHole;
81 }
82 //=======================================================================
83 //function : Init
84 //purpose :
85 //=======================================================================
Init(const TopoDS_Face & aFace,const Standard_Real TolUV)86 void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
87 const Standard_Real TolUV)
88 {
89 Standard_Boolean WireIsNotEmpty, Ancienpnt3dinitialise, degenerated;
90 Standard_Integer firstpoint, NbEdges;
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);
116 Handle(BRepAdaptor_Surface) surf = new BRepAdaptor_Surface();
117 surf->Initialize(aFace, Standard_False);
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 //
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)) {
160 continue;
161 }
162 //
163 aC2D=BRep_Tool::CurveOnSurface(edge, Face, pfbid, plbid);
164 if (aC2D.IsNull()) {
165 return;
166 }
167 //
168 BRepAdaptor_Curve2d C(edge,Face);
169 BRepAdaptor_Curve C3d;
170 //------------------------------------------
171 degenerated=Standard_False;
172 if(BRep_Tool::Degenerated(edge) ||
173 BRep_Tool::IsClosed(edge, Face)) {
174 degenerated=Standard_True;
175 }
176 //
177 TopExp::Vertices(edge,Va,Vb);
178 //
179 TolVertex1=0.;
180 TolVertex=0.;
181 if (Va.IsNull()) {
182 degenerated=Standard_True;
183 }
184 else {
185 TolVertex1=BRep_Tool::Tolerance(Va);
186 }
187 if (Vb.IsNull()){
188 degenerated=Standard_True;
189 }
190 else {
191 TolVertex=BRep_Tool::Tolerance(Vb);
192 }
193 //
194 if(TolVertex<TolVertex1) {
195 TolVertex=TolVertex1;
196 }
197 //
198 //-- Verification of cases when forgotten to code degenereted
199 if(!degenerated) {
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 {
210 Standard_Real U = pfbid + i * du / NBSTEPS;
211 gp_Pnt P3db = C3d.Value (U);
212 Standard_Real aR2 = P3da.SquareDistance (P3db);
213 if (aR2 > aPrec2) {
214 degenerated = Standard_False;
215 break;
216 }
217 }
218 }//if(!degenerated)
219 //-- ----------------------------------------
220 Tole = BRep_Tool::Tolerance(edge);
221 if(Tole>Tol) {
222 Tol=Tole;
223 }
224 //
225 // NbSamples +> nbs
226 nbs = Geom2dInt_Geom2dCurveTool::NbSamples(C);
227 if (nbs > 2) {
228 nbs*=4;
229 }
230 du = (plbid-pfbid)/(Standard_Real)(nbs-1);
231 //
232 if(Or==TopAbs_FORWARD) {
233 u = pfbid;
234 uFirst=pfbid;
235 uLast=plbid;
236 }
237 else {
238 u = plbid;
239 uFirst=plbid;
240 uLast=pfbid;
241 du=-du;
242 }
243 //
244 // aPrms
245 aNbs1=nbs+1;
246 TColStd_Array1OfReal aPrms(1, aNbs1);
247 //
248 if (nbs==2) {
249 Standard_Real aCoef=0.0025;
250 aPrms(1)=uFirst;
251 aPrms(2)=uFirst+aCoef*(uLast-uFirst);
252 aPrms(3)=uLast;
253 }
254 else if (nbs>2) {
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;
261 }
262 //
263 //-- ------------------------------------------------------------
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
268 Avant = SeqPnt2d.Length();
269 for(iX=firstpoint; iX<=aNbs1; iX++) {
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);
286 if(!SeqPnt2d.IsEmpty()) {
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 }
312 SeqPnt2d.Append(P2d);
313 }
314 //
315 ii= SeqPnt2d.Length();
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 }
332 }// for(iX=firstpoint; iX<=aNbs1; iX++) {
333 //
334 if(BadWire) {
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
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)
350 aV.Reverse();
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)
359 aV.Reverse();
360
361 if (NbEdges > 0)
362 aD1Prev.Append(aV);
363 else
364 aD1Prev.Prepend(aV);
365
366 // Fill the map anIndexMap.
367 if (Avant > 0)
368 anIndexMap.Bind(Avant, aD1Next.Length());
369 else
370 anIndexMap.Bind(1, aD1Next.Length());
371 } //for(;aWExp.More(); aWExp.Next()) {
372 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
373 //
374 if(NbEdges) {
375 //-- count ++ with normal explorer and -- with Wire Explorer
376 TColgp_Array1OfPnt2d PClass(1,2);
377 gp_Pnt2d anInitPnt(0., 0.);
378 //
379 PClass.Init(anInitPnt);
380 TabClass.Append((void *)new CSLib_Class2d(PClass,
381 FlecheU,
382 FlecheV,
383 Umin,Vmin,Umax,Vmax));
384 BadWire=1;
385 TabOrien.Append(-1);
386 }
387 //
388 else if(WireIsNotEmpty) {
389 if (SeqPnt2d.Length() > 3)
390 {
391 #ifdef DEBUG_PCLASS_POLYGON
392 TColgp_Array1OfPnt2d PClass(1, nbpnts);
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;
399 PClass(ii) = SeqPnt2d.Value(ii);
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
406 Standard_Real aS = 0.;
407 Standard_Real aPer = 0.;
408 Poly::PolygonProperties(SeqPnt2d, aS, aPer);
409
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.);
413 Standard_Boolean isChanged = Standard_False;
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;
420 isChanged = Standard_True;
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 }
466 anExpThick = Max(2. * Abs(aS) / aPer, 1e-7);
467 aDefl = Max(FlecheU, FlecheV);
468 aDiscrDefl = Min(aDiscrDefl * 0.1, anExpThick * 10.);
469 }
470
471 if (isChanged)
472 {
473 Poly::PolygonProperties(SeqPnt2d, aS, aPer);
474 }
475 //
476 if(FlecheU<Toluv)
477 FlecheU = Toluv;
478
479 if(FlecheV<Toluv)
480 FlecheV = Toluv;
481
482 TabClass.Append((void *)new CSLib_Class2d(SeqPnt2d,
483 FlecheU,
484 FlecheV,
485 Umin,Vmin,Umax,Vmax));
486 //
487 if(Abs(aS) < Precision::SquareConfusion()) {
488 BadWire=1;
489 TabOrien.Append(-1);
490 }
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 }
503 }
504 }
505 else {
506 BadWire=1;
507 TabOrien.Append(-1);
508 TColgp_Array1OfPnt2d PPClass(1,2);
509 SeqPnt2d.Clear();
510 TabClass.Append((void *)new CSLib_Class2d(SeqPnt2d,
511 FlecheU,
512 FlecheV,
513 Umin,Vmin,Umax,Vmax));
514 }
515 }// else if(WireIsNotEmpty)
516 } // for(; aExpF.More(); aExpF.Next()) {
517 //
518 Standard_Integer nbtabclass = TabClass.Length();
519 //
520 if(nbtabclass>0) {
521 //-- if an error on a wire was detected : all TabOrien set to -1
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) {
531 Standard_Real uuu=M_PI+M_PI-(Umax-Umin);
532 if(uuu<0) uuu=0;
533 U1 = Umin-uuu*0.5;
534 U2 = U1+M_PI+M_PI;
535 }
536 else {
537 U1=U2=0.0;
538 }
539
540 if(surf->GetType()==GeomAbs_Torus) {
541 Standard_Real uuu=M_PI+M_PI-(Vmax-Vmin);
542 if(uuu<0) uuu=0;
543
544 V1 = Vmin-uuu*0.5;
545 V2 = V1+M_PI+M_PI;
546 }
547 else {
548 V1=V2=0.0;
549 }
550 }
551 }
552 //=======================================================================
553 //function : PerformInfinitePoint
554 //purpose :
555 //=======================================================================
PerformInfinitePoint() const556 TopAbs_State IntTools_FClass2d::PerformInfinitePoint() const
557 {
558 if(Umax==-RealLast() || Vmax==-RealLast() ||
559 Umin==RealLast() || Vmin==RealLast()) {
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 //=======================================================================
Perform(const gp_Pnt2d & _Puv,const Standard_Boolean RecadreOnPeriodic) const569 TopAbs_State IntTools_FClass2d::Perform
570 (const gp_Pnt2d& _Puv,
571 const Standard_Boolean RecadreOnPeriodic) const
572 {
573 Standard_Integer nbtabclass = TabClass.Length();
574 if (nbtabclass == 0)
575 {
576 return TopAbs_IN;
577 }
578
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;
584 TopAbs_State aStatus = TopAbs_UNKNOWN;
585
586 Handle(BRepAdaptor_Surface) surf = new BRepAdaptor_Surface();
587 surf->Initialize( Face, Standard_False );
588
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;
593
594 Standard_Boolean urecadre, vrecadre, bUseClassifier;
595 Standard_Integer dedans = 1;
596 //
597 urecadre = Standard_False;
598 vrecadre = Standard_False;
599 //
600 if (RecadreOnPeriodic) {
601 Standard_Real du, dv;
602 if (IsUPer) {
603 GeomInt::AdjustPeriodic(uu, Umin, Umax, uperiod, uu, du);
604 }// if (IsUPer) {
605 //
606 if (IsVPer) {
607 GeomInt::AdjustPeriodic(vv, Vmin, Vmax, vperiod, vv, dv);
608 }//if (IsVPer) {
609 }
610 //
611 for(;;) {
612 dedans = 1;
613 gp_Pnt2d Puv(u,v);
614 bUseClassifier = (TabOrien(1) == -1);
615 if(!bUseClassifier) {
616 Standard_Integer n, cur, TabOrien_n ;
617 for(n=1; n<=nbtabclass; n++) {
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 }
637 } // for(n=1; n<=nbtabclass; n++)
638
639 if(dedans==0) {
640 bUseClassifier = Standard_True;
641 }
642 else {
643 aStatus = (dedans == 1) ? TopAbs_IN : TopAbs_OUT;
644 }
645 } // if(TabOrien(1)!=-1) {
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 //
658 if (bUIn==bVIn) {
659 aFCTol = Min(aURes, aVRes);
660 }
661 else {
662 aFCTol = (!bUIn) ? aURes : aVRes;
663 }
664 //
665
666 if (myFExplorer.get() == NULL)
667 myFExplorer.reset (new BRepClass_FaceExplorer (Face));
668
669 BRepClass_FClassifier aClassifier;
670 aClassifier.Perform(*myFExplorer, Puv, aFCTol);
671 aStatus = aClassifier.State();
672 }
673
674 if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
675 return aStatus;
676
677 if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
678 return aStatus;
679
680 if (!urecadre){
681 u = uu;
682 urecadre = Standard_True;
683 }
684 else {
685 if (IsUPer){
686 u += uperiod;
687 }
688 }
689
690 if (u > Umax || !IsUPer) {
691 if (!vrecadre){
692 v = vv;
693 vrecadre = Standard_True;
694 }
695 else {
696 if (IsVPer){
697 v += vperiod;
698 }
699 }
700
701 u = uu;
702
703 if (v > Vmax || !IsVPer) {
704 return aStatus;
705 }
706 }
707 } //while (1)
708 }
709
710 //=======================================================================
711 //function : TestOnRestriction
712 //purpose :
713 //=======================================================================
TestOnRestriction(const gp_Pnt2d & _Puv,const Standard_Real Tol,const Standard_Boolean RecadreOnPeriodic) const714 TopAbs_State IntTools_FClass2d::TestOnRestriction
715 (const gp_Pnt2d& _Puv,
716 const Standard_Real Tol,
717 const Standard_Boolean RecadreOnPeriodic) const
718 {
719 Standard_Integer nbtabclass = TabClass.Length();
720 if (nbtabclass == 0)
721 {
722 return TopAbs_IN;
723 }
724
725 //-- U1 is the First Param and U2 in this case is U1+Period
726 Standard_Real u=_Puv.X();
727 Standard_Real v=_Puv.Y();
728 Standard_Real uu = u, vv = v;
729
730 Handle(BRepAdaptor_Surface) surf = new BRepAdaptor_Surface();
731 surf->Initialize( Face, Standard_False );
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;
736 TopAbs_State aStatus = TopAbs_UNKNOWN;
737 Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
738 Standard_Integer dedans = 1;
739
740 if (RecadreOnPeriodic) {
741 Standard_Real du, dv;
742 if (IsUPer) {
743 GeomInt::AdjustPeriodic(uu, Umin, Umax, uperiod, uu, du);
744 }// if (IsUPer) {
745 //
746 if (IsVPer) {
747 GeomInt::AdjustPeriodic(vv, Vmin, Vmax, vperiod, vv, dv);
748 }//if (IsVPer) {
749 }
750 //
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++) {
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 }
774 }
775 if(dedans==0) {
776 aStatus = TopAbs_ON;
777 }
778 if(dedans == 1) {
779 aStatus = TopAbs_IN;
780 }
781 if(dedans == -1) {
782 aStatus = TopAbs_OUT;
783 }
784 }
785 else { //-- TabOrien(1)=-1 Wrong Wire
786
787 if (myFExplorer.get() == NULL)
788 myFExplorer.reset (new BRepClass_FaceExplorer (Face));
789
790 BRepClass_FClassifier aClassifier;
791 aClassifier.Perform(*myFExplorer, Puv, Tol);
792 aStatus = aClassifier.State();
793 }
794
795 if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
796 return aStatus;
797 if (aStatus == TopAbs_IN || aStatus == TopAbs_ON)
798 return aStatus;
799
800 if (!urecadre)
801 {
802 u = uu;
803 urecadre = Standard_True;
804 }
805 else
806 if (IsUPer)
807 u += uperiod;
808 if (u > Umax || !IsUPer)
809 {
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)
822 return aStatus;
823 }
824 } //for (;;)
825 }
826 //=======================================================================
827 //function : Destroy
828 //purpose :
829 //=======================================================================
Destroy()830 void IntTools_FClass2d::Destroy()
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
842