// File generated by CPPExt (Transient)
//
//
//                     Copyright (C) 1991 - 2000 by  
//                      Matra Datavision SA.  All rights reserved.
//  
//                     Copyright (C) 2001 - 2004 by
//                     Open CASCADE SA.  All rights reserved.
// 
// This file is part of the Open CASCADE Technology software.
//
// This software may be distributed and/or modified under the terms and
// conditions of the Open CASCADE Public License as defined by Open CASCADE SA
// and appearing in the file LICENSE included in the packaging of this file.
//  
// This software is distributed on an "AS IS" basis, without warranty of any
// kind, and Open CASCADE SA hereby disclaims all such warranties,
// including without limitation, any warranties of merchantability, fitness
// for a particular purpose or non-infringement. Please see the License for
// the specific terms and conditions governing rights and limitations under the
// License.

#ifndef _Geom_BSplineSurface_HeaderFile
#define _Geom_BSplineSurface_HeaderFile

#ifndef _Standard_HeaderFile
#include <Standard.hxx>
#endif
#ifndef _Handle_Geom_BSplineSurface_HeaderFile
#include <Handle_Geom_BSplineSurface.hxx>
#endif

#ifndef _Standard_Boolean_HeaderFile
#include <Standard_Boolean.hxx>
#endif
#ifndef _GeomAbs_BSplKnotDistribution_HeaderFile
#include <GeomAbs_BSplKnotDistribution.hxx>
#endif
#ifndef _GeomAbs_Shape_HeaderFile
#include <GeomAbs_Shape.hxx>
#endif
#ifndef _Standard_Integer_HeaderFile
#include <Standard_Integer.hxx>
#endif
#ifndef _Handle_TColgp_HArray2OfPnt_HeaderFile
#include <Handle_TColgp_HArray2OfPnt.hxx>
#endif
#ifndef _Handle_TColStd_HArray2OfReal_HeaderFile
#include <Handle_TColStd_HArray2OfReal.hxx>
#endif
#ifndef _Handle_TColStd_HArray1OfReal_HeaderFile
#include <Handle_TColStd_HArray1OfReal.hxx>
#endif
#ifndef _Handle_TColStd_HArray1OfInteger_HeaderFile
#include <Handle_TColStd_HArray1OfInteger.hxx>
#endif
#ifndef _Standard_Real_HeaderFile
#include <Standard_Real.hxx>
#endif
#ifndef _Geom_BoundedSurface_HeaderFile
#include <Geom_BoundedSurface.hxx>
#endif
#ifndef _Handle_Geom_Curve_HeaderFile
#include <Handle_Geom_Curve.hxx>
#endif
#ifndef _Handle_Geom_Geometry_HeaderFile
#include <Handle_Geom_Geometry.hxx>
#endif
class TColgp_HArray2OfPnt;
class TColStd_HArray2OfReal;
class TColStd_HArray1OfReal;
class TColStd_HArray1OfInteger;
class Standard_ConstructionError;
class Standard_DimensionError;
class Standard_DomainError;
class Standard_OutOfRange;
class Standard_NoSuchObject;
class Standard_RangeError;
class Geom_UndefinedDerivative;
class TColgp_Array2OfPnt;
class TColStd_Array1OfReal;
class TColStd_Array1OfInteger;
class TColStd_Array2OfReal;
class gp_Pnt;
class TColgp_Array1OfPnt;
class gp_Vec;
class Geom_Curve;
class gp_Trsf;
class Geom_Geometry;


