Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
3 | // | |
4 | // The content of this file is subject to the Open CASCADE Technology Public | |
5 | // License Version 6.5 (the "License"). You may not use the content of this file | |
6 | // except in compliance with the License. Please obtain a copy of the License | |
7 | // at http://www.opencascade.org and read it completely before using this file. | |
8 | // | |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
11 | // | |
12 | // The Original Code and all software distributed under the License is | |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
14 | // Initial Developer hereby disclaims all such warranties, including without | |
15 | // limitation, any warranties of merchantability, fitness for a particular | |
16 | // purpose or non-infringement. Please see the License for the specific terms | |
17 | // and conditions governing the rights and limitations under the License. | |
18 | ||
7fd59977 | 19 | //----------------------------------------------------------------- |
7fd59977 | 20 | |
21 | #include <Extrema_ExtPS.ixx> | |
22 | #include <Extrema_GenExtPS.hxx> | |
23 | #include <StdFail_NotDone.hxx> | |
24 | #include <Standard_NotImplemented.hxx> | |
25 | #include <Precision.hxx> | |
26 | #include <GeomAbs_CurveType.hxx> | |
27 | #include <Adaptor3d_SurfaceOfLinearExtrusion.hxx> | |
28 | #include <Adaptor3d_SurfaceOfRevolution.hxx> | |
29 | #include <ElCLib.hxx> | |
30 | #include <gp_Pnt.hxx> | |
31 | #include <gp_Pln.hxx> | |
32 | #include <gp_Cylinder.hxx> | |
33 | #include <gp_Cone.hxx> | |
34 | #include <gp_Sphere.hxx> | |
35 | #include <gp_Torus.hxx> | |
36 | #include <Extrema_ExtPExtS.hxx> | |
37 | #include <Extrema_ExtPRevS.hxx> | |
38 | #include <Extrema_POnSurf.hxx> | |
39 | #include <GeomAbs_IsoType.hxx> | |
40 | ||
41 | //======================================================================= | |
42 | //function : IsoIsDeg | |
43 | //purpose : | |
44 | //======================================================================= | |
45 | ||
46 | static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S, | |
47 | const Standard_Real Param, | |
48 | const GeomAbs_IsoType IT, | |
49 | const Standard_Real TolMin, | |
50 | const Standard_Real TolMax) | |
51 | { | |
52 | Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T; | |
53 | Standard_Boolean Along = Standard_True; | |
54 | U1 = S.FirstUParameter(); | |
55 | U2 = S.LastUParameter(); | |
56 | V1 = S.FirstVParameter(); | |
57 | V2 = S.LastVParameter(); | |
58 | gp_Vec D1U,D1V; | |
59 | gp_Pnt P; | |
60 | Standard_Real Step,D1NormMax; | |
61 | if (IT == GeomAbs_IsoV) | |
62 | { | |
5368adff | 63 | if( !Precision::IsInfinite(U1) && !Precision::IsInfinite(U2) ) |
7fd59977 | 64 | { |
5368adff | 65 | Step = (U2 - U1)/10; |
66 | if(Step < Precision::PConfusion()) { | |
67 | return Standard_False; | |
68 | } | |
69 | D1NormMax=0.; | |
70 | ||
71 | for (T=U1;T<=U2;T=T+Step) | |
72 | { | |
73 | S.D1(T,Param,P,D1U,D1V); | |
74 | D1NormMax=Max(D1NormMax,D1U.Magnitude()); | |
75 | } | |
76 | ||
77 | if (D1NormMax >TolMax || D1NormMax < TolMin ) | |
78 | Along = Standard_False; | |
7fd59977 | 79 | } |
7fd59977 | 80 | } |
81 | else | |
82 | { | |
5368adff | 83 | if( !Precision::IsInfinite(V1) && !Precision::IsInfinite(V2) ) |
7fd59977 | 84 | { |
5368adff | 85 | Step = (V2 - V1)/10; |
86 | if(Step < Precision::PConfusion()) { | |
87 | return Standard_False; | |
88 | } | |
89 | D1NormMax=0.; | |
90 | for (T=V1;T<=V2;T=T+Step) | |
91 | { | |
92 | S.D1(Param,T,P,D1U,D1V); | |
93 | D1NormMax=Max(D1NormMax,D1V.Magnitude()); | |
94 | } | |
95 | ||
96 | if (D1NormMax >TolMax || D1NormMax < TolMin ) | |
97 | Along = Standard_False; | |
7fd59977 | 98 | } |
99 | ||
7fd59977 | 100 | |
101 | ||
102 | } | |
103 | return Along; | |
104 | } | |
105 | ||
106 | //======================================================================= | |
107 | //function : TreatSolution | |
108 | //purpose : | |
109 | //======================================================================= | |
110 | ||
111 | void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS, | |
112 | const Standard_Real Val) | |
113 | { | |
114 | Standard_Real U, V; | |
115 | PS.Parameter(U, V); | |
116 | if (myS->IsUPeriodic()) { | |
117 | U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod()); | |
118 | } | |
119 | if (myS->IsVPeriodic()) { | |
120 | V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod()); | |
121 | } | |
122 | if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu && | |
123 | (myvinf-V) <= mytolv && (V-myvsup) <= mytolv) { | |
124 | myPoints.Append(Extrema_POnSurf (U, V, PS.Value())); | |
125 | mySqDist.Append(Val); | |
126 | } | |
127 | } | |
128 | ||
129 | ||
130 | //======================================================================= | |
131 | //function : Extrema_ExtPS | |
132 | //purpose : | |
133 | //======================================================================= | |
134 | ||
135 | Extrema_ExtPS::Extrema_ExtPS() | |
136 | { | |
137 | myDone = Standard_False; | |
138 | } | |
139 | ||
140 | ||
141 | //======================================================================= | |
142 | //function : Extrema_ExtPS | |
143 | //purpose : | |
144 | //======================================================================= | |
145 | ||
146 | Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P, | |
147 | const Adaptor3d_Surface& S, | |
148 | const Standard_Real TolU, | |
92d1589b A |
149 | const Standard_Real TolV, |
150 | const Extrema_ExtFlag F, | |
151 | const Extrema_ExtAlgo A) | |
7fd59977 | 152 | |
153 | { | |
92d1589b A |
154 | myExtPS.SetFlag(F); |
155 | myExtPS.SetAlgo(A); | |
7fd59977 | 156 | Initialize(S, S.FirstUParameter(), S.LastUParameter(), |
157 | S.FirstVParameter(), S.LastVParameter(), | |
158 | TolU, TolV); | |
159 | Perform(P); | |
160 | } | |
161 | ||
162 | //======================================================================= | |
163 | //function : Extrema_ExtPS | |
164 | //purpose : | |
165 | //======================================================================= | |
166 | ||
167 | Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P, | |
168 | const Adaptor3d_Surface& S, | |
169 | const Standard_Real Uinf, | |
170 | const Standard_Real Usup, | |
171 | const Standard_Real Vinf, | |
172 | const Standard_Real Vsup, | |
173 | const Standard_Real TolU, | |
92d1589b A |
174 | const Standard_Real TolV, |
175 | const Extrema_ExtFlag F, | |
176 | const Extrema_ExtAlgo A) | |
7fd59977 | 177 | |
178 | { | |
92d1589b A |
179 | myExtPS.SetFlag(F); |
180 | myExtPS.SetAlgo(A); | |
7fd59977 | 181 | Initialize(S, Uinf, Usup, Vinf, Vsup, TolU, TolV); |
182 | Perform(P); | |
183 | } | |
184 | ||
185 | ||
186 | //======================================================================= | |
187 | //function : Initialize | |
188 | //purpose : | |
189 | //======================================================================= | |
190 | ||
191 | void Extrema_ExtPS::Initialize(const Adaptor3d_Surface& S, | |
192 | const Standard_Real Uinf, | |
193 | const Standard_Real Usup, | |
194 | const Standard_Real Vinf, | |
195 | const Standard_Real Vsup, | |
196 | const Standard_Real TolU, | |
197 | const Standard_Real TolV) | |
198 | { | |
199 | myS = (Adaptor3d_SurfacePtr)&S; | |
200 | myuinf = Uinf; | |
201 | myusup = Usup; | |
202 | myvinf = Vinf; | |
203 | myvsup = Vsup; | |
204 | ||
205 | if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10; | |
206 | if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10; | |
207 | if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10; | |
208 | if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10; | |
209 | ||
210 | mytolu = TolU; | |
211 | mytolv = TolV; | |
212 | mytype = myS->GetType(); | |
213 | ||
214 | Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface || | |
215 | myS->GetType() == GeomAbs_BezierSurface ); | |
216 | ||
217 | Standard_Integer nbU = (isB) ? 44 : 32; | |
218 | Standard_Integer nbV = (isB) ? 44 : 32; | |
219 | ||
220 | Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False; | |
221 | ||
222 | if(myS->GetType() != GeomAbs_Plane) { | |
223 | bUIsoIsDeg = IsoIsDeg(S, myuinf, GeomAbs_IsoU, 0., 1.e-9) || | |
224 | IsoIsDeg(S, myusup, GeomAbs_IsoU, 0., 1.e-9); | |
225 | bVIsoIsDeg = IsoIsDeg(S, myvinf, GeomAbs_IsoV, 0., 1.e-9) || | |
226 | IsoIsDeg(S, myvsup, GeomAbs_IsoV, 0., 1.e-9); | |
227 | } | |
228 | ||
229 | if(bUIsoIsDeg) nbU = 300; | |
230 | if(bVIsoIsDeg) nbV = 300; | |
231 | ||
232 | myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv); | |
233 | } | |
234 | ||
235 | //======================================================================= | |
236 | //function : Perform | |
237 | //purpose : | |
238 | //======================================================================= | |
239 | ||
240 | void Extrema_ExtPS::Perform(const gp_Pnt& P) | |
241 | { | |
242 | myPoints.Clear(); | |
243 | mySqDist.Clear(); | |
244 | Standard_Integer i; | |
5368adff | 245 | |
7fd59977 | 246 | |
247 | switch(mytype) { | |
248 | ||
249 | case GeomAbs_Cylinder: | |
250 | myExtPElS.Perform(P, myS->Cylinder(), Precision::Confusion()); | |
251 | break; | |
252 | case GeomAbs_Plane: | |
253 | myExtPElS.Perform(P, myS->Plane(), Precision::Confusion()); | |
254 | break; | |
255 | case GeomAbs_Cone: | |
256 | myExtPElS.Perform(P, myS->Cone(), Precision::Confusion()); | |
257 | break; | |
258 | case GeomAbs_Sphere: | |
259 | myExtPElS.Perform(P, myS->Sphere(), Precision::Confusion()); | |
260 | break; | |
261 | case GeomAbs_Torus: | |
262 | myExtPElS.Perform(P, myS->Torus(), Precision::Confusion()); | |
263 | break; | |
264 | ||
265 | ||
266 | case GeomAbs_SurfaceOfExtrusion: { | |
267 | Extrema_ExtPExtS anExtPExtS(P, | |
268 | Adaptor3d_SurfaceOfLinearExtrusion(myS->BasisCurve(), | |
269 | myS->Direction()), | |
270 | myuinf,myusup, myvinf,myvsup, mytolu,mytolv); | |
271 | myDone = anExtPExtS.IsDone(); | |
272 | if (myDone) | |
273 | for (i = 1; i <= anExtPExtS.NbExt(); i++) { | |
274 | TreatSolution (anExtPExtS.Point(i), anExtPExtS.SquareDistance(i)); | |
275 | } | |
276 | return; | |
277 | } | |
278 | ||
279 | ||
280 | case GeomAbs_SurfaceOfRevolution: { | |
281 | Extrema_ExtPRevS anExtPRevS(P, | |
282 | Adaptor3d_SurfaceOfRevolution(myS->BasisCurve(), | |
283 | myS->AxeOfRevolution()), | |
284 | myuinf, myusup,myvinf, myvsup,mytolu, mytolv); | |
285 | myDone = anExtPRevS.IsDone(); | |
286 | if (myDone) | |
287 | for (i = 1; i <= anExtPRevS.NbExt(); i++) { | |
288 | TreatSolution (anExtPRevS.Point(i), anExtPRevS.SquareDistance(i)); | |
289 | } | |
290 | return; | |
291 | } | |
292 | ||
293 | ||
294 | default: | |
295 | myExtPS.Perform(P); | |
296 | myDone = myExtPS.IsDone(); | |
297 | if (myDone) | |
298 | for (i = 1; i <= myExtPS.NbExt(); i++) | |
299 | TreatSolution (myExtPS.Point(i), myExtPS.SquareDistance(i)); | |
300 | return; | |
301 | } | |
302 | ||
303 | ||
304 | myDone = myExtPElS.IsDone(); | |
305 | if (myDone) | |
306 | for (i = 1; i <= myExtPElS.NbExt(); i++) | |
307 | TreatSolution (myExtPElS.Point(i), myExtPElS.SquareDistance(i)); | |
308 | return; | |
309 | } | |
310 | ||
311 | ||
312 | ||
313 | Standard_Boolean Extrema_ExtPS::IsDone() const | |
314 | { | |
315 | return myDone; | |
316 | } | |
317 | ||
318 | ||
319 | Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const | |
320 | { | |
321 | if(!myDone) StdFail_NotDone::Raise(); | |
322 | if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise(); | |
323 | return mySqDist.Value(N); | |
324 | } | |
325 | ||
326 | ||
327 | Standard_Integer Extrema_ExtPS::NbExt() const | |
328 | { | |
329 | if(!myDone) StdFail_NotDone::Raise(); | |
330 | return mySqDist.Length(); | |
331 | } | |
332 | ||
333 | ||
334 | ||
335 | Extrema_POnSurf Extrema_ExtPS::Point(const Standard_Integer N) const | |
336 | { | |
337 | if(!myDone) StdFail_NotDone::Raise(); | |
338 | return myPoints.Value(N); | |
339 | } | |
340 | ||
341 | ||
342 | void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf, | |
343 | Standard_Real& dUfVl, | |
344 | Standard_Real& dUlVf, | |
345 | Standard_Real& dUlVl, | |
346 | gp_Pnt& PUfVf, | |
347 | gp_Pnt& PUfVl, | |
348 | gp_Pnt& PUlVf, | |
349 | gp_Pnt& PUlVl) const | |
350 | { | |
351 | dUfVf = d11; | |
352 | dUfVl = d12; | |
353 | dUlVf = d21; | |
354 | dUlVl = d22; | |
355 | PUfVf = P11; | |
356 | PUfVl = P12; | |
357 | PUlVf = P21; | |
358 | PUlVl = P22; | |
359 | } | |
92d1589b A |
360 | |
361 | void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F) | |
362 | { | |
363 | myExtPS.SetFlag(F); | |
364 | } | |
365 | ||
366 | void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A) | |
367 | { | |
368 | myExtPS.SetAlgo(A); | |
0d969553 | 369 | } |