b311480e |
1 | // Created on: 1995-07-18 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1995-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | |
23 | #include <Extrema_GenExtCS.ixx> |
24 | |
25 | #include <math_Vector.hxx> |
26 | #include <math_FunctionSetRoot.hxx> |
27 | #include <Precision.hxx> |
28 | |
29 | #include <Geom_Line.hxx> |
30 | #include <Adaptor3d_HCurve.hxx> |
31 | #include <GeomAdaptor_Curve.hxx> |
32 | |
33 | #include <Extrema_ExtCC.hxx> |
34 | #include <Extrema_POnCurv.hxx> |
35 | #include <Extrema_ExtPS.hxx> |
36 | |
37 | //======================================================================= |
38 | //function : Extrema_GenExtCS |
39 | //purpose : |
40 | //======================================================================= |
41 | |
b311480e |
42 | Extrema_GenExtCS::Extrema_GenExtCS() |
7fd59977 |
43 | { |
44 | myDone = Standard_False; |
45 | myInit = Standard_False; |
46 | } |
47 | |
48 | //======================================================================= |
49 | //function : Extrema_GenExtCS |
50 | //purpose : |
51 | //======================================================================= |
52 | |
53 | Extrema_GenExtCS::Extrema_GenExtCS(const Adaptor3d_Curve& C, |
54 | const Adaptor3d_Surface& S, |
55 | const Standard_Integer NbT, |
56 | const Standard_Integer NbU, |
57 | const Standard_Integer NbV, |
58 | const Standard_Real Tol1, |
59 | const Standard_Real Tol2) |
60 | { |
61 | Initialize(S, NbU, NbV, Tol2); |
62 | Perform(C, NbT, Tol1); |
63 | } |
64 | |
65 | //======================================================================= |
66 | //function : Extrema_GenExtCS |
67 | //purpose : |
68 | //======================================================================= |
69 | |
70 | Extrema_GenExtCS::Extrema_GenExtCS(const Adaptor3d_Curve& C, |
71 | const Adaptor3d_Surface& S, |
72 | const Standard_Integer NbT, |
73 | const Standard_Integer NbU, |
74 | const Standard_Integer NbV, |
75 | const Standard_Real tmin, |
76 | const Standard_Real tsup, |
77 | const Standard_Real Umin, |
78 | const Standard_Real Usup, |
79 | const Standard_Real Vmin, |
80 | const Standard_Real Vsup, |
81 | const Standard_Real Tol1, |
82 | const Standard_Real Tol2) |
83 | { |
84 | Initialize(S, NbU, NbV, Umin,Usup,Vmin,Vsup,Tol2); |
85 | Perform(C, NbT, tmin, tsup, Tol1); |
86 | } |
87 | |
88 | //======================================================================= |
89 | //function : Initialize |
90 | //purpose : |
91 | //======================================================================= |
92 | |
93 | void Extrema_GenExtCS::Initialize(const Adaptor3d_Surface& S, |
94 | const Standard_Integer NbU, |
95 | const Standard_Integer NbV, |
96 | const Standard_Real Tol2) |
97 | { |
98 | myumin = S.FirstUParameter(); |
99 | myusup = S.LastUParameter(); |
100 | myvmin = S.FirstVParameter(); |
101 | myvsup = S.LastVParameter(); |
102 | Initialize(S,NbU,NbV,myumin,myusup,myvmin,myvsup,Tol2); |
103 | } |
104 | |
105 | //======================================================================= |
106 | //function : Initialize |
107 | //purpose : |
108 | //======================================================================= |
109 | |
110 | void Extrema_GenExtCS::Initialize(const Adaptor3d_Surface& S, |
111 | const Standard_Integer NbU, |
112 | const Standard_Integer NbV, |
113 | const Standard_Real Umin, |
114 | const Standard_Real Usup, |
115 | const Standard_Real Vmin, |
116 | const Standard_Real Vsup, |
117 | const Standard_Real Tol2) |
118 | { |
119 | myS = (Adaptor3d_SurfacePtr)&S; |
7fd59977 |
120 | myusample = NbU; |
121 | myvsample = NbV; |
122 | myumin = Umin; |
123 | myusup = Usup; |
124 | myvmin = Vmin; |
125 | myvsup = Vsup; |
126 | mytol2 = Tol2; |
7fd59977 |
127 | } |
128 | |
129 | //======================================================================= |
130 | //function : Perform |
131 | //purpose : |
132 | //======================================================================= |
133 | |
134 | void Extrema_GenExtCS::Perform(const Adaptor3d_Curve& C, |
135 | const Standard_Integer NbT, |
136 | const Standard_Real Tol1) |
137 | { |
138 | mytmin = C.FirstParameter(); |
139 | mytsup = C.LastParameter(); |
140 | Perform(C, NbT, mytmin, mytsup,Tol1); |
141 | } |
142 | |
143 | //======================================================================= |
144 | //function : Perform |
145 | //purpose : |
146 | //======================================================================= |
147 | |
148 | void Extrema_GenExtCS::Perform(const Adaptor3d_Curve& C, |
149 | const Standard_Integer NbT, |
150 | const Standard_Real tmin, |
151 | const Standard_Real tsup, |
152 | const Standard_Real Tol1) |
153 | { |
154 | myDone = Standard_False; |
155 | myF.Initialize(C,*myS); |
156 | mytmin = tmin; |
157 | mytsup = tsup; |
158 | mytol1 = Tol1; |
159 | mytsample = NbT; |
b659a6dc |
160 | // Modif de lvt pour trimer la surface non pas aux infinis mais a +/- 10000 |
7fd59977 |
161 | |
162 | Standard_Real trimusup = myusup, trimumin = myumin,trimvsup = myvsup,trimvmin = myvmin; |
163 | if (Precision::IsInfinite(trimusup)){ |
164 | trimusup = 1.0e+10; |
165 | } |
166 | if (Precision::IsInfinite(trimvsup)){ |
167 | trimvsup = 1.0e+10; |
168 | } |
169 | if (Precision::IsInfinite(trimumin)){ |
170 | trimumin = -1.0e+10; |
171 | } |
172 | if (Precision::IsInfinite(trimvmin)){ |
173 | trimvmin = -1.0e+10; |
174 | } |
b659a6dc |
175 | // |
7fd59977 |
176 | math_Vector Tol(1, 3); |
177 | Tol(1) = mytol1; |
178 | Tol(2) = mytol2; |
179 | Tol(3) = mytol2; |
180 | math_Vector UV(1,3), UVinf(1,3), UVsup(1,3); |
181 | UVinf(1) = mytmin; |
182 | UVinf(2) = trimumin; |
183 | UVinf(3) = trimvmin; |
184 | |
185 | UVsup(1) = mytsup; |
186 | UVsup(2) = trimusup; |
187 | UVsup(3) = trimvsup; |
7fd59977 |
188 | // 18/02/02 akm vvv : (OCC163) bad extremas - extrusion surface versus the line. |
189 | // Try to preset the initial solution as extrema between |
190 | // extrusion direction and the curve. |
191 | if (myS->GetType() == GeomAbs_SurfaceOfExtrusion) |
192 | { |
193 | gp_Dir aDir = myS->Direction(); |
194 | Handle(Adaptor3d_HCurve) aCurve = myS->BasisCurve(); |
195 | Standard_Real dfUFirst = aCurve->FirstParameter(); |
196 | // Create iso line of U=U0 |
197 | GeomAdaptor_Curve anAx(new Geom_Line(aCurve->Value(dfUFirst), aDir), |
198 | trimvmin, trimvsup); |
199 | Extrema_ExtCC aLocator(C, anAx); |
200 | if (aLocator.IsDone() && aLocator.NbExt()>0) |
201 | { |
202 | Standard_Integer iExt; |
203 | // Try to find all extremas |
204 | Extrema_POnCurv aP1, aP2; |
205 | for (iExt=1; iExt<=aLocator.NbExt(); iExt++) |
206 | { |
b659a6dc |
207 | aLocator.Points (iExt, aP1, aP2); |
208 | // Parameter on curve |
209 | UV(1) = aP1.Parameter(); |
210 | // To find parameters on surf, try ExtPS |
211 | Extrema_ExtPS aPreciser (aP1.Value(), *myS, mytol2, mytol2); |
212 | if (aPreciser.IsDone()) |
213 | { |
214 | // Managed to find extremas between point and surface |
215 | Standard_Integer iPExt; |
216 | for (iPExt=1; iPExt<=aPreciser.NbExt(); iPExt++) |
217 | { |
218 | aPreciser.Point(iPExt).Parameter(UV(2),UV(3)); |
219 | math_FunctionSetRoot S1 (myF,UV,Tol,UVinf,UVsup); |
220 | } |
221 | } |
222 | else |
223 | { |
224 | // Failed... try the point on iso line |
225 | UV(2) = dfUFirst; |
226 | UV(3) = aP2.Parameter(); |
227 | math_FunctionSetRoot S1 (myF,UV,Tol,UVinf,UVsup); |
228 | } |
7fd59977 |
229 | } // for (iExt=1; iExt<=aLocator.NbExt(); iExt++) |
230 | } // if (aLocator.IsDone() && aLocator.NbExt()>0) |
231 | } // if (myS.Type() == GeomAbs_ExtrusionSurface) |
b659a6dc |
232 | else |
7fd59977 |
233 | { |
b659a6dc |
234 | Standard_Real aCUAdd = (mytsup - mytmin) / mytsample; |
235 | Standard_Real aSUAdd = (myusup - myumin) / myusample; |
236 | Standard_Real aSVAdd = (myvsup - myvmin) / myvsample; |
237 | TColgp_HArray1OfPnt aCPs(1, mytsample); |
238 | TColgp_HArray2OfPnt aSPs(1, myusample, 1, myvsample); |
239 | Standard_Integer aRestIterCount = 3; |
240 | // The value is calculated by the bug CR23830. |
241 | Standard_Integer aCUDen = 2, aSUDen = 2, aSVDen = 2; |
242 | Standard_Boolean anAreAvSqsInited = Standard_False; |
243 | Standard_Real aCUSq = 0, aSUSq = 0, aSVSq = 0; |
244 | while (aRestIterCount--) |
245 | { |
1d47d8d0 |
246 | Standard_Real aMinCU = 0., aMinSU = 0., aMinSV = 0., aMaxCU = 0., aMaxSU = 0., aMaxSV = 0.; |
b659a6dc |
247 | Standard_Real aMinSqDist = DBL_MAX, aMaxSqDist = -DBL_MAX; |
248 | for (Standard_Integer aSUNom = 1; aSUNom < aSUDen; aSUNom += 2) |
249 | { |
250 | Standard_Real aSU0 = myumin + (aSUNom * aSUAdd) / aSUDen; |
251 | for (Standard_Integer aSVNom = 1; aSVNom < aSVDen; aSVNom += 2) |
252 | { |
253 | Standard_Real aSV0 = myvmin + (aSVNom * aSVAdd) / aSVDen; |
254 | for (Standard_Integer aCUNom = 1; aCUNom < aCUDen; aCUNom += 2) |
255 | { |
256 | Standard_Real aCU0 = mytmin + (aCUNom * aCUAdd) / aCUDen; |
257 | Standard_Real aCU = aCU0; |
258 | for (Standard_Integer aCUI = 1; aCUI <= mytsample; |
259 | aCUI++, aCU += aCUAdd) |
260 | { |
261 | aCPs.SetValue(aCUI, C.Value(aCU)); |
262 | } |
263 | // |
264 | aCU = aCU0; |
265 | Standard_Real aSU = aSU0; |
266 | for (Standard_Integer aSUI = 1; aSUI <= myusample; |
267 | aSUI++, aSU += aSUAdd) |
268 | { |
269 | Standard_Real aSV = aSV0; |
270 | for (Standard_Integer aSVI = 1; aSVI <= myvsample; |
271 | aSVI++, aSV += aSVAdd) |
272 | { |
273 | gp_Pnt aSP = myS->Value(aSU, aSV); |
274 | aSPs.ChangeValue(aSUI, aSVI) = aSP; |
275 | Standard_Real aCU = aCU0; |
276 | for (Standard_Integer aCUI = 1; aCUI <= mytsample; |
277 | aCUI++, aCU += aCUAdd) |
278 | { |
279 | Standard_Real aSqDist = aSP.SquareDistance(aCPs.Value(aCUI)); |
280 | if (aSqDist < aMinSqDist) |
281 | { |
282 | aMinSqDist = aSqDist; |
283 | aMinCU = aCU; |
284 | aMinSU = aSU; |
285 | aMinSV = aSV; |
286 | } |
287 | if (aMaxSqDist < aSqDist) |
288 | { |
289 | aMaxSqDist = aSqDist; |
290 | aMaxCU = aCU; |
291 | aMaxSU = aSU; |
292 | aMaxSV = aSV; |
293 | } |
294 | } |
295 | } |
296 | } |
297 | } |
298 | } |
299 | } |
300 | // Find min approximation. |
301 | UV(1) = aMinCU; |
302 | UV(2) = aMinSU; |
303 | UV(3) = aMinSV; |
304 | math_FunctionSetRoot anA(myF, UV, Tol, UVinf, UVsup, 100, aRestIterCount); |
305 | // Find max approximation. |
306 | if (!anA.IsDivergent() || !aRestIterCount) |
307 | { |
308 | UV(1) = aMaxCU; |
309 | UV(2) = aMaxSU; |
310 | UV(3) = aMaxSV; |
311 | math_FunctionSetRoot(myF, UV, Tol, UVinf, UVsup); |
312 | break; |
313 | } |
314 | // |
315 | if (!anAreAvSqsInited) |
316 | { |
317 | anAreAvSqsInited = Standard_True; |
318 | // |
319 | const gp_Pnt * aCP1 = &aCPs.Value(1); |
320 | for (Standard_Integer aCUI = 2; aCUI <= mytsample; aCUI++) |
321 | { |
322 | const gp_Pnt & aCP2 = aCPs.Value(aCUI); |
323 | aCUSq += aCP1->SquareDistance(aCP2); |
324 | aCP1 = &aCP2; |
325 | } |
326 | aCUSq /= mytsample - 1; |
327 | // |
328 | for (Standard_Integer aSVI = 1; aSVI <= myvsample; aSVI++) |
329 | { |
330 | const gp_Pnt * aSP1 = &aSPs.Value(1, aSVI); |
331 | for (Standard_Integer aSUI = 2; aSUI <= myusample; aSUI++) |
332 | { |
333 | const gp_Pnt & aSP2 = aSPs.Value(aSUI, aSVI); |
334 | aSUSq += aSP1->SquareDistance(aSP2); |
335 | aSP1 = &aSP2; |
336 | } |
337 | } |
338 | aSUSq /= myvsample * (myusample - 1); |
339 | // |
340 | for (Standard_Integer aSUI = 1; aSUI <= myusample; aSUI++) |
341 | { |
342 | const gp_Pnt * aSP1 = &aSPs.Value(aSUI, 1); |
343 | for (Standard_Integer aSVI = 2; aSVI <= myvsample; aSVI++) |
344 | { |
345 | const gp_Pnt & aSP2 = aSPs.Value(aSUI, aSVI); |
346 | aSVSq += aSP1->SquareDistance(aSP2); |
347 | aSP1 = &aSP2; |
348 | } |
349 | } |
350 | aSVSq /= myusample * (myvsample - 1); |
351 | } |
352 | // |
353 | if ((aSUSq <= aCUSq) && (aSVSq <= aCUSq)) |
354 | { |
355 | aCUDen += aCUDen; |
356 | aCUSq /= 4; |
357 | } |
358 | else if ((aCUSq <= aSUSq) && (aSVSq <= aSUSq)) |
359 | { |
360 | aSUDen += aSUDen; |
361 | aSUSq /= 4; |
362 | } |
363 | else |
364 | { |
365 | aSVDen += aSVDen; |
366 | aSVSq /= 4; |
7fd59977 |
367 | } |
368 | } |
7fd59977 |
369 | } |
370 | |
371 | myDone = Standard_True; |
372 | } |
373 | |
374 | //======================================================================= |
375 | //function : IsDone |
376 | //purpose : |
377 | //======================================================================= |
378 | |
379 | Standard_Boolean Extrema_GenExtCS::IsDone() const |
380 | { |
381 | return myDone; |
382 | } |
383 | |
384 | //======================================================================= |
385 | //function : NbExt |
386 | //purpose : |
387 | //======================================================================= |
388 | |
389 | Standard_Integer Extrema_GenExtCS::NbExt() const |
390 | { |
391 | if (!IsDone()) { StdFail_NotDone::Raise(); } |
392 | return myF.NbExt(); |
393 | } |
394 | |
395 | //======================================================================= |
396 | //function : Value |
397 | //purpose : |
398 | //======================================================================= |
399 | |
400 | Standard_Real Extrema_GenExtCS::SquareDistance(const Standard_Integer N) const |
401 | { |
402 | if (!IsDone()) { StdFail_NotDone::Raise(); } |
403 | return myF.SquareDistance(N); |
404 | } |
405 | |
406 | //======================================================================= |
407 | //function : PointOnCurve |
408 | //purpose : |
409 | //======================================================================= |
410 | |
411 | const Extrema_POnCurv& Extrema_GenExtCS::PointOnCurve(const Standard_Integer N) const |
412 | { |
413 | if (!IsDone()) { StdFail_NotDone::Raise(); } |
414 | return myF.PointOnCurve(N); |
415 | } |
416 | |
417 | //======================================================================= |
418 | //function : PointOnSurface |
419 | //purpose : |
420 | //======================================================================= |
421 | |
422 | const Extrema_POnSurf& Extrema_GenExtCS::PointOnSurface(const Standard_Integer N) const |
423 | { |
424 | if (!IsDone()) { StdFail_NotDone::Raise(); } |
425 | return myF.PointOnSurface(N); |
426 | } |
427 | |
428 | //======================================================================= |
429 | //function : BidonSurface |
430 | //purpose : |
431 | //======================================================================= |
432 | |
433 | Adaptor3d_SurfacePtr Extrema_GenExtCS::BidonSurface() const |
434 | { |
435 | return (Adaptor3d_SurfacePtr)0L; |
436 | } |
437 | |
438 | //======================================================================= |
439 | //function : BidonCurve |
440 | //purpose : |
441 | //======================================================================= |
442 | |
443 | Adaptor3d_CurvePtr Extrema_GenExtCS::BidonCurve() const |
444 | { |
445 | return (Adaptor3d_CurvePtr)0L; |
446 | } |
447 | |