0024177: Eliminate CLang compiler warning -Wlogical-op-parentheses (&& within ||)
[occt.git] / src / Geom / Geom_OffsetSurface.cxx
CommitLineData
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
77typedef Handle(Geom_OffsetCurve) Handle(OffsetCurve);
78typedef Geom_OffsetCurve OffsetCurve;
79typedef Handle(Geom_Curve) Handle(Curve);
80typedef Handle(Geom_Surface) Handle(Surface);
81typedef Handle(Geom_OffsetSurface) Handle(OffsetSurface);
82typedef Geom_OffsetSurface OffsetSurface;
83typedef Handle(Geom_Geometry) Handle(Geometry);
84typedef gp_Dir Dir;
85typedef gp_Vec Vec;
86typedef gp_Pnt Pnt;
87typedef gp_Trsf Trsf;
88typedef gp_XYZ XYZ;
89//=======================================================================
90//function : derivatives
91//purpose :
92//=======================================================================
93
94static 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
212Handle(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
228Geom_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
258void 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
306void Geom_OffsetSurface::SetOffsetValue (const Standard_Real D) {
307
308 offsetValue = D;
309 equivSurf = Surface();
310}
311
312//=======================================================================
313//function : UReverse
314//purpose :
315//=======================================================================
316
317void 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
330Standard_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
341void 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
354Standard_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
364Handle(Surface) Geom_OffsetSurface::BasisSurface () const
365{
366 return basisSurf;
367}
368
369
370//=======================================================================
371//function : Bounds
372//purpose :
373//=======================================================================
374
375void 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
389GeomAbs_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
410void 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
429void 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
458void 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
485void 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
514Vec 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
543void 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
595void 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
706Standard_Real Geom_OffsetSurface::Offset () const {
707
708 return offsetValue;
709}
710
711//=======================================================================
712//function : LocalD0
713//purpose :
714//=======================================================================
715
716void 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
776void 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
838void 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
903void 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
972gp_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//=======================================================================
1036void 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
1106class 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
1125void 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
1147class 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
1166void 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
1196Handle(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
1244void 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
1263Handle(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
1308Standard_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
1320Standard_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
1332Standard_Boolean Geom_OffsetSurface::IsUPeriodic () const
1333{
1334 return basisSurf->IsUPeriodic();
1335}
1336
1337
1338//=======================================================================
1339//function : UPeriod
1340//purpose :
1341//=======================================================================
1342
1343Standard_Real Geom_OffsetSurface::UPeriod() const
1344{
1345 return basisSurf->UPeriod();
1346}
1347
1348
1349//=======================================================================
1350//function : IsVPeriodic
1351//purpose :
1352//=======================================================================
1353
1354Standard_Boolean Geom_OffsetSurface::IsVPeriodic () const
1355{
1356 return basisSurf->IsVPeriodic();
1357}
1358
1359
1360//=======================================================================
1361//function : VPeriod
1362//purpose :
1363//=======================================================================
1364
1365Standard_Real Geom_OffsetSurface::VPeriod() const
1366{
1367 return basisSurf->VPeriod();
1368}
1369
1370
1371//=======================================================================
1372//function : IsUClosed
1373//purpose :
1374//=======================================================================
1375
1376Standard_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
1429Standard_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
1459void 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
1471void Geom_OffsetSurface::TransformParameters(Standard_Real& U,
1472 Standard_Real& V,
1473 const gp_Trsf& T)
1474const
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
1485gp_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//=======================================================================
1496Handle(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
1627Standard_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
1635Standard_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//=======================================================================
1648void 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//=======================================================================/
1695void 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//=======================================================================/
1746void 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//=======================================================================/
1812void 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
1888Vec 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