// Created on: 1993-05-14 // Created by: Joelle CHAUVET // Copyright (c) 1993-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. // Modified: Thu Nov 26 16:37:18 1998 // correction in NbUIntervals for SurfaceOfLinearExtrusion // (PRO16346) #define No_Standard_RangeError #define No_Standard_OutOfRange #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const Standard_Real PosTol = Precision::PConfusion()*0.5; //======================================================================= //function : LocalContinuity //purpose : //======================================================================= GeomAbs_Shape LocalContinuity(Standard_Integer Degree, Standard_Integer Nb, TColStd_Array1OfReal& TK, TColStd_Array1OfInteger& TM, Standard_Real PFirst, Standard_Real PLast, Standard_Boolean IsPeriodic) { Standard_DomainError_Raise_if( (TK.Length()!=Nb || TM.Length()!=Nb )," "); Standard_Integer Index1 = 0; Standard_Integer Index2 = 0; Standard_Real newFirst, newLast; BSplCLib::LocateParameter(Degree,TK,TM,PFirst,IsPeriodic,1,Nb,Index1,newFirst); BSplCLib::LocateParameter(Degree,TK,TM,PLast, IsPeriodic,1,Nb,Index2,newLast ); const Standard_Real EpsKnot = Precision::PConfusion(); if (Abs(newFirst-TK(Index1+1))< EpsKnot) Index1++; if (Abs(newLast -TK(Index2 ))< EpsKnot) Index2--; // attention aux courbes peridiques. if ( (IsPeriodic) && (Index1 == Nb) ) Index1 = 1; if (Index2!=Index1) { Standard_Integer i, Multmax = TM(Index1+1); for (i = Index1+1; i<=Index2; i++) { if (TM(i)>Multmax) Multmax=TM(i); } Multmax = Degree - Multmax; if (Multmax <= 0) return GeomAbs_C0; switch (Multmax) { case 1: return GeomAbs_C1; case 2: return GeomAbs_C2; case 3: return GeomAbs_C3; } } return GeomAbs_CN; } //======================================================================= //function : Load //purpose : //======================================================================= void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S, const Standard_Real UFirst, const Standard_Real ULast, const Standard_Real VFirst, const Standard_Real VLast, const Standard_Real TolU, const Standard_Real TolV) { myTolU = TolU; myTolV = TolV; myUFirst = UFirst; myULast = ULast; myVFirst = VFirst; myVLast = VLast; mySurfaceCache.Nullify(); if ( mySurface != S) { mySurface = S; myNestedEvaluator.Nullify(); myBSplineSurface.Nullify(); const Handle(Standard_Type)& TheType = S->DynamicType(); if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { Load(Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface(), UFirst,ULast,VFirst,VLast); } else if ( TheType == STANDARD_TYPE(Geom_Plane)) mySurfaceType = GeomAbs_Plane; else if ( TheType == STANDARD_TYPE(Geom_CylindricalSurface)) mySurfaceType = GeomAbs_Cylinder; else if ( TheType == STANDARD_TYPE(Geom_ConicalSurface)) mySurfaceType = GeomAbs_Cone; else if ( TheType == STANDARD_TYPE(Geom_SphericalSurface)) mySurfaceType = GeomAbs_Sphere; else if ( TheType == STANDARD_TYPE(Geom_ToroidalSurface)) mySurfaceType = GeomAbs_Torus; else if ( TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution)) { mySurfaceType = GeomAbs_SurfaceOfRevolution; Handle(Geom_SurfaceOfRevolution) myRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(mySurface); // Create nested adaptor for base curve Handle(Geom_Curve) aBaseCurve = myRevSurf->BasisCurve(); Handle(Adaptor3d_HCurve) aBaseAdaptor = new GeomAdaptor_HCurve(aBaseCurve); // Create corresponding evaluator myNestedEvaluator = new GeomEvaluator_SurfaceOfRevolution (aBaseAdaptor, myRevSurf->Direction(), myRevSurf->Location()); } else if ( TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) { mySurfaceType = GeomAbs_SurfaceOfExtrusion; Handle(Geom_SurfaceOfLinearExtrusion) myExtSurf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurface); // Create nested adaptor for base curve Handle(Geom_Curve) aBaseCurve = myExtSurf->BasisCurve(); Handle(Adaptor3d_HCurve) aBaseAdaptor = new GeomAdaptor_HCurve(aBaseCurve); // Create corresponding evaluator myNestedEvaluator = new GeomEvaluator_SurfaceOfExtrusion (aBaseAdaptor, myExtSurf->Direction()); } else if (TheType == STANDARD_TYPE(Geom_BezierSurface)) { mySurfaceType = GeomAbs_BezierSurface; } else if (TheType == STANDARD_TYPE(Geom_BSplineSurface)) { mySurfaceType = GeomAbs_BSplineSurface; myBSplineSurface = Handle(Geom_BSplineSurface)::DownCast(mySurface); } else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface)) { mySurfaceType = GeomAbs_OffsetSurface; Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); // Create nested adaptor for base surface Handle(Geom_Surface) aBaseSurf = myOffSurf->BasisSurface(); Handle(GeomAdaptor_HSurface) aBaseAdaptor = new GeomAdaptor_HSurface(aBaseSurf, myUFirst, myULast, myVFirst, myVLast, myTolU, myTolV); myNestedEvaluator = new GeomEvaluator_OffsetSurface( aBaseAdaptor, myOffSurf->Offset(), myOffSurf->OsculatingSurface()); } else mySurfaceType = GeomAbs_OtherSurface; } } // -- // -- Global methods - Apply to the whole Surface. // -- //======================================================================= //function : UContinuity //purpose : //======================================================================= GeomAbs_Shape GeomAdaptor_Surface::UContinuity() const { switch (mySurfaceType) { case GeomAbs_BSplineSurface: { const Standard_Integer N = myBSplineSurface->NbUKnots(); TColStd_Array1OfReal TK(1,N); TColStd_Array1OfInteger TM(1,N); myBSplineSurface->UKnots(TK); myBSplineSurface->UMultiplicities(TM); return LocalContinuity(myBSplineSurface->UDegree(), myBSplineSurface->NbUKnots(), TK, TM, myUFirst, myULast, IsUPeriodic()); } case GeomAbs_OffsetSurface: { switch(BasisSurface()->UContinuity()) { case GeomAbs_CN : case GeomAbs_C3 : return GeomAbs_CN; case GeomAbs_G2 : case GeomAbs_C2 : return GeomAbs_C1; case GeomAbs_G1 : case GeomAbs_C1 : case GeomAbs_C0 : return GeomAbs_C0; } throw Standard_NoSuchObject("GeomAdaptor_Surface::UContinuity"); break; } case GeomAbs_SurfaceOfExtrusion: { Handle(Geom_SurfaceOfLinearExtrusion) myExtSurf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurface); GeomAdaptor_Curve GC(myExtSurf->BasisCurve(), myUFirst, myULast); return GC.Continuity(); } case GeomAbs_OtherSurface: throw Standard_NoSuchObject("GeomAdaptor_Surface::UContinuity"); case GeomAbs_Plane: case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: case GeomAbs_BezierSurface: case GeomAbs_SurfaceOfRevolution: break; } return GeomAbs_CN; } //======================================================================= //function : VContinuity //purpose : //======================================================================= GeomAbs_Shape GeomAdaptor_Surface::VContinuity() const { switch (mySurfaceType) { case GeomAbs_BSplineSurface: { const Standard_Integer N = myBSplineSurface->NbVKnots(); TColStd_Array1OfReal TK(1,N); TColStd_Array1OfInteger TM(1,N); myBSplineSurface->VKnots(TK); myBSplineSurface->VMultiplicities(TM); return LocalContinuity(myBSplineSurface->VDegree(), myBSplineSurface->NbVKnots(), TK, TM, myVFirst, myVLast, IsVPeriodic()); } case GeomAbs_OffsetSurface: { switch(BasisSurface()->VContinuity()) { case GeomAbs_CN : case GeomAbs_C3 : return GeomAbs_CN; case GeomAbs_G2 : case GeomAbs_C2 : return GeomAbs_C1; case GeomAbs_G1 : case GeomAbs_C1 : case GeomAbs_C0 : return GeomAbs_C0; } throw Standard_NoSuchObject("GeomAdaptor_Surface::VContinuity"); break; } case GeomAbs_SurfaceOfRevolution: { Handle(Geom_SurfaceOfRevolution) myRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(mySurface); GeomAdaptor_Curve GC(myRevSurf->BasisCurve(), myVFirst, myVLast); return GC.Continuity(); } case GeomAbs_OtherSurface: throw Standard_NoSuchObject("GeomAdaptor_Surface::VContinuity"); case GeomAbs_Plane: case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: case GeomAbs_BezierSurface: case GeomAbs_SurfaceOfExtrusion: break; } return GeomAbs_CN; } //======================================================================= //function : NbUIntervals //purpose : //======================================================================= Standard_Integer GeomAdaptor_Surface::NbUIntervals(const GeomAbs_Shape S) const { switch (mySurfaceType) { case GeomAbs_BSplineSurface: { GeomAdaptor_Curve myBasisCurve (myBSplineSurface->VIso(myBSplineSurface->VKnot(myBSplineSurface->FirstVKnotIndex())),myUFirst,myULast); return myBasisCurve.NbIntervals(S); } case GeomAbs_SurfaceOfExtrusion: { Handle(Geom_SurfaceOfLinearExtrusion) myExtSurf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurface); GeomAdaptor_Curve myBasisCurve(myExtSurf->BasisCurve(), myUFirst, myULast); if (myBasisCurve.GetType() == GeomAbs_BSplineCurve) return myBasisCurve.NbIntervals(S); break; } case GeomAbs_OffsetSurface: { GeomAbs_Shape BaseS = GeomAbs_CN; switch(S) { case GeomAbs_G1: case GeomAbs_G2: throw Standard_DomainError("GeomAdaptor_Curve::NbUIntervals"); case GeomAbs_C0: BaseS = GeomAbs_C1; break; case GeomAbs_C1: BaseS = GeomAbs_C2; break; case GeomAbs_C2: BaseS = GeomAbs_C3; break; case GeomAbs_C3: case GeomAbs_CN: break; } Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast); return Sur.NbUIntervals(BaseS); } case GeomAbs_Plane: case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: case GeomAbs_BezierSurface: case GeomAbs_OtherSurface: case GeomAbs_SurfaceOfRevolution: break; } return 1; } //======================================================================= //function : NbVIntervals //purpose : //======================================================================= Standard_Integer GeomAdaptor_Surface::NbVIntervals(const GeomAbs_Shape S) const { switch (mySurfaceType) { case GeomAbs_BSplineSurface: { GeomAdaptor_Curve myBasisCurve (myBSplineSurface->UIso(myBSplineSurface->UKnot(myBSplineSurface->FirstUKnotIndex())),myVFirst,myVLast); return myBasisCurve.NbIntervals(S); } case GeomAbs_SurfaceOfRevolution: { Handle(Geom_SurfaceOfRevolution) myRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(mySurface); GeomAdaptor_Curve myBasisCurve(myRevSurf->BasisCurve(), myVFirst, myVLast); if (myBasisCurve.GetType() == GeomAbs_BSplineCurve) return myBasisCurve.NbIntervals(S); break; } case GeomAbs_OffsetSurface: { GeomAbs_Shape BaseS = GeomAbs_CN; switch(S) { case GeomAbs_G1: case GeomAbs_G2: throw Standard_DomainError("GeomAdaptor_Curve::NbVIntervals"); case GeomAbs_C0: BaseS = GeomAbs_C1; break; case GeomAbs_C1: BaseS = GeomAbs_C2; break; case GeomAbs_C2: BaseS = GeomAbs_C3; break; case GeomAbs_C3: case GeomAbs_CN: break; } Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast); return Sur.NbVIntervals(BaseS); } case GeomAbs_Plane: case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: case GeomAbs_BezierSurface: case GeomAbs_OtherSurface: case GeomAbs_SurfaceOfExtrusion: break; } return 1; } //======================================================================= //function : UIntervals //purpose : //======================================================================= void GeomAdaptor_Surface::UIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shape S) const { Standard_Integer myNbUIntervals = 1; switch (mySurfaceType) { case GeomAbs_BSplineSurface: { GeomAdaptor_Curve myBasisCurve (myBSplineSurface->VIso(myBSplineSurface->VKnot(myBSplineSurface->FirstVKnotIndex())),myUFirst,myULast); myNbUIntervals = myBasisCurve.NbIntervals(S); myBasisCurve.Intervals(T,S); return; } case GeomAbs_SurfaceOfExtrusion: { GeomAdaptor_Curve myBasisCurve (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast); if (myBasisCurve.GetType() == GeomAbs_BSplineCurve) { myNbUIntervals = myBasisCurve.NbIntervals(S); myBasisCurve.Intervals(T,S); return; } break; } case GeomAbs_OffsetSurface: { GeomAbs_Shape BaseS = GeomAbs_CN; switch(S) { case GeomAbs_G1: case GeomAbs_G2: throw Standard_DomainError("GeomAdaptor_Curve::UIntervals"); case GeomAbs_C0: BaseS = GeomAbs_C1; break; case GeomAbs_C1: BaseS = GeomAbs_C2; break; case GeomAbs_C2: BaseS = GeomAbs_C3; break; case GeomAbs_C3: case GeomAbs_CN: break; } Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast); myNbUIntervals = Sur.NbUIntervals(BaseS); Sur.UIntervals(T, BaseS); return; } case GeomAbs_Plane: case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: case GeomAbs_BezierSurface: case GeomAbs_OtherSurface: case GeomAbs_SurfaceOfRevolution: break; } T(T.Lower()) = myUFirst; T(T.Lower() + myNbUIntervals) = myULast; } //======================================================================= //function : VIntervals //purpose : //======================================================================= void GeomAdaptor_Surface::VIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shape S) const { Standard_Integer myNbVIntervals = 1; switch (mySurfaceType) { case GeomAbs_BSplineSurface: { GeomAdaptor_Curve myBasisCurve (myBSplineSurface->UIso(myBSplineSurface->UKnot(myBSplineSurface->FirstUKnotIndex())),myVFirst,myVLast); myNbVIntervals = myBasisCurve.NbIntervals(S); myBasisCurve.Intervals(T,S); return; } case GeomAbs_SurfaceOfRevolution: { Handle(Geom_SurfaceOfRevolution) myRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(mySurface); GeomAdaptor_Curve myBasisCurve(myRevSurf->BasisCurve(), myVFirst, myVLast); if (myBasisCurve.GetType() == GeomAbs_BSplineCurve) { myNbVIntervals = myBasisCurve.NbIntervals(S); myBasisCurve.Intervals(T,S); return; } break; } case GeomAbs_OffsetSurface: { GeomAbs_Shape BaseS = GeomAbs_CN; switch(S) { case GeomAbs_G1: case GeomAbs_G2: throw Standard_DomainError("GeomAdaptor_Curve::VIntervals"); case GeomAbs_C0: BaseS = GeomAbs_C1; break; case GeomAbs_C1: BaseS = GeomAbs_C2; break; case GeomAbs_C2: BaseS = GeomAbs_C3; break; case GeomAbs_C3: case GeomAbs_CN: break; } Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast); myNbVIntervals = Sur.NbVIntervals(BaseS); Sur.VIntervals(T, BaseS); return; } case GeomAbs_Plane: case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: case GeomAbs_BezierSurface: case GeomAbs_OtherSurface: case GeomAbs_SurfaceOfExtrusion: break; } T(T.Lower()) = myVFirst; T(T.Lower() + myNbVIntervals) = myVLast; } //======================================================================= //function : UTrim //purpose : //======================================================================= Handle(Adaptor3d_HSurface) GeomAdaptor_Surface::UTrim(const Standard_Real First, const Standard_Real Last , const Standard_Real Tol ) const { return Handle(GeomAdaptor_HSurface) (new GeomAdaptor_HSurface(mySurface,First,Last,myVFirst,myVLast,Tol,myTolV)); } //======================================================================= //function : VTrim //purpose : //======================================================================= Handle(Adaptor3d_HSurface) GeomAdaptor_Surface::VTrim(const Standard_Real First, const Standard_Real Last , const Standard_Real Tol ) const { return Handle(GeomAdaptor_HSurface) (new GeomAdaptor_HSurface(mySurface,myUFirst,myULast,First,Last,myTolU,Tol)); } //======================================================================= //function : IsUClosed //purpose : //======================================================================= Standard_Boolean GeomAdaptor_Surface::IsUClosed() const { if (!mySurface->IsUClosed()) return Standard_False; Standard_Real U1,U2,V1,V2; mySurface->Bounds(U1,U2,V1,V2); if (mySurface->IsUPeriodic()) return (Abs(Abs(U1-U2)-Abs(myUFirst-myULast))IsVClosed()) return Standard_False; Standard_Real U1,U2,V1,V2; mySurface->Bounds(U1,U2,V1,V2); if (mySurface->IsVPeriodic()) return (Abs(Abs(V1-V2)-Abs(myVFirst-myVLast))IsUPeriodic()); } //======================================================================= //function : UPeriod //purpose : //======================================================================= Standard_Real GeomAdaptor_Surface::UPeriod() const { Standard_NoSuchObject_Raise_if(!IsUPeriodic()," "); return mySurface->UPeriod(); } //======================================================================= //function : IsVPeriodic //purpose : //======================================================================= Standard_Boolean GeomAdaptor_Surface::IsVPeriodic() const { return (mySurface->IsVPeriodic()); } //======================================================================= //function : VPeriod //purpose : //======================================================================= Standard_Real GeomAdaptor_Surface::VPeriod() const { Standard_NoSuchObject_Raise_if(!IsVPeriodic()," "); return mySurface->VPeriod(); } //======================================================================= //function : RebuildCache //purpose : //======================================================================= void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU, const Standard_Real theV) const { if (mySurfaceType == GeomAbs_BezierSurface) { // Create cache for Bezier Handle(Geom_BezierSurface) aBezier = Handle(Geom_BezierSurface)::DownCast(mySurface); Standard_Integer aDegU = aBezier->UDegree(); Standard_Integer aDegV = aBezier->VDegree(); TColStd_Array1OfReal aFlatKnotsU(BSplCLib::FlatBezierKnots(aDegU), 1, 2 * (aDegU + 1)); TColStd_Array1OfReal aFlatKnotsV(BSplCLib::FlatBezierKnots(aDegV), 1, 2 * (aDegV + 1)); if (mySurfaceCache.IsNull()) mySurfaceCache = new BSplSLib_Cache( aDegU, aBezier->IsUPeriodic(), aFlatKnotsU, aDegV, aBezier->IsVPeriodic(), aFlatKnotsV, aBezier->Weights()); mySurfaceCache->BuildCache (theU, theV, aFlatKnotsU, aFlatKnotsV, aBezier->Poles(), aBezier->Weights()); } else if (mySurfaceType == GeomAbs_BSplineSurface) { // Create cache for B-spline if (mySurfaceCache.IsNull()) mySurfaceCache = new BSplSLib_Cache( myBSplineSurface->UDegree(), myBSplineSurface->IsUPeriodic(), myBSplineSurface->UKnotSequence(), myBSplineSurface->VDegree(), myBSplineSurface->IsVPeriodic(), myBSplineSurface->VKnotSequence(), myBSplineSurface->Weights()); mySurfaceCache->BuildCache (theU, theV, myBSplineSurface->UKnotSequence(), myBSplineSurface->VKnotSequence(), myBSplineSurface->Poles(), myBSplineSurface->Weights()); } } //======================================================================= //function : Value //purpose : //======================================================================= gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U, const Standard_Real V) const { gp_Pnt aValue; D0(U, V, aValue); return aValue; } //======================================================================= //function : D0 //purpose : //======================================================================= void GeomAdaptor_Surface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt& P) const { switch (mySurfaceType) { case GeomAbs_BezierSurface: case GeomAbs_BSplineSurface: if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V)) RebuildCache(U, V); mySurfaceCache->D0(U, V, P); break; case GeomAbs_OffsetSurface: case GeomAbs_SurfaceOfExtrusion: case GeomAbs_SurfaceOfRevolution: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::D0: evaluator is not initialized"); myNestedEvaluator->D0(U, V, P); break; default: mySurface->D0(U, V, P); } } //======================================================================= //function : D1 //purpose : //======================================================================= void GeomAdaptor_Surface::D1(const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V ) const { Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0; Standard_Real u = U, v = V; if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;} else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;} if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;} else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;} switch(mySurfaceType) { case GeomAbs_BezierSurface: case GeomAbs_BSplineSurface: { if (!myBSplineSurface.IsNull() && (USide != 0 || VSide != 0) && IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) myBSplineSurface->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V); else { if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V)) RebuildCache(U, V); mySurfaceCache->D1(U, V, P, D1U, D1V); } break; } case GeomAbs_SurfaceOfExtrusion: case GeomAbs_SurfaceOfRevolution: case GeomAbs_OffsetSurface: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::D1: evaluator is not initialized"); myNestedEvaluator->D1(u, v, P, D1U, D1V); break; default: mySurface->D1(u, v, P, D1U, D1V); } } //======================================================================= //function : D2 //purpose : //======================================================================= void GeomAdaptor_Surface::D2(const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const { Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0; Standard_Real u = U, v = V; if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;} else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;} if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;} else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;} switch(mySurfaceType) { case GeomAbs_BezierSurface: case GeomAbs_BSplineSurface: { if (!myBSplineSurface.IsNull() && (USide != 0 || VSide != 0) && IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) myBSplineSurface->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV); else { if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V)) RebuildCache(U, V); mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV); } break; } case GeomAbs_SurfaceOfExtrusion : case GeomAbs_SurfaceOfRevolution : case GeomAbs_OffsetSurface : Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::D2: evaluator is not initialized"); myNestedEvaluator->D2(u, v, P, D1U, D1V, D2U, D2V, D2UV); break; default: { mySurface->D2(u, v, P, D1U, D1V, D2U, D2V, D2UV); break;} } } //======================================================================= //function : D3 //purpose : //======================================================================= void GeomAdaptor_Surface::D3(const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV, gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const { Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0; Standard_Real u = U, v = V; if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;} else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;} if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;} else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;} switch(mySurfaceType) { case GeomAbs_BSplineSurface: { if ((USide == 0) && (VSide == 0)) myBSplineSurface->D3(u, v, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); else { if (IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) myBSplineSurface->LocalD3(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); else myBSplineSurface->D3(u, v, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); } break; } case GeomAbs_SurfaceOfExtrusion : case GeomAbs_SurfaceOfRevolution : case GeomAbs_OffsetSurface: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::D3: evaluator is not initialized"); myNestedEvaluator->D3(u, v, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); break; default : { mySurface->D3(u,v,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break;} } } //======================================================================= //function : DN //purpose : //======================================================================= gp_Vec GeomAdaptor_Surface::DN(const Standard_Real U, const Standard_Real V, const Standard_Integer Nu, const Standard_Integer Nv) const { Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0; Standard_Real u = U, v = V; if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;} else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;} if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;} else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;} switch(mySurfaceType) { case GeomAbs_BSplineSurface: { if ((USide == 0) && (VSide == 0)) return myBSplineSurface->DN(u, v, Nu, Nv); else { if (IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) return myBSplineSurface->LocalDN(u, v, Ideb, Ifin, IVdeb, IVfin, Nu, Nv); else return myBSplineSurface->DN(u, v, Nu, Nv); } } case GeomAbs_SurfaceOfExtrusion: case GeomAbs_SurfaceOfRevolution: case GeomAbs_OffsetSurface: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::DN: evaluator is not initialized"); return myNestedEvaluator->DN(u, v, Nu, Nv); case GeomAbs_Plane: case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: case GeomAbs_BezierSurface: case GeomAbs_OtherSurface: default: break; } return mySurface->DN(u,v, Nu, Nv); } //======================================================================= //function : UResolution //purpose : //======================================================================= Standard_Real GeomAdaptor_Surface::UResolution(const Standard_Real R3d) const { Standard_Real Res = 0.; switch (mySurfaceType) { case GeomAbs_SurfaceOfExtrusion: { GeomAdaptor_Curve myBasisCurve (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast); return myBasisCurve.Resolution(R3d); } case GeomAbs_Torus: { Handle(Geom_ToroidalSurface) S (Handle(Geom_ToroidalSurface)::DownCast (mySurface)); const Standard_Real R = S->MajorRadius() + S->MinorRadius(); if(R>Precision::Confusion()) Res = R3d/(2.*R); break; } case GeomAbs_Sphere: { Handle(Geom_SphericalSurface) S (Handle(Geom_SphericalSurface)::DownCast (mySurface)); const Standard_Real R = S->Radius(); if(R>Precision::Confusion()) Res = R3d/(2.*R); break; } case GeomAbs_Cylinder: { Handle(Geom_CylindricalSurface) S (Handle(Geom_CylindricalSurface)::DownCast (mySurface)); const Standard_Real R = S->Radius(); if(R>Precision::Confusion()) Res = R3d/(2.*R); break; } case GeomAbs_Cone: { if (myVLast - myVFirst > 1.e10) { // Pas vraiment borne => resolution inconnue return Precision::Parametric(R3d); } Handle(Geom_ConicalSurface) S (Handle(Geom_ConicalSurface)::DownCast (mySurface)); Handle(Geom_Curve) C = S->VIso(myVLast); const Standard_Real Rayon1 = Handle(Geom_Circle)::DownCast (C)->Radius(); C = S->VIso(myVFirst); const Standard_Real Rayon2 = Handle(Geom_Circle)::DownCast (C)->Radius(); const Standard_Real R = (Rayon1 > Rayon2)? Rayon1 : Rayon2; return (R>Precision::Confusion()? (R3d / R) : 0.); } case GeomAbs_Plane: { return R3d; } case GeomAbs_BezierSurface: { Standard_Real Ures,Vres; Handle(Geom_BezierSurface)::DownCast (mySurface)->Resolution(R3d,Ures,Vres); return Ures; } case GeomAbs_BSplineSurface: { Standard_Real Ures,Vres; myBSplineSurface->Resolution(R3d,Ures,Vres); return Ures; } case GeomAbs_OffsetSurface: { Handle(Geom_Surface) base = Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface(); GeomAdaptor_Surface gabase(base,myUFirst,myULast,myVFirst,myVLast); return gabase.UResolution(R3d); } default: return Precision::Parametric(R3d); } if ( Res <= 1.) return 2.*ASin(Res); return 2.*M_PI; } //======================================================================= //function : VResolution //purpose : //======================================================================= Standard_Real GeomAdaptor_Surface::VResolution(const Standard_Real R3d) const { Standard_Real Res = 0.; switch (mySurfaceType) { case GeomAbs_SurfaceOfRevolution: { GeomAdaptor_Curve myBasisCurve (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast); return myBasisCurve.Resolution(R3d); } case GeomAbs_Torus: { Handle(Geom_ToroidalSurface) S (Handle(Geom_ToroidalSurface)::DownCast (mySurface)); const Standard_Real R = S->MinorRadius(); if(R>Precision::Confusion()) Res = R3d/(2.*R); break; } case GeomAbs_Sphere: { Handle(Geom_SphericalSurface) S (Handle(Geom_SphericalSurface)::DownCast (mySurface)); const Standard_Real R = S->Radius(); if(R>Precision::Confusion()) Res = R3d/(2.*R); break; } case GeomAbs_SurfaceOfExtrusion: case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Plane: { return R3d; } case GeomAbs_BezierSurface: { Standard_Real Ures,Vres; Handle(Geom_BezierSurface)::DownCast (mySurface)->Resolution(R3d,Ures,Vres); return Vres; } case GeomAbs_BSplineSurface: { Standard_Real Ures,Vres; myBSplineSurface->Resolution(R3d,Ures,Vres); return Vres; } case GeomAbs_OffsetSurface: { Handle(Geom_Surface) base = Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface(); GeomAdaptor_Surface gabase(base,myUFirst,myULast,myVFirst,myVLast); return gabase.VResolution(R3d); } default: return Precision::Parametric(R3d); } if ( Res <= 1.) return 2.*ASin(Res); return 2.*M_PI; } //======================================================================= //function : Plane //purpose : //======================================================================= gp_Pln GeomAdaptor_Surface::Plane() const { if (mySurfaceType != GeomAbs_Plane) throw Standard_NoSuchObject("GeomAdaptor_Surface::Plane"); return Handle(Geom_Plane)::DownCast (mySurface)->Pln(); } //======================================================================= //function : Cylinder //purpose : //======================================================================= gp_Cylinder GeomAdaptor_Surface::Cylinder() const { if (mySurfaceType != GeomAbs_Cylinder) throw Standard_NoSuchObject("GeomAdaptor_Surface::Cylinder"); return Handle(Geom_CylindricalSurface)::DownCast (mySurface)->Cylinder(); } //======================================================================= //function : Cone //purpose : //======================================================================= gp_Cone GeomAdaptor_Surface::Cone() const { if (mySurfaceType != GeomAbs_Cone) throw Standard_NoSuchObject("GeomAdaptor_Surface::Cone"); return Handle(Geom_ConicalSurface)::DownCast (mySurface)->Cone(); } //======================================================================= //function : Sphere //purpose : //======================================================================= gp_Sphere GeomAdaptor_Surface::Sphere() const { if (mySurfaceType != GeomAbs_Sphere) throw Standard_NoSuchObject("GeomAdaptor_Surface::Sphere"); return Handle(Geom_SphericalSurface)::DownCast (mySurface)->Sphere(); } //======================================================================= //function : Torus //purpose : //======================================================================= gp_Torus GeomAdaptor_Surface::Torus() const { if (mySurfaceType != GeomAbs_Torus) throw Standard_NoSuchObject("GeomAdaptor_Surface::Torus"); return Handle(Geom_ToroidalSurface)::DownCast (mySurface)->Torus(); } //======================================================================= //function : UDegree //purpose : //======================================================================= Standard_Integer GeomAdaptor_Surface::UDegree() const { if (mySurfaceType == GeomAbs_BSplineSurface) return myBSplineSurface->UDegree(); if ( mySurfaceType == GeomAbs_BezierSurface) return Handle(Geom_BezierSurface)::DownCast (mySurface)->UDegree(); if ( mySurfaceType == GeomAbs_SurfaceOfExtrusion) { GeomAdaptor_Curve myBasisCurve (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast); return myBasisCurve.Degree(); } throw Standard_NoSuchObject("GeomAdaptor_Surface::UDegree"); } //======================================================================= //function : NbUPoles //purpose : //======================================================================= Standard_Integer GeomAdaptor_Surface::NbUPoles() const { if (mySurfaceType == GeomAbs_BSplineSurface) return myBSplineSurface->NbUPoles(); if ( mySurfaceType == GeomAbs_BezierSurface) return Handle(Geom_BezierSurface)::DownCast (mySurface)->NbUPoles(); if ( mySurfaceType == GeomAbs_SurfaceOfExtrusion) { GeomAdaptor_Curve myBasisCurve (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast); return myBasisCurve.NbPoles(); } throw Standard_NoSuchObject("GeomAdaptor_Surface::NbUPoles"); } //======================================================================= //function : VDegree //purpose : //======================================================================= Standard_Integer GeomAdaptor_Surface::VDegree() const { if (mySurfaceType == GeomAbs_BSplineSurface) return myBSplineSurface->VDegree(); if ( mySurfaceType == GeomAbs_BezierSurface) return Handle(Geom_BezierSurface)::DownCast (mySurface)->VDegree(); if ( mySurfaceType == GeomAbs_SurfaceOfRevolution) { GeomAdaptor_Curve myBasisCurve (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast); return myBasisCurve.Degree(); } throw Standard_NoSuchObject("GeomAdaptor_Surface::VDegree"); } //======================================================================= //function : NbVPoles //purpose : //======================================================================= Standard_Integer GeomAdaptor_Surface::NbVPoles() const { if (mySurfaceType == GeomAbs_BSplineSurface) return myBSplineSurface->NbVPoles(); if ( mySurfaceType == GeomAbs_BezierSurface) return Handle(Geom_BezierSurface)::DownCast (mySurface)->NbVPoles(); if ( mySurfaceType == GeomAbs_SurfaceOfRevolution) { GeomAdaptor_Curve myBasisCurve (Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast); return myBasisCurve.NbPoles(); } throw Standard_NoSuchObject("GeomAdaptor_Surface::NbVPoles"); } //======================================================================= //function : NbUKnots //purpose : //======================================================================= Standard_Integer GeomAdaptor_Surface::NbUKnots() const { if (mySurfaceType == GeomAbs_BSplineSurface) return myBSplineSurface->NbUKnots(); if ( mySurfaceType == GeomAbs_SurfaceOfExtrusion) { GeomAdaptor_Curve myBasisCurve (Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(),myUFirst,myULast); return myBasisCurve.NbKnots(); } throw Standard_NoSuchObject("GeomAdaptor_Surface::NbUKnots"); } //======================================================================= //function : NbVKnots //purpose : //======================================================================= Standard_Integer GeomAdaptor_Surface::NbVKnots() const { if (mySurfaceType == GeomAbs_BSplineSurface) return myBSplineSurface->NbVKnots(); throw Standard_NoSuchObject("GeomAdaptor_Surface::NbVKnots"); } //======================================================================= //function : IsURational //purpose : //======================================================================= Standard_Boolean GeomAdaptor_Surface::IsURational() const { if (mySurfaceType == GeomAbs_BSplineSurface) return myBSplineSurface->IsURational(); if (mySurfaceType == GeomAbs_BezierSurface) return Handle(Geom_BezierSurface)::DownCast (mySurface)->IsURational(); return Standard_False; } //======================================================================= //function : IsVRational //purpose : //======================================================================= Standard_Boolean GeomAdaptor_Surface::IsVRational() const { if (mySurfaceType == GeomAbs_BSplineSurface) return myBSplineSurface->IsVRational(); if (mySurfaceType == GeomAbs_BezierSurface) return Handle(Geom_BezierSurface)::DownCast (mySurface)->IsVRational(); return Standard_False; } //======================================================================= //function : Bezier //purpose : //======================================================================= Handle(Geom_BezierSurface) GeomAdaptor_Surface::Bezier() const { if (mySurfaceType != GeomAbs_BezierSurface) throw Standard_NoSuchObject("GeomAdaptor_Surface::Bezier"); return Handle(Geom_BezierSurface)::DownCast (mySurface); } //======================================================================= //function : BSpline //purpose : //======================================================================= Handle(Geom_BSplineSurface) GeomAdaptor_Surface::BSpline() const { if (mySurfaceType != GeomAbs_BSplineSurface) throw Standard_NoSuchObject("GeomAdaptor_Surface::BSpline"); return myBSplineSurface; } //======================================================================= //function : AxeOfRevolution //purpose : //======================================================================= gp_Ax1 GeomAdaptor_Surface::AxeOfRevolution() const { if (mySurfaceType != GeomAbs_SurfaceOfRevolution) throw Standard_NoSuchObject("GeomAdaptor_Surface::AxeOfRevolution"); return Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->Axis(); } //======================================================================= //function : Direction //purpose : //======================================================================= gp_Dir GeomAdaptor_Surface::Direction() const { if (mySurfaceType != GeomAbs_SurfaceOfExtrusion) throw Standard_NoSuchObject("GeomAdaptor_Surface::Direction"); return Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->Direction(); } //======================================================================= //function : BasisCurve //purpose : //======================================================================= Handle(Adaptor3d_HCurve) GeomAdaptor_Surface::BasisCurve() const { Handle(Geom_Curve) C; if (mySurfaceType == GeomAbs_SurfaceOfExtrusion) C = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (mySurface)->BasisCurve(); else if (mySurfaceType == GeomAbs_SurfaceOfRevolution) C = Handle(Geom_SurfaceOfRevolution)::DownCast (mySurface)->BasisCurve(); else throw Standard_NoSuchObject("GeomAdaptor_Surface::BasisCurve"); return Handle(GeomAdaptor_HCurve)(new GeomAdaptor_HCurve(C)); } //======================================================================= //function : BasisSurface //purpose : //======================================================================= Handle(Adaptor3d_HSurface) GeomAdaptor_Surface::BasisSurface() const { if (mySurfaceType != GeomAbs_OffsetSurface) throw Standard_NoSuchObject("GeomAdaptor_Surface::BasisSurface"); return new GeomAdaptor_HSurface (Handle(Geom_OffsetSurface)::DownCast (mySurface)->BasisSurface(), myUFirst,myULast,myVFirst,myVLast); } //======================================================================= //function : OffsetValue //purpose : //======================================================================= Standard_Real GeomAdaptor_Surface::OffsetValue() const { if (mySurfaceType != GeomAbs_OffsetSurface) throw Standard_NoSuchObject("GeomAdaptor_Surface::BasisSurface"); return Handle(Geom_OffsetSurface)::DownCast (mySurface)->Offset(); } //======================================================================= //function : IfUVBound //purpose : locates U,V parameters if U,V =First, Last, // processes the finding span and returns the // parameters for LocalDi //======================================================================= Standard_Boolean GeomAdaptor_Surface::IfUVBound(const Standard_Real U, const Standard_Real V, Standard_Integer& IOutDeb, Standard_Integer& IOutFin, Standard_Integer& IOutVDeb, Standard_Integer& IOutVFin, const Standard_Integer USide, const Standard_Integer VSide) const { Standard_Integer Ideb,Ifin; Standard_Integer anUFKIndx = myBSplineSurface->FirstUKnotIndex(), anULKIndx = myBSplineSurface->LastUKnotIndex(), aVFKIndx = myBSplineSurface->FirstVKnotIndex(), aVLKIndx = myBSplineSurface->LastVKnotIndex(); myBSplineSurface->LocateU(U, PosTol, Ideb, Ifin, Standard_False); Standard_Boolean Local = (Ideb == Ifin); Span(USide,Ideb,Ifin,Ideb,Ifin,anUFKIndx,anULKIndx); Standard_Integer IVdeb,IVfin; myBSplineSurface->LocateV(V, PosTol, IVdeb, IVfin, Standard_False); if(IVdeb == IVfin) Local = Standard_True; Span(VSide,IVdeb,IVfin,IVdeb,IVfin,aVFKIndx,aVLKIndx); IOutDeb=Ideb; IOutFin=Ifin; IOutVDeb=IVdeb; IOutVFin=IVfin; return Local; } //======================================================================= //function : Span //purpose : locates U,V parameters if U=UFirst or U=ULast, // processes the finding span and returns the // parameters for LocalDi //======================================================================= void GeomAdaptor_Surface::Span(const Standard_Integer Side, const Standard_Integer Ideb, const Standard_Integer Ifin, Standard_Integer& OutIdeb, Standard_Integer& OutIfin, const Standard_Integer theFKIndx, const Standard_Integer theLKIndx) const { if(Ideb!=Ifin)//not a knot { if(IdebtheLKIndx) { OutIdeb=theLKIndx-1; OutIfin=theLKIndx; } else if(Ideb>=(theLKIndx-1)) { OutIdeb=theLKIndx-1; OutIfin=theLKIndx; } else if(Ifin<=theFKIndx+1) { OutIdeb=theFKIndx; OutIfin=theFKIndx+1; } else if(Ideb>Ifin) { OutIdeb=Ifin-1; OutIfin=Ifin; } else { OutIdeb=Ideb; OutIfin=Ifin; } } else { if(Ideb<=theFKIndx){ OutIdeb=theFKIndx; OutIfin=theFKIndx+1;}//first knot else if(Ifin>=theLKIndx) { OutIdeb=theLKIndx-1;OutIfin=theLKIndx;}//last knot else { if(Side==-1){OutIdeb=Ideb-1; OutIfin=Ifin;} else {OutIdeb=Ideb; OutIfin=Ifin+1;} } } }