Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 | 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 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 | //------------------------------------------------------------------------ |
0d969553 Y |
16 | // Calculate a point with given abscissa starting from a given point |
17 | // cases processed: straight segment, arc of circle, parameterized curve | |
18 | // curve should be C1 | |
0d969553 | 19 | // for a parameterized curve: |
0d969553 Y |
20 | // calculate the total length of the curve |
21 | // calculate an approached point by assimilating the curve to a staight line | |
22 | // calculate the length of the curve between the start point and the approached point | |
23 | // by succsessive iteration find the point and its associated parameter | |
24 | // call to FunctionRoot | |
7fd59977 | 25 | |
42cf5bc1 | 26 | #include <Adaptor2d_Curve2d.hxx> |
27 | #include <Adaptor3d_Curve.hxx> | |
28 | #include <CPnts_AbscissaPoint.hxx> | |
7fd59977 | 29 | #include <Geom2d_BezierCurve.hxx> |
30 | #include <Geom2d_BSplineCurve.hxx> | |
42cf5bc1 | 31 | #include <Geom_BezierCurve.hxx> |
32 | #include <Geom_BSplineCurve.hxx> | |
33 | #include <gp_Vec.hxx> | |
34 | #include <gp_Vec2d.hxx> | |
35 | #include <math_FunctionRoot.hxx> | |
36 | #include <math_GaussSingleIntegration.hxx> | |
7fd59977 | 37 | #include <Precision.hxx> |
42cf5bc1 | 38 | #include <Standard_ConstructionError.hxx> |
39 | #include <StdFail_NotDone.hxx> | |
7fd59977 | 40 | |
41 | // auxiliary functions to compute the length of the derivative | |
7fd59977 | 42 | static Standard_Real f3d(const Standard_Real X, const Standard_Address C) |
43 | { | |
81093856 | 44 | gp_Pnt P; |
45 | gp_Vec V; | |
46 | ((Adaptor3d_Curve*)C)->D1(X,P,V); | |
7fd59977 | 47 | return V.Magnitude(); |
48 | } | |
49 | ||
50 | static Standard_Real f2d(const Standard_Real X, const Standard_Address C) | |
51 | { | |
81093856 | 52 | gp_Pnt2d P; |
53 | gp_Vec2d V; | |
54 | ((Adaptor2d_Curve2d*)C)->D1(X,P,V); | |
7fd59977 | 55 | return V.Magnitude(); |
56 | } | |
57 | ||
58 | static Standard_Integer order(const Adaptor3d_Curve& C) | |
59 | { | |
60 | switch (C.GetType()) { | |
61 | ||
62 | case GeomAbs_Line : | |
63 | return 2; | |
64 | ||
65 | case GeomAbs_Parabola : | |
66 | return 5; | |
67 | ||
68 | case GeomAbs_BezierCurve : | |
e2f0aca0 | 69 | return Min(24, 2*C.Degree()); |
7fd59977 | 70 | |
71 | case GeomAbs_BSplineCurve : | |
e2f0aca0 | 72 | return Min(24, 2*C.NbPoles()-1); |
7fd59977 | 73 | |
74 | default : | |
75 | return 10; | |
76 | } | |
77 | } | |
78 | ||
79 | static Standard_Integer order(const Adaptor2d_Curve2d& C) | |
80 | { | |
81 | switch (C.GetType()) { | |
82 | ||
83 | case GeomAbs_Line : | |
84 | return 2; | |
85 | ||
86 | case GeomAbs_Parabola : | |
87 | return 5; | |
88 | ||
89 | case GeomAbs_BezierCurve : | |
90 | return Min(24, 2*C.Bezier()->Degree()); | |
91 | ||
92 | case GeomAbs_BSplineCurve : | |
93 | return Min(24, 2*C.BSpline()->NbPoles()-1); | |
94 | ||
95 | default : | |
96 | return 10; | |
97 | } | |
98 | } | |
99 | ||
100 | ||
101 | //======================================================================= | |
102 | //function : Length | |
103 | //purpose : 3d | |
104 | //======================================================================= | |
105 | ||
106 | Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C) | |
107 | { | |
108 | return CPnts_AbscissaPoint::Length(C, C.FirstParameter(), | |
109 | C.LastParameter()); | |
110 | } | |
111 | ||
112 | //======================================================================= | |
113 | //function : Length | |
114 | //purpose : 2d | |
115 | //======================================================================= | |
116 | ||
117 | Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C) | |
118 | { | |
119 | return CPnts_AbscissaPoint::Length(C, C.FirstParameter(), | |
120 | C.LastParameter()); | |
121 | } | |
122 | ||
123 | //======================================================================= | |
124 | //function : Length | |
125 | //purpose : 3d with tolerance | |
126 | //======================================================================= | |
127 | ||
128 | Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C, const Standard_Real Tol) | |
129 | { | |
130 | return CPnts_AbscissaPoint::Length(C, C.FirstParameter(), | |
131 | C.LastParameter(), Tol); | |
132 | } | |
133 | ||
134 | //======================================================================= | |
135 | //function : Length | |
136 | //purpose : 2d with tolerance | |
137 | //======================================================================= | |
138 | ||
139 | Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C, const Standard_Real Tol) | |
140 | { | |
141 | return CPnts_AbscissaPoint::Length(C, C.FirstParameter(), | |
142 | C.LastParameter(), Tol); | |
143 | } | |
144 | ||
145 | ||
146 | //======================================================================= | |
147 | //function : Length | |
148 | //purpose : 3d with parameters | |
149 | //======================================================================= | |
150 | ||
151 | Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C, | |
152 | const Standard_Real U1, | |
153 | const Standard_Real U2) | |
154 | { | |
155 | CPnts_MyGaussFunction FG; | |
156 | //POP pout WNT | |
157 | CPnts_RealFunction rf = f3d; | |
158 | FG.Init(rf,(Standard_Address)&C); | |
159 | // FG.Init(f3d,(Standard_Address)&C); | |
160 | math_GaussSingleIntegration TheLength(FG, U1, U2, order(C)); | |
161 | if (!TheLength.IsDone()) { | |
9775fa61 | 162 | throw Standard_ConstructionError(); |
7fd59977 | 163 | } |
164 | return Abs(TheLength.Value()); | |
165 | } | |
166 | ||
167 | //======================================================================= | |
168 | //function : Length | |
169 | //purpose : 2d with parameters | |
170 | //======================================================================= | |
171 | ||
172 | Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C, | |
173 | const Standard_Real U1, | |
174 | const Standard_Real U2) | |
175 | { | |
176 | CPnts_MyGaussFunction FG; | |
177 | //POP pout WNT | |
178 | CPnts_RealFunction rf = f2d; | |
179 | FG.Init(rf,(Standard_Address)&C); | |
180 | // FG.Init(f2d,(Standard_Address)&C); | |
181 | math_GaussSingleIntegration TheLength(FG, U1, U2, order(C)); | |
182 | if (!TheLength.IsDone()) { | |
9775fa61 | 183 | throw Standard_ConstructionError(); |
7fd59977 | 184 | } |
185 | return Abs(TheLength.Value()); | |
186 | } | |
187 | ||
188 | //======================================================================= | |
189 | //function : Length | |
190 | //purpose : 3d with parameters and tolerance | |
191 | //======================================================================= | |
192 | ||
193 | Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C, | |
194 | const Standard_Real U1, | |
195 | const Standard_Real U2, | |
196 | const Standard_Real Tol) | |
197 | { | |
198 | CPnts_MyGaussFunction FG; | |
199 | //POP pout WNT | |
200 | CPnts_RealFunction rf = f3d; | |
201 | FG.Init(rf,(Standard_Address)&C); | |
202 | // FG.Init(f3d,(Standard_Address)&C); | |
203 | math_GaussSingleIntegration TheLength(FG, U1, U2, order(C), Tol); | |
204 | if (!TheLength.IsDone()) { | |
9775fa61 | 205 | throw Standard_ConstructionError(); |
7fd59977 | 206 | } |
207 | return Abs(TheLength.Value()); | |
208 | } | |
209 | ||
210 | //======================================================================= | |
211 | //function : Length | |
212 | //purpose : 2d with parameters and tolerance | |
213 | //======================================================================= | |
214 | ||
215 | Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C, | |
216 | const Standard_Real U1, | |
217 | const Standard_Real U2, | |
218 | const Standard_Real Tol) | |
219 | { | |
220 | CPnts_MyGaussFunction FG; | |
221 | //POP pout WNT | |
222 | CPnts_RealFunction rf = f2d; | |
223 | FG.Init(rf,(Standard_Address)&C); | |
224 | // FG.Init(f2d,(Standard_Address)&C); | |
225 | math_GaussSingleIntegration TheLength(FG, U1, U2, order(C), Tol); | |
226 | if (!TheLength.IsDone()) { | |
9775fa61 | 227 | throw Standard_ConstructionError(); |
7fd59977 | 228 | } |
229 | return Abs(TheLength.Value()); | |
230 | } | |
231 | ||
232 | //======================================================================= | |
233 | //function : CPnts_AbscissaPoint | |
234 | //purpose : | |
235 | //======================================================================= | |
236 | ||
237 | CPnts_AbscissaPoint::CPnts_AbscissaPoint() : myDone(Standard_False) | |
238 | { | |
239 | } | |
240 | ||
241 | //======================================================================= | |
242 | //function : CPnts_AbscissaPoint | |
243 | //purpose : | |
244 | //======================================================================= | |
245 | ||
246 | CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor3d_Curve& C, | |
247 | const Standard_Real Abscissa, | |
248 | const Standard_Real U0, | |
249 | const Standard_Real Resolution) | |
250 | { | |
251 | // Init(C); | |
252 | Init(C, Resolution); //rbv's modification | |
253 | // | |
254 | Perform(Abscissa, U0, Resolution); | |
255 | } | |
256 | ||
257 | //======================================================================= | |
258 | //function : CPnts_AbscissaPoint | |
259 | //purpose : | |
260 | //======================================================================= | |
261 | ||
262 | CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor2d_Curve2d& C, | |
263 | const Standard_Real Abscissa, | |
264 | const Standard_Real U0, | |
265 | const Standard_Real Resolution) | |
266 | { | |
267 | Init(C); | |
268 | Perform(Abscissa, U0, Resolution); | |
269 | } | |
270 | ||
271 | ||
272 | //======================================================================= | |
273 | //function : CPnts_AbscissaPoint | |
274 | //purpose : | |
275 | //======================================================================= | |
276 | ||
277 | CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor3d_Curve& C, | |
278 | const Standard_Real Abscissa, | |
279 | const Standard_Real U0, | |
280 | const Standard_Real Ui, | |
281 | const Standard_Real Resolution) | |
282 | { | |
283 | Init(C); | |
284 | Perform(Abscissa, U0, Ui, Resolution); | |
285 | } | |
286 | ||
287 | //======================================================================= | |
288 | //function : CPnts_AbscissaPoint | |
289 | //purpose : | |
290 | //======================================================================= | |
291 | ||
292 | CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor2d_Curve2d& C, | |
293 | const Standard_Real Abscissa, | |
294 | const Standard_Real U0, | |
295 | const Standard_Real Ui, | |
296 | const Standard_Real Resolution) | |
297 | { | |
298 | Init(C); | |
299 | Perform(Abscissa, U0, Ui, Resolution); | |
300 | } | |
301 | ||
302 | ||
303 | //======================================================================= | |
304 | //function : Init | |
305 | //purpose : | |
306 | //======================================================================= | |
307 | ||
308 | void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C) | |
309 | { | |
310 | Init(C,C.FirstParameter(),C.LastParameter()); | |
311 | } | |
312 | ||
313 | //======================================================================= | |
314 | //function : Init | |
315 | //purpose : | |
316 | //======================================================================= | |
317 | ||
318 | void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C) | |
319 | { | |
320 | Init(C,C.FirstParameter(),C.LastParameter()); | |
321 | } | |
322 | ||
323 | //======================================================================= | |
324 | //function : Init | |
325 | //purpose : introduced by rbv for curvilinear parametrization | |
326 | //======================================================================= | |
327 | ||
328 | void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C, const Standard_Real Tol) | |
329 | { | |
330 | Init(C,C.FirstParameter(),C.LastParameter(), Tol); | |
331 | } | |
332 | ||
333 | //======================================================================= | |
334 | //function : Init | |
335 | //purpose : | |
336 | //======================================================================= | |
337 | ||
338 | void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C, const Standard_Real Tol) | |
339 | { | |
340 | Init(C,C.FirstParameter(),C.LastParameter(), Tol); | |
341 | } | |
342 | ||
343 | //======================================================================= | |
344 | //function : Init | |
345 | //purpose : | |
346 | //======================================================================= | |
347 | ||
348 | void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C, | |
349 | const Standard_Real U1, | |
350 | const Standard_Real U2) | |
351 | { | |
352 | //POP pout WNT | |
353 | CPnts_RealFunction rf = f3d; | |
354 | myF.Init(rf,(Standard_Address)&C,order(C)); | |
355 | // myF.Init(f3d,(Standard_Address)&C,order(C)); | |
356 | myL = CPnts_AbscissaPoint::Length(C, U1, U2); | |
357 | myUMin = Min(U1, U2); | |
358 | myUMax = Max(U1, U2); | |
359 | Standard_Real DU = myUMax - myUMin; | |
360 | myUMin = myUMin - DU; | |
361 | myUMax = myUMax + DU; | |
362 | } | |
363 | ||
364 | //======================================================================= | |
365 | //function : Init | |
366 | //purpose : | |
367 | //======================================================================= | |
368 | ||
369 | void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C, | |
370 | const Standard_Real U1, | |
371 | const Standard_Real U2) | |
372 | { | |
373 | //POP pout WNT | |
374 | CPnts_RealFunction rf = f2d; | |
375 | myF.Init(rf,(Standard_Address)&C,order(C)); | |
376 | // myF.Init(f2d,(Standard_Address)&C,order(C)); | |
377 | myL = CPnts_AbscissaPoint::Length(C, U1, U2); | |
378 | myUMin = Min(U1, U2); | |
379 | myUMax = Max(U1, U2); | |
380 | Standard_Real DU = myUMax - myUMin; | |
381 | myUMin = myUMin - DU; | |
382 | myUMax = myUMax + DU; | |
383 | } | |
384 | ||
385 | ||
386 | //======================================================================= | |
387 | //function : Init | |
388 | //purpose : introduced by rbv for curvilinear parametrization | |
389 | //======================================================================= | |
390 | ||
391 | void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C, | |
392 | const Standard_Real U1, | |
393 | const Standard_Real U2, | |
394 | const Standard_Real Tol) | |
395 | { | |
396 | //POP pout WNT | |
397 | CPnts_RealFunction rf = f3d; | |
398 | myF.Init(rf,(Standard_Address)&C,order(C)); | |
399 | // myF.Init(f3d,(Standard_Address)&C,order(C)); | |
400 | myL = CPnts_AbscissaPoint::Length(C, U1, U2, Tol); | |
401 | myUMin = Min(U1, U2); | |
402 | myUMax = Max(U1, U2); | |
403 | Standard_Real DU = myUMax - myUMin; | |
404 | myUMin = myUMin - DU; | |
405 | myUMax = myUMax + DU; | |
406 | } | |
407 | ||
408 | //======================================================================= | |
409 | //function : Init | |
410 | //purpose : | |
411 | //======================================================================= | |
412 | ||
413 | void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C, | |
414 | const Standard_Real U1, | |
415 | const Standard_Real U2, | |
416 | const Standard_Real Tol) | |
417 | { | |
418 | //POP pout WNT | |
419 | CPnts_RealFunction rf = f2d; | |
420 | myF.Init(rf,(Standard_Address)&C,order(C)); | |
421 | // myF.Init(f2d,(Standard_Address)&C,order(C)); | |
422 | myL = CPnts_AbscissaPoint::Length(C, U1, U2, Tol); | |
423 | myUMin = Min(U1, U2); | |
424 | myUMax = Max(U1, U2); | |
425 | Standard_Real DU = myUMax - myUMin; | |
426 | myUMin = myUMin - DU; | |
427 | myUMax = myUMax + DU; | |
428 | } | |
429 | ||
430 | //======================================================================= | |
431 | //function : Perform | |
432 | //purpose : | |
433 | //======================================================================= | |
434 | ||
435 | void CPnts_AbscissaPoint::Perform(const Standard_Real Abscissa, | |
436 | const Standard_Real U0, | |
437 | const Standard_Real Resolution) | |
438 | { | |
439 | if (myL < Precision::Confusion()) { | |
440 | // | |
0d969553 Y |
441 | // leave less violently : it is expected that |
442 | // the increment of the level of myParam will not be great | |
7fd59977 | 443 | // |
444 | myDone = Standard_True ; | |
445 | myParam = U0 ; | |
446 | ||
447 | } | |
448 | else { | |
449 | Standard_Real Ui = U0 + (Abscissa / myL) * (myUMax - myUMin) / 3.; | |
450 | // exercice : why 3 ? | |
451 | Perform(Abscissa,U0,Ui,Resolution); | |
452 | } | |
453 | } | |
454 | ||
455 | //======================================================================= | |
456 | //function : Perform | |
457 | //purpose : | |
458 | //======================================================================= | |
459 | ||
460 | void CPnts_AbscissaPoint::Perform(const Standard_Real Abscissa, | |
461 | const Standard_Real U0, | |
462 | const Standard_Real Ui, | |
463 | const Standard_Real Resolution) | |
464 | { | |
465 | if (myL < Precision::Confusion()) { | |
466 | // | |
0d969553 | 467 | // leave less violently : |
7fd59977 | 468 | // |
469 | myDone = Standard_True ; | |
470 | myParam = U0 ; | |
471 | } | |
472 | else { | |
473 | myDone = Standard_False; | |
474 | myF.Init(U0, Abscissa); | |
475 | ||
476 | math_FunctionRoot Solution(myF, Ui, Resolution, myUMin, myUMax); | |
477 | ||
0d969553 Y |
478 | // Temporarily suspend the validity test of the solution |
479 | // it is necessary to make a tolreached as soon as one will make a cdl | |
7fd59977 | 480 | // lbo 21/03/97 |
481 | // if (Solution.IsDone()) { | |
482 | // Standard_Real D; | |
483 | // myF.Derivative(Solution.Root(),D); | |
484 | // if (Abs(Solution.Value()) < Resolution * D) { | |
485 | // myDone = Standard_True; | |
486 | // myParam = Solution.Root(); | |
487 | // } | |
488 | // } | |
489 | if (Solution.IsDone()) { | |
490 | myDone = Standard_True; | |
491 | myParam = Solution.Root(); | |
492 | } | |
493 | } | |
494 | } | |
495 | ||
496 | //======================================================================= | |
497 | //function : AdvPerform | |
498 | //purpose : | |
499 | //======================================================================= | |
500 | ||
501 | void CPnts_AbscissaPoint::AdvPerform(const Standard_Real Abscissa, | |
502 | const Standard_Real U0, | |
503 | const Standard_Real Ui, | |
504 | const Standard_Real Resolution) | |
505 | { | |
506 | if (myL < Precision::Confusion()) { | |
507 | // | |
0d969553 | 508 | // leave less violently : |
7fd59977 | 509 | // |
510 | myDone = Standard_True ; | |
511 | myParam = U0 ; | |
512 | } | |
513 | else { | |
514 | myDone = Standard_False; | |
515 | // myF.Init(U0, Abscissa); | |
516 | myF.Init(U0, Abscissa, Resolution/10); // rbv's modification | |
517 | ||
518 | math_FunctionRoot Solution(myF, Ui, Resolution, myUMin, myUMax); | |
519 | ||
0d969553 Y |
520 | // Temporarily suspend the validity test of the solution |
521 | // it is necessary to make a tolreached as soon as one will make a cdl | |
7fd59977 | 522 | // lbo 21/03/97 |
523 | // if (Solution.IsDone()) { | |
524 | // Standard_Real D; | |
525 | // myF.Derivative(Solution.Root(),D); | |
526 | // if (Abs(Solution.Value()) < Resolution * D) { | |
527 | // myDone = Standard_True; | |
528 | // myParam = Solution.Root(); | |
529 | // } | |
530 | // } | |
531 | if (Solution.IsDone()) { | |
532 | myDone = Standard_True; | |
533 | myParam = Solution.Root(); | |
534 | } | |
535 | } | |
536 | } |