//! Describes a BSpline surface. <br>
//! In each parametric direction, a BSpline surface can be: <br>
//! - uniform or non-uniform, <br>
//! - rational or non-rational, <br>
//! - periodic or non-periodic. <br>
//! A BSpline surface is defined by: <br>
//! - its degrees, in the u and v parametric directions, <br>
//! - its periodic characteristic, in the u and v parametric directions, <br>
//! - a table of poles, also called control points (together <br>
//!   with the associated weights if the surface is rational), and <br>
//! - a table of knots, together with the associated multiplicities. <br>
//!   The degree of a Geom_BSplineSurface is limited to <br>
//! a value (25) which is defined and controlled by the <br>
//! system. This value is returned by the function MaxDegree. <br>
//!       Poles and Weights <br>
//! Poles and Weights are manipulated using two associative double arrays: <br>
//! - the poles table, which is a double array of gp_Pnt points, and <br>
//! - the weights table, which is a double array of reals. <br>
//! The bounds of the poles and weights arrays are: <br>
//! - 1 and NbUPoles for the row bounds (provided <br>
//!   that the BSpline surface is not periodic in the u <br>
//!   parametric direction), where NbUPoles is the <br>
//!   number of poles of the surface in the u parametric direction, and <br>
//! - 1 and NbVPoles for the column bounds (provided <br>
//!   that the BSpline surface is not periodic in the v <br>
//!   parametric direction), where NbVPoles is the <br>
//!   number of poles of the surface in the v parametric direction. <br>
//!   The poles of the surface are the points used to shape <br>
//! and reshape the surface. They comprise a rectangular network. <br>
//! If the surface is not periodic: <br>
//! - The points (1, 1), (NbUPoles, 1), (1, <br>
//!   NbVPoles), and (NbUPoles, NbVPoles) <br>
//!   are the four parametric "corners" of the surface. <br>
//! - The first column of poles and the last column of <br>
//!   poles define two BSpline curves which delimit the <br>
//!   surface in the v parametric direction. These are the <br>
//!   v isoparametric curves corresponding to the two <br>
//!   bounds of the v parameter. <br>
//! - The first row of poles and the last row of poles <br>
//!   define two BSpline curves which delimit the surface <br>
//!   in the u parametric direction. These are the u <br>
//!   isoparametric curves corresponding to the two bounds of the u parameter. <br>
//! If the surface is periodic, these geometric properties are not verified. <br>
//! It is more difficult to define a geometrical significance <br>
//! for the weights. However they are useful for <br>
//! representing a quadric surface precisely. Moreover, if <br>
//! the weights of all the poles are equal, the surface has <br>
//! a polynomial equation, and hence is a "non-rational surface". <br>
//! The non-rational surface is a special, but frequently <br>
//! used, case, where all poles have identical weights. <br>
//! The weights are defined and used only in the case of <br>
//! a rational surface. The rational characteristic is <br>
//! defined in each parametric direction. A surface can be <br>
//! rational in the u parametric direction, and <br>
//! non-rational in the v parametric direction. <br>
//!        Knots and Multiplicities <br>
//! For a Geom_BSplineSurface the table of knots is <br>
//! made up of two increasing sequences of reals, without <br>
//! repetition, one for each parametric direction. The <br>
//! multiplicities define the repetition of the knots. <br>
//! A BSpline surface comprises multiple contiguous <br>
//! patches, which are themselves polynomial or rational <br>
//! surfaces. The knots are the parameters of the <br>
//! isoparametric curves which limit these contiguous <br>
//! patches. The multiplicity of a knot on a BSpline <br>
//! surface (in a given parametric direction) is related to <br>
//! the degree of continuity of the surface at that knot in <br>
//! that parametric direction: <br>
//! Degree of continuity at knot(i) = Degree - Multi(i) where: <br>
//! - Degree is the degree of the BSpline surface in <br>
//!   the given parametric direction, and <br>
//! - Multi(i) is the multiplicity of knot number i in <br>
//!   the given parametric direction. <br>
//! There are some special cases, where the knots are <br>
//! regularly spaced in one parametric direction (i.e. the <br>
//! difference between two consecutive knots is a constant). <br>
//! - "Uniform": all the multiplicities are equal to 1. <br>
//! - "Quasi-uniform": all the multiplicities are equal to 1, <br>
//!   except for the first and last knots in this parametric <br>
//!   direction, and these are equal to Degree + 1. <br>
//! - "Piecewise Bezier": all the multiplicities are equal to <br>
//!   Degree except for the first and last knots, which <br>
//!   are equal to Degree + 1. This surface is a <br>
//!   concatenation of Bezier patches in the given <br>
//!   parametric direction. <br>
//! If the BSpline surface is not periodic in a given <br>
//! parametric direction, the bounds of the knots and <br>
//! multiplicities tables are 1 and NbKnots, where <br>
//! NbKnots is the number of knots of the BSpline <br>
//! surface in that parametric direction. <br>
//! If the BSpline surface is periodic in a given parametric <br>
//! direction, and there are k periodic knots and p <br>
//! periodic poles in that parametric direction: <br>
//! - the period is such that: <br>
//! period = Knot(k+1) - Knot(1), and <br>
//! - the poles and knots tables in that parametric <br>
//!   direction can be considered as infinite tables, such that: <br>
//! Knot(i+k) = Knot(i) + period, and <br>
//! Pole(i+p) = Pole(i) <br>
//! Note: The data structure tables for a periodic BSpline <br>
//! surface are more complex than those of a non-periodic one. <br>
//! References : <br>
//!  . A survey of curve and surface methods in CADG Wolfgang BOHM <br>
//!    CAGD 1 (1984) <br>
//!  . On de Boor-like algorithms and blossoming Wolfgang BOEHM <br>
//!    cagd 5 (1988) <br>
//!  . Blossoming and knot insertion algorithms for B-spline curves <br>
//!    Ronald N. GOLDMAN <br>
//!  . Modelisation des surfaces en CAO, Henri GIAUME Peugeot SA <br>
//!  . Curves and Surfaces for Computer Aided Geometric Design, <br>
//!    a practical guide Gerald Farin <br>
class Geom_BSplineSurface : public Geom_BoundedSurface {

public:
 // Methods PUBLIC
 // 

//! Creates  a non-rational b-spline surface (weights <br>
//!         default value is 1.). <br>//! The following conditions must be verified. <br>
//!   0 < UDegree <= MaxDegree. <br>
//!   UKnots.Length() == UMults.Length() >= 2 <br>
//!   UKnots(i) < UKnots(i+1) (Knots are increasing) <br>
//!   1 <= UMults(i) <= UDegree <br>
//!   On a   non  uperiodic   surface    the  first and    last <br>
//!   umultiplicities  may  be     UDegree+1  (this   is   even <br>
//!   recommanded if you want the curve  to start and finish on <br>
//!   the first and last pole). <br>
//!   On a uperiodic     surface  the first    and   the   last <br>
//!   umultiplicities must be the same. <br>
//!   on non-uperiodic surfaces <br>
//!     Poles.ColLength() == Sum(UMults(i)) - UDegree - 1 >= 2 <br>
//!   on uperiodic surfaces <br>
//!   Poles.ColLength() == Sum(UMults(i)) except the first or last <br>
//!   The previous conditions for U holds  also for V, with the <br>
//!   RowLength of the poles. <br>
Standard_EXPORT Geom_BSplineSurface(const TColgp_Array2OfPnt& Poles,const TColStd_Array1OfReal& UKnots,const TColStd_Array1OfReal& VKnots,const TColStd_Array1OfInteger& UMults,const TColStd_Array1OfInteger& VMults,const Standard_Integer UDegree,const Standard_Integer VDegree,const Standard_Boolean UPeriodic = Standard_False,const Standard_Boolean VPeriodic = Standard_False);

//! Creates  a non-rational b-spline surface (weights <br>
//!         default value is 1.). <br>
//! <br>//! The following conditions must be verified. <br>
//!  0 < UDegree <= MaxDegree. <br>
//! <br>
//!  UKnots.Length() == UMults.Length() >= 2 <br>
//! <br>
//!  UKnots(i) < UKnots(i+1) (Knots are increasing) <br>
//!  1 <= UMults(i) <= UDegree <br>
//! <br>
//!   On a   non  uperiodic   surface    the  first and    last <br>
//!   umultiplicities  may  be     UDegree+1  (this   is   even <br>
//!   recommanded if you want the curve  to start and finish on <br>
//!   the first and last pole). <br>
//! <br>
//!   On a uperiodic     surface  the first    and   the   last <br>
//!   umultiplicities must be the same. <br>
//! <br>
//!   on non-uperiodic surfaces <br>
//! <br>
//!     Poles.ColLength() == Sum(UMults(i)) - UDegree - 1 >= 2 <br>
//! <br>
//!   on uperiodic surfaces <br>
//! <br>
//!     Poles.ColLength() == Sum(UMults(i)) except the first or <br>
//!     last <br>
//! <br>
//! <br>
//!   The previous conditions for U holds  also for V, with the <br>
//!   RowLength of the poles. <br>
Standard_EXPORT Geom_BSplineSurface(const TColgp_Array2OfPnt& Poles,const TColStd_Array2OfReal& Weights,const TColStd_Array1OfReal& UKnots,const TColStd_Array1OfReal& VKnots,const TColStd_Array1OfInteger& UMults,const TColStd_Array1OfInteger& VMults,const Standard_Integer UDegree,const Standard_Integer VDegree,const Standard_Boolean UPeriodic = Standard_False,const Standard_Boolean VPeriodic = Standard_False);

//! Exchanges the u and v parametric directions on <br>
//! this BSpline surface. <br>
//! As a consequence: <br>
//! - the poles and weights tables are transposed, <br>
//! - the knots and multiplicities tables are exchanged, <br>
//! - degrees of continuity, and rational, periodic and <br>
//!   uniform characteristics are exchanged, and <br>
//! - the orientation of the surface is inverted. <br>
Standard_EXPORT   void ExchangeUV() ;

//! Sets the surface U periodic. <br>
Standard_EXPORT   void SetUPeriodic() ;

//!  Modifies this surface to be periodic in the u (or v) <br>
//! parametric direction. <br>
//! To become periodic in a given parametric direction a <br>
//! surface must be closed in that parametric direction, <br>
//! and the knot sequence relative to that direction must be periodic. <br>
//! To generate this periodic sequence of knots, the <br>
//! functions FirstUKnotIndex and LastUKnotIndex (or <br>
//! FirstVKnotIndex and LastVKnotIndex) are used to <br>
//! compute I1 and I2. These are the indexes, in the <br>
//! knot array associated with the given parametric <br>
//! direction, of the knots that correspond to the first and <br>
//! last parameters of this BSpline surface in the given <br>
//! parametric direction. Hence the period is: <br>
//! Knots(I1) - Knots(I2) <br>
//! As a result, the knots and poles tables are modified. <br>
//! Exceptions <br>
//! Standard_ConstructionError if the surface is not <br>
//! closed in the given parametric direction. <br>
Standard_EXPORT   void SetVPeriodic() ;

//! returns the parameter normalized within <br>
//!         the period if the surface is periodic : otherwise <br>
//!         does not do anything <br>
Standard_EXPORT   void PeriodicNormalization(Standard_Real& U,Standard_Real& V) const;

//! Assigns the knot of index Index in the knots table in <br>
//! the corresponding parametric direction to be the <br>
//! origin of this periodic BSpline surface. As a <br>
//! consequence, the knots and poles tables are modified. <br>
//! Exceptions <br>
//! Standard_NoSuchObject if this BSpline surface is <br>
//! not periodic in the given parametric direction. <br>
//! Standard_DomainError if Index is outside the <br>
//! bounds of the knots table in the given parametric direction. <br>
Standard_EXPORT   void SetUOrigin(const Standard_Integer Index) ;

//! Assigns the knot of index Index in the knots table in <br>
//! the corresponding parametric direction to be the <br>
//! origin of this periodic BSpline surface. As a <br>
//! consequence, the knots and poles tables are modified. <br>
//! Exceptions <br>
//! Standard_NoSuchObject if this BSpline surface is <br>
//! not periodic in the given parametric direction. <br>
//! Standard_DomainError if Index is outside the <br>
//! bounds of the knots table in the given parametric direction. <br>
Standard_EXPORT   void SetVOrigin(const Standard_Integer Index) ;


Standard_EXPORT   void SetUNotPeriodic() ;

//! Modifies this surface to be periodic in the u (or v) parametric direction. <br>
//! To become periodic in a given parametric direction a <br>
//! surface must be closed in that parametric direction, <br>
//! and the knot sequence relative to that direction must be periodic. <br>
//! To generate this periodic sequence of knots, the <br>
//! functions FirstUKnotIndex and LastUKnotIndex (or <br>
//! FirstVKnotIndex and LastVKnotIndex) are used to <br>
//! compute I1 and I2. These are the indexes, in the <br>
//! knot array associated with the given parametric <br>
//! direction, of the knots that correspond to the first and <br>
//! last parameters of this BSpline surface in the given <br>
//! parametric direction. Hence the period is: <br>
//! Knots(I1) - Knots(I2) <br>
//! As a result, the knots and poles tables are modified. <br>
//! Exceptions <br>
//! Standard_ConstructionError if the surface is not <br>
//! closed in the given parametric direction. <br>
Standard_EXPORT   void SetVNotPeriodic() ;


Standard_EXPORT   void UReverse() ;

//! Changes the orientation of this BSpline surface in the <br>
//! u (or v) parametric direction. The bounds of the <br>
//! surface are not changed but the given parametric <br>
//! direction is reversed. Hence the orientation of the <br>
//! surface is reversed. <br>
//! The knots and poles tables are modified. <br>
Standard_EXPORT   void VReverse() ;


Standard_EXPORT   Standard_Real UReversedParameter(const Standard_Real U) const;

//! Computes the u (or v) parameter on the modified <br>
//! surface, produced by reversing its u (or v) parametric <br>
//! direction, for the point of u parameter U, (or of v <br>
//! parameter V) on this BSpline surface. <br>
//! For a BSpline surface, these functions return respectively: <br>
//! - UFirst + ULast - U, or <br>
//! - VFirst + VLast - V, <br>
//! where UFirst, ULast, VFirst and VLast are <br>
//! the values of the first and last parameters of this <br>
//! BSpline surface, in the u and v parametric directions. <br>
Standard_EXPORT   Standard_Real VReversedParameter(const Standard_Real V) const;

//! Increases the degrees of this BSpline surface to <br>
//! UDegree and VDegree in the u and v parametric <br>
//! directions respectively. As a result, the tables of poles, <br>
//! weights and multiplicities are modified. The tables of <br>
//! knots is not changed. <br>
//! Note: Nothing is done if the given degree is less than <br>
//! or equal to the current degree in the corresponding <br>
//! parametric direction. <br>
//! Exceptions <br>
//! Standard_ConstructionError if UDegree or <br>
//! VDegree is greater than <br>
//! Geom_BSplineSurface::MaxDegree(). <br>
Standard_EXPORT   void IncreaseDegree(const Standard_Integer UDegree,const Standard_Integer VDegree) ;


Standard_EXPORT   void InsertUKnots(const TColStd_Array1OfReal& Knots,const TColStd_Array1OfInteger& Mults,const Standard_Real ParametricTolerance = 0.0,const Standard_Boolean Add = Standard_True) ;

//! Inserts into the knots table for the corresponding <br>
//! parametric direction of this BSpline surface: <br>
//! - the value U, or V, with the multiplicity M (defaulted to 1), or <br>
//! - the values of the array Knots, with their respective <br>
//! multiplicities, Mults. <br>
//! If the knot value to insert already exists in the table, its multiplicity is: <br>
//! - increased by M, if Add is true (the default), or <br>
//! - increased to M, if Add is false. <br>
//! The tolerance criterion used to check the equality of <br>
//! the knots is the larger of the values ParametricTolerance and <br>
//! Standard_Real::Epsilon(val), where val is the knot value to be inserted. <br>
//! Warning <br>
//! - If a given multiplicity coefficient is null, or negative, nothing is done. <br>
//! - The new multiplicity of a knot is limited to the degree of this BSpline surface in the <br>
//!   corresponding parametric direction. <br>
//! Exceptions <br>
//! Standard_ConstructionError if a knot value to <br>
//! insert is outside the bounds of this BSpline surface in <br>
//! the specified parametric direction. The comparison <br>
//! uses the precision criterion ParametricTolerance. <br>
Standard_EXPORT   void InsertVKnots(const TColStd_Array1OfReal& Knots,const TColStd_Array1OfInteger& Mults,const Standard_Real ParametricTolerance = 0.0,const Standard_Boolean Add = Standard_True) ;


Standard_EXPORT   Standard_Boolean RemoveUKnot(const Standard_Integer Index,const Standard_Integer M,const Standard_Real Tolerance) ;

//! Reduces to M the multiplicity of the knot of index <br>
//! Index in the given parametric direction. If M is 0, the knot is removed. <br>
//! With a modification of this type, the table of poles is also modified. <br>
//! Two different algorithms are used systematically to <br>
//! compute the new poles of the surface. For each <br>
//! pole, the distance between the pole calculated <br>
//! using the first algorithm and the same pole <br>
//! calculated using the second algorithm, is checked. If <br>
//! this distance is less than Tolerance it ensures that <br>
//! the surface is not modified by more than Tolerance. <br>
//! Under these conditions, the function returns true; <br>
//! otherwise, it returns false. <br>
//! A low tolerance prevents modification of the <br>
//! surface. A high tolerance "smoothes" the surface. <br>
//! Exceptions <br>
//! Standard_OutOfRange if Index is outside the <br>
//! bounds of the knots table of this BSpline surface. <br>
Standard_EXPORT   Standard_Boolean RemoveVKnot(const Standard_Integer Index,const Standard_Integer M,const Standard_Real Tolerance) ;


//!  Increases the multiplicity of the knot of range UIndex <br>
//!  in the UKnots sequence. <br>
//!  M is the new multiplicity. M must be greater than the <br>
//!  previous multiplicity and lower or equal to the degree <br>
//!  of the surface in the U parametric direction. <br>//! Raised if M is not in the range [1, UDegree] <br>
//!  Raised if UIndex is not in the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex] given by the methods with the same name. <br>
Standard_EXPORT   void IncreaseUMultiplicity(const Standard_Integer UIndex,const Standard_Integer M) ;


//!  Increases until order M the multiplicity of the set of knots <br>
//!  FromI1,...., ToI2 in the U direction. This method can be used <br>
//!  to make a B_spline surface into a PiecewiseBezier B_spline <br>
//!  surface. <br>
//!  If <me> was uniform, it can become non uniform. <br>
//!  Raised if FromI1 or ToI2 is out of the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex]. <br>
//!  M should be greater than the previous multiplicity of the <br>
//!  all the knots FromI1,..., ToI2 and lower or equal to the <br>
//!   Degree of the surface in the U parametric direction. <br>
Standard_EXPORT   void IncreaseUMultiplicity(const Standard_Integer FromI1,const Standard_Integer ToI2,const Standard_Integer M) ;


//!  Increments the multiplicity of the consecutives uknots FromI1..ToI2 <br>
//!  by step.   The multiplicity of each knot FromI1,.....,ToI2 must be <br>
//!  lower or equal to the UDegree of the B_spline. <br>
//!  Raised if FromI1 or ToI2 is not in the range <br>
//!  [FirstUKnotIndex, LastUKnotIndex] <br>
//!  Raised if one knot has a multiplicity greater than UDegree. <br>
Standard_EXPORT   void IncrementUMultiplicity(const Standard_Integer FromI1,const Standard_Integer ToI2,const Standard_Integer Step) ;


//!  Increases the multiplicity of a knot in the V direction. <br>
//!  M is the new multiplicity. <br>
//!  M should be greater than the previous multiplicity and lower <br>
//!  than the degree of the surface in the V parametric direction. <br>
//!  Raised if VIndex is not in the range [FirstVKnotIndex, <br>
//!  LastVKnotIndex] given by the methods with the same name. <br>
Standard_EXPORT   void IncreaseVMultiplicity(const Standard_Integer VIndex,const Standard_Integer M) ;


//!  Increases until order M the multiplicity of the set of knots <br>
//!  FromI1,...., ToI2 in the V direction. This method can be used to <br>
//!  make a BSplineSurface into a PiecewiseBezier B_spline <br>
//!  surface. If <me> was uniform, it can become non-uniform. <br>
//!  Raised if FromI1 or ToI2 is out of the range [FirstVKnotIndex, <br>
//!  LastVKnotIndex] given by the methods with the same name. <br>
//!  M should be greater than the previous multiplicity of the <br>
//!  all the knots FromI1,..., ToI2 and lower or equal to the <br>
//!  Degree of the surface in the V parametric direction. <br>
Standard_EXPORT   void IncreaseVMultiplicity(const Standard_Integer FromI1,const Standard_Integer ToI2,const Standard_Integer M) ;


//!  Increments the multiplicity of the consecutives vknots FromI1..ToI2 <br>
//!  by step.  The multiplicity of each knot FromI1,.....,ToI2 must be <br>
//!  lower or equal to the VDegree of the B_spline. <br>
//!  Raised if FromI1 or ToI2 is not in the range <br>
//!  [FirstVKnotIndex, LastVKnotIndex] <br>
//!  Raised if one knot has a multiplicity greater than VDegree. <br>
Standard_EXPORT   void IncrementVMultiplicity(const Standard_Integer FromI1,const Standard_Integer ToI2,const Standard_Integer Step) ;


//!  Inserts a knot value in the sequence of UKnots. If U is a knot <br>
//!  value this method increases the multiplicity of the knot if the <br>
//!  previous multiplicity was lower than M else it does nothing. The <br>
//!  tolerance criterion is ParametricTolerance. ParametricTolerance <br>
//!  should be greater or equal than Resolution from package gp. <br>
//!  Raised if U is out of the bounds [U1, U2] given by the methods <br>
//!  Bounds, the criterion ParametricTolerance is used. <br>
//!  Raised if M is not in the range [1, UDegree]. <br>
Standard_EXPORT   void InsertUKnot(const Standard_Real U,const Standard_Integer M,const Standard_Real ParametricTolerance,const Standard_Boolean Add = Standard_True) ;


//!  Inserts a knot value in the sequence of VKnots. If V is a knot <br>
//!  value this method increases the multiplicity of the knot if the <br>
//!  previous multiplicity was lower than M otherwise it does nothing. <br>
//!  The tolerance criterion is ParametricTolerance. <br>
//!  ParametricTolerance should be greater or equal than Resolution <br>
//!  from package gp. <br>
//!  raises if V is out of the Bounds [V1, V2] given by the methods <br>
//!  Bounds, the criterion ParametricTolerance is used. <br>
//!  raises if M is not in the range [1, VDegree]. <br>
Standard_EXPORT   void InsertVKnot(const Standard_Real V,const Standard_Integer M,const Standard_Real ParametricTolerance,const Standard_Boolean Add = Standard_True) ;


//!  Segments the surface between U1 and U2 in the U-Direction. <br>
//!                       between V1 and V2 in the V-Direction. <br>
//!  The control points are modified, the first and the last point <br>
//!  are not the same. <br>
//! Warnings : <br>
//!  Even if <me> is not closed it can become closed after the <br>
//!  segmentation for example if U1 or U2 are out of the bounds <br>
//!  of the surface <me> or if the surface makes loop. <br>//! raises if U2 < U1 or V2 < V1 <br>
Standard_EXPORT   void Segment(const Standard_Real U1,const Standard_Real U2,const Standard_Real V1,const Standard_Real V2) ;


//!  Segments the surface between U1 and U2 in the U-Direction. <br>
//!                       between V1 and V2 in the V-Direction. <br>
//! <br>
//!  same as Segment but do nothing if U1 and U2 (resp. V1 and V2) are <br>
//!  equal to the bounds in U (resp. in V) of <me>. <br>
//!  For example, if <me> is periodic in V, it will be always periodic <br>
//!  in V after the segmentation if the bounds in V are unchanged <br>
//! <br>
//! Warnings : <br>
//!  Even if <me> is not closed it can become closed after the <br>
//!  segmentation for example if U1 or U2 are out of the bounds <br>
//!  of the surface <me> or if the surface makes loop. <br>//! raises if U2 < U1 or V2 < V1 <br>
Standard_EXPORT   void CheckAndSegment(const Standard_Real U1,const Standard_Real U2,const Standard_Real V1,const Standard_Real V2) ;

//!  Substitutes the UKnots of range UIndex with K. <br>
//!  Raised if UIndex < 1 or UIndex > NbUKnots <br>
//!  Raised if K >= UKnots(UIndex+1) or K <= UKnots(UIndex-1) <br>
Standard_EXPORT   void SetUKnot(const Standard_Integer UIndex,const Standard_Real K) ;

//!  Changes all the U-knots of the surface. <br>
//!  The multiplicity of the knots are not modified. <br>
//!  Raised if there is an index such that UK (Index+1) <= UK (Index). <br>
//!  Raised if  UK.Lower() < 1 or UK.Upper() > NbUKnots <br>
Standard_EXPORT   void SetUKnots(const TColStd_Array1OfReal& UK) ;


//!  Changes the value of the UKnots of range UIndex and <br>
//!  increases its multiplicity. <br>
//!  Raised if UIndex is not in the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex] given by the methods with the same name. <br>
//!  Raised if K >= UKnots(UIndex+1) or K <= UKnots(UIndex-1) <br>
//!  M must be lower than UDegree and greater than the previous <br>
//!  multiplicity of the knot of range UIndex. <br>
Standard_EXPORT   void SetUKnot(const Standard_Integer UIndex,const Standard_Real K,const Standard_Integer M) ;

//!  Substitutes the VKnots of range VIndex with K. <br>
//!  Raised if VIndex < 1 or VIndex > NbVKnots <br>
//!  Raised if K >= VKnots(VIndex+1) or K <= VKnots(VIndex-1) <br>
Standard_EXPORT   void SetVKnot(const Standard_Integer VIndex,const Standard_Real K) ;

//!  Changes all the V-knots of the surface. <br>
//!  The multiplicity of the knots are not modified. <br>
//!  Raised if there is an index such that VK (Index+1) <= VK (Index). <br>
//!  Raised if  VK.Lower() < 1 or VK.Upper() > NbVKnots <br>
Standard_EXPORT   void SetVKnots(const TColStd_Array1OfReal& VK) ;


//!  Changes the value of the VKnots of range VIndex and increases <br>
//!  its multiplicity. <br>
//!  Raised if VIndex is not in the range [FirstVKnotIndex, <br>
//!  LastVKnotIndex] given by the methods with the same name. <br>
//!  Raised if K >= VKnots(VIndex+1) or K <= VKnots(VIndex-1) <br>
//!  M must be lower than VDegree and greater than the previous <br>
//!  multiplicity of the knot of range VIndex. <br>
Standard_EXPORT   void SetVKnot(const Standard_Integer VIndex,const Standard_Real K,const Standard_Integer M) ;


//!  Locates the parametric value U in the sequence of UKnots. <br>
//!  If "WithKnotRepetition" is True we consider the knot's <br>
//!  representation with repetition of multiple knot value, <br>
//!  otherwise  we consider the knot's representation with <br>
//!  no repetition of multiple knot values. <br>
//!  UKnots (I1) <= U <= UKnots (I2) <br>
//!  . if I1 = I2  U is a knot value (the tolerance criterion <br>
//!    ParametricTolerance is used). <br>
//!  . if I1 < 1  => U < UKnots(1) - Abs(ParametricTolerance) <br>
//!  . if I2 > NbUKnots => U > UKnots(NbUKnots)+Abs(ParametricTolerance) <br>
Standard_EXPORT   void LocateU(const Standard_Real U,const Standard_Real ParametricTolerance,Standard_Integer& I1,Standard_Integer& I2,const Standard_Boolean WithKnotRepetition = Standard_False) const;


//!  Locates the parametric value U in the sequence of knots. <br>
//!  If "WithKnotRepetition" is True we consider the knot's <br>
//!  representation with repetition of multiple knot value, <br>
//!  otherwise  we consider the knot's representation with <br>
//!  no repetition of multiple knot values. <br>
//!  VKnots (I1) <= V <= VKnots (I2) <br>
//!  . if I1 = I2  V is a knot value (the tolerance criterion <br>
//!    ParametricTolerance is used). <br>
//!  . if I1 < 1  => V < VKnots(1) - Abs(ParametricTolerance) <br>
//!  . if I2 > NbVKnots => V > VKnots(NbVKnots)+Abs(ParametricTolerance) <br>//!  poles insertion and removing <br>
//!  The following methods are available only if the surface <br>
//!  is Uniform or QuasiUniform in the considered direction <br>
//!  The knot repartition is modified. <br>
Standard_EXPORT   void LocateV(const Standard_Real V,const Standard_Real ParametricTolerance,Standard_Integer& I1,Standard_Integer& I2,const Standard_Boolean WithKnotRepetition = Standard_False) const;


//!  Substitutes the pole of range (UIndex, VIndex) with P. <br>
//!  If the surface is rational the weight of range (UIndex, VIndex) <br>
//!  is not modified. <br>
//!  Raised if UIndex < 1 or UIndex > NbUPoles or VIndex < 1 or <br>
//!  VIndex > NbVPoles. <br>
Standard_EXPORT   void SetPole(const Standard_Integer UIndex,const Standard_Integer VIndex,const gp_Pnt& P) ;


//!  Substitutes the pole and the weight of range (UIndex, VIndex) <br>
//!  with P and W. <br>
//!  Raised if UIndex < 1 or UIndex > NbUPoles or VIndex < 1 or <br>
//!  VIndex > NbVPoles. <br>//! Raised if Weight <= Resolution from package gp. <br>
Standard_EXPORT   void SetPole(const Standard_Integer UIndex,const Standard_Integer VIndex,const gp_Pnt& P,const Standard_Real Weight) ;


//!  Changes a column of poles or a part of this column. <br>//! Raised if Vindex < 1 or VIndex > NbVPoles. <br>
//!  Raised if CPoles.Lower() < 1 or CPoles.Upper() > NbUPoles. <br>
Standard_EXPORT   void SetPoleCol(const Standard_Integer VIndex,const TColgp_Array1OfPnt& CPoles) ;


//!  Changes a column of poles or a part of this column with the <br>
//!  corresponding weights. If the surface was rational it can <br>
//!  become non rational. If the surface was non rational it can <br>
//!  become rational. <br>//! Raised if Vindex < 1 or VIndex > NbVPoles. <br>
//!  Raised if CPoles.Lower() < 1 or CPoles.Upper() > NbUPoles <br>
//!  Raised if the bounds of CPoleWeights are not the same as the <br>
//!  bounds of CPoles. <br>
//!  Raised if one of the weight value of CPoleWeights is lower or <br>
//!  equal to Resolution from package gp. <br>
Standard_EXPORT   void SetPoleCol(const Standard_Integer VIndex,const TColgp_Array1OfPnt& CPoles,const TColStd_Array1OfReal& CPoleWeights) ;


//!  Changes a row of poles or a part of this row with the <br>
//!  corresponding weights. If the surface was rational it can <br>
//!  become non rational. If the surface was non rational it can <br>
//!  become rational. <br>//! Raised if Uindex < 1 or UIndex > NbUPoles. <br>
//!  Raised if CPoles.Lower() < 1 or CPoles.Upper() > NbVPoles <br>
//!  raises if the bounds of CPoleWeights are not the same as the <br>
//!  bounds of CPoles. <br>
//!  Raised if one of the weight value of CPoleWeights is lower or <br>
//!  equal to Resolution from package gp. <br>
Standard_EXPORT   void SetPoleRow(const Standard_Integer UIndex,const TColgp_Array1OfPnt& CPoles,const TColStd_Array1OfReal& CPoleWeights) ;


//!  Changes a row of poles or a part of this row. <br>//! Raised if Uindex < 1 or UIndex > NbUPoles. <br>
//!  Raised if CPoles.Lower() < 1 or CPoles.Upper() > NbVPoles. <br>
Standard_EXPORT   void SetPoleRow(const Standard_Integer UIndex,const TColgp_Array1OfPnt& CPoles) ;


//!  Changes the weight of the pole of range UIndex, VIndex. <br>
//!  If the surface was non rational it can become rational. <br>
//!  If the surface was rational it can become non rational. <br>
//!  Raised if UIndex < 1 or UIndex > NbUPoles or VIndex < 1 or <br>
//!  VIndex > NbVPoles <br>
//!  Raised if weight is lower or equal to Resolution from <br>
//!  package gp <br>
Standard_EXPORT   void SetWeight(const Standard_Integer UIndex,const Standard_Integer VIndex,const Standard_Real Weight) ;


//!  Changes a column of weights of a part of this column. <br>
//!  Raised if VIndex < 1 or VIndex > NbVPoles <br>
//!  Raised if CPoleWeights.Lower() < 1 or <br>
//!            CPoleWeights.Upper() > NbUPoles. <br>
//!  Raised if a weight value is lower or equal to Resolution <br>
//!  from package gp. <br>
Standard_EXPORT   void SetWeightCol(const Standard_Integer VIndex,const TColStd_Array1OfReal& CPoleWeights) ;


//!  Changes a row of weights or a part of this row. <br>
//!  Raised if UIndex < 1 or UIndex > NbUPoles <br>
//!  Raised if CPoleWeights.Lower() < 1 or <br>
//!            CPoleWeights.Upper() > NbVPoles. <br>
//!  Raised  if a weight value is lower or equal to Resolution <br>
//!  from package gp. <br>
Standard_EXPORT   void SetWeightRow(const Standard_Integer UIndex,const TColStd_Array1OfReal& CPoleWeights) ;

//! Move a point with parameter U and V to P. <br>
//!          given u,v  as parameters)  to  reach a  new position <br>
//!          UIndex1, UIndex2, VIndex1, VIndex2: <br>
//!                  indicates the poles which can be moved <br>
//!          if Problem in BSplineBasis calculation, no change <br>
//!          for the curve and <br>
//!              UFirstIndex, VLastIndex = 0 <br>
//!              VFirstIndex, VLastIndex = 0 <br>
//!  Raised if UIndex1 < UIndex2 or VIndex1 < VIndex2 or <br>
//!            UIndex1 < 1 || UIndex1 > NbUPoles or <br>
//!            UIndex2 < 1 || UIndex2 > NbUPoles <br>
//!            VIndex1 < 1 || VIndex1 > NbVPoles or <br>
//!            VIndex2 < 1 || VIndex2 > NbVPoles <br>//! characteristics of the surface <br>
Standard_EXPORT   void MovePoint(const Standard_Real U,const Standard_Real V,const gp_Pnt& P,const Standard_Integer UIndex1,const Standard_Integer UIndex2,const Standard_Integer VIndex1,const Standard_Integer VIndex2,Standard_Integer& UFirstIndex,Standard_Integer& ULastIndex,Standard_Integer& VFirstIndex,Standard_Integer& VLastIndex) ;


//!  Returns true if the first control points row and the last <br>
//!  control points row are identical. The tolerance criterion <br>
//!  is Resolution from package gp. <br>
Standard_EXPORT   Standard_Boolean IsUClosed() const;


//!  Returns true if the first control points column and the <br>
//!  last last control points column are identical. <br>
//!  The tolerance criterion is Resolution from package gp. <br>
Standard_EXPORT   Standard_Boolean IsVClosed() const;


//!  Returns True if the order of continuity of the surface in the <br>
//!  U direction  is N. <br>//! Raised if N < 0. <br>
Standard_EXPORT   Standard_Boolean IsCNu(const Standard_Integer N) const;


//!  Returns True if the order of continuity of the surface <br>
//!  in the V direction  is N. <br>//! Raised if N < 0. <br>
Standard_EXPORT   Standard_Boolean IsCNv(const Standard_Integer N) const;


//!  Returns True if the surface is closed in the U direction <br>
//!  and if the B-spline has been turned into a periodic surface <br>
//!  using the function SetUPeriodic. <br>
Standard_EXPORT   Standard_Boolean IsUPeriodic() const;


//!  Returns False if for each row of weights all the weights <br>
//!  are identical. <br>
//!  The tolerance criterion is resolution from package gp. <br>
//!  Example : <br>
//!                 |1.0, 1.0, 1.0| <br>
//!   if Weights =  |0.5, 0.5, 0.5|   returns False <br>
//!                 |2.0, 2.0, 2.0| <br>
Standard_EXPORT   Standard_Boolean IsURational() const;


//!  Returns True if the surface is closed in the V direction <br>
//!  and if the B-spline has been turned into a periodic <br>
//!  surface using the function SetVPeriodic. <br>
Standard_EXPORT   Standard_Boolean IsVPeriodic() const;


//!  Returns False if for each column of weights all the weights <br>
//!  are identical. <br>
//!  The tolerance criterion is resolution from package gp. <br>
//! Examples : <br>
//!                 |1.0, 2.0, 0.5| <br>
//!   if Weights =  |1.0, 2.0, 0.5|   returns False <br>
//!                 |1.0, 2.0, 0.5| <br>
Standard_EXPORT   Standard_Boolean IsVRational() const;


//!           Tells whether the Cache is valid for the <br>
//!           given parameter <br>
//! Warnings : the parameter must be normalized within <br>
//! the period if the curve is periodic. Otherwise <br>
//! the answer will be false <br>
//! <br>
Standard_EXPORT   Standard_Boolean IsCacheValid(const Standard_Real UParameter,const Standard_Real VParameter) const;


//!  Returns the parametric bounds of the surface. <br>
//! Warnings : <br>
//!  These parametric values are the bounds of the array of <br>
//!  knots UKnots and VKnots only if the first knots and the <br>
//!  last knots have a multiplicity equal to UDegree + 1 or <br>
//!  VDegree + 1 <br>
Standard_EXPORT   void Bounds(Standard_Real& U1,Standard_Real& U2,Standard_Real& V1,Standard_Real& V2) const;


//!  Returns the continuity of the surface : <br>
//!  C0 : only geometric continuity, <br>
//!  C1 : continuity of the first derivative all along the Surface, <br>
//!  C2 : continuity of the second derivative all along the Surface, <br>
//!  C3 : continuity of the third derivative all along the Surface, <br>
//!  CN : the order of continuity is infinite. <br>
//!  A B-spline surface is infinitely continuously differentiable <br>
//!  for the couple of parameters U, V such thats U != UKnots(i) <br>
//!  and V != VKnots(i). The continuity of the surface at a knot <br>
//!  value depends on the multiplicity of this knot. <br>
//! Example : <br>
//!  If the surface is C1 in the V direction and C2 in the U <br>
//!  direction this function returns Shape = C1. <br>
Standard_EXPORT   GeomAbs_Shape Continuity() const;


//!  Computes the Index of the UKnots which gives the first <br>
//!  parametric value of the surface in the U direction. <br>
//!  The UIso curve corresponding to this value is a <br>
//!  boundary curve of the surface. <br>
Standard_EXPORT   Standard_Integer FirstUKnotIndex() const;


//!  Computes the Index of the VKnots which gives the <br>
//!  first parametric value of the surface in the V direction. <br>
//!  The VIso curve corresponding to this knot is a boundary <br>
//!  curve of the surface. <br>
Standard_EXPORT   Standard_Integer FirstVKnotIndex() const;


//!  Computes the Index of the UKnots which gives the <br>
//!  last parametric value of the surface in the U direction. <br>
//!  The UIso curve corresponding to this knot is a boundary <br>
//!  curve of the surface. <br>
Standard_EXPORT   Standard_Integer LastUKnotIndex() const;


//!  Computes the Index of the VKnots which gives the <br>
//!  last parametric value of the surface in the V direction. <br>
//!  The VIso curve corresponding to this knot is a <br>
//!  boundary curve of the surface. <br>
Standard_EXPORT   Standard_Integer LastVKnotIndex() const;

//!  Returns the number of knots in the U direction. <br>
Standard_EXPORT   Standard_Integer NbUKnots() const;

//! Returns number of poles in the U direction. <br>
Standard_EXPORT   Standard_Integer NbUPoles() const;

//! Returns the number of knots in the V direction. <br>
Standard_EXPORT   Standard_Integer NbVKnots() const;

//! Returns the number of poles in the V direction. <br>
Standard_EXPORT   Standard_Integer NbVPoles() const;


//!  Returns the pole of range (UIndex, VIndex). <br>
//!  Raised if UIndex < 1 or UIndex > NbUPoles or VIndex < 1 or <br>
//!  VIndex > NbVPoles. <br>
Standard_EXPORT   gp_Pnt Pole(const Standard_Integer UIndex,const Standard_Integer VIndex) const;

//! Returns the poles of the B-spline surface. <br>
//!  Raised if the length of P in the U and V direction <br>
//!  is not equal to NbUpoles and NbVPoles. <br>
Standard_EXPORT   void Poles(TColgp_Array2OfPnt& P) const;


//!  Returns the degree of the normalized B-splines Ni,n in the U <br>
//!  direction. <br>
Standard_EXPORT   Standard_Integer UDegree() const;


//!  Returns the Knot value of range UIndex. <br>//! Raised if UIndex < 1 or UIndex > NbUKnots <br>
Standard_EXPORT   Standard_Real UKnot(const Standard_Integer UIndex) const;


//!  Returns NonUniform or Uniform or QuasiUniform or <br>
//!  PiecewiseBezier.  If all the knots differ by a <br>
//!  positive constant from the preceding knot in the U <br>
//!  direction the B-spline surface can be : <br>
//!  - Uniform if all the knots are of multiplicity 1, <br>
//!  - QuasiUniform if all the knots are of multiplicity 1 <br>
//!    except for the first and last knot which are of <br>
//!    multiplicity Degree + 1, <br>
//!  - PiecewiseBezier if the first and last knots have <br>
//!    multiplicity Degree + 1 and if interior knots have <br>
//!    multiplicity Degree <br>
//!  otherwise the surface is non uniform in the U direction <br>
//!  The tolerance criterion is Resolution from package gp. <br>
Standard_EXPORT   GeomAbs_BSplKnotDistribution UKnotDistribution() const;

//! Returns the knots in the U direction. <br>
//!  Raised if the length of Ku is not equal to the number of knots <br>
//!  in the U direction. <br>
Standard_EXPORT   void UKnots(TColStd_Array1OfReal& Ku) const;

//! Returns the uknots sequence. <br>
//!  In this sequence the knots with a multiplicity greater than 1 <br>
//!  are repeated. <br>
//! Example : <br>
//!  Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4} <br>
//!  Raised if the length of Ku is not equal to NbUPoles + UDegree + 1 <br>
Standard_EXPORT   void UKnotSequence(TColStd_Array1OfReal& Ku) const;


//!  Returns the multiplicity value of knot of range UIndex in <br>
//!  the u direction. <br>//! Raised if UIndex < 1 or UIndex > NbUKnots. <br>
Standard_EXPORT   Standard_Integer UMultiplicity(const Standard_Integer UIndex) const;


//!  Returns the multiplicities of the knots in the U direction. <br>
//!  Raised if the length of Mu is not equal to the number of <br>
//!  knots in the U direction. <br>
Standard_EXPORT   void UMultiplicities(TColStd_Array1OfInteger& Mu) const;


//!  Returns the degree of the normalized B-splines Ni,d in the <br>
//!  V direction. <br>
Standard_EXPORT   Standard_Integer VDegree() const;

//! Returns the Knot value of range VIndex. <br>
Standard_EXPORT   Standard_Real VKnot(const Standard_Integer VIndex) const;


//!  Returns NonUniform or Uniform or QuasiUniform or <br>
//!  PiecewiseBezier. If all the knots differ by a positive <br>
//!  constant from the preceding knot in the V direction the <br>
//!  B-spline surface can be : <br>
//!  - Uniform if all the knots are of multiplicity 1, <br>
//!  - QuasiUniform if all the knots are of multiplicity 1 <br>
//!    except for the first and last knot which are of <br>
//!    multiplicity Degree + 1, <br>
//!  - PiecewiseBezier if the first and last knots have <br>
//!    multiplicity  Degree + 1 and if interior knots have <br>
//!     multiplicity Degree <br>
//!  otherwise the surface is non uniform in the V direction. <br>
//!  The tolerance criterion is Resolution from package gp. <br>
Standard_EXPORT   GeomAbs_BSplKnotDistribution VKnotDistribution() const;

//! Returns the knots in the V direction. <br>
//!  Raised if the length of Kv is not equal to the number of <br>
//!  knots in the V direction. <br>
Standard_EXPORT   void VKnots(TColStd_Array1OfReal& Kv) const;

//! Returns the vknots sequence. <br>
//!  In this sequence the knots with a multiplicity greater than 1 <br>
//!  are repeated. <br>
//! Example : <br>
//!  Kv = {k1, k1, k1, k2, k3, k3, k4, k4, k4} <br>
//!  Raised if the length of Kv is not equal to NbVPoles + VDegree + 1 <br>
Standard_EXPORT   void VKnotSequence(TColStd_Array1OfReal& Kv) const;


//!  Returns the multiplicity value of knot of range VIndex in <br>
//!  the v direction. <br>//! Raised if VIndex < 1 or VIndex > NbVKnots <br>
Standard_EXPORT   Standard_Integer VMultiplicity(const Standard_Integer VIndex) const;


//!  Returns the multiplicities of the knots in the V direction. <br>
//!  Raised if the length of Mv is not equal to the number of <br>
//!  knots in the V direction. <br>
Standard_EXPORT   void VMultiplicities(TColStd_Array1OfInteger& Mv) const;

//! Returns the weight value of range UIndex, VIndex. <br>
//!  Raised if UIndex < 1 or UIndex > NbUPoles or VIndex < 1 <br>
//!  or VIndex > NbVPoles. <br>
Standard_EXPORT   Standard_Real Weight(const Standard_Integer UIndex,const Standard_Integer VIndex) const;

//! Returns the weights of the B-spline surface. <br>
//!  Raised if the length of W in the U and V direction is <br>
//!  not equal to NbUPoles and NbVPoles. <br>//! value and derivatives computation <br>
Standard_EXPORT   void Weights(TColStd_Array2OfReal& W) const;


Standard_EXPORT   void D0(const Standard_Real U,const Standard_Real V,gp_Pnt& P) const;

//! Raised if the continuity of the surface is not C1. <br>
Standard_EXPORT   void D1(const Standard_Real U,const Standard_Real V,gp_Pnt& P,gp_Vec& D1U,gp_Vec& D1V) const;

//! Raised if the continuity of the surface is not C2. <br>
Standard_EXPORT   void 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;

//! Raised if the continuity of the surface is not C3. <br>
Standard_EXPORT   void 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;


//!  Nu is the order of derivation in the U parametric direction and <br>
//!  Nv is the order of derivation in the V parametric direction. <br>
//!  Raised if the continuity of the surface is not CNu in the U <br>
//!  direction and CNv in the V direction. <br>
//!  Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. <br>
//!  The following functions computes the point for the <br>
//!  parametric values (U, V) and the derivatives at <br>
//!  this point on the B-spline surface patch delimited <br>
//!  with the knots FromUK1, FromVK1 and the knots ToUK2, <br>
//!  ToVK2.  (U, V) can be out of these parametric bounds <br>
//!  but for the computation we only use the definition <br>
//!  of the surface between these knots. This method is <br>
//!  useful to compute local derivative, if the order of <br>
//!  continuity of the whole surface is not greater enough. <br>
//!  Inside the parametric knot's domain previously defined <br>
//!  the evaluations are the same as if we consider the whole <br>
//!  definition of the surface. Of course the evaluations are <br>
//!  different outside this parametric domain. <br>
Standard_EXPORT   gp_Vec DN(const Standard_Real U,const Standard_Real V,const Standard_Integer Nu,const Standard_Integer Nv) const;

//! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2. <br>
//!  Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex] or if FromVK1, ToVK2 are not in the range <br>
//!  [FirstVKnotIndex, LastVKnotIndex] <br>
Standard_EXPORT   void LocalD0(const Standard_Real U,const Standard_Real V,const Standard_Integer FromUK1,const Standard_Integer ToUK2,const Standard_Integer FromVK1,const Standard_Integer ToVK2,gp_Pnt& P) const;


//!  Raised if the local continuity of the surface is not C1 <br>
//!  between the knots FromUK1, ToUK2 and FromVK1, ToVK2. <br>//! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2. <br>
//!  Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex] or if FromVK1, ToVK2 are not in the range <br>
//!  [FirstVKnotIndex, LastVKnotIndex] <br>
Standard_EXPORT   void LocalD1(const Standard_Real U,const Standard_Real V,const Standard_Integer FromUK1,const Standard_Integer ToUK2,const Standard_Integer FromVK1,const Standard_Integer ToVK2,gp_Pnt& P,gp_Vec& D1U,gp_Vec& D1V) const;


//!  Raised if the local continuity of the surface is not C2 <br>
//!  between the knots FromUK1, ToUK2 and FromVK1, ToVK2. <br>//! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2. <br>
//!  Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex] or if FromVK1, ToVK2 are not in the range <br>
//!  [FirstVKnotIndex, LastVKnotIndex] <br>
Standard_EXPORT   void LocalD2(const Standard_Real U,const Standard_Real V,const Standard_Integer FromUK1,const Standard_Integer ToUK2,const Standard_Integer FromVK1,const Standard_Integer ToVK2,gp_Pnt& P,gp_Vec& D1U,gp_Vec& D1V,gp_Vec& D2U,gp_Vec& D2V,gp_Vec& D2UV) const;


//!  Raised if the local continuity of the surface is not C3 <br>
//!  between the knots FromUK1, ToUK2 and FromVK1, ToVK2. <br>//! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2. <br>
//!  Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex] or if FromVK1, ToVK2 are not in the range <br>
//!  [FirstVKnotIndex, LastVKnotIndex] <br>
Standard_EXPORT   void LocalD3(const Standard_Real U,const Standard_Real V,const Standard_Integer FromUK1,const Standard_Integer ToUK2,const Standard_Integer FromVK1,const Standard_Integer ToVK2,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;


//!  Raised if the local continuity of the surface is not CNu <br>
//!  between the knots FromUK1, ToUK2 and CNv between the knots <br>
//!  FromVK1, ToVK2. <br>//! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2. <br>
//!  Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex] or if FromVK1, ToVK2 are not in the range <br>
//!  [FirstVKnotIndex, LastVKnotIndex] <br>
Standard_EXPORT   gp_Vec LocalDN(const Standard_Real U,const Standard_Real V,const Standard_Integer FromUK1,const Standard_Integer ToUK2,const Standard_Integer FromVK1,const Standard_Integer ToVK2,const Standard_Integer Nu,const Standard_Integer Nv) const;


//!  Computes the point of parameter U, V on the BSpline surface patch <br>
//!  defines between the knots UK1 UK2, VK1, VK2. U can be out of the <br>
//!  bounds [Knot UK1, Knot UK2] and V can be outof the bounds <br>
//!  [Knot VK1, Knot VK2]  but for the computation we only use the <br>
//!  definition of the surface between these knot values. <br>//! Raises if FromUK1 = ToUK2 or FromVK1 = ToVK2. <br>
//!  Raises if FromUK1, ToUK2 are not in the range [FirstUKnotIndex, <br>
//!  LastUKnotIndex] or if FromVK1, ToVK2 are not in the range <br>
//!  [FirstVKnotIndex, LastVKnotIndex] <br>
Standard_EXPORT   gp_Pnt LocalValue(const Standard_Real U,const Standard_Real V,const Standard_Integer FromUK1,const Standard_Integer ToUK2,const Standard_Integer FromVK1,const Standard_Integer ToVK2) const;


//!  Computes the U isoparametric curve. <br>
//!  A B-spline curve is returned. <br>
Standard_EXPORT   Handle_Geom_Curve UIso(const Standard_Real U) const;


//!  Computes the V isoparametric curve. <br>
//!  A B-spline curve is returned. <br>
Standard_EXPORT   Handle_Geom_Curve VIso(const Standard_Real V) const;


//!  Computes the U isoparametric curve. <br>
//!  If CheckRational=False, no try to make it non-rational. <br>
//!  A B-spline curve is returned. <br>
Standard_EXPORT   Handle_Geom_Curve UIso(const Standard_Real U,const Standard_Boolean CheckRational) const;


//!  Computes the V isoparametric curve. <br>
//!  If CheckRational=False, no try to make it non-rational. <br>
//!  A B-spline curve is returned. <br>//! transformations <br>
Standard_EXPORT   Handle_Geom_Curve VIso(const Standard_Real V,const Standard_Boolean CheckRational) const;

//! Applies the transformation T to this BSpline surface. <br>
Standard_EXPORT   void Transform(const gp_Trsf& T) ;


//!  Returns the value of the maximum degree of the normalized <br>
//!  B-spline basis functions in the u and v directions. <br>
Standard_EXPORT static  Standard_Integer MaxDegree() ;

//! Computes two tolerance values for this BSpline <br>
//! surface, based on the given tolerance in 3D space <br>
//! Tolerance3D. The tolerances computed are: <br>
//! - UTolerance in the u parametric direction, and <br>
//! - VTolerance in the v parametric direction. <br>
//! If f(u,v) is the equation of this BSpline surface, <br>
//! UTolerance and VTolerance guarantee that : <br>
//!          | u1 - u0 | < UTolerance and <br>
//!          | v1 - v0 | < VTolerance <br>
//!          ====> |f (u1,v1) - f (u0,v0)| < Tolerance3D <br>
Standard_EXPORT   void Resolution(const Standard_Real Tolerance3D,Standard_Real& UTolerance,Standard_Real& VTolerance) ;

//! Creates a new object which is a copy of this BSpline surface. <br>
Standard_EXPORT   Handle_Geom_Geometry Copy() const;
//Standard_EXPORT ~Geom_BSplineSurface();




 // Type management
 //
 Standard_EXPORT const Handle(Standard_Type)& DynamicType() const;
 //Standard_EXPORT Standard_Boolean	       IsKind(const Handle(Standard_Type)&) const;

protected:

 // Methods PROTECTED
 // 


 // Fields PROTECTED
 //


private: 

 // Methods PRIVATE
 // 

//! Recompute  the  flatknots,  the knotsdistribution, the <br>
//!          continuity for U. <br>
Standard_EXPORT   void UpdateUKnots() ;

//! Recompute  the  flatknots,  the knotsdistribution, the <br>
//!          continuity for V. <br>
Standard_EXPORT   void UpdateVKnots() ;

//! Invalidates the cache. This has to be private this has to be private <br>
Standard_EXPORT   void InvalidateCache() ;

//! updates the cache and validates it <br>
Standard_EXPORT   void ValidateCache(const Standard_Real UParameter,const Standard_Real VParameter) ;


 // Fields PRIVATE
 //
Standard_Boolean urational;
Standard_Boolean vrational;
Standard_Boolean uperiodic;
Standard_Boolean vperiodic;
GeomAbs_BSplKnotDistribution uknotSet;
GeomAbs_BSplKnotDistribution vknotSet;
GeomAbs_Shape Usmooth;
GeomAbs_Shape Vsmooth;
Standard_Integer udeg;
Standard_Integer vdeg;
Handle_TColgp_HArray2OfPnt poles;
Handle_TColStd_HArray2OfReal weights;
Handle_TColStd_HArray1OfReal ufknots;
Handle_TColStd_HArray1OfReal vfknots;
Handle_TColStd_HArray1OfReal uknots;
Handle_TColStd_HArray1OfReal vknots;
Handle_TColStd_HArray1OfInteger umults;
Handle_TColStd_HArray1OfInteger vmults;
Handle_TColgp_HArray2OfPnt cachepoles;
Handle_TColStd_HArray2OfReal cacheweights;
Standard_Real ucacheparameter;
Standard_Real vcacheparameter;
Standard_Real ucachespanlenght;
Standard_Real vcachespanlenght;
Standard_Integer ucachespanindex;
Standard_Integer vcachespanindex;
Standard_Integer validcache;
Standard_Real umaxderivinv;
Standard_Real vmaxderivinv;
Standard_Boolean maxderivinvok;


};





// other Inline functions and methods (like "C++: function call" methods)
//


#endif
