7fd59977 |
1 | // File: Extrema_GenExtSS.cxx |
2 | // Created: Tue Jul 18 08:21:34 1995 |
3 | // Author: Modelistation |
4 | // <model@metrox> |
5 | |
6 | |
7 | #include <Extrema_GenExtCS.ixx> |
8 | |
9 | #include <math_Vector.hxx> |
10 | #include <math_FunctionSetRoot.hxx> |
11 | #include <Precision.hxx> |
12 | |
13 | #include <Geom_Line.hxx> |
14 | #include <Adaptor3d_HCurve.hxx> |
15 | #include <GeomAdaptor_Curve.hxx> |
16 | |
17 | #include <Extrema_ExtCC.hxx> |
18 | #include <Extrema_POnCurv.hxx> |
19 | #include <Extrema_ExtPS.hxx> |
20 | |
21 | //======================================================================= |
22 | //function : Extrema_GenExtCS |
23 | //purpose : |
24 | //======================================================================= |
25 | |
26 | Extrema_GenExtCS::Extrema_GenExtCS() |
27 | { |
28 | myDone = Standard_False; |
29 | myInit = Standard_False; |
30 | } |
31 | |
32 | //======================================================================= |
33 | //function : Extrema_GenExtCS |
34 | //purpose : |
35 | //======================================================================= |
36 | |
37 | Extrema_GenExtCS::Extrema_GenExtCS(const Adaptor3d_Curve& C, |
38 | const Adaptor3d_Surface& S, |
39 | const Standard_Integer NbT, |
40 | const Standard_Integer NbU, |
41 | const Standard_Integer NbV, |
42 | const Standard_Real Tol1, |
43 | const Standard_Real Tol2) |
44 | { |
45 | Initialize(S, NbU, NbV, Tol2); |
46 | Perform(C, NbT, Tol1); |
47 | } |
48 | |
49 | //======================================================================= |
50 | //function : Extrema_GenExtCS |
51 | //purpose : |
52 | //======================================================================= |
53 | |
54 | Extrema_GenExtCS::Extrema_GenExtCS(const Adaptor3d_Curve& C, |
55 | const Adaptor3d_Surface& S, |
56 | const Standard_Integer NbT, |
57 | const Standard_Integer NbU, |
58 | const Standard_Integer NbV, |
59 | const Standard_Real tmin, |
60 | const Standard_Real tsup, |
61 | const Standard_Real Umin, |
62 | const Standard_Real Usup, |
63 | const Standard_Real Vmin, |
64 | const Standard_Real Vsup, |
65 | const Standard_Real Tol1, |
66 | const Standard_Real Tol2) |
67 | { |
68 | Initialize(S, NbU, NbV, Umin,Usup,Vmin,Vsup,Tol2); |
69 | Perform(C, NbT, tmin, tsup, Tol1); |
70 | } |
71 | |
72 | //======================================================================= |
73 | //function : Initialize |
74 | //purpose : |
75 | //======================================================================= |
76 | |
77 | void Extrema_GenExtCS::Initialize(const Adaptor3d_Surface& S, |
78 | const Standard_Integer NbU, |
79 | const Standard_Integer NbV, |
80 | const Standard_Real Tol2) |
81 | { |
82 | myumin = S.FirstUParameter(); |
83 | myusup = S.LastUParameter(); |
84 | myvmin = S.FirstVParameter(); |
85 | myvsup = S.LastVParameter(); |
86 | Initialize(S,NbU,NbV,myumin,myusup,myvmin,myvsup,Tol2); |
87 | } |
88 | |
89 | //======================================================================= |
90 | //function : Initialize |
91 | //purpose : |
92 | //======================================================================= |
93 | |
94 | void Extrema_GenExtCS::Initialize(const Adaptor3d_Surface& S, |
95 | const Standard_Integer NbU, |
96 | const Standard_Integer NbV, |
97 | const Standard_Real Umin, |
98 | const Standard_Real Usup, |
99 | const Standard_Real Vmin, |
100 | const Standard_Real Vsup, |
101 | const Standard_Real Tol2) |
102 | { |
103 | myS = (Adaptor3d_SurfacePtr)&S; |
104 | mypoints2 = new TColgp_HArray2OfPnt(0,NbU+1,0,NbV+1); |
105 | myusample = NbU; |
106 | myvsample = NbV; |
107 | myumin = Umin; |
108 | myusup = Usup; |
109 | myvmin = Vmin; |
110 | myvsup = Vsup; |
111 | mytol2 = Tol2; |
112 | |
113 | // Parametrage de l echantillon sur S |
114 | |
115 | Standard_Real PasU = myusup - myumin; |
116 | Standard_Real PasV = myvsup - myvmin; |
117 | Standard_Real U0 = PasU / myusample / 100.; |
118 | Standard_Real V0 = PasV / myvsample / 100.; |
119 | gp_Pnt P1; |
120 | PasU = (PasU - U0) / (myusample - 1); |
121 | PasV = (PasV - V0) / (myvsample - 1); |
122 | U0 = myumin + U0/2.; |
123 | V0 = myvmin + V0/2.; |
124 | |
125 | // Calcul des distances |
126 | |
127 | Standard_Integer NoU, NoV; |
128 | Standard_Real U, V; |
129 | for ( NoU = 1, U = U0; NoU <= myusample; NoU++, U += PasU) { |
130 | for ( NoV = 1, V = V0; NoV <= myvsample; NoV++, V += PasV) { |
131 | P1 = myS->Value(U, V); |
132 | mypoints2->SetValue(NoU,NoV,P1); |
133 | } |
134 | } |
135 | } |
136 | |
137 | //======================================================================= |
138 | //function : Perform |
139 | //purpose : |
140 | //======================================================================= |
141 | |
142 | void Extrema_GenExtCS::Perform(const Adaptor3d_Curve& C, |
143 | const Standard_Integer NbT, |
144 | const Standard_Real Tol1) |
145 | { |
146 | mytmin = C.FirstParameter(); |
147 | mytsup = C.LastParameter(); |
148 | Perform(C, NbT, mytmin, mytsup,Tol1); |
149 | } |
150 | |
151 | //======================================================================= |
152 | //function : Perform |
153 | //purpose : |
154 | //======================================================================= |
155 | |
156 | void Extrema_GenExtCS::Perform(const Adaptor3d_Curve& C, |
157 | const Standard_Integer NbT, |
158 | const Standard_Real tmin, |
159 | const Standard_Real tsup, |
160 | const Standard_Real Tol1) |
161 | { |
162 | myDone = Standard_False; |
163 | myF.Initialize(C,*myS); |
164 | mytmin = tmin; |
165 | mytsup = tsup; |
166 | mytol1 = Tol1; |
167 | mytsample = NbT; |
168 | mypoints1 = new TColgp_HArray1OfPnt(0,NbT); |
169 | |
170 | Standard_Real t1, U, V; |
171 | Standard_Integer NoT, NoU, NoV; |
172 | gp_Pnt P1, P2; |
173 | |
174 | // Modif de lvt pour trimer la surface non pas aux infinis mais a +/- 10000 |
175 | |
176 | Standard_Real trimusup = myusup, trimumin = myumin,trimvsup = myvsup,trimvmin = myvmin; |
177 | if (Precision::IsInfinite(trimusup)){ |
178 | trimusup = 1.0e+10; |
179 | } |
180 | if (Precision::IsInfinite(trimvsup)){ |
181 | trimvsup = 1.0e+10; |
182 | } |
183 | if (Precision::IsInfinite(trimumin)){ |
184 | trimumin = -1.0e+10; |
185 | } |
186 | if (Precision::IsInfinite(trimvmin)){ |
187 | trimvmin = -1.0e+10; |
188 | } |
189 | |
190 | |
191 | // Parametrage de l echantillon sur C |
192 | |
193 | Standard_Real PasT = mytsup - mytmin; |
194 | Standard_Real t0 = PasT / mytsample / 100.; |
195 | PasT = (PasT - t0) / (mytsample - 1); |
196 | t0 = mytmin + t0/2.; |
197 | |
198 | // Parametrage de l echantillon sur S |
199 | |
200 | Standard_Real PasU = trimusup - trimumin; |
201 | Standard_Real PasV = trimvsup - trimvmin; |
202 | Standard_Real U0 = PasU / myusample / 100.; |
203 | Standard_Real V0 = PasV / myvsample / 100.; |
204 | PasU = (PasU - U0) / (myusample - 1); |
205 | PasV = (PasV - V0) / (myvsample - 1); |
206 | U0 = trimumin + U0/2.; |
207 | V0 = trimvmin + V0/2.; |
208 | |
209 | // Calcul des distances |
210 | |
211 | for ( NoT = 1, t1 = t0; NoT <= mytsample; NoT++, t1 += PasT) { |
212 | P1 = C.Value(t1); |
213 | mypoints1->SetValue(NoT,P1); |
214 | } |
215 | |
216 | |
217 | /* |
218 | b- Calcul des minima: |
219 | ----------------- |
220 | b.a) Initialisations: |
221 | */ |
222 | |
223 | math_Vector Tol(1, 3); |
224 | Tol(1) = mytol1; |
225 | Tol(2) = mytol2; |
226 | Tol(3) = mytol2; |
227 | math_Vector UV(1,3), UVinf(1,3), UVsup(1,3); |
228 | UVinf(1) = mytmin; |
229 | UVinf(2) = trimumin; |
230 | UVinf(3) = trimvmin; |
231 | |
232 | UVsup(1) = mytsup; |
233 | UVsup(2) = trimusup; |
234 | UVsup(3) = trimvsup; |
235 | |
236 | // 18/02/02 akm vvv : (OCC163) bad extremas - extrusion surface versus the line. |
237 | // Try to preset the initial solution as extrema between |
238 | // extrusion direction and the curve. |
239 | if (myS->GetType() == GeomAbs_SurfaceOfExtrusion) |
240 | { |
241 | gp_Dir aDir = myS->Direction(); |
242 | Handle(Adaptor3d_HCurve) aCurve = myS->BasisCurve(); |
243 | Standard_Real dfUFirst = aCurve->FirstParameter(); |
244 | // Create iso line of U=U0 |
245 | GeomAdaptor_Curve anAx(new Geom_Line(aCurve->Value(dfUFirst), aDir), |
246 | trimvmin, trimvsup); |
247 | Extrema_ExtCC aLocator(C, anAx); |
248 | if (aLocator.IsDone() && aLocator.NbExt()>0) |
249 | { |
250 | Standard_Integer iExt; |
251 | // Try to find all extremas |
252 | Extrema_POnCurv aP1, aP2; |
253 | for (iExt=1; iExt<=aLocator.NbExt(); iExt++) |
254 | { |
255 | aLocator.Points (iExt, aP1, aP2); |
256 | // Parameter on curve |
257 | UV(1) = aP1.Parameter(); |
258 | // To find parameters on surf, try ExtPS |
259 | Extrema_ExtPS aPreciser (aP1.Value(), *myS, mytol2, mytol2); |
260 | if (aPreciser.IsDone()) |
261 | { |
262 | // Managed to find extremas between point and surface |
263 | Standard_Integer iPExt; |
264 | for (iPExt=1; iPExt<=aPreciser.NbExt(); iPExt++) |
265 | { |
266 | aPreciser.Point(iPExt).Parameter(UV(2),UV(3)); |
267 | math_FunctionSetRoot S1 (myF,UV,Tol,UVinf,UVsup); |
268 | } |
269 | } |
270 | else |
271 | { |
272 | // Failed... try the point on iso line |
273 | UV(2) = dfUFirst; |
274 | UV(3) = aP2.Parameter(); |
275 | math_FunctionSetRoot S1 (myF,UV,Tol,UVinf,UVsup); |
276 | } |
277 | } // for (iExt=1; iExt<=aLocator.NbExt(); iExt++) |
278 | } // if (aLocator.IsDone() && aLocator.NbExt()>0) |
279 | } // if (myS.Type() == GeomAbs_ExtrusionSurface) |
280 | else |
281 | // 18/02/02 akm ^^^ |
282 | { |
283 | Standard_Real distmin = RealLast(), distmax = 0.0, TheDist; |
284 | |
285 | Standard_Integer NTmin=0,NUmin=0,NVmin=0; |
286 | gp_Pnt PP1min, PP2min; |
287 | Standard_Integer NTmax=0,NUmax=0,NVmax=0; |
288 | gp_Pnt PP1max, PP2max; |
289 | for ( NoT = 1, t1 = t0; NoT <= mytsample; NoT++, t1 += PasT) { |
290 | P1 = mypoints1->Value(NoT); |
291 | for ( NoU = 1, U = U0; NoU <= myusample; NoU++, U += PasU) { |
292 | for ( NoV = 1, V = V0; NoV <= myvsample; NoV++, V += PasV) { |
293 | P2 = mypoints2->Value(NoU, NoV); |
294 | TheDist = P1.SquareDistance(P2); |
295 | if (TheDist < distmin) { |
296 | distmin = TheDist; |
297 | NTmin = NoT; |
298 | NUmin = NoU; |
299 | NVmin = NoV; |
300 | PP1min = P1; |
301 | PP2min = P2; |
302 | } |
303 | if (TheDist > distmax) { |
304 | distmax = TheDist; |
305 | NTmax = NoT; |
306 | NUmax = NoU; |
307 | NVmax = NoV; |
308 | PP1max = P1; |
309 | PP2max = P2; |
310 | } |
311 | } |
312 | } |
313 | } |
314 | |
315 | // minimum: |
316 | UV(1) = t0 + (NTmin - 1) * PasT; |
317 | UV(2) = U0 + (NUmin - 1) * PasU; |
318 | UV(3) = V0 + (NVmin - 1) * PasV; |
319 | |
320 | math_FunctionSetRoot S1 (myF,UV,Tol,UVinf,UVsup); |
321 | |
322 | // maximum: |
323 | UV(1) = t0 + (NTmax - 1) * PasT; |
324 | UV(2) = U0 + (NUmax - 1) * PasU; |
325 | UV(3) = V0 + (NVmax - 1) * PasV; |
326 | |
327 | math_FunctionSetRoot S2 (myF,UV,Tol,UVinf,UVsup); |
328 | |
329 | } |
330 | |
331 | myDone = Standard_True; |
332 | } |
333 | |
334 | //======================================================================= |
335 | //function : IsDone |
336 | //purpose : |
337 | //======================================================================= |
338 | |
339 | Standard_Boolean Extrema_GenExtCS::IsDone() const |
340 | { |
341 | return myDone; |
342 | } |
343 | |
344 | //======================================================================= |
345 | //function : NbExt |
346 | //purpose : |
347 | //======================================================================= |
348 | |
349 | Standard_Integer Extrema_GenExtCS::NbExt() const |
350 | { |
351 | if (!IsDone()) { StdFail_NotDone::Raise(); } |
352 | return myF.NbExt(); |
353 | } |
354 | |
355 | //======================================================================= |
356 | //function : Value |
357 | //purpose : |
358 | //======================================================================= |
359 | |
360 | Standard_Real Extrema_GenExtCS::SquareDistance(const Standard_Integer N) const |
361 | { |
362 | if (!IsDone()) { StdFail_NotDone::Raise(); } |
363 | return myF.SquareDistance(N); |
364 | } |
365 | |
366 | //======================================================================= |
367 | //function : PointOnCurve |
368 | //purpose : |
369 | //======================================================================= |
370 | |
371 | const Extrema_POnCurv& Extrema_GenExtCS::PointOnCurve(const Standard_Integer N) const |
372 | { |
373 | if (!IsDone()) { StdFail_NotDone::Raise(); } |
374 | return myF.PointOnCurve(N); |
375 | } |
376 | |
377 | //======================================================================= |
378 | //function : PointOnSurface |
379 | //purpose : |
380 | //======================================================================= |
381 | |
382 | const Extrema_POnSurf& Extrema_GenExtCS::PointOnSurface(const Standard_Integer N) const |
383 | { |
384 | if (!IsDone()) { StdFail_NotDone::Raise(); } |
385 | return myF.PointOnSurface(N); |
386 | } |
387 | |
388 | //======================================================================= |
389 | //function : BidonSurface |
390 | //purpose : |
391 | //======================================================================= |
392 | |
393 | Adaptor3d_SurfacePtr Extrema_GenExtCS::BidonSurface() const |
394 | { |
395 | return (Adaptor3d_SurfacePtr)0L; |
396 | } |
397 | |
398 | //======================================================================= |
399 | //function : BidonCurve |
400 | //purpose : |
401 | //======================================================================= |
402 | |
403 | Adaptor3d_CurvePtr Extrema_GenExtCS::BidonCurve() const |
404 | { |
405 | return (Adaptor3d_CurvePtr)0L; |
406 | } |
407 | |