7fd59977 |
1 | // File: Extrema_FuncExtPS.cxx |
2 | // Created: Tue Jul 18 08:11:24 1995 |
3 | // Author: Modelistation |
4 | // <model@metrox> |
5 | |
6 | // Modified by skv - Thu Sep 30 15:21:07 2004 OCC593 |
7 | |
8 | |
9 | #include <Extrema_FuncExtPS.ixx> |
10 | #include <gp_Vec.hxx> |
11 | #include <gp_Pnt.hxx> |
12 | #include <Standard_TypeMismatch.hxx> |
13 | #include <Precision.hxx> |
14 | #include <GeomAbs_IsoType.hxx> |
15 | |
16 | /*----------------------------------------------------------------------------- |
17 | Fonctions permettant de rechercher une distance extremale entre un point P |
18 | et une surface S (en partant d'un point approche S(u0,v0)). |
19 | Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par |
20 | l'algorithme math_FunctionSetRoot. |
21 | Si on note Dus et Dvs, les derivees en u et v, les 2 fonctions a annuler sont: |
22 | { F1(u,v) = (S(u,v)-P).Dus(u,v) } |
23 | { F2(u,v) = (S(u,v)-P).Dvs(u,v) } |
24 | Si on note Duus, Dvvs et Duvs, les derivees secondes de S, les derivees de F1 |
25 | et F2 sont egales a: |
26 | { Duf1(u,v) = Dus(u,v).Dus(u,v) + (S(u,v)-P).Duus(u,v) |
27 | = ||Dus(u,v)|| ** 2 + (S(u,v)-P).Duus(u,v) |
28 | { Dvf1(u,v) = Dvs(u,v).Dus(u,v) + (S(u,v)-P).Duvs(u,v) |
29 | { Duf2(u,v) = Dus(u,v).Dvs(u,v) + (S(u,v)-P).Duvs(u,v) = dF1v(u,v) |
30 | { Dvf2(u,v) = Dvs(u,v).Dvs(u,v) + (S(u,v)-P).Dvvs(u,v) |
31 | = ||Dvs(u,v)|| ** 2 + (S(u,v)-P).Dvvs(u,v) |
32 | |
33 | ----------------------------------------------------------------------------*/ |
34 | // modified by NIZHNY-EAP Wed Nov 21 17:33:05 2001 |
35 | // -- Dus and Dvs normalized, Df modified accordingly (BUC61043) |
36 | //============================================================================= |
37 | //------------------------------------------------------------------------------ |
38 | // This method checks if isocurve is punctual (for details see Geom_OffsetSurface |
39 | // and Geom_OsculatingSurface |
40 | //------------------------------------------------------------------------------- |
41 | |
42 | static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S, |
43 | const Standard_Real Param, |
44 | const GeomAbs_IsoType IT, |
45 | const Standard_Real TolMin, |
46 | const Standard_Real TolMax) |
47 | { |
48 | Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T; |
49 | Standard_Boolean Along = Standard_True; |
50 | U1 = S.FirstUParameter(); |
51 | U2 = S.LastUParameter(); |
52 | V1 = S.FirstVParameter(); |
53 | V2 = S.LastVParameter(); |
54 | gp_Vec D1U,D1V; |
55 | gp_Pnt P; |
56 | Standard_Real Step,D1NormMax; |
57 | if (IT == GeomAbs_IsoV) |
58 | { |
59 | Step = (U2 - U1)/10; |
60 | D1NormMax=0.; |
61 | for (T=U1;T<=U2;T=T+Step) |
62 | { |
63 | S.D1(T,Param,P,D1U,D1V); |
64 | D1NormMax=Max(D1NormMax,D1U.Magnitude()); |
65 | } |
66 | |
67 | if (D1NormMax >TolMax || D1NormMax < TolMin ) |
68 | Along = Standard_False; |
69 | } |
70 | else |
71 | { |
72 | Step = (V2 - V1)/10; |
73 | D1NormMax=0.; |
74 | for (T=V1;T<=V2;T=T+Step) |
75 | { |
76 | S.D1(Param,T,P,D1U,D1V); |
77 | D1NormMax=Max(D1NormMax,D1V.Magnitude()); |
78 | } |
79 | |
80 | if (D1NormMax >TolMax || D1NormMax < TolMin ) |
81 | Along = Standard_False; |
82 | |
83 | |
84 | } |
85 | return Along; |
86 | } |
87 | |
88 | |
89 | Extrema_FuncExtPS::Extrema_FuncExtPS () |
90 | { |
91 | myPinit = Standard_False; |
92 | mySinit = Standard_False; |
93 | myUIsoIsDeg = Standard_False; |
94 | myVIsoIsDeg = Standard_False; |
95 | } |
96 | //============================================================================= |
97 | Extrema_FuncExtPS::Extrema_FuncExtPS (const gp_Pnt& P, |
98 | const Adaptor3d_Surface& S) |
99 | { |
100 | myP = P; |
101 | myS = (Adaptor3d_SurfacePtr)&S; |
102 | myUIsoIsDeg = Standard_False; |
103 | myVIsoIsDeg = Standard_False; |
104 | GeomAbs_SurfaceType aSType = S.GetType(); |
105 | if(aSType == GeomAbs_BezierSurface || |
106 | aSType == GeomAbs_BSplineSurface) { |
107 | Standard_Real u1, u2, v1, v2; |
108 | Standard_Real tol = Precision::Confusion(); |
109 | u1 = S.FirstUParameter(); |
110 | u2 = S.LastUParameter(); |
111 | v1 = S.FirstVParameter(); |
112 | v2 = S.LastVParameter(); |
113 | myUIsoIsDeg = IsoIsDeg(S, u1, GeomAbs_IsoU, 0., tol) || |
114 | IsoIsDeg(S, u2, GeomAbs_IsoU, 0., tol); |
115 | myVIsoIsDeg = IsoIsDeg(S, v1, GeomAbs_IsoV, 0., tol) || |
116 | IsoIsDeg(S, v2, GeomAbs_IsoV, 0., tol); |
117 | } |
118 | myPinit = Standard_True; |
119 | mySinit = Standard_True; |
120 | } |
121 | |
122 | //============================================================================= |
123 | void Extrema_FuncExtPS::Initialize(const Adaptor3d_Surface& S) |
124 | { |
125 | myS = (Adaptor3d_SurfacePtr)&S; |
126 | myUIsoIsDeg = Standard_False; |
127 | myVIsoIsDeg = Standard_False; |
128 | GeomAbs_SurfaceType aSType = S.GetType(); |
129 | if(aSType == GeomAbs_BezierSurface || |
130 | aSType == GeomAbs_BSplineSurface) { |
131 | Standard_Real u1, u2, v1, v2; |
132 | Standard_Real tol = Precision::Confusion(); |
133 | u1 = S.FirstUParameter(); |
134 | u2 = S.LastUParameter(); |
135 | v1 = S.FirstVParameter(); |
136 | v2 = S.LastVParameter(); |
137 | myUIsoIsDeg = IsoIsDeg(S, u1, GeomAbs_IsoU, 0., tol) || |
138 | IsoIsDeg(S, u2, GeomAbs_IsoU, 0., tol); |
139 | myVIsoIsDeg = IsoIsDeg(S, v1, GeomAbs_IsoV, 0., tol) || |
140 | IsoIsDeg(S, v2, GeomAbs_IsoV, 0., tol); |
141 | } |
142 | mySinit = Standard_True; |
143 | myPoint.Clear(); |
144 | mySqDist.Clear(); |
145 | } |
146 | |
147 | //============================================================================= |
148 | |
149 | void Extrema_FuncExtPS::SetPoint(const gp_Pnt& P) |
150 | { |
151 | myP = P; |
152 | myPinit = Standard_True; |
153 | myPoint.Clear(); |
154 | mySqDist.Clear(); |
155 | } |
156 | |
157 | //============================================================================= |
158 | |
159 | //============================================================================= |
160 | |
161 | Standard_Integer Extrema_FuncExtPS::NbVariables () const { return 2;} |
162 | //============================================================================= |
163 | |
164 | Standard_Integer Extrema_FuncExtPS::NbEquations () const { return 2;} |
165 | //============================================================================= |
166 | |
167 | Standard_Boolean Extrema_FuncExtPS::Value (const math_Vector& UV, |
168 | math_Vector& F) |
169 | { |
170 | if (!myPinit || !mySinit) Standard_TypeMismatch::Raise(); |
171 | myU = UV(1); |
172 | myV = UV(2); |
173 | gp_Vec Dus, Dvs; |
174 | myS->D1(myU,myV,myPs,Dus,Dvs); |
175 | |
176 | gp_Vec PPs (myP,myPs); |
177 | // EAP |
178 | if(myVIsoIsDeg) |
179 | { |
180 | Standard_Real DusMod = Dus.Magnitude(); |
181 | if (DusMod>gp::Resolution() && DusMod<1.) |
182 | Dus.Multiply(1/DusMod); |
183 | } |
184 | if (myUIsoIsDeg) { |
185 | Standard_Real DvsMod = Dvs.Magnitude(); |
186 | if (DvsMod>gp::Resolution() && DvsMod<1.) |
187 | Dvs.Multiply(1/DvsMod); |
188 | } |
189 | |
190 | F(1) = PPs.Dot(Dus); |
191 | F(2) = PPs.Dot(Dvs); |
192 | |
193 | return Standard_True; |
194 | } |
195 | //============================================================================= |
196 | |
197 | Standard_Boolean Extrema_FuncExtPS::Derivatives (const math_Vector& UV, |
198 | math_Matrix& Df) |
199 | { |
200 | math_Vector F(1,2); |
201 | return Values(UV,F,Df); |
202 | } |
203 | //============================================================================= |
204 | |
205 | Standard_Boolean Extrema_FuncExtPS::Values (const math_Vector& UV, |
206 | math_Vector& F, |
207 | math_Matrix& Df) |
208 | { |
209 | if (!myPinit || !mySinit) Standard_TypeMismatch::Raise(); |
210 | myU = UV(1); |
211 | myV = UV(2); |
212 | gp_Vec Dus, Dvs, Duus, Dvvs, Duvs; |
213 | myS->D2(myU,myV,myPs,Dus,Dvs,Duus,Dvvs,Duvs); |
214 | |
215 | gp_Vec PPs (myP,myPs); |
216 | // EAP |
217 | // Df(1,1) = Dus.SquareMagnitude() + PPs.Dot(Duus); |
218 | // Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs); |
219 | // Df(2,1) = Df(1,2); |
220 | // Df(2,2) = Dvs.SquareMagnitude() + PPs.Dot(Dvvs); |
221 | |
222 | // 25/03/02 akm : (OCC231) Further normalization of derivatives for surfaces |
223 | // with singularities will hence be performed only when modulus |
224 | // becomes less than 1.0. Thus the continuity will be kept, |
225 | // and normalization will be switched off 'far' from singularities. |
226 | // 1. V iso |
227 | Standard_Real DusMod2 = Dus.SquareMagnitude(); |
228 | if (myVIsoIsDeg) |
229 | { |
230 | Standard_Real DusMod = Sqrt(DusMod2); |
231 | if (DusMod2>gp::Resolution() && DusMod2<1.) |
232 | { |
233 | Dus.Multiply(1/DusMod); |
234 | Df(1,1) = DusMod2 + PPs.Dot( (Duus*DusMod - Dus*(Dus.Dot(Duus)/DusMod)) / DusMod2 ); |
235 | Df(1,2) = Dvs.Dot(Dus) + PPs.Dot( (Duvs*DusMod-Dus*(Dus.Dot(Duvs)/DusMod)) / DusMod2 ); |
236 | } |
237 | else { |
238 | Df(1,1) = DusMod2 + PPs.Dot(Duus); |
239 | Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs); |
240 | } |
241 | } |
242 | else { |
243 | Df(1,1) = DusMod2 + PPs.Dot(Duus); |
244 | Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs); |
245 | } |
246 | // 2. U iso |
247 | Standard_Real DvsMod2 = Dvs.SquareMagnitude(); |
248 | if (myUIsoIsDeg) |
249 | { |
250 | Standard_Real DvsMod = Sqrt(DvsMod2); |
251 | if (DvsMod2>gp::Resolution() && DvsMod2<1.) |
252 | { |
253 | Dvs.Multiply(1/DvsMod); |
254 | Df(2,1) = Dvs.Dot(Dus) + PPs.Dot( (Duvs*DvsMod-Dvs*(Dvs.Dot(Duvs)/DvsMod)) / DvsMod2 ); |
255 | Df(2,2) = DvsMod2 + PPs.Dot( (Duus*DvsMod - Dus*(Dus.Dot(Duus)/DvsMod)) / DvsMod2 ); |
256 | } |
257 | else { |
258 | Df(2,1) = Dvs.Dot(Dus) + PPs.Dot(Duvs); |
259 | Df(2,2) = DvsMod2 + PPs.Dot(Dvvs); |
260 | } |
261 | } |
262 | else { |
263 | Df(2,1) = Dvs.Dot(Dus) + PPs.Dot(Duvs); |
264 | Df(2,2) = DvsMod2 + PPs.Dot(Dvvs); |
265 | } |
266 | |
267 | F(1) = PPs.Dot(Dus); |
268 | F(2) = PPs.Dot(Dvs); |
269 | |
270 | return Standard_True; |
271 | } |
272 | //============================================================================= |
273 | |
274 | Standard_Integer Extrema_FuncExtPS::GetStateNumber () |
275 | { |
276 | if (!myPinit || !mySinit) Standard_TypeMismatch::Raise(); |
277 | mySqDist.Append(myPs.SquareDistance(myP)); |
278 | myPoint.Append(Extrema_POnSurf(myU,myV,myPs)); |
279 | return 0; |
280 | } |
281 | //============================================================================= |
282 | |
283 | Standard_Integer Extrema_FuncExtPS::NbExt () const |
284 | { |
285 | return mySqDist.Length(); |
286 | } |
287 | //============================================================================= |
288 | |
289 | Standard_Real Extrema_FuncExtPS::SquareDistance (const Standard_Integer N) const |
290 | { |
291 | if (!myPinit || !mySinit) Standard_TypeMismatch::Raise(); |
292 | return mySqDist.Value(N); |
293 | } |
294 | //============================================================================= |
295 | |
296 | Extrema_POnSurf Extrema_FuncExtPS::Point (const Standard_Integer N) const |
297 | { |
298 | if (!myPinit || !mySinit) Standard_TypeMismatch::Raise(); |
299 | return myPoint.Value(N); |
300 | } |
301 | //============================================================================= |
302 | |
303 | // Modified by skv - Thu Sep 30 15:21:07 2004 OCC593 Begin |
304 | Standard_Boolean Extrema_FuncExtPS::HasDegIso() const |
305 | { |
306 | return myUIsoIsDeg || myVIsoIsDeg; |
307 | } |
308 | // Modified by skv - Thu Sep 30 15:21:07 2004 OCC593 End |