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