0026738: Make Boolean operations safely treating arguments when running with fuzzy...
[occt.git] / src / IntTools / IntTools_EdgeFace.cxx
CommitLineData
b311480e 1// Created on: 2001-02-26
2// Created by: Peter KURNEV
973c2be1 3// Copyright (c) 2001-2014 OPEN CASCADE SAS
7fd59977 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
7fd59977 16
17#include <Bnd_Box.hxx>
18#include <BndLib_AddSurface.hxx>
42cf5bc1 19#include <BRep_Tool.hxx>
20#include <BRepAdaptor_Surface.hxx>
7fd59977 21#include <Extrema_ExtCS.hxx>
22#include <Extrema_POnCurv.hxx>
23#include <Extrema_POnSurf.hxx>
42cf5bc1 24#include <Geom_Curve.hxx>
25#include <Geom_Surface.hxx>
26#include <GeomAdaptor_Curve.hxx>
7fd59977 27#include <GeomAdaptor_HCurve.hxx>
28#include <GeomAdaptor_HSurface.hxx>
42cf5bc1 29#include <GeomAdaptor_Surface.hxx>
30#include <GeomAPI_ProjectPointOnSurf.hxx>
31#include <gp_Ax1.hxx>
32#include <gp_Circ.hxx>
33#include <gp_Cone.hxx>
34#include <gp_Cylinder.hxx>
35#include <gp_Lin.hxx>
36#include <gp_Pln.hxx>
37#include <gp_Pnt.hxx>
38#include <gp_Torus.hxx>
39#include <IntCurveSurface_HInter.hxx>
7fd59977 40#include <IntCurveSurface_IntersectionPoint.hxx>
42cf5bc1 41#include <IntTools.hxx>
42#include <IntTools_Array1OfRange.hxx>
43#include <IntTools_BeanFaceIntersector.hxx>
44#include <IntTools_CArray1OfInteger.hxx>
45#include <IntTools_CArray1OfReal.hxx>
46#include <IntTools_CommonPrt.hxx>
47#include <IntTools_Context.hxx>
48#include <IntTools_EdgeFace.hxx>
49#include <IntTools_Range.hxx>
50#include <IntTools_Root.hxx>
51#include <IntTools_Tools.hxx>
52#include <Precision.hxx>
53#include <TopoDS_Edge.hxx>
54#include <TopoDS_Face.hxx>
7fd59977 55
e35db416 56#include <algorithm>
7fd59977 57static
58 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& ,
bd28b2af 59 const BRepAdaptor_Surface& );
7fd59977 60static
61 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
bd28b2af 62 const BRepAdaptor_Surface& aSurface,
63 const Standard_Real aCriteria);
7fd59977 64static
65 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
bd28b2af 66 const BRepAdaptor_Curve& aCurve ,
67 const BRepAdaptor_Surface& aSurface);
7fd59977 68
69//=======================================================================
70//function : IntTools_EdgeFace::IntTools_EdgeFace
71//purpose :
72//=======================================================================
73 IntTools_EdgeFace::IntTools_EdgeFace()
74{
0d0481c7 75 myFuzzyValue = Precision::Confusion();
76 myDiscret = 30;
7fd59977 77 myEpsT =1e-12;
7fd59977 78 myDeflection=0.01;
79 myIsDone=Standard_False;
80 myErrorStatus=1;
6dc83e21 81 myQuickCoincidenceCheck=Standard_False;
4f189102
P
82}
83//=======================================================================
84//function : SetContext
85//purpose :
86//=======================================================================
1e143abb 87void IntTools_EdgeFace::SetContext(const Handle(IntTools_Context)& theContext)
4f189102
P
88{
89 myContext = theContext;
7fd59977 90}
91
92//=======================================================================
4f189102
P
93//function : Context
94//purpose :
95//=======================================================================
1e143abb 96const Handle(IntTools_Context)& IntTools_EdgeFace::Context()const
4f189102
P
97{
98 return myContext;
99}
100//=======================================================================
7fd59977 101//function : SetEdge
102//purpose :
103//=======================================================================
e30616a7 104void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge)
7fd59977 105{
106 myEdge=anEdge;
107}
7fd59977 108//=======================================================================
109//function : SetFace
110//purpose :
111//=======================================================================
e30616a7 112void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
7fd59977 113{
114 myFace=aFace;
115}
7fd59977 116//=======================================================================
e30616a7 117//function : Edge
118//purpose :
119//=======================================================================
120const TopoDS_Edge& IntTools_EdgeFace::Edge()const
121{
122 return myEdge;
123}
124//=======================================================================
125//function : Face
126//purpose :
127//=======================================================================
128const TopoDS_Face& IntTools_EdgeFace::Face()const
129{
130 return myFace;
131}
132//=======================================================================
0d0481c7 133//function : SetFuzzyValue
e30616a7 134//purpose :
135//=======================================================================
0d0481c7 136void IntTools_EdgeFace::SetFuzzyValue(const Standard_Real theFuzz)
e30616a7 137{
0d0481c7 138 myFuzzyValue = Max(theFuzz, Precision::Confusion());
e30616a7 139}
7fd59977 140//=======================================================================
141//function : SetDiscretize
142//purpose :
143//=======================================================================
e30616a7 144void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret)
7fd59977 145{
146 myDiscret=aDiscret;
147}
148//=======================================================================
149//function : SetDeflection
150//purpose :
151//=======================================================================
e30616a7 152void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl)
7fd59977 153{
154 myDeflection=aDefl;
155}
156//=======================================================================
157//function : SetEpsilonT
158//purpose :
159//=======================================================================
e30616a7 160void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT)
7fd59977 161{
162 myEpsT=anEpsT;
163}
164//=======================================================================
7fd59977 165//function : SetRange
166//purpose :
167//=======================================================================
e30616a7 168void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
169 const Standard_Real aLast)
7fd59977 170{
171 myRange.SetFirst (aFirst);
172 myRange.SetLast (aLast);
173}
174
175//=======================================================================
176//function : SetRange
177//purpose :
178//=======================================================================
e30616a7 179void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange)
7fd59977 180{
6dc83e21 181 SetRange(aRange.First(), aRange.Last());
7fd59977 182}
183//=======================================================================
184//function : IsDone
185//purpose :
186//=======================================================================
4f189102 187Standard_Boolean IntTools_EdgeFace::IsDone()const
7fd59977 188{
189 return myIsDone;
190}
191//=======================================================================
192//function : ErrorStatus
193//purpose :
194//=======================================================================
4f189102 195Standard_Integer IntTools_EdgeFace::ErrorStatus()const
7fd59977 196{
197 return myErrorStatus;
198}
199//=======================================================================
200//function : CommonParts
201//purpose :
202//=======================================================================
4f189102 203const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const
7fd59977 204{
205 return mySeqOfCommonPrts;
206}
207//=======================================================================
208//function : Range
209//purpose :
210//=======================================================================
4f189102 211const IntTools_Range& IntTools_EdgeFace::Range() const
7fd59977 212{
213 return myRange;
214}
6dc83e21 215//=======================================================================
216//function : IsCoincident
217//purpose :
218//=======================================================================
219Standard_Boolean IntTools_EdgeFace::IsCoincident()
220{
221 Standard_Integer i, iCnt;
222 Standard_Real dT, aT, aD, aT1, aT2, aU, aV;
223
224 gp_Pnt aP;
225 TopAbs_State aState;
226 gp_Pnt2d aP2d;
227 //
228 GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace);
229
230 const Standard_Integer aNbSeg=23;
231 const Standard_Real aTresh=0.5;
232 const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
233 aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
234 const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace);
235
236 aT1=myRange.First();
237 aT2=myRange.Last();
238 dT=(aT2-aT1)/aNbSeg;
239 //
240 Standard_Boolean isClassified = Standard_False;
241 iCnt=0;
242 for(i=0; i <= aNbSeg; ++i) {
243 aT = aT1+i*dT;
244 aP=myC.Value(aT);
245 //
246 aProjector.Perform(aP);
247 if (!aProjector.IsDone()) {
248 continue;
249 }
250 //
251
252 aD=aProjector.LowerDistance();
253 if (aD>myCriteria) {
254 continue;
255 }
256 //
257
258 ++iCnt;
259
260 //We classify only three points: in the begin, in the
261 //end and in the middle of the edge.
262 //However, exact middle point (when i == (aNbSeg + 1)/2)
263 //can be unprojectable. Therefore, it will not be able to
264 //be classified. Therefore, points with indexes in
265 //[aTreshIdxF, aTreshIdxL] range are made available
266 //for classification.
267 //isClassified == TRUE if MIDDLE point has been choosen and
268 //classified correctly.
269
270 if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg)))
271 continue;
272
273 if(isClassified && (i != aNbSeg))
274 continue;
275
276 aProjector.LowerDistanceParameters(aU, aV);
277 aP2d.SetX(aU);
278 aP2d.SetY(aV);
279
280 IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace);
281 aState = aClass2d.Perform(aP2d);
282
283 if(aState == TopAbs_OUT)
284 return Standard_False;
7fd59977 285
6dc83e21 286 if(i != 0)
287 isClassified = Standard_True;
288 }
289 //
290 const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
291 return (aCoeff > aTresh);
292}
7fd59977 293//=======================================================================
294//function : CheckData
295//purpose :
296//=======================================================================
4f189102 297void IntTools_EdgeFace::CheckData()
7fd59977 298{
299 if (BRep_Tool::Degenerated(myEdge)) {
300 myErrorStatus=2;
301 }
302 if (!BRep_Tool::IsGeometric(myEdge)) {
303 myErrorStatus=3;
304 }
305}
7fd59977 306//=======================================================================
307//function : Prepare
308//purpose :
309//=======================================================================
e30616a7 310void IntTools_EdgeFace::Prepare()
7fd59977 311{
312 Standard_Integer pri;
6dc83e21 313 Standard_Real aTmin, aTmax;
7fd59977 314 IntTools_CArray1OfReal aPars;
315
316 //
317 // 1.Prepare Curve's data and Surface's data
318 myC.Initialize(myEdge);
319 GeomAbs_CurveType aCurveType;
320 aCurveType=myC.GetType();
321 //
322 // 2.Prepare myCriteria
0d0481c7 323 Standard_Real aFuzz = myFuzzyValue / 2.;
324 Standard_Real aTolF = BRep_Tool::Tolerance(myFace) + aFuzz;
325 Standard_Real aTolE = BRep_Tool::Tolerance(myEdge) + aFuzz;
326 if (aCurveType == GeomAbs_BSplineCurve ||
327 aCurveType == GeomAbs_BezierCurve) {
328 myCriteria = 1.5*aTolE + aTolF;
7fd59977 329 }
330 else {
0d0481c7 331 myCriteria = aTolE + aTolF;
7fd59977 332 }
333 // 2.a myTmin, myTmax
6dc83e21 334 aTmin=myRange.First();
335 aTmax=myRange.Last();
7fd59977 336 // 2.b myFClass2d
337 myS.Initialize (myFace,Standard_True);
338 myFClass2d.Init(myFace, 1.e-6);
339 //
340 // 2.c Prepare adaptive myDiscret
341 myDiscret=AdaptiveDiscret(myDiscret, myC, myS);
342 //
343 //
344 // 3.Prepare myPars
6dc83e21 345 pri = IntTools::PrepareArgs(myC, aTmax, aTmin,
e30616a7 346 myDiscret, myDeflection, aPars);
7fd59977 347 if (pri) {
348 myErrorStatus=6;
349 return;
350 }
351 // 4.
352 //ProjectableRanges
353 Standard_Integer i, iProj, aNb, aNbProj, ind0, ind1;
354 Standard_Real t0, t1, tRoot;
355
356 //
357 // Table of Projection's function values
358 aNb=aPars.Length();
359 IntTools_CArray1OfInteger anArrProjectability;
360 anArrProjectability.Resize(aNb);
361
362 for (iProj=0, i=0; i<aNb; i++) {
363 t0=aPars(i);
364 aNbProj=IsProjectable (t0);
365
366 anArrProjectability(i)=0;
367 if (aNbProj) {
368 anArrProjectability(i)=1;
369 iProj++;
370 }
371 }
372 //
373 // Checking
374 if (!iProj ) {
375 myErrorStatus=7;
376 return;
377 }
378
379 //
380 // Projectable Ranges
381 IntTools_Range aRange;
382
383 ind0=anArrProjectability(0);
384 if (ind0) {
385 t0=aPars(0);
386 aRange.SetFirst(t0);
387 }
388
389 for(i=1; i<aNb; i++) {
390 ind1=anArrProjectability(i);
391 t0=aPars(i-1);
392 t1=aPars(i);
393
394 if (i==(aNb-1)) {
395 if (ind1 && ind0) {
e30616a7 396 aRange.SetLast(t1);
397 myProjectableRanges.Append(aRange);
7fd59977 398 }
399 if (ind1 && !ind0) {
e30616a7 400 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
401 aRange.SetFirst(tRoot);
402 aRange.SetLast(t1);
403 myProjectableRanges.Append(aRange);
7fd59977 404 }
405 //
406 if (ind0 && !ind1) {
e30616a7 407 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
408 aRange.SetLast(tRoot);
409 myProjectableRanges.Append(aRange);
7fd59977 410 }
411 //
412 break;
413 }
414
415 if (ind0 != ind1) {
416 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
417
418 if (ind0 && !ind1) {
e30616a7 419 aRange.SetLast(tRoot);
420 myProjectableRanges.Append(aRange);
7fd59977 421 }
422 else {
e30616a7 423 aRange.SetFirst(tRoot);
7fd59977 424 }
425 } // if (ind0 != ind1)
426 ind0=ind1;
427 } // for(i=1; i<aNb; i++) {
428}
429
430//=======================================================================
431//function : FindProjectableRoot
432//purpose :
433//=======================================================================
55468283 434 void IntTools_EdgeFace::FindProjectableRoot (const Standard_Real tt1,
435 const Standard_Real tt2,
436 const Standard_Integer ff1,
437 const Standard_Integer /*ff2*/,
438 Standard_Real& tRoot)
7fd59977 439{
440 Standard_Real tm, t1, t2, aEpsT;
55468283 441 Standard_Integer anIsProj1, anIsProjm;
442 aEpsT = 0.5 * myEpsT;
443
7fd59977 444 // Root is inside [tt1, tt2]
55468283 445 t1 = tt1;
446 t2 = tt2;
447 anIsProj1 = ff1;
448
449 for(;;)
450 {
451 if (fabs(t1 - t2) < aEpsT)
452 {
453 tRoot = (anIsProj1) ? t1 : t2;
7fd59977 454 return;
455 }
55468283 456 tm = 0.5 * (t1 + t2);
457 anIsProjm = IsProjectable(tm);
458
459 if (anIsProjm != anIsProj1)
460 {
461 t2 = tm;
7fd59977 462 }
55468283 463 else
464 {
465 t1 = tm;
466 anIsProj1 = anIsProjm;
7fd59977 467 }
55468283 468 } // for(;;)
7fd59977 469}
470//=======================================================================
471//function : IsProjectable
472//purpose :
473//=======================================================================
e30616a7 474Standard_Boolean IntTools_EdgeFace::IsProjectable
475 (const Standard_Real aT) const
7fd59977 476{
66993778 477 Standard_Boolean bFlag;
478 gp_Pnt aPC;
7fd59977 479 //
66993778 480 myC.D0(aT, aPC);
481 bFlag=myContext->IsValidPointForFace(aPC, myFace, myCriteria);
7fd59977 482 //
7fd59977 483 return bFlag;
484}
7fd59977 485//=======================================================================
486//function : DistanceFunction
487//purpose :
488//=======================================================================
e30616a7 489Standard_Real IntTools_EdgeFace::DistanceFunction
490 (const Standard_Real t)
7fd59977 491{
96a95605
DB
492 Standard_Real aD;
493
7fd59977 494 //
495 gp_Pnt P;
496 myC.D0(t, P);
497 //
498 Standard_Boolean bIsEqDistance;
499
500 bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD);
501 if (bIsEqDistance) {
502 aD=aD-myCriteria;
503 return aD;
504 }
7fd59977 505
7fd59977 506 //
507 Standard_Boolean bFlag = Standard_False;
508
4f189102
P
509 GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
510 aLocProj.Perform(P);
511 bFlag = aLocProj.IsDone();
512
513 if(bFlag) {
514 aD = aLocProj.LowerDistance();
7fd59977 515 }
516 //
517
518 if (!bFlag) {
519 myErrorStatus=11;
520 return 99.;
521 }
522
523 //
524 // aD=aProjector.LowerDistance();
525 //
526 aD=aD-myCriteria;
527 return aD;
528}
529//
530//=======================================================================
531//function : IsEqDistance
532//purpose :
533//=======================================================================
e30616a7 534Standard_Boolean IntTools_EdgeFace::IsEqDistance
535 (const gp_Pnt& aP,
536 const BRepAdaptor_Surface& aBAS,
537 const Standard_Real aTol,
538 Standard_Real& aD)
7fd59977 539{
540 Standard_Boolean bRetFlag=Standard_True;
541
542 GeomAbs_SurfaceType aSurfType=aBAS.GetType();
543
544 if (aSurfType==GeomAbs_Cylinder) {
545 gp_Cylinder aCyl=aBAS.Cylinder();
546 const gp_Ax1& anAx1 =aCyl.Axis();
547 gp_Lin aLinAxis(anAx1);
548 Standard_Real aDC, aRadius=aCyl.Radius();
549 aDC=aLinAxis.Distance(aP);
550 if (aDC < aTol) {
551 aD=aRadius;
552 return bRetFlag;
553 }
554 }
555
556 if (aSurfType==GeomAbs_Cone) {
557 gp_Cone aCone=aBAS.Cone();
558 const gp_Ax1& anAx1 =aCone.Axis();
559 gp_Lin aLinAxis(anAx1);
560 Standard_Real aDC, aRadius, aDS, aSemiAngle;
561 aDC=aLinAxis.Distance(aP);
562 if (aDC < aTol) {
563 gp_Pnt anApex=aCone.Apex();
564 aSemiAngle=aCone.SemiAngle();
565 aDS=aP.Distance(anApex);
566
567 aRadius=aDS*tan(aSemiAngle);
568 aD=aRadius;
569 return bRetFlag;
570 }
571 }
572
573 if (aSurfType==GeomAbs_Torus) {
574 Standard_Real aMajorRadius, aMinorRadius, aDC;
575
576 gp_Torus aTorus=aBAS.Torus();
577 gp_Pnt aPLoc=aTorus.Location();
578 aMajorRadius=aTorus.MajorRadius();
579
580 aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
581 if (aDC < aTol) {
582 aMinorRadius=aTorus.MinorRadius();
583 aD=aMinorRadius;
584 return bRetFlag;
585 }
586 }
587 return !bRetFlag;
588}
589//
590//=======================================================================
7fd59977 591//function : MakeType
592//purpose :
593//=======================================================================
e30616a7 594Standard_Integer IntTools_EdgeFace::MakeType
595 (IntTools_CommonPrt& aCommonPrt)
7fd59977 596{
597 Standard_Real af1, al1;
295cb053 598 Standard_Real df1, tm;
7fd59977 599 Standard_Boolean bAllNullFlag;
600 //
601 bAllNullFlag=aCommonPrt.AllNullFlag();
602 if (bAllNullFlag) {
603 aCommonPrt.SetType(TopAbs_EDGE);
604 return 0;
605 }
606 //
607 aCommonPrt.Range1(af1, al1);
608
609 {
610 gp_Pnt aPF, aPL;
611 myC.D0(af1, aPF);
612 myC.D0(al1, aPL);
613 df1=aPF.Distance(aPL);
614 Standard_Boolean isWholeRange = Standard_False;
615
616 if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
617 (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
618 isWholeRange = Standard_True;
e30616a7 619
7fd59977 620
621 if ((df1 > myCriteria * 2.) && isWholeRange) {
622 aCommonPrt.SetType(TopAbs_EDGE);
623 }
624 else {
625 if(isWholeRange) {
e30616a7 626 tm = (af1 + al1) * 0.5;
627
628 if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
629 aCommonPrt.SetType(TopAbs_EDGE);
630 return 0;
631 }
7fd59977 632 }
e30616a7 633
7fd59977 634 if(!CheckTouch(aCommonPrt, tm)) {
e30616a7 635 tm = (af1 + al1) * 0.5;
7fd59977 636 }
637 aCommonPrt.SetType(TopAbs_VERTEX);
638 aCommonPrt.SetVertexParameter1(tm);
639 aCommonPrt.SetRange1 (af1, al1);
640 }
7fd59977 641 }
e30616a7 642 return 0;
7fd59977 643}
644
645
646//=======================================================================
7fd59977 647//function : CheckTouch
648//purpose :
649//=======================================================================
e30616a7 650Standard_Boolean IntTools_EdgeFace::CheckTouch
651 (const IntTools_CommonPrt& aCP,
652 Standard_Real& aTx)
7fd59977 653{
654 Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
655 Standard_Boolean theflag=Standard_False;
51740958 656 Standard_Integer aNbExt, iLower;
7fd59977 657
658 aCP.Range1(aTF, aTL);
659
660 //
661 Standard_Real aCR;
662 aCR=myC.Resolution(myCriteria);
663 if((Abs(aTF - myRange.First()) < aCR) &&
664 (Abs(aTL - myRange.Last()) < aCR)) {
665 return theflag; // EDGE
666 }
667 //
668
669 Tol = Precision::PConfusion();
670
671 const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al);
672 const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
673 // Surface->Bounds(U1f,U1l,V1f,V1l);
674 U1f = myS.FirstUParameter();
675 U1l = myS.LastUParameter();
676 V1f = myS.FirstVParameter();
677 V1l = myS.LastVParameter();
678
679 GeomAdaptor_Curve TheCurve (Curve,aTF, aTL);
680 GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l);
e30616a7 681
7fd59977 682 Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
683
684 aDist2 = 1.e100;
685
686 if(anExtrema.IsDone()) {
687 aMinDist2 = aDist2;
688
689 if(!anExtrema.IsParallel()) {
690 aNbExt=anExtrema.NbExt();
691
692 if(aNbExt > 0) {
e30616a7 693 iLower=1;
51740958 694 for (Standard_Integer i=1; i<=aNbExt; i++) {
e30616a7 695 aDist2=anExtrema.SquareDistance(i);
696 if (aDist2 < aMinDist2) {
697 aMinDist2=aDist2;
698 iLower=i;
699 }
700 }
701 aDist2=anExtrema.SquareDistance(iLower);
702 Extrema_POnCurv aPOnC;
703 Extrema_POnSurf aPOnS;
704 anExtrema.Points(iLower, aPOnC, aPOnS);
705 aTx=aPOnC.Parameter();
7fd59977 706 }
707 else {
e30616a7 708 // modified by NIZHNY-MKK Thu Jul 21 11:35:32 2005.BEGIN
709 IntCurveSurface_HInter anExactIntersector;
7fd59977 710
e30616a7 711 Handle(GeomAdaptor_HCurve) aCurve = new GeomAdaptor_HCurve(TheCurve);
712 Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
713
714 anExactIntersector.Perform(aCurve, aSurface);
7fd59977 715
e30616a7 716 if(anExactIntersector.IsDone()) {
51740958 717 for(Standard_Integer i = 1; i <= anExactIntersector.NbPoints(); i++) {
e30616a7 718 const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
7fd59977 719
e30616a7 720 if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
721 aDist2=0.;
722 aTx = aPoint.W();
723 }
724 }
725 }
726 // modified by NIZHNY-MKK Thu Jul 21 11:35:40 2005.END
7fd59977 727 }
728 }
729 else {
730 return theflag;
731 }
732 }
733
734 Standard_Real aBoundaryDist;
735
736 aBoundaryDist = DistanceFunction(aTF) + myCriteria;
737 if(aBoundaryDist * aBoundaryDist < aDist2) {
738 aDist2 = aBoundaryDist * aBoundaryDist;
739 aTx = aTF;
740 }
741
742 aBoundaryDist = DistanceFunction(aTL) + myCriteria;
743 if(aBoundaryDist * aBoundaryDist < aDist2) {
744 aDist2 = aBoundaryDist * aBoundaryDist;
745 aTx = aTL;
746 }
747
748 Standard_Real aParameter = (aTF + aTL) * 0.5;
749 aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
750 if(aBoundaryDist * aBoundaryDist < aDist2) {
751 aDist2 = aBoundaryDist * aBoundaryDist;
752 aTx = aParameter;
753 }
754
755 if(aDist2 > myCriteria * myCriteria) {
756 return theflag;
757 }
758
759 if (fabs (aTx-aTF) < myEpsT) {
760 return !theflag;
761 }
762
763 if (fabs (aTx-aTL) < myEpsT) {
764 return !theflag;
765 }
766
767 if (aTx>aTF && aTx<aTL) {
768 return !theflag;
769 }
770
771 return theflag;
772}
6dc83e21 773
7fd59977 774//=======================================================================
775//function : Perform
776//purpose :
777//=======================================================================
e30616a7 778void IntTools_EdgeFace::Perform()
7fd59977 779{
780 Standard_Integer i, aNb;
781 IntTools_CommonPrt aCommonPrt;
7fd59977 782 //
4f189102 783 aCommonPrt.SetEdge1(myEdge);
7fd59977 784 //
785 myErrorStatus=0;
786 CheckData();
4f189102 787 if (myErrorStatus) {
7fd59977 788 return;
4f189102
P
789 }
790 //
791 if (myContext.IsNull()) {
1e143abb 792 myContext=new IntTools_Context;
4f189102
P
793 }
794 //
7fd59977 795 myIsDone = Standard_False;
796 myC.Initialize(myEdge);
797 GeomAbs_CurveType aCurveType;
798 aCurveType=myC.GetType();
799 //
800 // Prepare myCriteria
0d0481c7 801 Standard_Real aFuzz = myFuzzyValue / 2.;
802 Standard_Real aTolF = BRep_Tool::Tolerance(myFace) + aFuzz;
803 Standard_Real aTolE = BRep_Tool::Tolerance(myEdge) + aFuzz;
804 if (aCurveType == GeomAbs_BSplineCurve ||
e30616a7 805 aCurveType==GeomAbs_BezierCurve) {
7fd59977 806 //--- 5112
0d0481c7 807 Standard_Real diff1 = (aTolE/aTolF);
808 Standard_Real diff2 = (aTolF/aTolE);
7fd59977 809 if( diff1 > 100 || diff2 > 100 ) {
0d0481c7 810 myCriteria = Max(aTolE,aTolF);
7fd59977 811 }
812 else //--- 5112
0d0481c7 813 myCriteria = 1.5*aTolE + aTolF;
7fd59977 814 }
815 else {
0d0481c7 816 myCriteria = aTolE + aTolF;
7fd59977 817 }
e30616a7 818
7fd59977 819 myS.Initialize (myFace,Standard_True);
e30616a7 820
4f189102 821 if(myContext.IsNull()) {
7fd59977 822 myFClass2d.Init(myFace, 1.e-6);
823 }
6dc83e21 824 //
825 if (myQuickCoincidenceCheck) {
826 if (IsCoincident()) {
827 aCommonPrt.SetType(TopAbs_EDGE);
828 aCommonPrt.SetRange1(myRange.First(), myRange.Last());
829 MakeType (aCommonPrt);
830 mySeqOfCommonPrts.Append(aCommonPrt);
831 myIsDone=Standard_True;
832 return;
833 }
834 }
835 //
0d0481c7 836 IntTools_BeanFaceIntersector anIntersector(myC, myS, aTolE, aTolF);
7fd59977 837 anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
838 //
839 anIntersector.SetContext(myContext);
840 //
841 anIntersector.Perform();
e30616a7 842
7fd59977 843 if(!anIntersector.IsDone()) {
844 return;
845 }
e30616a7 846
7fd59977 847 for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
848 const IntTools_Range& aRange = anIntersector.Result().Value(r);
849
850 if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
851 aCommonPrt.SetRange1(aRange.First(), aRange.Last());
852 mySeqOfCommonPrts.Append(aCommonPrt);
853 }
854 }
855
856 aNb = mySeqOfCommonPrts.Length();
857
858 for (i=1; i<=aNb; i++) {
859 IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
860 //
861 Standard_Real aTx1, aTx2;
862 gp_Pnt aPx1, aPx2;
863 //
864 aCP.Range1(aTx1, aTx2);
865 myC.D0(aTx1, aPx1);
866 myC.D0(aTx2, aPx2);
867 aCP.SetBoundingPoints(aPx1, aPx2);
868 //
869 MakeType (aCP);
870 }
871 {
872 // Line\Cylinder's Common Parts treatement
873 GeomAbs_CurveType aCType;
874 GeomAbs_SurfaceType aSType;
875 TopAbs_ShapeEnum aType;
876 Standard_Boolean bIsTouch;
877 Standard_Real aTx;
e30616a7 878
7fd59977 879 aCType=myC.GetType();
880 aSType=myS.GetType();
881
882 if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
883 for (i=1; i<=aNb; i++) {
e30616a7 884 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
885 aType=aCP.Type();
886 if (aType==TopAbs_EDGE) {
887 bIsTouch=CheckTouch (aCP, aTx);
888 if (bIsTouch) {
889 aCP.SetType(TopAbs_VERTEX);
890 aCP.SetVertexParameter1(aTx);
bd28b2af 891 //aCP.SetRange1 (aTx, aTx);
e30616a7 892 }
893 }
bd28b2af 894 else if (aType==TopAbs_VERTEX) {
e30616a7 895 bIsTouch=CheckTouchVertex (aCP, aTx);
896 if (bIsTouch) {
897 aCP.SetVertexParameter1(aTx);
bd28b2af 898 //aCP.SetRange1 (aTx, aTx);
e30616a7 899 }
900 }
7fd59977 901 }
902 }
e30616a7 903
7fd59977 904 // Circle\Plane's Common Parts treatement
905
906 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
907 Standard_Boolean bIsCoplanar, bIsRadius;
908 bIsCoplanar=IsCoplanar(myC, myS);
bd28b2af 909 bIsRadius=IsRadius(myC, myS, myCriteria);
7fd59977 910 if (!bIsCoplanar && !bIsRadius) {
e30616a7 911 for (i=1; i<=aNb; i++) {
912 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
913 aType=aCP.Type();
914 if (aType==TopAbs_EDGE) {
915 bIsTouch=CheckTouch (aCP, aTx);
916 if (bIsTouch) {
917 aCP.SetType(TopAbs_VERTEX);
918 aCP.SetVertexParameter1(aTx);
bd28b2af 919 //aCP.SetRange1 (aTx, aTx);
920 }
921 }
922 else if (aType==TopAbs_VERTEX) {
923 bIsTouch=CheckTouchVertex (aCP, aTx);
924 if (bIsTouch) {
925 aCP.SetVertexParameter1(aTx);
926 //aCP.SetRange1 (aTx, aTx);
e30616a7 927 }
928 }
929 }
7fd59977 930 }
931 }
932 }
933 myIsDone=Standard_True;
934}
935
936//
937// myErrorStatus
938// 1 - the method Perform() is not invoked
939// 2,3,4,5 -the method CheckData() fails
940// 6 - PrepareArgs() problems
941// 7 - No Projectable ranges
942// 8,9 - PrepareArgs() problems occured inside projectable Ranges
943// 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays
944
945
946//=======================================================================
947//function : CheckTouch
948//purpose :
949//=======================================================================
e30616a7 950Standard_Boolean IntTools_EdgeFace::CheckTouchVertex
951 (const IntTools_CommonPrt& aCP,
952 Standard_Real& aTx)
7fd59977 953{
cf2439de 954 Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l;
955 Standard_Real aEpsT, af, al,aDist2, aMinDist2, aTm, aDist2New;
7fd59977 956 Standard_Boolean theflag=Standard_False;
957 Standard_Integer aNbExt, i, iLower ;
cf2439de 958 GeomAbs_CurveType aType;
959 //
7fd59977 960 aCP.Range1(aTF, aTL);
cf2439de 961 aType=myC.GetType();
962 //
ddd95bbf 963 aEpsT=8.e-5;
cf2439de 964 if (aType==GeomAbs_Line) {
965 aEpsT=9.e-5;
966 }
967 //
7fd59977 968 aTm=0.5*(aTF+aTL);
969 aDist2=DistanceFunction(aTm);
970 aDist2 *= aDist2;
971
972 Tol = Precision::PConfusion();
973
cf2439de 974 const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al);
7fd59977 975 const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
976
977 Surface->Bounds(U1f,U1l,V1f,V1l);
978
979 GeomAdaptor_Curve TheCurve (Curve,aTF, aTL);
980 GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l);
e30616a7 981
7fd59977 982 Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
983
984 if(!anExtrema.IsDone()) {
985 return theflag;
986 }
987 if (anExtrema.IsParallel()) {
988 return theflag;
989 }
990
991 aNbExt=anExtrema.NbExt() ;
992 if (!aNbExt) {
993 return theflag;
994 }
995
996 iLower=1;
997 aMinDist2=1.e100;
998 for (i=1; i<=aNbExt; ++i) {
999 aDist2=anExtrema.SquareDistance(i);
1000 if (aDist2 < aMinDist2) {
1001 aMinDist2=aDist2;
1002 iLower=i;
1003 }
1004 }
1005
1006 aDist2New=anExtrema.SquareDistance(iLower);
1007
1008 if (aDist2New > aDist2) {
1009 aTx=aTm;
1010 return !theflag;
1011 }
1012
1013 if (aDist2New > myCriteria * myCriteria) {
1014 return theflag;
1015 }
1016
1017 Extrema_POnCurv aPOnC;
1018 Extrema_POnSurf aPOnS;
1019 anExtrema.Points(iLower, aPOnC, aPOnS);
1020
ddd95bbf 1021
7fd59977 1022 aTx=aPOnC.Parameter();
ddd95bbf 1023 ///
1024 if (fabs (aTx-aTF) < aEpsT) {
1025 return theflag;
7fd59977 1026 }
1027
ddd95bbf 1028 if (fabs (aTx-aTL) < aEpsT) {
1029 return theflag;
7fd59977 1030 }
1031
1032 if (aTx>aTF && aTx<aTL) {
1033 return !theflag;
1034 }
1035
1036 return theflag;
1037}
1038
1039
1040//=======================================================================
1041//function : IsCoplanar
1042//purpose :
1043//=======================================================================
1044Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
e30616a7 1045 const BRepAdaptor_Surface& aSurface)
7fd59977 1046{
1047 Standard_Boolean bFlag=Standard_False;
1048
1049 GeomAbs_CurveType aCType;
1050 GeomAbs_SurfaceType aSType;
1051
1052 aCType=aCurve.GetType();
1053 aSType=aSurface.GetType();
1054
1055 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1056 gp_Circ aCirc=aCurve.Circle();
1057 const gp_Ax1& anAx1=aCirc.Axis();
1058 const gp_Dir& aDirAx1=anAx1.Direction();
1059
1060 gp_Pln aPln=aSurface.Plane();
1061 const gp_Ax1& anAx=aPln.Axis();
1062 const gp_Dir& aDirPln=anAx.Direction();
1063
1064 bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
1065 }
1066 return bFlag;
1067}
1068//=======================================================================
1069//function : IsRadius
1070//purpose :
1071//=======================================================================
bd28b2af 1072Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve,
1073 const BRepAdaptor_Surface& aSurface,
1074 const Standard_Real aCriteria)
7fd59977 1075{
1076 Standard_Boolean bFlag=Standard_False;
1077
1078 GeomAbs_CurveType aCType;
1079 GeomAbs_SurfaceType aSType;
1080
1081 aCType=aCurve.GetType();
1082 aSType=aSurface.GetType();
1083
1084 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1085 gp_Circ aCirc=aCurve.Circle();
1086 const gp_Pnt aCenter=aCirc.Location();
1087 Standard_Real aR=aCirc.Radius();
1088 gp_Pln aPln=aSurface.Plane();
1089 Standard_Real aD=aPln.Distance(aCenter);
bd28b2af 1090 if (fabs (aD-aR) < aCriteria) {
7fd59977 1091 return !bFlag;
1092 }
1093 }
1094 return bFlag;
1095}
1096//
1097//=======================================================================
1098//function : AdaptiveDiscret
1099//purpose :
1100//=======================================================================
1101Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
e30616a7 1102 const BRepAdaptor_Curve& aCurve ,
1103 const BRepAdaptor_Surface& aSurface)
7fd59977 1104{
1105 Standard_Integer iDiscretNew;
1106
1107 iDiscretNew=iDiscret;
1108
7fd59977 1109 GeomAbs_SurfaceType aSType;
1110
7fd59977 1111 aSType=aSurface.GetType();
1112
1113 if (aSType==GeomAbs_Cylinder) {
96a95605 1114 Standard_Real aELength, aRadius, dLR;
7fd59977 1115
1116 aELength=IntTools::Length(aCurve.Edge());
7fd59977 1117
1118 gp_Cylinder aCylinder=aSurface.Cylinder();
1119 aRadius=aCylinder.Radius();
1120 dLR=2*aRadius;
1121
1122 iDiscretNew=(Standard_Integer)(aELength/dLR);
1123
1124 if (iDiscretNew<iDiscret) {
1125 iDiscretNew=iDiscret;
1126 }
1127
1128 }
1129 return iDiscretNew;
1130}
1131
57c28b61 1132#ifdef _MSC_VER
7fd59977 1133#pragma warning ( default : 4101 )
1134#endif