0025337: Regression to version 6.7.1 : boolean operations fail on two planar circular...
[occt.git] / src / IntTools / IntTools_EdgeEdge.cxx
CommitLineData
ec0cdc0e 1// Created by: Eugeny MALTCHIKOV
d5f74e42 2// Copyright (c) 2013-2014 OPEN CASCADE SAS
7fd59977 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
ec0cdc0e 15#include <IntTools_EdgeEdge.ixx>
7fd59977 16
7fd59977 17#include <gp_Dir.hxx>
ec0cdc0e 18#include <gp_Lin.hxx>
7fd59977 19
fa9681ca 20#include <ElCLib.hxx>
fa9681ca 21
ec0cdc0e 22#include <TopoDS_Iterator.hxx>
7fd59977 23
ec0cdc0e 24#include <Bnd_Box.hxx>
25#include <BndLib_Add3dCurve.hxx>
fa9681ca 26
a4e383e1 27#include <Geom_Circle.hxx>
28#include <Geom_Ellipse.hxx>
29#include <Geom_BezierCurve.hxx>
30#include <Geom_BSplineCurve.hxx>
31
fa9681ca
P
32#include <GeomAPI_ProjectPointOnCurve.hxx>
33
fa9681ca 34#include <BRep_Tool.hxx>
ec0cdc0e 35#include <BRepAdaptor_Curve.hxx>
fa9681ca 36
ec0cdc0e 37#include <IntTools_CommonPrt.hxx>
7fd59977 38
3e594885 39#include <BOPCol_MapOfInteger.hxx>
6b1fe48c 40
ec0cdc0e 41static
42 void BndBuildBox(const BRepAdaptor_Curve& theBAC,
43 const Standard_Real aT1,
44 const Standard_Real aT2,
45 const Standard_Real theTol,
46 Bnd_Box& theBox);
6b1fe48c 47static
48 Standard_Real PointBoxDistance(const Bnd_Box& aB,
49 const gp_Pnt& aP);
ec0cdc0e 50static
6b1fe48c 51 void SplitRangeOnSegments(const Standard_Real aT1,
52 const Standard_Real aT2,
53 const Standard_Real theResolution,
54 const Standard_Integer theNbSeg,
55 IntTools_SequenceOfRanges& theSegments);
ec0cdc0e 56static
57 Standard_Integer DistPC(const Standard_Real aT1,
58 const Handle(Geom_Curve)& theC1,
59 const Standard_Real theCriteria,
60 GeomAPI_ProjectPointOnCurve& theProjector,
61 Standard_Real& aD,
62 Standard_Real& aT2,
63 const Standard_Integer iC = 1);
64static
65 Standard_Integer DistPC(const Standard_Real aT1,
66 const Handle(Geom_Curve)& theC1,
67 const Standard_Real theCriteria,
68 GeomAPI_ProjectPointOnCurve& theProjector,
69 Standard_Real& aD,
70 Standard_Real& aT2,
71 Standard_Real& aDmax,
72 Standard_Real& aT1max,
73 Standard_Real& aT2max,
74 const Standard_Integer iC = 1);
75static
76 Standard_Integer FindDistPC(const Standard_Real aT1A,
77 const Standard_Real aT1B,
78 const Handle(Geom_Curve)& theC1,
79 const Standard_Real theCriteria,
80 const Standard_Real theEps,
81 GeomAPI_ProjectPointOnCurve& theProjector,
82 Standard_Real& aDmax,
83 Standard_Real& aT1max,
84 Standard_Real& aT2max,
85 const Standard_Boolean bMaxDist = Standard_True);
a4e383e1 86static
87 Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
88 const IntTools_Range& theRange);
89static
90 Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
91 const GeomAbs_CurveType theCurveType,
92 const Standard_Real theResCoeff,
93 const Standard_Real theR3D);
94static
95 Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
96 const IntTools_Range& theRange);
3e594885 97static
98 Standard_Integer IsClosed(const Handle(Geom_Curve)& theCurve,
99 const Standard_Real aT1,
100 const Standard_Real aT2,
101 const Standard_Real theTol,
102 const Standard_Real theRes);
ec0cdc0e 103static
104 Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType);
7fd59977 105
106//=======================================================================
ec0cdc0e 107//function : Prepare
7fd59977 108//purpose :
109//=======================================================================
ec0cdc0e 110void IntTools_EdgeEdge::Prepare()
7fd59977 111{
ec0cdc0e 112 GeomAbs_CurveType aCT1, aCT2;
113 Standard_Integer iCT1, iCT2;
114 //
115 myCurve1.Initialize(myEdge1);
116 myCurve2.Initialize(myEdge2);
117 //
118 if (myRange1.First() == 0. && myRange1.Last() == 0.) {
119 myRange1.SetFirst(myCurve1.FirstParameter());
120 myRange1.SetLast (myCurve1.LastParameter());
121 }
122 //
123 if (myRange2.First() == 0. && myRange2.Last() == 0.) {
124 myRange2.SetFirst(myCurve2.FirstParameter());
125 myRange2.SetLast (myCurve2.LastParameter());
126 }
127 //
128 aCT1 = myCurve1.GetType();
129 aCT2 = myCurve2.GetType();
130 //
131 iCT1 = TypeToInteger(aCT1);
132 iCT2 = TypeToInteger(aCT2);
133 //
134 if (iCT1 == iCT2) {
135 if (iCT1 != 0) {
136 //compute deflection
a4e383e1 137 Standard_Real aC1, aC2;
ec0cdc0e 138 //
a4e383e1 139 aC2 = CurveDeflection(myCurve2, myRange2);
140 aC1 = (aC2 > Precision::Confusion()) ?
141 CurveDeflection(myCurve1, myRange1) : 1.;
ec0cdc0e 142 //
143 if (aC1 < aC2) {
144 --iCT1;
145 }
146 }
147 }
148 //
149 if (iCT1 < iCT2) {
150 TopoDS_Edge tmpE = myEdge1;
151 myEdge1 = myEdge2;
152 myEdge2 = tmpE;
153 //
154 BRepAdaptor_Curve tmpC = myCurve1;
155 myCurve1 = myCurve2;
156 myCurve2 = tmpC;
157 //
158 IntTools_Range tmpR = myRange1;
159 myRange1 = myRange2;
160 myRange2 = tmpR;
161 //
162 mySwap = Standard_True;
163 }
164 //
165 myTol1 = myCurve1.Tolerance();
166 myTol2 = myCurve2.Tolerance();
167 myTol = myTol1 + myTol2;
168 //
ec0cdc0e 169 if (iCT1 != 0 || iCT2 != 0) {
a743e2e5 170 Standard_Real f, l, aTM;
171 //
ec0cdc0e 172 myGeom1 = BRep_Tool::Curve(myEdge1, f, l);
173 myGeom2 = BRep_Tool::Curve(myEdge2, f, l);
a743e2e5 174 //
a4e383e1 175 myResCoeff1 = ResolutionCoeff(myCurve1, myRange1);
176 myResCoeff2 = ResolutionCoeff(myCurve2, myRange2);
177 //
524a5f7a 178 myRes1 = Resolution(myCurve1.Curve().Curve(), myCurve1.GetType(), myResCoeff1, myTol1);
179 myRes2 = Resolution(myCurve2.Curve().Curve(), myCurve2.GetType(), myResCoeff2, myTol2);
a4e383e1 180 //
a743e2e5 181 myPTol1 = 5.e-13;
182 aTM = Max(fabs(myRange1.First()), fabs(myRange1.Last()));
183 if (aTM > 999.) {
184 myPTol1 = 5.e-16 * aTM;
185 }
186 //
187 myPTol2 = 5.e-13;
188 aTM = Max(fabs(myRange2.First()), fabs(myRange2.Last()));
189 if (aTM > 999.) {
190 myPTol2 = 5.e-16 * aTM;
191 }
ec0cdc0e 192 }
7fd59977 193}
7fd59977 194
7fd59977 195//=======================================================================
196//function : Perform
197//purpose :
198//=======================================================================
ec0cdc0e 199void IntTools_EdgeEdge::Perform()
7fd59977 200{
ec0cdc0e 201 //1. Check data
7fd59977 202 CheckData();
7fd59977 203 if (myErrorStatus) {
204 return;
205 }
206 //
ec0cdc0e 207 //2. Prepare Data
208 Prepare();
f793011e 209 //
ec0cdc0e 210 //3.1. Check Line/Line case
211 if (myCurve1.GetType() == GeomAbs_Line &&
212 myCurve2.GetType() == GeomAbs_Line) {
7fd59977 213 ComputeLineLine();
7fd59977 214 return;
215 }
f793011e 216 //
6b1fe48c 217 IntTools_SequenceOfRanges aRanges1, aRanges2;
218 //
a743e2e5 219 //3.2. Find ranges containig solutions
3e594885 220 Standard_Boolean bSplit2;
221 FindSolutions(aRanges1, aRanges2, bSplit2);
6b1fe48c 222 //
a743e2e5 223 //4. Merge solutions and save common parts
3e594885 224 MergeSolutions(aRanges1, aRanges2, bSplit2);
225}
226
227//=======================================================================
228//function : FindSolutions
229//purpose :
230//=======================================================================
231void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
232 IntTools_SequenceOfRanges& theRanges2,
233 Standard_Boolean& bSplit2)
234{
235 Standard_Boolean bIsClosed2;
236 Standard_Real aT11, aT12, aT21, aT22;
237 Bnd_Box aB2;
238 //
239 bSplit2 = Standard_False;
240 myRange1.Range(aT11, aT12);
241 myRange2.Range(aT21, aT22);
242 //
243 bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
244 //
245 if (bIsClosed2) {
246 Bnd_Box aB1;
247 BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
248 //
249 gp_Pnt aP = myGeom2->Value(aT21);
250 bIsClosed2 = !aB1.IsOut(aP);
251 }
252 //
253 if (!bIsClosed2) {
254 BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
255 FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
256 return;
257 }
258 //
524a5f7a 259 if (!CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1)) {
260 theRanges1.Append(myRange1);
261 theRanges2.Append(myRange2);
262 return;
263 }
264 //
3e594885 265 Standard_Integer i, j, aNb1, aNb2;
266 IntTools_SequenceOfRanges aSegments1, aSegments2;
267 //
268 aNb1 = IsClosed(myGeom1, aT11, aT12, myTol1, myRes1) ? 2 : 1;
269 aNb2 = 2;
270 //
271 SplitRangeOnSegments(aT11, aT12, myRes1, aNb1, aSegments1);
272 SplitRangeOnSegments(aT21, aT22, myRes2, aNb2, aSegments2);
273 //
274 aNb1 = aSegments1.Length();
275 aNb2 = aSegments2.Length();
276 for (i = 1; i <= aNb1; ++i) {
277 const IntTools_Range& aR1 = aSegments1(i);
278 for (j = 1; j <= aNb2; ++j) {
279 const IntTools_Range& aR2 = aSegments2(j);
280 BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
281 FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
282 }
283 }
284 //
285 bSplit2 = aNb2 > 1;
0d19eb34 286}
287
288//=======================================================================
289//function : FindSolutions
290//purpose :
291//=======================================================================
292void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
293 const IntTools_Range& theR2,
3e594885 294 const Bnd_Box& theBox2,
295 IntTools_SequenceOfRanges& theRanges1,
0d19eb34 296 IntTools_SequenceOfRanges& theRanges2)
297{
ec0cdc0e 298 Standard_Boolean bOut, bStop, bThin;
0d19eb34 299 Standard_Real aT11, aT12, aT21, aT22;
300 Standard_Real aTB11, aTB12, aTB21, aTB22;
524a5f7a 301 Standard_Real aSmallStep1, aSmallStep2;
ec0cdc0e 302 Standard_Integer iCom;
0d19eb34 303 Bnd_Box aB1, aB2;
304 //
305 theR1.Range(aT11, aT12);
306 theR2.Range(aT21, aT22);
a743e2e5 307 //
3e594885 308 aB2 = theBox2;
f793011e 309 //
ec0cdc0e 310 bThin = Standard_False;
311 bStop = Standard_False;
ec0cdc0e 312 iCom = 1;
313 //
314 do {
a4e383e1 315 aTB11 = aT11;
316 aTB12 = aT12;
317 aTB21 = aT21;
318 aTB22 = aT22;
319 //
320 //1. Build box for first edge and find parameters
321 // of the second one in that box
322 BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
323 bOut = aB1.IsOut(aB2);
ec0cdc0e 324 if (bOut) {
325 break;
326 }
f793011e 327 //
a4e383e1 328 bThin = ((aT12 - aT11) < myRes1) ||
524a5f7a 329 (aB1.IsXThin(myTol) && aB1.IsYThin(myTol) && aB1.IsZThin(myTol));
a4e383e1 330 //
331 bOut = !FindParameters(myCurve2, aTB21, aTB22, myRes2, myPTol2,
332 myResCoeff2, aB1, aT21, aT22);
333 if (bOut || bThin) {
0d19eb34 334 break;
335 }
336 //
a4e383e1 337 //2. Build box for second edge and find parameters
338 // of the first one in that box
339 BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
340 bOut = aB1.IsOut(aB2);
0d19eb34 341 if (bOut) {
342 break;
343 }
344 //
524a5f7a 345 bThin = ((aT22 - aT21) < myRes2) ||
346 (aB2.IsXThin(myTol) && aB2.IsYThin(myTol) && aB2.IsZThin(myTol));
0d19eb34 347 //
a4e383e1 348 bOut = !FindParameters(myCurve1, aTB11, aTB12, myRes1, myPTol1,
349 myResCoeff1, aB2, aT11, aT12);
350 //
351 if (bOut || bThin) {
352 break;
7fd59977 353 }
ec0cdc0e 354 //
a4e383e1 355 //3. Check if it makes sense to continue
356 aSmallStep1 = (aTB12 - aTB11) / 250.;
357 aSmallStep2 = (aTB22 - aTB21) / 250.;
358 //
359 if (aSmallStep1 < myRes1) {
360 aSmallStep1 = myRes1;
361 }
362 if (aSmallStep2 < myRes2) {
363 aSmallStep2 = myRes2;
364 }
365 //
366 if (((aT11 - aTB11) < aSmallStep1) && ((aTB12 - aT12) < aSmallStep1) &&
367 ((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
368 bStop = Standard_True;
369 }
370 //
371 } while (!bStop);
ec0cdc0e 372 //
373 if (bOut) {
374 //no intersection;
375 return;
7fd59977 376 }
f793011e 377 //
ec0cdc0e 378 if (!bThin) {
379 //check curves for coincidence on the ranges
380 iCom = CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1);
381 if (!iCom) {
382 bThin = Standard_True;
a4e383e1 383 }
7fd59977 384 }
385 //
ec0cdc0e 386 if (bThin) {
387 if (iCom != 0) {
388 //check intermediate points
524a5f7a 389 Standard_Boolean bSol;
390 Standard_Real aT1;
391 gp_Pnt aP1;
392 GeomAPI_ProjectPointOnCurve aProjPC;
f793011e 393 //
3e594885 394 aT1 = (aT11 + aT12) * .5;
6b1fe48c 395 myGeom1->D0(aT1, aP1);
f793011e 396 //
524a5f7a 397 aProjPC.Init(myGeom2, aT21, aT22);
398 aProjPC.Perform(aP1);
399 //
400 if (aProjPC.NbPoints()) {
401 bSol = aProjPC.LowerDistance() <= myTol;
402 }
403 else {
404 Standard_Real aT2;
405 gp_Pnt aP2;
406 //
407 aT2 = (aT21 + aT22) * .5;
408 myGeom2->D0(aT2, aP2);
409 //
410 bSol = aP1.IsEqual(aP2, myTol);
411 }
412 //
413 if (!bSol) {
ec0cdc0e 414 return;
7fd59977 415 }
416 }
ec0cdc0e 417 //add common part
418 IntTools_Range aR1(aT11, aT12), aR2(aT21, aT22);
419 //
420 theRanges1.Append(aR1);
421 theRanges2.Append(aR2);
422 return;
7fd59977 423 }
f793011e 424 //
ec0cdc0e 425 if (!IsIntersection(aT11, aT12, aT21, aT22)) {
426 return;
7fd59977 427 }
f793011e 428 //
ec0cdc0e 429 //split ranges on segments and repeat
430 Standard_Integer i, aNb1;
431 IntTools_SequenceOfRanges aSegments1;
432 //
433 IntTools_Range aR2(aT21, aT22);
3e594885 434 BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
0d19eb34 435 //
ec0cdc0e 436 SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
437 aNb1 = aSegments1.Length();
438 for (i = 1; i <= aNb1; ++i) {
439 const IntTools_Range& aR1 = aSegments1(i);
3e594885 440 FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
7fd59977 441 }
7fd59977 442}
ec0cdc0e 443
7fd59977 444//=======================================================================
ec0cdc0e 445//function : FindParameters
7fd59977 446//purpose :
447//=======================================================================
ec0cdc0e 448Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theBAC,
449 const Standard_Real aT1,
450 const Standard_Real aT2,
451 const Standard_Real theRes,
a743e2e5 452 const Standard_Real thePTol,
a4e383e1 453 const Standard_Real theResCoeff,
ec0cdc0e 454 const Bnd_Box& theCBox,
455 Standard_Real& aTB1,
456 Standard_Real& aTB2)
7fd59977 457{
ec0cdc0e 458 Standard_Boolean bRet;
459 Standard_Integer aC, i, k;
6b1fe48c 460 Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn;
a743e2e5 461 Standard_Real aDist, aDistP, aDistTol, aTol;
ec0cdc0e 462 gp_Pnt aP;
463 Bnd_Box aCBx;
7fd59977 464 //
ec0cdc0e 465 bRet = Standard_False;
466 aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.;
467 aDt = theRes;
ec0cdc0e 468 aTol = theBAC.Tolerance();
469 aDistP = 0.;
6b1fe48c 470 aDistTol = Precision::PConfusion();
ec0cdc0e 471 aCBx = theCBox;
472 aCBx.Enlarge(aTol);
7fd59977 473 //
a4e383e1 474 const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
475 const GeomAbs_CurveType aCurveType = theBAC.GetType();
476 //
ec0cdc0e 477 for (i = 0; i < 2; ++i) {
478 aTB = !i ? aT1 : aT2;
479 aT = !i ? aT2 : aTB1;
480 aC = !i ? 1 : -1;
481 bRet = Standard_False;
482 k = 0;
483 //looking for the point on the edge which is in the box;
484 while (aC*(aT-aTB) >= 0) {
6b1fe48c 485 theBAC.D0(aTB, aP);
486 aDist = PointBoxDistance(theCBox, aP);
ec0cdc0e 487 if (aDist > aTol) {
6b1fe48c 488 if (fabs(aDist - aDistP) < aDistTol) {
a4e383e1 489 aDt = Resolution(aCurve, aCurveType, theResCoeff, (++k)*aDist);
6b1fe48c 490 } else {
491 k = 0;
a4e383e1 492 aDt = Resolution(aCurve, aCurveType, theResCoeff, aDist);
6b1fe48c 493 }
ec0cdc0e 494 aTB += aC*aDt;
495 } else {
496 bRet = Standard_True;
497 break;
498 }
499 aDistP = aDist;
500 }
501 //
502 if (!bRet) {
503 if (!i) {
504 //edge is out of the box;
505 return bRet;
506 } else {
507 bRet = !bRet;
508 aTB = aTB1;
509 aDt = aT2 - aTB1;
510 }
511 }
512 //
513 aT = !i ? aT1 : aT2;
514 if (aTB != aT) {
515 //one point IN, one point OUT; looking for the bounding point;
516 aTIn = aTB;
517 aTOut = aTB - aC*aDt;
518 aDiff = aTIn - aTOut;
a743e2e5 519 while (fabs(aDiff) > thePTol) {
ec0cdc0e 520 aTB = aTOut + aDiff*aCf;
6b1fe48c 521 theBAC.D0(aTB, aP);
ec0cdc0e 522 if (aCBx.IsOut(aP)) {
523 aTOut = aTB;
524 } else {
525 aTIn = aTB;
526 }
527 aDiff = aTIn - aTOut;
528 }
529 }
530 if (!i) {
531 aTB1 = aTB;
532 } else {
533 aTB2 = aTB;
7fd59977 534 }
535 }
ec0cdc0e 536 return bRet;
7fd59977 537}
538
539//=======================================================================
ec0cdc0e 540//function : MergeSolutions
7fd59977 541//purpose :
542//=======================================================================
ec0cdc0e 543void IntTools_EdgeEdge::MergeSolutions(const IntTools_SequenceOfRanges& theRanges1,
3e594885 544 const IntTools_SequenceOfRanges& theRanges2,
545 const Standard_Boolean bSplit2)
7fd59977 546{
3e594885 547 Standard_Integer aNbCP = theRanges1.Length();
548 if (aNbCP == 0) {
549 return;
550 }
551 //
ec0cdc0e 552 IntTools_Range aRi1, aRi2, aRj1, aRj2;
524a5f7a 553 Standard_Boolean bCond;
3e594885 554 Standard_Integer i, j;
ec0cdc0e 555 TopAbs_ShapeEnum aType;
524a5f7a 556 Standard_Real aT11, aT12, aT21, aT22;
557 Standard_Real aTi11, aTi12, aTi21, aTi22;
558 Standard_Real aTj11, aTj12, aTj21, aTj22;
559 Standard_Real aRes1, aRes2, dTR1, dTR2;
3e594885 560 BOPCol_MapOfInteger aMI;
ec0cdc0e 561 //
524a5f7a 562 aRes1 = Resolution(myCurve1.Curve().Curve(),
563 myCurve1.GetType(), myResCoeff1, myTol);
564 aRes2 = Resolution(myCurve2.Curve().Curve(),
565 myCurve2.GetType(), myResCoeff2, myTol);
566 //
567 myRange1.Range(aT11, aT12);
568 myRange2.Range(aT21, aT22);
569 dTR1 = 20*aRes1;
570 dTR2 = 20*aRes2;
ec0cdc0e 571 aType = TopAbs_VERTEX;
572 //
3e594885 573 for (i = 1; i <= aNbCP;) {
574 if (aMI.Contains(i)) {
575 ++i;
576 continue;
577 }
578 //
ec0cdc0e 579 aRi1 = theRanges1(i);
580 aRi2 = theRanges2(i);
581 //
582 aRi1.Range(aTi11, aTi12);
583 aRi2.Range(aTi21, aTi22);
584 //
3e594885 585 aMI.Add(i);
586 //
ec0cdc0e 587 for (j = i+1; j <= aNbCP; ++j) {
3e594885 588 if (aMI.Contains(j)) {
589 continue;
590 }
591 //
ec0cdc0e 592 aRj1 = theRanges1(j);
593 aRj2 = theRanges2(j);
594 //
595 aRj1.Range(aTj11, aTj12);
596 aRj2.Range(aTj21, aTj22);
524a5f7a 597 //
598 bCond = (fabs(aTi12 - aTj11) < dTR1) ||
599 (bSplit2 && (fabs(aTj12 - aTi11) < dTR1));
600 if (bCond && bSplit2) {
601 bCond = (fabs((Max(aTi22, aTj22) - Min(aTi21, aTj21)) -
602 ((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2);
603 }
604 //
605 if (bCond) {
ec0cdc0e 606 aTi11 = Min(aTi11, aTj11);
607 aTi12 = Max(aTi12, aTj12);
608 aTi21 = Min(aTi21, aTj21);
609 aTi22 = Max(aTi22, aTj22);
3e594885 610 aMI.Add(j);
611 }
612 else if (!bSplit2) {
613 i = j;
ec0cdc0e 614 break;
7fd59977 615 }
616 }
ec0cdc0e 617 //
524a5f7a 618 if (((fabs(aT11 - aTi11) < myRes1) && (fabs(aT12 - aTi12) < myRes1)) ||
619 ((fabs(aT21 - aTi21) < myRes2) && (fabs(aT22 - aTi22) < myRes2))) {
ec0cdc0e 620 aType = TopAbs_EDGE;
3e594885 621 myCommonParts.Clear();
ec0cdc0e 622 }
623 //
624 AddSolution(aTi11, aTi12, aTi21, aTi22, aType);
3e594885 625 if (aType == TopAbs_EDGE) {
626 break;
627 }
628 //
629 if (bSplit2) {
630 ++i;
631 }
7fd59977 632 }
7fd59977 633}
634
635//=======================================================================
ec0cdc0e 636//function : AddSolution
7fd59977 637//purpose :
638//=======================================================================
ec0cdc0e 639void IntTools_EdgeEdge::AddSolution(const Standard_Real aT11,
640 const Standard_Real aT12,
641 const Standard_Real aT21,
642 const Standard_Real aT22,
643 const TopAbs_ShapeEnum theType)
7fd59977 644{
ec0cdc0e 645 IntTools_CommonPrt aCPart;
646 //
647 aCPart.SetType(theType);
648 if (!mySwap) {
649 aCPart.SetEdge1(myEdge1);
650 aCPart.SetEdge2(myEdge2);
651 aCPart.SetRange1(aT11, aT12);
652 aCPart.AppendRange2(aT21, aT22);
653 } else {
654 aCPart.SetEdge1(myEdge2);
655 aCPart.SetEdge2(myEdge1);
656 aCPart.SetRange1(aT21, aT22);
657 aCPart.AppendRange2(aT11, aT12);
0d19eb34 658 }
ec0cdc0e 659 //
660 if (theType == TopAbs_VERTEX) {
661 Standard_Real aT1, aT2;
662 //
663 FindBestSolution(aT11, aT12, aT21, aT22, aT1, aT2);
664 //
665 if (!mySwap) {
666 aCPart.SetVertexParameter1(aT1);
667 aCPart.SetVertexParameter2(aT2);
668 } else {
669 aCPart.SetVertexParameter1(aT2);
670 aCPart.SetVertexParameter2(aT1);
671 }
672 }
673 myCommonParts.Append(aCPart);
7fd59977 674}
675
7fd59977 676//=======================================================================
ec0cdc0e 677//function : FindBestSolution
678//purpose :
7fd59977 679//=======================================================================
ec0cdc0e 680void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11,
681 const Standard_Real aT12,
682 const Standard_Real aT21,
683 const Standard_Real aT22,
684 Standard_Real& aT1,
685 Standard_Real& aT2)
7fd59977 686{
0d19eb34 687 Standard_Integer i, aNbS, iErr;
524a5f7a 688 Standard_Real aDMin, aD, aCrit, aRes1;
0d19eb34 689 Standard_Real aT1x, aT2x, aT1p, aT2p;
ec0cdc0e 690 GeomAPI_ProjectPointOnCurve aProj;
0d19eb34 691 IntTools_SequenceOfRanges aSeg1;
ec0cdc0e 692 //
3e594885 693 aT1 = (aT11 + aT12) * .5;
694 aT2 = (aT21 + aT22) * .5;
0d19eb34 695 //
ec0cdc0e 696 aDMin = 100.;
697 aD = 100.;
6b1fe48c 698 aCrit = 0.;//1.e-16;
ec0cdc0e 699 //
524a5f7a 700 aRes1 = Resolution(myCurve1.Curve().Curve(),
701 myCurve1.GetType(), myResCoeff1, myTol);
0d19eb34 702 aNbS = 10;
524a5f7a 703 SplitRangeOnSegments(aT11, aT12, 3*aRes1, aNbS, aSeg1);
0d19eb34 704 aNbS = aSeg1.Length();
705 //
ec0cdc0e 706 aProj.Init(myGeom2, aT21, aT22);
0d19eb34 707 for (i = 1; i <= aNbS; ++i) {
708 const IntTools_Range& aR1 = aSeg1(i);
709 aR1.Range(aT1x, aT2x);
710 //
a743e2e5 711 iErr = FindDistPC(aT1x, aT2x, myGeom1, aCrit, myPTol1,
0d19eb34 712 aProj, aD, aT1p, aT2p, Standard_False);
ec0cdc0e 713 if (iErr != 1 && aD < aDMin) {
714 aT1 = aT1p;
715 aT2 = aT2p;
716 aDMin = aD;
6b1fe48c 717 if (aDMin <= aCrit) {
ec0cdc0e 718 break;
7fd59977 719 }
720 }
7fd59977 721 }
722}
723
724//=======================================================================
ec0cdc0e 725//function : ComputeLineLine
7fd59977 726//purpose :
727//=======================================================================
ec0cdc0e 728void IntTools_EdgeEdge::ComputeLineLine()
7fd59977 729{
ec0cdc0e 730 Standard_Boolean IsParallel, IsCoincide;
731 Standard_Real aSin, aCos, aAng, aTol;
732 Standard_Real aT1, aT2, aT11, aT12, aT21, aT22;
733 gp_Pnt aP11, aP12;
734 gp_Lin aL1, aL2;
735 gp_Dir aD1, aD2;
736 IntTools_CommonPrt aCommonPrt;
7fd59977 737 //
ec0cdc0e 738 IsParallel = Standard_False;
739 IsCoincide = Standard_False;
740 aTol = myTol*myTol;
741 aL1 = myCurve1.Line();
742 aL2 = myCurve2.Line();
743 aD1 = aL1.Position().Direction();
744 aD2 = aL2.Position().Direction();
745 myRange1.Range(aT11, aT12);
746 myRange2.Range(aT21, aT22);
7fd59977 747 //
ec0cdc0e 748 aCommonPrt.SetEdge1(myEdge1);
749 aCommonPrt.SetEdge2(myEdge2);
7fd59977 750 //
ec0cdc0e 751 aCos = aD1.Dot(aD2);
752 aAng = (aCos >= 0.) ? 2.*(1. - aCos) : 2.*(1. + aCos);
7fd59977 753 //
ec0cdc0e 754 if(aAng <= Precision::Angular()) {
755 IsParallel = Standard_True;
756 if(aL1.SquareDistance(aL2.Location()) <= aTol) {
757 IsCoincide = Standard_True;
758 aP11 = ElCLib::Value(aT11, aL1);
759 aP12 = ElCLib::Value(aT12, aL1);
7fd59977 760 }
7fd59977 761 }
ec0cdc0e 762 else {
763 aP11 = ElCLib::Value(aT11, aL1);
764 aP12 = ElCLib::Value(aT12, aL1);
765 if(aL2.SquareDistance(aP11) <= aTol && aL2.SquareDistance(aP12) <= aTol) {
766 IsCoincide = Standard_True;
7fd59977 767 }
768 }
769 //
ec0cdc0e 770 if (IsCoincide) {
771 Standard_Real t21, t22;
772 //
773 t21 = ElCLib::Parameter(aL2, aP11);
774 t22 = ElCLib::Parameter(aL2, aP12);
775 if((t21 > aT22 && t22 > aT22) || (t21 < aT21 && t22 < aT21)) {
776 return;
7fd59977 777 }
ec0cdc0e 778 //
779 Standard_Real temp;
780 if(t21 > t22) {
781 temp = t21;
782 t21 = t22;
783 t22 = temp;
7fd59977 784 }
ec0cdc0e 785 //
786 if(t21 >= aT21) {
787 if(t22 <= aT22) {
788 aCommonPrt.SetRange1(aT11, aT12);
789 aCommonPrt.SetAllNullFlag(Standard_True);
790 aCommonPrt.AppendRange2(t21, t22);
791 }
792 else {
793 aCommonPrt.SetRange1(aT11, aT12 - (t22 - aT22));
794 aCommonPrt.AppendRange2(t21, aT22);
795 }
7fd59977 796 }
ec0cdc0e 797 else {
798 aCommonPrt.SetRange1(aT11 + (aT21 - t21), aT12);
799 aCommonPrt.AppendRange2(aT21, t22);
7fd59977 800 }
ec0cdc0e 801 aCommonPrt.SetType(TopAbs_EDGE);
802 myCommonParts.Append(aCommonPrt);
803 return;
804 }
805 //
806 if (IsParallel) {
807 return;
808 }
809 //
810 {
811 TopoDS_Iterator aIt1, aIt2;
812 aIt1.Initialize(myEdge1);
813 for (; aIt1.More(); aIt1.Next()) {
814 const TopoDS_Shape& aV1 = aIt1.Value();
815 aIt2.Initialize(myEdge2);
816 for (; aIt2.More(); aIt2.Next()) {
817 const TopoDS_Shape& aV2 = aIt2.Value();
818 if (aV2.IsSame(aV1)) {
819 return;
820 }
821 }
7fd59977 822 }
7fd59977 823 }
ec0cdc0e 824 //
825 aSin = 1. - aCos*aCos;
826 gp_Pnt O1 = aL1.Location();
827 gp_Pnt O2 = aL2.Location();
828 gp_Vec O1O2 (O1, O2);
829 //
830 aT2 = (aD1.XYZ()*(O1O2.Dot(aD1))-(O1O2.XYZ())).Dot(aD2.XYZ());
831 aT2 /= aSin;
832 //
833 if(aT2 < aT21 || aT2 > aT22) {
834 return;
835 }
836 //
837 gp_Pnt aP2(ElCLib::Value(aT2, aL2));
838 aT1 = (gp_Vec(O1, aP2)).Dot(aD1);
839 //
840 if(aT1 < aT11 || aT1 > aT12) {
841 return;
842 }
843 //
844 gp_Pnt aP1(ElCLib::Value(aT1, aL1));
845 Standard_Real aDist = aP1.SquareDistance(aP2);
846 //
847 if (aDist > aTol) {
848 return;
849 }
850 //
851 aCommonPrt.SetRange1(aT1 - myTol, aT1 + myTol);
852 aCommonPrt.AppendRange2(aT2 - myTol, aT2 + myTol);
853 aCommonPrt.SetType(TopAbs_VERTEX);
854 aCommonPrt.SetVertexParameter1(aT1);
855 aCommonPrt.SetVertexParameter2(aT2);
856 myCommonParts.Append(aCommonPrt);
7fd59977 857}
ec0cdc0e 858
7fd59977 859//=======================================================================
ec0cdc0e 860//function : IsIntersection
7fd59977 861//purpose :
862//=======================================================================
ec0cdc0e 863Standard_Boolean IntTools_EdgeEdge::IsIntersection(const Standard_Real aT11,
864 const Standard_Real aT12,
865 const Standard_Real aT21,
866 const Standard_Real aT22)
7fd59977 867{
ec0cdc0e 868 Standard_Boolean bRet;
869 gp_Pnt aP11, aP12, aP21, aP22;
870 gp_Vec aV11, aV12, aV21, aV22;
871 Standard_Real aD11_21, aD11_22, aD12_21, aD12_22, aCriteria, aCoef;
872 Standard_Boolean bSmall_11_21, bSmall_11_22, bSmall_12_21, bSmall_12_22;
873 //
874 bRet = Standard_True;
875 aCoef = 1.e+5;
876 if (((aT12 - aT11) > aCoef*myRes1) && ((aT22 - aT21) > aCoef*myRes2)) {
877 aCoef = 5000;
878 } else {
879 Standard_Real aTRMin = Min((aT12 - aT11)/myRes1, (aT22 - aT21)/myRes2);
880 aCoef = aTRMin / 100.;
881 if (aCoef < 1.) {
882 aCoef = 1.;
7fd59977 883 }
884 }
ec0cdc0e 885 aCriteria = aCoef * myTol;
886 aCriteria *= aCriteria;
7fd59977 887 //
ec0cdc0e 888 myGeom1->D1(aT11, aP11, aV11);
889 myGeom1->D1(aT12, aP12, aV12);
890 myGeom2->D1(aT21, aP21, aV21);
891 myGeom2->D1(aT22, aP22, aV22);
892 //
893 aD11_21 = aP11.SquareDistance(aP21);
894 aD11_22 = aP11.SquareDistance(aP22);
895 aD12_21 = aP12.SquareDistance(aP21);
896 aD12_22 = aP12.SquareDistance(aP22);
897 //
898 bSmall_11_21 = aD11_21 < aCriteria;
899 bSmall_11_22 = aD11_22 < aCriteria;
900 bSmall_12_21 = aD12_21 < aCriteria;
901 bSmall_12_22 = aD12_22 < aCriteria;
902 //
903 if ((bSmall_11_21 && bSmall_12_22) ||
904 (bSmall_11_22 && bSmall_12_21)) {
905 if (aCoef == 1.) {
906 return bRet;
7fd59977 907 }
ec0cdc0e 908 //
909 Standard_Real anAngleCriteria;
910 Standard_Real anAngle1, anAngle2;
911 //
912 anAngleCriteria = 5.e-3;
913 if (bSmall_11_21 && bSmall_12_22) {
914 anAngle1 = aV11.Angle(aV21);
915 anAngle2 = aV12.Angle(aV22);
916 } else {
917 anAngle1 = aV11.Angle(aV22);
918 anAngle2 = aV12.Angle(aV21);
7fd59977 919 }
ec0cdc0e 920 //
921 if (((anAngle1 < anAngleCriteria) || ((M_PI - anAngle1) < anAngleCriteria)) ||
922 ((anAngle2 < anAngleCriteria) || ((M_PI - anAngle2) < anAngleCriteria))) {
923 GeomAPI_ProjectPointOnCurve aProj;
924 Standard_Integer iErr;
925 Standard_Real aD, aT1p, aT2p;
926 //
927 aD = 100.;
928 aProj.Init(myGeom2, aT21, aT22);
929 iErr = FindDistPC(aT11, aT12, myGeom1, myTol, myRes1, aProj, aD, aT1p, aT2p, Standard_False);
930 bRet = (iErr == 2);
7fd59977 931 }
7fd59977 932 }
ec0cdc0e 933 return bRet;
7fd59977 934}
935
936//=======================================================================
ec0cdc0e 937//function : CheckCoincidence
7fd59977 938//purpose :
939//=======================================================================
ec0cdc0e 940Standard_Integer IntTools_EdgeEdge::CheckCoincidence(const Standard_Real aT11,
941 const Standard_Real aT12,
942 const Standard_Real aT21,
943 const Standard_Real aT22,
944 const Standard_Real theCriteria,
0d19eb34 945 const Standard_Real theCurveRes1)
7fd59977 946{
6b1fe48c 947 Standard_Integer iErr, aNb, aNb1, i;
0d19eb34 948 Standard_Real aT1A, aT1B, aT1max, aT2max, aDmax;
ec0cdc0e 949 GeomAPI_ProjectPointOnCurve aProjPC;
0d19eb34 950 IntTools_SequenceOfRanges aSeg1;
ec0cdc0e 951 //
952 iErr = 0;
953 aDmax = -1.;
954 aProjPC.Init(myGeom2, aT21, aT22);
955 //
956 // 1. Express evaluation
957 aNb = 10; // Number of intervals on the curve #1
6b1fe48c 958 SplitRangeOnSegments(aT11, aT12, theCurveRes1, aNb, aSeg1);
959 aNb1 = aSeg1.Length();
960 for (i = 1; i < aNb1; ++i) {
0d19eb34 961 const IntTools_Range& aR1 = aSeg1(i);
962 aR1.Range(aT1A, aT1B);
ec0cdc0e 963 //
0d19eb34 964 iErr = DistPC(aT1B, myGeom1, theCriteria, aProjPC, aDmax, aT2max);
ec0cdc0e 965 if (iErr) {
966 return iErr;
7fd59977 967 }
968 }
ec0cdc0e 969 //
0d19eb34 970 // if the ranges in aSeg1 are less than theCurveRes1,
971 // there is no need to do step 2 (deep evaluation)
6b1fe48c 972 if (aNb1 < aNb) {
0d19eb34 973 return iErr;
974 }
975 //
ec0cdc0e 976 // 2. Deep evaluation
6b1fe48c 977 for (i = 2; i < aNb1; ++i) {
0d19eb34 978 const IntTools_Range& aR1 = aSeg1(i);
979 aR1.Range(aT1A, aT1B);
ec0cdc0e 980 //
0d19eb34 981 iErr = FindDistPC(aT1A, aT1B, myGeom1, theCriteria, theCurveRes1,
ec0cdc0e 982 aProjPC, aDmax, aT1max, aT2max);
983 if (iErr) {
984 return iErr;
7fd59977 985 }
7fd59977 986 }
ec0cdc0e 987 // Possible values:
988 // iErr == 0 - the patches are coincided
989 // iErr == 1 - a point from aC1 can not be projected on aC2
990 // iErr == 2 - the distance is too big
991 return iErr;
7fd59977 992}
ec0cdc0e 993
7fd59977 994//=======================================================================
ec0cdc0e 995//function : FindDistPC
7fd59977 996//purpose :
997//=======================================================================
ec0cdc0e 998Standard_Integer FindDistPC(const Standard_Real aT1A,
999 const Standard_Real aT1B,
1000 const Handle(Geom_Curve)& theC1,
1001 const Standard_Real theCriteria,
1002 const Standard_Real theEps,
1003 GeomAPI_ProjectPointOnCurve& theProjPC,
1004 Standard_Real& aDmax,
1005 Standard_Real& aT1max,
1006 Standard_Real& aT2max,
1007 const Standard_Boolean bMaxDist)
7fd59977 1008{
ec0cdc0e 1009 Standard_Integer iErr, iC;
1010 Standard_Real aGS, aXP, aA, aB, aXL, aYP, aYL, aT2P, aT2L;
1011 //
1012 iC = bMaxDist ? 1 : -1;
1013 iErr = 0;
1014 //
1015 aGS = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))-1.;
1016 aA = aT1A;
1017 aB = aT1B;
1018 //
1019 // check bounds
1020 iErr = DistPC(aA, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
1021 if (iErr == 2) {
1022 return iErr;
7fd59977 1023 }
ec0cdc0e 1024 //
1025 iErr = DistPC(aB, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
1026 if (iErr == 2) {
1027 return iErr;
7fd59977 1028 }
ec0cdc0e 1029 //
1030 aXP = aA + (aB - aA)*aGS;
1031 aXL = aB - (aB - aA)*aGS;
1032 //
1033 iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
1034 if (iErr) {
1035 return iErr;
7fd59977 1036 }
ec0cdc0e 1037 //
1038 iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
1039 if (iErr) {
1040 return iErr;
7fd59977 1041 }
7fd59977 1042 //
ec0cdc0e 1043 for (;;) {
1044 if (iC*(aYP - aYL) > 0) {
1045 aA = aXL;
1046 aXL = aXP;
1047 aYL = aYP;
1048 aXP = aA + (aB - aA)*aGS;
1049 iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
1050 if (iErr) {
1051 return iErr;
1052 }
1053 }
1054 else {
1055 aB = aXP;
1056 aXP = aXL;
1057 aYP = aYL;
1058 aXL = aB - (aB - aA)*aGS;
1059 iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
1060 if (iErr) {
1061 return iErr;
1062 }
7fd59977 1063 }
ec0cdc0e 1064 //
1065 if ((aB - aA) < theEps) {
1066 break;
7fd59977 1067 }
ec0cdc0e 1068 }// for (;;) {
7fd59977 1069 //
ec0cdc0e 1070 return iErr;
7fd59977 1071}
7fd59977 1072//=======================================================================
ec0cdc0e 1073//function : DistPC
1074//purpose :
7fd59977 1075//=======================================================================
ec0cdc0e 1076Standard_Integer DistPC(const Standard_Real aT1,
1077 const Handle(Geom_Curve)& theC1,
1078 const Standard_Real theCriteria,
1079 GeomAPI_ProjectPointOnCurve& theProjPC,
1080 Standard_Real& aD,
1081 Standard_Real& aT2,
1082 Standard_Real& aDmax,
1083 Standard_Real& aT1max,
1084 Standard_Real& aT2max,
1085 const Standard_Integer iC)
7fd59977 1086{
ec0cdc0e 1087 Standard_Integer iErr;
7fd59977 1088 //
ec0cdc0e 1089 iErr = DistPC(aT1, theC1, theCriteria, theProjPC, aD, aT2, iC);
1090 if (iErr) {
1091 return iErr;
7fd59977 1092 }
1093 //
ec0cdc0e 1094 if (iC*(aD - aDmax) > 0) {
1095 aDmax = aD;
1096 aT1max = aT1;
1097 aT2max = aT2;
7fd59977 1098 }
1099 //
ec0cdc0e 1100 return iErr;
1101}
1102//=======================================================================
1103//function : DistPC
1104//purpose :
1105//=======================================================================
1106Standard_Integer DistPC(const Standard_Real aT1,
1107 const Handle(Geom_Curve)& theC1,
1108 const Standard_Real theCriteria,
1109 GeomAPI_ProjectPointOnCurve& theProjPC,
1110 Standard_Real& aD,
1111 Standard_Real& aT2,
1112 const Standard_Integer iC)
1113{
1114 Standard_Integer iErr, aNbP2;
1115 gp_Pnt aP1;
1116 //
1117 iErr = 0;
1118 theC1->D0(aT1, aP1);
1119 //
1120 theProjPC.Perform(aP1);
1121 aNbP2 = theProjPC.NbPoints();
1122 if (!aNbP2) {
1123 iErr = 1;// the point from aC1 can not be projected on aC2
1124 return iErr;
7fd59977 1125 }
1126 //
ec0cdc0e 1127 aD = theProjPC.LowerDistance();
1128 aT2 = theProjPC.LowerDistanceParameter();
1129 if (iC*(aD - theCriteria) > 0) {
1130 iErr = 2;// the distance is too big or small
7fd59977 1131 }
1132 //
ec0cdc0e 1133 return iErr;
7fd59977 1134}
ec0cdc0e 1135
7fd59977 1136//=======================================================================
ec0cdc0e 1137//function : SplitRangeOnSegments
7fd59977 1138//purpose :
1139//=======================================================================
6b1fe48c 1140void SplitRangeOnSegments(const Standard_Real aT1,
1141 const Standard_Real aT2,
1142 const Standard_Real theResolution,
1143 const Standard_Integer theNbSeg,
1144 IntTools_SequenceOfRanges& theSegments)
7fd59977 1145{
6b1fe48c 1146 Standard_Real aDiff = aT2 - aT1;
a4e383e1 1147 if (aDiff < theResolution || theNbSeg == 1) {
0d19eb34 1148 theSegments.Append(IntTools_Range(aT1, aT2));
6b1fe48c 1149 return;
0d19eb34 1150 }
1151 //
ec0cdc0e 1152 Standard_Real aDt, aT1x, aT2x, aSeg;
1153 Standard_Integer aNbSegments, i;
1154 //
1155 aNbSegments = theNbSeg;
6b1fe48c 1156 aDt = aDiff / aNbSegments;
ec0cdc0e 1157 if (aDt < theResolution) {
6b1fe48c 1158 aSeg = aDiff / theResolution;
0d19eb34 1159 aNbSegments = Standard_Integer(aSeg) + 1;
6b1fe48c 1160 aDt = aDiff / aNbSegments;
7fd59977 1161 }
ec0cdc0e 1162 //
ec0cdc0e 1163 aT1x = aT1;
6b1fe48c 1164 for (i = 1; i < aNbSegments; ++i) {
ec0cdc0e 1165 aT2x = aT1x + aDt;
ec0cdc0e 1166 //
1167 IntTools_Range aR(aT1x, aT2x);
1168 theSegments.Append(aR);
1169 //
1170 aT1x = aT2x;
7fd59977 1171 }
0d19eb34 1172 //
6b1fe48c 1173 IntTools_Range aR(aT1x, aT2);
1174 theSegments.Append(aR);
ec0cdc0e 1175}
7fd59977 1176
ec0cdc0e 1177//=======================================================================
1178//function : BndBuildBox
1179//purpose :
1180//=======================================================================
1181void BndBuildBox(const BRepAdaptor_Curve& theBAC,
1182 const Standard_Real aT1,
1183 const Standard_Real aT2,
1184 const Standard_Real theTol,
1185 Bnd_Box& theBox)
1186{
1187 Bnd_Box aB;
1188 BndLib_Add3dCurve::Add(theBAC, aT1, aT2, theTol, aB);
1189 theBox = aB;
1190}
7fd59977 1191
6b1fe48c 1192//=======================================================================
1193//function : PointBoxDistance
1194//purpose :
1195//=======================================================================
1196Standard_Real PointBoxDistance(const Bnd_Box& aB,
1197 const gp_Pnt& aP)
1198{
1199 Standard_Real aPCoord[3];
1200 Standard_Real aBMinCoord[3], aBMaxCoord[3];
1201 Standard_Real aDist, aR1, aR2;
1202 Standard_Integer i;
1203 //
1204 aP.Coord(aPCoord[0], aPCoord[1], aPCoord[2]);
1205 aB.Get(aBMinCoord[0], aBMinCoord[1], aBMinCoord[2],
1206 aBMaxCoord[0], aBMaxCoord[1], aBMaxCoord[2]);
1207 //
1208 aDist = 0.;
1209 for (i = 0; i < 3; ++i) {
1210 aR1 = aBMinCoord[i] - aPCoord[i];
1211 if (aR1 > 0.) {
1212 aDist += aR1*aR1;
1213 continue;
1214 }
1215 //
1216 aR2 = aPCoord[i] - aBMaxCoord[i];
1217 if (aR2 > 0.) {
1218 aDist += aR2*aR2;
1219 }
1220 }
1221 //
1222 aDist = Sqrt(aDist);
1223 return aDist;
1224}
1225
ec0cdc0e 1226//=======================================================================
1227//function : TypeToInteger
1228//purpose :
1229//=======================================================================
1230Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType)
1231{
1232 Standard_Integer iRet;
bd05fabf 1233 //
ec0cdc0e 1234 switch(theCType) {
1235 case GeomAbs_Line:
1236 iRet=0;
1237 break;
ec0cdc0e 1238 case GeomAbs_Hyperbola:
1239 case GeomAbs_Parabola:
3e594885 1240 iRet=1;
1241 break;
1242 case GeomAbs_Circle:
1243 case GeomAbs_Ellipse:
ec0cdc0e 1244 iRet=2;
1245 break;
1246 case GeomAbs_BezierCurve:
1247 case GeomAbs_BSplineCurve:
1248 iRet=3;
1249 break;
1250 default:
1251 iRet=4;
1252 break;
1253 }
1254 return iRet;
7fd59977 1255}
ec0cdc0e 1256
a4e383e1 1257//=======================================================================
1258//function : ResolutionCoeff
1259//purpose :
1260//=======================================================================
1261Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
1262 const IntTools_Range& theRange)
1263{
1264 Standard_Real aResCoeff;
1265 //
1266 const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
1267 const GeomAbs_CurveType aCurveType = theBAC.GetType();
1268 //
1269 switch (aCurveType) {
1270 case GeomAbs_Circle :
1271 aResCoeff = 1. / (2 * (*((Handle(Geom_Circle)*)&aCurve))->Circ().Radius());
1272 break;
1273 case GeomAbs_Ellipse :
1274 aResCoeff = 1. / (*((Handle(Geom_Ellipse)*)&aCurve))->MajorRadius();
1275 break;
1276 case GeomAbs_Hyperbola :
1277 case GeomAbs_Parabola :
1278 case GeomAbs_OtherCurve :{
1279 Standard_Real k, kMin, aDist, aDt, aT1, aT2, aT;
1280 Standard_Integer aNbP, i;
1281 gp_Pnt aP1, aP2;
1282 //
1283 aNbP = 30;
1284 theRange.Range(aT1, aT2);
1285 aDt = (aT2 - aT1) / aNbP;
1286 aT = aT1;
1287 kMin = 10.;
1288 //
1289 theBAC.D0(aT1, aP1);
1290 for (i = 1; i <= aNbP; ++i) {
1291 aT += aDt;
1292 theBAC.D0(aT, aP2);
1293 aDist = aP1.Distance(aP2);
1294 k = aDt / aDist;
1295 if (k < kMin) {
1296 kMin = k;
1297 }
1298 aP1 = aP2;
1299 }
1300 //
1301 aResCoeff = kMin;
1302 break;
1303 }
1304 default:
1305 aResCoeff = 0.;
1306 break;
1307 }
1308 //
1309 return aResCoeff;
1310}
1311
1312//=======================================================================
1313//function : Resolution
1314//purpose :
1315//=======================================================================
1316Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
1317 const GeomAbs_CurveType theCurveType,
1318 const Standard_Real theResCoeff,
1319 const Standard_Real theR3D)
1320{
1321 Standard_Real aRes;
1322 //
1323 switch (theCurveType) {
1324 case GeomAbs_Line :
1325 aRes = theR3D;
1326 break;
1327 case GeomAbs_Circle: {
1328 Standard_Real aDt = theResCoeff * theR3D;
1329 aRes = (aDt <= 1.) ? 2*ASin(aDt) : 2*M_PI;
1330 break;
1331 }
1332 case GeomAbs_BezierCurve:
1333 (*((Handle(Geom_BezierCurve)*)&theCurve))->Resolution(theR3D, aRes);
1334 break;
1335 case GeomAbs_BSplineCurve:
1336 (*((Handle(Geom_BSplineCurve)*)&theCurve))->Resolution(theR3D, aRes);
1337 break;
1338 default:
1339 aRes = theResCoeff * theR3D;
1340 break;
1341 }
1342 //
1343 return aRes;
1344}
1345
1346//=======================================================================
1347//function : CurveDeflection
1348//purpose :
1349//=======================================================================
1350Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
1351 const IntTools_Range& theRange)
1352{
1353 Standard_Real aDt, aT, aT1, aT2, aDefl;
1354 Standard_Integer i, aNbP;
1355 gp_Vec aV1, aV2;
1356 gp_Pnt aP;
1357 //
1358 aDefl = 0;
1359 aNbP = 10;
1360 theRange.Range(aT1, aT2);
1361 aDt = (aT2 - aT1) / aNbP;
1362 aT = aT1;
1363 //
1364 theBAC.D1(aT1, aP, aV1);
1365 for (i = 1; i <= aNbP; ++i) {
1366 aT += aDt;
1367 theBAC.D1(aT, aP, aV2);
1368 if (aV1.Magnitude() > gp::Resolution() &&
1369 aV2.Magnitude() > gp::Resolution()) {
1370 gp_Dir aD1(aV1), aD2(aV2);
1371 aDefl += aD1.Angle(aD2);
1372 }
1373 aV1 = aV2;
1374 }
1375 //
1376 return aDefl;
1377}
1378
3e594885 1379//=======================================================================
1380//function : IsClosed
1381//purpose :
1382//=======================================================================
1383Standard_Integer IsClosed(const Handle(Geom_Curve)& theCurve,
1384 const Standard_Real aT1,
1385 const Standard_Real aT2,
1386 const Standard_Real theTol,
1387 const Standard_Real theRes)
1388{
1389 Standard_Boolean bClosed;
1390 Standard_Real aD;
1391 gp_Pnt aP1, aP2;
1392 //
1393 bClosed = Standard_False;
1394 if (Abs(aT1 - aT2) < theRes) {
1395 return bClosed;
1396 }
1397 //
1398 theCurve->D0(aT1, aP1);
1399 theCurve->D0(aT2, aP2);
1400 //
1401 aD = aP1.Distance(aP2);
1402 bClosed = aD < theTol;
1403 //
1404 return bClosed;
1405}