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