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>
52 #include <GeomAdaptor_Surface.hxx>
53 #include <GeomEvaluator_OffsetSurface.hxx>
56 #include <gp_GTrsf2d.hxx>
58 #include <gp_Trsf.hxx>
61 #include <Precision.hxx>
62 #include <Standard_ConstructionError.hxx>
63 #include <Standard_NoSuchObject.hxx>
64 #include <Standard_NotImplemented.hxx>
65 #include <Standard_RangeError.hxx>
66 #include <Standard_Type.hxx>
67 #include <TColgp_Array1OfPnt.hxx>
68 #include <TColgp_Array2OfVec.hxx>
69 #include <TColgp_HArray2OfPnt.hxx>
70 #include <TColStd_Array1OfInteger.hxx>
71 #include <TColStd_Array1OfReal.hxx>
72 #include <TColStd_HArray1OfInteger.hxx>
73 #include <TColStd_HArray1OfReal.hxx>
74 #include <TColStd_HArray2OfInteger.hxx>
76 IMPLEMENT_STANDARD_RTTIEXT(Geom_OffsetSurface,Geom_Surface)
78 static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
81 //=======================================================================
84 //=======================================================================
86 Handle(Geom_Geometry) Geom_OffsetSurface::Copy () const
88 Handle(Geom_OffsetSurface) S(new Geom_OffsetSurface(basisSurf, offsetValue, Standard_True));
92 //=======================================================================
93 //function : Geom_OffsetSurface
94 //purpose : Basis surface cannot be an Offset surface or trimmed from
96 //=======================================================================
98 Geom_OffsetSurface::Geom_OffsetSurface (const Handle(Geom_Surface)& theSurf,
99 const Standard_Real theOffset,
100 const Standard_Boolean isNotCheckC0)
101 : offsetValue (theOffset)
103 SetBasisSurface(theSurf, isNotCheckC0);
106 //=======================================================================
107 //function : SetBasisSurface
109 //=======================================================================
111 void Geom_OffsetSurface::SetBasisSurface (const Handle(Geom_Surface)& S,
112 const Standard_Boolean isNotCheckC0)
114 Standard_Real aUf, aUl, aVf, aVl;
115 S->Bounds(aUf, aUl, aVf, aVl);
117 Handle(Geom_Surface) aCheckingSurf = Handle(Geom_Surface)::DownCast(S->Copy());
118 Standard_Boolean isTrimmed = Standard_False;
120 while(aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
121 aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
123 if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
125 Handle(Geom_RectangularTrimmedSurface) aTrimS =
126 Handle(Geom_RectangularTrimmedSurface)::DownCast(aCheckingSurf);
127 aCheckingSurf = aTrimS->BasisSurface();
128 isTrimmed = Standard_True;
131 if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
133 Handle(Geom_OffsetSurface) aOS =
134 Handle(Geom_OffsetSurface)::DownCast(aCheckingSurf);
135 aCheckingSurf = aOS->BasisSurface();
136 offsetValue += aOS->Offset();
140 myBasisSurfContinuity = aCheckingSurf->Continuity();
142 Standard_Boolean isC0 = !isNotCheckC0 && (myBasisSurfContinuity == GeomAbs_C0);
144 // Basis surface must be at least C1
147 Handle(Geom_Curve) aCurve;
149 if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)))
151 Handle(Geom_SurfaceOfRevolution) aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aCheckingSurf);
152 aCurve = aRevSurf->BasisCurve();
154 else if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)))
156 Handle(Geom_SurfaceOfLinearExtrusion) aLESurf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aCheckingSurf);
157 aCurve = aLESurf->BasisCurve();
162 while(aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ||
163 aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
165 if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
167 Handle(Geom_TrimmedCurve) aTrimC =
168 Handle(Geom_TrimmedCurve)::DownCast(aCurve);
169 aCurve = aTrimC->BasisCurve();
172 if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
174 Handle(Geom_OffsetCurve) aOC =
175 Handle(Geom_OffsetCurve)::DownCast(aCurve);
176 aCurve = aOC->BasisCurve();
181 const Standard_Real aUIsoPar = (aUf + aUl)/2.0, aVIsoPar = (aVf + aVl)/2.0;
182 Standard_Boolean isUG1 = Standard_False, isVG1 = Standard_False;
184 const Handle(Geom_Curve) aCurv1 = aCurve.IsNull() ? aCheckingSurf->UIso(aUIsoPar) : aCurve;
185 const Handle(Geom_Curve) aCurv2 = aCheckingSurf->VIso(aVIsoPar);
186 isUG1 = !aCurv1->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
187 isVG1 = !aCurv2->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
191 Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv1);
192 isUG1 = aBC->IsG1(aVf, aVl, MyAngularToleranceForG1);
197 Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv2);
198 isVG1 = aBC->IsG1(aUf, aUl, MyAngularToleranceForG1);
203 myBasisSurfContinuity = GeomAbs_G1;
204 isC0 = Standard_False;
207 // Raise exception if still C0
209 Standard_ConstructionError::Raise("Offset with no C1 Surface");
215 new Geom_RectangularTrimmedSurface(aCheckingSurf, aUf, aUl, aVf, aVl);
219 basisSurf = aCheckingSurf;
222 equivSurf = Surface();
224 if (basisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface)) ||
225 basisSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)))
227 // Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur
228 // et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso
229 // et aussi pour les singularite. Pour les surfaces osculatrices, on l'utilise pour
230 // detecter si une iso est degeneree.
231 const Standard_Real Tol = Precision::Confusion(); //0.0001;
232 myOscSurf = new Geom_OsculatingSurface(basisSurf, Tol);
235 // Surface value calculator
236 if (equivSurf.IsNull())
237 myEvaluator = new GeomEvaluator_OffsetSurface(basisSurf, offsetValue, myOscSurf);
240 //=======================================================================
241 //function : SetOffsetValue
243 //=======================================================================
245 void Geom_OffsetSurface::SetOffsetValue (const Standard_Real D)
248 equivSurf = Surface();
249 if (equivSurf.IsNull())
251 if (myEvaluator.IsNull())
252 myEvaluator = new GeomEvaluator_OffsetSurface(basisSurf, offsetValue, myOscSurf);
254 myEvaluator->SetOffsetValue(offsetValue);
258 //=======================================================================
259 //function : UReverse
261 //=======================================================================
263 void Geom_OffsetSurface::UReverse ()
265 basisSurf->UReverse();
266 offsetValue = -offsetValue;
267 if (!equivSurf.IsNull())
268 equivSurf->UReverse();
270 myEvaluator->SetOffsetValue(offsetValue);
273 //=======================================================================
274 //function : UReversedParameter
276 //=======================================================================
278 Standard_Real Geom_OffsetSurface::UReversedParameter(const Standard_Real U) const
280 return basisSurf->UReversedParameter(U);
283 //=======================================================================
284 //function : VReverse
286 //=======================================================================
288 void Geom_OffsetSurface::VReverse ()
290 basisSurf->VReverse();
291 offsetValue = -offsetValue;
292 if (!equivSurf.IsNull())
293 equivSurf->VReverse();
295 myEvaluator->SetOffsetValue(offsetValue);
298 //=======================================================================
299 //function : VReversedParameter
301 //=======================================================================
303 Standard_Real Geom_OffsetSurface::VReversedParameter(const Standard_Real V) const
305 return basisSurf->VReversedParameter(V);
308 //=======================================================================
311 //=======================================================================
313 void Geom_OffsetSurface::Bounds (Standard_Real& U1, Standard_Real& U2,
314 Standard_Real& V1, Standard_Real& V2) const
316 basisSurf->Bounds (U1, U2 ,V1, V2);
319 //=======================================================================
320 //function : Continuity
322 //=======================================================================
324 GeomAbs_Shape Geom_OffsetSurface::Continuity () const
326 switch (myBasisSurfContinuity) {
327 case GeomAbs_C2 : return GeomAbs_C1;
328 case GeomAbs_C3 : return GeomAbs_C2;
329 case GeomAbs_CN : return GeomAbs_CN;
335 //=======================================================================
338 //=======================================================================
340 void Geom_OffsetSurface::D0 (const Standard_Real U, const Standard_Real V, gp_Pnt& P) const
343 if (myBasisSurfContinuity == GeomAbs_C0)
344 Geom_UndefinedValue::Raise();
346 if (equivSurf.IsNull())
347 myEvaluator->D0(U, V, P);
349 equivSurf->D0(U,V,P);
352 //=======================================================================
355 //=======================================================================
357 void Geom_OffsetSurface::D1 (const Standard_Real U, const Standard_Real V,
359 gp_Vec& D1U, gp_Vec& D1V) const
362 if (myBasisSurfContinuity == GeomAbs_C0 ||
363 myBasisSurfContinuity == GeomAbs_C1)
364 Geom_UndefinedDerivative::Raise();
366 if (equivSurf.IsNull())
367 myEvaluator->D1(U, V, P, D1U, D1V);
369 equivSurf->D1(U,V,P,D1U,D1V);
372 //=======================================================================
375 //=======================================================================
377 void Geom_OffsetSurface::D2 (const Standard_Real U, const Standard_Real V,
379 gp_Vec& D1U, gp_Vec& D1V,
380 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const
383 if (myBasisSurfContinuity == GeomAbs_C0 ||
384 myBasisSurfContinuity == GeomAbs_C1 ||
385 myBasisSurfContinuity == GeomAbs_C2)
386 Geom_UndefinedDerivative::Raise();
388 if (equivSurf.IsNull())
389 myEvaluator->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
391 equivSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
394 //=======================================================================
397 //=======================================================================
399 void Geom_OffsetSurface::D3 (const Standard_Real U, const Standard_Real V,
401 gp_Vec& D1U, gp_Vec& D1V,
402 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
403 gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const
406 if (!(basisSurf->IsCNu (4) && basisSurf->IsCNv (4))) {
407 Geom_UndefinedDerivative::Raise();
410 if (equivSurf.IsNull())
411 myEvaluator->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV);
413 equivSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
416 //=======================================================================
419 //=======================================================================
421 gp_Vec Geom_OffsetSurface::DN (const Standard_Real U, const Standard_Real V,
422 const Standard_Integer Nu, const Standard_Integer Nv) const
424 Standard_RangeError_Raise_if (Nu < 0 || Nv < 0 || Nu + Nv < 1, " ");
426 if (!(basisSurf->IsCNu (Nu) && basisSurf->IsCNv (Nv))) {
427 Geom_UndefinedDerivative::Raise();
432 if (equivSurf.IsNull())
433 D = myEvaluator->DN(U, V, Nu, Nv);
435 D = equivSurf->DN(U,V,Nu,Nv);
440 ////*************************************************
442 //// EVALUATOR FOR THE ISO-CURVE APPROXIMATION
444 ////*************************************************
446 class Geom_OffsetSurface_UIsoEvaluator : public AdvApprox_EvaluatorFunction
449 Geom_OffsetSurface_UIsoEvaluator (const Handle(Geom_Surface)& theSurface, const Standard_Real theU)
450 : CurrentSurface(theSurface), IsoPar(theU) {}
452 virtual void Evaluate (Standard_Integer *Dimension,
453 Standard_Real StartEnd[2],
454 Standard_Real *Parameter,
455 Standard_Integer *DerivativeRequest,
456 Standard_Real *Result, // [Dimension]
457 Standard_Integer *ErrorCode);
460 GeomAdaptor_Surface CurrentSurface;
461 Standard_Real IsoPar;
464 void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/
465 Standard_Real /*StartEnd*/[2],
466 Standard_Real *Parameter,
467 Standard_Integer *DerivativeRequest,
468 Standard_Real *Result,
469 Standard_Integer *ReturnCode)
472 if (*DerivativeRequest == 0) {
473 P = CurrentSurface.Value(IsoPar,*Parameter);
480 CurrentSurface.D1(IsoPar,*Parameter,P,DU,DV);
488 class Geom_OffsetSurface_VIsoEvaluator : public AdvApprox_EvaluatorFunction
491 Geom_OffsetSurface_VIsoEvaluator (const Handle(Geom_Surface)& theSurface, const Standard_Real theV)
492 : CurrentSurface(theSurface), IsoPar(theV) {}
494 virtual void Evaluate (Standard_Integer *Dimension,
495 Standard_Real StartEnd[2],
496 Standard_Real *Parameter,
497 Standard_Integer *DerivativeRequest,
498 Standard_Real *Result, // [Dimension]
499 Standard_Integer *ErrorCode);
502 Handle(Geom_Surface) CurrentSurface;
503 Standard_Real IsoPar;
506 void Geom_OffsetSurface_VIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/
507 Standard_Real /*StartEnd*/[2],
508 Standard_Real *Parameter,
509 Standard_Integer *DerivativeRequest,
510 Standard_Real *Result,
511 Standard_Integer *ReturnCode)
514 if (*DerivativeRequest == 0) {
515 P = CurrentSurface->Value(*Parameter,IsoPar);
522 CurrentSurface->D1(*Parameter,IsoPar,P,DU,DV);
530 //=======================================================================
532 //purpose : The Uiso or the VIso of an OffsetSurface can't be clearly
533 // exprimed as a curve from Geom. So, to extract the U or VIso
534 // an Approximation is needed. This approx always will return a
535 // BSplineCurve from Geom.
536 //=======================================================================
538 Handle(Geom_Curve) Geom_OffsetSurface::UIso (const Standard_Real UU) const
540 if (equivSurf.IsNull()) {
541 const Standard_Integer Num1 = 0, Num2 = 0, Num3 = 1;
542 Handle(TColStd_HArray1OfReal) T1, T2, T3 = new TColStd_HArray1OfReal(1,Num3);
543 T3->Init(Precision::Approximation());
544 Standard_Real U1,U2,V1,V2;
546 const GeomAbs_Shape Cont = GeomAbs_C1;
547 const Standard_Integer MaxSeg = 100, MaxDeg = 14;
549 Handle(Geom_OffsetSurface) me (this);
550 Geom_OffsetSurface_UIsoEvaluator ev (me, UU);
551 AdvApprox_ApproxAFunction Approx(Num1, Num2, Num3, T1, T2, T3,
552 V1, V2, Cont, MaxDeg, MaxSeg, ev);
554 Standard_ConstructionError_Raise_if (!Approx.IsDone(), " Geom_OffsetSurface : UIso");
556 const Standard_Integer NbPoles = Approx.NbPoles();
558 TColgp_Array1OfPnt Poles( 1, NbPoles);
559 TColStd_Array1OfReal Knots( 1, Approx.NbKnots());
560 TColStd_Array1OfInteger Mults( 1, Approx.NbKnots());
562 Approx.Poles(1, Poles);
563 Knots = Approx.Knots()->Array1();
564 Mults = Approx.Multiplicities()->Array1();
566 Handle(Geom_BSplineCurve) C =
567 new Geom_BSplineCurve( Poles, Knots, Mults, Approx.Degree());
571 return equivSurf->UIso(UU);
574 //=======================================================================
577 //=======================================================================
579 Handle(Geom_Curve) Geom_OffsetSurface::VIso (const Standard_Real VV) const
581 if (equivSurf.IsNull()) {
582 const Standard_Integer Num1 = 0, Num2 = 0, Num3 = 1;
583 Handle(TColStd_HArray1OfReal) T1, T2, T3 = new TColStd_HArray1OfReal(1,Num3);
584 T3->Init(Precision::Approximation());
585 Standard_Real U1,U2,V1,V2;
587 const GeomAbs_Shape Cont = GeomAbs_C1;
588 const Standard_Integer MaxSeg = 100, MaxDeg = 14;
590 Handle(Geom_OffsetSurface) me (this);
591 Geom_OffsetSurface_VIsoEvaluator ev (me, VV);
592 AdvApprox_ApproxAFunction Approx (Num1, Num2, Num3, T1, T2, T3,
593 U1, U2, Cont, MaxDeg, MaxSeg, ev);
595 Standard_ConstructionError_Raise_if (!Approx.IsDone(), " Geom_OffsetSurface : VIso");
597 TColgp_Array1OfPnt Poles( 1, Approx.NbPoles());
598 TColStd_Array1OfReal Knots( 1, Approx.NbKnots());
599 TColStd_Array1OfInteger Mults( 1, Approx.NbKnots());
601 Approx.Poles(1, Poles);
602 Knots = Approx.Knots()->Array1();
603 Mults = Approx.Multiplicities()->Array1();
605 Handle(Geom_BSplineCurve) C =
606 new Geom_BSplineCurve( Poles, Knots, Mults, Approx.Degree());
610 return equivSurf->VIso(VV);
613 //=======================================================================
616 //=======================================================================
618 Standard_Boolean Geom_OffsetSurface::IsCNu (const Standard_Integer N) const
620 Standard_RangeError_Raise_if (N < 0, " ");
621 return basisSurf->IsCNu (N+1);
624 //=======================================================================
627 //=======================================================================
629 Standard_Boolean Geom_OffsetSurface::IsCNv (const Standard_Integer N) const
631 Standard_RangeError_Raise_if (N < 0, " ");
632 return basisSurf->IsCNv (N+1);
635 //=======================================================================
636 //function : IsUPeriodic
638 //=======================================================================
640 Standard_Boolean Geom_OffsetSurface::IsUPeriodic () const
642 return basisSurf->IsUPeriodic();
645 //=======================================================================
648 //=======================================================================
650 Standard_Real Geom_OffsetSurface::UPeriod() const
652 return basisSurf->UPeriod();
655 //=======================================================================
656 //function : IsVPeriodic
658 //=======================================================================
660 Standard_Boolean Geom_OffsetSurface::IsVPeriodic () const
662 return basisSurf->IsVPeriodic();
665 //=======================================================================
668 //=======================================================================
670 Standard_Real Geom_OffsetSurface::VPeriod() const
672 return basisSurf->VPeriod();
675 //=======================================================================
676 //function : IsUClosed
678 //=======================================================================
680 Standard_Boolean Geom_OffsetSurface::IsUClosed () const
682 Standard_Boolean UClosed;
683 Handle(Geom_Surface) SBasis = BasisSurface();
685 if (SBasis->IsKind (STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
686 Handle(Geom_RectangularTrimmedSurface) St =
687 Handle(Geom_RectangularTrimmedSurface)::DownCast(SBasis);
689 Handle(Geom_Surface) S = St->BasisSurface();
690 if (S->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
691 UClosed = SBasis->IsUClosed();
693 else if (S->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
694 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
695 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S);
697 Handle(Geom_Curve) C = Extru->BasisCurve();
698 if (C->IsKind (STANDARD_TYPE(Geom_Circle)) || C->IsKind (STANDARD_TYPE(Geom_Ellipse))) {
699 UClosed = SBasis->IsUClosed();
701 else { UClosed = Standard_False; }
703 else if (S->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
704 UClosed = SBasis->IsUClosed();
706 else { UClosed = Standard_False; }
709 if (SBasis->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
710 UClosed = SBasis->IsUClosed();
712 else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
713 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
714 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SBasis);
716 Handle(Geom_Curve) C = Extru->BasisCurve();
717 UClosed = (C->IsKind(STANDARD_TYPE(Geom_Circle)) || C->IsKind(STANDARD_TYPE(Geom_Ellipse)));
719 else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
720 UClosed = Standard_True;
722 else { UClosed = Standard_False; }
727 //=======================================================================
728 //function : IsVClosed
730 //=======================================================================
732 Standard_Boolean Geom_OffsetSurface::IsVClosed () const
734 Standard_Boolean VClosed;
735 Handle(Geom_Surface) SBasis = BasisSurface();
737 if (SBasis->IsKind (STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
738 Handle(Geom_RectangularTrimmedSurface) St =
739 Handle(Geom_RectangularTrimmedSurface)::DownCast(SBasis);
741 Handle(Geom_Surface) S = St->BasisSurface();
742 if (S->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
743 VClosed = SBasis->IsVClosed();
745 else { VClosed = Standard_False; }
748 if (SBasis->IsKind (STANDARD_TYPE(Geom_ElementarySurface))) {
749 VClosed = SBasis->IsVClosed();
751 else { VClosed = Standard_False; }
756 //=======================================================================
757 //function : Transform
759 //=======================================================================
761 void Geom_OffsetSurface::Transform (const gp_Trsf& T)
763 basisSurf->Transform (T);
764 offsetValue *= T.ScaleFactor();
766 if (myEvaluator.IsNull())
767 myEvaluator = new GeomEvaluator_OffsetSurface(basisSurf, offsetValue, myOscSurf);
769 myEvaluator->SetOffsetValue(offsetValue);
772 //=======================================================================
773 //function : TransformParameters
775 //=======================================================================
777 void Geom_OffsetSurface::TransformParameters(Standard_Real& U, Standard_Real& V,
778 const gp_Trsf& T) const
780 basisSurf->TransformParameters(U,V,T);
781 if(!equivSurf.IsNull()) equivSurf->TransformParameters(U,V,T);
784 //=======================================================================
785 //function : ParametricTransformation
787 //=======================================================================
789 gp_GTrsf2d Geom_OffsetSurface::ParametricTransformation (const gp_Trsf& T) const
791 return basisSurf->ParametricTransformation(T);
794 //=======================================================================
796 //purpose : Trouve si elle existe, une surface non offset, equivalente
797 // a l'offset surface.
798 //=======================================================================
800 Handle(Geom_Surface) Geom_OffsetSurface::Surface() const
802 if (offsetValue == 0.0) return basisSurf; // Cas direct
804 Standard_Real Tol = Precision::Confusion();
805 Handle(Geom_Surface) Result, Base;
807 Handle(Standard_Type) TheType = basisSurf->DynamicType();
808 Standard_Boolean IsTrimmed;
809 Standard_Real U1 = 0., V1 = 0., U2 = 0., V2 = 0.;
811 // Preambule pour les surface trimmes
812 if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
813 Handle(Geom_RectangularTrimmedSurface) S =
814 Handle(Geom_RectangularTrimmedSurface)::DownCast(basisSurf);
815 Base = S->BasisSurface();
816 TheType = Base->DynamicType();
817 S->Bounds(U1,U2,V1,V2);
818 IsTrimmed = Standard_True;
821 IsTrimmed = Standard_False;
825 // Traite les surfaces cannonique
826 if (TheType == STANDARD_TYPE(Geom_Plane))
828 Handle(Geom_Plane) P =
829 Handle(Geom_Plane)::DownCast(Base);
830 gp_Vec T = P->Position().XDirection()^P->Position().YDirection();
832 Result = Handle(Geom_Plane)::DownCast(P->Translated(T));
834 else if (TheType == STANDARD_TYPE(Geom_CylindricalSurface))
836 Handle(Geom_CylindricalSurface) C =
837 Handle(Geom_CylindricalSurface)::DownCast(Base);
838 Standard_Real Radius = C->Radius();
839 gp_Ax3 Axis = C->Position();
841 Radius += offsetValue;
843 Radius -= offsetValue;
844 if ( Radius >= Tol ) {
845 Result = new Geom_CylindricalSurface( Axis, Radius);
847 else if ( Radius <= -Tol ){
848 Axis.Rotate(gp_Ax1(Axis.Location(),Axis.Direction()),M_PI);
849 Result = new Geom_CylindricalSurface( Axis, Abs(Radius));
857 else if (TheType == STANDARD_TYPE(Geom_ConicalSurface))
859 Handle(Geom_ConicalSurface) C =
860 Handle(Geom_ConicalSurface)::DownCast(Base);
861 gp_Ax3 anAxis = C->Position();
862 Standard_Boolean isDirect = anAxis.Direct();
863 Standard_Real anAlpha = C->SemiAngle();
864 Standard_Real aRadius;
867 aRadius = C->RefRadius() + offsetValue * Cos (anAlpha);
871 aRadius = C->RefRadius() - offsetValue * Cos (anAlpha);
875 gp_Vec aZ (anAxis.Direction());
878 aZ *= -offsetValue * Sin (anAlpha);
882 aZ *= offsetValue * Sin (anAlpha);
884 anAxis.Translate (aZ);
885 Result = new Geom_ConicalSurface (anAxis, anAlpha, aRadius);
892 else if (TheType == STANDARD_TYPE(Geom_SphericalSurface)) {
893 Handle(Geom_SphericalSurface) S =
894 Handle(Geom_SphericalSurface)::DownCast(Base);
895 Standard_Real Radius = S->Radius();
896 gp_Ax3 Axis = S->Position();
898 Radius += offsetValue;
900 Radius -= offsetValue;
901 if ( Radius >= Tol) {
902 Result = new Geom_SphericalSurface(Axis, Radius);
904 else if ( Radius <= -Tol ) {
905 Axis.Rotate(gp_Ax1(Axis.Location(),Axis.Direction()),M_PI);
907 Result = new Geom_SphericalSurface(Axis, -Radius);
914 else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface))
917 Handle(Geom_ToroidalSurface)
918 S = Handle(Geom_ToroidalSurface)::DownCast(Base);
919 Standard_Real MajorRadius = S->MajorRadius();
920 Standard_Real MinorRadius = S->MinorRadius();
921 gp_Ax3 Axis = S->Position();
922 if (MinorRadius <= MajorRadius)
925 MinorRadius += offsetValue;
927 MinorRadius -= offsetValue;
928 if (MinorRadius >= Tol)
929 Result = new Geom_ToroidalSurface(Axis,MajorRadius,MinorRadius);
930 // else if (MinorRadius <= -Tol)
931 // Result->UReverse();
939 // S'il le faut on trimme le resultat
940 if (IsTrimmed && !Result.IsNull()) {
942 Result = new Geom_RectangularTrimmedSurface (Base, U1, U2, V1,V2);
948 //=======================================================================
949 //function : UOsculatingSurface
951 //=======================================================================
953 Standard_Boolean Geom_OffsetSurface::UOsculatingSurface(const Standard_Real U, const Standard_Real V,
954 Standard_Boolean& t, Handle(Geom_BSplineSurface)& L) const
956 return !myOscSurf.IsNull() && myOscSurf->UOscSurf(U,V,t,L);
959 //=======================================================================
960 //function : VOsculatingSurface
962 //=======================================================================
964 Standard_Boolean Geom_OffsetSurface::VOsculatingSurface(const Standard_Real U, const Standard_Real V,
965 Standard_Boolean& t, Handle(Geom_BSplineSurface)& L) const
967 return !myOscSurf.IsNull() && myOscSurf->VOscSurf(U, V, t, L);