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