OCC22540 Regression: Exception during building of patch by GeomPlate
[occt.git] / src / Extrema / Extrema_GenExtPS.cxx
CommitLineData
7fd59977 1// File: Extrema_GenExtPS.cxx
2// Created: Tue Jul 18 08:21:34 1995
3// Author: Modelistation
4// <model@metrox>
5
6// Modified by skv - Thu Sep 30 15:21:07 2004 OCC593
7
8
9#include <Extrema_GenExtPS.ixx>
10#include <StdFail_NotDone.hxx>
11#include <Standard_OutOfRange.hxx>
12#include <TColStd_Array2OfInteger.hxx>
13#include <TColStd_Array2OfReal.hxx>
14#include <TColgp_Array2OfPnt.hxx>
15#include <math_FunctionSetRoot.hxx>
16#include <math_Vector.hxx>
17#include <math_NewtonFunctionSetRoot.hxx>
18#include <GeomAbs_IsoType.hxx>
92d1589b
A
19#include <Bnd_Sphere.hxx>
20#include <Extrema_HUBTreeOfSphere.hxx>
21#include <Extrema_ExtFlag.hxx>
22#include <Bnd_Array1OfSphere.hxx>
23#include <Bnd_HArray1OfSphere.hxx>
7fd59977 24
92d1589b
A
25//IMPLEMENT_HARRAY1(Extrema_HArray1OfSphere)
26
27
28class Bnd_SphereUBTreeSelector : public Extrema_UBTreeOfSphere::Selector
29{
30 public:
31
32 Bnd_SphereUBTreeSelector (const Handle(Bnd_HArray1OfSphere)& theSphereArray,
33Bnd_Sphere& theSol)
34 : myXYZ(0,0,0),
35 mySphereArray(theSphereArray),
36 mySol(theSol)
37 {
38 //myXYZ = gp_Pnt(0, 0, 0);
39 }
40
41 void DefineCheckPoint( const gp_Pnt& theXYZ )
42 { myXYZ = theXYZ; }
43
44 Bnd_Sphere& Sphere() const
45 { return mySol; }
46
47 virtual Standard_Boolean Reject( const Bnd_Sphere &theBnd ) const = 0;
48
49 virtual Standard_Boolean Accept(const Standard_Integer& theObj) = 0;
50
51 protected:
52 gp_Pnt myXYZ;
53 const Handle(Bnd_HArray1OfSphere)& mySphereArray;
54 Bnd_Sphere& mySol;
55
56};
57
58class Bnd_SphereUBTreeSelectorMin : public Bnd_SphereUBTreeSelector
59{
60public:
61 Bnd_SphereUBTreeSelectorMin (const Handle(Bnd_HArray1OfSphere)& theSphereArray,
62 Bnd_Sphere& theSol)
63 : Bnd_SphereUBTreeSelector(theSphereArray, theSol),
64 myMinDist(RealLast())
65 {}
66
67 void SetMinDist( const Standard_Real theMinDist )
68 { myMinDist = theMinDist; }
69
70 Standard_Real MinDist() const
71 { return myMinDist; }
72
73 Standard_Boolean Reject( const Bnd_Sphere &theBnd ) const
74 {
75 Bnd_SphereUBTreeSelectorMin* me =
76 const_cast<Bnd_SphereUBTreeSelectorMin*>(this);
77 // myMinDist is decreased each time a nearer object is found
78 return theBnd.IsOut( myXYZ.XYZ(), me->myMinDist );
79 }
80
81 Standard_Boolean Accept(const Standard_Integer&);
82
83private:
84 Standard_Real myMinDist;
85};
86
87Standard_Boolean Bnd_SphereUBTreeSelectorMin::Accept(const Standard_Integer& theInd)
88{
89 const Bnd_Sphere& aSph = mySphereArray->Value(theInd);
90 Standard_Real aCurDist;
91
92 if ( (aCurDist = aSph.SquareDistance(myXYZ.XYZ())) < mySol.SquareDistance(myXYZ.XYZ()) )
93 {
94 mySol = aSph;
95 if ( aCurDist < myMinDist )
96 myMinDist = aCurDist;
97
98 return Standard_True;
99 }
100
101 return Standard_False;
102}
103
104class Bnd_SphereUBTreeSelectorMax : public Bnd_SphereUBTreeSelector
105{
106public:
107 Bnd_SphereUBTreeSelectorMax (const Handle(Bnd_HArray1OfSphere)& theSphereArray,
108 Bnd_Sphere& theSol)
109 : Bnd_SphereUBTreeSelector(theSphereArray, theSol),
110 myMaxDist(0)
111 {}
112
113 void SetMaxDist( const Standard_Real theMaxDist )
114 { myMaxDist = theMaxDist; }
115
116 Standard_Real MaxDist() const
117 { return myMaxDist; }
118
119 Standard_Boolean Reject( const Bnd_Sphere &theBnd ) const
120 {
121 Bnd_SphereUBTreeSelectorMax* me =
122 const_cast<Bnd_SphereUBTreeSelectorMax*>(this);
123 // myMaxDist is decreased each time a nearer object is found
124 return theBnd.IsOut( myXYZ.XYZ(), me->myMaxDist );
125 }
126
127 Standard_Boolean Accept(const Standard_Integer&);
128
129private:
130 Standard_Real myMaxDist;
131};
132
133Standard_Boolean Bnd_SphereUBTreeSelectorMax::Accept(const Standard_Integer& theInd)
134{
135 const Bnd_Sphere& aSph = mySphereArray->Value(theInd);
136 Standard_Real aCurDist;
137
138 if ( (aCurDist = aSph.SquareDistance(myXYZ.XYZ())) > mySol.SquareDistance(myXYZ.XYZ()) )
139 {
140 mySol = aSph;
141 if ( aCurDist > myMaxDist )
142 myMaxDist = aCurDist;
143
144 return Standard_True;
145 }
146
147 return Standard_False;
148}
7fd59977 149
150
151
152//=============================================================================
153
154/*-----------------------------------------------------------------------------
92d1589b
A
155Function:
156 Find all extremum distances between point P and surface
157 S using sampling (NbU,NbV).
7fd59977 158
92d1589b
A
159Method:
160 The algorithm bases on the hypothesis that sampling is precise enough
7fd59977 161 pour que, s'il existe N distances extremales entre le point et la surface,
162 alors il existe aussi N extrema entre le point et la grille.
92d1589b
A
163 So, the algorithm consists in starting from extrema of the grid to find the
164 extrema of the surface.
165 The extrema are calculated by the algorithm math_FunctionSetRoot with the
166 following arguments:
167 - F: Extrema_FuncExtPS created from P and S,
168 - UV: math_Vector the components which of are parameters of the extremum on the
169 grid,
170 - Tol: Min(TolU,TolV), (Prov.:math_FunctionSetRoot does not autorize a vector)
171 - UVinf: math_Vector the components which of are lower limits of u and v,
172 - UVsup: math_Vector the components which of are upper limits of u and v.
173
174Processing:
175 a- Creation of the table of distances (TbDist(0,NbU+1,0,NbV+1)):
176 The table is expanded at will; lines 0 and NbU+1 and
177 columns 0 and NbV+1 are initialized at RealFirst() or RealLast()
178 to simplify the tests carried out at stage b
179 (there is no need to test if the point is on border of the grid).
180 b- Calculation of extrema:
181 First the minimums and then the maximums are found. These 2 procedured
182 pass in a similar way:
183 b.a- Initialization:
184 - 'borders' of table TbDist (RealLast() in case of minimums
185 and RealLast() in case of maximums),
186 - table TbSel(0,NbU+1,0,NbV+1) of selection of points for
187 calculation of local extremum (0). When a point will selected,
188 it will not be selectable, as well as the ajacent points
189 (8 at least). The corresponding addresses will be set to 1.
190 b.b- Calculation of minimums (or maximums):
191 All distances from table TbDist are parsed in a loop:
192 - search minimum (or maximum) in the grid,
193 - calculate extremum on the surface,
194 - update table TbSel.
7fd59977 195-----------------------------------------------------------------------------*/
196
197static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
198 const Standard_Real Param,
199 const GeomAbs_IsoType IT,
200 const Standard_Real TolMin,
201 const Standard_Real TolMax)
202{
203 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
204 Standard_Boolean Along = Standard_True;
205 U1 = S.FirstUParameter();
206 U2 = S.LastUParameter();
207 V1 = S.FirstVParameter();
208 V2 = S.LastVParameter();
209 gp_Vec D1U,D1V;
210 gp_Pnt P;
211 Standard_Real Step,D1NormMax;
212 if (IT == GeomAbs_IsoV)
213 {
214 Step = (U2 - U1)/10;
215 D1NormMax=0.;
216 for (T=U1;T<=U2;T=T+Step)
217 {
218 S.D1(T,Param,P,D1U,D1V);
219 D1NormMax=Max(D1NormMax,D1U.Magnitude());
220 }
221
222 if (D1NormMax >TolMax || D1NormMax < TolMin )
223 Along = Standard_False;
224 }
225 else
226 {
227 Step = (V2 - V1)/10;
228 D1NormMax=0.;
229 for (T=V1;T<=V2;T=T+Step)
230 {
231 S.D1(Param,T,P,D1U,D1V);
232 D1NormMax=Max(D1NormMax,D1V.Magnitude());
233 }
234
235 if (D1NormMax >TolMax || D1NormMax < TolMin )
236 Along = Standard_False;
237
238
239 }
240 return Along;
241}
242//----------------------------------------------------------
243Extrema_GenExtPS::Extrema_GenExtPS()
244{
245 myDone = Standard_False;
246 myInit = Standard_False;
92d1589b
A
247 myFlag = Extrema_ExtFlag_MINMAX;
248 myAlgo = Extrema_ExtAlgo_Grad;
7fd59977 249}
250
251
252Extrema_GenExtPS::Extrema_GenExtPS (const gp_Pnt& P,
253 const Adaptor3d_Surface& S,
254 const Standard_Integer NbU,
255 const Standard_Integer NbV,
256 const Standard_Real TolU,
92d1589b
A
257 const Standard_Real TolV,
258 const Extrema_ExtFlag F,
259 const Extrema_ExtAlgo A)
260 : myF (P,S), myFlag(F), myAlgo(A)
7fd59977 261{
262 Initialize(S, NbU, NbV, TolU, TolV);
263 Perform(P);
264}
265
266Extrema_GenExtPS::Extrema_GenExtPS (const gp_Pnt& P,
267 const Adaptor3d_Surface& S,
268 const Standard_Integer NbU,
269 const Standard_Integer NbV,
270 const Standard_Real Umin,
271 const Standard_Real Usup,
272 const Standard_Real Vmin,
273 const Standard_Real Vsup,
274 const Standard_Real TolU,
92d1589b
A
275 const Standard_Real TolV,
276 const Extrema_ExtFlag F,
277 const Extrema_ExtAlgo A)
278 : myF (P,S), myFlag(F), myAlgo(A)
7fd59977 279{
280 Initialize(S, NbU, NbV, Umin, Usup, Vmin, Vsup, TolU, TolV);
281 Perform(P);
282}
283
284
285void Extrema_GenExtPS::Initialize(const Adaptor3d_Surface& S,
286 const Standard_Integer NbU,
287 const Standard_Integer NbV,
288 const Standard_Real TolU,
289 const Standard_Real TolV)
290{
291 myumin = S.FirstUParameter();
292 myusup = S.LastUParameter();
293 myvmin = S.FirstVParameter();
294 myvsup = S.LastVParameter();
295 Initialize(S,NbU,NbV,myumin,myusup,myvmin,myvsup,TolU,TolV);
296}
297
298
299void Extrema_GenExtPS::Initialize(const Adaptor3d_Surface& S,
300 const Standard_Integer NbU,
301 const Standard_Integer NbV,
302 const Standard_Real Umin,
303 const Standard_Real Usup,
304 const Standard_Real Vmin,
305 const Standard_Real Vsup,
306 const Standard_Real TolU,
307 const Standard_Real TolV)
308{
309 myInit = Standard_True;
310 myS = (Adaptor3d_SurfacePtr)&S;
311 myusample = NbU;
312 myvsample = NbV;
313 mytolu = TolU;
314 mytolv = TolV;
315 myumin = Umin;
316 myusup = Usup;
317 myvmin = Vmin;
318 myvsup = Vsup;
319
320 if ((myusample < 2) ||
321 (myvsample < 2)) { Standard_OutOfRange::Raise(); }
322
323 myF.Initialize(S);
324
82469411 325 mySphereUBTree.Nullify();
7fd59977 326
92d1589b
A
327 if(myAlgo == Extrema_ExtAlgo_Grad)
328 {
329 //If flag was changed and extrema not reinitialized Extrema would fail
330 mypoints = new TColgp_HArray2OfPnt(0,myusample+1,0,myvsample+1);
7fd59977 331 Standard_Real PasU = myusup - myumin;
332 Standard_Real PasV = myvsup - myvmin;
333 Standard_Real U0 = PasU / myusample / 100.;
334 Standard_Real V0 = PasV / myvsample / 100.;
335 gp_Pnt P1;
336 PasU = (PasU - U0) / (myusample - 1);
337 PasV = (PasV - V0) / (myvsample - 1);
338 U0 = U0/2. + myumin;
339 V0 = V0/2. + myvmin;
340
341// Calcul des distances
342
343 Standard_Integer NoU, NoV;
344 Standard_Real U, V;
345 for ( NoU = 1, U = U0; NoU <= myusample; NoU++, U += PasU) {
346 for ( NoV = 1, V = V0; NoV <= myvsample; NoV++, V += PasV) {
347 P1 = myS->Value(U, V);
348 mypoints->SetValue(NoU,NoV,P1);
349 }
350 }
92d1589b
A
351 }
352
353 //mypoints = new TColgp_HArray2OfPnt(0,myusample+1,0,myvsample+1);
354
355/*
356a- Constitution du tableau des distances (TbDist(0,myusample+1,0,myvsample+1)):
357 ---------------------------------------------------------------
358*/
359
360// Parametrage de l echantillon
361
362
7fd59977 363}
364
92d1589b
A
365void Extrema_GenExtPS::BuildTree()
366{
82469411
A
367 // if tree already exists, assume it is already correctly filled
368 if ( ! mySphereUBTree.IsNull() )
369 return;
370
371 Standard_Real PasU = myusup - myumin;
372 Standard_Real PasV = myvsup - myvmin;
373 Standard_Real U0 = PasU / myusample / 100.;
374 Standard_Real V0 = PasV / myvsample / 100.;
375 gp_Pnt P1;
376 PasU = (PasU - U0) / (myusample - 1);
377 PasV = (PasV - V0) / (myvsample - 1);
378 U0 = U0/2. + myumin;
379 V0 = V0/2. + myvmin;
380
381 // Calcul des distances
382 mySphereUBTree = new Extrema_UBTreeOfSphere;
383 Extrema_UBTreeFillerOfSphere aFiller(*mySphereUBTree);
384 Standard_Integer i = 0;
385 Standard_Real U, V;
386 mySphereArray = new Bnd_HArray1OfSphere(0, myusample * myvsample);
387 Standard_Integer NoU, NoV;
388 for ( NoU = 1, U = U0; NoU <= myusample; NoU++, U += PasU) {
389 for ( NoV = 1, V = V0; NoV <= myvsample; NoV++, V += PasV) {
390 P1 = myS->Value(U, V);
391 Bnd_Sphere aSph(P1.XYZ(), 0/*mytolu < mytolv ? mytolu : mytolv*/, NoU, NoV);
392 aFiller.Add(i, aSph);
393 mySphereArray->SetValue( i, aSph );
394 i++;
395 }
396 }
397 aFiller.Fill();
92d1589b
A
398}
399
400void Extrema_GenExtPS::FindSolution(const gp_Pnt& P, const math_Vector& UV, const Standard_Real PasU, const Standard_Real PasV, const Extrema_ExtFlag f)
401{
402 math_Vector Tol(1,2);
403 Tol(1) = mytolu;
404 Tol(2) = mytolv;
7fd59977 405
92d1589b
A
406 math_Vector UVinf(1,2), UVsup(1,2);
407 UVinf(1) = myumin;
408 UVinf(2) = myvmin;
409 UVsup(1) = myusup;
410 UVsup(2) = myvsup;
411
412 math_Vector errors(1,2);
413 math_Vector root(1, 2);
414 Standard_Real eps = 1.e-9;
415 Standard_Integer nbsubsample = 11;
416
417 Standard_Integer aNbMaxIter = 100;
418
419 if (myF.HasDegIso())
420 aNbMaxIter = 150;
421
422 math_FunctionSetRoot S (myF,UV,Tol,UVinf,UVsup, aNbMaxIter);
423 if(S.IsDone()) {
424 root = S.Root();
425 myF.Value(root, errors);
426 if(f == Extrema_ExtFlag_MIN)
427 {
428 if(Abs(errors(1)) > eps || Abs(errors(2)) > eps) {
429 //try to improve solution on subgrid of sample points
430 gp_Pnt PSol = myS->Value(root(1), root(2));
431 Standard_Real DistSol = P.SquareDistance(PSol);
432
433 Standard_Real u1 = Max(UV(1) - PasU, myumin), u2 = Min(UV(1) + PasU, myusup);
434 Standard_Real v1 = Max(UV(2) - PasV, myvmin), v2 = Min(UV(2) + PasV, myvsup);
435
436 if(u2 - u1 < 2.*PasU) {
437 if(Abs(u1 - myumin) < 1.e-9) {
438 u2 = u1 + 2.*PasU;
439 u2 = Min(u2, myusup);
440 }
441 if(Abs(u2 - myusup) < 1.e-9) {
442 u1 = u2 - 2.*PasU;
443 u1 = Max(u1, myumin);
444 }
445 }
446
447 if(v2 - v1 < 2.*PasV) {
448 if(Abs(v1 - myvmin) < 1.e-9) {
449 v2 = v1 + 2.*PasV;
450 v2 = Min(v2, myvsup);
451 }
452 if(Abs(v2 - myvsup) < 1.e-9) {
453 v1 = v2 - 2.*PasV;
454 v1 = Max(v1, myvmin);
455 }
456 }
457
458 Standard_Real du = (u2 - u1)/(nbsubsample-1);
459 Standard_Real dv = (v2 - v1)/(nbsubsample-1);
460 Standard_Real u, v;
461 Standard_Real dist;
462
463 Standard_Boolean NewSolution = Standard_False;
464 Standard_Integer Nu, Nv;
465 for (Nu = 1, u = u1; Nu < nbsubsample; Nu++, u += du) {
466 for (Nv = 1, v = v1; Nv < nbsubsample; Nv++, v += dv) {
467 gp_Pnt Puv = myS->Value(u, v);
468 dist = P.SquareDistance(Puv);
469
470 if(dist < DistSol) {
471 UV(1) = u;
472 UV(2) = v;
473 NewSolution = Standard_True;
474 DistSol = dist;
475 }
476 }
477 }
478
479 if(NewSolution) {
480 //try to precise
481 math_FunctionSetRoot S (myF,UV,Tol,UVinf,UVsup, aNbMaxIter);
482 }
483
484 }
485 }
486 }
487 myDone = Standard_True;
488}
489
490void Extrema_GenExtPS::SetFlag(const Extrema_ExtFlag F)
491{
492 myFlag = F;
493}
494
495void Extrema_GenExtPS::SetAlgo(const Extrema_ExtAlgo A)
496{
497 myAlgo = A;
498}
7fd59977 499
500void Extrema_GenExtPS::Perform(const gp_Pnt& P)
501{
92d1589b 502 //BuildTree();
7fd59977 503 myDone = Standard_False;
504 myF.SetPoint(P);
505
7fd59977 506 Standard_Real PasU = myusup - myumin;
507 Standard_Real PasV = myvsup - myvmin;
508 Standard_Real U, U0 = PasU / myusample / 100.;
509 Standard_Real V, V0 = PasV / myvsample / 100.;
510 PasU = (PasU - U0) / (myusample - 1);
511 PasV = (PasV - V0) / (myvsample - 1);
512 U0 = U0/2.+myumin;
513 V0 = V0/2.+myvmin;
514
92d1589b
A
515 //math_Vector Tol(1, 2);
516 math_Vector UV(1,2);
7fd59977 517
92d1589b
A
518 if(myAlgo == Extrema_ExtAlgo_Grad)
519 {
520 Standard_Integer NoU,NoV;
7fd59977 521
92d1589b
A
522 TColStd_Array2OfReal TheDist(0, myusample+1, 0, myvsample+1);
523 for ( NoU = 1, U = U0; NoU <= myusample; NoU++, U += PasU) {
524 for ( NoV = 1, V = V0; NoV <= myvsample; NoV++, V += PasV) {
525 TheDist(NoU, NoV) = P.SquareDistance(mypoints->Value(NoU, NoV));
526 }
7fd59977 527 }
7fd59977 528
92d1589b
A
529 TColStd_Array2OfInteger TbSel(0,myusample+1,0,myvsample+1);
530 TbSel.Init(0);
7fd59977 531
92d1589b 532 Standard_Real Dist;
7fd59977 533
92d1589b
A
534 if(myFlag == Extrema_ExtFlag_MIN || myFlag == Extrema_ExtFlag_MINMAX)
535 {
536 for (NoV = 0; NoV <= myvsample+1; NoV++) {
537 TheDist(0,NoV) = RealLast();
538 TheDist(myusample+1,NoV) = RealLast();
539 }
540 for (NoU = 1; NoU <= myusample; NoU++) {
541 TheDist(NoU,0) = RealLast();
542 TheDist(NoU,myvsample+1) = RealLast();
543 }
544 for (NoU = 1; NoU <= myusample; NoU++) {
545 for (NoV = 1; NoV <= myvsample; NoV++) {
546 if (TbSel(NoU,NoV) == 0) {
547 Dist = TheDist(NoU,NoV);
548 if ((TheDist(NoU-1,NoV-1) >= Dist) &&
549 (TheDist(NoU-1,NoV ) >= Dist) &&
550 (TheDist(NoU-1,NoV+1) >= Dist) &&
551 (TheDist(NoU ,NoV-1) >= Dist) &&
552 (TheDist(NoU ,NoV+1) >= Dist) &&
553 (TheDist(NoU+1,NoV-1) >= Dist) &&
554 (TheDist(NoU+1,NoV ) >= Dist) &&
555 (TheDist(NoU+1,NoV+1) >= Dist)) {
556 //Create array of UV vectors to calculate min
557 UV(1) = U0 + (NoU - 1) * PasU;
558 UV(2) = V0 + (NoV - 1) * PasV;
559 FindSolution(P, UV, PasU, PasV, Extrema_ExtFlag_MIN);
560 }
561 }
562 }
563 }
564 }
565
566 if(myFlag == Extrema_ExtFlag_MAX || myFlag == Extrema_ExtFlag_MINMAX)
567 {
568 for (NoV = 0; NoV <= myvsample+1; NoV++) {
569 TheDist(0,NoV) = RealFirst();
570 TheDist(myusample+1,NoV) = RealFirst();
571 }
572 for (NoU = 1; NoU <= myusample; NoU++) {
573 TheDist(NoU,0) = RealFirst();
574 TheDist(NoU,myvsample+1) = RealFirst();
575 }
576 for (NoU = 1; NoU <= myusample; NoU++) {
577 for (NoV = 1; NoV <= myvsample; NoV++) {
578 if (TbSel(NoU,NoV) == 0) {
579 Dist = TheDist(NoU,NoV);
580 if ((TheDist(NoU-1,NoV-1) <= Dist) &&
581 (TheDist(NoU-1,NoV ) <= Dist) &&
582 (TheDist(NoU-1,NoV+1) <= Dist) &&
583 (TheDist(NoU ,NoV-1) <= Dist) &&
584 (TheDist(NoU ,NoV+1) <= Dist) &&
585 (TheDist(NoU+1,NoV-1) <= Dist) &&
586 (TheDist(NoU+1,NoV ) <= Dist) &&
587 (TheDist(NoU+1,NoV+1) <= Dist)) {
588 //Create array of UV vectors to calculate max
589 UV(1) = U0 + (NoU - 1) * PasU;
590 UV(2) = V0 + (NoV - 1) * PasV;
591 FindSolution(P, UV, PasU, PasV, Extrema_ExtFlag_MAX);
592 }
593 }
594 }
595 }
596 }
7fd59977 597 }
92d1589b
A
598 else
599 {
600 BuildTree();
601 if(myFlag == Extrema_ExtFlag_MIN || myFlag == Extrema_ExtFlag_MINMAX)
602 {
603 Bnd_Sphere aSol = mySphereArray->Value(0);
604 Bnd_SphereUBTreeSelectorMin aSelector(mySphereArray, aSol);
605 //aSelector.SetMaxDist( RealLast() );
606 aSelector.DefineCheckPoint( P );
82469411 607 Standard_Integer aNbSel = mySphereUBTree->Select( aSelector );
92d1589b
A
608 //TODO: check if no solution in binary tree
609 Bnd_Sphere& aSph = aSelector.Sphere();
610
611 UV(1) = U0 + (aSph.U() - 1) * PasU;
612 UV(2) = V0 + (aSph.V() - 1) * PasV;
613
614 FindSolution(P, UV, PasU, PasV, Extrema_ExtFlag_MIN);
615 }
616 if(myFlag == Extrema_ExtFlag_MAX || myFlag == Extrema_ExtFlag_MINMAX)
617 {
618 Bnd_Sphere aSol = mySphereArray->Value(0);
619 Bnd_SphereUBTreeSelectorMax aSelector(mySphereArray, aSol);
620 //aSelector.SetMaxDist( RealLast() );
621 aSelector.DefineCheckPoint( P );
82469411 622 Standard_Integer aNbSel = mySphereUBTree->Select( aSelector );
92d1589b
A
623 //TODO: check if no solution in binary tree
624 Bnd_Sphere& aSph = aSelector.Sphere();
625
626 UV(1) = U0 + (aSph.U() - 1) * PasU;
627 UV(2) = V0 + (aSph.V() - 1) * PasV;
628
629 FindSolution(P, UV, PasU, PasV, Extrema_ExtFlag_MAX);
7fd59977 630 }
631 }
7fd59977 632}
633//=============================================================================
634
635Standard_Boolean Extrema_GenExtPS::IsDone () const { return myDone; }
636//=============================================================================
637
638Standard_Integer Extrema_GenExtPS::NbExt () const
639{
640 if (!IsDone()) { StdFail_NotDone::Raise(); }
641 return myF.NbExt();
642}
643//=============================================================================
644
645Standard_Real Extrema_GenExtPS::SquareDistance (const Standard_Integer N) const
646{
647 if (!IsDone()) { StdFail_NotDone::Raise(); }
648 return myF.SquareDistance(N);
649}
650//=============================================================================
651
652Extrema_POnSurf Extrema_GenExtPS::Point (const Standard_Integer N) const
653{
654 if (!IsDone()) { StdFail_NotDone::Raise(); }
655 return myF.Point(N);
656}
657//=============================================================================