0023022: This is desirable to access OpenGl extensions and core API (1.2+) in one...
[occt.git] / src / Extrema / Extrema_GenExtCS.cxx
CommitLineData
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
77void 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
94void 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
142void 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
156void 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/*
218b- 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
339Standard_Boolean Extrema_GenExtCS::IsDone() const
340{
341 return myDone;
342}
343
344//=======================================================================
345//function : NbExt
346//purpose :
347//=======================================================================
348
349Standard_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
360Standard_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
371const 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
382const 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
393Adaptor3d_SurfacePtr Extrema_GenExtCS::BidonSurface() const
394{
395 return (Adaptor3d_SurfacePtr)0L;
396}
397
398//=======================================================================
399//function : BidonCurve
400//purpose :
401//=======================================================================
402
403Adaptor3d_CurvePtr Extrema_GenExtCS::BidonCurve() const
404{
405 return (Adaptor3d_CurvePtr)0L;
406}
407