1 // Created on: 1995-07-18
2 // Created by: Modelistation
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor3d_Curve.hxx>
19 #include <Adaptor3d_HCurve.hxx>
20 #include <Adaptor3d_Surface.hxx>
21 #include <Extrema_ExtCC.hxx>
22 #include <Extrema_ExtPS.hxx>
23 #include <Extrema_GenExtCS.hxx>
24 #include <Extrema_GlobOptFuncCS.hxx>
25 #include <Extrema_POnCurv.hxx>
26 #include <Extrema_POnSurf.hxx>
27 #include <Geom_Line.hxx>
28 #include <GeomAdaptor_Curve.hxx>
29 #include <math_FunctionSetRoot.hxx>
30 #include <math_PSO.hxx>
31 #include <math_PSOParticlesPool.hxx>
32 #include <math_Vector.hxx>
33 #include <Precision.hxx>
34 #include <Standard_OutOfRange.hxx>
35 #include <Standard_TypeMismatch.hxx>
36 #include <StdFail_NotDone.hxx>
37 #include <TColgp_HArray1OfPnt.hxx>
39 const Standard_Real aMaxParamVal = 1.0e+10;
40 const Standard_Real aBorderDivisor = 1.0e+4;
42 //=======================================================================
43 //function : Extrema_GenExtCS
45 //=======================================================================
46 Extrema_GenExtCS::Extrema_GenExtCS()
48 myDone = Standard_False;
49 myInit = Standard_False;
52 //=======================================================================
53 //function : Extrema_GenExtCS
55 //=======================================================================
56 Extrema_GenExtCS::Extrema_GenExtCS(const Adaptor3d_Curve& C,
57 const Adaptor3d_Surface& S,
58 const Standard_Integer NbT,
59 const Standard_Integer NbU,
60 const Standard_Integer NbV,
61 const Standard_Real Tol1,
62 const Standard_Real Tol2)
64 Initialize(S, NbU, NbV, Tol2);
65 Perform(C, NbT, Tol1);
68 //=======================================================================
69 //function : Extrema_GenExtCS
71 //=======================================================================
73 Extrema_GenExtCS::Extrema_GenExtCS (const Adaptor3d_Curve& C,
74 const Adaptor3d_Surface& S,
75 const Standard_Integer NbT,
76 const Standard_Integer NbU,
77 const Standard_Integer NbV,
78 const Standard_Real tmin,
79 const Standard_Real tsup,
80 const Standard_Real Umin,
81 const Standard_Real Usup,
82 const Standard_Real Vmin,
83 const Standard_Real Vsup,
84 const Standard_Real Tol1,
85 const Standard_Real Tol2)
87 Initialize(S, NbU, NbV, Umin,Usup,Vmin,Vsup,Tol2);
88 Perform(C, NbT, tmin, tsup, Tol1);
91 //=======================================================================
92 //function : Initialize
94 //=======================================================================
95 void Extrema_GenExtCS::Initialize (const Adaptor3d_Surface& S,
96 const Standard_Integer NbU,
97 const Standard_Integer NbV,
98 const Standard_Real Tol2)
100 myumin = S.FirstUParameter();
101 myusup = S.LastUParameter();
102 myvmin = S.FirstVParameter();
103 myvsup = S.LastVParameter();
104 Initialize(S,NbU,NbV,myumin,myusup,myvmin,myvsup,Tol2);
107 //=======================================================================
108 //function : Initialize
110 //=======================================================================
111 void Extrema_GenExtCS::Initialize (const Adaptor3d_Surface& S,
112 const Standard_Integer NbU,
113 const Standard_Integer NbV,
114 const Standard_Real Umin,
115 const Standard_Real Usup,
116 const Standard_Real Vmin,
117 const Standard_Real Vsup,
118 const Standard_Real Tol2)
120 myS = (Adaptor3d_SurfacePtr)&S;
129 const Standard_Real aTrimMaxU = Precision::IsInfinite (myusup) ? aMaxParamVal : myusup;
130 const Standard_Real aTrimMinU = Precision::IsInfinite (myumin) ? -aMaxParamVal : myumin;
131 const Standard_Real aTrimMaxV = Precision::IsInfinite (myvsup) ? aMaxParamVal : myvsup;
132 const Standard_Real aTrimMinV = Precision::IsInfinite (myvmin) ? -aMaxParamVal : myvmin;
134 const Standard_Real aMinU = aTrimMinU + (aTrimMaxU - aTrimMinU) / aBorderDivisor;
135 const Standard_Real aMinV = aTrimMinV + (aTrimMaxV - aTrimMinV) / aBorderDivisor;
136 const Standard_Real aMaxU = aTrimMaxU - (aTrimMaxU - aTrimMinU) / aBorderDivisor;
137 const Standard_Real aMaxV = aTrimMaxV - (aTrimMaxV - aTrimMinV) / aBorderDivisor;
139 const Standard_Real aStepSU = (aMaxU - aMinU) / myusample;
140 const Standard_Real aStepSV = (aMaxV - aMinV) / myvsample;
142 mySurfPnts = new TColgp_HArray2OfPnt (0, myusample, 0, myvsample);
144 Standard_Real aSU = aMinU;
145 for (Standard_Integer aSUI = 0; aSUI <= myusample; aSUI++, aSU += aStepSU)
147 Standard_Real aSV = aMinV;
148 for (Standard_Integer aSVI = 0; aSVI <= myvsample; aSVI++, aSV += aStepSV)
150 mySurfPnts->ChangeValue (aSUI, aSVI) = myS->Value (aSU, aSV);
155 //=======================================================================
158 //=======================================================================
159 void Extrema_GenExtCS::Perform(const Adaptor3d_Curve& C,
160 const Standard_Integer NbT,
161 const Standard_Real Tol1)
163 mytmin = C.FirstParameter();
164 mytsup = C.LastParameter();
165 Perform(C, NbT, mytmin, mytsup,Tol1);
168 //=======================================================================
171 //=======================================================================
172 void Extrema_GenExtCS::Perform (const Adaptor3d_Curve& C,
173 const Standard_Integer NbT,
174 const Standard_Real tmin,
175 const Standard_Real tsup,
176 const Standard_Real Tol1)
178 myDone = Standard_False;
179 myF.Initialize(C,*myS);
184 // Modif de lvt pour trimer la surface non pas aux infinis mais a +/- 10000
186 Standard_Real trimusup = myusup, trimumin = myumin,trimvsup = myvsup,trimvmin = myvmin;
187 if (Precision::IsInfinite(trimusup)){
188 trimusup = aMaxParamVal;
190 if (Precision::IsInfinite(trimvsup)){
191 trimvsup = aMaxParamVal;
193 if (Precision::IsInfinite(trimumin)){
194 trimumin = -aMaxParamVal;
196 if (Precision::IsInfinite(trimvmin)){
197 trimvmin = -aMaxParamVal;
200 math_Vector Tol(1, 3);
204 math_Vector TUV(1,3), TUVinf(1,3), TUVsup(1,3);
206 TUVinf(2) = trimumin;
207 TUVinf(3) = trimvmin;
210 TUVsup(2) = trimusup;
211 TUVsup(3) = trimvsup;
213 // Number of particles used in PSO algorithm (particle swarm optimization).
214 const Standard_Integer aNbParticles = 32;
216 math_PSOParticlesPool aParticles(aNbParticles, 3);
218 math_Vector aMinTUV(1,3);
219 aMinTUV = TUVinf + (TUVsup - TUVinf) / aBorderDivisor;
221 math_Vector aMaxTUV(1,3);
222 aMaxTUV = TUVsup - (TUVsup - TUVinf) / aBorderDivisor;
224 Standard_Real aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
225 Standard_Real aStepSU = (aMaxTUV(2) - aMinTUV(2)) / myusample;
226 Standard_Real aStepSV = (aMaxTUV(3) - aMinTUV(3)) / myvsample;
228 // Correct number of curve samples in case of low resolution
229 Standard_Real aScaleFactor = 5.0;
230 Standard_Real aResolutionCU = aStepCU / C.Resolution (1.0);
232 Standard_Real aMinResolution = aScaleFactor * Min (aResolutionCU,
233 Min (aStepSU / myS->UResolution (1.0), aStepSV / myS->VResolution (1.0)));
235 if (aMinResolution > Epsilon (1.0))
237 if (aResolutionCU > aMinResolution)
239 const Standard_Integer aMaxNbNodes = 50;
241 mytsample = Min(aMaxNbNodes,
242 RealToInt(mytsample * aResolutionCU / aMinResolution));
244 aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
248 // Pre-compute curve sample points.
249 TColgp_HArray1OfPnt aCurvPnts (0, mytsample);
251 Standard_Real aCU1 = aMinTUV(1);
252 for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU1 += aStepCU)
253 aCurvPnts.SetValue (aCUI, C.Value (aCU1));
255 PSO_Particle* aParticle = aParticles.GetWorstParticle();
256 // Select specified number of particles from pre-computed set of samples
257 Standard_Real aSU = aMinTUV(2);
258 for (Standard_Integer aSUI = 0; aSUI <= myusample; aSUI++, aSU += aStepSU)
260 Standard_Real aSV = aMinTUV(3);
261 for (Standard_Integer aSVI = 0; aSVI <= myvsample; aSVI++, aSV += aStepSV)
263 Standard_Real aCU2 = aMinTUV(1);
264 for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU2 += aStepCU)
266 Standard_Real aSqDist = mySurfPnts->Value(aSUI, aSVI).SquareDistance(aCurvPnts.Value(aCUI));
268 if (aSqDist < aParticle->Distance)
270 aParticle->Position[0] = aCU2;
271 aParticle->Position[1] = aSU;
272 aParticle->Position[2] = aSV;
274 aParticle->BestPosition[0] = aCU2;
275 aParticle->BestPosition[1] = aSU;
276 aParticle->BestPosition[2] = aSV;
278 aParticle->Distance = aSqDist;
279 aParticle->BestDistance = aSqDist;
281 aParticle = aParticles.GetWorstParticle();
287 math_Vector aStep(1,3);
292 // Find min approximation
293 Standard_Real aValue;
294 Extrema_GlobOptFuncCS aFunc(&C, myS);
295 math_PSO aPSO(&aFunc, TUVinf, TUVsup, aStep);
296 aPSO.Perform(aParticles, aNbParticles, aValue, TUV);
298 math_FunctionSetRoot anA(myF, Tol);
299 anA.Perform(myF, TUV, TUVinf, TUVsup);
301 myDone = Standard_True;
304 //=======================================================================
307 //=======================================================================
308 Standard_Boolean Extrema_GenExtCS::IsDone() const
313 //=======================================================================
316 //=======================================================================
317 Standard_Integer Extrema_GenExtCS::NbExt() const
319 if (!IsDone()) { StdFail_NotDone::Raise(); }
323 //=======================================================================
326 //=======================================================================
327 Standard_Real Extrema_GenExtCS::SquareDistance(const Standard_Integer N) const
329 if (!IsDone()) { StdFail_NotDone::Raise(); }
330 return myF.SquareDistance(N);
333 //=======================================================================
334 //function : PointOnCurve
336 //=======================================================================
337 const Extrema_POnCurv& Extrema_GenExtCS::PointOnCurve(const Standard_Integer N) const
339 if (!IsDone()) { StdFail_NotDone::Raise(); }
340 return myF.PointOnCurve(N);
343 //=======================================================================
344 //function : PointOnSurface
346 //=======================================================================
347 const Extrema_POnSurf& Extrema_GenExtCS::PointOnSurface(const Standard_Integer N) const
349 if (!IsDone()) { StdFail_NotDone::Raise(); }
350 return myF.PointOnSurface(N);
353 //=======================================================================
354 //function : BidonSurface
356 //=======================================================================
357 Adaptor3d_SurfacePtr Extrema_GenExtCS::BidonSurface() const
359 return (Adaptor3d_SurfacePtr)0L;
362 //=======================================================================
363 //function : BidonCurve
365 //=======================================================================
366 Adaptor3d_CurvePtr Extrema_GenExtCS::BidonCurve() const
368 return (Adaptor3d_CurvePtr)0L;