Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1991-06-25 |
2 | // Created by: JCV | |
3 | // Copyright (c) 1991-1999 Matra Datavision | |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
5 | // | |
6 | // The content of this file is subject to the Open CASCADE Technology Public | |
7 | // License Version 6.5 (the "License"). You may not use the content of this file | |
8 | // except in compliance with the License. Please obtain a copy of the License | |
9 | // at http://www.opencascade.org and read it completely before using this file. | |
10 | // | |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
13 | // | |
14 | // The Original Code and all software distributed under the License is | |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
16 | // Initial Developer hereby disclaims all such warranties, including without | |
17 | // limitation, any warranties of merchantability, fitness for a particular | |
18 | // purpose or non-infringement. Please see the License for the specific terms | |
19 | // and conditions governing the rights and limitations under the License. | |
20 | ||
7fd59977 | 21 | |
7fd59977 | 22 | // Modified 04/10/96 : JCT : derivee des surfaces offset utilisation de |
23 | // CSLib | |
24 | // Modified 15/11/96 : JPI : ajout equivalent surface pour les surfaces canoniques et modif des methodes D0 D1, ... UIso,VIso | |
25 | // Modified 18/11/96 : JPI : inversion de l'offsetValue dans UReverse et Vreverse | |
b311480e | 26 | |
7fd59977 | 27 | #include <Geom_OffsetSurface.ixx> |
28 | #include <gp.hxx> | |
29 | #include <gp_Vec.hxx> | |
30 | #include <gp_Dir.hxx> | |
31 | #include <gp_XYZ.hxx> | |
32 | #include <BSplSLib.hxx> | |
33 | #include <BSplCLib.hxx> | |
34 | #include <CSLib.hxx> | |
35 | #include <Precision.hxx> | |
36 | #include <Standard_ConstructionError.hxx> | |
37 | #include <Standard_NotImplemented.hxx> | |
38 | #include <Standard_RangeError.hxx> | |
39 | #include <Geom_UndefinedValue.hxx> | |
40 | #include <Geom_UndefinedDerivative.hxx> | |
41 | ||
42 | #include <Geom_OffsetCurve.hxx> | |
43 | #include <Geom_BSplineCurve.hxx> | |
44 | #include <Geom_Geometry.hxx> | |
45 | #include <Geom_Surface.hxx> | |
46 | #include <Geom_Plane.hxx> | |
47 | #include <Geom_ElementarySurface.hxx> | |
48 | #include <Geom_CylindricalSurface.hxx> | |
49 | #include <Geom_ConicalSurface.hxx> | |
50 | #include <Geom_SphericalSurface.hxx> | |
51 | #include <Geom_ToroidalSurface.hxx> | |
52 | #include <Geom_BezierSurface.hxx> | |
53 | #include <Geom_BSplineSurface.hxx> | |
54 | #include <Geom_SurfaceOfRevolution.hxx> | |
55 | #include <Geom_SurfaceOfLinearExtrusion.hxx> | |
56 | #include <Geom_RectangularTrimmedSurface.hxx> | |
57 | #include <Geom_Curve.hxx> | |
58 | #include <Geom_Circle.hxx> | |
59 | #include <Geom_Ellipse.hxx> | |
60 | ||
61 | #include <TColgp_Array1OfPnt.hxx> | |
62 | #include <TColgp_Array2OfVec.hxx> | |
63 | #include <TColStd_Array1OfReal.hxx> | |
64 | #include <TColStd_Array1OfInteger.hxx> | |
65 | #include <TColStd_HArray1OfReal.hxx> | |
66 | #include <TColStd_HArray1OfInteger.hxx> | |
67 | ||
68 | #include <AdvApprox_ApproxAFunction.hxx> | |
69 | #include <TColgp_HArray2OfPnt.hxx> | |
70 | #include <BSplSLib.hxx> | |
71 | #include <Convert_GridPolynomialToPoles.hxx> | |
72 | #include <TColStd_HArray2OfInteger.hxx> | |
73 | #include <GeomAbs_IsoType.hxx> | |
74 | #include <GeomAbs_Shape.hxx> | |
75 | #include <GeomAbs_CurveType.hxx> | |
76 | ||
77 | typedef Handle(Geom_OffsetCurve) Handle(OffsetCurve); | |
78 | typedef Geom_OffsetCurve OffsetCurve; | |
79 | typedef Handle(Geom_Curve) Handle(Curve); | |
80 | typedef Handle(Geom_Surface) Handle(Surface); | |
81 | typedef Handle(Geom_OffsetSurface) Handle(OffsetSurface); | |
82 | typedef Geom_OffsetSurface OffsetSurface; | |
83 | typedef Handle(Geom_Geometry) Handle(Geometry); | |
84 | typedef gp_Dir Dir; | |
85 | typedef gp_Vec Vec; | |
86 | typedef gp_Pnt Pnt; | |
87 | typedef gp_Trsf Trsf; | |
88 | typedef gp_XYZ XYZ; | |
89 | //======================================================================= | |
90 | //function : derivatives | |
91 | //purpose : | |
92 | //======================================================================= | |
93 | ||
94 | static void derivatives(Standard_Integer MaxOrder, | |
95 | Standard_Integer MinOrder, | |
96 | const Standard_Real U, | |
97 | const Standard_Real V, | |
98 | const Handle(Geom_Surface)& basisSurf, | |
99 | const Standard_Integer Nu, | |
100 | const Standard_Integer Nv, | |
101 | const Standard_Boolean AlongU, | |
102 | const Standard_Boolean AlongV, | |
103 | const Handle(Geom_BSplineSurface)& L, | |
104 | TColgp_Array2OfVec& DerNUV, | |
105 | TColgp_Array2OfVec& DerSurf) | |
106 | { | |
107 | Standard_Integer i,j; | |
108 | gp_Pnt P; | |
109 | gp_Vec DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3UUV, DL3UVV, DL3V; | |
110 | ||
111 | if (AlongU || AlongV) | |
112 | { | |
113 | MaxOrder=0; | |
114 | TColgp_Array2OfVec DerSurfL(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1); | |
115 | switch (MinOrder) | |
116 | { | |
117 | case 1 : | |
118 | L->D1(U, V, P, DL1U, DL1V); | |
119 | DerSurfL.SetValue(1, 0, DL1U); | |
120 | DerSurfL.SetValue(0, 1, DL1V); | |
121 | break; | |
122 | case 2 : | |
123 | L->D2(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV); | |
124 | DerSurfL.SetValue(1, 0, DL1U); | |
125 | DerSurfL.SetValue(0, 1, DL1V); | |
126 | DerSurfL.SetValue(1, 1, DL2UV); | |
127 | DerSurfL.SetValue(2, 0, DL2U); | |
128 | DerSurfL.SetValue(0, 2, DL2V); | |
129 | break; | |
130 | case 3 : | |
131 | L->D3(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3V ,DL3UUV, DL3UVV); | |
132 | DerSurfL.SetValue(1, 0, DL1U); | |
133 | DerSurfL.SetValue(0, 1, DL1V); | |
134 | DerSurfL.SetValue(1, 1, DL2UV); | |
135 | DerSurfL.SetValue(2, 0, DL2U); | |
136 | DerSurfL.SetValue(0, 2, DL2V); | |
137 | DerSurfL.SetValue(3, 0, DL3U); | |
138 | DerSurfL.SetValue(2, 1, DL3UUV); | |
139 | DerSurfL.SetValue(1, 2, DL3UVV); | |
140 | DerSurfL.SetValue(0, 3, DL3V); | |
141 | break; | |
142 | default: | |
143 | break; | |
144 | } | |
145 | ||
146 | if(Nu <= Nv) | |
147 | { | |
148 | for(i=0;i<=MaxOrder+1+Nu;i++) | |
149 | for(j=i;j<=MaxOrder+Nv+1;j++) | |
150 | if(i+j> MinOrder) | |
151 | { | |
152 | DerSurfL.SetValue(i,j,L->DN(U,V,i,j)); | |
153 | DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); | |
154 | if (i!=j && j <= Nu+1) | |
155 | { | |
156 | DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); | |
157 | DerSurfL.SetValue(j,i,L->DN(U,V,j,i)); | |
158 | } | |
159 | } | |
160 | } | |
161 | else | |
162 | { | |
163 | for(j=0;j<=MaxOrder+1+Nv;j++) | |
164 | for(i=j;i<=MaxOrder+Nu+1;i++) | |
165 | if(i+j> MinOrder) | |
166 | { | |
167 | DerSurfL.SetValue(i,j,L->DN(U,V,i,j)); | |
168 | DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); | |
169 | if (i!=j && i <= Nv+1) | |
170 | { | |
171 | DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); | |
172 | DerSurfL.SetValue(j,i,L->DN(U,V,j,i)); | |
173 | } | |
174 | } | |
175 | } | |
176 | for(i=0;i<=MaxOrder+Nu;i++) | |
177 | for(j=0;j<=MaxOrder+Nv;j++) | |
178 | { | |
179 | if (AlongU) | |
180 | DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurfL,DerSurf)); | |
181 | if (AlongV) | |
182 | DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf,DerSurfL)); | |
183 | } | |
184 | ||
185 | } | |
186 | else | |
187 | { | |
188 | ||
189 | for(i=0;i<=MaxOrder+Nu+1;i++) | |
190 | for(j=i;j<=MaxOrder+Nv+1;j++) | |
191 | if(i+j>MinOrder) | |
192 | { | |
193 | ||
194 | DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); | |
195 | if (i!=j) DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); | |
196 | } | |
197 | for(i=0;i<=MaxOrder+Nu;i++) | |
198 | for(j=0;j<=MaxOrder+Nv;j++) | |
199 | { | |
200 | DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf)); | |
201 | } | |
202 | } | |
203 | ||
204 | } | |
205 | ||
206 | ||
207 | //======================================================================= | |
208 | //function : Copy | |
209 | //purpose : | |
210 | //======================================================================= | |
211 | ||
212 | Handle(Geom_Geometry) Geom_OffsetSurface::Copy () const { | |
213 | ||
214 | Handle(OffsetSurface) S; | |
215 | S = new OffsetSurface (basisSurf, offsetValue); | |
216 | return S; | |
217 | } | |
218 | ||
219 | ||
220 | ||
221 | ||
222 | ||
223 | //======================================================================= | |
224 | //function : Geom_OffsetSurface | |
225 | //purpose : | |
226 | //======================================================================= | |
227 | ||
228 | Geom_OffsetSurface::Geom_OffsetSurface ( const Handle(Surface)& S, | |
229 | const Standard_Real Offset ) | |
230 | : offsetValue (Offset) | |
231 | { | |
7fd59977 | 232 | Handle(Geom_OffsetSurface) Off_S; |
233 | Off_S = Handle(Geom_OffsetSurface)::DownCast(S); | |
234 | if (!Off_S.IsNull()) { | |
06be28a4 RL |
235 | offsetValue += Off_S->Offset(); |
236 | SetBasisSurface (Off_S->BasisSurface()); | |
237 | } | |
7fd59977 | 238 | else { |
06be28a4 | 239 | SetBasisSurface(S); |
7fd59977 | 240 | } |
06be28a4 | 241 | |
7fd59977 | 242 | // |
243 | // Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur | |
244 | // et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso | |
245 | // et aussi pour les singularite. Pour les surfaces osculatrices, on l'utilise pour | |
246 | // detecter si une iso est degeneree. | |
247 | Standard_Real Tol = Precision::Confusion(); //0.0001; | |
248 | myOscSurf.Init(basisSurf,Tol); | |
249 | } | |
250 | ||
251 | ||
252 | ||
253 | //======================================================================= | |
254 | //function : SetBasisSurface | |
255 | //purpose : | |
256 | //======================================================================= | |
257 | ||
06be28a4 RL |
258 | void Geom_OffsetSurface::SetBasisSurface (const Handle(Surface)& S) |
259 | { | |
260 | Handle(Surface) aBasisSurf = Handle(Surface)::DownCast(S->Copy()); | |
261 | ||
262 | // Basis surface must be at least C1 | |
263 | if (aBasisSurf->Continuity() == GeomAbs_C0) | |
264 | { | |
265 | // For B-splines it is sometimes possible to increase continuity by removing | |
266 | // unnecessarily duplicated knots | |
267 | if (aBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) | |
268 | { | |
269 | Handle(Geom_BSplineSurface) aBSurf = Handle(Geom_BSplineSurface)::DownCast(aBasisSurf); | |
270 | Standard_Integer uDegree = aBSurf->UDegree(), vDegree = aBSurf->VDegree(); | |
271 | Standard_Real Toler = Precision::Confusion(); | |
272 | Standard_Integer start = aBSurf->IsUPeriodic() ? 1 : aBSurf->FirstUKnotIndex(), | |
273 | finish = aBSurf->IsUPeriodic() ? aBSurf->NbUKnots() : aBSurf->LastUKnotIndex(); | |
274 | for (Standard_Integer i = start; i <= finish; i++) | |
275 | { | |
276 | Standard_Integer mult = aBSurf->UMultiplicity(i); | |
277 | if ( mult == uDegree ) | |
278 | aBSurf->RemoveUKnot(i,uDegree - 1, Toler); | |
279 | } | |
280 | start = aBSurf->IsVPeriodic() ? 1 : aBSurf->FirstVKnotIndex(); | |
281 | finish = aBSurf->IsVPeriodic() ? aBSurf->NbVKnots() : aBSurf->LastVKnotIndex(); | |
282 | for (Standard_Integer i = start; i <= finish; i++) | |
283 | { | |
284 | Standard_Integer mult = aBSurf->VMultiplicity(i); | |
285 | if ( mult == vDegree ) | |
286 | aBSurf->RemoveVKnot(i,vDegree - 1, Toler); | |
287 | } | |
288 | } | |
289 | ||
290 | // Raise exception if still C0 | |
291 | if (aBasisSurf->Continuity() == GeomAbs_C0) | |
292 | Standard_ConstructionError::Raise("Offset with no C1 Surface"); | |
293 | } | |
7fd59977 | 294 | |
06be28a4 | 295 | basisSurf = aBasisSurf; |
7fd59977 | 296 | equivSurf = Surface(); |
7fd59977 | 297 | } |
298 | ||
299 | ||
300 | ||
301 | //======================================================================= | |
302 | //function : SetOffsetValue | |
303 | //purpose : | |
304 | //======================================================================= | |
305 | ||
306 | void Geom_OffsetSurface::SetOffsetValue (const Standard_Real D) { | |
307 | ||
308 | offsetValue = D; | |
309 | equivSurf = Surface(); | |
310 | } | |
311 | ||
312 | //======================================================================= | |
313 | //function : UReverse | |
314 | //purpose : | |
315 | //======================================================================= | |
316 | ||
317 | void Geom_OffsetSurface::UReverse () { | |
318 | ||
319 | basisSurf->UReverse(); | |
320 | offsetValue = -offsetValue; | |
321 | if(!equivSurf.IsNull()) equivSurf->UReverse(); | |
322 | } | |
323 | ||
324 | ||
325 | //======================================================================= | |
326 | //function : UReversedParameter | |
327 | //purpose : | |
328 | //======================================================================= | |
329 | ||
330 | Standard_Real Geom_OffsetSurface::UReversedParameter( const Standard_Real U) const { | |
331 | ||
332 | return basisSurf->UReversedParameter( U); | |
333 | } | |
334 | ||
335 | ||
336 | //======================================================================= | |
337 | //function : VReverse | |
338 | //purpose : | |
339 | //======================================================================= | |
340 | ||
341 | void Geom_OffsetSurface::VReverse () { | |
342 | ||
343 | basisSurf->VReverse(); | |
344 | offsetValue = -offsetValue; | |
345 | if(!equivSurf.IsNull()) equivSurf->VReverse(); | |
346 | } | |
347 | ||
348 | ||
349 | //======================================================================= | |
350 | //function : VReversedParameter | |
351 | //purpose : | |
352 | //======================================================================= | |
353 | ||
354 | Standard_Real Geom_OffsetSurface::VReversedParameter( const Standard_Real V) const { | |
355 | ||
356 | return basisSurf->VReversedParameter( V); | |
357 | } | |
358 | ||
359 | //======================================================================= | |
360 | //function : BasisSurface | |
361 | //purpose : | |
362 | //======================================================================= | |
363 | ||
364 | Handle(Surface) Geom_OffsetSurface::BasisSurface () const | |
365 | { | |
366 | return basisSurf; | |
367 | } | |
368 | ||
369 | ||
370 | //======================================================================= | |
371 | //function : Bounds | |
372 | //purpose : | |
373 | //======================================================================= | |
374 | ||
375 | void Geom_OffsetSurface::Bounds (Standard_Real& U1, | |
376 | Standard_Real& U2, | |
377 | Standard_Real& V1, | |
378 | Standard_Real& V2) const { | |
379 | ||
380 | basisSurf->Bounds (U1, U2 ,V1, V2); | |
381 | } | |
382 | ||
383 | ||
384 | //======================================================================= | |
385 | //function : Continuity | |
386 | //purpose : | |
387 | //======================================================================= | |
388 | ||
389 | GeomAbs_Shape Geom_OffsetSurface::Continuity () const { | |
390 | ||
391 | GeomAbs_Shape OffsetShape=GeomAbs_C0; | |
392 | switch (basisSurf->Continuity()) { | |
393 | case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break; | |
394 | case GeomAbs_G1 : OffsetShape = GeomAbs_C0; break; | |
395 | case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break; | |
396 | case GeomAbs_G2 : OffsetShape = GeomAbs_C0; break; | |
397 | case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break; | |
398 | case GeomAbs_C3 : OffsetShape = GeomAbs_C2; break; | |
399 | case GeomAbs_CN : OffsetShape = GeomAbs_CN; break; | |
400 | } | |
401 | return OffsetShape; | |
402 | } | |
403 | ||
404 | ||
405 | //======================================================================= | |
406 | //function : D0 | |
407 | //purpose : | |
408 | //======================================================================= | |
409 | ||
410 | void Geom_OffsetSurface::D0 (const Standard_Real U, const Standard_Real V, Pnt& P) const { | |
411 | ||
412 | Vec D1U, D1V; | |
413 | #ifdef CHECK | |
414 | if (basisSurf->Continuity() == GeomAbs_C0) Geom_UndefinedValue::Raise(); | |
415 | #endif | |
416 | if (equivSurf.IsNull()){ | |
417 | basisSurf->D1(U, V, P, D1U, D1V); | |
418 | SetD0(U,V,P,D1U,D1V); | |
419 | } | |
420 | else equivSurf->D0(U,V,P); | |
421 | } | |
422 | ||
423 | ||
424 | //======================================================================= | |
425 | //function : D1 | |
426 | //purpose : | |
427 | //======================================================================= | |
428 | ||
429 | void Geom_OffsetSurface::D1 (const Standard_Real U, const Standard_Real V, | |
430 | Pnt& P, | |
431 | Vec& D1U, Vec& D1V) const | |
432 | { | |
433 | ||
434 | #ifdef CHECK | |
435 | if (basisSurf->Continuity()==GeomAbs_C0 || | |
436 | basisSurf->Continuity()==GeomAbs_C1) { | |
437 | Geom_UndefinedDerivative::Raise(); | |
438 | } | |
439 | #endif | |
440 | if (equivSurf.IsNull()) | |
441 | { | |
442 | gp_Vec d2u, d2v, d2uv; | |
443 | basisSurf->D2(U, V, P, D1U, D1V, d2u, d2v, d2uv); | |
444 | SetD1(U,V,P,D1U,D1V,d2u, d2v, d2uv); | |
445 | } | |
446 | else { | |
447 | equivSurf->D1(U,V,P,D1U,D1V); | |
448 | } | |
449 | } | |
450 | ||
451 | ||
452 | ||
453 | //======================================================================= | |
454 | //function : D2 | |
455 | //purpose : | |
456 | //======================================================================= | |
457 | ||
458 | void Geom_OffsetSurface::D2 (const Standard_Real U, const Standard_Real V, | |
459 | Pnt& P, | |
460 | Vec& D1U, Vec& D1V, | |
461 | Vec& D2U, Vec& D2V, Vec& D2UV) const { | |
462 | ||
463 | #ifdef CHECK | |
464 | GeomAbs_Shape Continuity = basisSurf->Continuity(); | |
465 | if (Continuity == GeomAbs_C0 || Continuity == GeomAbs_C1 || | |
466 | Continuity == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); } | |
467 | #endif | |
468 | if (equivSurf.IsNull()) | |
469 | { | |
470 | gp_Vec d3u, d3uuv, d3uvv, d3v; | |
471 | basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, | |
472 | d3u,d3v, d3uuv, d3uvv); | |
473 | ||
474 | SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,d3u,d3v, d3uuv, d3uvv); | |
475 | } | |
476 | else equivSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); | |
477 | } | |
478 | ||
479 | ||
480 | //======================================================================= | |
481 | //function : D3 | |
482 | //purpose : | |
483 | //======================================================================= | |
484 | ||
485 | void Geom_OffsetSurface::D3 (const Standard_Real U, const Standard_Real V, | |
486 | Pnt& P, | |
487 | Vec& D1U, Vec& D1V, | |
488 | Vec& D2U, Vec& D2V, Vec& D2UV, | |
489 | Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV) const { | |
490 | #ifdef CHECK | |
491 | if (!(basisSurf->IsCNu (4) && basisSurf->IsCNv (4))) { | |
492 | Geom_UndefinedDerivative::Raise(); | |
493 | } | |
494 | #endif | |
495 | if (equivSurf.IsNull()) | |
496 | { | |
497 | ||
498 | basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, | |
499 | D3U, D3V, D3UUV, D3UVV); | |
500 | SetD3(U, V, P, D1U, D1V, D2U, D2V, D2UV, | |
501 | D3U, D3V, D3UUV, D3UVV); | |
502 | } | |
503 | else equivSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); | |
504 | } | |
505 | ||
506 | ||
507 | ||
508 | ||
509 | //======================================================================= | |
510 | //function : DN | |
511 | //purpose : | |
512 | //======================================================================= | |
513 | ||
514 | Vec Geom_OffsetSurface::DN ( const Standard_Real U , const Standard_Real V, | |
515 | const Standard_Integer Nu, const Standard_Integer Nv) const | |
516 | { | |
517 | ||
518 | Standard_RangeError_Raise_if (Nu < 0 || Nv < 0 || Nu + Nv < 1, " "); | |
519 | #ifdef CHECK | |
520 | if (!(basisSurf->IsCNu (Nu) && basisSurf->IsCNv (Nv))) { | |
521 | Geom_UndefinedDerivative::Raise(); | |
522 | } | |
523 | #endif | |
524 | gp_Vec D(0,0,0); | |
525 | ||
526 | if (equivSurf.IsNull()) | |
527 | { | |
528 | Pnt P; | |
529 | Vec D1U,D1V; | |
530 | basisSurf->D1 (U, V, P, D1U, D1V); | |
531 | ||
532 | D = SetDN(U,V,Nu,Nv,D1U,D1V); | |
533 | } | |
534 | else D=equivSurf->DN(U,V,Nu,Nv); | |
535 | return D; | |
536 | } | |
537 | ||
538 | //======================================================================= | |
539 | //function : D1 | |
540 | //purpose : | |
541 | //======================================================================= | |
542 | ||
543 | void Geom_OffsetSurface::D1 | |
544 | (const Standard_Real U, const Standard_Real V, | |
545 | Pnt& P, Pnt& Pbasis, | |
546 | Vec& D1U, Vec& D1V, Vec& D1Ubasis , Vec& D1Vbasis, | |
547 | Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis) const { | |
548 | ||
549 | if (basisSurf->Continuity() == GeomAbs_C0 || | |
550 | basisSurf->Continuity() == GeomAbs_C1) { | |
551 | Geom_UndefinedDerivative::Raise(); | |
552 | } | |
553 | basisSurf->D2 (U, V, Pbasis, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, | |
554 | D2UVbasis); | |
555 | Vec Ndir = D1Ubasis.Crossed (D1Vbasis); | |
556 | Standard_Real R2 = Ndir.SquareMagnitude(); | |
557 | Standard_Real R = Sqrt (R2); | |
558 | Standard_Real R3 = R * R2; | |
559 | Vec DUNdir = D2Ubasis.Crossed (D1Vbasis); | |
560 | DUNdir.Add (D1Ubasis.Crossed (D2UVbasis)); | |
561 | Vec DVNdir = D2UVbasis.Crossed (D1Vbasis); | |
562 | DVNdir.Add (D1Ubasis.Crossed (D2Vbasis)); | |
563 | Standard_Real DRu = Ndir.Dot (DUNdir); | |
564 | Standard_Real DRv = Ndir.Dot (DVNdir); | |
565 | if (R3 <= gp::Resolution()) { | |
566 | if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); | |
567 | DUNdir.Multiply(R); | |
568 | DUNdir.Subtract (Ndir.Multiplied (DRu/R)); | |
569 | DUNdir.Multiply (offsetValue/R2); | |
570 | D1U = D1Ubasis.Added (DUNdir); | |
571 | DVNdir.Multiply(R); | |
572 | DVNdir.Subtract (Ndir.Multiplied (DRv/R)); | |
573 | DVNdir.Multiply (offsetValue/R2); | |
574 | D1V = D1Vbasis.Added (DVNdir); | |
575 | } | |
576 | else { | |
577 | DUNdir.Multiply (offsetValue / R); | |
578 | DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3)); | |
579 | D1U = D1Ubasis.Added (DUNdir); | |
580 | DVNdir.Multiply (offsetValue / R); | |
581 | DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3)); | |
582 | D1V = D1Vbasis.Added (DVNdir); | |
583 | } | |
584 | Ndir.Multiply (offsetValue/R); | |
585 | P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ())); | |
586 | } | |
587 | ||
588 | ||
589 | ||
590 | //======================================================================= | |
591 | //function : D2 | |
592 | //purpose : | |
593 | //======================================================================= | |
594 | ||
595 | void Geom_OffsetSurface::D2 | |
596 | (const Standard_Real U, const Standard_Real V, | |
597 | Pnt& P, Pnt& Pbasis, | |
598 | Vec& D1U, Vec& D1V, Vec& D2U, Vec& D2V, Vec& D2UV, | |
599 | Vec& D1Ubasis, Vec& D1Vbasis, | |
600 | Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis, | |
601 | Vec& D3Ubasis, Vec& D3Vbasis, Vec& D3UUVbasis, Vec& D3UVVbasis) const { | |
602 | ||
603 | ||
604 | GeomAbs_Shape Continuity = basisSurf->Continuity(); | |
605 | if (Continuity == GeomAbs_C0 || Continuity == GeomAbs_C1 || | |
606 | Continuity == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); } | |
607 | // Vec D3U, D3V, D3UVV, D3UUV; | |
608 | basisSurf->D3 (U, V, P, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, D2UVbasis, | |
609 | D3Ubasis, D3Vbasis, D3UUVbasis, D3UVVbasis); | |
610 | Vec Ndir = D1Ubasis.Crossed (D1Vbasis); | |
611 | Standard_Real R2 = Ndir.SquareMagnitude(); | |
612 | Standard_Real R = Sqrt (R2); | |
613 | Standard_Real R3 = R2 * R; | |
614 | Standard_Real R4 = R2 * R2; | |
615 | Standard_Real R5 = R3 * R2; | |
616 | Vec DUNdir = D2Ubasis.Crossed (D1Vbasis); | |
617 | DUNdir.Add (D1Ubasis.Crossed (D2UVbasis)); | |
618 | Vec DVNdir = D2UVbasis.Crossed (D1Vbasis); | |
619 | DVNdir.Add (D1Ubasis.Crossed (D2Vbasis)); | |
620 | Standard_Real DRu = Ndir.Dot (DUNdir); | |
621 | Standard_Real DRv = Ndir.Dot (DVNdir); | |
622 | Vec D2UNdir = D3Ubasis.Crossed (D1Vbasis); | |
623 | D2UNdir.Add (D1Ubasis.Crossed (D3UUVbasis)); | |
624 | D2UNdir.Add (2.0 * (D2Ubasis.Crossed (D2UVbasis))); | |
625 | Vec D2VNdir = D3UVVbasis.Crossed (D1Vbasis); | |
626 | D2VNdir.Add (D1Ubasis.Crossed (D3Vbasis)); | |
627 | D2VNdir.Add (2.0 * (D2UVbasis.Crossed (D2Vbasis))); | |
628 | Vec D2UVNdir = D2UVbasis.Crossed (D1Vbasis); | |
629 | D2UVNdir.Add (D1Ubasis.Crossed (D3UVVbasis)); | |
630 | D2UVNdir.Add (D2Ubasis.Crossed (D2Vbasis)); | |
631 | Standard_Real D2Ru = Ndir.Dot (D2UNdir) + DUNdir.Dot (DUNdir); | |
632 | Standard_Real D2Rv = Ndir.Dot (D2VNdir) + DVNdir.Dot (DVNdir); | |
633 | Standard_Real D2Ruv = DVNdir.Dot (DUNdir) + Ndir.Dot (D2UVNdir); | |
634 | ||
635 | if (R5 <= gp::Resolution()) { | |
636 | //We try another computation but the stability is not very good | |
637 | //dixit ISG. | |
638 | if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); | |
639 | // V2 = P" (U) : | |
640 | // Standard_Real R4 = R2 * R2; | |
641 | D2UNdir.Subtract (DUNdir.Multiplied (2.0 * DRu / R2)); | |
642 | D2UNdir.Subtract (Ndir.Multiplied (D2Ru/R2)); | |
643 | D2UNdir.Add (Ndir.Multiplied (3.0 * DRu * DRu / R4)); | |
644 | D2UNdir.Multiply (offsetValue / R); | |
645 | D2U = D2Ubasis.Added (D2UNdir); | |
646 | D2VNdir.Subtract (DVNdir.Multiplied (2.0 * DRv / R2)); | |
647 | D2VNdir.Subtract (Ndir.Multiplied (D2Rv/R2)); | |
648 | D2VNdir.Add (Ndir.Multiplied (3.0 * DRv * DRv / R4)); | |
649 | D2VNdir.Multiply (offsetValue / R); | |
650 | D2V = D2Vbasis.Added (D2VNdir); | |
651 | ||
652 | D2UVNdir.Subtract (DUNdir.Multiplied (DRv / R2)); | |
653 | D2UVNdir.Subtract (DVNdir.Multiplied (DRu / R2)); | |
654 | D2UVNdir.Subtract (Ndir.Multiplied (D2Ruv / R2)); | |
655 | D2UVNdir.Add (Ndir.Multiplied (3.0 * DRu * DRv / R4)); | |
656 | D2UVNdir.Multiply (offsetValue / R); | |
657 | D2UV = D2UVbasis.Added (D2UVNdir); | |
658 | ||
659 | DUNdir.Multiply(R); | |
660 | DUNdir.Subtract (Ndir.Multiplied (DRu/R)); | |
661 | DUNdir.Multiply (offsetValue/R2); | |
662 | D1U = D1Ubasis.Added (DUNdir); | |
663 | DVNdir.Multiply(R); | |
664 | DVNdir.Subtract (Ndir.Multiplied (DRv/R)); | |
665 | DVNdir.Multiply (offsetValue/R2); | |
666 | D1V = D1Vbasis.Added (DVNdir); | |
667 | } | |
668 | else { | |
669 | D2UNdir.Multiply (offsetValue/R); | |
670 | D2UNdir.Subtract (DUNdir.Multiplied (2.0 * offsetValue * DRu / R3)); | |
671 | D2UNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ru / R3)); | |
672 | D2UNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRu * DRu / R5)); | |
673 | D2U = D2Ubasis.Added (D2UNdir); | |
674 | ||
675 | D2VNdir.Multiply (offsetValue/R); | |
676 | D2VNdir.Subtract (DVNdir.Multiplied (2.0 * offsetValue * DRv / R3)); | |
677 | D2VNdir.Subtract (Ndir.Multiplied (offsetValue * D2Rv / R3)); | |
678 | D2VNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRv * DRv / R5)); | |
679 | D2V = D2Vbasis.Added (D2VNdir); | |
680 | ||
681 | D2UVNdir.Multiply (offsetValue/R); | |
682 | D2UVNdir.Subtract (DUNdir.Multiplied (offsetValue * DRv / R3)); | |
683 | D2UVNdir.Subtract (DVNdir.Multiplied (offsetValue * DRu / R3)); | |
684 | D2UVNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ruv / R3)); | |
685 | D2UVNdir.Add (Ndir.Multiplied (3.0 * offsetValue * DRu * DRv / R5)); | |
686 | D2UV = D2UVbasis.Added (D2UVNdir); | |
687 | ||
688 | DUNdir.Multiply (offsetValue / R); | |
689 | DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3)); | |
690 | D1U = D1Ubasis.Added (DUNdir); | |
691 | DVNdir.Multiply (offsetValue / R); | |
692 | DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3)); | |
693 | D1V = D1Vbasis.Added (DVNdir); | |
694 | } | |
695 | Ndir.Multiply (offsetValue/R); | |
696 | P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ())); | |
697 | } | |
698 | ||
699 | ||
700 | ||
701 | //======================================================================= | |
702 | //function : Offset | |
703 | //purpose : | |
704 | //======================================================================= | |
705 | ||
706 | Standard_Real Geom_OffsetSurface::Offset () const { | |
707 | ||
708 | return offsetValue; | |
709 | } | |
710 | ||
711 | //======================================================================= | |
712 | //function : LocalD0 | |
713 | //purpose : | |
714 | //======================================================================= | |
715 | ||
716 | void Geom_OffsetSurface::LocalD0 (const Standard_Real U, | |
717 | const Standard_Real V, | |
718 | const Standard_Integer USide, | |
719 | const Standard_Integer VSide, | |
720 | gp_Pnt& P ) const | |
721 | { | |
722 | if (equivSurf.IsNull()) { | |
723 | Vec D1U, D1V; | |
724 | Handle(Geom_Surface) Basis = basisSurf; | |
725 | ||
726 | // if Basis is Trimmed we take the basis's basis | |
727 | Handle(Geom_RectangularTrimmedSurface) RTS; | |
728 | RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis); | |
729 | if (!RTS.IsNull()) { | |
730 | Basis = RTS->BasisSurface(); | |
731 | } | |
732 | ||
733 | // BSpline case | |
734 | Handle(Geom_BSplineSurface) BSplS; | |
735 | BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); | |
736 | if (!BSplS.IsNull()) { | |
737 | Vec D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV; | |
738 | LocateSides(U,V,USide,VSide,BSplS,1,P,D1U,D1V,D2U,D2V,D2UV, | |
739 | D3U,D3V,D3UUV,D3UVV); | |
740 | SetD0(U,V,P,D1U,D1V); | |
741 | return; | |
742 | } | |
743 | ||
744 | // Extrusion case | |
745 | Handle( Geom_SurfaceOfLinearExtrusion) SE; | |
746 | SE= Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis); | |
747 | ||
748 | if (!SE.IsNull()) { | |
749 | SE->LocalD1(U,V,USide,P,D1U,D1V); | |
750 | SetD0(U,V,P,D1U,D1V); | |
751 | return; | |
752 | } | |
753 | ||
754 | // Revolution case | |
755 | Handle(Geom_SurfaceOfRevolution) SR; | |
756 | SR = Handle(Geom_SurfaceOfRevolution)::DownCast(Basis); | |
757 | if (!SR.IsNull()) { | |
758 | SR->LocalD1(U,V, VSide,P,D1U,D1V); | |
759 | SetD0(U,V, P, D1U,D1V); | |
760 | return; | |
761 | } | |
762 | ||
763 | // General cases | |
764 | basisSurf->D1(U, V, P, D1U, D1V); | |
765 | SetD0(U,V, P, D1U,D1V); | |
766 | } | |
767 | else | |
768 | equivSurf-> D0(U,V,P); | |
769 | } | |
770 | ||
771 | //======================================================================= | |
772 | //function : LocalD1 | |
773 | //purpose : | |
774 | //======================================================================= | |
775 | ||
776 | void Geom_OffsetSurface::LocalD1 (const Standard_Real U, | |
777 | const Standard_Real V, | |
778 | const Standard_Integer USide, | |
779 | const Standard_Integer VSide, | |
780 | gp_Pnt& P, | |
781 | gp_Vec& D1U, | |
782 | gp_Vec& D1V) const | |
783 | { | |
784 | if (equivSurf.IsNull()) { | |
785 | Vec D2U,D2V,D2UV ; | |
786 | Handle(Geom_Surface) Basis = basisSurf; | |
787 | ||
788 | // if Basis is Trimmed we take the basis's basis | |
789 | Handle(Geom_RectangularTrimmedSurface) RTS; | |
790 | RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis); | |
791 | if (!RTS.IsNull()) { | |
792 | Basis = RTS->BasisSurface(); | |
793 | } | |
794 | ||
795 | // BSpline case | |
796 | Handle(Geom_BSplineSurface) BSplS; | |
797 | BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); | |
798 | if (!BSplS.IsNull()) { | |
799 | Vec D3U,D3V,D3UUV,D3UVV; | |
800 | LocateSides(U,V,USide,VSide,BSplS,2,P,D1U,D1V,D2U,D2V,D2UV, | |
801 | D3U,D3V,D3UUV,D3UVV); | |
802 | SetD1(U,V,P,D1U,D1V,D2U,D2V,D2UV); | |
803 | return; | |
804 | } | |
805 | ||
806 | // Extrusion case | |
807 | Handle( Geom_SurfaceOfLinearExtrusion) SE; | |
808 | SE= Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis); | |
809 | ||
810 | if (!SE.IsNull()) { | |
811 | SE->LocalD2(U,V,USide,P,D1U,D1V,D2U,D2V,D2UV); | |
812 | SetD1(U,V,P,D1U,D1V,D2U,D2V,D2UV); | |
813 | return; | |
814 | } | |
815 | ||
816 | // Revolution case | |
817 | Handle(Geom_SurfaceOfRevolution) SR; | |
818 | SR = Handle(Geom_SurfaceOfRevolution)::DownCast(Basis); | |
819 | if (!SR.IsNull()) { | |
820 | SR->LocalD2(U,V, VSide,P,D1U,D1V,D2U,D2V,D2UV); | |
821 | SetD1(U,V, P, D1U,D1V,D2U,D2V,D2UV); | |
822 | return; | |
823 | } | |
824 | ||
825 | // General cases | |
826 | basisSurf->D2(U, V, P, D1U, D1V,D2U,D2V,D2UV); | |
827 | SetD1(U,V, P, D1U,D1V,D2U,D2V,D2UV); | |
828 | } | |
829 | else | |
830 | equivSurf-> D1(U,V,P,D1U,D1V); | |
831 | } | |
832 | ||
833 | //======================================================================= | |
834 | //function : LocalD2 | |
835 | //purpose : | |
836 | //======================================================================= | |
837 | ||
838 | void Geom_OffsetSurface::LocalD2 (const Standard_Real U, | |
839 | const Standard_Real V, | |
840 | const Standard_Integer USide, | |
841 | const Standard_Integer VSide, | |
842 | gp_Pnt& P, | |
843 | gp_Vec& D1U, | |
844 | gp_Vec& D1V, | |
845 | gp_Vec& D2U, | |
846 | gp_Vec& D2V, | |
847 | gp_Vec& D2UV) const | |
848 | { | |
849 | if (equivSurf.IsNull()) { | |
850 | Handle(Geom_Surface) Basis = basisSurf; | |
851 | Vec D3U,D3V,D3UUV,D3UVV; | |
852 | ||
853 | // if Basis is Trimmed we take the basis's basis | |
854 | Handle(Geom_RectangularTrimmedSurface) RTS; | |
855 | RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis); | |
856 | if (!RTS.IsNull()) { | |
857 | Basis = RTS->BasisSurface(); | |
858 | } | |
859 | ||
860 | // BSpline case | |
861 | Handle(Geom_BSplineSurface) BSplS; | |
862 | BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); | |
863 | if (!BSplS.IsNull()) { | |
864 | LocateSides(U,V,USide,VSide,BSplS,3,P,D1U,D1V,D2U,D2V,D2UV, | |
865 | D3U,D3V,D3UUV,D3UVV); | |
866 | SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); | |
867 | return; | |
868 | } | |
869 | ||
870 | // Extrusion case | |
871 | Handle( Geom_SurfaceOfLinearExtrusion) SE; | |
872 | SE= Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis); | |
873 | ||
874 | if (!SE.IsNull()) { | |
875 | SE->LocalD3(U,V,USide,P,D1U,D1V, | |
876 | D2U,D2V,D2UV, | |
877 | D3U,D3V,D3UUV,D3UVV); | |
878 | SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); | |
879 | return; | |
880 | } | |
881 | ||
882 | // Revolution case | |
883 | Handle(Geom_SurfaceOfRevolution) SR; | |
884 | SR = Handle(Geom_SurfaceOfRevolution)::DownCast(Basis); | |
885 | if (!SR.IsNull()) { | |
886 | SR->LocalD3(U,V, VSide,P,D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); | |
887 | SetD2(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); | |
888 | return; | |
889 | } | |
890 | ||
891 | // General cases | |
892 | basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV,D3U, D3V, D3UUV, D3UVV); | |
893 | SetD2(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); | |
894 | } | |
895 | else | |
896 | equivSurf-> D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); | |
897 | } | |
898 | //======================================================================= | |
899 | //function : LocalD3 | |
900 | //purpose : | |
901 | //======================================================================= | |
902 | ||
903 | void Geom_OffsetSurface::LocalD3 (const Standard_Real U, | |
904 | const Standard_Real V, | |
905 | const Standard_Integer USide, | |
906 | const Standard_Integer VSide, | |
907 | gp_Pnt& P, | |
908 | gp_Vec& D1U, | |
909 | gp_Vec& D1V, | |
910 | gp_Vec& D2U, | |
911 | gp_Vec& D2V, | |
912 | gp_Vec& D2UV, | |
913 | gp_Vec& D3U, | |
914 | gp_Vec& D3V, | |
915 | gp_Vec& D3UUV, | |
916 | gp_Vec& D3UVV) const | |
917 | { | |
918 | if (equivSurf.IsNull()) { | |
919 | Handle(Geom_Surface) Basis = basisSurf; | |
920 | ||
921 | // if Basis is Trimmed we take the basis's basis | |
922 | Handle(Geom_RectangularTrimmedSurface) RTS; | |
923 | RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis); | |
924 | if (!RTS.IsNull()) { | |
925 | Basis = RTS->BasisSurface(); | |
926 | } | |
927 | ||
928 | // BSpline case | |
929 | Handle(Geom_BSplineSurface) BSplS; | |
930 | BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); | |
931 | if (!BSplS.IsNull()) { | |
932 | LocateSides(U,V,USide,VSide,BSplS,3,P,D1U,D1V,D2U,D2V,D2UV, | |
933 | D3U,D3V,D3UUV,D3UVV); | |
934 | SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); | |
935 | return; | |
936 | } | |
937 | ||
938 | // Extrusion case | |
939 | Handle( Geom_SurfaceOfLinearExtrusion) SE; | |
940 | SE= Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis); | |
941 | ||
942 | if (!SE.IsNull()) { | |
943 | SE->LocalD3(U,V,USide,P,D1U,D1V, | |
944 | D2U,D2V,D2UV, | |
945 | D3U,D3V,D3UUV,D3UVV); | |
946 | SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); | |
947 | return; | |
948 | } | |
949 | ||
950 | // Revolution case | |
951 | Handle(Geom_SurfaceOfRevolution) SR; | |
952 | SR = Handle(Geom_SurfaceOfRevolution)::DownCast(Basis); | |
953 | if (!SR.IsNull()) { | |
954 | SR->LocalD3(U,V, VSide,P,D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); | |
955 | SetD3(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); | |
956 | return; | |
957 | } | |
958 | ||
959 | // General cases | |
960 | basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV,D3U, D3V, D3UUV, D3UVV); | |
961 | SetD3(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); | |
962 | } | |
963 | else | |
964 | equivSurf-> D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); | |
965 | } | |
966 | ||
967 | //======================================================================= | |
968 | //function : LocalDN | |
969 | //purpose : | |
970 | //======================================================================= | |
971 | ||
972 | gp_Vec Geom_OffsetSurface::LocalDN (const Standard_Real U, | |
973 | const Standard_Real V, | |
974 | const Standard_Integer USide, | |
975 | const Standard_Integer VSide, | |
976 | const Standard_Integer Nu, | |
977 | const Standard_Integer Nv) const | |
978 | { | |
979 | gp_Vec D(0,0,0); | |
980 | ||
981 | if(equivSurf.IsNull()) { | |
982 | ||
983 | Vec D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV; | |
984 | Pnt P; | |
985 | Handle(Geom_Surface) Basis = basisSurf; | |
986 | ||
987 | // if Basis is Trimmed we make the basis`s basis | |
988 | Handle(Geom_RectangularTrimmedSurface) RTS; | |
989 | RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis); | |
990 | ||
991 | if (!RTS.IsNull()) { | |
992 | Basis = RTS -> BasisSurface(); | |
993 | } | |
994 | ||
995 | //BSpline case | |
996 | Handle(Geom_BSplineSurface) BSplS; | |
997 | BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); | |
998 | ||
999 | if(!BSplS.IsNull()) { | |
1000 | LocateSides(U,V,USide,VSide,BSplS,1,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); | |
1001 | return D = SetDN(U,V,Nu,Nv,D1U,D1V); | |
1002 | } | |
1003 | ||
1004 | //Extrusion case | |
1005 | Handle( Geom_SurfaceOfLinearExtrusion) SE; | |
1006 | SE = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis); | |
1007 | ||
1008 | if(!SE.IsNull()) { | |
1009 | ||
1010 | SE->LocalD1(U,V,USide,P,D1U,D1V); | |
1011 | D = SetDN(U,V,Nu,Nv,D1U,D1V); | |
1012 | return D; | |
1013 | } | |
1014 | ||
1015 | //Revolution case | |
1016 | Handle(Geom_SurfaceOfRevolution) SR; | |
1017 | SR = Handle(Geom_SurfaceOfRevolution)::DownCast(Basis); | |
1018 | ||
1019 | if(!SR.IsNull()) { | |
1020 | D = SR->LocalDN(U,V,VSide,Nu,Nv); | |
1021 | return D = SetDN(U,V,Nu,Nv,D1U,D1V); | |
1022 | } | |
1023 | ||
1024 | //General cases | |
1025 | D = basisSurf->DN(U,V,Nu,Nv); | |
1026 | return D = SetDN(U,V,Nu,Nv,D1U,D1V); | |
1027 | } | |
1028 | else | |
1029 | return D = equivSurf->DN(U,V,Nu,Nv); | |
1030 | } | |
1031 | ||
1032 | //======================================================================= | |
1033 | //function : LocateSides | |
1034 | //purpose : | |
1035 | //======================================================================= | |
1036 | void Geom_OffsetSurface::LocateSides(const Standard_Real U, | |
1037 | const Standard_Real V, | |
1038 | const Standard_Integer USide, | |
1039 | const Standard_Integer VSide, | |
1040 | const Handle(Geom_BSplineSurface)& BSplS, | |
1041 | const Standard_Integer NDir, | |
1042 | gp_Pnt& P, | |
1043 | gp_Vec& D1U,gp_Vec& D1V, | |
1044 | gp_Vec& D2U,gp_Vec& D2V,gp_Vec& D2UV, | |
1045 | gp_Vec& D3U,gp_Vec& D3V,gp_Vec& D3UUV,gp_Vec& D3UVV ) const | |
1046 | { | |
1047 | Standard_Boolean UIsKnot=Standard_False, VIsKnot=Standard_False ; | |
1048 | Standard_Integer Ideb, Ifin, IVdeb, IVfin; | |
1049 | Standard_Real ParTol=Precision::PConfusion()/10.; | |
1050 | BSplS->Geom_BSplineSurface::LocateU(U,ParTol,Ideb, Ifin, Standard_False); | |
1051 | BSplS->Geom_BSplineSurface::LocateV(V,ParTol,IVdeb,IVfin,Standard_False); | |
1052 | ||
1053 | if(Ideb == Ifin ) { //knot | |
1054 | ||
1055 | if(USide == 1) {Ifin++; UIsKnot=Standard_True;} | |
1056 | ||
1057 | else if(USide == -1) {Ideb--; UIsKnot=Standard_True;} | |
1058 | ||
1059 | else {Ideb--; Ifin++;} //USide == 0 | |
1060 | ||
1061 | } | |
1062 | ||
1063 | if(Ideb < BSplS->FirstUKnotIndex()) {Ideb = BSplS->FirstUKnotIndex(); Ifin = Ideb + 1;} | |
1064 | ||
1065 | if(Ifin > BSplS->LastUKnotIndex()) {Ifin = BSplS->LastUKnotIndex(); Ideb = Ifin - 1;} | |
1066 | ||
1067 | ||
1068 | if(IVdeb == IVfin ) { //knot | |
1069 | ||
1070 | if(VSide == 1) {IVfin++; VIsKnot=Standard_True;} | |
1071 | ||
1072 | else if(VSide == -1) {IVdeb--; VIsKnot=Standard_True;} | |
1073 | ||
1074 | else {IVdeb--; IVfin++;} //VSide == 0 | |
1075 | ||
1076 | } | |
1077 | ||
1078 | if(IVdeb < BSplS->FirstVKnotIndex()) {IVdeb = BSplS->FirstVKnotIndex(); IVfin = IVdeb + 1;} | |
1079 | ||
1080 | if(IVfin > BSplS->LastVKnotIndex()) {IVfin = BSplS->LastVKnotIndex(); IVdeb = IVfin - 1;} | |
1081 | ||
1082 | ||
1083 | if((UIsKnot)||(VIsKnot)) | |
1084 | switch(NDir) | |
1085 | { | |
1086 | case 0 : BSplS->Geom_BSplineSurface::LocalD0(U,V,Ideb,Ifin,IVdeb,IVfin,P); break; | |
1087 | case 1 : BSplS->Geom_BSplineSurface::LocalD1(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V); break; | |
1088 | case 2 : BSplS->Geom_BSplineSurface::LocalD2(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV); break; | |
1089 | case 3 : BSplS->Geom_BSplineSurface::LocalD3(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break; | |
1090 | }else switch(NDir) | |
1091 | { | |
1092 | case 0 : basisSurf->D0(U,V,P); break; | |
1093 | case 1 : basisSurf->D1(U,V,P,D1U,D1V); break; | |
1094 | case 2 : basisSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); break; | |
1095 | case 3 : basisSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break; | |
1096 | } | |
1097 | } | |
1098 | ||
1099 | ||
1100 | ////************************************************* | |
1101 | //// | |
1102 | //// EVALUATOR FOR THE ISO-CURVE APPROXIMATION | |
1103 | //// | |
1104 | ////************************************************* | |
1105 | ||
1106 | class Geom_OffsetSurface_UIsoEvaluator : public AdvApprox_EvaluatorFunction | |
1107 | { | |
1108 | public: | |
1109 | Geom_OffsetSurface_UIsoEvaluator (const Handle(Geom_Surface)& theSurface, | |
1110 | Standard_Real theU) | |
1111 | : CurrentSurface(theSurface), IsoPar(theU) {} | |
1112 | ||
1113 | virtual void Evaluate (Standard_Integer *Dimension, | |
1114 | Standard_Real StartEnd[2], | |
1115 | Standard_Real *Parameter, | |
1116 | Standard_Integer *DerivativeRequest, | |
1117 | Standard_Real *Result, // [Dimension] | |
1118 | Standard_Integer *ErrorCode); | |
1119 | ||
1120 | private: | |
1121 | Handle(Geom_Surface) CurrentSurface; | |
1122 | Standard_Real IsoPar; | |
1123 | }; | |
1124 | ||
1125 | void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/ | |
1126 | Standard_Real /*StartEnd*/[2], | |
1127 | Standard_Real *Parameter, | |
1128 | Standard_Integer *DerivativeRequest, | |
1129 | Standard_Real *Result, | |
1130 | Standard_Integer *ReturnCode) | |
1131 | { | |
1132 | gp_Pnt P; | |
1133 | if (*DerivativeRequest == 0) { | |
1134 | P = CurrentSurface->Value(IsoPar,*Parameter); | |
1135 | for (Standard_Integer i = 0; i < 3; i++) | |
1136 | Result[i] = P.Coord(i+1); | |
1137 | } | |
1138 | else { | |
1139 | gp_Vec DU,DV; | |
1140 | CurrentSurface->D1(IsoPar,*Parameter,P,DU,DV); | |
1141 | for (Standard_Integer i = 0; i < 3; i++) | |
1142 | Result[i] = DV.Coord(i+1); | |
1143 | } | |
1144 | *ReturnCode = 0 ; | |
1145 | } | |
1146 | ||
1147 | class Geom_OffsetSurface_VIsoEvaluator : public AdvApprox_EvaluatorFunction | |
1148 | { | |
1149 | public: | |
1150 | Geom_OffsetSurface_VIsoEvaluator (const Handle(Geom_Surface)& theSurface, | |
1151 | Standard_Real theV) | |
1152 | : CurrentSurface(theSurface), IsoPar(theV) {} | |
1153 | ||
1154 | virtual void Evaluate (Standard_Integer *Dimension, | |
1155 | Standard_Real StartEnd[2], | |
1156 | Standard_Real *Parameter, | |
1157 | Standard_Integer *DerivativeRequest, | |
1158 | Standard_Real *Result, // [Dimension] | |
1159 | Standard_Integer *ErrorCode); | |
1160 | ||
1161 | private: | |
1162 | Handle(Geom_Surface) CurrentSurface; | |
1163 | Standard_Real IsoPar; | |
1164 | }; | |
1165 | ||
1166 | void Geom_OffsetSurface_VIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/ | |
1167 | Standard_Real /*StartEnd*/[2], | |
1168 | Standard_Real *Parameter, | |
1169 | Standard_Integer *DerivativeRequest, | |
1170 | Standard_Real *Result, | |
1171 | Standard_Integer *ReturnCode) | |
1172 | { | |
1173 | gp_Pnt P; | |
1174 | if (*DerivativeRequest == 0) { | |
1175 | P = CurrentSurface->Value(*Parameter,IsoPar); | |
1176 | for (Standard_Integer i = 0; i < 3; i++) | |
1177 | Result[i] = P.Coord(i+1); | |
1178 | } | |
1179 | else { | |
1180 | gp_Vec DU,DV; | |
1181 | CurrentSurface->D1(*Parameter,IsoPar,P,DU,DV); | |
1182 | for (Standard_Integer i = 0; i < 3; i++) | |
1183 | Result[i] = DU.Coord(i+1); | |
1184 | } | |
1185 | *ReturnCode = 0 ; | |
1186 | } | |
1187 | ||
1188 | //======================================================================= | |
1189 | //function : UIso | |
1190 | //purpose : The Uiso or the VIso of an OffsetSurface can't be clearly | |
1191 | // exprimed as a curve from Geom. So, to extract the U or VIso | |
1192 | // an Approximation is needed. This approx always will return a | |
1193 | // BSplineCurve from Geom. | |
1194 | //======================================================================= | |
1195 | ||
1196 | Handle(Geom_Curve) Geom_OffsetSurface::UIso (const Standard_Real UU) const | |
1197 | { | |
1198 | if (equivSurf.IsNull()) { | |
1199 | Standard_Integer Num1 = 0; | |
1200 | Standard_Integer Num2 = 0; | |
1201 | Standard_Integer Num3 = 1; | |
1202 | Handle(TColStd_HArray1OfReal) T1; | |
1203 | Handle(TColStd_HArray1OfReal) T2; | |
1204 | Handle(TColStd_HArray1OfReal) T3 = | |
1205 | new TColStd_HArray1OfReal(1,Num3); | |
1206 | T3->Init(Precision::Approximation()); | |
1207 | Standard_Real U1,U2,V1,V2; | |
1208 | Bounds(U1,U2,V1,V2); | |
1209 | GeomAbs_Shape Cont = GeomAbs_C1; | |
1210 | Standard_Integer MaxSeg = 100, MaxDeg =14; | |
1211 | ||
1212 | Geom_OffsetSurface_UIsoEvaluator ev (this, UU); | |
1213 | AdvApprox_ApproxAFunction Approx(Num1, Num2, Num3, T1, T2, T3, | |
1214 | V1, V2, Cont, | |
1215 | MaxDeg,MaxSeg, ev); | |
1216 | ||
1217 | Standard_ConstructionError_Raise_if (!Approx.IsDone(), | |
1218 | " Geom_OffsetSurface : UIso"); | |
1219 | ||
1220 | Standard_Integer NbPoles = Approx.NbPoles(); | |
1221 | ||
1222 | TColgp_Array1OfPnt Poles( 1, NbPoles); | |
1223 | TColStd_Array1OfReal Knots( 1, Approx.NbKnots()); | |
1224 | TColStd_Array1OfInteger Mults( 1, Approx.NbKnots()); | |
1225 | ||
1226 | Approx.Poles(1, Poles); | |
1227 | Knots = Approx.Knots()->Array1(); | |
1228 | Mults = Approx.Multiplicities()->Array1(); | |
1229 | ||
1230 | Handle(Geom_BSplineCurve) C = | |
1231 | new Geom_BSplineCurve( Poles, Knots, Mults, Approx.Degree()); | |
1232 | return C; | |
1233 | } | |
1234 | else | |
1235 | return equivSurf->UIso(UU); | |
1236 | } | |
1237 | ||
1238 | ||
1239 | //======================================================================= | |
1240 | //function : Value | |
1241 | //purpose : | |
1242 | //======================================================================= | |
1243 | ||
1244 | void Geom_OffsetSurface::Value | |
1245 | ( const Standard_Real U, const Standard_Real V, | |
1246 | // Pnt& P, Pnt& Pbasis, | |
1247 | Pnt& P, Pnt& , | |
1248 | Vec& D1Ubasis, Vec& D1Vbasis) const { | |
1249 | ||
1250 | if (basisSurf->Continuity() == GeomAbs_C0) | |
1251 | Geom_UndefinedValue::Raise(); | |
1252 | ||
1253 | SetD0(U,V,P,D1Ubasis,D1Vbasis); | |
1254 | } | |
1255 | ||
1256 | ||
1257 | ||
1258 | //======================================================================= | |
1259 | //function : VIso | |
1260 | //purpose : | |
1261 | //======================================================================= | |
1262 | ||
1263 | Handle(Geom_Curve) Geom_OffsetSurface::VIso (const Standard_Real VV) const | |
1264 | { | |
1265 | if (equivSurf.IsNull()) { | |
1266 | Standard_Integer Num1 = 0; | |
1267 | Standard_Integer Num2 = 0; | |
1268 | Standard_Integer Num3 = 1; | |
1269 | Handle(TColStd_HArray1OfReal) T1; | |
1270 | Handle(TColStd_HArray1OfReal) T2; | |
1271 | Handle(TColStd_HArray1OfReal) T3 = | |
1272 | new TColStd_HArray1OfReal(1,Num3); | |
1273 | T3->Init(Precision::Approximation()); | |
1274 | Standard_Real U1,U2,V1,V2; | |
1275 | Bounds(U1,U2,V1,V2); | |
1276 | GeomAbs_Shape Cont = GeomAbs_C1; | |
1277 | Standard_Integer MaxSeg = 100, MaxDeg =14; | |
1278 | ||
1279 | Geom_OffsetSurface_VIsoEvaluator ev (this, VV); | |
1280 | AdvApprox_ApproxAFunction Approx (Num1, Num2, Num3, T1, T2, T3, | |
1281 | U1, U2, Cont, MaxDeg, MaxSeg, ev); | |
1282 | ||
1283 | Standard_ConstructionError_Raise_if (!Approx.IsDone(), | |
1284 | " Geom_OffsetSurface : VIso"); | |
1285 | ||
1286 | TColgp_Array1OfPnt Poles( 1, Approx.NbPoles()); | |
1287 | TColStd_Array1OfReal Knots( 1, Approx.NbKnots()); | |
1288 | TColStd_Array1OfInteger Mults( 1, Approx.NbKnots()); | |
1289 | ||
1290 | Approx.Poles(1, Poles); | |
1291 | Knots = Approx.Knots()->Array1(); | |
1292 | Mults = Approx.Multiplicities()->Array1(); | |
1293 | ||
1294 | Handle(Geom_BSplineCurve) C = | |
1295 | new Geom_BSplineCurve( Poles, Knots, Mults, Approx.Degree()); | |
1296 | return C; | |
1297 | } | |
1298 | else | |
1299 | return equivSurf->VIso(VV); | |
1300 | } | |
1301 | ||
1302 | ||
1303 | //======================================================================= | |
1304 | //function : IsCNu | |
1305 | //purpose : | |
1306 | //======================================================================= | |
1307 | ||
1308 | Standard_Boolean Geom_OffsetSurface::IsCNu (const Standard_Integer N) const { | |
1309 | ||
1310 | Standard_RangeError_Raise_if (N < 0, " "); | |
1311 | return basisSurf->IsCNu (N+1); | |
1312 | } | |
1313 | ||
1314 | ||
1315 | //======================================================================= | |
1316 | //function : IsCNv | |
1317 | //purpose : | |
1318 | //======================================================================= | |
1319 | ||
1320 | Standard_Boolean Geom_OffsetSurface::IsCNv (const Standard_Integer N) const { | |
1321 | ||
1322 | Standard_RangeError_Raise_if (N < 0, " "); | |
1323 | return basisSurf->IsCNv (N+1); | |
1324 | } | |
1325 | ||
1326 | ||
1327 | //======================================================================= | |
1328 | //function : IsUPeriodic | |
1329 | //purpose : | |
1330 | //======================================================================= | |
1331 | ||
1332 | Standard_Boolean Geom_OffsetSurface::IsUPeriodic () const | |
1333 | { | |
1334 | return basisSurf->IsUPeriodic(); | |
1335 | } | |
1336 | ||
1337 | ||
1338 | //======================================================================= | |
1339 | //function : UPeriod | |
1340 | //purpose : | |
1341 | //======================================================================= | |
1342 | ||
1343 | Standard_Real Geom_OffsetSurface::UPeriod() const | |
1344 | { | |
1345 | return basisSurf->UPeriod(); | |
1346 | } | |
1347 | ||
1348 | ||
1349 | //======================================================================= | |
1350 | //function : IsVPeriodic | |
1351 | //purpose : | |
1352 | //======================================================================= | |
1353 | ||
1354 | Standard_Boolean Geom_OffsetSurface::IsVPeriodic () const | |
1355 | { | |
1356 | return basisSurf->IsVPeriodic(); | |
1357 | } | |
1358 | ||
1359 | ||
1360 | //======================================================================= | |
1361 | //function : VPeriod | |
1362 | //purpose : | |
1363 | //======================================================================= | |
1364 | ||
1365 | Standard_Real Geom_OffsetSurface::VPeriod() const | |
1366 | { | |
1367 | return basisSurf->VPeriod(); | |
1368 | } | |
1369 | ||
1370 | ||
1371 | //======================================================================= | |
1372 | //function : IsUClosed | |
1373 | //purpose : | |
1374 | //======================================================================= | |
1375 | ||
1376 | Standard_Boolean Geom_OffsetSurface::IsUClosed () const { | |
1377 | ||
1378 | Standard_Boolean UClosed; | |
1379 | Handle(Surface) SBasis = BasisSurface(); | |
1380 | ||
1381 | if (SBasis->IsKind (STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { | |
1382 | Handle(Geom_RectangularTrimmedSurface) St = | |
1383 | Handle(Geom_RectangularTrimmedSurface)::DownCast(SBasis); | |
1384 | ||
1385 | Handle(Surface) S = Handle(Surface)::DownCast(St->BasisSurface()); | |
1386 | if (S->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) { | |
1387 | UClosed = SBasis->IsUClosed(); | |
1388 | } | |
1389 | else if (S->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) { | |
1390 | Handle(Geom_SurfaceOfLinearExtrusion) Extru = | |
1391 | Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S); | |
1392 | ||
1393 | Handle(Curve) C = Extru->BasisCurve(); | |
1394 | if (C->IsKind (STANDARD_TYPE(Geom_Circle)) || C->IsKind (STANDARD_TYPE(Geom_Ellipse))) { | |
1395 | UClosed = SBasis->IsUClosed(); | |
1396 | } | |
1397 | else { UClosed = Standard_False; } | |
1398 | } | |
1399 | else if (S->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution))) { | |
1400 | UClosed = SBasis->IsUClosed(); | |
1401 | } | |
1402 | else { UClosed = Standard_False; } | |
1403 | } | |
1404 | else { | |
1405 | if (SBasis->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) { | |
1406 | UClosed = SBasis->IsUClosed(); | |
1407 | } | |
1408 | else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) { | |
1409 | Handle(Geom_SurfaceOfLinearExtrusion) Extru = | |
1410 | Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SBasis); | |
1411 | ||
1412 | Handle(Curve) C = Extru->BasisCurve(); | |
1413 | UClosed = (C->IsKind(STANDARD_TYPE(Geom_Circle)) || C->IsKind(STANDARD_TYPE(Geom_Ellipse))); | |
1414 | } | |
1415 | else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution))) { | |
1416 | UClosed = Standard_True; | |
1417 | } | |
1418 | else { UClosed = Standard_False; } | |
1419 | } | |
1420 | return UClosed; | |
1421 | } | |
1422 | ||
1423 | ||
1424 | //======================================================================= | |
1425 | //function : IsVClosed | |
1426 | //purpose : | |
1427 | //======================================================================= | |
1428 | ||
1429 | Standard_Boolean Geom_OffsetSurface::IsVClosed () const { | |
1430 | ||
1431 | Standard_Boolean VClosed; | |
1432 | Handle(Surface) SBasis = BasisSurface(); | |
1433 | ||
1434 | if (SBasis->IsKind (STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { | |
1435 | Handle(Geom_RectangularTrimmedSurface) St = | |
1436 | Handle(Geom_RectangularTrimmedSurface)::DownCast(SBasis); | |
1437 | ||
1438 | Handle(Surface) S = Handle(Surface)::DownCast(St->BasisSurface()); | |
1439 | if (S->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) { | |
1440 | VClosed = SBasis->IsVClosed(); | |
1441 | } | |
1442 | else { VClosed = Standard_False; } | |
1443 | } | |
1444 | else { | |
1445 | if (SBasis->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) { | |
1446 | VClosed = SBasis->IsVClosed(); | |
1447 | } | |
1448 | else { VClosed = Standard_False; } | |
1449 | } | |
1450 | return VClosed; | |
1451 | } | |
1452 | ||
1453 | ||
1454 | //======================================================================= | |
1455 | //function : Transform | |
1456 | //purpose : | |
1457 | //======================================================================= | |
1458 | ||
1459 | void Geom_OffsetSurface::Transform (const Trsf& T) | |
1460 | { | |
1461 | basisSurf->Transform (T); | |
1462 | offsetValue *= T.ScaleFactor(); | |
1463 | equivSurf.Nullify(); | |
1464 | } | |
1465 | ||
1466 | //======================================================================= | |
1467 | //function : TransformParameters | |
1468 | //purpose : | |
1469 | //======================================================================= | |
1470 | ||
1471 | void Geom_OffsetSurface::TransformParameters(Standard_Real& U, | |
1472 | Standard_Real& V, | |
1473 | const gp_Trsf& T) | |
1474 | const | |
1475 | { | |
1476 | basisSurf->TransformParameters(U,V,T); | |
1477 | if(!equivSurf.IsNull()) equivSurf->TransformParameters(U,V,T); | |
1478 | } | |
1479 | ||
1480 | //======================================================================= | |
1481 | //function : ParametricTransformation | |
1482 | //purpose : | |
1483 | //======================================================================= | |
1484 | ||
1485 | gp_GTrsf2d Geom_OffsetSurface::ParametricTransformation | |
1486 | (const gp_Trsf& T) const | |
1487 | { | |
1488 | return basisSurf->ParametricTransformation(T); | |
1489 | } | |
1490 | ||
1491 | //======================================================================= | |
1492 | //function : Surface | |
1493 | //purpose : Trouve si elle existe, une surface non offset, equivalente | |
1494 | // a l'offset surface. | |
1495 | //======================================================================= | |
1496 | Handle(Geom_Surface) Geom_OffsetSurface::Surface() const | |
1497 | { | |
1498 | if (offsetValue == 0.0) return basisSurf; // Cas direct | |
1499 | ||
1500 | Standard_Real Tol = Precision::Confusion(); | |
1501 | Handle(Geom_Surface) Result, Base; | |
1502 | Result.Nullify(); | |
1503 | Handle(Standard_Type) TheType = basisSurf->DynamicType(); | |
1504 | Standard_Boolean IsTrimmed; | |
1d47d8d0 | 1505 | Standard_Real U1 = 0., V1 = 0., U2 = 0., V2 = 0.; |
7fd59977 | 1506 | |
1507 | // Preambule pour les surface trimmes | |
1508 | if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { | |
1509 | Handle(Geom_RectangularTrimmedSurface) S = | |
1510 | Handle(Geom_RectangularTrimmedSurface)::DownCast(basisSurf); | |
1511 | Base = S->BasisSurface(); | |
1512 | TheType = Base->DynamicType(); | |
1513 | S->Bounds(U1,U2,V1,V2); | |
1514 | IsTrimmed = Standard_True; | |
1515 | } | |
1516 | else { | |
1517 | IsTrimmed = Standard_False; | |
1518 | Base = basisSurf; | |
1519 | } | |
1520 | ||
1521 | // Traite les surfaces cannonique | |
1522 | if (TheType == STANDARD_TYPE(Geom_Plane)) | |
1523 | { | |
1524 | Handle(Geom_Plane) P = | |
1525 | Handle(Geom_Plane)::DownCast(Base); | |
1526 | gp_Vec T = P->Position().XDirection()^P->Position().YDirection(); | |
1527 | T *= offsetValue; | |
1528 | Result = Handle(Geom_Plane)::DownCast(P->Translated(T)); | |
1529 | } | |
1530 | else if (TheType == STANDARD_TYPE(Geom_CylindricalSurface)) | |
1531 | { | |
1532 | Handle(Geom_CylindricalSurface) C = | |
1533 | Handle(Geom_CylindricalSurface)::DownCast(Base); | |
1534 | Standard_Real Radius = C->Radius(); | |
1535 | gp_Ax3 Axis = C->Position(); | |
1536 | if (Axis.Direct()) | |
1537 | Radius += offsetValue; | |
1538 | else | |
1539 | Radius -= offsetValue; | |
1540 | if ( Radius >= Tol ) { | |
1541 | Result = new Geom_CylindricalSurface( Axis, Radius); | |
1542 | } | |
1543 | else if ( Radius <= -Tol ){ | |
c6541a0c | 1544 | Axis.Rotate(gp_Ax1(Axis.Location(),Axis.Direction()),M_PI); |
7fd59977 | 1545 | Result = new Geom_CylindricalSurface( Axis, Abs(Radius)); |
1546 | Result->UReverse(); | |
1547 | } | |
1548 | else | |
1549 | { | |
1550 | // surface degeneree | |
1551 | } | |
1552 | } | |
1553 | else if (TheType == STANDARD_TYPE(Geom_ConicalSurface)) | |
1554 | { | |
1555 | Handle(Geom_ConicalSurface) C = | |
1556 | Handle(Geom_ConicalSurface)::DownCast(Base); | |
1557 | Standard_Real Alpha = C->SemiAngle(); | |
1558 | Standard_Real Radius = C->RefRadius() + offsetValue * Cos(Alpha); | |
1559 | gp_Ax3 Axis = C->Position(); | |
1560 | if ( Radius >= 0.) { | |
1561 | gp_Vec Z( Axis.Direction()); | |
1562 | Z *= - offsetValue * Sin(Alpha); | |
1563 | Axis.Translate(Z); | |
1564 | Result = new Geom_ConicalSurface(Axis, Alpha, Radius); | |
1565 | } | |
1566 | else | |
1567 | { | |
1568 | // surface degeneree | |
1569 | } | |
1570 | } | |
1571 | else if (TheType == STANDARD_TYPE(Geom_SphericalSurface)) { | |
1572 | Handle(Geom_SphericalSurface) S = | |
1573 | Handle(Geom_SphericalSurface)::DownCast(Base); | |
1574 | Standard_Real Radius = S->Radius(); | |
1575 | gp_Ax3 Axis = S->Position(); | |
1576 | if (Axis.Direct()) | |
1577 | Radius += offsetValue; | |
1578 | else | |
1579 | Radius -= offsetValue; | |
1580 | if ( Radius >= Tol) { | |
1581 | Result = new Geom_SphericalSurface(Axis, Radius); | |
1582 | } | |
1583 | else if ( Radius <= -Tol ) { | |
c6541a0c | 1584 | Axis.Rotate(gp_Ax1(Axis.Location(),Axis.Direction()),M_PI); |
7fd59977 | 1585 | Axis.ZReverse(); |
1586 | Result = new Geom_SphericalSurface(Axis, -Radius); | |
1587 | Result->UReverse(); | |
1588 | } | |
1589 | else { | |
1590 | // surface degeneree | |
1591 | } | |
1592 | } | |
1593 | else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface)) | |
1594 | ||
1595 | { | |
1596 | Handle(Geom_ToroidalSurface) | |
1597 | S = Handle(Geom_ToroidalSurface)::DownCast(Base); | |
1598 | Standard_Real MajorRadius = S->MajorRadius(); | |
1599 | Standard_Real MinorRadius = S->MinorRadius(); | |
1600 | gp_Ax3 Axis = S->Position(); | |
1601 | if (MinorRadius <= MajorRadius) | |
1602 | { | |
1603 | if (Axis.Direct()) | |
1604 | MinorRadius += offsetValue; | |
1605 | else | |
1606 | MinorRadius -= offsetValue; | |
1607 | if (MinorRadius >= Tol) | |
1608 | Result = new Geom_ToroidalSurface(Axis,MajorRadius,MinorRadius); | |
1609 | // else if (MinorRadius <= -Tol) | |
1610 | // Result->UReverse(); | |
1611 | else | |
1612 | { | |
1613 | // surface degeneree | |
1614 | } | |
1615 | } | |
1616 | } | |
1617 | ||
1618 | // S'il le faut on trimme le resultat | |
1619 | if (IsTrimmed && !Result.IsNull()) { | |
1620 | Base = Result; | |
1621 | Result = new Geom_RectangularTrimmedSurface (Base, U1, U2, V1,V2); | |
1622 | } | |
1623 | ||
1624 | return Result; | |
1625 | } | |
1626 | ||
1627 | Standard_Boolean Geom_OffsetSurface::UOsculatingSurface(const Standard_Real U, | |
1628 | const Standard_Real V, | |
1629 | Standard_Boolean& t, | |
1630 | Handle(Geom_BSplineSurface)& L) const | |
1631 | { | |
1632 | return myOscSurf.UOscSurf(U,V,t,L); | |
1633 | } | |
1634 | ||
1635 | Standard_Boolean Geom_OffsetSurface::VOsculatingSurface(const Standard_Real U, | |
1636 | const Standard_Real V, | |
1637 | Standard_Boolean& t, | |
1638 | Handle(Geom_BSplineSurface)& L) const | |
1639 | { | |
1640 | return myOscSurf.VOscSurf(U,V,t,L); | |
1641 | } | |
1642 | ||
1643 | ||
1644 | //======================================================================= | |
1645 | //function : | |
1646 | //purpose : private | |
1647 | //======================================================================= | |
1648 | void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V, | |
1649 | Pnt& P, | |
1650 | const Vec& D1U, const Vec& D1V)const | |
1651 | { | |
1652 | Standard_Boolean AlongU = Standard_False, | |
1653 | AlongV = Standard_False; | |
1654 | Handle(Geom_BSplineSurface) L; | |
1655 | Standard_Boolean IsOpposite=Standard_False; | |
1656 | Standard_Real signe = 1.; | |
1657 | AlongU = UOsculatingSurface(U,V,IsOpposite,L); | |
1658 | AlongV = VOsculatingSurface(U,V,IsOpposite,L); | |
1659 | if ((AlongV || AlongU) && IsOpposite) signe = -1; | |
1660 | ||
1661 | Standard_Real MagTol=0.000000001; | |
1662 | Dir Normal; | |
1663 | CSLib_NormalStatus NStatus; | |
1664 | CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal); | |
1665 | ||
0ebaa4db | 1666 | if (NStatus == CSLib_Defined) // akm - only in singularities && !AlongU && !AlongV) |
7fd59977 | 1667 | { |
1668 | P.SetXYZ(P.XYZ() + offsetValue * Normal.XYZ()); | |
1669 | } | |
1670 | else | |
1671 | { | |
1672 | Standard_Integer MaxOrder=3; | |
1673 | TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder); | |
1674 | TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1); | |
1675 | Standard_Integer OrderU,OrderV; | |
1676 | Standard_Real Umin,Umax,Vmin,Vmax; | |
1677 | Bounds(Umin,Umax,Vmin,Vmax); | |
1678 | DerSurf.SetValue(1, 0, D1U); | |
1679 | DerSurf.SetValue(0, 1, D1V); | |
1680 | derivatives(MaxOrder,1,U,V,basisSurf,0,0,AlongU,AlongV,L,DerNUV,DerSurf); | |
1681 | ||
1682 | CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); | |
1683 | if (NStatus == CSLib_Defined) | |
1684 | P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); | |
1685 | else | |
1686 | Geom_UndefinedValue::Raise(); | |
1687 | ||
1688 | } | |
1689 | } | |
1690 | ||
1691 | //======================================================================= | |
1692 | //function : | |
1693 | //purpose : private | |
1694 | //=======================================================================/ | |
1695 | void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V, | |
1696 | Pnt& P, | |
1697 | Vec& D1U, Vec& D1V, | |
1698 | const Vec& d2u, const Vec& d2v, const Vec& d2uv ) const | |
1699 | { | |
1700 | ||
1701 | Standard_Real MagTol=0.000000001; | |
1702 | Dir Normal; | |
1703 | CSLib_NormalStatus NStatus; | |
1704 | CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal); | |
1705 | Standard_Integer MaxOrder; | |
1706 | if (NStatus == CSLib_Defined) | |
1707 | MaxOrder=0; | |
1708 | else | |
1709 | MaxOrder=3; | |
1710 | Standard_Integer OrderU,OrderV; | |
1711 | TColgp_Array2OfVec DerNUV(0,MaxOrder+1,0,MaxOrder+1); | |
1712 | TColgp_Array2OfVec DerSurf(0,MaxOrder+2,0,MaxOrder+2); | |
1713 | Standard_Real Umin,Umax,Vmin,Vmax; | |
1714 | Bounds(Umin,Umax,Vmin,Vmax); | |
1715 | DerSurf.SetValue(1, 0, D1U); | |
1716 | DerSurf.SetValue(0, 1, D1V); | |
1717 | DerSurf.SetValue(1, 1, d2uv); | |
1718 | DerSurf.SetValue(2, 0, d2u); | |
1719 | DerSurf.SetValue(0, 2, d2v); | |
1720 | Handle(Geom_BSplineSurface) L; | |
1721 | Standard_Boolean AlongU = Standard_False, | |
1722 | AlongV = Standard_False; | |
1723 | Standard_Boolean IsOpposite=Standard_False; | |
1724 | Standard_Real signe = 1.; | |
1725 | AlongU = UOsculatingSurface(U,V,IsOpposite,L); | |
1726 | AlongV = VOsculatingSurface(U,V,IsOpposite,L); | |
1727 | if ((AlongV || AlongU) && IsOpposite) signe = -1; | |
1728 | derivatives(MaxOrder,2,U,V,basisSurf,1,1,AlongU,AlongV,L,DerNUV,DerSurf); | |
1729 | ||
1730 | CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); | |
1731 | if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise(); | |
1732 | ||
1733 | P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); | |
1734 | ||
1735 | D1U = DerSurf(1,0) | |
1736 | + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV); | |
1737 | D1V = DerSurf(0,1) | |
1738 | + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV); | |
1739 | ||
1740 | } | |
1741 | ||
1742 | //======================================================================= | |
1743 | //function : | |
1744 | //purpose : private | |
1745 | //=======================================================================/ | |
1746 | void Geom_OffsetSurface::SetD2(const Standard_Real U, const Standard_Real V, | |
1747 | Pnt& P, | |
1748 | Vec& D1U, Vec& D1V, | |
1749 | Vec& D2U, Vec& D2V, Vec& D2UV, | |
1750 | const Vec& d3u, const Vec& d3v, | |
1751 | const Vec& d3uuv, const Vec& d3uvv ) const | |
1752 | { | |
1753 | Standard_Real MagTol=0.000000001; | |
1754 | Dir Normal; | |
1755 | CSLib_NormalStatus NStatus; | |
1756 | CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal); | |
1757 | Standard_Integer MaxOrder; | |
1758 | if (NStatus == CSLib_Defined) | |
1759 | MaxOrder=0; | |
1760 | else | |
1761 | MaxOrder=3; | |
1762 | Standard_Integer OrderU,OrderV; | |
1763 | TColgp_Array2OfVec DerNUV(0,MaxOrder+2,0,MaxOrder+2); | |
1764 | TColgp_Array2OfVec DerSurf(0,MaxOrder+3,0,MaxOrder+3); | |
1765 | Standard_Real Umin,Umax,Vmin,Vmax; | |
1766 | Bounds(Umin,Umax,Vmin,Vmax); | |
1767 | DerSurf.SetValue(1, 0, D1U); | |
1768 | DerSurf.SetValue(0, 1, D1V); | |
1769 | DerSurf.SetValue(1, 1, D2UV); | |
1770 | DerSurf.SetValue(2, 0, D2U); | |
1771 | DerSurf.SetValue(0, 2, D2V); | |
1772 | DerSurf.SetValue(3, 0, d3u); | |
1773 | DerSurf.SetValue(2, 1, d3uuv); | |
1774 | DerSurf.SetValue(1, 2, d3uvv); | |
1775 | DerSurf.SetValue(0, 3, d3v); | |
1776 | //********************* | |
1777 | ||
1778 | Handle(Geom_BSplineSurface) L; | |
1779 | Standard_Boolean AlongU = Standard_False, | |
1780 | AlongV = Standard_False; | |
1781 | Standard_Boolean IsOpposite=Standard_False; | |
1782 | Standard_Real signe = 1.; | |
1783 | AlongU = UOsculatingSurface(U,V,IsOpposite,L); | |
1784 | AlongV = VOsculatingSurface(U,V,IsOpposite,L); | |
1785 | if ((AlongV || AlongU) && IsOpposite) signe = -1; | |
1786 | derivatives(MaxOrder,3,U,V,basisSurf,2,2,AlongU,AlongV,L,DerNUV,DerSurf); | |
1787 | ||
1788 | CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); | |
1789 | if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise(); | |
1790 | ||
1791 | ||
1792 | P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); | |
1793 | ||
1794 | D1U = DerSurf(1,0) | |
1795 | + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV); | |
1796 | D1V = DerSurf(0,1) | |
1797 | + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV); | |
1798 | ||
1799 | D2U = basisSurf->DN(U,V,2,0) | |
1800 | + signe * offsetValue * CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV); | |
1801 | D2V = basisSurf->DN(U,V,0,2) | |
1802 | + signe * offsetValue * CSLib::DNNormal(0,2,DerNUV,OrderU,OrderV); | |
1803 | D2UV = basisSurf->DN(U,V,1,1) | |
1804 | + signe * offsetValue * CSLib::DNNormal(1,1,DerNUV,OrderU,OrderV); | |
1805 | } | |
1806 | ||
1807 | ||
1808 | //======================================================================= | |
1809 | //function : | |
1810 | //purpose : private | |
1811 | //=======================================================================/ | |
1812 | void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V, | |
1813 | Pnt& P, | |
1814 | Vec& D1U, Vec& D1V, | |
1815 | Vec& D2U, Vec& D2V, Vec& D2UV, | |
1816 | Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const | |
1817 | { | |
1818 | Standard_Real MagTol=0.000000001; | |
1819 | Dir Normal; | |
1820 | CSLib_NormalStatus NStatus; | |
1821 | CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal); | |
1822 | Standard_Integer MaxOrder; | |
1823 | if (NStatus == CSLib_Defined) | |
1824 | MaxOrder=0; | |
1825 | else | |
1826 | MaxOrder=3; | |
1827 | Standard_Integer OrderU,OrderV; | |
1828 | TColgp_Array2OfVec DerNUV(0,MaxOrder+3,0,MaxOrder+3); | |
1829 | TColgp_Array2OfVec DerSurf(0,MaxOrder+4,0,MaxOrder+4); | |
1830 | Standard_Real Umin,Umax,Vmin,Vmax; | |
1831 | Bounds(Umin,Umax,Vmin,Vmax); | |
1832 | ||
1833 | DerSurf.SetValue(1, 0, D1U); | |
1834 | DerSurf.SetValue(0, 1, D1V); | |
1835 | DerSurf.SetValue(1, 1, D2UV); | |
1836 | DerSurf.SetValue(2, 0, D2U); | |
1837 | DerSurf.SetValue(0, 2, D2V); | |
1838 | DerSurf.SetValue(3, 0, D3U); | |
1839 | DerSurf.SetValue(2, 1, D3UUV); | |
1840 | DerSurf.SetValue(1, 2, D3UVV); | |
1841 | DerSurf.SetValue(0, 3, D3V); | |
1842 | ||
1843 | ||
1844 | //********************* | |
1845 | Handle(Geom_BSplineSurface) L; | |
1846 | Standard_Boolean AlongU = Standard_False, | |
1847 | AlongV = Standard_False; | |
1848 | Standard_Boolean IsOpposite=Standard_False; | |
1849 | Standard_Real signe = 1.; | |
1850 | AlongU = UOsculatingSurface(U,V,IsOpposite,L); | |
1851 | AlongV = VOsculatingSurface(U,V,IsOpposite,L); | |
1852 | if ((AlongV || AlongU) && IsOpposite) signe = -1; | |
1853 | derivatives(MaxOrder,3,U,V,basisSurf,3,3,AlongU,AlongV,L,DerNUV,DerSurf); | |
1854 | ||
1855 | CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); | |
1856 | if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise(); | |
1857 | ||
1858 | ||
1859 | P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); | |
1860 | ||
1861 | D1U = DerSurf(1,0) | |
1862 | + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV); | |
1863 | D1V = DerSurf(0,1) | |
1864 | + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV); | |
1865 | ||
1866 | D2U = basisSurf->DN(U,V,2,0) | |
1867 | + signe * offsetValue * CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV); | |
1868 | D2V = basisSurf->DN(U,V,0,2) | |
1869 | + signe * offsetValue * CSLib::DNNormal(0,2,DerNUV,OrderU,OrderV); | |
1870 | D2UV = basisSurf->DN(U,V,1,1) | |
1871 | + signe * offsetValue * CSLib::DNNormal(1,1,DerNUV,OrderU,OrderV); | |
1872 | D3U = basisSurf->DN(U,V,3,0) | |
1873 | + signe * offsetValue * CSLib::DNNormal(3,0,DerNUV,OrderU,OrderV); | |
1874 | D3V = basisSurf->DN(U,V,0,3) | |
1875 | + signe * offsetValue * CSLib::DNNormal(0,3,DerNUV,OrderU,OrderV); | |
1876 | D3UUV = basisSurf->DN(U,V,2,1) | |
1877 | + signe * offsetValue * CSLib::DNNormal(2,1,DerNUV,OrderU,OrderV); | |
1878 | D3UVV = basisSurf->DN(U,V,1,2) | |
1879 | + signe * offsetValue * CSLib::DNNormal(1,2,DerNUV,OrderU,OrderV); | |
1880 | } | |
1881 | ||
1882 | ||
1883 | //======================================================================= | |
1884 | //function : SetDN | |
1885 | //purpose : | |
1886 | //======================================================================= | |
1887 | ||
1888 | Vec Geom_OffsetSurface::SetDN ( const Standard_Real U , const Standard_Real V, | |
1889 | const Standard_Integer Nu, const Standard_Integer Nv, | |
1890 | const Vec& D1U, const Vec& D1V) const | |
1891 | { | |
1892 | gp_Vec D(0,0,0); | |
1893 | Standard_Real MagTol=0.000000001; | |
1894 | Dir Normal; | |
1895 | CSLib_NormalStatus NStatus; | |
1896 | CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal); | |
1897 | Standard_Integer MaxOrder; | |
1898 | if (NStatus == CSLib_Defined) | |
1899 | MaxOrder=0; | |
1900 | else | |
1901 | MaxOrder=3; | |
1902 | Standard_Integer OrderU,OrderV; | |
1903 | TColgp_Array2OfVec DerNUV(0,MaxOrder+Nu,0,MaxOrder+Nu); | |
1904 | TColgp_Array2OfVec DerSurf(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1); | |
1905 | Standard_Real Umin,Umax,Vmin,Vmax; | |
1906 | Bounds(Umin,Umax,Vmin,Vmax); | |
1907 | ||
1908 | DerSurf.SetValue(1, 0, D1U); | |
1909 | DerSurf.SetValue(0, 1, D1V); | |
1910 | //********************* | |
1911 | Handle(Geom_BSplineSurface) L; | |
1912 | Standard_Boolean AlongU = Standard_False, AlongV = Standard_False; | |
1913 | // Is there any osculatingsurface along U or V; | |
1914 | Standard_Boolean IsOpposite=Standard_False; | |
1915 | Standard_Real signe = 1.; | |
1916 | AlongU = UOsculatingSurface(U,V,IsOpposite,L); | |
1917 | AlongV = VOsculatingSurface(U,V,IsOpposite,L); | |
1918 | if ((AlongV || AlongU) && IsOpposite) signe = -1; | |
1919 | derivatives(MaxOrder,1,U,V,basisSurf,Nu,Nv,AlongU,AlongV,L,DerNUV,DerSurf); | |
1920 | ||
1921 | CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); | |
1922 | if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise(); | |
1923 | ||
1924 | D = basisSurf->DN(U,V,Nu,Nv) | |
1925 | + signe * offsetValue * CSLib::DNNormal(Nu,Nv,DerNUV,OrderU,OrderV); | |
1926 | ||
1927 | return D; | |
1928 | } | |
1929 |