OCC22322 Improvement of Extrema performance
[occt.git] / src / Extrema / Extrema_ExtPS.cxx
CommitLineData
7fd59977 1// File Extrema_ExtPS.cxx
2//-----------------------------------------------------------------
3// modif JMB le 17 Mai 1999.
4// on trimme la surface a +/- 10000 plutot qu'a l'infini
5// (sinon ca raise dans les Math)
6// voir bug ID260065
7//-----------------------------------------------------------------
8
9#include <Extrema_ExtPS.ixx>
10#include <Extrema_GenExtPS.hxx>
11#include <StdFail_NotDone.hxx>
12#include <Standard_NotImplemented.hxx>
13#include <Precision.hxx>
14#include <GeomAbs_CurveType.hxx>
15#include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
16#include <Adaptor3d_SurfaceOfRevolution.hxx>
17#include <ElCLib.hxx>
18#include <gp_Pnt.hxx>
19#include <gp_Pln.hxx>
20#include <gp_Cylinder.hxx>
21#include <gp_Cone.hxx>
22#include <gp_Sphere.hxx>
23#include <gp_Torus.hxx>
24#include <Extrema_ExtPExtS.hxx>
25#include <Extrema_ExtPRevS.hxx>
26#include <Extrema_POnSurf.hxx>
27#include <GeomAbs_IsoType.hxx>
28
29//=======================================================================
30//function : IsoIsDeg
31//purpose :
32//=======================================================================
33
34static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
35 const Standard_Real Param,
36 const GeomAbs_IsoType IT,
37 const Standard_Real TolMin,
38 const Standard_Real TolMax)
39{
40 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
41 Standard_Boolean Along = Standard_True;
42 U1 = S.FirstUParameter();
43 U2 = S.LastUParameter();
44 V1 = S.FirstVParameter();
45 V2 = S.LastVParameter();
46 gp_Vec D1U,D1V;
47 gp_Pnt P;
48 Standard_Real Step,D1NormMax;
49 if (IT == GeomAbs_IsoV)
50 {
51 Step = (U2 - U1)/10;
52 if(Step < Precision::PConfusion()) {
53 return Standard_False;
54 }
92d1589b
A
55 if(Step < Precision::PConfusion()) {
56 return Standard_False;
57 }
7fd59977 58 D1NormMax=0.;
59 for (T=U1;T<=U2;T=T+Step)
60 {
61 S.D1(T,Param,P,D1U,D1V);
62 D1NormMax=Max(D1NormMax,D1U.Magnitude());
63 }
64
65 if (D1NormMax >TolMax || D1NormMax < TolMin )
66 Along = Standard_False;
67 }
68 else
69 {
70 Step = (V2 - V1)/10;
71 if(Step < Precision::PConfusion()) {
72 return Standard_False;
73 }
92d1589b
A
74 if(Step < Precision::PConfusion()) {
75 return Standard_False;
76 }
7fd59977 77 D1NormMax=0.;
78 for (T=V1;T<=V2;T=T+Step)
79 {
80 S.D1(Param,T,P,D1U,D1V);
81 D1NormMax=Max(D1NormMax,D1V.Magnitude());
82 }
83
84 if (D1NormMax >TolMax || D1NormMax < TolMin )
85 Along = Standard_False;
86
87
88 }
89 return Along;
90}
91
92//=======================================================================
93//function : TreatSolution
94//purpose :
95//=======================================================================
96
97void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
98 const Standard_Real Val)
99{
100 Standard_Real U, V;
101 PS.Parameter(U, V);
102 if (myS->IsUPeriodic()) {
103 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
104 }
105 if (myS->IsVPeriodic()) {
106 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
107 }
108 if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu &&
109 (myvinf-V) <= mytolv && (V-myvsup) <= mytolv) {
110 myPoints.Append(Extrema_POnSurf (U, V, PS.Value()));
111 mySqDist.Append(Val);
112 }
113}
114
115
116//=======================================================================
117//function : Extrema_ExtPS
118//purpose :
119//=======================================================================
120
121Extrema_ExtPS::Extrema_ExtPS()
122{
123 myDone = Standard_False;
124}
125
126
127//=======================================================================
128//function : Extrema_ExtPS
129//purpose :
130//=======================================================================
131
132Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
133 const Adaptor3d_Surface& S,
134 const Standard_Real TolU,
92d1589b
A
135 const Standard_Real TolV,
136 const Extrema_ExtFlag F,
137 const Extrema_ExtAlgo A)
7fd59977 138
139{
92d1589b
A
140 myExtPS.SetFlag(F);
141 myExtPS.SetAlgo(A);
7fd59977 142 Initialize(S, S.FirstUParameter(), S.LastUParameter(),
143 S.FirstVParameter(), S.LastVParameter(),
144 TolU, TolV);
145 Perform(P);
146}
147
148//=======================================================================
149//function : Extrema_ExtPS
150//purpose :
151//=======================================================================
152
153Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
154 const Adaptor3d_Surface& S,
155 const Standard_Real Uinf,
156 const Standard_Real Usup,
157 const Standard_Real Vinf,
158 const Standard_Real Vsup,
159 const Standard_Real TolU,
92d1589b
A
160 const Standard_Real TolV,
161 const Extrema_ExtFlag F,
162 const Extrema_ExtAlgo A)
7fd59977 163
164{
92d1589b
A
165 myExtPS.SetFlag(F);
166 myExtPS.SetAlgo(A);
7fd59977 167 Initialize(S, Uinf, Usup, Vinf, Vsup, TolU, TolV);
168 Perform(P);
169}
170
171
172//=======================================================================
173//function : Initialize
174//purpose :
175//=======================================================================
176
177void Extrema_ExtPS::Initialize(const Adaptor3d_Surface& S,
178 const Standard_Real Uinf,
179 const Standard_Real Usup,
180 const Standard_Real Vinf,
181 const Standard_Real Vsup,
182 const Standard_Real TolU,
183 const Standard_Real TolV)
184{
185 myS = (Adaptor3d_SurfacePtr)&S;
186 myuinf = Uinf;
187 myusup = Usup;
188 myvinf = Vinf;
189 myvsup = Vsup;
190
191 if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
192 if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
193 if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
194 if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
195
196 mytolu = TolU;
197 mytolv = TolV;
198 mytype = myS->GetType();
199
200 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
201 myS->GetType() == GeomAbs_BezierSurface );
202
203 Standard_Integer nbU = (isB) ? 44 : 32;
204 Standard_Integer nbV = (isB) ? 44 : 32;
205
206 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
207
208 if(myS->GetType() != GeomAbs_Plane) {
209 bUIsoIsDeg = IsoIsDeg(S, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
210 IsoIsDeg(S, myusup, GeomAbs_IsoU, 0., 1.e-9);
211 bVIsoIsDeg = IsoIsDeg(S, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
212 IsoIsDeg(S, myvsup, GeomAbs_IsoV, 0., 1.e-9);
213 }
214
215 if(bUIsoIsDeg) nbU = 300;
216 if(bVIsoIsDeg) nbV = 300;
217
218 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
219}
220
221//=======================================================================
222//function : Perform
223//purpose :
224//=======================================================================
225
226void Extrema_ExtPS::Perform(const gp_Pnt& P)
227{
228 myPoints.Clear();
229 mySqDist.Clear();
230 Standard_Integer i;
231 P11 = myS->Value(myuinf, myvinf);
232 P12 = myS->Value(myuinf, myvsup);
233 P21 = myS->Value(myusup, myvinf);
234 P22 = myS->Value(myusup, myvsup);
235 d11 = P.SquareDistance(P11);
236 d12 = P.SquareDistance(P12);
237 d21 = P.SquareDistance(P21);
238 d22 = P.SquareDistance(P22);
239
240 switch(mytype) {
241
242 case GeomAbs_Cylinder:
243 myExtPElS.Perform(P, myS->Cylinder(), Precision::Confusion());
244 break;
245 case GeomAbs_Plane:
246 myExtPElS.Perform(P, myS->Plane(), Precision::Confusion());
247 break;
248 case GeomAbs_Cone:
249 myExtPElS.Perform(P, myS->Cone(), Precision::Confusion());
250 break;
251 case GeomAbs_Sphere:
252 myExtPElS.Perform(P, myS->Sphere(), Precision::Confusion());
253 break;
254 case GeomAbs_Torus:
255 myExtPElS.Perform(P, myS->Torus(), Precision::Confusion());
256 break;
257
258
259 case GeomAbs_SurfaceOfExtrusion: {
260 Extrema_ExtPExtS anExtPExtS(P,
261 Adaptor3d_SurfaceOfLinearExtrusion(myS->BasisCurve(),
262 myS->Direction()),
263 myuinf,myusup, myvinf,myvsup, mytolu,mytolv);
264 myDone = anExtPExtS.IsDone();
265 if (myDone)
266 for (i = 1; i <= anExtPExtS.NbExt(); i++) {
267 TreatSolution (anExtPExtS.Point(i), anExtPExtS.SquareDistance(i));
268 }
269 return;
270 }
271
272
273 case GeomAbs_SurfaceOfRevolution: {
274 Extrema_ExtPRevS anExtPRevS(P,
275 Adaptor3d_SurfaceOfRevolution(myS->BasisCurve(),
276 myS->AxeOfRevolution()),
277 myuinf, myusup,myvinf, myvsup,mytolu, mytolv);
278 myDone = anExtPRevS.IsDone();
279 if (myDone)
280 for (i = 1; i <= anExtPRevS.NbExt(); i++) {
281 TreatSolution (anExtPRevS.Point(i), anExtPRevS.SquareDistance(i));
282 }
283 return;
284 }
285
286
287 default:
288 myExtPS.Perform(P);
289 myDone = myExtPS.IsDone();
290 if (myDone)
291 for (i = 1; i <= myExtPS.NbExt(); i++)
292 TreatSolution (myExtPS.Point(i), myExtPS.SquareDistance(i));
293 return;
294 }
295
296
297 myDone = myExtPElS.IsDone();
298 if (myDone)
299 for (i = 1; i <= myExtPElS.NbExt(); i++)
300 TreatSolution (myExtPElS.Point(i), myExtPElS.SquareDistance(i));
301 return;
302}
303
304
305
306Standard_Boolean Extrema_ExtPS::IsDone() const
307{
308 return myDone;
309}
310
311
312Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
313{
314 if(!myDone) StdFail_NotDone::Raise();
315 if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
316 return mySqDist.Value(N);
317}
318
319
320Standard_Integer Extrema_ExtPS::NbExt() const
321{
322 if(!myDone) StdFail_NotDone::Raise();
323 return mySqDist.Length();
324}
325
326
327
328Extrema_POnSurf Extrema_ExtPS::Point(const Standard_Integer N) const
329{
330 if(!myDone) StdFail_NotDone::Raise();
331 return myPoints.Value(N);
332}
333
334
335void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
336 Standard_Real& dUfVl,
337 Standard_Real& dUlVf,
338 Standard_Real& dUlVl,
339 gp_Pnt& PUfVf,
340 gp_Pnt& PUfVl,
341 gp_Pnt& PUlVf,
342 gp_Pnt& PUlVl) const
343{
344 dUfVf = d11;
345 dUfVl = d12;
346 dUlVf = d21;
347 dUlVl = d22;
348 PUfVf = P11;
349 PUfVl = P12;
350 PUlVf = P21;
351 PUlVl = P22;
352}
92d1589b
A
353
354void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
355{
356 myExtPS.SetFlag(F);
357}
358
359void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)
360{
361 myExtPS.SetAlgo(A);
362}