-- File: BSplSLib.cdl -- Created: Mon Aug 26 07:44:24 1991 -- Author: JCV ---Copyright: Matra Datavision 1991 package BSplSLib --- Purpose : BSplSLib B-spline surface Library -- This package provides an implementation of geometric -- functions for rational and non rational, periodic and non -- periodic B-spline surface computation. -- -- this package uses the multi-dimensions splines methods -- provided in the package BSplCLib. -- -- In this package the B-spline surface is defined with : -- . its control points : Array2OfPnt Poles -- . its weights : Array2OfReal Weights -- . its knots and their multiplicity in the two parametric -- direction U and V : Array1OfReal UKnots, VKnots and -- Array1OfInteger UMults, VMults. -- . the degree of the normalized Spline functions : -- UDegree, VDegree -- -- . the Booleans URational, VRational to know if the weights -- are constant in the U or V direction. -- -- . the Booleans UPeriodic, VRational to know if the the -- surface is periodic in the U or V direction. -- -- Warnings : The bounds of UKnots and UMults should be the -- same, the bounds of VKnots and VMults should be the same, -- the bounds of Poles and Weights shoud be the same. -- -- The Control points representation is : -- Poles(Uorigin,Vorigin) ...................Poles(Uorigin,Vend) -- . . -- . . -- Poles(Uend, Vorigin) .....................Poles(Uend, Vend) -- -- For the double array the row indice corresponds to the -- parametric U direction and the columns indice corresponds -- to the parametric V direction. -- -- KeyWords : -- B-spline surface, Functions, Library -- -- References : -- . A survey of curve and surface methods in CADG Wolfgang BOHM -- CAGD 1 (1984) -- . On de Boor-like algorithms and blossoming Wolfgang BOEHM -- cagd 5 (1988) -- . Blossoming and knot insertion algorithms for B-spline curves -- Ronald N. GOLDMAN -- . Modelisation des surfaces en CAO, Henri GIAUME Peugeot SA -- . Curves and Surfaces for Computer Aided Geometric Design, -- a practical guide Gerald Farin uses TColStd, gp, TColgp is imported EvaluatorFunction ; ---Purpose: -- this is a one dimensional function -- typedef void (*EvaluatorFunction) ( -- Standard_Integer // Derivative Request -- Standard_Real * // StartEnd[2][2] -- // [0] = U -- // [1] = V -- // [0] = start -- // [1] = end -- Standard_Real // UParameter -- Standard_Real // VParamerer -- Standard_Real & // Result -- Standard_Integer &) ;// Error Code -- serves to multiply a given vectorial BSpline by a function ------------------------------------------------------------- ------------------------------------------------------------- ---------- ----------- ---------- Surface Evaluations ----------- ---------- ----------- ------------------------------------------------------------- ------------------------------------------------------------- RationalDerivative(UDeg,VDeg : Integer; N,M : Integer; Ders : in out Real; RDers : in out Real; All : Boolean = Standard_True); ---Purpose: Computes the derivatives of a ratio of -- two-variables functions x(u,v) / w(u,v) at orders -- , x(u,v) is a vector in dimension -- <3>. -- -- is an array containing the values of the -- input derivatives from 0 to Min(,), 0 to -- Min(,). For orders higher than -- the input derivatives are assumed to -- be 0. -- -- The is a 2d array and the dimension of the -- lines is always (+1) * (<3>+1), even -- if is smaller than (the derivatives -- higher than are not used). -- -- Content of : -- -- x(i,j)[k] means : the composant k of x derivated -- (i) times in u and (j) times in v. -- -- ... First line ... -- -- x[1],x[2],...,x[3],w -- x(0,1)[1],...,x(0,1)[3],w(1,0) -- ... -- x(0,VDeg)[1],...,x(0,VDeg)[3],w(0,VDeg) -- -- ... Then second line ... -- -- x(1,0)[1],...,x(1,0)[3],w(1,0) -- x(1,1)[1],...,x(1,1)[3],w(1,1) -- ... -- x(1,VDeg)[1],...,x(1,VDeg)[3],w(1,VDeg) -- -- ... -- -- ... Last line ... -- -- x(UDeg,0)[1],...,x(UDeg,0)[3],w(UDeg,0) -- x(UDeg,1)[1],...,x(UDeg,1)[3],w(UDeg,1) -- ... -- x(Udeg,VDeg)[1],...,x(UDeg,VDeg)[3],w(Udeg,VDeg) -- -- -- -- If is false, only the derivative at order -- is computed. is an array of length -- 3 which will contain the result : -- -- x(1)/w , x(2)/w , ... derivated times -- -- If is true multiples derivatives are -- computed. All the derivatives (i,j) with 0 <= i+j -- <= Max(N,M) are computed. is an array of -- length 3 * (+1) * (+1) which will -- contains : -- -- x(1)/w , x(2)/w , ... -- x(1)/w , x(2)/w , ... derivated <0,1> times -- x(1)/w , x(2)/w , ... derivated <0,2> times -- ... -- x(1)/w , x(2)/w , ... derivated <0,N> times -- -- x(1)/w , x(2)/w , ... derivated <1,0> times -- x(1)/w , x(2)/w , ... derivated <1,1> times -- ... -- x(1)/w , x(2)/w , ... derivated <1,N> times -- -- x(1)/w , x(2)/w , ... derivated times -- .... -- Warning: must be dimensionned properly. D0 (U, V : in Real; UIndex, VIndex : in Integer; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; UKnots, VKnots : in Array1OfReal from TColStd; UMults, VMults : in Array1OfInteger from TColStd; UDegree, VDegree : in Integer; URat,VRat : in Boolean; UPer,VPer : in Boolean; P : out Pnt from gp); D1 (U, V : in Real; UIndex, VIndex : in Integer; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; UKnots, VKnots : in Array1OfReal from TColStd; UMults, VMults : in Array1OfInteger from TColStd; Degree, VDegree : in Integer; URat,VRat : in Boolean; UPer,VPer : in Boolean; P : out Pnt from gp; Vu, Vv : out Vec from gp); D2 (U, V : in Real; UIndex, VIndex : in Integer; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; UKnots, VKnots : in Array1OfReal from TColStd; UMults, VMults : in Array1OfInteger from TColStd; UDegree, VDegree : in Integer; URat,VRat : in Boolean; UPer,VPer : in Boolean; P : out Pnt from gp; Vu, Vv : out Vec from gp; Vuu, Vvv, Vuv : out Vec from gp); D3 (U, V : in Real; UIndex, VIndex : in Integer; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; UKnots, VKnots : in Array1OfReal from TColStd; UMults, VMults : in Array1OfInteger from TColStd; UDegree, VDegree : in Integer; URat,VRat : in Boolean; UPer,VPer : in Boolean; P : out Pnt from gp; Vu, Vv : out Vec from gp; Vuu, Vvv, Vuv : out Vec from gp; Vuuu, Vvvv, Vuuv, Vuvv : out Vec from gp); DN (U, V : in Real; Nu, Nv : in Integer; UIndex, VIndex : in Integer; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; UKnots, VKnots : in Array1OfReal from TColStd; UMults, VMults : in Array1OfInteger from TColStd; UDegree, VDegree : in Integer; URat,VRat : in Boolean; UPer,VPer : in Boolean; Vn : out Vec from gp); Iso (Param : in Real; IsU : in Boolean; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; Knots : in Array1OfReal from TColStd; Mults : in Array1OfInteger from TColStd; Degree : in Integer; Periodic : in Boolean; CPoles : out Array1OfPnt from TColgp; CWeights : out Array1OfReal from TColStd); ---Purpose: Computes the poles and weights of an isoparametric -- curve at parameter (UIso if is True, -- VIso else). Reverse (Poles : in out Array2OfPnt from TColgp; Last : Integer from Standard; UDirection : Boolean from Standard); ---Purpose: Reverses the array of poles. Last is the Index of -- the new first Row( Col) of Poles. -- On a non periodic surface Last is -- Poles.Upper(). -- On a periodic curve last is -- (number of flat knots - degree - 1) -- or -- (sum of multiplicities(but for the last) + degree -- - 1) HomogeneousD0 (U, V : in Real; UIndex, VIndex : in Integer; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; UKnots, VKnots : in Array1OfReal from TColStd; UMults, VMults : in Array1OfInteger from TColStd; UDegree, VDegree : in Integer; URat,VRat : in Boolean; UPer,VPer : in Boolean; W : out Real ; P : out Pnt from gp); ---Purpose: Makes an homogeneous evaluation of Poles and Weights -- any and returns in P the Numerator value and -- in W the Denominator value if Weights are present -- otherwise returns 1.0e0 -- HomogeneousD1 (U, V : in Real; UIndex, VIndex : in Integer; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; UKnots, VKnots : in Array1OfReal from TColStd; UMults, VMults : in Array1OfInteger from TColStd; UDegree, VDegree : in Integer; URat,VRat : in Boolean; UPer,VPer : in Boolean; N : out Pnt from gp; Nu : out Vec from gp; Nv : out Vec from gp; D : out Real ; Du : out Real ; Dv : out Real) ; ---Purpose: Makes an homogeneous evaluation of Poles and Weights -- any and returns in P the Numerator value and -- in W the Denominator value if Weights are present -- otherwise returns 1.0e0 -- Reverse (Weights : in out Array2OfReal from TColStd; Last : Integer from Standard; UDirection : Boolean from Standard); ---Purpose: Reverses the array of weights. IsRational(Weights : Array2OfReal from TColStd; I1,I2 : Integer from Standard; J1,J2 : Integer from Standard; Epsilon : Real = 0.0) returns Boolean; ---Purpose: -- Returns False if all the weights of the array -- in the area [I1,I2] * [J1,J2] are identic. -- Epsilon is used for comparing weights. -- If Epsilon is 0. the Epsilon of the first weight is used. SetPoles(Poles : Array2OfPnt from TColgp; FP : out Array1OfReal from TColStd; UDirection : Boolean from Standard); ---Purpose: Copy in FP the coordinates of the poles. SetPoles(Poles : Array2OfPnt from TColgp; Weights : Array2OfReal from TColStd; FP : out Array1OfReal from TColStd; UDirection : Boolean from Standard); ---Purpose: Copy in FP the coordinates of the poles. GetPoles(FP : Array1OfReal from TColStd; Poles : out Array2OfPnt from TColgp; UDirection : Boolean from Standard); ---Purpose: Get from FP the coordinates of the poles. GetPoles(FP : Array1OfReal from TColStd; Poles : out Array2OfPnt from TColgp; Weights : out Array2OfReal from TColStd; UDirection : Boolean from Standard); ---Purpose: Get from FP the coordinates of the poles. MovePoint(U, V : Real; -- parameters of the point Displ : Vec from gp; -- translation vector of the point UIndex1 : Integer; -- first movable pole in U UIndex2 : Integer; -- last movable pole in U VIndex1 : Integer; -- first movable pole in V VIndex2 : Integer; -- last movable pole in V UDegree : Integer; VDegree : Integer; Rational : Boolean; Poles : Array2OfPnt from TColgp; Weights : Array2OfReal from TColStd; UFlatKnots : Array1OfReal from TColStd; VFlatKnots : Array1OfReal from TColStd; UFirstIndex : in out Integer; -- first pole modified in U ULastIndex : in out Integer; -- last pole modified in U VFirstIndex : in out Integer; -- first pole modified in V VLastIndex : in out Integer; -- last pole modified in V NewPoles : in out Array2OfPnt from TColgp); -- new poles ---Purpose: Find the new poles which allows an old point (with a -- given u,v as parameters) to reach a new position -- UIndex1,UIndex2 indicate the range of poles we can -- move for U -- (1, UNbPoles-1) or (2, UNbPoles) -> no constraint -- for one side in U -- (2, UNbPoles-1) -> the ends are enforced for U -- don't enter (1,NbPoles) and (1,VNbPoles) -- -> error: rigid move -- if problem in BSplineBasis calculation, no change -- for the curve and -- UFirstIndex, VLastIndex = 0 -- VFirstIndex, VLastIndex = 0 InsertKnots(UDirection : in Boolean from Standard; Degree : in Integer from Standard; Periodic : in Boolean from Standard; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; Knots : in Array1OfReal from TColStd; Mults : in Array1OfInteger from TColStd; AddKnots : in Array1OfReal from TColStd; AddMults : in Array1OfInteger from TColStd; NewPoles : out Array2OfPnt from TColgp; NewWeights : out Array2OfReal from TColStd; NewKnots : out Array1OfReal from TColStd; NewMults : out Array1OfInteger from TColStd; Epsilon : in Real from Standard; Add : in Boolean from Standard = Standard_True); RemoveKnot(UDirection : in Boolean from Standard; Index : in Integer from Standard; Mult : in Integer from Standard; Degree : in Integer from Standard; Periodic : in Boolean from Standard; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; Knots : in Array1OfReal from TColStd; Mults : in Array1OfInteger from TColStd; NewPoles : out Array2OfPnt from TColgp; NewWeights : out Array2OfReal from TColStd; NewKnots : out Array1OfReal from TColStd; NewMults : out Array1OfInteger from TColStd; Tolerance : in Real from Standard) returns Boolean from Standard; IncreaseDegree(UDirection : in Boolean from Standard; Degree : in Integer from Standard; NewDegree : in Integer from Standard; Periodic : in Boolean from Standard; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; Knots : in Array1OfReal from TColStd; Mults : in Array1OfInteger from TColStd; NewPoles : out Array2OfPnt from TColgp; NewWeights : out Array2OfReal from TColStd; NewKnots : out Array1OfReal from TColStd; NewMults : out Array1OfInteger from TColStd); Unperiodize(UDirection : in Boolean from Standard; Degree : in Integer from Standard; Mults : in Array1OfInteger from TColStd; Knots : in Array1OfReal from TColStd; Poles : in Array2OfPnt from TColgp; Weights : in Array2OfReal from TColStd; NewMults : out Array1OfInteger from TColStd; NewKnots : out Array1OfReal from TColStd; NewPoles : out Array2OfPnt from TColgp; NewWeights : out Array2OfReal from TColStd); NoWeights returns Array2OfReal from TColStd; ---Purpose: Used as argument for a non rational curve. -- ---C++: return & ---C++: inline BuildCache(U,V : Real; USpanDomain,VSpanDomain : Real; UPeriodicFlag,VPeriodicFlag : Boolean ; UDegree,VDegree : Integer; UIndex, VIndex : Integer; UFlatKnots,VFlatKnots : Array1OfReal from TColStd ; Poles : Array2OfPnt from TColgp; Weights : Array2OfReal from TColStd ; CachePoles : in out Array2OfPnt from TColgp; CacheWeights : in out Array2OfReal from TColStd); ---Purpose: Perform the evaluation of the Taylor expansion -- of the Bspline normalized between 0 and 1. -- If rational computes the homogeneous Taylor expension -- for the numerator and stores it in CachePoles -- -- CacheD0(U,V : Real; UDegree,VDegree : Integer; UCacheParameter,VCacheParameter : Real; USpanLenght,VSpanLength : Real; Poles : Array2OfPnt from TColgp ; Weights : Array2OfReal from TColStd ; Point : out Pnt from gp) ; ---Purpose: Perform the evaluation of the of the cache -- the parameter must be normalized between -- the 0 and 1 for the span. -- The Cache must be valid when calling this -- routine. Geom Package will insure that. -- and then multiplies by the weights -- this just evaluates the current point -- the CacheParameter is where the Cache was -- constructed the SpanLength is to normalize -- the polynomial in the cache to avoid bad conditioning -- effects -- CoefsD0(U,V : Real; Poles : Array2OfPnt from TColgp ; Weights : Array2OfReal from TColStd ; Point : out Pnt from gp) ; ---Purpose: Calls CacheD0 for Bezier Surfaces Arrays computed with -- the method PolesCoefficients. -- Warning: To be used for BezierSurfaces ONLY!!! ---C++: inline CacheD1(U,V : Real; UDegree,VDegree : Integer; UCacheParameter,VCacheParameter : Real; USpanLenght,VSpanLength : Real; Poles : Array2OfPnt from TColgp ; Weights : Array2OfReal from TColStd ; Point : out Pnt from gp; VecU, VecV : out Vec from gp) ; ---Purpose: Perform the evaluation of the of the cache -- the parameter must be normalized between -- the 0 and 1 for the span. -- The Cache must be valid when calling this -- routine. Geom Package will insure that. -- and then multiplies by the weights -- this just evaluates the current point -- the CacheParameter is where the Cache was -- constructed the SpanLength is to normalize -- the polynomial in the cache to avoid bad conditioning -- effects -- CoefsD1(U,V : Real; Poles : Array2OfPnt from TColgp; Weights : Array2OfReal from TColStd; Point : out Pnt from gp; VecU, VecV : out Vec from gp) ; ---Purpose: Calls CacheD0 for Bezier Surfaces Arrays computed with -- the method PolesCoefficients. -- Warning: To be used for BezierSurfaces ONLY!!! ---C++: inline CacheD2(U,V : Real; UDegree,VDegree : Integer; UCacheParameter,VCacheParameter : Real; USpanLenght,VSpanLength : Real; Poles : Array2OfPnt from TColgp ; Weights : Array2OfReal from TColStd ; Point : out Pnt from gp; VecU, VecV, VecUU, VecUV, VecVV : out Vec from gp) ; ---Purpose: Perform the evaluation of the of the cache -- the parameter must be normalized between -- the 0 and 1 for the span. -- The Cache must be valid when calling this -- routine. Geom Package will insure that. -- and then multiplies by the weights -- this just evaluates the current point -- the CacheParameter is where the Cache was -- constructed the SpanLength is to normalize -- the polynomial in the cache to avoid bad conditioning -- effects -- CoefsD2(U,V : Real; Poles : Array2OfPnt from TColgp ; Weights : Array2OfReal from TColStd ; Point : out Pnt from gp; VecU, VecV, VecUU, VecUV, VecVV : out Vec from gp) ; ---Purpose: Calls CacheD0 for Bezier Surfaces Arrays computed with -- the method PolesCoefficients. -- Warning: To be used for BezierSurfaces ONLY!!! ---C++: inline PolesCoefficients(Poles : Array2OfPnt from TColgp; CachePoles : in out Array2OfPnt from TColgp); ---Purpose: Warning! To be used for BezierSurfaces ONLY!!! ---C++: inline PolesCoefficients(Poles : Array2OfPnt from TColgp; Weights : Array2OfReal from TColStd ; CachePoles : in out Array2OfPnt from TColgp; CacheWeights : in out Array2OfReal from TColStd) ; ---Purpose: Encapsulation of BuildCache to perform the -- evaluation of the Taylor expansion for beziersurfaces -- at parameters 0.,0.; -- Warning: To be used for BezierSurfaces ONLY!!! -- Resolution(Poles : in Array2OfPnt from TColgp ; Weights : in Array2OfReal from TColStd; UKnots, VKnots : in Array1OfReal from TColStd; UMults, VMults : in Array1OfInteger from TColStd; UDegree, VDegree : in Integer; URat,VRat : in Boolean; UPer,VPer : in Boolean; Tolerance3D : in Real from Standard ; UTolerance : in out Real from Standard ; VTolerance : in out Real from Standard) ; ---Purpose: Given a tolerance in 3D space returns two -- tolerances, one in U one in V such that for -- all (u1,v1) and (u0,v0) in the domain of -- the surface f(u,v) we have : -- | u1 - u0 | < UTolerance and -- | v1 - v0 | < VTolerance -- we have |f (u1,v1) - f (u0,v0)| < Tolerance3D Interpolate(UDegree, VDegree : Integer ; UFlatKnots , VFlatKnots : Array1OfReal from TColStd ; UParameters, VParameters : Array1OfReal from TColStd ; Poles : in out Array2OfPnt from TColgp ; Weights : in out Array2OfReal from TColStd ; InversionProblem : out Integer) ; ---Purpose: Performs the interpolation of the data points given in -- the Poles array in the form -- [1,...,RL][1,...,RC][1...PolesDimension] . The -- ColLength CL and the Length of UParameters must be the -- same. The length of VFlatKnots is VDegree + CL + 1. -- -- The RowLength RL and the Length of VParameters must be -- the same. The length of VFlatKnots is Degree + RL + 1. -- -- Warning: the method used to do that interpolation -- is gauss elimination WITHOUT pivoting. Thus if the -- diagonal is not dominant there is no guarantee that -- the algorithm will work. Nevertheless for Cubic -- interpolation at knots or interpolation at Scheonberg -- points the method will work. The InversionProblem -- will report 0 if there was no problem else it will -- give the index of the faulty pivot -- Interpolate(UDegree, VDegree : Integer ; UFlatKnots , VFlatKnots : Array1OfReal from TColStd ; UParameters, VParameters : Array1OfReal from TColStd ; Poles : in out Array2OfPnt from TColgp ; InversionProblem : out Integer) ; ---Purpose: Performs the interpolation of the data points given in -- the Poles array. -- The ColLength CL and the Length of UParameters must be -- the same. The length of VFlatKnots is VDegree + CL + 1. -- -- The RowLength RL and the Length of VParameters must be -- the same. The length of VFlatKnots is Degree + RL + 1. -- -- Warning: the method used to do that interpolation -- is gauss elimination WITHOUT pivoting. Thus if the -- diagonal is not dominant there is no guarantee that -- the algorithm will work. Nevertheless for Cubic -- interpolation at knots or interpolation at Scheonberg -- points the method will work. The InversionProblem -- will report 0 if there was no problem else it will -- give the index of the faulty pivot -- FunctionMultiply( Function : EvaluatorFunction from BSplSLib ; UBSplineDegree : Integer ; VBSplineDegree : Integer ; UBSplineKnots : Array1OfReal from TColStd ; VBSplineKnots : Array1OfReal from TColStd ; UMults : Array1OfInteger from TColStd ; VMults : Array1OfInteger from TColStd ; Poles : Array2OfPnt from TColgp ; Weights : Array2OfReal from TColStd ; UFlatKnots : Array1OfReal from TColStd ; VFlatKnots : Array1OfReal from TColStd ; UNewDegree : Integer ; VNewDegree : Integer ; NewNumerator : in out Array2OfPnt from TColgp ; NewDenominator : in out Array2OfReal from TColStd ; Status : in out Integer) ; ---Purpose: this will multiply a given BSpline numerator N(u,v) -- and denominator D(u,v) defined by its -- U/VBSplineDegree and U/VBSplineKnots, and -- U/VMults. Its Poles and Weights are arrays which are -- coded as array2 of the form -- [1..UNumPoles][1..VNumPoles] by a function a(u,v) -- which is assumed to satisfy the following : 1. -- a(u,v) * N(u,v) and a(u,v) * D(u,v) is a polynomial -- BSpline that can be expressed exactly as a BSpline of -- degree U/VNewDegree on the knots U/VFlatKnots 2. the range -- of a(u,v) is the same as the range of N(u,v) -- or D(u,v) -- ---Warning: it is the caller's responsability to -- insure that conditions 1. and 2. above are satisfied -- : no check whatsoever is made in this method -- -- Status will return 0 if OK else it will return the -- pivot index -- of the matrix that was inverted to -- compute the multiplied -- BSpline : the method used -- is interpolation at Schoenenberg -- points of -- a(u,v)* N(u,v) and a(u,v) * D(u,v) -- Status will return 0 if OK else it will return the pivot index -- of the matrix that was inverted to compute the multiplied -- BSpline : the method used is interpolation at Schoenenberg -- points of a(u,v)*F(u,v) -- -- -- end BSplSLib;