0031043: GCPnts_TangentialDeflection generates points which number is inconsistent...
[occt.git] / src / GCPnts / GCPnts_TangentialDeflection.pxx
CommitLineData
b311480e 1// Created on: 1996-11-08
2// Created by: Jean Claude VAUTHIER
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <GCPnts_DeflectionType.hxx>
18#include <Standard_ConstructionError.hxx>
19#include <Precision.hxx>
20#include <gp_XYZ.hxx>
21#include <gp_Pnt.hxx>
22#include <gp_Vec.hxx>
23#include <gp.hxx>
9c1519c4 24#include <NCollection_List.hxx>
25#include <math_PSO.hxx>
26#include <math_BrentMinimum.hxx>
7fd59977 27
28#define Us3 0.3333333333333333333333333333
29
30void GCPnts_TangentialDeflection::EvaluateDu (
31 const TheCurve& C,
32 const Standard_Real U,
4071d9e6
O
33 gp_Pnt& P,
34 Standard_Real& Du,
35 Standard_Boolean& NotDone) const {
7fd59977 36
37 gp_Vec T, N;
38 D2 (C, U, P, T, N);
39 Standard_Real Lt = T.Magnitude ();
40 Standard_Real LTol = Precision::Confusion ();
41 if (Lt > LTol && N.Magnitude () > LTol) {
42 Standard_Real Lc = N.CrossMagnitude (T);
4071d9e6
O
43 Standard_Real Ln = Lc/Lt;
44 if (Ln > LTol) {
74da0216 45 Du = sqrt (8.0 * Max(curvatureDeflection, myMinLen) / Ln);
7fd59977 46 NotDone = Standard_False;
47 }
48 }
49}
50
51
52//=======================================================================
53//function : GCPnts_TangentialDeflection
54//purpose :
55//=======================================================================
56
57GCPnts_TangentialDeflection::GCPnts_TangentialDeflection (
58 const TheCurve& C,
59 const Standard_Real AngularDeflection,
60 const Standard_Real CurvatureDeflection,
61 const Standard_Integer MinimumOfPoints,
74da0216 62 const Standard_Real UTol,
63 const Standard_Real theMinLen)
7fd59977 64
65{
74da0216 66 Initialize (C,AngularDeflection,CurvatureDeflection,MinimumOfPoints,UTol,theMinLen);
7fd59977 67}
68
69
70//=======================================================================
71//function : GCPnts_TangentialDeflection
72//purpose :
73//=======================================================================
74
75GCPnts_TangentialDeflection::GCPnts_TangentialDeflection (
76 const TheCurve& C,
77 const Standard_Real FirstParameter,
78 const Standard_Real LastParameter,
79 const Standard_Real AngularDeflection,
80 const Standard_Real CurvatureDeflection,
81 const Standard_Integer MinimumOfPoints,
74da0216 82 const Standard_Real UTol,
83 const Standard_Real theMinLen)
7fd59977 84
85{
86 Initialize (C,
4071d9e6
O
87 FirstParameter,
88 LastParameter,
89 AngularDeflection,
90 CurvatureDeflection,
91 MinimumOfPoints,
74da0216 92 UTol, theMinLen);
7fd59977 93}
94
95
96
97//=======================================================================
98//function : Initialize
99//purpose :
100//=======================================================================
101
102void GCPnts_TangentialDeflection::Initialize (
103 const TheCurve& C,
104 const Standard_Real AngularDeflection,
105 const Standard_Real CurvatureDeflection,
106 const Standard_Integer MinimumOfPoints,
74da0216 107 const Standard_Real UTol,
108 const Standard_Real theMinLen)
7fd59977 109
110{
111 Initialize (C,
112 C.FirstParameter (),
113 C.LastParameter (),
114 AngularDeflection,
115 CurvatureDeflection,
4071d9e6 116 MinimumOfPoints,
74da0216 117 UTol, theMinLen);
7fd59977 118}
119
120
121//=======================================================================
122//function : Initialize
123//purpose :
124//=======================================================================
125
126void GCPnts_TangentialDeflection::Initialize (
127 const TheCurve& C,
128 const Standard_Real FirstParameter,
129 const Standard_Real LastParameter,
130 const Standard_Real AngularDeflection,
131 const Standard_Real CurvatureDeflection,
132 const Standard_Integer MinimumOfPoints,
74da0216 133 const Standard_Real UTol,
134 const Standard_Real theMinLen)
7fd59977 135
136{
137
51cf5bb6 138 Standard_ConstructionError_Raise_if (CurvatureDeflection < Precision::Confusion () ||
139 AngularDeflection < Precision::Angular (),
140 "GCPnts_TangentialDeflection::Initialize - Zero Deflection")
7fd59977 141
142 parameters.Clear ();
143 points .Clear ();
144 if (FirstParameter < LastParameter) {
145 firstu = FirstParameter;
146 lastu = LastParameter;
147 }
148 else {
149 lastu = FirstParameter;
150 firstu = LastParameter;
151 }
152 uTol = UTol;
153 angularDeflection = AngularDeflection;
154 curvatureDeflection = CurvatureDeflection;
155 minNbPnts = Max (MinimumOfPoints, 2);
74da0216 156 myMinLen = Max(theMinLen, Precision::Confusion());
7fd59977 157
158 switch (C.GetType()) {
159
160 case GeomAbs_Line:
161 PerformLinear (C);
162 break;
163
164 case GeomAbs_Circle:
165 PerformCircular (C);
166 break;
167
168 case GeomAbs_BSplineCurve:
169 {
170 Handle_TheBSplineCurve BS = C.BSpline() ;
171 if (BS->NbPoles() == 2 ) PerformLinear (C);
4071d9e6 172 else PerformCurve (C);
7fd59977 173 break;
174 }
175 case GeomAbs_BezierCurve:
176 {
177 Handle_TheBezierCurve BZ = C.Bezier();
178 if (BZ->NbPoles() == 2) PerformLinear (C);
4071d9e6 179 else PerformCurve (C);
7fd59977 180 break;
181 }
182 default: PerformCurve (C);
183
184 }
185}
186
187
188//=======================================================================
189//function : PerformLinear
190//purpose :
191//=======================================================================
192
193void GCPnts_TangentialDeflection::PerformLinear (const TheCurve& C) {
194
195 gp_Pnt P;
196 D0 (C, firstu, P);
197 parameters.Append (firstu);
198 points .Append (P);
da6b95a0 199 if (minNbPnts > 2)
200 {
7fd59977 201 Standard_Real Du = (lastu - firstu) / minNbPnts;
202 Standard_Real U = firstu + Du;
da6b95a0 203 for (Standard_Integer i = 2; i < minNbPnts; i++)
204 {
7fd59977 205 D0 (C, U, P);
206 parameters.Append (U);
207 points .Append (P);
208 U += Du;
209 }
210 }
211 D0 (C, lastu, P);
212 parameters.Append (lastu);
213 points .Append (P);
214}
215
7fd59977 216//=======================================================================
217//function : PerformCircular
218//purpose :
219//=======================================================================
220
221void GCPnts_TangentialDeflection::PerformCircular (const TheCurve& C)
222{
223 // akm 8/01/02 : check the radius before divide by it
224 Standard_Real dfR = C.Circle().Radius();
74da0216 225 Standard_Real Du = GCPnts_TangentialDeflection::ArcAngularStep(
226 dfR, curvatureDeflection, angularDeflection, myMinLen);
227
228 const Standard_Real aDiff = lastu - firstu;
b819ae67 229 // Round up number of points to satisfy curvatureDeflection more precisely
7bd071ed 230 Standard_Integer NbPoints = (Standard_Integer)Min(Ceiling(aDiff / Du), 1.0e+6);
74da0216 231 NbPoints = Max(NbPoints, minNbPnts - 1);
232 Du = aDiff / NbPoints;
7fd59977 233
234 gp_Pnt P;
235 Standard_Real U = firstu;
74da0216 236 for (Standard_Integer i = 1; i <= NbPoints; i++)
237 {
7fd59977 238 D0 (C, U, P);
239 parameters.Append (U);
240 points .Append (P);
241 U += Du;
242 }
243 D0 (C, lastu, P);
244 parameters.Append (lastu);
245 points .Append (P);
246}
247
248
7fd59977 249//=======================================================================
250//function : PerformCurve
251//purpose : On respecte ll'angle et la fleche, on peut imposer un nombre
252// minimum de points sur un element lineaire
253//=======================================================================
7fd59977 254void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
255
256{
d2388a81 257 Standard_Integer i, j;
7fd59977 258 gp_XYZ V1, V2;
7fd59977 259 gp_Pnt MiddlePoint, CurrentPoint, LastPoint;
4071d9e6 260 Standard_Real Du, Dusave, MiddleU, L1, L2;
7fd59977 261
262 Standard_Real U1 = firstu;
7fd59977 263 Standard_Real LTol = Precision::Confusion (); //protection longueur nulle
9c1519c4 264 Standard_Real ATol = 1.e-2 * angularDeflection;
265 if(ATol > 1.e-2)
266 ATol = 1.e-2;
267 else if(ATol < 1.e-7)
268 ATol = 1.e-7;
7fd59977 269
270 D0 (C, lastu, LastPoint);
271
272 //Initialization du calcul
7fd59977 273
274 Standard_Boolean NotDone = Standard_True;
275 Dusave = (lastu - firstu)*Us3;
276 Du = Dusave;
277 EvaluateDu (C, U1, CurrentPoint, Du, NotDone);
278 parameters.Append (U1);
279 points .Append (CurrentPoint);
280
fa89e082 281 // Used to detect "isLine" current bspline and in Du computation in general handling.
31b1749c 282 Standard_Integer NbInterv = C.NbIntervals(GeomAbs_CN);
fa89e082 283 TColStd_Array1OfReal Intervs(1, NbInterv+1);
31b1749c 284 C.Intervals(Intervs, GeomAbs_CN);
fa89e082 285
9c1519c4 286 if (NotDone || Du > 5. * Dusave) {
7fd59977 287 //C'est soit une droite, soit une singularite :
74da0216 288 V1 = (LastPoint.XYZ() - CurrentPoint.XYZ());
7fd59977 289 L1 = V1.Modulus ();
74da0216 290 if (L1 > LTol)
291 {
7fd59977 292 //Si c'est une droite on verifie en calculant minNbPoints :
293 Standard_Boolean IsLine = Standard_True;
74da0216 294 Standard_Integer NbPoints = (minNbPnts > 3) ? minNbPnts : 3;
9c1519c4 295 switch (C.GetType()) {
296 case GeomAbs_BSplineCurve:
297 {
298 Handle_TheBSplineCurve BS = C.BSpline() ;
299 NbPoints = Max(BS->Degree() + 1, NbPoints);
300 break;
301 }
302 case GeomAbs_BezierCurve:
303 {
304 Handle_TheBezierCurve BZ = C.Bezier();
305 NbPoints = Max(BZ->Degree() + 1, NbPoints);
306 break;
307 }
308 default:
309 ;}
d2388a81 310 ////
d2388a81 311 Standard_Real param = 0.;
74da0216 312 for (i = 1; i <= NbInterv && IsLine; ++i)
d2388a81 313 {
314 // Avoid usage intervals out of [firstu, lastu].
315 if ((Intervs(i+1) < firstu) ||
316 (Intervs(i) > lastu))
317 {
318 continue;
319 }
320 // Fix border points in applicable intervals, to avoid be out of target interval.
321 if ((Intervs(i) < firstu) &&
322 (Intervs(i+1) > firstu))
323 {
324 Intervs(i) = firstu;
325 }
326 if ((Intervs(i) < lastu) &&
327 (Intervs(i+1) > lastu))
328 {
329 Intervs(i + 1) = lastu;
330 }
331
332 Standard_Real delta = (Intervs(i+1) - Intervs(i))/NbPoints;
74da0216 333 for (j = 1; j <= NbPoints && IsLine; ++j)
d2388a81 334 {
335 param = Intervs(i) + j*delta;
336 D0 (C, param, MiddlePoint);
74da0216 337 V2 = (MiddlePoint.XYZ() - CurrentPoint.XYZ());
d2388a81 338 L2 = V2.Modulus ();
74da0216 339 if (L2 > LTol)
340 {
341 const Standard_Real aAngle = V2.CrossMagnitude(V1)/(L1*L2);
342 IsLine = (aAngle < ATol);
4071d9e6
O
343 }
344 }
7fd59977 345 }
74da0216 346
347 if (IsLine)
348 {
349 parameters.Clear();
350 points .Clear();
351
352 PerformLinear(C);
4071d9e6 353 return;
7fd59977 354 }
74da0216 355 else
356 {
4071d9e6 357 //c'etait une singularite on continue :
d2388a81 358 //Du = Dusave;
359 EvaluateDu (C, param, MiddlePoint, Du, NotDone);
7fd59977 360 }
361 }
74da0216 362 else
363 {
7fd59977 364 Du = (lastu-firstu)/2.1;
365 MiddleU = firstu + Du;
366 D0 (C, MiddleU, MiddlePoint);
74da0216 367 V1 = (MiddlePoint.XYZ() - CurrentPoint.XYZ());
7fd59977 368 L1 = V1.Modulus ();
74da0216 369 if (L1 < LTol)
370 {
4071d9e6
O
371 // L1 < LTol C'est une courbe de longueur nulle, calcul termine :
372 // on renvoi un segment de 2 points (protection)
373 parameters.Append (lastu);
374 points .Append (LastPoint);
375 return;
7fd59977 376 }
377 }
378 }
379
380 if (Du > Dusave) Du = Dusave;
381 else Dusave = Du;
382
383 if (Du < uTol) {
384 Du = lastu - firstu;
385 if (Du < uTol) {
386 parameters.Append (lastu);
387 points .Append (LastPoint);
388 return;
389 }
390 }
391
392 //Traitement normal pour une courbe
4071d9e6
O
393 Standard_Boolean MorePoints = Standard_True;
394 Standard_Real U2 = firstu;
395 Standard_Real AngleMax = angularDeflection * 0.5; //car on prend le point milieu
fa89e082 396 Standard_Integer aIdx[2] = {Intervs.Lower(), Intervs.Lower()}; // Indexes of intervals of U1 and U2, used to handle non-uniform case.
397 Standard_Boolean isNeedToCheck = Standard_False;
4071d9e6 398 gp_Pnt aPrevPoint = points.Last();
7fd59977 399
400 while (MorePoints) {
fa89e082 401 aIdx[0] = getIntervalIdx(U1, Intervs, aIdx[0]);
402 U2 += Du;
7fd59977 403
404 if (U2 >= lastu) { //Bout de courbe
405 U2 = lastu;
406 CurrentPoint = LastPoint;
407 Du = U2-U1;
408 Dusave = Du;
409 }
410 else D0 (C, U2, CurrentPoint); //Point suivant
411
fa89e082 412 Standard_Real Coef = 0.0, ACoef = 0., FCoef = 0.;
4071d9e6 413 Standard_Boolean Correction, TooLarge, TooSmall;
7fd59977 414 TooLarge = Standard_False;
7fd59977 415 Correction = Standard_True;
fa89e082 416 TooSmall = Standard_False;
4071d9e6 417
7fd59977 418 while (Correction) { //Ajustement Du
fa89e082 419 if (isNeedToCheck)
420 {
421 aIdx[1] = getIntervalIdx(U2, Intervs, aIdx[0]);
422 if (aIdx[1] > aIdx[0]) // Jump to another polynom.
423 {
424 if (Du > (Intervs(aIdx[0] + 1) - Intervs(aIdx[0]) ) * Us3) // Set Du to the smallest value and check deflection on it.
425 {
426 Du = (Intervs(aIdx[0] + 1) - Intervs(aIdx[0]) ) * Us3;
427 U2 = U1 + Du;
428 if (U2 > lastu)
429 U2 = lastu;
430 D0 (C, U2, CurrentPoint);
431 }
432 }
433 }
7fd59977 434 MiddleU = (U1+U2)*0.5; //Verif / au point milieu
435 D0 (C, MiddleU, MiddlePoint);
436
74da0216 437 V1 = (CurrentPoint.XYZ() - aPrevPoint.XYZ()); //Critere de fleche
438 V2 = (MiddlePoint.XYZ() - aPrevPoint.XYZ());
7fd59977 439 L1 = V1.Modulus ();
7fd59977 440
74da0216 441 FCoef = (L1 > myMinLen) ?
442 V1.CrossMagnitude(V2)/(L1*curvatureDeflection) : 0.0;
443
444 V1 = (CurrentPoint.XYZ() - MiddlePoint.XYZ()); //Critere d'angle
7fd59977 445 L1 = V1.Modulus ();
446 L2 = V2.Modulus ();
74da0216 447 if (L1 > myMinLen && L2 > myMinLen)
66190a47 448 {
449 Standard_Real angg = V1.CrossMagnitude(V2) / (L1 * L2);
450 ACoef = angg / AngleMax;
451 }
452 else
453 ACoef = 0.0;
7fd59977 454
74da0216 455 //On retient le plus penalisant
456 Coef = Max(ACoef, FCoef);
7fd59977 457
fa89e082 458 if (isNeedToCheck && Coef < 0.55)
459 {
460 isNeedToCheck = Standard_False;
461 Du = Dusave;
462 U2 = U1 + Du;
463 if (U2 > lastu)
464 U2 = lastu;
465 D0 (C, U2, CurrentPoint);
466 continue;
467 }
468
4071d9e6
O
469 if (Coef <= 1.0) {
470 if (Abs (lastu-U2) < uTol) {
7fd59977 471 parameters.Append (lastu);
4071d9e6
O
472 points .Append (LastPoint);
473 MorePoints = Standard_False;
474 Correction = Standard_False;
475 }
476 else {
477 if (Coef >= 0.55 || TooLarge) {
478 parameters.Append (U2);
479 points .Append (CurrentPoint);
480 aPrevPoint = CurrentPoint;
481 Correction = Standard_False;
fa89e082 482 isNeedToCheck = Standard_True;
4071d9e6
O
483 }
484 else if (TooSmall) {
485 Correction = Standard_False;
486 aPrevPoint = CurrentPoint;
487 }
488 else {
489 TooSmall = Standard_True;
4071d9e6
O
490 //Standard_Real UUU2 = U2;
491 Du += Min((U2-U1)*(1.-Coef), Du*Us3);
492
493 U2 = U1 + Du;
fe790035 494 if (U2 > lastu)
495 U2 = lastu;
496 D0 (C, U2, CurrentPoint);
4071d9e6
O
497 }
498 }
7fd59977 499 }
500 else {
501
4071d9e6 502 if (Coef >= 1.5) {
77e39787 503 if (!aPrevPoint.IsEqual(points.Last(), Precision::Confusion()))
504 {
505 parameters.Append (U1);
506 points .Append (aPrevPoint);
507 }
4071d9e6 508 U2 = MiddleU;
3492f422 509 Du = U2-U1;
4071d9e6
O
510 CurrentPoint = MiddlePoint;
511 }
512 else {
513 Du*=0.9;
514 U2 = U1 + Du;
515 D0 (C, U2, CurrentPoint);
516 TooLarge = Standard_True;
517 }
7fd59977 518
519 }
520 }
521
522 Du = U2-U1;
523
524 if (MorePoints) {
525 if (U1 > firstu) {
4071d9e6
O
526 if (FCoef > ACoef) {
527 //La fleche est critere de decoupage
528 EvaluateDu (C, U2, CurrentPoint, Du, NotDone);
529 if (NotDone) {
530 Du += (Du-Dusave)*(Du/Dusave);
531 if (Du > 1.5 * Dusave) Du = 1.5 * Dusave;
532 if (Du < 0.75* Dusave) Du = 0.75 * Dusave;
533 }
534 }
535 else {
536 //L'angle est le critere de decoupage
537 Du += (Du-Dusave)*(Du/Dusave);
538 if (Du > 1.5 * Dusave) Du = 1.5 * Dusave;
539 if (Du < 0.75* Dusave) Du = 0.75 * Dusave;
540 }
7fd59977 541 }
542
543 if (Du < uTol) {
4071d9e6
O
544 Du = lastu - U2;
545 if (Du < uTol) {
546 parameters.Append (lastu);
547 points .Append (LastPoint);
548 MorePoints = Standard_False;
549 }
550 else if (Du*Us3 > uTol) Du*=Us3;
7fd59977 551 }
552 U1 = U2;
553 Dusave = Du;
554 }
555 }
4071d9e6 556 //Recalage avant dernier point :
7fd59977 557 i = points.Length()-1;
558// Real d = points (i).Distance (points (i+1));
559// if (Abs(parameters (i) - parameters (i+1))<= 0.000001 || d < Precision::Confusion()) {
560// cout<<"deux points confondus"<<endl;
561// parameters.Remove (i+1);
562// points.Remove (i+1);
563// i--;
564// }
7fd59977 565 if (i >= 2) {
566 MiddleU = parameters (i-1);
567 MiddleU = (lastu + MiddleU)*0.5;
568 D0 (C, MiddleU, MiddlePoint);
569 parameters.SetValue (i, MiddleU);
570 points .SetValue (i, MiddlePoint);
571 }
572
7fd59977 573 //-- On rajoute des points aux milieux des segments si le nombre
574 //-- mini de points n'est pas atteint
575 //--
da6b95a0 576 Standard_Integer Nbp = points.Length();
577
578 //std::cout << "GCPnts_TangentialDeflection: Number of Points (" << Nbp << " " << minNbPnts << " )" << std::endl;
579
580 while(Nbp < minNbPnts)
581 {
582 for (i = 2; i <= Nbp; i += 2)
583 {
7fd59977 584 MiddleU = (parameters.Value(i-1)+parameters.Value(i))*0.5;
585 D0 (C, MiddleU, MiddlePoint);
586 parameters.InsertBefore(i,MiddleU);
587 points.InsertBefore(i,MiddlePoint);
588 Nbp++;
7fd59977 589 }
590 }
9c1519c4 591 //Additional check for intervals
592 Standard_Real MinLen2 = myMinLen * myMinLen;
593 Standard_Integer MaxNbp = 10 * Nbp;
594 for(i = 1; i < Nbp; ++i)
595 {
596 U1 = parameters(i);
597 U2 = parameters(i + 1);
846245d4 598
599 if (U2 - U1 <= uTol)
600 {
601 continue;
602 }
603
9c1519c4 604 // Check maximal deflection on interval;
605 Standard_Real dmax = 0.;
606 Standard_Real umax = 0.;
607 Standard_Real amax = 0.;
608 EstimDefl(C, U1, U2, dmax, umax);
609 const gp_Pnt& P1 = points(i);
610 const gp_Pnt& P2 = points(i+1);
611 D0(C, umax, MiddlePoint);
612 amax = EstimAngl(P1, MiddlePoint, P2);
613 if(dmax > curvatureDeflection || amax > AngleMax)
614 {
615 if(umax - U1 > uTol && U2 - umax > uTol)
616 {
617 if (P1.SquareDistance(MiddlePoint) > MinLen2 && P2.SquareDistance(MiddlePoint) > MinLen2)
618 {
619 parameters.InsertAfter(i, umax);
620 points.InsertAfter(i, MiddlePoint);
621 ++Nbp;
622 --i; //To compensate ++i in loop header: i must point to first part of splitted interval
623 if(Nbp > MaxNbp)
624 {
625 break;
626 }
627 }
628 }
629 }
630 }
631 //
632}
633
634//=======================================================================
635//function : EstimDefl
636//purpose : Estimation of maximal deflection for interval [U1, U2]
637//
638//=======================================================================
639void GCPnts_TangentialDeflection::EstimDefl (const TheCurve& C,
640 const Standard_Real U1, const Standard_Real U2,
641 Standard_Real& MaxDefl, Standard_Real& UMax)
642{
643 Standard_Real Du = (lastu - firstu);
644 //
645 TheMaxCurvLinDist aFunc(C, U1, U2);
646 //
647 const Standard_Integer aNbIter = 100;
648 Standard_Real reltol = Max(1.e-3, 2.*uTol/((Abs(U1) + Abs(U2))));
649 //
650 math_BrentMinimum anOptLoc(reltol, aNbIter, uTol);
651 anOptLoc.Perform(aFunc, U1, (U1+U2)/2., U2);
652 if(anOptLoc.IsDone())
653 {
654 MaxDefl = Sqrt(-anOptLoc.Minimum());
655 UMax = anOptLoc.Location();
656 return;
657 }
658 //
659 math_Vector aLowBorder(1,1);
660 math_Vector aUppBorder(1,1);
661 math_Vector aSteps(1,1);
662 //
663 aSteps(1) = Max(0.1 * Du, 100. * uTol);
664 Standard_Integer aNbParticles = Max(8, RealToInt(32 * (U2 - U1) / Du));
665 //
666 aLowBorder(1) = U1;
667 aUppBorder(1) = U2;
668 //
669 //
670 Standard_Real aValue;
671 math_Vector aT(1,1);
672 TheMaxCurvLinDistMV aFuncMV(aFunc);
673
674 math_PSO aFinder(&aFuncMV, aLowBorder, aUppBorder, aSteps, aNbParticles);
675 aFinder.Perform(aSteps, aValue, aT);
676 //
677 anOptLoc.Perform(aFunc, Max(aT(1) - aSteps(1), U1) , aT(1), Min(aT(1) + aSteps(1),U2));
678 if(anOptLoc.IsDone())
679 {
680 MaxDefl = Sqrt(-anOptLoc.Minimum());
681 UMax = anOptLoc.Location();
682 return;
683 }
684 MaxDefl = Sqrt(-aValue);
685 UMax = aT(1);
686 //
7fd59977 687}