0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / CPnts / CPnts_AbscissaPoint.cxx
CommitLineData
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 42static 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
50static 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
58static 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
79static 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
106Standard_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
117Standard_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
128Standard_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
139Standard_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
151Standard_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
172Standard_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
193Standard_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
215Standard_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
237CPnts_AbscissaPoint::CPnts_AbscissaPoint() : myDone(Standard_False)
238{
239}
240
241//=======================================================================
242//function : CPnts_AbscissaPoint
243//purpose :
244//=======================================================================
245
246CPnts_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
262CPnts_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
277CPnts_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
292CPnts_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
308void 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
318void 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
328void 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
338void 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
348void 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
369void 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
391void 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
413void 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
435void 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
460void 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
501void 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}