0024313: BRepAlgoAPI_Section and IntTools_FaceFace aren't written to handle Geom_Surf...
[occt.git] / src / IntTools / IntTools_BeanBeanIntersector.cxx
CommitLineData
b311480e 1// Copyright (c) 1999-2012 OPEN CASCADE SAS
7fd59977 2//
b311480e 3// The content of this file is subject to the Open CASCADE Technology Public
4// License Version 6.5 (the "License"). You may not use the content of this file
5// except in compliance with the License. Please obtain a copy of the License
6// at http://www.opencascade.org and read it completely before using this file.
7fd59977 7//
b311480e 8// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
7fd59977 10//
b311480e 11// The Original Code and all software distributed under the License is
12// distributed on an "AS IS" basis, without warranty of any kind, and the
13// Initial Developer hereby disclaims all such warranties, including without
14// limitation, any warranties of merchantability, fitness for a particular
15// purpose or non-infringement. Please see the License for the specific terms
16// and conditions governing the rights and limitations under the License.
17
7fd59977 18#include <IntTools_BeanBeanIntersector.ixx>
19
20#include <IntTools_Root.hxx>
21#include <Precision.hxx>
22#include <Extrema_POnCurv.hxx>
23#include <BRep_Tool.hxx>
24#include <Geom_Curve.hxx>
25#include <TColStd_Array1OfReal.hxx>
26#include <TColStd_Array1OfInteger.hxx>
27#include <IntTools_CArray1OfReal.hxx>
28#include <gp_Lin.hxx>
29#include <Intf_Array1OfLin.hxx>
30#include <Bnd_Box.hxx>
31#include <Extrema_ExtCC.hxx>
32#include <Extrema_ExtElC.hxx>
33#include <Extrema_LocateExtPC.hxx>
34#include <gp_Circ.hxx>
35#include <gp_Elips.hxx>
36#include <IntTools.hxx>
37#include <ElCLib.hxx>
38#include <Geom_Line.hxx>
39#include <GeomAdaptor_HCurve.hxx>
40
24def445 41static
42 void LocalPrepareArgs(BRepAdaptor_Curve& theCurve,
43 const Standard_Real theFirstParameter,
44 const Standard_Real theLastParameter,
45 Standard_Real& theDeflection,
46 IntTools_CArray1OfReal& theArgs);
47
48static
49 Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
50 IntTools_MarkedRangeSet& theMarkedRange);
51static
52 Standard_Integer CheckCoincidence(const Standard_Real aT11,
53 const Standard_Real aT12,
54 const Handle(Geom_Curve)& aC1,
55 const Standard_Real aT21,
56 const Standard_Real aT22,
57 const Handle(Geom_Curve)& aC2,
58 const Standard_Real aCriteria,
59 const Standard_Real aCurveResolution1,
60 GeomAPI_ProjectPointOnCurve& aProjector);
7fd59977 61
7fd59977 62
63// ==================================================================================
64// function: IntTools_BeanBeanIntersector
65// purpose:
66// ==================================================================================
67IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector() :
68
69myFirstParameter1(0.),
70myLastParameter1(0.),
71myFirstParameter2(0.),
72myLastParameter2(0.),
73myBeanTolerance1(0.),
74myBeanTolerance2(0.),
75myCurveResolution1(0.),
76myCriteria(0.),
77myIsDone(Standard_False)
78{
79}
80
81// ==================================================================================
82// function: IntTools_BeanBeanIntersector
83// purpose:
84// ==================================================================================
85IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const TopoDS_Edge& theEdge1,
86 const TopoDS_Edge& theEdge2) :
87
88myFirstParameter1(0.),
89myLastParameter1(0.),
90myFirstParameter2(0.),
91myLastParameter2(0.),
92myBeanTolerance1(0.),
93myBeanTolerance2(0.),
94myCurveResolution1(0.),
95myCriteria(0.),
96myIsDone(Standard_False)
97{
98 Init(theEdge1, theEdge2);
99}
100
101// ==================================================================================
102// function: IntTools_BeanBeanIntersector
103// purpose:
104// ==================================================================================
105IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const BRepAdaptor_Curve& theCurve1,
106 const BRepAdaptor_Curve& theCurve2,
107 const Standard_Real theBeanTolerance1,
108 const Standard_Real theBeanTolerance2) :
109
110myFirstParameter1(0.),
111myLastParameter1(0.),
112myFirstParameter2(0.),
113myLastParameter2(0.),
114myBeanTolerance1(0.),
115myBeanTolerance2(0.),
116myCurveResolution1(0.),
117myCriteria(0.),
118myIsDone(Standard_False)
119{
120 Init(theCurve1, theCurve2, theBeanTolerance1, theBeanTolerance2);
121}
122
123// ==================================================================================
124// function: IntTools_BeanBeanIntersector
125// purpose:
126// ==================================================================================
127IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const BRepAdaptor_Curve& theCurve1,
128 const BRepAdaptor_Curve& theCurve2,
129 const Standard_Real theFirstParOnCurve1,
130 const Standard_Real theLastParOnCurve1,
131 const Standard_Real theFirstParOnCurve2,
132 const Standard_Real theLastParOnCurve2,
133 const Standard_Real theBeanTolerance1,
134 const Standard_Real theBeanTolerance2) :
135
136myFirstParameter1(0.),
137myLastParameter1(0.),
138myFirstParameter2(0.),
139myLastParameter2(0.),
140myBeanTolerance1(0.),
141myBeanTolerance2(0.),
142myCurveResolution1(0.),
143myCriteria(0.),
144myIsDone(Standard_False)
145{
146 Init(theCurve1, theCurve2, theFirstParOnCurve1, theLastParOnCurve1,
147 theFirstParOnCurve2, theLastParOnCurve2,
148 theBeanTolerance1, theBeanTolerance2);
149}
150
151// ==================================================================================
152// function: Init
153// purpose:
154// ==================================================================================
155void IntTools_BeanBeanIntersector::Init(const TopoDS_Edge& theEdge1,
156 const TopoDS_Edge& theEdge2)
157{
158 myCurve1.Initialize(theEdge1);
159 myCurve2.Initialize(theEdge2);
160
161 myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf()));
162 myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf()));
163
164 SetBeanParameters(Standard_True, myCurve1.FirstParameter(), myCurve1.LastParameter());
165 SetBeanParameters(Standard_False, myCurve2.FirstParameter(), myCurve2.LastParameter());
166
167 myBeanTolerance1 = BRep_Tool::Tolerance(theEdge1);
168 myBeanTolerance2 = BRep_Tool::Tolerance(theEdge2);
169 myCriteria = myBeanTolerance1 + myBeanTolerance2;
170 myCurveResolution1 = myCurve1.Resolution(myCriteria);
171}
172
173// ==================================================================================
174// function: Init
175// purpose:
176// ==================================================================================
177void IntTools_BeanBeanIntersector::Init(const BRepAdaptor_Curve& theCurve1,
178 const BRepAdaptor_Curve& theCurve2,
179 const Standard_Real theBeanTolerance1,
180 const Standard_Real theBeanTolerance2)
181{
182 myCurve1 = theCurve1;
183 myCurve2 = theCurve2;
184
185 SetBeanParameters(Standard_True, myCurve1.FirstParameter(), myCurve1.LastParameter());
186 SetBeanParameters(Standard_False, myCurve2.FirstParameter(), myCurve2.LastParameter());
187
188 myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf()));
189 myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf()));
190
191 myBeanTolerance1 = theBeanTolerance1;
192 myBeanTolerance2 = theBeanTolerance2;
193 myCriteria = myBeanTolerance1 + myBeanTolerance2;
194 myCurveResolution1 = myCurve1.Resolution(myCriteria);
195}
196
197// ==================================================================================
198// function: Init
199// purpose:
200// ==================================================================================
201void IntTools_BeanBeanIntersector::Init(const BRepAdaptor_Curve& theCurve1,
202 const BRepAdaptor_Curve& theCurve2,
203 const Standard_Real theFirstParOnCurve1,
204 const Standard_Real theLastParOnCurve1,
205 const Standard_Real theFirstParOnCurve2,
206 const Standard_Real theLastParOnCurve2,
207 const Standard_Real theBeanTolerance1,
208 const Standard_Real theBeanTolerance2)
209{
210 myCurve1 = theCurve1;
211 myCurve2 = theCurve2;
212
213 myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf()));
214 myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf()));
215
216 SetBeanParameters(Standard_True, theFirstParOnCurve1, theLastParOnCurve1);
217 SetBeanParameters(Standard_False, theFirstParOnCurve2, theLastParOnCurve2);
218
219 myBeanTolerance1 = theBeanTolerance1;
220 myBeanTolerance2 = theBeanTolerance2;
221 myCriteria = myBeanTolerance1 + myBeanTolerance2;
222 myCurveResolution1 = myCurve1.Resolution(myCriteria);
223}
224
225// ==================================================================================
226// function: SetBeanParameters
227// purpose:
228// ==================================================================================
229void IntTools_BeanBeanIntersector::SetBeanParameters(const Standard_Boolean IsFirstBean,
230 const Standard_Real theFirstParOnCurve,
231 const Standard_Real theLastParOnCurve)
232{
233 if(IsFirstBean) {
234 myFirstParameter1 = theFirstParOnCurve;
235 myLastParameter1 = theLastParOnCurve;
236 }
237 else {
238 myFirstParameter2 = theFirstParOnCurve;
239 myLastParameter2 = theLastParOnCurve;
240 }
241}
242// ==================================================================================
243// function: Result
244// purpose:
245// ==================================================================================
246const IntTools_SequenceOfRanges& IntTools_BeanBeanIntersector::Result() const
247{
248 return myResults;
249}
250
251// ==================================================================================
252// function: Result
253// purpose:
254// ==================================================================================
255 void IntTools_BeanBeanIntersector::Result(IntTools_SequenceOfRanges& theResults) const
256{
257 theResults = myResults;
258}
259// ==================================================================================
260// function: Perform
261// purpose:
262// ==================================================================================
263void IntTools_BeanBeanIntersector::Perform()
264{
265 Standard_Boolean bFastComputed;
266 Standard_Integer k, i, iFlag, aNbRanges, aNbResults;
267 Standard_Real aMidParameter, aCoeff, aParamDist, aPPC;
268 Standard_Real aCriteria2, aD2;
269 gp_Pnt aPi, aPh;
270 IntTools_CArray1OfReal aParams;
271 IntTools_Range aRange2, aRange;
272 //
273 myIsDone = Standard_False;
274 myResults.Clear();
275 //
276 LocalPrepareArgs(myCurve1, myFirstParameter1, myLastParameter1, myDeflection, aParams);
277 //
278 myRangeManager.SetRanges(aParams, 0);
279 //
280 aNbRanges=myRangeManager.Length();
281 if(!aNbRanges) {
282 return;
283 }
284 //
285 bFastComputed=FastComputeIntersection();
286 if(bFastComputed) {
287 aRange.SetFirst(myFirstParameter1);
288 aRange.SetLast (myLastParameter1);
289 myResults.Append(aRange);
290 myIsDone = Standard_True;
291 return;
292 }
293 //
294 ComputeRoughIntersection();
295
296 //Standard_Real aMidParameter = (myFirstParameter2 + myLastParameter2) * 0.5;
297 aCoeff=0.5753;
298 aMidParameter = myFirstParameter2+(myLastParameter2-myFirstParameter2)*aCoeff;
299 //
300 for(k = 0; k < 2; ++k) {
301 if(!k) {
302 aRange2.SetFirst(myFirstParameter2);
303 aRange2.SetLast(aMidParameter);
304 }
305 else {
306 aRange2.SetFirst(aMidParameter);
307 aRange2.SetLast(myLastParameter2);
308 }
309
310 ComputeUsingExtrema(aRange2);
311
312 ComputeNearRangeBoundaries(aRange2);
313 }
314 //
315 // Legend iFlag
316 //
317 // 0 - just initialized
318 // 1 - non-intersected
319 // 2 - roughly intersected
320 // 3 - intersection is not done
321 // 4 - coincided range
322 //
323 aPPC=Precision::PConfusion();
324 aCriteria2=myCriteria*myCriteria;
325 aNbRanges=myRangeManager.Length();
326 //
327 for(i=1; i<=aNbRanges; ++i) {
328 iFlag=myRangeManager.Flag(i);
329 //
330 if(iFlag==4) {
331 aRange=myRangeManager.Range(i);
332 aNbResults=myResults.Length();
333 if(aNbResults>0) {
334 const IntTools_Range& aLastRange = myResults.Last();
335 //
336 aParamDist = Abs(aRange.First() - aLastRange.Last());
337 if(aParamDist > myCurveResolution1) {
338 myResults.Append(aRange);
339 }
340 else {
341 aPi=myCurve1.Value(aRange.First());
342 aPh=myCurve1.Value(aLastRange.Last());
343 aD2=aPi.SquareDistance(aPh);
344 if(aParamDist<aPPC || aD2<aCriteria2) {
345 myResults.ChangeValue(aNbResults).SetLast(aRange.Last());
346 }
347 else {
348 myResults.Append(aRange);
349 }
350 }
351 }// if(aNbR>0) {
352 else {
353 myResults.Append(aRange);
354 }
355 } //if(iFlag==4) {
356 } // for(i = 1; i <= myRangeManager.Length(); i++) {
357 myIsDone = Standard_True;
358}
359// ==================================================================================
360// function: FastComputeIntersection
361// purpose:
362// ==================================================================================
363Standard_Boolean IntTools_BeanBeanIntersector::FastComputeIntersection()
364{
365 Standard_Boolean aresult;
366 GeomAbs_CurveType aCT1, aCT2;
367 //
368 aresult = Standard_False;
369 //
370 aCT1=myCurve1.GetType();
371 aCT2=myCurve2.GetType();
372 //
373 if(aCT1 != aCT2) {
374 return aresult;
375 }
376 //
377 // Line
378 if(aCT1==GeomAbs_Line) {
379 Standard_Real par1, par2;
380
381 if((Distance(myFirstParameter1, par1) < myCriteria) &&
382 (Distance(myLastParameter1, par2) < myCriteria)) {
383
384 if((par1 >= myFirstParameter2) && (par1 <= myLastParameter2) &&
385 (par2 >= myFirstParameter2) && (par2 <= myLastParameter2)) {
386 myRangeManager.InsertRange(myFirstParameter1, myLastParameter1, 4);
387 aresult = Standard_True;
388 }
389 }
390 return aresult;
391 }
392 //
393 // Circle
394 if(aCT1==GeomAbs_Circle) {
395 Standard_Real anAngle, aPA, aDistLoc, aDist, aDiff, aR1, aR2;
396 gp_Circ aCirc1, aCirc2;
397 gp_Dir aDir1, aDir2;
398 //
399 aCirc1=myCurve1.Circle();
400 aCirc2=myCurve2.Circle();
401 aR1=aCirc1.Radius();
402 aR2=aCirc2.Radius();
403 //
404 aPA=Precision::Angular();
405 aDir1 = aCirc1.Axis().Direction();
406 aDir2 = aCirc2.Axis().Direction();
407 //
408 anAngle = aDir1.Angle(aDir2);
409 if(anAngle > aPA) {
410 return aresult; //->
411 }
412 //
413 const gp_Pnt& aPLoc1=aCirc1.Location();
414 const gp_Pnt& aPLoc2=aCirc2.Location();
415 aDistLoc = aPLoc1.Distance(aPLoc2);
416 aDist=aDistLoc;
417 aDiff=aR1 - aR2;
418 aDist+=Abs(aDiff);
419 if(Abs(aDist) > myCriteria) {
420 return aresult; //->
421 }
422 //
423 Standard_Real aSinPA, atmpvalue, aprojectedradius;
424 //
425 aSinPA=sin(aPA);
426 atmpvalue = aR1*aSinPA;
427 atmpvalue *= atmpvalue;
428 aprojectedradius = sqrt(aR1*aR1 - atmpvalue);
429
430 aDiff = aprojectedradius - aR2;
431 aDist = aDistLoc + sqrt((aDiff * aDiff) + atmpvalue);
432 if(Abs(aDist) > myCriteria) {
433 return aresult; //->
434 }
435 //
436 Standard_Boolean newparfound;
437 Standard_Integer i;
438 Standard_Real afirstpar, alastpar, par1, par2, apar;
439 //
440 afirstpar = myFirstParameter1;
441 alastpar = myLastParameter1;
442
443 for(i = 0; i < 2; i++) {
444 if((Distance(afirstpar, par1) < myCriteria) &&
445 (Distance(alastpar , par2) < myCriteria)) {
446
447 if(i || Distance((myFirstParameter1 + myLastParameter2) * 0.5, apar) < myCriteria) {
448 myRangeManager.InsertRange(afirstpar, alastpar, 4);
449
450 if(!i) {
451 aresult = Standard_True;
452 }
453 }
454 break;
455 }
456 //
457 if(i) {
458 break;
459 }
460 // i=0 :
461 newparfound = Standard_False;
462
463 if(Distance((myFirstParameter1 + myLastParameter2) * 0.5, apar) < myCriteria) {
464 afirstpar = myFirstParameter1 + myCriteria;
465 alastpar = myLastParameter1 - myCriteria;
466 newparfound = Standard_True;
467
468 if(alastpar <= afirstpar) {
469 newparfound = Standard_False;
470 }
471 }
24def445 472 //
7fd59977 473 if(!newparfound) {
474 break;
475 }
476 }// for(i = 0; i < 2; i++) {
477 } // if(aCT1==GeomAbs_Circle)
24def445 478 //modified by NIZNHY-PKV Mon Oct 08 14:08:19 2012f
479 if (aCT1==GeomAbs_BSplineCurve || aCT1==GeomAbs_BezierCurve) {
480 Standard_Integer iFlag;
481 //
482 iFlag=CheckCoincidence(myFirstParameter1,
483 myLastParameter1,
484 myTrsfCurve1,
485 myFirstParameter2,
486 myLastParameter2,
487 myTrsfCurve2,
488 myCriteria,
489 myCurveResolution1,
490 myProjector);
491 if (!iFlag) {
492 aresult=!aresult;
493 }
494 }
495 //modified by NIZNHY-PKV Mon Oct 08 14:08:23 2012t
7fd59977 496 return aresult;
497}
498// ==================================================================================
499// function: Distance
500// purpose:
501// ==================================================================================
502Standard_Real IntTools_BeanBeanIntersector::Distance(const Standard_Real theArg,
24def445 503 Standard_Real& theArgOnOtherBean)
7fd59977 504{
505 Standard_Real aDistance;
506 Standard_Integer aNbPoints;
507 gp_Pnt aPoint;
508 //
509 aDistance=RealLast();
510 //
511 aPoint=myCurve1.Value(theArg);
7fd59977 512 myProjector.Init(myTrsfCurve2, myFirstParameter2, myLastParameter2);
513 myProjector.Perform(aPoint);
7fd59977 514 //
515 aNbPoints=myProjector.NbPoints();
516 if(aNbPoints > 0) {
517 theArgOnOtherBean = myProjector.LowerDistanceParameter();
518 aDistance=myProjector.LowerDistance();
519 }
520 //
521 else {
522 Standard_Real aDistance1, aDistance2;
523 //
524 aDistance1 = aPoint.Distance(myCurve2.Value(myFirstParameter2));
525 aDistance2 = aPoint.Distance(myCurve2.Value(myLastParameter2));
526 //
527 theArgOnOtherBean = myLastParameter2;
528 aDistance=aDistance2;
529 if(aDistance1 < aDistance2) {
530 theArgOnOtherBean = myFirstParameter2;
531 aDistance=aDistance1;
532 }
533 }
534 return aDistance;
535}
536// ==================================================================================
537// function: ComputeRoughIntersection
538// purpose:
539// ==================================================================================
540void IntTools_BeanBeanIntersector::ComputeRoughIntersection()
541{
542 Standard_Boolean isintersection;
543 Standard_Integer i, aNbArgs, aNbArgs1, aNbRanges, j, aNbLines, k, pIt, extIt, iFlag;
544 Standard_Real aDeflection, aGPR, aCurDeflection, aT1, aT2, aD;
545 Standard_Real aMaxDistance, aDistance, aPPC, aPrm1, aPrm2, aPPA;
546 GeomAbs_CurveType aCT1, aCT2;
547 gp_Pnt aPoint1, aPoint2, aMidPOnCurve, aMidPOnLine, aP1, aP2;
548 IntTools_CArray1OfReal anArgs;
549 LocalPrepareArgs(myCurve2, myFirstParameter2, myLastParameter2, aDeflection, anArgs);
550 //
551 aNbArgs=anArgs.Length();
552 if(!aNbArgs) {
553 return;
554 }
555 //
556 aCT1=myCurve1.GetType();
557 aCT2=myCurve2.GetType();
558 aGPR=gp::Resolution();
559 aPPC=Precision::PConfusion();
560 aPPA=Precision::Angular();
561 aNbArgs1=aNbArgs-1;
562 //
563 Intf_Array1OfLin aLines(1, aNbArgs1);
564 TColStd_Array1OfInteger aLineFlags(1, aNbArgs1);
565 TColStd_Array1OfReal aDistances(1, aNbArgs1);
566 //
567 aT1=anArgs(0);
568 aPoint1 = myCurve2.Value(aT1);
569 for(i=1; i<aNbArgs; ++i) {
570 aT2=anArgs(i);
571 aPoint2 = myCurve2.Value(aT2);
572 gp_Vec aVec(aPoint1, aPoint2);
573 aD=aVec.Magnitude();
574 aDistances.SetValue(i, aD);
575 //
576 if(aD<=aGPR) {
577 aLineFlags.SetValue(i, 0);
578 }
579 else {
580 aLineFlags.SetValue(i, 1);
581 gp_Lin aLine(aPoint1, gp_Dir(aVec));
582 aLines.SetValue(i, aLine);
583 //
584 if((aCT2 == GeomAbs_BezierCurve) ||
585 (aCT2 == GeomAbs_BSplineCurve)) {
586 aMidPOnCurve = myCurve2.Value((aT1+aT2) * 0.5);
587 aMidPOnLine = ElCLib::Value((aDistances(i)*0.5), aLine);
588 aCurDeflection = aMidPOnCurve.Distance(aMidPOnLine);
589 if(aCurDeflection > aDeflection) {
590 aDeflection = aCurDeflection;
591 }
592 }
593 }
594 aT1=aT2;
595 aPoint1 = aPoint2;
596 }
597 //
598 aNbLines=aLines.Upper();
599 aMaxDistance = myCriteria + myDeflection + aDeflection;
600
601 aT1=myRangeManager.Range(1).First();
602 aPoint1 = myCurve1.Value(aT1);
603 aNbRanges=myRangeManager.Length();
604 for(i = 1; i <= aNbRanges; ++i) {
605 const IntTools_Range& aRange = myRangeManager.Range(i);
606 aT2=aRange.Last();
607 aPoint2 = myCurve1.Value(aT2);
608 //
609 iFlag=myRangeManager.Flag(i);
610 if(iFlag==4) {// coincided
611 aT1=aT2;
612 aPoint1 = aPoint2;
613 continue;
614 }
615 //
616 myRangeManager.SetFlag(i, 1); // not intersected
617
618 Bnd_Box aBox1;
619 aBox1.Add(aPoint1);
620 aBox1.Add(aPoint2);
621 aBox1.Enlarge(myBeanTolerance1 + myDeflection);
622
623 gp_Vec aVec(aPoint1, aPoint2);
624
625 aDistance=aVec.Magnitude();
626 if(aDistance <= aGPR) {
627 myRangeManager.SetFlag(i, 0);
628 continue;
629 }
630 //
631 gp_Lin aLine(aPoint1, gp_Dir(aVec));
632 //
633 if((aCT1 == GeomAbs_BezierCurve) ||
634 (aCT1 == GeomAbs_BSplineCurve)) {
635 aMidPOnCurve = myCurve1.Value((aRange.First() + aRange.Last()) * 0.5);
636 aMidPOnLine = ElCLib::Value((aDistance*0.5), aLine);
637 aCurDeflection = aMidPOnCurve.Distance(aMidPOnLine);
638 if(myDeflection < aCurDeflection) {
639 aMaxDistance += aCurDeflection - myDeflection;
640 myDeflection = aCurDeflection;
641 }
642 }
643 //
644 for(j=1; j<=aNbLines; ++j) {
645 if(!aLineFlags(j)) {
646 myRangeManager.SetFlag(i, 0);
647 continue;
648 }
649 //
650 const gp_Lin& aL2=aLines(j);
651 //Handle(Geom_Line) aC2=new Geom_Line(aL2); // DEB ft
652 aD=aDistances(j);
653 aP1=ElCLib::Value(0., aL2);
654 aP2=ElCLib::Value(aD, aL2);
655 //
656 Extrema_ExtElC anExtrema(aLine, aL2, aPPA);
657 if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) {
658 isintersection = Standard_False;
659
660 if(anExtrema.IsParallel()) {
661 isintersection = (anExtrema.SquareDistance(1) < aMaxDistance * aMaxDistance);
662 }
663 else { //1
664 for(k = 1; !isintersection && k <= anExtrema.NbExt(); ++k) {
665 if(anExtrema.SquareDistance(k) < aMaxDistance * aMaxDistance) {
666 Extrema_POnCurv P1, P2;
667 anExtrema.Points(k, P1, P2);
668 aPrm1=P1.Parameter();
669 aPrm2=P2.Parameter();
670 if((aPrm1 >= -aMaxDistance) && (aPrm1 <= aDistance+aMaxDistance) &&
671 (aPrm2 >= -aMaxDistance) && (aPrm2 <= aD+aMaxDistance)) {
672 isintersection = Standard_True;
673 }
674 else { // 2
675 Extrema_ExtPElC aPointProjector;
676
677 for(pIt = 0; !isintersection && (pIt < 4); ++pIt) {
678 switch (pIt) {
679 case 0: {
680 aPointProjector =
681 //Extrema_ExtPElC(aPoint1, aLines(j), aPPC, 0., aDistances(j));
682 Extrema_ExtPElC(aPoint1, aL2, aPPC, -aMaxDistance, aD+aMaxDistance);
683 break;
684 }
685 case 1: {
686 aPointProjector =
687 //Extrema_ExtPElC(aPoint2, aLines(j), aPPC, 0., aD);
688 Extrema_ExtPElC(aPoint2, aL2, aPPC, -aMaxDistance, aD+aMaxDistance);
689 break;
690 }
691 case 2: {
692 aPointProjector =
693 //Extrema_ExtPElC(ElCLib::Value(0., aLines(j)), aLine, aPPC, 0., aDistance);
694 Extrema_ExtPElC(aP1, aLine, aPPC, -aMaxDistance, aDistance+aMaxDistance);
695 break;
696 }
697 case 3: {
698 aPointProjector =
699 //Extrema_ExtPElC(ElCLib::Value(aDistances(j), aLines(j)), aLine, aPPC, 0., aDistance);
700 Extrema_ExtPElC(aP2, aLine, aPPC, -aMaxDistance, aDistance+aMaxDistance);
701 break;
702 }
703 default: {
704 break;
705 }
706 }
707 //
708 if(aPointProjector.IsDone()) {
709 Standard_Real aMaxDistance2 = aMaxDistance * aMaxDistance;
710 for(extIt = 1; extIt <= aPointProjector.NbExt(); extIt++) {
711 if(aPointProjector.SquareDistance(extIt) < aMaxDistance2) {
712 isintersection = Standard_True;
713 }
714 }
715 }
716 } // end for
717 }// else { // 2
718 }//if(anExtrema.Value(k) < aMaxDistance) {
719 }//for(k = 1; !isintersection && k <= anExtrema.NbExt(); k++) {
720 }//else { //1
721
722 if(isintersection) {
723 myRangeManager.SetFlag(i, 2); // roughly intersected
724 break;
725 }
726 }//if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) {
727 else {
728 Bnd_Box aBox2;
729 aBox2.Add(myCurve2.Value(anArgs(j-1)));
730 aBox2.Add(myCurve2.Value(anArgs(j)));
731 aBox2.Enlarge(myBeanTolerance2 + aDeflection);
732 //
733 if(!aBox1.IsOut(aBox2)) {
734 myRangeManager.SetFlag(i, 2); // roughly intersected
735 break;
736 }
737 }
738 }
739 aT1=aT2;
740 aPoint1 = aPoint2;
741 }
742}
743
744// ==================================================================================
745// function: ComputeUsingExtrema
746// purpose:
747// ==================================================================================
748void IntTools_BeanBeanIntersector::ComputeUsingExtrema(const IntTools_Range& theRange2)
749{
750 //rln Dec 2008.
751 //Extrema_ExtCC is reused throughout this method to store caches computed on
752 //theRange2. However it is actually used only in a few calls of
753 //ComputeUsingExtrema(), so using a default constructor would add unnecessary overhead
754 //of initialization its internal fields. Since it is not manipulated by Handle then
755 //we will use a pointer to it and initialize it only when needed.
756 Extrema_ExtCC *apExtrema = 0;
757 Handle(GeomAdaptor_HCurve) aHCurve1, aHCurve2; //will be initialized later, only if needed
758 //handles are used to guard pointers to GeomAdaptor_Curve inside Extrema
759 Standard_Real aCriteria2 = myCriteria * myCriteria;
760 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
761
762 if(myRangeManager.Flag(i) == 2 || myRangeManager.Flag(i) == 0) {
763 const IntTools_Range& aParamRange = myRangeManager.Range(i);
764
765 if(aParamRange.Last() - aParamRange.First() < Precision::PConfusion()) {
766
767 if(((i > 1) && (myRangeManager.Flag(i-1) == 4)) ||
768 ((i < myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 4))) {
769 myRangeManager.SetFlag(i, 4);
770 continue;
771 }
772 }
773 if (aHCurve2.IsNull()) {
774 //initialize only once
775 apExtrema = new Extrema_ExtCC;
776 Standard_Real ftmp = theRange2.First() - Precision::PConfusion();
777 Standard_Real ltmp = theRange2.Last() + Precision::PConfusion();
778 ftmp = (ftmp < myFirstParameter2) ? myFirstParameter2 : ftmp;
779 ltmp = (ltmp > myLastParameter2) ? myLastParameter2 : ltmp;
780 aHCurve2 = new GeomAdaptor_HCurve (myTrsfCurve2, ftmp, ltmp);
781 apExtrema->SetCurve (2, aHCurve2->Curve(), theRange2.First(), theRange2.Last());
782 }
783 Extrema_ExtCC& anExtrema = *apExtrema;
784
785 Standard_Real ftmp = aParamRange.First() - Precision::PConfusion();
786 Standard_Real ltmp = aParamRange.Last() + Precision::PConfusion();
787 ftmp = (ftmp < myFirstParameter1) ? myFirstParameter1 : ftmp;
788 ltmp = (ltmp > myLastParameter1) ? myLastParameter1 : ltmp;
789 aHCurve1 = new GeomAdaptor_HCurve (myTrsfCurve1, ftmp, ltmp);
790 anExtrema.SetCurve (1, aHCurve1->Curve(), aParamRange.First(), aParamRange.Last());
791
792 anExtrema.Perform();
793
794 if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) {
795 Standard_Integer anOldNbRanges = myRangeManager.Length();
796
797 if (anExtrema.IsParallel()) {
798 if(anExtrema.SquareDistance(1) < aCriteria2) {
799 Standard_Real theParameter1, theParameter2;
800 Standard_Real adistance1 = Distance(aParamRange.First(), theParameter1);
801 Standard_Real adistance2 = Distance(aParamRange.Last(), theParameter2);
802 Standard_Boolean validdistance1 = (adistance1 < myCriteria);
803 Standard_Boolean validdistance2 = (adistance2 < myCriteria);
804
805 if (validdistance1 && validdistance2) {
806 myRangeManager.InsertRange(aParamRange.First(), aParamRange.Last(), 4);
807 continue;
808 }
809 else {
810 if(validdistance1) {
811 ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), i, theParameter1, theRange2);
812 }
813 else {
814 if(validdistance2) {
815 ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), i, theParameter2, theRange2);
816 }
817 else {
818 Standard_Real a = aParamRange.First();
819 Standard_Real b = aParamRange.Last();
820 Standard_Real da = adistance1;
821 Standard_Real db = adistance2;
822 Standard_Real asolution = a;
823 Standard_Boolean found = Standard_False;
824
825 while(((b - a) > myCurveResolution1) && !found) {
826 asolution = (a+b)*0.5;
827 Standard_Real adist = Distance(asolution, theParameter1);
828
829 if(adist < myCriteria) {
830 found = Standard_True;
831 }
832 else {
833 if(da < db) {
834 b = asolution;
835 db = adist;
836 }
837 else {
838 a = asolution;
839 da = adist;
840 }
841 }
842 } // end while
843
844 if(found) {
845 ComputeRangeFromStartPoint(Standard_False, asolution, i, theParameter1, theRange2);
846 ComputeRangeFromStartPoint(Standard_True, asolution, i, theParameter1, theRange2);
847 }
848 else {
849 myRangeManager.SetFlag(i, 2);
850 }
851 }
852 }
853 }
854 }
855 }
856 else {
857
858 for(Standard_Integer j = 1 ; j <= anExtrema.NbExt(); j++) {
859 if(anExtrema.SquareDistance(j) < aCriteria2) {
860 Extrema_POnCurv p1, p2;
861 anExtrema.Points(j, p1, p2);
862
863 Standard_Integer aNbRanges = myRangeManager.Length();
864
865 Standard_Integer anIndex = myRangeManager.GetIndex(p1.Parameter(), Standard_False);
866 if(anIndex > 0) {
867 ComputeRangeFromStartPoint(Standard_False, p1.Parameter(), anIndex, p2.Parameter(), theRange2);
868 }
869
870 anIndex = myRangeManager.GetIndex(p1.Parameter(), Standard_True);
871
872 if(anIndex > 0) {
873 ComputeRangeFromStartPoint(Standard_True, p1.Parameter(), anIndex, p2.Parameter(), theRange2);
874 }
875
876 if(aNbRanges == myRangeManager.Length()) {
877 SetEmptyResultRange(p1.Parameter(), myRangeManager);
878 }
879 }
880 } // end for
881 }
882 Standard_Integer adifference = myRangeManager.Length() - anOldNbRanges;
883
884 if(adifference > 0) {
885 i+=adifference;
886 }
887 }
888 else {
889 myRangeManager.SetFlag(i, 3); // intersection not done.
890 }
891 }
892 }
893 if (apExtrema) delete apExtrema;
894}
895
896// ==================================================================================
897// function: ComputeNearRangeBoundaries
898// purpose:
899// ==================================================================================
900void IntTools_BeanBeanIntersector::ComputeNearRangeBoundaries(const IntTools_Range& theRange2)
901{
902 Standard_Real theParameter = theRange2.First();
903
904 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
905 if(myRangeManager.Flag(i) != 3)
906 continue;
907
908 if((i > 1) && ((myRangeManager.Flag(i-1) == 1) || (myRangeManager.Flag(i-1) == 4))) {
909 myRangeManager.SetFlag(i, 2);
910 continue;
911 }
912
913 const IntTools_Range& aParamRange = myRangeManager.Range(i);
914
915 if(Distance(aParamRange.First(), theParameter) < myCriteria) {
916 Standard_Integer aNbRanges = myRangeManager.Length();
917
918 if(i > 1) {
919 ComputeRangeFromStartPoint(Standard_False, aParamRange.First(), i-1, theParameter, theRange2);
920 }
921 ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), i + (myRangeManager.Length() - aNbRanges), theParameter, theRange2);
922
923 if(aNbRanges == myRangeManager.Length()) {
924 SetEmptyResultRange(aParamRange.First(), myRangeManager);
925 }
926 }
927 else {
928 myRangeManager.SetFlag(i, 2);
929 }
930 }
931
932 if((myRangeManager.Flag(myRangeManager.Length()) == 3) ||
933 (myRangeManager.Flag(myRangeManager.Length()) == 2)) {
934 const IntTools_Range& aParamRange = myRangeManager.Range(myRangeManager.Length());
935
936 if(Distance(aParamRange.Last(), theParameter) < myCriteria) {
937 Standard_Integer aNbRanges = myRangeManager.Length();
938 myRangeManager.SetFlag(myRangeManager.Length(), 2);
939
940 ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), myRangeManager.Length(), theParameter, theRange2);
941
942 if(aNbRanges == myRangeManager.Length()) {
943 SetEmptyResultRange(aParamRange.Last(), myRangeManager);
944 }
945 }
946 else {
947 myRangeManager.SetFlag(myRangeManager.Length(), 2);
948 }
949 }
950}
951
952// ==================================================================================
953// function: ComputeRangeFromStartPoint
954// purpose:
955// ==================================================================================
956void IntTools_BeanBeanIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
957 const Standard_Real theParameter,
958 const Standard_Integer theIndex,
959 const Standard_Real theParameter2,
960 const IntTools_Range& theRange2)
961{
962
963 if(myRangeManager.Flag(theIndex) == 4 ||
964 myRangeManager.Flag(theIndex) == 1)
965 return;
966
967 Standard_Integer aValidIndex = theIndex;
968 Standard_Real aMinDelta = myCurveResolution1 * 0.5;
969 Standard_Real aDeltaRestrictor = myLastParameter1 - myFirstParameter1;
970
971 if(Abs(aDeltaRestrictor) < Precision::PConfusion()) {
972 return;
973 }
974
975 if(aMinDelta > aDeltaRestrictor) {
976 aMinDelta = aDeltaRestrictor;
977 }
978 Standard_Real tenOfMinDelta = aMinDelta * 10.;
979 Standard_Real aDelta = myCurveResolution1;
980 Standard_Real aCurPar = (ToIncreaseParameter) ? (theParameter + aDelta) : (theParameter - aDelta);
981 Standard_Real aPrevPar = theParameter;
982 IntTools_Range aCurrentRange = myRangeManager.Range(aValidIndex);
983
984 Standard_Boolean BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
985
986 if(BoundaryCondition) {
987 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
988 BoundaryCondition = Standard_False;
989 }
990
991 Standard_Integer loopcounter = 0; // neccesary to have no infinite loop
992 Standard_Real aParameter = theParameter2;
993 Standard_Boolean anotherSolutionFound = Standard_False;
994
995 Standard_Boolean isboundaryindex = Standard_False;
996 Standard_Boolean isvalidindex = Standard_True;
997
998 Standard_Real aCriteria2 = myCriteria * myCriteria;
999
1000 while((aDelta >= aMinDelta) && (loopcounter <= 10)) {
1001 Standard_Boolean pointfound = Standard_False;
1002
1003 gp_Pnt aPoint = myCurve1.Value(aCurPar);
1004 GeomAdaptor_Curve aCurve2(myTrsfCurve2, theRange2.First(), theRange2.Last());
1005
1006 Extrema_LocateExtPC anExtrema(aPoint, aCurve2, aParameter, theRange2.First(), theRange2.Last(), 1.e-10);
1007
1008 if(anExtrema.IsDone()) {
1009 if(anExtrema.SquareDistance() < aCriteria2) {
1010 Extrema_POnCurv aPOnCurv = anExtrema.Point();
1011 aParameter = aPOnCurv.Parameter();
1012 pointfound = Standard_True;
1013 }
1014 }
1015 else {
1016 // pointfound = (Distance(aCurPar, aParameter) < myCriteria);
1017 Standard_Real afoundparam = aParameter;
1018
1019 if(Distance(aCurPar, afoundparam) < myCriteria) {
1020 aParameter = afoundparam;
1021 pointfound = Standard_True;
1022 }
1023 }
1024
1025 if(pointfound) {
1026 aPrevPar = aCurPar;
1027 anotherSolutionFound = Standard_True;
1028
1029 if(BoundaryCondition && (isboundaryindex || !isvalidindex))
1030 break;
1031 }
1032 else {
1033 aDeltaRestrictor = aDelta;
1034 }
1035
1036 // if pointfound decide to increase aDelta using derivative of distance function
1037 //
1038
1039 aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5);
1040 aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor;
1041 aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta);
1042
1043 BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1044
1045 isboundaryindex = Standard_False;
1046 isvalidindex = Standard_True;
1047
1048 if(BoundaryCondition) {
1049 isboundaryindex = ((!ToIncreaseParameter && (aValidIndex == 1)) ||
1050 (ToIncreaseParameter && (aValidIndex == myRangeManager.Length())));
1051
1052 if(!isboundaryindex) {
1053 if(pointfound) {
1054 Standard_Integer aFlag = (ToIncreaseParameter) ? myRangeManager.Flag(aValidIndex + 1) : myRangeManager.Flag(aValidIndex - 1);
1055
1056 if(aFlag != 1 && aFlag != 4) {
1057 aValidIndex = (ToIncreaseParameter) ? (aValidIndex + 1) : (aValidIndex - 1);
1058 aCurrentRange = myRangeManager.Range(aValidIndex);
1059
1060 if((ToIncreaseParameter && (aCurPar > aCurrentRange.Last())) ||
1061 (!ToIncreaseParameter && (aCurPar < aCurrentRange.First()))) {
1062 aCurPar = (aCurrentRange.First() + aCurrentRange.Last()) * 0.5;
1063 aDelta*=0.5;
1064 }
1065 }
1066 else {
1067 isvalidindex = Standard_False;
1068 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1069 }
1070 }
1071 }
1072 else {
1073 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1074 }
1075
1076 if(aDelta < tenOfMinDelta) {
1077 loopcounter++;
1078 }
1079 else {
1080 loopcounter = 0;
1081 }
1082 } // end if(BoundaryCondition)
1083 }
1084
1085 if(anotherSolutionFound) {
1086 if(ToIncreaseParameter)
1087 myRangeManager.InsertRange(theParameter, aPrevPar, 4);
1088 else
1089 myRangeManager.InsertRange(aPrevPar, theParameter, 4);
1090 }
1091}
1092
1093// ---------------------------------------------------------------------------------
1094// static function: LocalPrepareArgs
1095// purpose:
1096// ---------------------------------------------------------------------------------
1097static void LocalPrepareArgs(BRepAdaptor_Curve& theCurve,
1098 const Standard_Real theFirstParameter,
1099 const Standard_Real theLastParameter,
1100 Standard_Real& theDeflection,
1101 IntTools_CArray1OfReal& theArgs) {
1102 Standard_Integer aDiscretization = 30;
1103 Standard_Real aRelativeDeflection = 0.01;
1104 theDeflection = aRelativeDeflection;
1105 Standard_Boolean prepareargs = Standard_True;
1106
1107 switch(theCurve.GetType()) {
1108 case GeomAbs_Line: {
1109 prepareargs = Standard_False;
1110 aDiscretization = 3;
1111 theArgs.Append(theFirstParameter);
1112
1113 if((theLastParameter - theFirstParameter) > Precision::PConfusion()) {
1114 theArgs.Append((theFirstParameter + theLastParameter)*0.5);
1115 }
1116 theArgs.Append(theLastParameter);
1117 theDeflection = Precision::Confusion();
1118 break;
1119 }
1120 case GeomAbs_Circle: {
1121 aDiscretization = 23;
1122 theDeflection = aRelativeDeflection * theCurve.Circle().Radius();
1123 break;
1124 }
1125 case GeomAbs_Ellipse: {
1126 aDiscretization = 40;
1127 theDeflection = 2 * aRelativeDeflection * theCurve.Ellipse().MajorRadius();
1128 break;
1129 }
1130 case GeomAbs_Hyperbola:
1131 case GeomAbs_Parabola: {
1132 aDiscretization = 40;
1133 theDeflection = aRelativeDeflection;
1134 break;
1135 }
1136 case GeomAbs_BezierCurve: {
1137 aDiscretization = 30;
1138 theDeflection = aRelativeDeflection;
1139 break;
1140 }
1141 case GeomAbs_BSplineCurve: {
1142 aDiscretization = 30;
1143 theDeflection = aRelativeDeflection;
1144 break;
1145 }
1146 default: {
1147 aDiscretization = 30;
1148 theDeflection = aRelativeDeflection;
1149 }
1150 }
1151
1152 if(prepareargs) {
1153 IntTools::PrepareArgs(theCurve, theLastParameter, theFirstParameter, aDiscretization, aRelativeDeflection, theArgs);
1154 }
1155}
7fd59977 1156// ---------------------------------------------------------------------------------
1157// static function: SetEmptyResultRange
1158// purpose:
1159// ---------------------------------------------------------------------------------
1160static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
1161 IntTools_MarkedRangeSet& theMarkedRange) {
1162
1163 const TColStd_SequenceOfInteger& anIndices = theMarkedRange.GetIndices(theParameter);
1164 Standard_Boolean add = (anIndices.Length() > 0);
1165
1166 for(Standard_Integer k = 1; k <= anIndices.Length(); k++) {
1167 if(theMarkedRange.Flag(anIndices(k)) == 4) {
1168 add = Standard_False;
1169 break;
1170 }
1171 }
1172
1173 if(add) {
1174 theMarkedRange.InsertRange(theParameter, theParameter, 4);
1175 }
1176
1177 return add;
1178}
24def445 1179//modified by NIZNHY-PKV Fri Oct 12 09:34:10 2012f
1180static
1181 Standard_Integer DistPC(const Standard_Real aT1,
1182 const Handle(Geom_Curve)& aC1,
1183 const Standard_Real aCriteria,
1184 GeomAPI_ProjectPointOnCurve& aProjector,
1185 Standard_Real& aD,
1186 Standard_Real& aT2);
1187
1188
1189static
1190 Standard_Integer DistPC(const Standard_Real aT1,
1191 const Handle(Geom_Curve)& aC1,
1192 const Standard_Real aCriteria,
1193 GeomAPI_ProjectPointOnCurve& aProjector,
1194 Standard_Real& aD,
1195 Standard_Real& aT2,
1196 Standard_Real& aDmax,
1197 Standard_Real& aTmax);
1198
1199static
1200 Standard_Integer FindMaxDistPC(const Standard_Real aT1A,
1201 const Standard_Real aT1B,
1202 const Handle(Geom_Curve)& aC1,
1203 const Standard_Real aCriteria,
1204 const Standard_Real aEps1,
1205 GeomAPI_ProjectPointOnCurve& aProjector,
1206 Standard_Real& aDmax,
1207 Standard_Real& aT1max);
1208
1209//=======================================================================
1210//function : CheckCoincidence
1211//purpose :
1212//=======================================================================
1213Standard_Integer CheckCoincidence(const Standard_Real aT11,
1214 const Standard_Real aT12,
1215 const Handle(Geom_Curve)& aC1,
1216 const Standard_Real aT21,
1217 const Standard_Real aT22,
1218 const Handle(Geom_Curve)& aC2,
1219 const Standard_Real aCriteria,
1220 const Standard_Real aEps1,
1221 GeomAPI_ProjectPointOnCurve& aProjector)
1222{
1223 Standard_Integer iErr, aNb1, i, aNbX;
b9736bcc 1224 Standard_Real dT1, aT1, aT2, aD, aDmax, aTmax;
24def445 1225 Standard_Real aT1A, aT1B, aD1max,aT1max;
1226 //
1227 iErr=0; // the patches are coincided
1228 //
1229 //
1230 aProjector.Init(aC2, aT21, aT22);
1231 //
1232 aDmax=-1.;
1233 //
1234 // 1. Express evaluation
1235 //
1236 aNb1=10; // Number of intervals on the curve #1
1237 dT1=(aT12-aT11)/aNb1;
1238 for (i=1; i<aNb1; ++i) {
1239 aT1=aT11+i*dT1;
1240 //
1241 iErr=DistPC(aT1, aC1, aCriteria, aProjector, aD, aT2, aDmax, aTmax);
1242 if (iErr) {
1243 iErr=1;// a point from aC1 can not be projected on aC2
1244 return iErr;
1245 }
1246 //
1247 if (aDmax>aCriteria) {
1248 iErr=2; // the distance is too big
1249 return iErr;
1250 }
1251 }
1252 //
1253 // 2. Deep evaluation
1254 aD1max=aDmax;
1255 //
1256 aNbX=aNb1-1;
1257 for (i=1; i<aNbX; ++i) {
1258 aT1A=aT11+i*dT1;
1259 aT1B=aT1A+dT1;
1260 //
1261 iErr=FindMaxDistPC(aT1A, aT1B, aC1, aCriteria, aEps1, aProjector, aD1max, aT1max);
1262 if (iErr) {
1263 iErr=1;
1264 return iErr;
1265 }
1266 }
1267 //
1268 return iErr;
1269}
1270//
1271//=======================================================================
1272//function : FindMaxDistPC
1273//purpose :
1274//=======================================================================
1275Standard_Integer FindMaxDistPC(const Standard_Real aT1A,
1276 const Standard_Real aT1B,
1277 const Handle(Geom_Curve)& aC1,
1278 const Standard_Real aCriteria,
1279 const Standard_Real aEps1,
1280 GeomAPI_ProjectPointOnCurve& aProjector,
1281 Standard_Real& aDmax,
1282 Standard_Real& aT1max)
1283{
1284 Standard_Integer iErr, iCnt;
1285 Standard_Real aGS, aXP, aA, aB, aXL, aYP, aYL, aT2P, aT2L, aX0;
1286 //
1287 iCnt=0;
1288 iErr=0;
1289 aDmax=0.;
1290 //
1291 aGS=0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))-1.;
1292 aA=aT1A;
1293 aB=aT1B;
1294 //
1295 aXP=aA+(aB-aA)*aGS;
1296 aXL=aB-(aB-aA)*aGS;
1297 //
1298 iErr=DistPC(aXP, aC1, aCriteria, aProjector, aYP, aT2P, aDmax, aT1max);
1299 if(iErr){
1300 return iErr;
1301 }
1302 //
1303 iErr=DistPC(aXL, aC1, aCriteria, aProjector, aYL, aT2L, aDmax, aT1max);
1304 if(iErr){
1305 return iErr;
1306 }
1307 //
302f96fb 1308 for(;;) {
24def445 1309 if (aYP>aYL) {
1310 aA=aXL;
1311 aXL=aXP;
1312 aYL=aYP;
1313 aXP=aA+(aB-aA)*aGS;
1314 iErr=DistPC(aXP, aC1, aCriteria, aProjector, aYP, aT2P, aDmax, aT1max);
1315 if(iErr){
1316 return iErr;
1317 }
1318 }
1319 else {
1320 aB=aXP;
1321 aXP=aXL;
1322 aYP=aYL;
1323 aXL=aB-(aB-aA)*aGS;
1324 iErr=DistPC(aXL, aC1, aCriteria, aProjector, aYL, aT2L, aDmax, aT1max);
1325 if(iErr){
1326 return iErr;
1327 }
1328 }
1329 //
1330 if ((aB-aA)<aEps1) {
1331 aX0=0.5*(aA+aB);
1332 break;
1333 }
1334 }// while(1) {
1335 //
1336 return iErr;
1337}
1338//=======================================================================
1339//function : DistPC
1340//purpose :
1341//=======================================================================
1342Standard_Integer DistPC(const Standard_Real aT1,
1343 const Handle(Geom_Curve)& aC1,
1344 const Standard_Real aCriteria,
1345 GeomAPI_ProjectPointOnCurve& aProjector,
1346 Standard_Real& aD,
1347 Standard_Real& aT2,
1348 Standard_Real& aDmax,
1349 Standard_Real& aTmax)
1350{
1351 Standard_Integer iErr;
1352 //
1353 iErr=DistPC(aT1, aC1, aCriteria, aProjector, aD, aT2);
1354 if (iErr) {
1355 return iErr;
1356 }
1357 //
1358 if (aD>aDmax) {
1359 aDmax=aD;
1360 aTmax=aT2;
1361 }
1362 //
1363 return iErr;
1364}
1365//=======================================================================
1366//function : DistPC
1367//purpose :
1368//=======================================================================
1369Standard_Integer DistPC(const Standard_Real aT1,
1370 const Handle(Geom_Curve)& aC1,
1371 const Standard_Real aCriteria,
1372 GeomAPI_ProjectPointOnCurve& aProjector,
1373 Standard_Real& aD,
1374 Standard_Real& aT2)
1375{
1376 Standard_Integer iErr, aNbP2;
1377 gp_Pnt aP1;
1378 //
1379 iErr=0;
1380 aC1->D0(aT1, aP1);
1381 //
1382 aProjector.Perform(aP1);
1383 aNbP2=aProjector.NbPoints();
1384 if (!aNbP2) {
1385 iErr=1;// the point from aC1 can not be projected on aC2
1386 return iErr;
1387 }
1388 //
1389 aD=aProjector.LowerDistance();
1390 aT2=aProjector.LowerDistanceParameter();
1391 if (aD>aCriteria) {
1392 iErr=2;// the distance is too big
1393 }
1394 //
1395 return iErr;
1396}
1397//modified by NIZNHY-PKV Fri Oct 12 09:34:12 2012t