b311480e |
1 | // Created on: 1995-07-18 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1995-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 | |
7fd59977 |
17 | |
e8e8b273 |
18 | #include <Extrema_GenExtCS.hxx> |
42cf5bc1 |
19 | #include <Adaptor3d_Curve.hxx> |
7fd59977 |
20 | #include <Adaptor3d_HCurve.hxx> |
42cf5bc1 |
21 | #include <Adaptor3d_Surface.hxx> |
e8e8b273 |
22 | #include <Adaptor3d_HSurface.hxx> |
23 | #include <Geom_OffsetCurve.hxx> |
1d33d22b |
24 | #include <Extrema_GlobOptFuncCS.hxx> |
e8e8b273 |
25 | #include <Extrema_GlobOptFuncConicS.hxx> |
26 | #include <Extrema_GlobOptFuncCQuadric.hxx> |
1d33d22b |
27 | #include <Extrema_POnCurv.hxx> |
42cf5bc1 |
28 | #include <Extrema_POnSurf.hxx> |
f4dee9bb |
29 | #include <Geom_Hyperbola.hxx> |
1d33d22b |
30 | #include <math_FunctionSetRoot.hxx> |
31 | #include <math_PSO.hxx> |
32 | #include <math_PSOParticlesPool.hxx> |
33 | #include <math_Vector.hxx> |
34 | #include <Precision.hxx> |
42cf5bc1 |
35 | #include <Standard_OutOfRange.hxx> |
36 | #include <Standard_TypeMismatch.hxx> |
37 | #include <StdFail_NotDone.hxx> |
e8e8b273 |
38 | #include <TColgp_Array1OfPnt.hxx> |
f4dee9bb |
39 | #include <Geom_TrimmedCurve.hxx> |
e8e8b273 |
40 | #include <ElCLib.hxx> |
7fd59977 |
41 | |
f4dee9bb |
42 | const Standard_Real MaxParamVal = 1.0e+10; |
1d33d22b |
43 | const Standard_Real aBorderDivisor = 1.0e+4; |
f4dee9bb |
44 | const Standard_Real HyperbolaLimit = 23.; //ln(MaxParamVal) |
45 | |
e8e8b273 |
46 | static Standard_Boolean IsQuadric(const GeomAbs_SurfaceType theSType) |
47 | { |
48 | if (theSType == GeomAbs_Plane) return Standard_True; |
49 | if (theSType == GeomAbs_Cylinder) return Standard_True; |
50 | if (theSType == GeomAbs_Cone) return Standard_True; |
51 | if (theSType == GeomAbs_Sphere) return Standard_True; |
52 | if (theSType == GeomAbs_Torus) return Standard_True; |
53 | return Standard_False; |
54 | } |
55 | static Standard_Boolean IsConic(const GeomAbs_CurveType theCType) |
56 | { |
57 | if (theCType == GeomAbs_Line) return Standard_True; |
58 | if (theCType == GeomAbs_Circle) return Standard_True; |
59 | if (theCType == GeomAbs_Ellipse) return Standard_True; |
60 | if (theCType == GeomAbs_Hyperbola) return Standard_True; |
61 | if (theCType == GeomAbs_Parabola) return Standard_True; |
62 | return Standard_False; |
63 | } |
f4dee9bb |
64 | // restrict maximal parameter on hyperbola to avoid FPE |
65 | static Standard_Real GetCurvMaxParamVal (const Adaptor3d_Curve& theC) |
66 | { |
67 | if (theC.GetType() == GeomAbs_Hyperbola) |
68 | { |
69 | return HyperbolaLimit; |
70 | } |
71 | if (theC.GetType() == GeomAbs_OffsetCurve) |
72 | { |
73 | Handle(Geom_Curve) aBC (theC.OffsetCurve()->BasisCurve()); |
74 | Handle(Geom_TrimmedCurve) aTC = Handle(Geom_TrimmedCurve)::DownCast (aBC); |
75 | if (! aTC.IsNull()) |
76 | { |
77 | aBC = aTC->BasisCurve(); |
78 | } |
79 | if (aBC->IsKind (STANDARD_TYPE(Geom_Hyperbola))) |
80 | return HyperbolaLimit; |
81 | } |
82 | return MaxParamVal; |
83 | } |
84 | |
85 | // restrict maximal parameter on surfaces based on hyperbola to avoid FPE |
86 | static void GetSurfMaxParamVals (const Adaptor3d_Surface& theS, |
87 | Standard_Real& theUmax, Standard_Real& theVmax) |
88 | { |
89 | theUmax = theVmax = MaxParamVal; |
90 | |
91 | if (theS.GetType() == GeomAbs_SurfaceOfExtrusion) |
92 | { |
93 | theUmax = GetCurvMaxParamVal (theS.BasisCurve()->Curve()); |
94 | } |
95 | else if (theS.GetType() == GeomAbs_SurfaceOfRevolution) |
96 | { |
97 | theVmax = GetCurvMaxParamVal (theS.BasisCurve()->Curve()); |
98 | } |
99 | else if (theS.GetType() == GeomAbs_OffsetSurface) |
100 | { |
101 | GetSurfMaxParamVals (theS.BasisSurface()->Surface(), theUmax, theVmax); |
102 | } |
103 | } |
113493b0 |
104 | |
7fd59977 |
105 | //======================================================================= |
106 | //function : Extrema_GenExtCS |
107 | //purpose : |
108 | //======================================================================= |
b311480e |
109 | Extrema_GenExtCS::Extrema_GenExtCS() |
d533dafb |
110 | : myDone(Standard_False), |
111 | mytmin(0.0), |
112 | mytsup(0.0), |
113 | myumin(0.0), |
114 | myusup(0.0), |
115 | myvmin(0.0), |
116 | myvsup(0.0), |
117 | mytsample(0), |
118 | myusample(0), |
119 | myvsample(0), |
120 | mytol1(0.0), |
121 | mytol2(0.0), |
122 | myS(NULL) |
7fd59977 |
123 | { |
7fd59977 |
124 | } |
125 | |
126 | //======================================================================= |
127 | //function : Extrema_GenExtCS |
128 | //purpose : |
129 | //======================================================================= |
1d33d22b |
130 | Extrema_GenExtCS::Extrema_GenExtCS(const Adaptor3d_Curve& C, |
131 | const Adaptor3d_Surface& S, |
132 | const Standard_Integer NbT, |
133 | const Standard_Integer NbU, |
134 | const Standard_Integer NbV, |
135 | const Standard_Real Tol1, |
136 | const Standard_Real Tol2) |
7fd59977 |
137 | { |
138 | Initialize(S, NbU, NbV, Tol2); |
139 | Perform(C, NbT, Tol1); |
140 | } |
141 | |
142 | //======================================================================= |
143 | //function : Extrema_GenExtCS |
144 | //purpose : |
145 | //======================================================================= |
146 | |
1d33d22b |
147 | Extrema_GenExtCS::Extrema_GenExtCS (const Adaptor3d_Curve& C, |
148 | const Adaptor3d_Surface& S, |
149 | const Standard_Integer NbT, |
150 | const Standard_Integer NbU, |
151 | const Standard_Integer NbV, |
152 | const Standard_Real tmin, |
153 | const Standard_Real tsup, |
154 | const Standard_Real Umin, |
113493b0 |
155 | const Standard_Real Usup, |
1d33d22b |
156 | const Standard_Real Vmin, |
157 | const Standard_Real Vsup, |
158 | const Standard_Real Tol1, |
113493b0 |
159 | const Standard_Real Tol2) |
7fd59977 |
160 | { |
161 | Initialize(S, NbU, NbV, Umin,Usup,Vmin,Vsup,Tol2); |
162 | Perform(C, NbT, tmin, tsup, Tol1); |
163 | } |
164 | |
165 | //======================================================================= |
166 | //function : Initialize |
167 | //purpose : |
168 | //======================================================================= |
1d33d22b |
169 | void Extrema_GenExtCS::Initialize (const Adaptor3d_Surface& S, |
170 | const Standard_Integer NbU, |
171 | const Standard_Integer NbV, |
113493b0 |
172 | const Standard_Real Tol2) |
7fd59977 |
173 | { |
174 | myumin = S.FirstUParameter(); |
175 | myusup = S.LastUParameter(); |
176 | myvmin = S.FirstVParameter(); |
177 | myvsup = S.LastVParameter(); |
178 | Initialize(S,NbU,NbV,myumin,myusup,myvmin,myvsup,Tol2); |
179 | } |
180 | |
181 | //======================================================================= |
182 | //function : Initialize |
183 | //purpose : |
184 | //======================================================================= |
113493b0 |
185 | void Extrema_GenExtCS::Initialize (const Adaptor3d_Surface& S, |
186 | const Standard_Integer NbU, |
187 | const Standard_Integer NbV, |
188 | const Standard_Real Umin, |
189 | const Standard_Real Usup, |
190 | const Standard_Real Vmin, |
191 | const Standard_Real Vsup, |
192 | const Standard_Real Tol2) |
7fd59977 |
193 | { |
194 | myS = (Adaptor3d_SurfacePtr)&S; |
7fd59977 |
195 | myusample = NbU; |
196 | myvsample = NbV; |
197 | myumin = Umin; |
198 | myusup = Usup; |
199 | myvmin = Vmin; |
200 | myvsup = Vsup; |
201 | mytol2 = Tol2; |
113493b0 |
202 | |
f4dee9bb |
203 | Standard_Real umaxpar, vmaxpar; |
204 | GetSurfMaxParamVals(*myS, umaxpar, vmaxpar); |
113493b0 |
205 | |
f4dee9bb |
206 | if(Precision::IsInfinite (myusup)) |
207 | { |
208 | myusup = umaxpar; |
209 | } |
210 | if(Precision::IsInfinite (myumin)) |
211 | { |
212 | myumin = -umaxpar; |
213 | } |
214 | if(Precision::IsInfinite (myvsup)) |
215 | { |
216 | myvsup = vmaxpar; |
217 | } |
218 | if(Precision::IsInfinite (myvmin)) |
219 | { |
220 | myvmin = -vmaxpar; |
221 | } |
222 | |
223 | Standard_Real du = (myusup - myumin) / aBorderDivisor; |
224 | Standard_Real dv = (myvsup - myvmin) / aBorderDivisor; |
225 | const Standard_Real aMinU = myumin + du; |
226 | const Standard_Real aMinV = myvmin + dv; |
227 | const Standard_Real aMaxU = myusup - du; |
228 | const Standard_Real aMaxV = myvsup - dv; |
113493b0 |
229 | |
230 | const Standard_Real aStepSU = (aMaxU - aMinU) / myusample; |
231 | const Standard_Real aStepSV = (aMaxV - aMinV) / myvsample; |
232 | |
233 | mySurfPnts = new TColgp_HArray2OfPnt (0, myusample, 0, myvsample); |
234 | |
235 | Standard_Real aSU = aMinU; |
236 | for (Standard_Integer aSUI = 0; aSUI <= myusample; aSUI++, aSU += aStepSU) |
237 | { |
238 | Standard_Real aSV = aMinV; |
239 | for (Standard_Integer aSVI = 0; aSVI <= myvsample; aSVI++, aSV += aStepSV) |
240 | { |
241 | mySurfPnts->ChangeValue (aSUI, aSVI) = myS->Value (aSU, aSV); |
242 | } |
243 | } |
7fd59977 |
244 | } |
245 | |
246 | //======================================================================= |
247 | //function : Perform |
248 | //purpose : |
249 | //======================================================================= |
7fd59977 |
250 | void Extrema_GenExtCS::Perform(const Adaptor3d_Curve& C, |
29d778bf |
251 | const Standard_Integer NbT, |
252 | const Standard_Real Tol1) |
7fd59977 |
253 | { |
254 | mytmin = C.FirstParameter(); |
255 | mytsup = C.LastParameter(); |
256 | Perform(C, NbT, mytmin, mytsup,Tol1); |
257 | } |
258 | |
259 | //======================================================================= |
260 | //function : Perform |
261 | //purpose : |
262 | //======================================================================= |
113493b0 |
263 | void Extrema_GenExtCS::Perform (const Adaptor3d_Curve& C, |
264 | const Standard_Integer NbT, |
265 | const Standard_Real tmin, |
266 | const Standard_Real tsup, |
267 | const Standard_Real Tol1) |
7fd59977 |
268 | { |
269 | myDone = Standard_False; |
270 | myF.Initialize(C,*myS); |
271 | mytmin = tmin; |
272 | mytsup = tsup; |
273 | mytol1 = Tol1; |
274 | mytsample = NbT; |
b659a6dc |
275 | // Modif de lvt pour trimer la surface non pas aux infinis mais a +/- 10000 |
7fd59977 |
276 | |
277 | Standard_Real trimusup = myusup, trimumin = myumin,trimvsup = myvsup,trimvmin = myvmin; |
f4dee9bb |
278 | Standard_Real aCMaxVal = GetCurvMaxParamVal (C); |
279 | if (Precision::IsInfinite(mytsup)){ |
280 | mytsup = aCMaxVal; |
7fd59977 |
281 | } |
f4dee9bb |
282 | if (Precision::IsInfinite(mytmin)){ |
283 | mytmin = -aCMaxVal; |
7fd59977 |
284 | } |
b659a6dc |
285 | // |
e8e8b273 |
286 | Standard_Integer aNbVar = 3; |
287 | GeomAbs_SurfaceType aSType = myS->GetType(); |
288 | if (IsQuadric(aSType)) |
289 | { |
290 | aNbVar = 1; |
291 | } |
292 | else |
293 | { |
294 | GeomAbs_CurveType aCType = C.GetType(); |
295 | if (IsConic(aCType)) |
296 | { |
297 | aNbVar = 2; |
298 | } |
299 | } |
300 | |
301 | math_Vector Tol(1, 3), TUV(1, 3), TUVinf(1, 3), TUVsup(1, 3); |
302 | // |
7fd59977 |
303 | Tol(1) = mytol1; |
304 | Tol(2) = mytol2; |
305 | Tol(3) = mytol2; |
e8e8b273 |
306 | // |
1d33d22b |
307 | TUVinf(1) = mytmin; |
308 | TUVinf(2) = trimumin; |
309 | TUVinf(3) = trimvmin; |
e8e8b273 |
310 | // |
1d33d22b |
311 | TUVsup(1) = mytsup; |
312 | TUVsup(2) = trimusup; |
313 | TUVsup(3) = trimvsup; |
e8e8b273 |
314 | // |
032d0272 |
315 | // Number of particles used in PSO algorithm (particle swarm optimization). |
fa6d1712 |
316 | const Standard_Integer aNbParticles = 48; |
e8e8b273 |
317 | // |
318 | if (aNbVar == 3) |
319 | { |
320 | GlobMinGenCS(C, aNbParticles, TUVinf, TUVsup, TUV); |
321 | } |
322 | else if (aNbVar == 2) |
323 | { |
324 | GlobMinConicS(C, aNbParticles, TUVinf, TUVsup, TUV); |
325 | } |
326 | else |
327 | { |
328 | GlobMinCQuadric(C, aNbParticles, TUVinf, TUVsup, TUV); |
329 | } |
330 | |
331 | // Find min approximation |
332 | math_FunctionSetRoot anA(myF, Tol); |
333 | anA.Perform(myF, TUV, TUVinf, TUVsup); |
113493b0 |
334 | |
e8e8b273 |
335 | myDone = Standard_True; |
336 | } |
337 | //======================================================================= |
338 | //function : GlobMinGenCS |
339 | //purpose : |
340 | //======================================================================= |
341 | void Extrema_GenExtCS::GlobMinGenCS(const Adaptor3d_Curve& theC, |
342 | const Standard_Integer theNbParticles, |
343 | const math_Vector& theTUVinf, |
344 | const math_Vector& theTUVsup, |
345 | math_Vector& theTUV) |
346 | { |
347 | math_PSOParticlesPool aParticles(theNbParticles, 3); |
113493b0 |
348 | |
e8e8b273 |
349 | math_Vector aMinTUV(1, 3); |
350 | aMinTUV = theTUVinf + (theTUVsup - theTUVinf) / aBorderDivisor; |
113493b0 |
351 | |
e8e8b273 |
352 | math_Vector aMaxTUV(1, 3); |
353 | aMaxTUV = theTUVsup - (theTUVsup - theTUVinf) / aBorderDivisor; |
113493b0 |
354 | |
032d0272 |
355 | Standard_Real aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample; |
356 | Standard_Real aStepSU = (aMaxTUV(2) - aMinTUV(2)) / myusample; |
357 | Standard_Real aStepSV = (aMaxTUV(3) - aMinTUV(3)) / myvsample; |
113493b0 |
358 | |
032d0272 |
359 | // Correct number of curve samples in case of low resolution |
e8e8b273 |
360 | Standard_Integer aNewCsample = mytsample; |
032d0272 |
361 | Standard_Real aScaleFactor = 5.0; |
e8e8b273 |
362 | Standard_Real aResolutionCU = aStepCU / theC.Resolution(1.0); |
113493b0 |
363 | |
e8e8b273 |
364 | Standard_Real aMinResolution = aScaleFactor * Min(aResolutionCU, |
365 | Min(aStepSU / myS->UResolution(1.0), aStepSV / myS->VResolution(1.0))); |
032d0272 |
366 | |
e8e8b273 |
367 | if (aMinResolution > Epsilon(1.0)) |
032d0272 |
368 | { |
369 | if (aResolutionCU > aMinResolution) |
29d778bf |
370 | { |
032d0272 |
371 | const Standard_Integer aMaxNbNodes = 50; |
113493b0 |
372 | |
e8e8b273 |
373 | aNewCsample = Min(aMaxNbNodes, |
032d0272 |
374 | RealToInt(mytsample * aResolutionCU / aMinResolution)); |
113493b0 |
375 | |
e8e8b273 |
376 | aStepCU = (aMaxTUV(1) - aMinTUV(1)) / aNewCsample; |
113493b0 |
377 | } |
032d0272 |
378 | } |
113493b0 |
379 | |
032d0272 |
380 | // Pre-compute curve sample points. |
e8e8b273 |
381 | TColgp_Array1OfPnt aCurvPnts(0, aNewCsample); |
113493b0 |
382 | |
51740958 |
383 | Standard_Real aCU1 = aMinTUV(1); |
e8e8b273 |
384 | for (Standard_Integer aCUI = 0; aCUI <= aNewCsample; aCUI++, aCU1 += aStepCU) |
385 | aCurvPnts.SetValue(aCUI, theC.Value(aCU1)); |
113493b0 |
386 | |
032d0272 |
387 | PSO_Particle* aParticle = aParticles.GetWorstParticle(); |
388 | // Select specified number of particles from pre-computed set of samples |
389 | Standard_Real aSU = aMinTUV(2); |
390 | for (Standard_Integer aSUI = 0; aSUI <= myusample; aSUI++, aSU += aStepSU) |
391 | { |
392 | Standard_Real aSV = aMinTUV(3); |
393 | for (Standard_Integer aSVI = 0; aSVI <= myvsample; aSVI++, aSV += aStepSV) |
113493b0 |
394 | { |
51740958 |
395 | Standard_Real aCU2 = aMinTUV(1); |
e8e8b273 |
396 | for (Standard_Integer aCUI = 0; aCUI <= aNewCsample; aCUI++, aCU2 += aStepCU) |
29d778bf |
397 | { |
e8e8b273 |
398 | Standard_Real aSqDist = mySurfPnts->Value(aSUI, aSVI).SquareDistance(aCurvPnts.Value(aCUI)); |
113493b0 |
399 | |
032d0272 |
400 | if (aSqDist < aParticle->Distance) |
401 | { |
51740958 |
402 | aParticle->Position[0] = aCU2; |
032d0272 |
403 | aParticle->Position[1] = aSU; |
404 | aParticle->Position[2] = aSV; |
113493b0 |
405 | |
51740958 |
406 | aParticle->BestPosition[0] = aCU2; |
032d0272 |
407 | aParticle->BestPosition[1] = aSU; |
408 | aParticle->BestPosition[2] = aSV; |
29d778bf |
409 | |
e8e8b273 |
410 | aParticle->Distance = aSqDist; |
032d0272 |
411 | aParticle->BestDistance = aSqDist; |
113493b0 |
412 | |
032d0272 |
413 | aParticle = aParticles.GetWorstParticle(); |
b659a6dc |
414 | } |
7fd59977 |
415 | } |
416 | } |
032d0272 |
417 | } |
113493b0 |
418 | |
e8e8b273 |
419 | math_Vector aStep(1, 3); |
032d0272 |
420 | aStep(1) = aStepCU; |
421 | aStep(2) = aStepSU; |
422 | aStep(3) = aStepSV; |
1d33d22b |
423 | |
032d0272 |
424 | // Find min approximation |
425 | Standard_Real aValue; |
e8e8b273 |
426 | Extrema_GlobOptFuncCS aFunc(&theC, myS); |
427 | math_PSO aPSO(&aFunc, theTUVinf, theTUVsup, aStep); |
428 | aPSO.Perform(aParticles, theNbParticles, aValue, theTUV); |
1d33d22b |
429 | |
e8e8b273 |
430 | } |
431 | //======================================================================= |
432 | //function : GlobMinConicS |
433 | //purpose : |
434 | //======================================================================= |
435 | void Extrema_GenExtCS::GlobMinConicS(const Adaptor3d_Curve& theC, |
436 | const Standard_Integer theNbParticles, |
437 | const math_Vector& theTUVinf, |
438 | const math_Vector& theTUVsup, |
439 | math_Vector& theTUV) |
440 | { |
441 | Standard_Integer aNbVar = 2; |
442 | math_Vector anUVinf(1, aNbVar), anUVsup(1, aNbVar), anUV(1, aNbVar); |
443 | Standard_Integer i; |
444 | for (i = 1; i <= aNbVar; ++i) |
445 | { |
446 | anUVinf(i) = theTUVinf(i + 1); |
447 | anUVsup(i) = theTUVsup(i + 1); |
448 | } |
449 | // |
450 | math_PSOParticlesPool aParticles(theNbParticles, aNbVar); |
451 | |
452 | math_Vector aMinUV(1, aNbVar); |
453 | aMinUV = anUVinf + (anUVsup - anUVinf) / aBorderDivisor; |
454 | |
455 | math_Vector aMaxUV(1, aNbVar); |
456 | aMaxUV = anUVsup - (anUVsup - anUVinf) / aBorderDivisor; |
457 | |
458 | //Increase numbers of UV samples to improve searching global minimum |
459 | Standard_Integer anAddsample = Max(mytsample / 2, 3); |
460 | Standard_Integer anUsample = myusample + anAddsample; |
461 | Standard_Integer aVsample = myvsample + anAddsample; |
462 | // |
463 | Standard_Real aStepSU = (aMaxUV(1) - aMinUV(1)) / anUsample; |
464 | Standard_Real aStepSV = (aMaxUV(2) - aMinUV(2)) / aVsample; |
465 | // |
466 | Extrema_GlobOptFuncConicS aFunc(myS, anUVinf(1), anUVsup(1), anUVinf(2), anUVsup(2)); |
467 | aFunc.LoadConic(&theC, theTUVinf(1), theTUVsup(1)); |
468 | |
469 | |
470 | PSO_Particle* aParticle = aParticles.GetWorstParticle(); |
471 | // Select specified number of particles from pre-computed set of samples |
472 | Standard_Real aSU = aMinUV(1); |
473 | |
474 | for (Standard_Integer aSUI = 0; aSUI <= anUsample; aSUI++, aSU += aStepSU) |
475 | { |
476 | anUV(1) = aSU; |
477 | Standard_Real aSV = aMinUV(2); |
478 | for (Standard_Integer aSVI = 0; aSVI <= aVsample; aSVI++, aSV += aStepSV) |
479 | { |
480 | anUV(2) = aSV; |
481 | Standard_Real aSqDist; |
482 | if (!aFunc.Value(anUV, aSqDist)) |
483 | { |
484 | aSqDist = Precision::Infinite(); |
485 | } |
486 | |
487 | if (aSqDist < aParticle->Distance) |
488 | { |
489 | aParticle->Position[0] = aSU; |
490 | aParticle->Position[1] = aSV; |
491 | |
492 | aParticle->BestPosition[0] = aSU; |
493 | aParticle->BestPosition[1] = aSV; |
494 | |
495 | aParticle->Distance = aSqDist; |
496 | aParticle->BestDistance = aSqDist; |
497 | |
498 | aParticle = aParticles.GetWorstParticle(); |
499 | } |
500 | } |
501 | } |
502 | |
503 | math_Vector aStep(1, aNbVar); |
504 | aStep(1) = aStepSU; |
505 | aStep(2) = aStepSV; |
506 | |
507 | // Find min approximation |
508 | Standard_Real aValue; |
509 | math_PSO aPSO(&aFunc, anUVinf, anUVsup, aStep); |
510 | aPSO.Perform(aParticles, theNbParticles, aValue, anUV); |
511 | // |
512 | Standard_Real aCT = aFunc.ConicParameter(anUV); |
513 | if (theC.IsPeriodic()) |
514 | { |
515 | if (aCT < theTUVinf(1) - Precision::PConfusion() || aCT > theTUVsup(1) + Precision::PConfusion()) |
516 | { |
517 | aCT = ElCLib::InPeriod(aCT, theTUVinf(1), theTUVinf(1) + 2. * M_PI); |
518 | } |
519 | } |
520 | theTUV(1) = aCT; |
521 | theTUV(2) = anUV(1); |
522 | theTUV(3) = anUV(2); |
523 | |
524 | } |
525 | //======================================================================= |
526 | //function : GlobMinCQuadric |
527 | //purpose : |
528 | //======================================================================= |
529 | void Extrema_GenExtCS::GlobMinCQuadric(const Adaptor3d_Curve& theC, |
530 | const Standard_Integer theNbParticles, |
531 | const math_Vector& theTUVinf, |
532 | const math_Vector& theTUVsup, |
533 | math_Vector& theTUV) |
534 | { |
535 | Standard_Integer aNbVar = 1; |
536 | math_Vector aTinf(1, aNbVar), aTsup(1, aNbVar), aT(1, aNbVar); |
537 | aTinf(1) = theTUVinf(1); |
538 | aTsup(1) = theTUVsup(1); |
539 | // |
540 | math_PSOParticlesPool aParticles(theNbParticles, aNbVar); |
541 | |
542 | math_Vector aMinT(1, aNbVar); |
543 | aMinT = aTinf + (aTsup - aTinf) / aBorderDivisor; |
544 | |
545 | math_Vector aMaxT(1, aNbVar); |
546 | aMaxT = aTsup - (aTsup - aTinf) / aBorderDivisor; |
547 | // |
548 | |
549 | //Increase numbers of curve samples to improve searching global minimum |
550 | //because dimension of optimisation task is redused |
551 | const Standard_Integer aMaxNbNodes = 50; |
552 | Standard_Integer aNewCsample = mytsample; |
553 | Standard_Integer anAddsample = Max(myusample / 2, 3); |
554 | aNewCsample += anAddsample; |
555 | aNewCsample = Min(aNewCsample, aMaxNbNodes); |
556 | // |
557 | // Correct number of curve samples in case of low resolution |
558 | Standard_Real aStepCT = (aMaxT(1) - aMinT(1)) / aNewCsample; |
559 | Standard_Real aStepSU = (theTUVsup(2) - theTUVinf(2)) / myusample; |
560 | Standard_Real aStepSV = (theTUVsup(3) - theTUVinf(3)) / myvsample; |
561 | Standard_Real aScaleFactor = 5.0; |
562 | Standard_Real aResolutionCU = aStepCT / theC.Resolution(1.0); |
563 | |
564 | Standard_Real aMinResolution = aScaleFactor * Min(aResolutionCU, |
565 | Min(aStepSU / myS->UResolution(1.0), aStepSV / myS->VResolution(1.0))); |
566 | |
567 | if (aMinResolution > Epsilon(1.0)) |
568 | { |
569 | if (aResolutionCU > aMinResolution) |
570 | { |
571 | |
572 | aNewCsample = Min(aMaxNbNodes, |
573 | RealToInt(aNewCsample * aResolutionCU / aMinResolution)); |
574 | |
575 | aStepCT = (aMaxT(1) - aMinT(1)) / aNewCsample; |
576 | } |
577 | } |
578 | |
579 | // |
580 | Extrema_GlobOptFuncCQuadric aFunc(&theC, aTinf(1), aTsup(1)); |
581 | aFunc.LoadQuad(myS, theTUVinf(2), theTUVsup(2), theTUVinf(3), theTUVsup(3)); |
582 | |
583 | PSO_Particle* aParticle = aParticles.GetWorstParticle(); |
584 | // Select specified number of particles from pre-computed set of samples |
585 | Standard_Real aCT = aMinT(1); |
586 | for (Standard_Integer aCUI = 0; aCUI <= aNewCsample; aCUI++, aCT += aStepCT) |
587 | { |
588 | aT(1) = aCT; |
589 | Standard_Real aSqDist; |
590 | if (!aFunc.Value(aT, aSqDist)) |
591 | { |
592 | aSqDist = Precision::Infinite(); |
593 | } |
594 | |
595 | if (aSqDist < aParticle->Distance) |
596 | { |
597 | aParticle->Position[0] = aCT; |
598 | |
599 | aParticle->BestPosition[0] = aCT; |
600 | |
601 | aParticle->Distance = aSqDist; |
602 | aParticle->BestDistance = aSqDist; |
603 | |
604 | aParticle = aParticles.GetWorstParticle(); |
605 | } |
606 | } |
607 | // |
608 | math_Vector aStep(1, aNbVar); |
609 | aStep(1) = aStepCT; |
610 | |
611 | // Find min approximation |
612 | Standard_Real aValue; |
613 | math_PSO aPSO(&aFunc, aTinf, aTsup, aStep); |
614 | aPSO.Perform(aParticles, theNbParticles, aValue, aT); |
615 | // |
616 | math_Vector anUV(1, 2); |
617 | aFunc.QuadricParameters(aT, anUV); |
618 | if (myS->IsUPeriodic()) |
619 | { |
620 | if (anUV(1) < theTUVinf(2) - Precision::PConfusion() || anUV(1)> theTUVsup(2) + Precision::PConfusion()) |
621 | { |
622 | anUV(1) = ElCLib::InPeriod(anUV(1), theTUVinf(2), theTUVinf(2) + 2. * M_PI); |
623 | } |
624 | } |
625 | // |
626 | if (myS->IsVPeriodic()) |
627 | { |
628 | if (anUV(2) < theTUVinf(3) - Precision::PConfusion() || anUV(2)> theTUVsup(3) + Precision::PConfusion()) |
629 | { |
630 | anUV(2) = ElCLib::InPeriod(anUV(2), theTUVinf(3), theTUVinf(3) + 2. * M_PI); |
631 | } |
632 | } |
633 | // |
634 | theTUV(1) = aT(1); |
635 | theTUV(2) = anUV(1); |
636 | theTUV(3) = anUV(2); |
7fd59977 |
637 | |
7fd59977 |
638 | } |
639 | |
640 | //======================================================================= |
641 | //function : IsDone |
642 | //purpose : |
643 | //======================================================================= |
7fd59977 |
644 | Standard_Boolean Extrema_GenExtCS::IsDone() const |
645 | { |
646 | return myDone; |
647 | } |
648 | |
649 | //======================================================================= |
650 | //function : NbExt |
651 | //purpose : |
652 | //======================================================================= |
7fd59977 |
653 | Standard_Integer Extrema_GenExtCS::NbExt() const |
654 | { |
9775fa61 |
655 | if (!IsDone()) { throw StdFail_NotDone(); } |
7fd59977 |
656 | return myF.NbExt(); |
657 | } |
658 | |
659 | //======================================================================= |
660 | //function : Value |
661 | //purpose : |
662 | //======================================================================= |
7fd59977 |
663 | Standard_Real Extrema_GenExtCS::SquareDistance(const Standard_Integer N) const |
664 | { |
638ad7f3 |
665 | if (N < 1 || N > NbExt()) |
666 | { |
667 | throw Standard_OutOfRange(); |
668 | } |
669 | |
7fd59977 |
670 | return myF.SquareDistance(N); |
671 | } |
672 | |
673 | //======================================================================= |
674 | //function : PointOnCurve |
675 | //purpose : |
676 | //======================================================================= |
7fd59977 |
677 | const Extrema_POnCurv& Extrema_GenExtCS::PointOnCurve(const Standard_Integer N) const |
678 | { |
638ad7f3 |
679 | if (N < 1 || N > NbExt()) |
680 | { |
681 | throw Standard_OutOfRange(); |
682 | } |
683 | |
7fd59977 |
684 | return myF.PointOnCurve(N); |
685 | } |
686 | |
687 | //======================================================================= |
688 | //function : PointOnSurface |
689 | //purpose : |
690 | //======================================================================= |
7fd59977 |
691 | const Extrema_POnSurf& Extrema_GenExtCS::PointOnSurface(const Standard_Integer N) const |
692 | { |
638ad7f3 |
693 | if (N < 1 || N > NbExt()) |
694 | { |
695 | throw Standard_OutOfRange(); |
696 | } |
697 | |
7fd59977 |
698 | return myF.PointOnSurface(N); |
699 | } |
700 | |
701 | //======================================================================= |
702 | //function : BidonSurface |
703 | //purpose : |
704 | //======================================================================= |
7fd59977 |
705 | Adaptor3d_SurfacePtr Extrema_GenExtCS::BidonSurface() const |
706 | { |
707 | return (Adaptor3d_SurfacePtr)0L; |
708 | } |
709 | |
710 | //======================================================================= |
711 | //function : BidonCurve |
712 | //purpose : |
713 | //======================================================================= |
7fd59977 |
714 | Adaptor3d_CurvePtr Extrema_GenExtCS::BidonCurve() const |
715 | { |
716 | return (Adaptor3d_CurvePtr)0L; |
717 | } |
718 | |