1 // Created on: 1991-06-25
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified 04/10/96 : JCT : derivee des surfaces offset utilisation de
19 // Modified 15/11/96 : JPI : ajout equivalent surface pour les surfaces canoniques et modif des methodes D0 D1, ... UIso,VIso
20 // Modified 18/11/96 : JPI : inversion de l'offsetValue dans UReverse et Vreverse
22 #include <AdvApprox_ApproxAFunction.hxx>
23 #include <BSplCLib.hxx>
24 #include <BSplSLib.hxx>
25 #include <Convert_GridPolynomialToPoles.hxx>
27 #include <Geom_BezierSurface.hxx>
28 #include <Geom_BSplineCurve.hxx>
29 #include <Geom_BSplineSurface.hxx>
30 #include <Geom_Circle.hxx>
31 #include <Geom_ConicalSurface.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_CylindricalSurface.hxx>
34 #include <Geom_ElementarySurface.hxx>
35 #include <Geom_Ellipse.hxx>
36 #include <Geom_Geometry.hxx>
37 #include <Geom_OffsetCurve.hxx>
38 #include <Geom_OffsetSurface.hxx>
39 #include <Geom_Plane.hxx>
40 #include <Geom_RectangularTrimmedSurface.hxx>
41 #include <Geom_SphericalSurface.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_SurfaceOfLinearExtrusion.hxx>
44 #include <Geom_SurfaceOfRevolution.hxx>
45 #include <Geom_ToroidalSurface.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47 #include <Geom_UndefinedDerivative.hxx>
48 #include <Geom_UndefinedValue.hxx>
49 #include <GeomAbs_CurveType.hxx>
50 #include <GeomAbs_IsoType.hxx>
51 #include <GeomAbs_Shape.hxx>
54 #include <gp_GTrsf2d.hxx>
56 #include <gp_Trsf.hxx>
59 #include <Precision.hxx>
60 #include <Standard_ConstructionError.hxx>
61 #include <Standard_NoSuchObject.hxx>
62 #include <Standard_NotImplemented.hxx>
63 #include <Standard_RangeError.hxx>
64 #include <Standard_Type.hxx>
65 #include <TColgp_Array1OfPnt.hxx>
66 #include <TColgp_Array2OfVec.hxx>
67 #include <TColgp_HArray2OfPnt.hxx>
68 #include <TColStd_Array1OfInteger.hxx>
69 #include <TColStd_Array1OfReal.hxx>
70 #include <TColStd_HArray1OfInteger.hxx>
71 #include <TColStd_HArray1OfReal.hxx>
72 #include <TColStd_HArray2OfInteger.hxx>
74 static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
76 //=======================================================================
77 //function : derivatives
79 //=======================================================================
81 static void derivatives(Standard_Integer MaxOrder,
82 Standard_Integer MinOrder,
83 const Standard_Real U,
84 const Standard_Real V,
85 const Handle(Geom_Surface)& basisSurf,
86 const Standard_Integer Nu,
87 const Standard_Integer Nv,
88 const Standard_Boolean AlongU,
89 const Standard_Boolean AlongV,
90 const Handle(Geom_BSplineSurface)& L,
91 TColgp_Array2OfVec& DerNUV,
92 TColgp_Array2OfVec& DerSurf)
96 gp_Vec DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3UUV, DL3UVV, DL3V;
101 TColgp_Array2OfVec DerSurfL(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1);
105 L->D1(U, V, P, DL1U, DL1V);
106 DerSurfL.SetValue(1, 0, DL1U);
107 DerSurfL.SetValue(0, 1, DL1V);
110 L->D2(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV);
111 DerSurfL.SetValue(1, 0, DL1U);
112 DerSurfL.SetValue(0, 1, DL1V);
113 DerSurfL.SetValue(1, 1, DL2UV);
114 DerSurfL.SetValue(2, 0, DL2U);
115 DerSurfL.SetValue(0, 2, DL2V);
118 L->D3(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3V ,DL3UUV, DL3UVV);
119 DerSurfL.SetValue(1, 0, DL1U);
120 DerSurfL.SetValue(0, 1, DL1V);
121 DerSurfL.SetValue(1, 1, DL2UV);
122 DerSurfL.SetValue(2, 0, DL2U);
123 DerSurfL.SetValue(0, 2, DL2V);
124 DerSurfL.SetValue(3, 0, DL3U);
125 DerSurfL.SetValue(2, 1, DL3UUV);
126 DerSurfL.SetValue(1, 2, DL3UVV);
127 DerSurfL.SetValue(0, 3, DL3V);
135 for(i=0;i<=MaxOrder+1+Nu;i++)
136 for(j=i;j<=MaxOrder+Nv+1;j++)
139 DerSurfL.SetValue(i,j,L->DN(U,V,i,j));
140 DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
141 if (i!=j && j <= Nu+1)
143 DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
144 DerSurfL.SetValue(j,i,L->DN(U,V,j,i));
150 for(j=0;j<=MaxOrder+1+Nv;j++)
151 for(i=j;i<=MaxOrder+Nu+1;i++)
154 DerSurfL.SetValue(i,j,L->DN(U,V,i,j));
155 DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
156 if (i!=j && i <= Nv+1)
158 DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
159 DerSurfL.SetValue(j,i,L->DN(U,V,j,i));
163 for(i=0;i<=MaxOrder+Nu;i++)
164 for(j=0;j<=MaxOrder+Nv;j++)
167 DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurfL,DerSurf));
169 DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf,DerSurfL));
176 for(i=0;i<=MaxOrder+Nu+1;i++)
177 for(j=i;j<=MaxOrder+Nv+1;j++)
181 DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j));
182 if (i!=j) DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i));
184 for(i=0;i<=MaxOrder+Nu;i++)
185 for(j=0;j<=MaxOrder+Nv;j++)
187 DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf));
193 //=======================================================================
196 //=======================================================================
198 Handle(Geom_Geometry) Geom_OffsetSurface::Copy () const
200 Handle(Geom_OffsetSurface) S(new Geom_OffsetSurface(basisSurf, offsetValue, Standard_True));
204 //=======================================================================
205 //function : Geom_OffsetSurface
206 //purpose : Basis surface cannot be an Offset surface or trimmed from
208 //=======================================================================
210 Geom_OffsetSurface::Geom_OffsetSurface (const Handle(Geom_Surface)& theSurf,
211 const Standard_Real theOffset,
212 const Standard_Boolean isNotCheckC0)
213 : offsetValue (theOffset)
215 SetBasisSurface(theSurf, isNotCheckC0);
218 //=======================================================================
219 //function : SetBasisSurface
221 //=======================================================================
223 void Geom_OffsetSurface::SetBasisSurface (const Handle(Geom_Surface)& S,
224 const Standard_Boolean isNotCheckC0)
226 Standard_Real aUf, aUl, aVf, aVl;
227 S->Bounds(aUf, aUl, aVf, aVl);
229 Handle(Geom_Surface) aCheckingSurf = Handle(Geom_Surface)::DownCast(S->Copy());
230 Standard_Boolean isTrimmed = Standard_False;
232 while(aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
233 aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
235 if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
237 Handle(Geom_RectangularTrimmedSurface) aTrimS =
238 Handle(Geom_RectangularTrimmedSurface)::DownCast(aCheckingSurf);
239 aCheckingSurf = aTrimS->BasisSurface();
240 isTrimmed = Standard_True;
243 if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
245 Handle(Geom_OffsetSurface) aOS =
246 Handle(Geom_OffsetSurface)::DownCast(aCheckingSurf);
247 aCheckingSurf = aOS->BasisSurface();
248 offsetValue += aOS->Offset();
252 myBasisSurfContinuity = aCheckingSurf->Continuity();
254 Standard_Boolean isC0 = !isNotCheckC0 && (myBasisSurfContinuity == GeomAbs_C0);
256 // Basis surface must be at least C1
259 Handle(Geom_Curve) aCurve;
261 if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)))
263 Handle(Geom_SurfaceOfRevolution) aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aCheckingSurf);
264 aCurve = aRevSurf->BasisCurve();
266 else if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)))
268 Handle(Geom_SurfaceOfLinearExtrusion) aLESurf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aCheckingSurf);
269 aCurve = aLESurf->BasisCurve();
274 while(aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ||
275 aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
277 if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
279 Handle(Geom_TrimmedCurve) aTrimC =
280 Handle(Geom_TrimmedCurve)::DownCast(aCurve);
281 aCurve = aTrimC->BasisCurve();
284 if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
286 Handle(Geom_OffsetCurve) aOC =
287 Handle(Geom_OffsetCurve)::DownCast(aCurve);
288 aCurve = aOC->BasisCurve();
293 const Standard_Real aUIsoPar = (aUf + aUl)/2.0, aVIsoPar = (aVf + aVl)/2.0;
294 Standard_Boolean isUG1 = Standard_False, isVG1 = Standard_False;
296 const Handle(Geom_Curve) aCurv1 = aCurve.IsNull() ? aCheckingSurf->UIso(aUIsoPar) : aCurve;
297 const Handle(Geom_Curve) aCurv2 = aCheckingSurf->VIso(aVIsoPar);
298 isUG1 = !aCurv1->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
299 isVG1 = !aCurv2->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
303 Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv1);
304 isUG1 = aBC->IsG1(aVf, aVl, MyAngularToleranceForG1);
309 Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv2);
310 isVG1 = aBC->IsG1(aUf, aUl, MyAngularToleranceForG1);
315 myBasisSurfContinuity = GeomAbs_G1;
316 isC0 = Standard_False;
319 // Raise exception if still C0
321 Standard_ConstructionError::Raise("Offset with no C1 Surface");
327 new Geom_RectangularTrimmedSurface(aCheckingSurf, aUf, aUl, aVf, aVl);
331 basisSurf = aCheckingSurf;
334 equivSurf = Surface();
336 // Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur
337 // et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso
338 // et aussi pour les singularite. Pour les surfaces osculatrices, on l'utilise pour
339 // detecter si une iso est degeneree.
340 const Standard_Real Tol = Precision::Confusion(); //0.0001;
341 myOscSurf.Init(basisSurf,Tol);
344 //=======================================================================
345 //function : SetOffsetValue
347 //=======================================================================
349 void Geom_OffsetSurface::SetOffsetValue (const Standard_Real D)
352 equivSurf = Surface();
355 //=======================================================================
356 //function : UReverse
358 //=======================================================================
360 void Geom_OffsetSurface::UReverse ()
362 basisSurf->UReverse();
363 offsetValue = -offsetValue;
364 if(!equivSurf.IsNull()) equivSurf->UReverse();
367 //=======================================================================
368 //function : UReversedParameter
370 //=======================================================================
372 Standard_Real Geom_OffsetSurface::UReversedParameter(const Standard_Real U) const
374 return basisSurf->UReversedParameter(U);
377 //=======================================================================
378 //function : VReverse
380 //=======================================================================
382 void Geom_OffsetSurface::VReverse ()
384 basisSurf->VReverse();
385 offsetValue = -offsetValue;
386 if(!equivSurf.IsNull()) equivSurf->VReverse();
389 //=======================================================================
390 //function : VReversedParameter
392 //=======================================================================
394 Standard_Real Geom_OffsetSurface::VReversedParameter(const Standard_Real V) const
396 return basisSurf->VReversedParameter(V);
399 //=======================================================================
402 //=======================================================================
404 void Geom_OffsetSurface::Bounds (Standard_Real& U1, Standard_Real& U2,
405 Standard_Real& V1, Standard_Real& V2) const
407 basisSurf->Bounds (U1, U2 ,V1, V2);
410 //=======================================================================
411 //function : Continuity
413 //=======================================================================
415 GeomAbs_Shape Geom_OffsetSurface::Continuity () const
417 switch (myBasisSurfContinuity) {
418 case GeomAbs_C2 : return GeomAbs_C1;
419 case GeomAbs_C3 : return GeomAbs_C2;
420 case GeomAbs_CN : return GeomAbs_CN;
426 //=======================================================================
429 //=======================================================================
431 void Geom_OffsetSurface::D0 (const Standard_Real U, const Standard_Real V, gp_Pnt& P) const
435 if (myBasisSurfContinuity == GeomAbs_C0)
436 Geom_UndefinedValue::Raise();
438 if (equivSurf.IsNull()){
439 basisSurf->D1(U, V, P, D1U, D1V);
440 SetD0(U,V,P,D1U,D1V);
443 equivSurf->D0(U,V,P);
446 //=======================================================================
449 //=======================================================================
451 void Geom_OffsetSurface::D1 (const Standard_Real U, const Standard_Real V,
453 gp_Vec& D1U, gp_Vec& D1V) const
456 if (myBasisSurfContinuity == GeomAbs_C0 ||
457 myBasisSurfContinuity == GeomAbs_C1)
458 Geom_UndefinedDerivative::Raise();
460 if (equivSurf.IsNull())
462 gp_Vec d2u, d2v, d2uv;
463 basisSurf->D2(U, V, P, D1U, D1V, d2u, d2v, d2uv);
464 SetD1(U,V,P,D1U,D1V,d2u,d2v,d2uv);
467 equivSurf->D1(U,V,P,D1U,D1V);
470 //=======================================================================
473 //=======================================================================
475 void Geom_OffsetSurface::D2 (const Standard_Real U, const Standard_Real V,
477 gp_Vec& D1U, gp_Vec& D1V,
478 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const
481 if (myBasisSurfContinuity == GeomAbs_C0 ||
482 myBasisSurfContinuity == GeomAbs_C1 ||
483 myBasisSurfContinuity == GeomAbs_C2)
484 Geom_UndefinedDerivative::Raise();
486 if (equivSurf.IsNull())
488 gp_Vec d3u, d3uuv, d3uvv, d3v;
489 basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, d3u, d3v, d3uuv, d3uvv);
490 SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,d3u,d3v,d3uuv,d3uvv);
493 equivSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
496 //=======================================================================
499 //=======================================================================
501 void Geom_OffsetSurface::D3 (const Standard_Real U, const Standard_Real V,
503 gp_Vec& D1U, gp_Vec& D1V,
504 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
505 gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const
508 if (!(basisSurf->IsCNu (4) && basisSurf->IsCNv (4))) {
509 Geom_UndefinedDerivative::Raise();
512 if (equivSurf.IsNull())
514 basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV);
515 SetD3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV);
518 equivSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
521 //=======================================================================
524 //=======================================================================
526 gp_Vec Geom_OffsetSurface::DN (const Standard_Real U, const Standard_Real V,
527 const Standard_Integer Nu, const Standard_Integer Nv) const
529 Standard_RangeError_Raise_if (Nu < 0 || Nv < 0 || Nu + Nv < 1, " ");
531 if (!(basisSurf->IsCNu (Nu) && basisSurf->IsCNv (Nv))) {
532 Geom_UndefinedDerivative::Raise();
537 if (equivSurf.IsNull())
541 basisSurf->D1 (U, V, P, D1U, D1V);
543 D = SetDN(U,V,Nu,Nv,D1U,D1V);
546 D = equivSurf->DN(U,V,Nu,Nv);
550 //=======================================================================
553 //=======================================================================
555 void Geom_OffsetSurface::D1
556 (const Standard_Real U, const Standard_Real V,
557 gp_Pnt& P, gp_Pnt& Pbasis,
558 gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D1Ubasis, gp_Vec& D1Vbasis,
559 gp_Vec& D2Ubasis, gp_Vec& D2Vbasis, gp_Vec& D2UVbasis) const
561 const GeomAbs_Shape basisCont = basisSurf->Continuity();
562 if (basisCont == GeomAbs_C0 || basisCont == GeomAbs_C1)
563 Geom_UndefinedDerivative::Raise();
564 basisSurf->D2 (U, V, Pbasis, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, D2UVbasis);
565 gp_Vec Ndir = D1Ubasis.Crossed (D1Vbasis);
566 const Standard_Real R2 = Ndir.SquareMagnitude();
567 const Standard_Real R = Sqrt (R2);
568 const Standard_Real R3 = R * R2;
569 gp_Vec DUNdir = D2Ubasis.Crossed (D1Vbasis);
570 DUNdir.Add (D1Ubasis.Crossed (D2UVbasis));
571 gp_Vec DVNdir = D2UVbasis.Crossed (D1Vbasis);
572 DVNdir.Add (D1Ubasis.Crossed (D2Vbasis));
573 const Standard_Real DRu = Ndir.Dot (DUNdir);
574 const Standard_Real DRv = Ndir.Dot (DVNdir);
575 if (R3 <= gp::Resolution()) {
576 if (R2 <= gp::Resolution())
577 Geom_UndefinedDerivative::Raise();
579 DUNdir.Subtract (Ndir.Multiplied (DRu/R));
580 DUNdir.Multiply (offsetValue/R2);
581 D1U = D1Ubasis.Added (DUNdir);
583 DVNdir.Subtract (Ndir.Multiplied (DRv/R));
584 DVNdir.Multiply (offsetValue/R2);
585 D1V = D1Vbasis.Added (DVNdir);
588 DUNdir.Multiply (offsetValue / R);
589 DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3));
590 D1U = D1Ubasis.Added (DUNdir);
591 DVNdir.Multiply (offsetValue / R);
592 DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3));
593 D1V = D1Vbasis.Added (DVNdir);
595 Ndir.Multiply (offsetValue/R);
596 P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ()));
599 //=======================================================================
602 //=======================================================================
604 void Geom_OffsetSurface::D2
605 (const Standard_Real U, const Standard_Real V,
606 gp_Pnt& P, gp_Pnt& Pbasis,
607 gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
608 gp_Vec& D1Ubasis, gp_Vec& D1Vbasis,
609 gp_Vec& D2Ubasis, gp_Vec& D2Vbasis, gp_Vec& D2UVbasis,
610 gp_Vec& D3Ubasis, gp_Vec& D3Vbasis, gp_Vec& D3UUVbasis, gp_Vec& D3UVVbasis) const
612 const GeomAbs_Shape basisCont = basisSurf->Continuity();
613 if (basisCont == GeomAbs_C0 || basisCont == GeomAbs_C1 || basisCont == GeomAbs_C2)
614 Geom_UndefinedDerivative::Raise();
615 basisSurf->D3 (U, V, P, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, D2UVbasis, D3Ubasis, D3Vbasis, D3UUVbasis, D3UVVbasis);
616 gp_Vec Ndir = D1Ubasis.Crossed (D1Vbasis);
617 const Standard_Real R2 = Ndir.SquareMagnitude();
618 const Standard_Real R = Sqrt (R2);
619 const Standard_Real R3 = R2 * R;
620 const Standard_Real R4 = R2 * R2;
621 const Standard_Real R5 = R3 * R2;
622 gp_Vec DUNdir = D2Ubasis.Crossed (D1Vbasis);
623 DUNdir.Add (D1Ubasis.Crossed (D2UVbasis));
624 gp_Vec DVNdir = D2UVbasis.Crossed (D1Vbasis);
625 DVNdir.Add (D1Ubasis.Crossed (D2Vbasis));
626 const Standard_Real DRu = Ndir.Dot (DUNdir);
627 const Standard_Real DRv = Ndir.Dot (DVNdir);
628 gp_Vec D2UNdir = D3Ubasis.Crossed (D1Vbasis);
629 D2UNdir.Add (D1Ubasis.Crossed (D3UUVbasis));
630 D2UNdir.Add (2.0 * (D2Ubasis.Crossed (D2UVbasis)));
631 gp_Vec D2VNdir = D3UVVbasis.Crossed (D1Vbasis);
632 D2VNdir.Add (D1Ubasis.Crossed (D3Vbasis));
633 D2VNdir.Add (2.0 * (D2UVbasis.Crossed (D2Vbasis)));
634 gp_Vec D2UVNdir = D2UVbasis.Crossed (D1Vbasis);
635 D2UVNdir.Add (D1Ubasis.Crossed (D3UVVbasis));
636 D2UVNdir.Add (D2Ubasis.Crossed (D2Vbasis));
637 const Standard_Real D2Ru = Ndir.Dot (D2UNdir) + DUNdir.Dot (DUNdir);
638 const Standard_Real D2Rv = Ndir.Dot (D2VNdir) + DVNdir.Dot (DVNdir);
639 const Standard_Real D2Ruv = DVNdir.Dot (DUNdir) + Ndir.Dot (D2UVNdir);
641 if (R5 <= gp::Resolution()) {
642 //We try another computation but the stability is not very good
644 if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
646 // Standard_Real R4 = R2 * R2;
647 D2UNdir.Subtract (DUNdir.Multiplied (2.0 * DRu / R2));
648 D2UNdir.Subtract (Ndir.Multiplied (D2Ru/R2));
649 D2UNdir.Add (Ndir.Multiplied (3.0 * DRu * DRu / R4));
650 D2UNdir.Multiply (offsetValue / R);
651 D2U = D2Ubasis.Added (D2UNdir);
652 D2VNdir.Subtract (DVNdir.Multiplied (2.0 * DRv / R2));
653 D2VNdir.Subtract (Ndir.Multiplied (D2Rv/R2));
654 D2VNdir.Add (Ndir.Multiplied (3.0 * DRv * DRv / R4));
655 D2VNdir.Multiply (offsetValue / R);
656 D2V = D2Vbasis.Added (D2VNdir);
658 D2UVNdir.Subtract (DUNdir.Multiplied (DRv / R2));
659 D2UVNdir.Subtract (DVNdir.Multiplied (DRu / R2));
660 D2UVNdir.Subtract (Ndir.Multiplied (D2Ruv / R2));
661 D2UVNdir.Add (Ndir.Multiplied (3.0 * DRu * DRv / R4));
662 D2UVNdir.Multiply (offsetValue / R);
663 D2UV = D2UVbasis.Added (D2UVNdir);
666 DUNdir.Subtract (Ndir.Multiplied (DRu/R));
667 DUNdir.Multiply (offsetValue/R2);
668 D1U = D1Ubasis.Added (DUNdir);
670 DVNdir.Subtract (Ndir.Multiplied (DRv/R));
671 DVNdir.Multiply (offsetValue/R2);
672 D1V = D1Vbasis.Added (DVNdir);
675 D2UNdir.Multiply (offsetValue/R);
676 D2UNdir.Subtract (DUNdir.Multiplied (2.0 * offsetValue * DRu / R3));
677 D2UNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ru / R3));
678 D2UNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRu * DRu / R5));
679 D2U = D2Ubasis.Added (D2UNdir);
681 D2VNdir.Multiply (offsetValue/R);
682 D2VNdir.Subtract (DVNdir.Multiplied (2.0 * offsetValue * DRv / R3));
683 D2VNdir.Subtract (Ndir.Multiplied (offsetValue * D2Rv / R3));
684 D2VNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRv * DRv / R5));
685 D2V = D2Vbasis.Added (D2VNdir);
687 D2UVNdir.Multiply (offsetValue/R);
688 D2UVNdir.Subtract (DUNdir.Multiplied (offsetValue * DRv / R3));
689 D2UVNdir.Subtract (DVNdir.Multiplied (offsetValue * DRu / R3));
690 D2UVNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ruv / R3));
691 D2UVNdir.Add (Ndir.Multiplied (3.0 * offsetValue * DRu * DRv / R5));
692 D2UV = D2UVbasis.Added (D2UVNdir);
694 DUNdir.Multiply (offsetValue / R);
695 DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3));
696 D1U = D1Ubasis.Added (DUNdir);
697 DVNdir.Multiply (offsetValue / R);
698 DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3));
699 D1V = D1Vbasis.Added (DVNdir);
701 Ndir.Multiply (offsetValue/R);
702 P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ()));
705 //=======================================================================
708 //=======================================================================
710 void Geom_OffsetSurface::LocalD0 (const Standard_Real U, const Standard_Real V,
711 const Standard_Integer USide, const Standard_Integer VSide,
714 if (equivSurf.IsNull()) {
716 Handle(Geom_Surface) Basis = basisSurf;
718 // if Basis is Trimmed we take the basis's basis
719 Handle(Geom_RectangularTrimmedSurface) RTS =
720 Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis);
722 Basis = RTS->BasisSurface();
725 Handle(Geom_BSplineSurface) BSplS =
726 Handle(Geom_BSplineSurface)::DownCast(Basis);
727 if (!BSplS.IsNull()) {
728 gp_Vec D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV;
729 LocateSides(U,V,USide,VSide,BSplS,1,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
730 SetD0(U,V,P,D1U,D1V);
735 Handle( Geom_SurfaceOfLinearExtrusion) SE =
736 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis);
738 SE->LocalD1(U,V,USide,P,D1U,D1V);
739 SetD0(U,V,P,D1U,D1V);
744 Handle(Geom_SurfaceOfRevolution) SR =
745 Handle(Geom_SurfaceOfRevolution)::DownCast(Basis);
747 SR->LocalD1(U,V,VSide,P,D1U,D1V);
748 SetD0(U,V,P,D1U,D1V);
753 basisSurf->D1(U, V, P, D1U, D1V);
754 SetD0(U,V,P,D1U,D1V);
757 equivSurf-> D0(U,V,P);
760 //=======================================================================
763 //=======================================================================
765 void Geom_OffsetSurface::LocalD1 (const Standard_Real U, const Standard_Real V,
766 const Standard_Integer USide, const Standard_Integer VSide,
768 gp_Vec& D1U, gp_Vec& D1V) const
770 if (equivSurf.IsNull()) {
771 gp_Vec D2U,D2V,D2UV ;
772 Handle(Geom_Surface) Basis = basisSurf;
774 // if Basis is Trimmed we take the basis's basis
775 Handle(Geom_RectangularTrimmedSurface) RTS =
776 Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis);
778 Basis = RTS->BasisSurface();
781 Handle(Geom_BSplineSurface) BSplS =
782 Handle(Geom_BSplineSurface)::DownCast(Basis);
783 if (!BSplS.IsNull()) {
784 gp_Vec D3U,D3V,D3UUV,D3UVV;
785 LocateSides(U,V,USide,VSide,BSplS,2,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
786 SetD1(U,V,P,D1U,D1V,D2U,D2V,D2UV);
791 Handle( Geom_SurfaceOfLinearExtrusion) SE =
792 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis);
794 SE->LocalD2(U,V,USide,P,D1U,D1V,D2U,D2V,D2UV);
795 SetD1(U,V,P,D1U,D1V,D2U,D2V,D2UV);
800 Handle(Geom_SurfaceOfRevolution) SR =
801 Handle(Geom_SurfaceOfRevolution)::DownCast(Basis);
803 SR->LocalD2(U,V,VSide,P,D1U,D1V,D2U,D2V,D2UV);
804 SetD1(U,V,P,D1U,D1V,D2U,D2V,D2UV);
809 basisSurf->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
810 SetD1(U,V,P,D1U,D1V,D2U,D2V,D2UV);
813 equivSurf->D1(U,V,P,D1U,D1V);
816 //=======================================================================
819 //=======================================================================
821 void Geom_OffsetSurface::LocalD2 (const Standard_Real U, const Standard_Real V,
822 const Standard_Integer USide, const Standard_Integer VSide,
824 gp_Vec& D1U, gp_Vec& D1V,
825 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const
827 if (equivSurf.IsNull()) {
828 Handle(Geom_Surface) Basis = basisSurf;
829 gp_Vec D3U,D3V,D3UUV,D3UVV;
831 // if Basis is Trimmed we take the basis's basis
832 Handle(Geom_RectangularTrimmedSurface) RTS =
833 Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis);
835 Basis = RTS->BasisSurface();
838 Handle(Geom_BSplineSurface) BSplS =
839 Handle(Geom_BSplineSurface)::DownCast(Basis);
840 if (!BSplS.IsNull()) {
841 LocateSides(U,V,USide,VSide,BSplS,3,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
842 SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
847 Handle(Geom_SurfaceOfLinearExtrusion) SE =
848 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis);
850 SE->LocalD3(U,V,USide,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
851 SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
856 Handle(Geom_SurfaceOfRevolution) SR =
857 Handle(Geom_SurfaceOfRevolution)::DownCast(Basis);
859 SR->LocalD3(U,V,VSide,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
860 SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
865 basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV);
866 SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
869 equivSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
872 //=======================================================================
875 //=======================================================================
877 void Geom_OffsetSurface::LocalD3 (const Standard_Real U, const Standard_Real V,
878 const Standard_Integer USide, const Standard_Integer VSide,
880 gp_Vec& D1U, gp_Vec& D1V,
881 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
882 gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const
884 if (equivSurf.IsNull()) {
885 Handle(Geom_Surface) Basis = basisSurf;
887 // if Basis is Trimmed we take the basis's basis
888 Handle(Geom_RectangularTrimmedSurface) RTS =
889 Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis);
891 Basis = RTS->BasisSurface();
894 Handle(Geom_BSplineSurface) BSplS =
895 Handle(Geom_BSplineSurface)::DownCast(Basis);
896 if (!BSplS.IsNull()) {
897 LocateSides(U,V,USide,VSide,BSplS,3,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
898 SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
903 Handle(Geom_SurfaceOfLinearExtrusion) SE =
904 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis);
906 SE->LocalD3(U,V,USide,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
907 SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
912 Handle(Geom_SurfaceOfRevolution) SR =
913 Handle(Geom_SurfaceOfRevolution)::DownCast(Basis);
915 SR->LocalD3(U,V,VSide,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
916 SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
921 basisSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
922 SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
925 equivSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
928 //=======================================================================
931 //=======================================================================
933 gp_Vec Geom_OffsetSurface::LocalDN (const Standard_Real U, const Standard_Real V,
934 const Standard_Integer USide, const Standard_Integer VSide,
935 const Standard_Integer Nu, const Standard_Integer Nv) const
937 if(equivSurf.IsNull()) {
939 gp_Vec D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV;
941 Handle(Geom_Surface) Basis = basisSurf;
943 // if Basis is Trimmed we make the basis`s basis
944 Handle(Geom_RectangularTrimmedSurface) RTS =
945 Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis);
947 Basis = RTS -> BasisSurface();
950 Handle(Geom_BSplineSurface) BSplS =
951 Handle(Geom_BSplineSurface)::DownCast(Basis);
952 if(!BSplS.IsNull()) {
953 LocateSides(U,V,USide,VSide,BSplS,1,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
954 return SetDN(U,V,Nu,Nv,D1U,D1V);
958 Handle( Geom_SurfaceOfLinearExtrusion) SE =
959 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis);
961 SE->LocalD1(U,V,USide,P,D1U,D1V);
962 return SetDN(U,V,Nu,Nv,D1U,D1V);
966 Handle(Geom_SurfaceOfRevolution) SR =
967 Handle(Geom_SurfaceOfRevolution)::DownCast(Basis);
969 SR->LocalDN(U,V,VSide,Nu,Nv);
970 return SetDN(U,V,Nu,Nv,D1U,D1V);
974 basisSurf->DN(U,V,Nu,Nv);
975 return SetDN(U,V,Nu,Nv,D1U,D1V);
978 return equivSurf->DN(U,V,Nu,Nv);
981 //=======================================================================
982 //function : LocateSides
984 //=======================================================================
986 void Geom_OffsetSurface::LocateSides(const Standard_Real U, const Standard_Real V,
987 const Standard_Integer USide, const Standard_Integer VSide,
988 const Handle(Geom_BSplineSurface)& BSplS,
989 const Standard_Integer NDir,
991 gp_Vec& D1U,gp_Vec& D1V,
992 gp_Vec& D2U,gp_Vec& D2V,gp_Vec& D2UV,
993 gp_Vec& D3U,gp_Vec& D3V,gp_Vec& D3UUV,gp_Vec& D3UVV) const
995 Standard_Boolean UIsKnot=Standard_False, VIsKnot=Standard_False;
996 Standard_Integer Ideb, Ifin, IVdeb, IVfin;
997 const Standard_Real ParTol=Precision::PConfusion()/10.;
998 BSplS->Geom_BSplineSurface::LocateU(U,ParTol,Ideb, Ifin, Standard_False);
999 BSplS->Geom_BSplineSurface::LocateV(V,ParTol,IVdeb,IVfin,Standard_False);
1001 if(Ideb == Ifin ) { //knot
1003 if(USide == 1) {Ifin++; UIsKnot=Standard_True;}
1004 else if(USide == -1) {Ideb--; UIsKnot=Standard_True;}
1005 else {Ideb--; Ifin++;} //USide == 0
1009 if(Ideb < BSplS->FirstUKnotIndex()) {Ideb = BSplS->FirstUKnotIndex(); Ifin = Ideb + 1;}
1011 if(Ifin > BSplS->LastUKnotIndex()) {Ifin = BSplS->LastUKnotIndex(); Ideb = Ifin - 1;}
1013 if(IVdeb == IVfin ) { //knot
1015 if(VSide == 1) {IVfin++; VIsKnot=Standard_True;}
1016 else if(VSide == -1) {IVdeb--; VIsKnot=Standard_True;}
1017 else {IVdeb--; IVfin++;} //VSide == 0
1021 if(IVdeb < BSplS->FirstVKnotIndex()) {IVdeb = BSplS->FirstVKnotIndex(); IVfin = IVdeb + 1;}
1023 if(IVfin > BSplS->LastVKnotIndex()) {IVfin = BSplS->LastVKnotIndex(); IVdeb = IVfin - 1;}
1025 if((UIsKnot)||(VIsKnot))
1028 case 0 : BSplS->Geom_BSplineSurface::LocalD0(U,V,Ideb,Ifin,IVdeb,IVfin,P); break;
1029 case 1 : BSplS->Geom_BSplineSurface::LocalD1(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V); break;
1030 case 2 : BSplS->Geom_BSplineSurface::LocalD2(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV); break;
1031 case 3 : BSplS->Geom_BSplineSurface::LocalD3(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break;
1036 case 0 : basisSurf->D0(U,V,P); break;
1037 case 1 : basisSurf->D1(U,V,P,D1U,D1V); break;
1038 case 2 : basisSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); break;
1039 case 3 : basisSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break;
1043 ////*************************************************
1045 //// EVALUATOR FOR THE ISO-CURVE APPROXIMATION
1047 ////*************************************************
1049 class Geom_OffsetSurface_UIsoEvaluator : public AdvApprox_EvaluatorFunction
1052 Geom_OffsetSurface_UIsoEvaluator (const Handle(Geom_Surface)& theSurface, const Standard_Real theU)
1053 : CurrentSurface(theSurface), IsoPar(theU) {}
1055 virtual void Evaluate (Standard_Integer *Dimension,
1056 Standard_Real StartEnd[2],
1057 Standard_Real *Parameter,
1058 Standard_Integer *DerivativeRequest,
1059 Standard_Real *Result, // [Dimension]
1060 Standard_Integer *ErrorCode);
1063 Handle(Geom_Surface) CurrentSurface;
1064 Standard_Real IsoPar;
1067 void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/
1068 Standard_Real /*StartEnd*/[2],
1069 Standard_Real *Parameter,
1070 Standard_Integer *DerivativeRequest,
1071 Standard_Real *Result,
1072 Standard_Integer *ReturnCode)
1075 if (*DerivativeRequest == 0) {
1076 P = CurrentSurface->Value(IsoPar,*Parameter);
1083 CurrentSurface->D1(IsoPar,*Parameter,P,DU,DV);
1091 class Geom_OffsetSurface_VIsoEvaluator : public AdvApprox_EvaluatorFunction
1094 Geom_OffsetSurface_VIsoEvaluator (const Handle(Geom_Surface)& theSurface, const Standard_Real theV)
1095 : CurrentSurface(theSurface), IsoPar(theV) {}
1097 virtual void Evaluate (Standard_Integer *Dimension,
1098 Standard_Real StartEnd[2],
1099 Standard_Real *Parameter,
1100 Standard_Integer *DerivativeRequest,
1101 Standard_Real *Result, // [Dimension]
1102 Standard_Integer *ErrorCode);
1105 Handle(Geom_Surface) CurrentSurface;
1106 Standard_Real IsoPar;
1109 void Geom_OffsetSurface_VIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/
1110 Standard_Real /*StartEnd*/[2],
1111 Standard_Real *Parameter,
1112 Standard_Integer *DerivativeRequest,
1113 Standard_Real *Result,
1114 Standard_Integer *ReturnCode)
1117 if (*DerivativeRequest == 0) {
1118 P = CurrentSurface->Value(*Parameter,IsoPar);
1125 CurrentSurface->D1(*Parameter,IsoPar,P,DU,DV);
1133 //=======================================================================
1135 //purpose : The Uiso or the VIso of an OffsetSurface can't be clearly
1136 // exprimed as a curve from Geom. So, to extract the U or VIso
1137 // an Approximation is needed. This approx always will return a
1138 // BSplineCurve from Geom.
1139 //=======================================================================
1141 Handle(Geom_Curve) Geom_OffsetSurface::UIso (const Standard_Real UU) const
1143 if (equivSurf.IsNull()) {
1144 const Standard_Integer Num1 = 0, Num2 = 0, Num3 = 1;
1145 Handle(TColStd_HArray1OfReal) T1, T2, T3 = new TColStd_HArray1OfReal(1,Num3);
1146 T3->Init(Precision::Approximation());
1147 Standard_Real U1,U2,V1,V2;
1148 Bounds(U1,U2,V1,V2);
1149 const GeomAbs_Shape Cont = GeomAbs_C1;
1150 const Standard_Integer MaxSeg = 100, MaxDeg = 14;
1152 Handle(Geom_OffsetSurface) me (this);
1153 Geom_OffsetSurface_UIsoEvaluator ev (me, UU);
1154 AdvApprox_ApproxAFunction Approx(Num1, Num2, Num3, T1, T2, T3,
1155 V1, V2, Cont, MaxDeg, MaxSeg, ev);
1157 Standard_ConstructionError_Raise_if (!Approx.IsDone(), " Geom_OffsetSurface : UIso");
1159 const Standard_Integer NbPoles = Approx.NbPoles();
1161 TColgp_Array1OfPnt Poles( 1, NbPoles);
1162 TColStd_Array1OfReal Knots( 1, Approx.NbKnots());
1163 TColStd_Array1OfInteger Mults( 1, Approx.NbKnots());
1165 Approx.Poles(1, Poles);
1166 Knots = Approx.Knots()->Array1();
1167 Mults = Approx.Multiplicities()->Array1();
1169 Handle(Geom_BSplineCurve) C =
1170 new Geom_BSplineCurve( Poles, Knots, Mults, Approx.Degree());
1174 return equivSurf->UIso(UU);
1177 //=======================================================================
1180 //=======================================================================
1182 void Geom_OffsetSurface::Value
1183 (const Standard_Real U, const Standard_Real V,
1184 gp_Pnt& P, gp_Pnt& ,
1185 gp_Vec& D1Ubasis, gp_Vec& D1Vbasis) const
1187 if (myBasisSurfContinuity == GeomAbs_C0)
1188 Geom_UndefinedValue::Raise();
1190 SetD0(U,V,P,D1Ubasis,D1Vbasis);
1193 //=======================================================================
1196 //=======================================================================
1198 Handle(Geom_Curve) Geom_OffsetSurface::VIso (const Standard_Real VV) const
1200 if (equivSurf.IsNull()) {
1201 const Standard_Integer Num1 = 0, Num2 = 0, Num3 = 1;
1202 Handle(TColStd_HArray1OfReal) T1, T2, T3 = new TColStd_HArray1OfReal(1,Num3);
1203 T3->Init(Precision::Approximation());
1204 Standard_Real U1,U2,V1,V2;
1205 Bounds(U1,U2,V1,V2);
1206 const GeomAbs_Shape Cont = GeomAbs_C1;
1207 const Standard_Integer MaxSeg = 100, MaxDeg = 14;
1209 Handle(Geom_OffsetSurface) me (this);
1210 Geom_OffsetSurface_VIsoEvaluator ev (me, VV);
1211 AdvApprox_ApproxAFunction Approx (Num1, Num2, Num3, T1, T2, T3,
1212 U1, U2, Cont, MaxDeg, MaxSeg, ev);
1214 Standard_ConstructionError_Raise_if (!Approx.IsDone(), " Geom_OffsetSurface : VIso");
1216 TColgp_Array1OfPnt Poles( 1, Approx.NbPoles());
1217 TColStd_Array1OfReal Knots( 1, Approx.NbKnots());
1218 TColStd_Array1OfInteger Mults( 1, Approx.NbKnots());
1220 Approx.Poles(1, Poles);
1221 Knots = Approx.Knots()->Array1();
1222 Mults = Approx.Multiplicities()->Array1();
1224 Handle(Geom_BSplineCurve) C =
1225 new Geom_BSplineCurve( Poles, Knots, Mults, Approx.Degree());
1229 return equivSurf->VIso(VV);
1232 //=======================================================================
1235 //=======================================================================
1237 Standard_Boolean Geom_OffsetSurface::IsCNu (const Standard_Integer N) const
1239 Standard_RangeError_Raise_if (N < 0, " ");
1240 return basisSurf->IsCNu (N+1);
1243 //=======================================================================
1246 //=======================================================================
1248 Standard_Boolean Geom_OffsetSurface::IsCNv (const Standard_Integer N) const
1250 Standard_RangeError_Raise_if (N < 0, " ");
1251 return basisSurf->IsCNv (N+1);
1254 //=======================================================================
1255 //function : IsUPeriodic
1257 //=======================================================================
1259 Standard_Boolean Geom_OffsetSurface::IsUPeriodic () const
1261 return basisSurf->IsUPeriodic();
1264 //=======================================================================
1265 //function : UPeriod
1267 //=======================================================================
1269 Standard_Real Geom_OffsetSurface::UPeriod() const
1271 return basisSurf->UPeriod();
1274 //=======================================================================
1275 //function : IsVPeriodic
1277 //=======================================================================
1279 Standard_Boolean Geom_OffsetSurface::IsVPeriodic () const
1281 return basisSurf->IsVPeriodic();
1284 //=======================================================================
1285 //function : VPeriod
1287 //=======================================================================
1289 Standard_Real Geom_OffsetSurface::VPeriod() const
1291 return basisSurf->VPeriod();
1294 //=======================================================================
1295 //function : IsUClosed
1297 //=======================================================================
1299 Standard_Boolean Geom_OffsetSurface::IsUClosed () const
1301 Standard_Boolean UClosed;
1302 Handle(Geom_Surface) SBasis = BasisSurface();
1304 if (SBasis->IsKind (STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1305 Handle(Geom_RectangularTrimmedSurface) St =
1306 Handle(Geom_RectangularTrimmedSurface)::DownCast(SBasis);
1308 Handle(Geom_Surface) S = Handle(Geom_Surface)::DownCast(St->BasisSurface());
1309 if (S->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
1310 UClosed = SBasis->IsUClosed();
1312 else if (S->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
1313 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
1314 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S);
1316 Handle(Geom_Curve) C = Extru->BasisCurve();
1317 if (C->IsKind (STANDARD_TYPE(Geom_Circle)) || C->IsKind (STANDARD_TYPE(Geom_Ellipse))) {
1318 UClosed = SBasis->IsUClosed();
1320 else { UClosed = Standard_False; }
1322 else if (S->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
1323 UClosed = SBasis->IsUClosed();
1325 else { UClosed = Standard_False; }
1328 if (SBasis->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
1329 UClosed = SBasis->IsUClosed();
1331 else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
1332 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
1333 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SBasis);
1335 Handle(Geom_Curve) C = Extru->BasisCurve();
1336 UClosed = (C->IsKind(STANDARD_TYPE(Geom_Circle)) || C->IsKind(STANDARD_TYPE(Geom_Ellipse)));
1338 else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
1339 UClosed = Standard_True;
1341 else { UClosed = Standard_False; }
1346 //=======================================================================
1347 //function : IsVClosed
1349 //=======================================================================
1351 Standard_Boolean Geom_OffsetSurface::IsVClosed () const
1353 Standard_Boolean VClosed;
1354 Handle(Geom_Surface) SBasis = BasisSurface();
1356 if (SBasis->IsKind (STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1357 Handle(Geom_RectangularTrimmedSurface) St =
1358 Handle(Geom_RectangularTrimmedSurface)::DownCast(SBasis);
1360 Handle(Geom_Surface) S = Handle(Geom_Surface)::DownCast(St->BasisSurface());
1361 if (S->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
1362 VClosed = SBasis->IsVClosed();
1364 else { VClosed = Standard_False; }
1367 if (SBasis->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
1368 VClosed = SBasis->IsVClosed();
1370 else { VClosed = Standard_False; }
1375 //=======================================================================
1376 //function : Transform
1378 //=======================================================================
1380 void Geom_OffsetSurface::Transform (const gp_Trsf& T)
1382 basisSurf->Transform (T);
1383 offsetValue *= T.ScaleFactor();
1384 equivSurf.Nullify();
1387 //=======================================================================
1388 //function : TransformParameters
1390 //=======================================================================
1392 void Geom_OffsetSurface::TransformParameters(Standard_Real& U, Standard_Real& V,
1393 const gp_Trsf& T) const
1395 basisSurf->TransformParameters(U,V,T);
1396 if(!equivSurf.IsNull()) equivSurf->TransformParameters(U,V,T);
1399 //=======================================================================
1400 //function : ParametricTransformation
1402 //=======================================================================
1404 gp_GTrsf2d Geom_OffsetSurface::ParametricTransformation (const gp_Trsf& T) const
1406 return basisSurf->ParametricTransformation(T);
1409 //=======================================================================
1410 //function : Surface
1411 //purpose : Trouve si elle existe, une surface non offset, equivalente
1412 // a l'offset surface.
1413 //=======================================================================
1415 Handle(Geom_Surface) Geom_OffsetSurface::Surface() const
1417 if (offsetValue == 0.0) return basisSurf; // Cas direct
1419 Standard_Real Tol = Precision::Confusion();
1420 Handle(Geom_Surface) Result, Base;
1422 Handle(Standard_Type) TheType = basisSurf->DynamicType();
1423 Standard_Boolean IsTrimmed;
1424 Standard_Real U1 = 0., V1 = 0., U2 = 0., V2 = 0.;
1426 // Preambule pour les surface trimmes
1427 if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1428 Handle(Geom_RectangularTrimmedSurface) S =
1429 Handle(Geom_RectangularTrimmedSurface)::DownCast(basisSurf);
1430 Base = S->BasisSurface();
1431 TheType = Base->DynamicType();
1432 S->Bounds(U1,U2,V1,V2);
1433 IsTrimmed = Standard_True;
1436 IsTrimmed = Standard_False;
1440 // Traite les surfaces cannonique
1441 if (TheType == STANDARD_TYPE(Geom_Plane))
1443 Handle(Geom_Plane) P =
1444 Handle(Geom_Plane)::DownCast(Base);
1445 gp_Vec T = P->Position().XDirection()^P->Position().YDirection();
1447 Result = Handle(Geom_Plane)::DownCast(P->Translated(T));
1449 else if (TheType == STANDARD_TYPE(Geom_CylindricalSurface))
1451 Handle(Geom_CylindricalSurface) C =
1452 Handle(Geom_CylindricalSurface)::DownCast(Base);
1453 Standard_Real Radius = C->Radius();
1454 gp_Ax3 Axis = C->Position();
1456 Radius += offsetValue;
1458 Radius -= offsetValue;
1459 if ( Radius >= Tol ) {
1460 Result = new Geom_CylindricalSurface( Axis, Radius);
1462 else if ( Radius <= -Tol ){
1463 Axis.Rotate(gp_Ax1(Axis.Location(),Axis.Direction()),M_PI);
1464 Result = new Geom_CylindricalSurface( Axis, Abs(Radius));
1469 // surface degeneree
1472 else if (TheType == STANDARD_TYPE(Geom_ConicalSurface))
1474 Handle(Geom_ConicalSurface) C =
1475 Handle(Geom_ConicalSurface)::DownCast(Base);
1476 gp_Ax3 anAxis = C->Position();
1477 Standard_Boolean isDirect = anAxis.Direct();
1478 Standard_Real anAlpha = C->SemiAngle();
1479 Standard_Real aRadius;
1482 aRadius = C->RefRadius() + offsetValue * Cos (anAlpha);
1486 aRadius = C->RefRadius() - offsetValue * Cos (anAlpha);
1490 gp_Vec aZ (anAxis.Direction());
1493 aZ *= -offsetValue * Sin (anAlpha);
1497 aZ *= offsetValue * Sin (anAlpha);
1499 anAxis.Translate (aZ);
1500 Result = new Geom_ConicalSurface (anAxis, anAlpha, aRadius);
1504 // surface degeneree
1507 else if (TheType == STANDARD_TYPE(Geom_SphericalSurface)) {
1508 Handle(Geom_SphericalSurface) S =
1509 Handle(Geom_SphericalSurface)::DownCast(Base);
1510 Standard_Real Radius = S->Radius();
1511 gp_Ax3 Axis = S->Position();
1513 Radius += offsetValue;
1515 Radius -= offsetValue;
1516 if ( Radius >= Tol) {
1517 Result = new Geom_SphericalSurface(Axis, Radius);
1519 else if ( Radius <= -Tol ) {
1520 Axis.Rotate(gp_Ax1(Axis.Location(),Axis.Direction()),M_PI);
1522 Result = new Geom_SphericalSurface(Axis, -Radius);
1526 // surface degeneree
1529 else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface))
1532 Handle(Geom_ToroidalSurface)
1533 S = Handle(Geom_ToroidalSurface)::DownCast(Base);
1534 Standard_Real MajorRadius = S->MajorRadius();
1535 Standard_Real MinorRadius = S->MinorRadius();
1536 gp_Ax3 Axis = S->Position();
1537 if (MinorRadius <= MajorRadius)
1540 MinorRadius += offsetValue;
1542 MinorRadius -= offsetValue;
1543 if (MinorRadius >= Tol)
1544 Result = new Geom_ToroidalSurface(Axis,MajorRadius,MinorRadius);
1545 // else if (MinorRadius <= -Tol)
1546 // Result->UReverse();
1549 // surface degeneree
1554 // S'il le faut on trimme le resultat
1555 if (IsTrimmed && !Result.IsNull()) {
1557 Result = new Geom_RectangularTrimmedSurface (Base, U1, U2, V1,V2);
1563 //=======================================================================
1564 //function : UOsculatingSurface
1566 //=======================================================================
1568 Standard_Boolean Geom_OffsetSurface::UOsculatingSurface(const Standard_Real U, const Standard_Real V,
1569 Standard_Boolean& t, Handle(Geom_BSplineSurface)& L) const
1571 return myOscSurf.UOscSurf(U,V,t,L);
1574 //=======================================================================
1575 //function : VOsculatingSurface
1577 //=======================================================================
1579 Standard_Boolean Geom_OffsetSurface::VOsculatingSurface(const Standard_Real U, const Standard_Real V,
1580 Standard_Boolean& t, Handle(Geom_BSplineSurface)& L) const
1582 return myOscSurf.VOscSurf(U,V,t,L);
1585 //=======================================================================
1588 //=======================================================================
1590 void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V,
1592 const gp_Vec& D1U, const gp_Vec& D1V) const // First Derivative
1594 const Standard_Real MagTol=0.000000001;
1596 gp_Vec aNorm = D1U.Crossed(D1V);
1597 if (aNorm.SquareMagnitude() > MagTol * MagTol)
1599 // Non singular case. Simple computations.
1601 P.SetXYZ(P.XYZ() + offsetValue * aNorm.XYZ());
1605 Standard_Boolean AlongU = Standard_False,
1606 AlongV = Standard_False;
1607 Handle(Geom_BSplineSurface) L;
1608 Standard_Boolean IsOpposite=Standard_False;
1609 AlongU = UOsculatingSurface(U,V,IsOpposite,L);
1610 AlongV = VOsculatingSurface(U,V,IsOpposite,L);
1612 CSLib_NormalStatus NStatus;
1613 Standard_Integer MaxOrder=3;
1614 TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder);
1615 TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1);
1616 Standard_Integer OrderU,OrderV;
1617 Standard_Real Umin,Umax,Vmin,Vmax;
1618 Bounds(Umin,Umax,Vmin,Vmax);
1619 DerSurf.SetValue(1, 0, D1U);
1620 DerSurf.SetValue(0, 1, D1V);
1621 derivatives(MaxOrder,1,U,V,basisSurf,0,0,AlongU,AlongV,L,DerNUV,DerSurf);
1623 Standard_Real signe = 1.0;
1624 if ((AlongV || AlongU) && IsOpposite)
1627 CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
1628 if (NStatus == CSLib_Defined)
1629 P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
1632 if (NStatus == CSLib_InfinityOfSolutions &&
1633 D1U.SquareMagnitude() + D1V.SquareMagnitude() > MagTol * MagTol)
1635 // Use non-null derivative as normal direction in degenerated case.
1636 gp_Vec aNorm = D1U.SquareMagnitude() > MagTol * MagTol ? D1U : D1V;
1639 P.SetXYZ(P.XYZ() + offsetValue * signe * aNorm.XYZ());
1642 Geom_UndefinedValue::Raise();
1647 //=======================================================================
1650 //=======================================================================/
1652 void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V,
1654 gp_Vec& D1U, gp_Vec& D1V, // First derivative
1655 const gp_Vec& D2UU, const gp_Vec& D2VV, const gp_Vec& D2UV) const // Second derivative
1657 const Standard_Real MagTol=0.000000001;
1659 // Check offset side.
1660 Handle(Geom_BSplineSurface) L;
1661 Standard_Boolean AlongU = Standard_False,
1662 AlongV = Standard_False;
1663 Standard_Boolean IsOpposite=Standard_False;
1664 AlongU = UOsculatingSurface(U,V,IsOpposite,L);
1665 AlongV = VOsculatingSurface(U,V,IsOpposite,L);
1666 Standard_Real signe = 1.0;
1667 if ((AlongV || AlongU) && IsOpposite)
1670 Standard_Integer MaxOrder = 0;
1671 gp_Vec aNorm = D1U.Crossed(D1V);
1672 if (aNorm.SquareMagnitude() > MagTol * MagTol)
1676 if (!AlongV && !AlongU)
1678 // AlongU or AlongV leads to more complex D1 computations,
1679 // try to compute D0 and D1 much simpler.
1681 P.SetXYZ(P.XYZ() + offsetValue * signe * aNorm.XYZ());
1683 gp_Vec aN0(aNorm.XYZ()), aN1U, aN1V;
1684 Standard_Real aScale = (D1U^D1V).Dot(aN0);
1685 aN1U.SetX(D2UU.Y() * D1V.Z() + D1U.Y() * D2UV.Z()
1686 - D2UU.Z() * D1V.Y() - D1U.Z() * D2UV.Y());
1687 aN1U.SetY((D2UU.X() * D1V.Z() + D1U.X() * D2UV.Z()
1688 - D2UU.Z() * D1V.X() - D1U.Z() * D2UV.X() ) * -1.0);
1689 aN1U.SetZ(D2UU.X() * D1V.Y() + D1U.X() * D2UV.Y()
1690 - D2UU.Y() * D1V.X() - D1U.Y() * D2UV.X());
1691 Standard_Real aScaleU = aN1U.Dot(aN0);
1692 aN1U.Subtract(aScaleU * aN0);
1695 aN1V.SetX(D2UV.Y() * D1V.Z() + D2VV.Z() * D1U.Y()
1696 - D2UV.Z() * D1V.Y() - D2VV.Y() * D1U.Z());
1697 aN1V.SetY((D2UV.X() * D1V.Z() + D2VV.Z() * D1U.X()
1698 - D2UV.Z() * D1V.X() - D2VV.X() * D1U.Z()) * -1.0);
1699 aN1V.SetZ(D2UV.X() * D1V.Y() + D2VV.Y() * D1U.X()
1700 - D2UV.Y() * D1V.X() - D2VV.X() * D1U.Y());
1701 Standard_Real aScaleV = aN1V.Dot(aN0);
1702 aN1V.Subtract(aScaleV * aN0);
1705 D1U += offsetValue * signe * aN1U;
1706 D1V += offsetValue * signe * aN1V;
1714 Standard_Integer OrderU,OrderV;
1715 TColgp_Array2OfVec DerNUV(0,MaxOrder+1,0,MaxOrder+1);
1716 TColgp_Array2OfVec DerSurf(0,MaxOrder+2,0,MaxOrder+2);
1717 Standard_Real Umin,Umax,Vmin,Vmax;
1718 Bounds(Umin,Umax,Vmin,Vmax);
1719 DerSurf.SetValue(1, 0, D1U);
1720 DerSurf.SetValue(0, 1, D1V);
1721 DerSurf.SetValue(1, 1, D2UV);
1722 DerSurf.SetValue(2, 0, D2UU);
1723 DerSurf.SetValue(0, 2, D2VV);
1724 derivatives(MaxOrder,2,U,V,basisSurf,1,1,AlongU,AlongV,L,DerNUV,DerSurf);
1727 CSLib_NormalStatus NStatus;
1728 CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
1729 if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
1731 P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
1734 + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
1736 + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
1739 //=======================================================================
1742 //=======================================================================/
1744 void Geom_OffsetSurface::SetD2(const Standard_Real U, const Standard_Real V,
1746 gp_Vec& D1U, gp_Vec& D1V,
1747 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
1748 const gp_Vec& d3u, const gp_Vec& d3v,
1749 const gp_Vec& d3uuv, const gp_Vec& d3uvv) const
1751 const Standard_Real MagTol=0.000000001;
1754 CSLib_NormalStatus NStatus;
1755 CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal);
1757 const Standard_Integer MaxOrder = (NStatus == CSLib_Defined)? 0 : 3;
1758 Standard_Integer OrderU,OrderV;
1759 TColgp_Array2OfVec DerNUV(0,MaxOrder+2,0,MaxOrder+2);
1760 TColgp_Array2OfVec DerSurf(0,MaxOrder+3,0,MaxOrder+3);
1761 Standard_Real Umin,Umax,Vmin,Vmax;
1762 Bounds(Umin,Umax,Vmin,Vmax);
1763 DerSurf.SetValue(1, 0, D1U);
1764 DerSurf.SetValue(0, 1, D1V);
1765 DerSurf.SetValue(1, 1, D2UV);
1766 DerSurf.SetValue(2, 0, D2U);
1767 DerSurf.SetValue(0, 2, D2V);
1768 DerSurf.SetValue(3, 0, d3u);
1769 DerSurf.SetValue(2, 1, d3uuv);
1770 DerSurf.SetValue(1, 2, d3uvv);
1771 DerSurf.SetValue(0, 3, d3v);
1772 //*********************
1774 Handle(Geom_BSplineSurface) L;
1775 Standard_Boolean IsOpposite=Standard_False;
1776 const Standard_Boolean AlongU = UOsculatingSurface(U,V,IsOpposite,L);
1777 const Standard_Boolean AlongV = VOsculatingSurface(U,V,IsOpposite,L);
1778 const Standard_Real signe = ((AlongV || AlongU) && IsOpposite)? -1. : 1.;
1779 derivatives(MaxOrder,3,U,V,basisSurf,2,2,AlongU,AlongV,L,DerNUV,DerSurf);
1781 CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
1782 if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
1784 P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
1787 + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
1789 + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
1791 D2U = basisSurf->DN(U,V,2,0)
1792 + signe * offsetValue * CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV);
1793 D2V = basisSurf->DN(U,V,0,2)
1794 + signe * offsetValue * CSLib::DNNormal(0,2,DerNUV,OrderU,OrderV);
1795 D2UV = basisSurf->DN(U,V,1,1)
1796 + signe * offsetValue * CSLib::DNNormal(1,1,DerNUV,OrderU,OrderV);
1799 //=======================================================================
1802 //=======================================================================/
1804 void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V,
1806 gp_Vec& D1U, gp_Vec& D1V,
1807 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
1808 gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const
1810 const Standard_Real MagTol=0.000000001;
1813 CSLib_NormalStatus NStatus;
1814 CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal);
1815 const Standard_Integer MaxOrder = (NStatus == CSLib_Defined)? 0 : 3;
1816 Standard_Integer OrderU,OrderV;
1817 TColgp_Array2OfVec DerNUV(0,MaxOrder+3,0,MaxOrder+3);
1818 TColgp_Array2OfVec DerSurf(0,MaxOrder+4,0,MaxOrder+4);
1819 Standard_Real Umin,Umax,Vmin,Vmax;
1820 Bounds(Umin,Umax,Vmin,Vmax);
1822 DerSurf.SetValue(1, 0, D1U);
1823 DerSurf.SetValue(0, 1, D1V);
1824 DerSurf.SetValue(1, 1, D2UV);
1825 DerSurf.SetValue(2, 0, D2U);
1826 DerSurf.SetValue(0, 2, D2V);
1827 DerSurf.SetValue(3, 0, D3U);
1828 DerSurf.SetValue(2, 1, D3UUV);
1829 DerSurf.SetValue(1, 2, D3UVV);
1830 DerSurf.SetValue(0, 3, D3V);
1833 //*********************
1834 Handle(Geom_BSplineSurface) L;
1835 Standard_Boolean IsOpposite=Standard_False;
1836 const Standard_Boolean AlongU = UOsculatingSurface(U,V,IsOpposite,L);
1837 const Standard_Boolean AlongV = VOsculatingSurface(U,V,IsOpposite,L);
1838 const Standard_Real signe = ((AlongV || AlongU) && IsOpposite)? -1. : 1.;
1839 derivatives(MaxOrder,3,U,V,basisSurf,3,3,AlongU,AlongV,L,DerNUV,DerSurf);
1841 CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
1842 if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
1844 P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
1847 + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
1849 + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
1851 D2U = basisSurf->DN(U,V,2,0)
1852 + signe * offsetValue * CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV);
1853 D2V = basisSurf->DN(U,V,0,2)
1854 + signe * offsetValue * CSLib::DNNormal(0,2,DerNUV,OrderU,OrderV);
1855 D2UV = basisSurf->DN(U,V,1,1)
1856 + signe * offsetValue * CSLib::DNNormal(1,1,DerNUV,OrderU,OrderV);
1857 D3U = basisSurf->DN(U,V,3,0)
1858 + signe * offsetValue * CSLib::DNNormal(3,0,DerNUV,OrderU,OrderV);
1859 D3V = basisSurf->DN(U,V,0,3)
1860 + signe * offsetValue * CSLib::DNNormal(0,3,DerNUV,OrderU,OrderV);
1861 D3UUV = basisSurf->DN(U,V,2,1)
1862 + signe * offsetValue * CSLib::DNNormal(2,1,DerNUV,OrderU,OrderV);
1863 D3UVV = basisSurf->DN(U,V,1,2)
1864 + signe * offsetValue * CSLib::DNNormal(1,2,DerNUV,OrderU,OrderV);
1867 //=======================================================================
1870 //=======================================================================
1872 gp_Vec Geom_OffsetSurface::SetDN ( const Standard_Real U, const Standard_Real V,
1873 const Standard_Integer Nu, const Standard_Integer Nv,
1874 const gp_Vec& D1U, const gp_Vec& D1V) const
1876 const Standard_Real MagTol=0.000000001;
1879 CSLib_NormalStatus NStatus;
1880 CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal);
1881 const Standard_Integer MaxOrder = (NStatus == CSLib_Defined)? 0 : 3;
1882 Standard_Integer OrderU,OrderV;
1883 TColgp_Array2OfVec DerNUV(0,MaxOrder+Nu,0,MaxOrder+Nu);
1884 TColgp_Array2OfVec DerSurf(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1);
1885 Standard_Real Umin,Umax,Vmin,Vmax;
1886 Bounds(Umin,Umax,Vmin,Vmax);
1888 DerSurf.SetValue(1, 0, D1U);
1889 DerSurf.SetValue(0, 1, D1V);
1891 //*********************
1892 Handle(Geom_BSplineSurface) L;
1893 // Is there any osculatingsurface along U or V;
1894 Standard_Boolean IsOpposite=Standard_False;
1895 const Standard_Boolean AlongU = UOsculatingSurface(U,V,IsOpposite,L);
1896 const Standard_Boolean AlongV = VOsculatingSurface(U,V,IsOpposite,L);
1897 const Standard_Real signe = ((AlongV || AlongU) && IsOpposite)? -1. : 1.;
1898 derivatives(MaxOrder,1,U,V,basisSurf,Nu,Nv,AlongU,AlongV,L,DerNUV,DerSurf);
1900 CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
1901 if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
1903 gp_Vec D = basisSurf->DN(U,V,Nu,Nv)
1904 + signe * offsetValue * CSLib::DNNormal(Nu,Nv,DerNUV,OrderU,OrderV);