0024510: Remove unused local variables
[occt.git] / src / IntTools / IntTools_EdgeEdge.cxx
CommitLineData
b311480e 1// Created on: 2000-10-26
2// Created by: Peter KURNEV
973c2be1 3// Copyright (c) 2000-2014 OPEN CASCADE SAS
7fd59977 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
973c2be1 7// This library is free software; you can redistribute it and / or modify it
8// under the terms of the GNU Lesser General Public version 2.1 as published
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.
b311480e 15
7fd59977 16#include <IntTools_EdgeEdge.ixx>
17
fa9681ca 18#include <Precision.hxx>
7fd59977 19
7fd59977 20#include <TColStd_SequenceOfReal.hxx>
21
7fd59977 22#include <gp_Circ.hxx>
23#include <gp_Ax1.hxx>
24#include <gp_Lin.hxx>
25#include <gp_Dir.hxx>
26#include <gp_Pnt.hxx>
27
fa9681ca
P
28#include <ElCLib.hxx>
29#include <Geom_Curve.hxx>
30
31#include <Geom_BSplineCurve.hxx>
32#include <GeomAdaptor_Curve.hxx>
7fd59977 33
34#include <CPnts_AbscissaPoint.hxx>
fa9681ca
P
35
36#include <GeomAPI_ProjectPointOnCurve.hxx>
37
7fd59977 38#include <Extrema_ExtElC.hxx>
39#include <Extrema_POnCurv.hxx>
fa9681ca
P
40#include <Extrema_ExtCC.hxx>
41
bd05fabf 42#include <TopoDS_Iterator.hxx>
fa9681ca
P
43#include <BRep_Tool.hxx>
44
45#include <IntTools.hxx>
46#include <IntTools_Range.hxx>
47#include <IntTools_CArray1OfReal.hxx>
48#include <IntTools_CommonPrt.hxx>
49#include <IntTools_SequenceOfRanges.hxx>
50#include <IntTools_Tools.hxx>
51#include <IntTools_BeanBeanIntersector.hxx>
7fd59977 52
e145f8c1 53
7fd59977 54//=======================================================================
55//function : IntTools_EdgeEdge::IntTools_EdgeEdge
56//purpose :
57//=======================================================================
b311480e 58IntTools_EdgeEdge::IntTools_EdgeEdge()
7fd59977 59{
60 myTol1=1.e-7;
61 myTol2=1.e-7;
62 myDiscret=30;
63 myEpsT=1e-12;
64 myEpsNull=1e-12;
65 myDeflection=0.01;
66 myIsDone=Standard_False;
67 myErrorStatus=1;
68 myOrder=Standard_False;
69
70 myPar1=0.;
71 myParallel=Standard_False;
72}
73
74//=======================================================================
75//function : SetEdge1
76//purpose :
77//=======================================================================
78 void IntTools_EdgeEdge::SetEdge1(const TopoDS_Edge& anEdge)
79{
80 myEdge1=anEdge;
81}
82//=======================================================================
83//function : SetEdge2
84//purpose :
85//=======================================================================
86 void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge& anEdge)
87{
88 myEdge2=anEdge;
89}
90
91//=======================================================================
92//function : SetTolerance1
93//purpose :
94//=======================================================================
95 void IntTools_EdgeEdge::SetTolerance1(const Standard_Real aTol)
96{
97 myTol1=aTol;
98}
99//=======================================================================
100//function : SetTolerance2
101//purpose :
102//=======================================================================
103 void IntTools_EdgeEdge::SetTolerance2(const Standard_Real aTol)
104{
105 myTol2=aTol;
106}
107
108//=======================================================================
109//function : SetDiscretize
110//purpose :
111//=======================================================================
112 void IntTools_EdgeEdge::SetDiscretize(const Standard_Integer aDiscret)
113{
114 myDiscret=aDiscret;
115}
116//=======================================================================
117//function : SetDeflection
118//purpose :
119//=======================================================================
120 void IntTools_EdgeEdge::SetDeflection(const Standard_Real aDefl)
121{
122 myDeflection=aDefl;
123}
124//=======================================================================
125//function : SetEpsilonT
126//purpose :
127//=======================================================================
128 void IntTools_EdgeEdge::SetEpsilonT(const Standard_Real anEpsT)
129{
130 myEpsT=anEpsT;
131}
132//=======================================================================
133//function : SetEpsilonNull
134//purpose :
135//=======================================================================
136 void IntTools_EdgeEdge::SetEpsilonNull(const Standard_Real anEpsNull)
137{
138 myEpsNull=anEpsNull;
139}
140
141//=======================================================================
142//function : SetRange1
143//purpose :
144//=======================================================================
145 void IntTools_EdgeEdge::SetRange1(const Standard_Real aFirst,
146 const Standard_Real aLast)
147{
148 myRange1.SetFirst (aFirst);
149 myRange1.SetLast (aLast);
150}
151//=======================================================================
152//function : SetRange2
153//purpose :
154//=======================================================================
155 void IntTools_EdgeEdge::SetRange2(const Standard_Real aFirst,
156 const Standard_Real aLast)
157{
158 myRange2.SetFirst (aFirst);
159 myRange2.SetLast (aLast);
160}
161
162//=======================================================================
163//function : SetRange1
164//purpose :
165//=======================================================================
166 void IntTools_EdgeEdge::SetRange1(const IntTools_Range& aRange)
167{
168 myRange1.SetFirst (aRange.First());
169 myRange1.SetLast (aRange.Last());
170}
171//=======================================================================
172//function : SetRange2
173//purpose :
174//=======================================================================
175 void IntTools_EdgeEdge::SetRange2(const IntTools_Range& aRange)
176{
177 myRange2.SetFirst (aRange.First());
178 myRange2.SetLast (aRange.Last());
179}
180
181//=======================================================================
182//function : Order
183//purpose :
184//=======================================================================
185 Standard_Boolean IntTools_EdgeEdge::Order()const
186{
187 return myOrder;
188}
189//=======================================================================
190//function : IsDone
191//purpose :
192//=======================================================================
193 Standard_Boolean IntTools_EdgeEdge::IsDone()const
194{
195 return myIsDone;
196}
197//=======================================================================
198//function : ErrorStatus
199//purpose :
200//=======================================================================
201 Standard_Integer IntTools_EdgeEdge::ErrorStatus()const
202{
203 return myErrorStatus;
204}
205
206//=======================================================================
207//function : CommonParts
208//purpose :
209//=======================================================================
210 const IntTools_SequenceOfCommonPrts& IntTools_EdgeEdge::CommonParts() const
211{
212 return mySeqOfCommonPrts;
213}
214//=======================================================================
215//function : Range1
216//purpose :
217//=======================================================================
218 const IntTools_Range& IntTools_EdgeEdge::Range1() const
219{
220 return myRange1;
221}
222//=======================================================================
223//function : Range2
224//purpose :
225//=======================================================================
226 const IntTools_Range& IntTools_EdgeEdge::Range2() const
227{
228 return myRange2;
229}
230//=======================================================================
231//function : Perform
232//purpose :
233//=======================================================================
234 void IntTools_EdgeEdge::Perform()
235{
f793011e
P
236 Standard_Boolean bIsSameCurves;
237 Standard_Integer i, pri, aNbCommonPrts, aNbRange;
238 Standard_Real aT1, aT2, aPC;
7fd59977 239 IntTools_CommonPrt aCommonPrt;
f793011e
P
240 GeomAbs_CurveType aCTFrom, aCTTo;
241 //
242 myIsDone=Standard_False;
7fd59977 243 myErrorStatus=0;
f793011e 244 //
7fd59977 245 CheckData();
246 if (myErrorStatus)
247 return;
248 //
7fd59977 249 Prepare();
f793011e 250
7fd59977 251 if (myErrorStatus) {
252 return;
253 }
254 //
f793011e
P
255 aCTFrom = myCFrom.GetType();
256 aCTTo = myCTo.GetType();
257 //
258 if(aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Line) {
7fd59977 259 ComputeLineLine();
260 if (myOrder) {
261 TopoDS_Edge aTmp;
262 aTmp=myEdge1;
263 myEdge1=myEdge2;
264 myEdge2=aTmp;
265 }
266 return;
267 }
f793011e 268 //
f793011e
P
269 bIsSameCurves=IsSameCurves();
270 if (bIsSameCurves) {
271 aCommonPrt.SetType(TopAbs_EDGE);
272 aCommonPrt.SetRange1 (myTminFrom, myTmaxFrom);
273 aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
274 mySeqOfCommonPrts.Append(aCommonPrt);
275 myIsDone=Standard_True;
276 return;
277 }
f793011e 278 //
7fd59977 279 IntTools_BeanBeanIntersector anIntersector(myCFrom, myCTo, myTolFrom, myTolTo);
280 anIntersector.SetBeanParameters(Standard_True, myTminFrom, myTmaxFrom);
281 anIntersector.SetBeanParameters(Standard_False, myTminTo, myTmaxTo);
f793011e 282 //
7fd59977 283 anIntersector.Perform();
7fd59977 284 if(!anIntersector.IsDone()) {
285 myIsDone = Standard_False;
286 return;
287 }
f793011e
P
288 //
289 aPC=Precision::PConfusion();
7fd59977 290 aCommonPrt.SetEdge1(myCFrom.Edge());
291 aCommonPrt.SetEdge2(myCTo.Edge());
f793011e
P
292 //
293 const IntTools_SequenceOfRanges& aSR=anIntersector.Result();
294 aNbRange=aSR.Length();
295 for(i=1; i <=aNbRange; ++i) {
296 const IntTools_Range& aRange =aSR.Value(i);
297 aT1=aRange.First();
298 aT2=aRange.Last();
299 //
300 if(IsProjectable(IntTools_Tools::IntermediatePoint(aT1, aT2))) {
301 aCommonPrt.SetRange1(aT1, aT2);
302 //
303 if(((aT1 - myTminFrom)<aPC) && ((myTmaxFrom - aT2)<aPC)) {
7fd59977 304 aCommonPrt.SetAllNullFlag(Standard_True);
305 }
306 mySeqOfCommonPrts.Append(aCommonPrt);
307 }
308 }
f793011e 309 //
7fd59977 310 aNbCommonPrts=mySeqOfCommonPrts.Length();
f793011e 311 for (i=1; i<=aNbCommonPrts; ++i) {
7fd59977 312 IntTools_CommonPrt& aCmnPrt=mySeqOfCommonPrts.ChangeValue(i);
313 pri=FindRangeOnCurve2 (aCmnPrt);
7fd59977 314 if (pri) {
315 myErrorStatus=10;
316 return;
317 }
318 }
319 //
f793011e
P
320 // Line Circle's Common Parts treatement
321 if ((aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Circle) ||
322 (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Line) ||
323 (aCTFrom==GeomAbs_Ellipse && aCTTo==GeomAbs_Ellipse) ||
324 (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Circle)) {
325 for (i=1; i<=aNbCommonPrts; i++) {
326 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
327 TopAbs_ShapeEnum aType=aCP.Type();
328 Standard_Boolean bIsTouch;
329 Standard_Real aTx1, aTx2;
330 //
331 if ((aType==TopAbs_EDGE) && !aCommonPrt.AllNullFlag()) {
332 bIsTouch=CheckTouch (aCP, aTx1, aTx2);
333 if (bIsTouch) {
334 aCP.SetType(TopAbs_VERTEX);
335 aCP.SetVertexParameter1(aTx1);
336 aCP.SetRange1 (aTx1, aTx1);
337 IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
338 aRange2.SetFirst(aTx2);
339 aRange2.SetLast (aTx2);
340 }
341 }
342 //
343 if (aType==TopAbs_VERTEX) {
344 if(aCTFrom==GeomAbs_Line || aCTTo==GeomAbs_Line) {
345 bIsTouch=CheckTouchVertex (aCP, aTx1, aTx2);
7fd59977 346 if (bIsTouch) {
7fd59977 347 aCP.SetVertexParameter1(aTx1);
348 aCP.SetRange1 (aTx1, aTx1);
349 IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
350 aRange2.SetFirst(aTx2);
351 aRange2.SetLast (aTx2);
352 }
353 }
7fd59977 354 }
355 }
356 }
f793011e 357 //
7fd59977 358 if (myOrder) {
359 TopoDS_Edge aTmp;
360 aTmp=myEdge1;
361 myEdge1=myEdge2;
362 myEdge2=aTmp;
363 }
f793011e 364 //
7fd59977 365 myIsDone=Standard_True;
366}
fa9681ca 367
7fd59977 368//=======================================================================
369//function : CheckData
370//purpose :
371//=======================================================================
372 void IntTools_EdgeEdge::CheckData()
373{
374 if (BRep_Tool::Degenerated(myEdge1)) {
375 myErrorStatus=2;
376 }
377 if (!BRep_Tool::IsGeometric(myEdge1)) {
378 myErrorStatus=3;
379 }
380 if (BRep_Tool::Degenerated(myEdge2)) {
381 myErrorStatus=4;
382 }
383 if (!BRep_Tool::IsGeometric(myEdge2)) {
384 myErrorStatus=5;
385 }
386}
387//=======================================================================
388//function : Prepare
389//purpose :
390//=======================================================================
391 void IntTools_EdgeEdge::Prepare()
392{
f793011e
P
393 Standard_Real aLE1, aLE2, aT1, aT2, aTol1, aTol2;
394 GeomAdaptor_Curve aGAC;
395 GeomAbs_CurveType aCT1, aCT2;
7fd59977 396 //
397 // 1.Prepare Curves' data
f793011e
P
398 const Handle(Geom_Curve)& aC1=BRep_Tool::Curve (myEdge1, aT1, aT2);
399 aT1=myRange1.First();
400 aT2=myRange1.Last();
401 aGAC.Load(aC1, myRange1.First(), myRange1.Last());
402 aLE1=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
403 //
404 const Handle(Geom_Curve)& aC2=BRep_Tool::Curve (myEdge2, aT1, aT2);
405 aT1=myRange2.First();
406 aT2=myRange2.Last();
407 aGAC.Load(aC2, aT1, aT2);
408 aLE2=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
409 //
410 myOrder=Standard_False;
7fd59977 411 if (aLE1 <= aLE2) {
412 myCFrom.Initialize(myEdge1);
413 myCTo .Initialize(myEdge2);
414 myTolFrom=myTol1;
415 myTolTo=myTol2;
416 myTminFrom=myRange1.First();
417 myTmaxFrom=myRange1.Last ();
418 myTminTo =myRange2.First();
419 myTmaxTo =myRange2.Last ();
420 }
421 else {
422 myCFrom.Initialize(myEdge2);
423 myCTo .Initialize(myEdge1);
424 myTolFrom=myTol2;
425 myTolTo=myTol1;
426 myTminFrom=myRange2.First();
427 myTmaxFrom=myRange2.Last ();
428 myTminTo =myRange1.First();
429 myTmaxTo =myRange1.Last ();
f793011e 430 //
7fd59977 431 myOrder=Standard_True; // revesed order
432 }
433 //
434 // 2.Prepare myCriteria
7fd59977 435 aCT1=myCFrom.GetType();
f793011e 436 aCT2=myCTo.GetType();
7fd59977 437 //
f793011e
P
438 aTol1=myTol1;
439 if(aCT1==GeomAbs_BSplineCurve|| aCT1==GeomAbs_BezierCurve){
440 aTol1=1.2*myTol1;
7fd59977 441 }
f793011e
P
442 aTol2=myTol2;
443 if(aCT2==GeomAbs_BSplineCurve|| aCT2==GeomAbs_BezierCurve){
444 aTol2=1.2*myTol2;
7fd59977 445 }
f793011e 446 myCriteria=aTol1+aTol2;
7fd59977 447}
7fd59977 448//=======================================================================
449//function : IsProjectable
450//purpose :
451//=======================================================================
452 Standard_Integer IntTools_EdgeEdge::IsProjectable(const Standard_Real t) const
453{
454 Standard_Integer aNbProj;
455 Standard_Real f, l;
456 gp_Pnt aPFrom;
457
458 GeomAPI_ProjectPointOnCurve aProjector;
459 const TopoDS_Edge& aEFrom=myCFrom.Edge();
460 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
461 aCurveFrom->D0(t, aPFrom);
462
463 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (myCTo.Edge(), f, l);
7fd59977 464 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
465 aProjector.Perform(aPFrom);
7fd59977 466 aNbProj=aProjector.NbPoints();
467 //
468 if (myCTo.GetType()==GeomAbs_Circle) {
469 gp_Circ aCirc=myCTo.Circle();
470 const gp_Pnt& aCenter=aCirc.Location();
471 if (aCenter.SquareDistance(aPFrom) < 1.e-7) {
472 aNbProj=1;
473 }
474 }
475 return aNbProj;
476}
477
478//=======================================================================
479//function : DistanceFunction
480//purpose :
481//=======================================================================
482 Standard_Real IntTools_EdgeEdge::DistanceFunction(const Standard_Real t)//const
483{
484 Standard_Real aD, f, l;
485 GeomAPI_ProjectPointOnCurve aProjector;
486 gp_Pnt aPFrom; //ZZ , aPTo;
487
488 const TopoDS_Edge& aEFrom=myCFrom.Edge();
489 const TopoDS_Edge& aETo =myCTo.Edge();
490
491 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
492 aCurveFrom->D0 (t, aPFrom);
493 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (aETo, f, l);
494
495 if (myCTo.GetType()==GeomAbs_Circle) {
496 gp_Circ aCirc=myCTo.Circle();
497 const gp_Pnt& aCenter=aCirc.Location();
498 const gp_Ax1& anAx1 =aCirc.Axis();
499 const gp_Dir& aDir =anAx1.Direction();
500 gp_Lin aLin(aCenter, aDir);
501 Standard_Real dPFromLin=aLin.Distance(aPFrom);
502 if (dPFromLin < 1.e-7) {
503 gp_Pnt anAnyPTo;
504 aCurveTo->D0 (myTminTo, anAnyPTo);
505 aD=aPFrom.Distance(anAnyPTo);
506
507 aD=aD-myCriteria;
508 return aD;
509 }
510 }
511
7fd59977 512 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
513 aProjector.Perform(aPFrom);
7fd59977 514 //
515 Standard_Integer j, aNbPoints;
516 //
517 aNbPoints =aProjector.NbPoints();
518 if (!aNbPoints) {
519 for (j=0; j<=1; j++) {
520 Standard_Real tt;
521 tt=t+myEpsT;
522 if (j) {
523 tt=t-myEpsT;
524 }
525
526 aCurveFrom->D0 (tt, aPFrom);
7fd59977 527 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
528 aProjector.Perform(aPFrom);
7fd59977 529 aNbPoints=aProjector.NbPoints();
530 if (aNbPoints) {
531 break;
532 }
533 }
534 }
535
536
537 if (!aNbPoints) {
538 // Can't find projection.
539 myErrorStatus=11;
540 aD=100.;
541 return aD;
542 }
543
544 aD=aProjector.LowerDistance();
545 //
546 aD=aD-myCriteria;
547 return aD;
548}
549
550//=======================================================================
551//function : DerivativeFunction
552//purpose :
553//=======================================================================
554 Standard_Real IntTools_EdgeEdge::DerivativeFunction(const Standard_Real t2)
555{
556 Standard_Real t1, t3, aD1, aD2, aD3;
557 Standard_Real dt=1.e-7;
558 t1=t2-dt;
559 aD1=DistanceFunction(t1);
560 t3=t2+dt;
561 aD3=DistanceFunction(t3);
562
563 aD2=.5*(aD3-aD1)/dt;
564 return aD2;
565}
566
7fd59977 567
7fd59977 568//=======================================================================
569//function : FindSimpleRoot
570//purpose : [private]
571//=======================================================================
572 Standard_Real IntTools_EdgeEdge::FindSimpleRoot (const Standard_Integer IP,
573 const Standard_Real tA,
574 const Standard_Real tB,
575 const Standard_Real fA)
576{
577 Standard_Real r, a, b, y, x0, s;
578
579 a=tA; b=tB; r=fA;
580
581 Standard_Integer step = 1, stepcheck = 1000, steplimit = 100000;
582 Standard_Real value = (IP==1) ? DistanceFunction(0.5*(a+b)) : DerivativeFunction(0.5*(a+b));
583
302f96fb 584 for(;;) {
7fd59977 585 x0=.5*(a+b);
586
587 if (IP==1)
588 y=DistanceFunction(x0);
589 else
590 y=DerivativeFunction(x0);
591
592 Standard_Real aMaxAB100 = 100.*Max(a, b);
593 Standard_Real anEps = Epsilon(aMaxAB100);
594 Standard_Real anEpsT = Max(anEps, myEpsT);
595// if (fabs(b-a) < myEpsT || y==0.) {
596 if (fabs(b-a) < anEpsT || y==0.) {
597 return x0;
598 }
599
600 if( step == stepcheck ) {
601 if( Abs(value - y) <= 1.e-9 ) {
602 return x0;
603 }
604 else {
605 value = y;
606 step = 1;
607 }
608 }
609
610 if( step == steplimit ) {
611 return x0;
612 }
613
614 s=y*r;
615
616 if (s<0.) {
617 b=x0;
618 continue;
619 }
620
621 if (s>0.) {
622 a=x0; r=y;
623 }
624
625 step++;
626
627 }
628}
629
630//=======================================================================
631//function : FindRangeOnCurve2
632//purpose :
633//=======================================================================
e145f8c1 634Standard_Integer IntTools_EdgeEdge::FindRangeOnCurve2(IntTools_CommonPrt& aCommonPrt)
7fd59977 635{
7fd59977 636 Standard_Integer pri;
e145f8c1 637 //
638 pri=0;
639 if (aCommonPrt.AllNullFlag()) {
640 aCommonPrt.SetType(TopAbs_EDGE);
641 aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
642 return pri;
643 }
644 //
645 Standard_Real ttmp, f, l, af1, al1, am1, af2, al2, am2;
7fd59977 646 gp_Pnt aPf1, aPl1, aPm1, aPf2, aPl2, aPm2;
647 GeomAPI_ProjectPointOnCurve aProjector;
648
649 aCommonPrt.Range1(af1, al1);
650 am1=.5*(af1+al1);
651
652 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
653 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f, l);
654
655 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
656 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
657 //
658 // af2, aPf2
659 aCurveFrom->D0 (af1, aPf1);
660 pri=GetParameterOnCurve2 (af1, af2);
661 if (pri) {
662 return 1;
663 }
664 aCurveTo->D0(af2, aPf2);
665 //
666 // al2, aPl2
667 aCurveFrom->D0 (al1, aPl1);
668 pri=GetParameterOnCurve2 (al1, al2);
669 if (pri) {
670 return 1;
671 }
672 aCurveTo->D0(al2, aPl2);
673 //
674 // am2, aPm2
675 aCurveFrom->D0 (am1, aPm1);
676 pri=GetParameterOnCurve2 (am1, am2);
677 if (pri) {
678 return 1;
679 }
680 aCurveTo->D0(am2, aPm2);
681 //
682 // Reverse C2 points if it is necessary
683 Standard_Boolean reverse = (af2 > al2);
684
685 if (reverse) {
686 ttmp=af2;
687 af2=al2;
688 al2=ttmp;
689 gp_Pnt aPTmp;
690 aPTmp=aPf2;
691 aPf2=aPl2;
692 aPl2=aPTmp;
693 }
694
695 if((Abs(af2 - myTminTo) < Precision::PConfusion()) &&
696 (Abs(al2 - myTmaxTo) < Precision::PConfusion())) {
697 aCommonPrt.SetAllNullFlag(Standard_True);
698 }
699 //
700 //
701 Standard_Boolean aVFlag1, aVFlag2, aGeomFlag1, aGeomFlag2;
96a95605 702 Standard_Real Df2m2, Dm2l2, Df2l2, df2m2, dm2l2, df2l2, df1l1;
7fd59977 703 Standard_Real tV1, tV2;
704 //
705 // parametric differences for C2
706 Df2m2=fabs(af2-am2);
707 Dm2l2=fabs(am2-al2);
708 Df2l2=fabs(af2-al2);
709 //
710 // geometric distances for C2
711 df2m2=aPf2.Distance(aPm2);
712 dm2l2=aPm2.Distance(aPl2);
713 df2l2=aPf2.Distance(aPl2);
714
715 aVFlag1=(Df2m2<myEpsT && Dm2l2<myEpsT);
716 aVFlag2=(df2m2 < myCriteria && dm2l2 < myCriteria);
717
718 //
719 // Two perpendicular lines => VERTEX
720 if ( aVFlag1 && aVFlag2) {
721 // V e r t e x
722 aCommonPrt.SetType(TopAbs_VERTEX);
723 pri=TreatVertexType(am1, am2, aCommonPrt);
724
725 if (pri) {
726 tV2=.5*(af2+al2);
727 aCommonPrt.SetVertexParameter2(tV2);
728 aCommonPrt.AppendRange2 (af2, al2);
729
730 tV1=.5*(af1+al1);
731 aCommonPrt.SetVertexParameter1(tV1);
732 aCommonPrt.SetRange1 (af1, al1);
733 }
734 return 0;
735 }
736 //
737 // geometric distances for C1
7fd59977 738 df1l1=aPf1.Distance(aPl1);
739 //
740 // if geometric distances between boundaries is less than myCriteria
741 // we have VERTEX
742 aGeomFlag1=(df1l1 < myCriteria);
743 aGeomFlag2=(df2l2 < myCriteria);
744 if (aGeomFlag1 && aGeomFlag2) {
745 aCommonPrt.SetType(TopAbs_VERTEX);
746
747 tV2=.5*(af2+al2);
748 aCommonPrt.SetVertexParameter2(tV2);
749 aCommonPrt.AppendRange2 (af2, al2);
750
751 tV1=.5*(af1+al1);
752 aCommonPrt.SetVertexParameter1(tV1);
753 aCommonPrt.SetRange1 (af1, al1);
754 return 0;
755 }
756 //
757 // ???
758 if (Df2l2 < myEpsT && !aVFlag1) {
759 if (aPf1.Distance(aPl1) < myCriteria && aPf2.Distance(aPl2) < myCriteria) {
760 af1=myTminTo;
761 al2=myTmaxTo;
762 aCommonPrt.AppendRange2 (af1, al2);
763 aCommonPrt.SetType(TopAbs_EDGE);
764 return 0;
765 }
766 }
767 //
7fd59977 768 aProjector.Init(aCurveFrom, myTminFrom, myTmaxFrom);
769 aProjector.Perform(aPm2);
7fd59977 770 Standard_Integer aNbPoints=aProjector.NbPoints();
771 if (aNbPoints) {
772 Standard_Real aDD=aProjector.LowerDistance();
773 if (aDD > myCriteria) {
774 // Passed through 0
775 aCommonPrt.SetType(TopAbs_EDGE);
776 aCommonPrt.AppendRange2 (myTminTo, af2);
777 aCommonPrt.AppendRange2 (al2, myTmaxTo);
778 return 0;
779 }
780 }
781 else {
782 // Passed through 0
783 aCommonPrt.SetType(TopAbs_EDGE);
784 aCommonPrt.AppendRange2 (myTminTo, af2);
785 aCommonPrt.AppendRange2 (al2, myTmaxTo);
786 return 0;
787 }
788
789 IsIntersection (af1, al1);
790 if (!myParallel && !aCommonPrt.AllNullFlag()) {
791 Standard_Real aPar2;
792 GetParameterOnCurve2 (myPar1, aPar2);
793 aCommonPrt.SetType(TopAbs_VERTEX);
794
795 Standard_Boolean IsmyPar1 = Standard_True;
796
797 if(Abs(af1-myTminFrom) < Precision::PConfusion()) {
798 IsmyPar1 = Standard_False;
799 aCommonPrt.SetVertexParameter1(af1);
800 if(reverse)
801 aCommonPrt.SetVertexParameter2(al2);
802 else
803 aCommonPrt.SetVertexParameter2(af2);
804 }
805
806 if(Abs(al1-myTmaxFrom) < Precision::PConfusion()) {
807 IsmyPar1 = Standard_False;
808 aCommonPrt.SetVertexParameter1(al1);
809
810 if(reverse)
811 aCommonPrt.SetVertexParameter2(af2);
812 else
813 aCommonPrt.SetVertexParameter2(al2);
814 }
815
816 if(Abs(af2-myTminTo) < Precision::PConfusion()) {
817 IsmyPar1 = Standard_False;
818 aCommonPrt.SetVertexParameter2(af2);
819
820 if(reverse)
821 aCommonPrt.SetVertexParameter1(al1);
822 else
823 aCommonPrt.SetVertexParameter1(af1);
824 }
825
826 if(Abs(al2-myTmaxTo) < Precision::PConfusion()) {
827 IsmyPar1 = Standard_False;
828 aCommonPrt.SetVertexParameter2(al2);
829
830 if(reverse)
831 aCommonPrt.SetVertexParameter1(af1);
832 else
833 aCommonPrt.SetVertexParameter1(al1);
834 }
835 // aCommonPrt.SetVertexParameter1(myPar1);
836 // aCommonPrt.SetRange1 (af1, al1);
837
838 // aCommonPrt.SetVertexParameter2(aPar2);
839 if(IsmyPar1) {
840 aCommonPrt.SetVertexParameter1(myPar1);
841 aCommonPrt.SetRange1 (af1, al1);
842
843 aCommonPrt.SetVertexParameter2(aPar2);
844 }
845 aCommonPrt.AppendRange2 (af2, al2);
846 return 0;
847 }
848
849
850
851 aCommonPrt.SetType(TopAbs_EDGE);
852 aCommonPrt.AppendRange2 (af2, al2);
853 return 0;
854}
855
856//=======================================================================
857//function : IsIntersection
858//purpose :
859//=======================================================================
860 void IntTools_EdgeEdge::IsIntersection (const Standard_Real ta,
861 const Standard_Real tb)
862{
96a95605 863 Standard_Integer i, aNb;
7fd59977 864 Standard_Real t, f;
865 GeomAbs_CurveType aCT1, aCT2;
866 IntTools_CArray1OfReal anArgs, aFunc;
867 //
868 aCT1=myCFrom.GetType();
869 aCT2=myCTo.GetType();
870 if((aCT1==GeomAbs_Line) && (aCT2==GeomAbs_Line)) {
871 const Handle(Geom_Curve)& Curve1=BRep_Tool::Curve (myCFrom.Edge(), t, f);
872 const Handle(Geom_Curve)& Curve2=BRep_Tool::Curve (myCTo.Edge() , t, f);
873
874 GeomAdaptor_Curve TheCurve1 (Curve1);
875 GeomAdaptor_Curve TheCurve2 (Curve2);
876 Extrema_ExtCC anExtrema (TheCurve1, TheCurve2);
877
878 if(anExtrema.IsDone() && anExtrema.IsParallel()) {
879 myParallel = Standard_True;
880 return;
881 }
882 }
883 //
7fd59977 884 if (aCT1==GeomAbs_Circle && aCT2==GeomAbs_Circle) {
885 Standard_Boolean bIsDone, bIsParallel;
886 Standard_Integer aNbExt;
887 Standard_Real aD2, aCriteria2, aT1;
888 gp_Circ aCirc1, aCirc2;
889 Extrema_POnCurv aPC1, aPC2;
890 //
891 aCirc1=myCFrom.Circle();
892 aCirc2=myCTo.Circle();
893 //
894 Extrema_ExtElC aExtElC(aCirc1, aCirc2);
895 //
896 bIsDone=aExtElC.IsDone();
897 if (bIsDone) {
898 bIsParallel=aExtElC.IsParallel();
899 if (!bIsParallel) {
900 aCriteria2=myCriteria*myCriteria;
901 aNbExt=aExtElC.NbExt();
902 for (i=1; i<=aNbExt; ++i) {
903 aD2=aExtElC.SquareDistance(i);
904 if (aD2<aCriteria2) {
905 aExtElC.Points(i, aPC1, aPC2);
906 aT1=aPC1.Parameter();
907 if (aT1>ta && aT1<tb) {
908 myPar1=aT1;
909 myParallel=Standard_False;
910 return;
911 }
912 }
913 }
914 }
915 }
916 }
7fd59977 917 //
918 // Prepare values of arguments for the interval [ta, tb]
96a95605 919 IntTools::PrepareArgs (myCFrom, tb, ta, myDiscret, myDeflection, anArgs);
7fd59977 920 aNb=anArgs.Length();
921
922 aFunc.Resize(aNb);
923 for (i=0; i<aNb; i++) {
924 t=anArgs(i);
925 f=DistanceFunction(t);
926 if (fabs(f) < myEpsNull) {
927 f=0.;
928 }
929 aFunc(i)=f;
930 }
931 FindDerivativeRoot(anArgs, aFunc);
932 return ;
933}
934
935//=======================================================================
936//function : FindDerivativeRoot
937//purpose :
938//=======================================================================
939 void IntTools_EdgeEdge::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
940 const IntTools_CArray1OfReal& f)
941{
942 Standard_Integer i, n, k;
96a95605 943 Standard_Real tr, anEpsNull;
7fd59977 944 IntTools_CArray1OfReal fd;
945 TColStd_SequenceOfReal aTSeq, aFSeq;
946
947 anEpsNull=100.*myEpsNull;
948 myPar1=0.;
949 myParallel=Standard_True;
950
951 n=t.Length();
952 fd.Resize(n+1);
953 //
954 // Table of derivatives
955 fd(0)=(f(1)-f(0))/(t(1)-t(0));
956 if (fabs(fd(0)) < anEpsNull) {
957 fd(0)=0.;
958 }
959 k=n-1;
960 for (i=1; i<k; i++) {
961 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
962 if (fabs(fd(i)) < anEpsNull) {
963 fd(i)=0.;
964 }
965 }
966 fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
967 if (fabs(fd(n-1)) < anEpsNull) {
968 fd(n-1)=0.;
969 }
970 //
971 // Finding the range where the derivatives have different signs
972 // for neighbouring points
973 for (i=1; i<n; i++) {
974 Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
975 Standard_Boolean bF1, bF2;
976 t1 =t(i-1);
977 t2 =t(i);
978 fd1=fd(i-1);
979 fd2=fd(i);
980
981 fabsfd1=fabs(fd1);
982 bF1=fabsfd1 < myEpsNull;
983
984 fabsfd2=fabs(fd2);
985 bF2=fabsfd2 < myEpsNull;
986
987 //aa
988 if (fd1*fd2 < 0.) {
989 tr=FindSimpleRoot(2, t1, t2, fd1);
7fd59977 990 myPar1=tr;
991 myParallel=Standard_False;
992 break;
993 }
994
995 if (!bF1 && bF2) {
996 tr=t2;
7fd59977 997 myPar1=tr;
998 myParallel=Standard_False;
999 break;
1000 }
1001
1002 if (bF1 && !bF2) {
1003 tr=t1;
7fd59977 1004 myPar1=tr;
1005 myParallel=Standard_False;
1006 break;
1007 }
1008
1009 }
1010}
1011
1012//=======================================================================
1013//function : GetParameterOnCurve2
1014//purpose :
1015//=======================================================================
1016 Standard_Integer IntTools_EdgeEdge::GetParameterOnCurve2(const Standard_Real aT1,
1017 Standard_Real& aT2) const
1018{
1019 Standard_Real f, l;
1020 Standard_Integer j, found, aNbPoints;
1021 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
1022 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
1023
1024 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
1025 Handle(Geom_Curve)aCurveTo =BRep_Tool::Curve (anEdgeTo, f, l);
1026
1027 gp_Pnt aP1;
1028 aCurveFrom->D0 (aT1, aP1);
1029 GeomAPI_ProjectPointOnCurve aProjector;
7fd59977 1030 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
1031 aProjector.Perform(aP1);
7fd59977 1032 aNbPoints=aProjector.NbPoints();
1033 found=1;
1034 if (!aNbPoints) {
1035 found=0;
1036 for (j=0; j<=1; j++) {
1037 Standard_Real tt;
1038 tt=aT1+myEpsT;
1039 if (j) {
1040 tt=aT1-myEpsT;
1041 }
1042 aCurveFrom->D0 (tt, aP1);
7fd59977 1043 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
1044 aProjector.Perform(aP1);
7fd59977 1045 aNbPoints=aProjector.NbPoints();
1046 if (aNbPoints) {
1047 found=1;
1048 break;
1049 }
1050 }
1051 }
1052
1053 if (!found) {
1054 aCurveFrom->D0 (aT1, aP1);
1055 Standard_Real aDistance = RealLast();
1056
1057 for(Standard_Integer pIt=0; pIt < 2; pIt++) {
1058 Standard_Real adist = aDistance;
1059 if(pIt)
1060 adist = aP1.Distance(aCurveTo->Value(myTminTo));
1061 else
1062 adist = aP1.Distance(aCurveTo->Value(myTmaxTo));
1063
1064 if(adist < myCriteria) {
1065 found = Standard_True;
1066
1067 if(adist < aDistance) {
1068 aT2 = (pIt) ? myTminTo : myTmaxTo;
1069 aDistance = adist;
1070 }
1071 }
1072 }
1073 if(found)
1074 return 0;
1075 }
1076
1077 if (!found) {
1078 aT2=0.;
1079 return 1;
1080 }
1081
1082 for (j=1; j<=aNbPoints; j++) {
1083 aT2=aProjector.Parameter(j);
1084 f=aProjector.Distance(j);
1085 }
1086
1087 aT2=aProjector.LowerDistanceParameter();
1088 if (aT2 < myTminTo) {
1089 aT2=myTminTo;
1090 }
1091 if (aT2 > myTmaxTo) {
1092 aT2=myTmaxTo;
1093 }
1094 return 0;
1095}
1096
1097//=======================================================================
1098//function : TreatVertexType
1099//purpose :
1100//=======================================================================
1101 Standard_Integer IntTools_EdgeEdge::TreatVertexType(const Standard_Real am1,
1102 const Standard_Real am2,
1103 IntTools_CommonPrt& aCommonPrt)
1104{
1105 Standard_Real f1, l1, f2, l2, Alfa , aPeriod;
1106 gp_Pnt aPm1, aPm2, aP;
1107 gp_Vec aVm1, aVm2;
1108
1109
1110 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
1111 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f1, l1);
1112 aCurveFrom->D1 (am1, aPm1, aVm1);
1113 aVm1.Normalize();
1114
1115 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
1116 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f2, l2);
1117 aCurveTo->D1 (am2, aPm2, aVm2);
1118 aVm2.Normalize();
1119
1120 Alfa=aVm1.Angle(aVm2);
1121
1122 if (Alfa < Precision::Angular()) {
1123 return 1;
1124 }
1125
1126 Standard_Real sinAlfa, cosAlfa, dd, tf1, tl1, tf2, tl2, aL1, aL2;
1127 Standard_Integer ip;
1128
1129 sinAlfa=sin(Alfa);
1130 cosAlfa=cos(Alfa);
1131
1132 dd=aPm1.Distance(aPm2);
1133 // aL2
1134 if (dd>myCriteria) {
1135 return 1;
1136 }
1137 aL2=(myTolTo*cosAlfa+myTolFrom)/sinAlfa;
1138 // left point
1139 aP.SetXYZ(aPm2.XYZ()-aVm2.XYZ()*aL2);
1140 ip=IntTools::Parameter (aP, aCurveTo, tf2);
1141 if (ip){
1142 return ip;
1143 }
1144 //
1145 if(aP.Distance(aCurveTo->Value(tf2)) > myTolTo)
1146 return 1;
1147
1148 // right point
1149 aP.SetXYZ(aPm2.XYZ()+aVm2.XYZ()*aL2);
1150 ip=IntTools::Parameter (aP, aCurveTo, tl2);
1151 if (ip){
1152 return ip;
1153 }
1154
1155 if(aP.Distance(aCurveTo->Value(tl2)) > myTolTo)
1156 return 1;
1157
1158 // aL1
1159 if (dd>myCriteria) {
1160 return 1;
1161 }
1162
1163 aL1=(myTolFrom*cosAlfa+myTolTo)/sinAlfa;
1164 // left point
1165 aP.SetXYZ(aPm1.XYZ()-aVm1.XYZ()*aL1);
1166 ip=IntTools::Parameter (aP, aCurveFrom, tf1);
1167 if (ip){
1168 return ip;
1169 }
1170
1171 if(aP.Distance(aCurveFrom->Value(tf1)) > myTolFrom)
1172 return 1;
1173
1174 // right point
1175 aP.SetXYZ(aPm1.XYZ()+aVm1.XYZ()*aL1);
1176 ip=IntTools::Parameter (aP, aCurveFrom, tl1);
1177 if (ip){
1178 return ip;
1179 }
1180
1181 if(aP.Distance(aCurveFrom->Value(tl1)) > myTolFrom)
1182 return 1;
1183
1184 //
1185 if (aCurveFrom->IsPeriodic()) {
1186 aPeriod=aCurveFrom->Period();
1187 if (tf1<f1 || tf1>l1) {
1188 tf1=tf1+aPeriod;
1189 }
1190 if (tl1<f1 || tl1>l1) {
1191 tl1=tl1+aPeriod;
1192 }
1193 }
1194 //
1195 // First range
1196 aCommonPrt.SetRange1 (tf1, tl1);
1197 aCommonPrt.SetVertexParameter1((tf1 + tl1) * 0.5);
1198 //
1199 // Second Range(s)
1200 if (aCurveTo->IsPeriodic() && tf2 > tl2) {
1201 // aCurveTo is periodic curve and we pass through 0.
1202
1203 aPeriod=aCurveTo->Period();
1204 aCommonPrt.AppendRange2 (tf2, aPeriod);
1205 aCommonPrt.AppendRange2 (0., tl2);
1206 aCommonPrt.SetVertexParameter2((tf2 + aPeriod) * 0.5);
1207 }
1208 else {
1209 // usual cases
1210 return 1;
1211 //
1212 }
1213 return 0;
1214}
1215
1216
1217//
1218//
1219// Print block
1220
1221// myErrorStatus
1222// 1 - the method Perform() is not invoked
1223// 2,3,4,5 -the method CheckData() fails
1224// 6 - PrepareArgs() problems
1225// 7 - No Projectable ranges
1226// 8,9 - PrepareArgs() problems occured inside projectable Ranges
1227// 10 - problems in FindRange2
1228// 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays:
1229// possible reason is that no points on myCFrom that could be projected
1230// on myCTo
1231//
1232
fa9681ca 1233
7fd59977 1234//=======================================================================
1235//function : CheckTouchVertex
1236//purpose : line/Circle refinement
1237//=======================================================================
1238 Standard_Boolean IntTools_EdgeEdge::CheckTouchVertex (const IntTools_CommonPrt& aCP,
1239 Standard_Real& aTx1,
1240 Standard_Real& aTx2) const
1241{
1242 Standard_Boolean bFlag;
1243 Standard_Real aTFR1, aTLR1, aTFR2, aTLR2;
1244 Standard_Real aTL1, aTL2, aTC1, aTC2;
1245 Standard_Real aRC, aDLC, aD2, aC2, aTLx, aTCx;
96a95605 1246 GeomAbs_CurveType aTFrom;
7fd59977 1247 gp_Circ aCirc;
1248 gp_Lin aLine;
1249 gp_Pnt aPC, aPLx, aPCx;
1250 //
1251 bFlag=Standard_False;
1252 aCP.Range1(aTFR1, aTLR1);
1253 (aCP.Ranges2())(1).Range(aTFR2, aTLR2);
1254 //
1255 aTFrom=myCFrom.GetType();
7fd59977 1256 //
1257 aTL1=aTFR1;
1258 aTL2=aTLR1;
1259 aTC1=aTFR2;
1260 aTC2=aTLR2;
1261 if (aTFrom==GeomAbs_Circle) {
1262 aCirc=myCFrom.Circle();
1263 aLine=myCTo.Line();
1264 aTL1=aTFR2;
1265 aTL2=aTLR2;
1266 aTC1=aTFR1;
1267 aTC2=aTLR1;
1268 }
1269 else {
1270 aCirc=myCTo.Circle();
1271 aLine=myCFrom.Line();
1272 }
1273 //
1274 aPC=aCirc.Location();
1275 aRC=aCirc.Radius();
1276 //
1277 aDLC=aLine.Distance(aPC);
1278 if (fabs(aDLC-aRC)>myCriteria) {
1279 return bFlag;
1280 }
1281 //
1282 aTLx=ElCLib::Parameter(aLine, aPC);
1283 aPLx=ElCLib::Value(aTLx, aLine);
1284 aTCx=ElCLib::Parameter(aCirc, aPLx);
1285 aPCx=ElCLib::Value(aTCx, aCirc);
1286 aD2=aPLx.SquareDistance(aPCx);
1287 aC2=myCriteria*myCriteria;
1288 if (aD2>aC2) {
1289 return bFlag;
1290 }
1291 //
1292 if (aTLx<aTL1 || aTLx>aTL2) {
1293 return bFlag;
1294 }
1295 if (aTCx<aTC1 || aTCx>aTC2) {
1296 return bFlag;
1297 }
1298 //
1299 aTx1=aTLx;
1300 aTx2=aTCx;
1301 if (aTFrom==GeomAbs_Circle) {
1302 aTx1=aTCx;
1303 aTx2=aTLx;
1304 }
1305 //
1306 return !bFlag;
1307}
1308//=======================================================================
1309//function : CheckTouch
1310//purpose :
1311//=======================================================================
1312 Standard_Boolean IntTools_EdgeEdge::CheckTouch(const IntTools_CommonPrt& aCP,
1313 Standard_Real& aTx1,
1314 Standard_Real& aTx2)
1315{
1316 Standard_Real aTF1, aTL1, aTF2, aTL2, Tol, af, al,aDist2, aMinDist2;
1317 Standard_Boolean theflag=Standard_False;
1318 Standard_Integer aNbExt, i, iLower;
1319
1320 aCP.Range1(aTF1, aTL1);
1321 (aCP.Ranges2())(1).Range(aTF2, aTL2);
1322
1323 Tol = Precision::PConfusion();
1324
1325 const Handle(Geom_Curve)& Curve1 =BRep_Tool::Curve (myCFrom.Edge(), af, al);
1326 const Handle(Geom_Curve)& Curve2 =BRep_Tool::Curve (myCTo.Edge() , af, al);
1327
1328 GeomAdaptor_Curve TheCurve1 (Curve1, aTF1, aTL1);
1329 GeomAdaptor_Curve TheCurve2 (Curve2, aTF2, aTL2);
1330
1331 {
1332 Standard_Real aTol1 = TheCurve1.Resolution(myCriteria);
1333 aTol1 = (Tol < aTol1) ? Tol : aTol1;
1334
1335 Standard_Boolean isfirst = (Abs(myTminFrom - aTF1) < aTol1);
1336 Standard_Boolean islast = (Abs(myTmaxFrom - aTL1) < aTol1);
1337
1338 if(!isfirst || !islast) {
1339 if(isfirst) {
1340 aTx1 = aTF1;
7fd59977 1341 GeomAPI_ProjectPointOnCurve aProjector;
1342 aProjector.Init(Curve2, aTF2, aTL2);
1343 aProjector.Perform(Curve1->Value(aTx1));
7fd59977 1344 //
1345 if(aProjector.NbPoints() > 0)
1346 aTx2 = aProjector.LowerDistanceParameter();
1347 else {
1348 if(Curve1->Value(aTx1).Distance(Curve2->Value(aTF2)) < myCriteria)
1349 aTx2 = aTF2;
1350 else
1351 aTx2 = aTL2;
1352 }
1353 return !theflag;
1354 }
1355
1356 if(islast) {
1357 aTx1 = aTL1;
7fd59977 1358 GeomAPI_ProjectPointOnCurve aProjector;
1359 aProjector.Init(Curve2, aTF2, aTL2);
1360 aProjector.Perform(Curve1->Value(aTx1));
7fd59977 1361 if(aProjector.NbPoints() > 0)
1362 aTx2 = aProjector.LowerDistanceParameter();
1363 else {
1364 if(Curve1->Value(aTx1).Distance(Curve2->Value(aTL2)) < myCriteria)
1365 aTx2 = aTL2;
1366 else
1367 aTx2 = aTF2;
1368 }
1369 return !theflag;
1370 }
1371 }
1372 }
1373
1374 Extrema_ExtCC anExtrema (TheCurve1, TheCurve2, aTF1-Tol, aTL1+Tol, aTF2-Tol, aTL2+Tol, Tol, Tol);
1375
1376 if(!anExtrema.IsDone()) {
1377 return theflag;
1378 }
1379 if (anExtrema.IsParallel()) {
1380 return theflag;
1381 }
1382
1383 aNbExt=anExtrema.NbExt() ;
1384 if (!aNbExt) {
1385 return theflag;
1386 }
1387
1388 Standard_Boolean istouch = Standard_True;
1389 Standard_Integer avalidindex = 0;
1390
1391 iLower=1;
1392 aMinDist2=1.e100;
1393 for (i=1; i<=aNbExt; ++i) {
1394 aDist2=anExtrema.SquareDistance(i);
1395 if (aDist2 < aMinDist2) {
1396 aMinDist2=aDist2;
1397 iLower=i;
1398 }
1399
1400 if(aDist2 < myCriteria * myCriteria) {
1401 if(avalidindex) {
1402 Extrema_POnCurv aPOnC1, aPOnC2;
1403 anExtrema.Points(i, aPOnC1, aPOnC2);
1404 Standard_Real aPar1 = aPOnC1.Parameter();
1405 anExtrema.Points(avalidindex, aPOnC1, aPOnC2);
1406 Standard_Real aPar2 = aPOnC1.Parameter();
1407
1408 if(Abs(aPar1 - aPar2) > Precision::PConfusion()) {
1409 istouch = Standard_False;
1410 }
1411 }
1412 avalidindex = i;
1413 }
1414 }
1415
1416 aDist2=anExtrema.SquareDistance(iLower);
1417 if (aDist2 > myCriteria * myCriteria) {
1418 return theflag;
1419 }
1420
1421 Extrema_POnCurv aPOnC1, aPOnC2;
1422 anExtrema.Points(iLower, aPOnC1, aPOnC2);
1423
1424 aTx1=aPOnC1.Parameter();
1425 aTx2=aPOnC2.Parameter();
1426
1427 if((myCFrom.GetType() == GeomAbs_Line && myCTo.GetType() == GeomAbs_Circle) ||
1428 (myCFrom.GetType() == GeomAbs_Circle && myCTo.GetType() == GeomAbs_Line))
1429 {
1430 Standard_Real aRadius;
96a95605 1431 GeomAbs_CurveType aTFrom;
7fd59977 1432 gp_Circ aCirc;
1433 gp_Lin aLine;
1434 gp_Pnt aPCenter, aPOnLine;
1435
1436 aTFrom=myCFrom.GetType();
7fd59977 1437
1438 if (aTFrom==GeomAbs_Circle) {
1439 aCirc=myCFrom.Circle();
1440 aLine=myCTo.Line();
1441 Curve2->D0(aTx2, aPOnLine);
1442 }
1443
1444 else {
1445 aCirc=myCTo.Circle();
1446 aLine=myCFrom.Line();
1447 Curve1->D0(aTx1, aPOnLine);
1448 }
1449
1450
1451 aPCenter=aCirc.Location();
1452 aRadius =aCirc.Radius();
1453
1454 aDist2=aPOnLine.SquareDistance(aPCenter);
1455 aDist2=fabs (sqrt(aDist2)-aRadius);
1456 aDist2 *= aDist2;
1457 if (aDist2 < Tol * Tol) {
1458 return !theflag;
1459 }
1460 }
1461
1462 GeomAPI_ProjectPointOnCurve aProjector;
1463 Standard_Real aMidPar, aMidDist;
1464 aMidPar = (aTF1 + aTL1) * 0.5;
7fd59977 1465 aProjector.Init(Curve2, aTF2, aTL2);
1466 aProjector.Perform(Curve1->Value(aMidPar));
7fd59977 1467 if(aProjector.NbPoints() > 0) {
1468 aMidDist=aProjector.LowerDistance();
1469 if(aMidDist * aMidDist < aDist2 || !istouch) {
1470 aTx1 = aMidPar;
1471 aTx2 = aProjector.LowerDistanceParameter();
1472 }
1473 }
1474
1475 if (fabs (aTx1-aTF1) < Tol) {
1476 return !theflag;
1477 }
1478
1479 if (fabs (aTx1-aTL1) < Tol) {
1480 return !theflag;
1481 }
1482
1483 if (aTx1 > (aTF1-Tol) && aTx1 < (aTL1+Tol) ) {
1484 return !theflag;
1485 }
1486
1487 return theflag;
1488}
7fd59977 1489
1490//=======================================================================
1491//function : ComputeLineLine
1492//purpose :
1493//=======================================================================
1494 void IntTools_EdgeEdge::ComputeLineLine()
1495{
bd05fabf
S
1496 Standard_Boolean IsParallel, IsCoincide;
1497 Standard_Real Tolang2, Tol2;
7fd59977 1498 gp_Pnt P11, P12, P21, P22;
bd05fabf
S
1499 //
1500 myIsDone = Standard_True;
1501 //
1502 IsParallel = Standard_False;
1503 IsCoincide = Standard_False;
4e57c75e 1504 Tolang2 = Precision::Angular();
bd05fabf
S
1505 Tol2 = myCriteria*myCriteria;
1506 //
7fd59977 1507 gp_Lin C1 = myCFrom.Line();
1508 gp_Lin C2 = myCTo.Line();
1509 const gp_Dir& D1 = C1.Position().Direction();
1510 const gp_Dir& D2 = C2.Position().Direction();
1511 Standard_Real aCos = D1.Dot(D2);
1512 Standard_Real Ang2;
4e57c75e 1513
7fd59977 1514 if(aCos >= 0. ) {
1515 Ang2 = 2.*(1. - aCos);
1516 }
1517 else {
1518 Ang2 = 2.*(1. + aCos);
1519 }
1520
1521 if(Ang2 <= Tolang2) {
1522 IsParallel = Standard_True;
1523 if(C2.SquareDistance(C1.Location()) <= Tol2) {
1524 IsCoincide = Standard_True;
1525 P11 = ElCLib::Value(myTminFrom, C1);
1526 P12 = ElCLib::Value(myTmaxFrom, C1);
1527 }
1528 }
1529 else {
1530 //Check coincidence of extremity points;
1531 //Check only shortest line
1532 P11 = ElCLib::Value(myTminFrom, C1);
1533 P12 = ElCLib::Value(myTmaxFrom, C1);
1534 if(C2.SquareDistance(P11) <= Tol2 && C2.SquareDistance(P12) <= Tol2) {
1535 IsCoincide = Standard_True;
1536 }
1537 }
1538
1539 if(IsCoincide) {
1540 Standard_Real t21, t22;
1541 t21 = ElCLib::Parameter(C2, P11);
1542 t22 = ElCLib::Parameter(C2, P12);
1543
1544 if((t21 > myTmaxTo && t22 > myTmaxTo) || (t21 < myTminTo && t22 < myTminTo)) {
1545 return;
1546 }
1547
1548 Standard_Real temp;
1549 if(t21 > t22) {
1550 temp = t21;
1551 t21 = t22;
1552 t22 = temp;
1553 }
1554
1555 IntTools_CommonPrt aCommonPrt;
1556 aCommonPrt.SetEdge1(myCFrom.Edge());
1557 aCommonPrt.SetEdge2(myCTo.Edge());
1558 if(t21 >= myTminTo) {
1559 if(t22 <= myTmaxTo) {
1560 aCommonPrt.SetRange1(myTminFrom, myTmaxFrom);
1561 aCommonPrt.SetAllNullFlag(Standard_True);
1562 aCommonPrt.AppendRange2(t21, t22);
1563 }
1564 else {
1565 aCommonPrt.SetRange1(myTminFrom, myTmaxFrom - (t22 - myTmaxTo));
1566 aCommonPrt.AppendRange2(t21, myTmaxTo);
1567 }
1568 }
1569 else {
1570 aCommonPrt.SetRange1(myTminFrom + (myTminTo - t21), myTmaxFrom);
1571 aCommonPrt.AppendRange2(myTminTo, t22);
1572 }
1573 aCommonPrt.SetType(TopAbs_EDGE);
1574 mySeqOfCommonPrts.Append(aCommonPrt);
1575 return;
1576
1577 }
1578
1579 if(IsParallel) {
1580 return;
1581 }
bd05fabf 1582 //
bd05fabf
S
1583 {
1584 TopoDS_Iterator aIt1, aIt2;
1585 //
1586 aIt1.Initialize(myEdge1);
1587 for (; aIt1.More(); aIt1.Next()) {
1588 const TopoDS_Shape& aV1=aIt1.Value();
1589 aIt2.Initialize(myEdge2);
1590 for (; aIt2.More(); aIt2.Next()) {
1591 const TopoDS_Shape& aV2=aIt2.Value();
1592 if (aV2.IsSame(aV1)) {
1593 // the two straight lines have commpn vertex
1594 return;
1595 }
1596 }
1597 }
1598 }
bd05fabf 1599 //
7fd59977 1600 Standard_Real aSin2 = 1. - aCos*aCos;
1601 gp_Pnt O1 = C1.Location();
1602 gp_Pnt O2 = C2.Location();
1603 gp_Vec O1O2 (O1,O2);
1604 Standard_Real U2 = (D1.XYZ()*(O1O2.Dot(D1))-(O1O2.XYZ())).Dot(D2.XYZ());
1605 U2 /= aSin2;
1606 if(U2 < myTminTo || U2 > myTmaxTo) {
1607 return;
1608 }
1609
1610 gp_Pnt P2(ElCLib::Value(U2,C2));
1611 Standard_Real U1 = (gp_Vec(O1,P2)).Dot(D1);
1612 if(U1 < myTminFrom || U1 > myTmaxFrom) {
1613 return;
1614 }
1615
1616 gp_Pnt P1(ElCLib::Value(U1,C1));
1617 Standard_Real d2 = P1.SquareDistance(P2);
1618
1619 if(d2 > Tol2) {
1620 return;
1621 }
bd05fabf 1622 //
7fd59977 1623 IntTools_CommonPrt aCommonPrt;
1624 aCommonPrt.SetEdge1(myCFrom.Edge());
1625 aCommonPrt.SetEdge2(myCTo.Edge());
1626 aCommonPrt.SetRange1(U1 - myCriteria, U1 + myCriteria);
1627 aCommonPrt.AppendRange2(U2 - myCriteria, U2 + myCriteria);
1628 aCommonPrt.SetType(TopAbs_VERTEX);
1629 aCommonPrt.SetVertexParameter1(U1);
1630 aCommonPrt.SetVertexParameter2(U2);
1631 mySeqOfCommonPrts.Append(aCommonPrt);
1632
1633}