Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-05 09:22:05

0001 // Created on: 1993-03-24
0002 // Created by: JCV
0003 // Copyright (c) 1993-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016 
0017 #ifndef _Geom2d_BSplineCurve_HeaderFile
0018 #define _Geom2d_BSplineCurve_HeaderFile
0019 
0020 #include <Standard.hxx>
0021 #include <Standard_Type.hxx>
0022 
0023 #include <Precision.hxx>
0024 #include <GeomAbs_BSplKnotDistribution.hxx>
0025 #include <GeomAbs_Shape.hxx>
0026 #include <gp_Pnt2d.hxx>
0027 #include <NCollection_Array1.hxx>
0028 #include <Geom2d_BoundedCurve.hxx>
0029 class gp_Trsf2d;
0030 class Geom2d_Geometry;
0031 
0032 namespace Geom2dEval_RepCurveDesc
0033 {
0034 class Base;
0035 }
0036 
0037 //! Describes a BSpline curve.
0038 //! A BSpline curve can be:
0039 //! - uniform or non-uniform,
0040 //! - rational or non-rational,
0041 //! - periodic or non-periodic.
0042 //! A BSpline curve is defined by:
0043 //! - its degree; the degree for a
0044 //! Geom2d_BSplineCurve is limited to a value (25)
0045 //! which is defined and controlled by the system. This
0046 //! value is returned by the function MaxDegree;
0047 //! - its periodic or non-periodic nature;
0048 //! - a table of poles (also called control points), with
0049 //! their associated weights if the BSpline curve is
0050 //! rational. The poles of the curve are "control points"
0051 //! used to deform the curve. If the curve is
0052 //! non-periodic, the first pole is the start point of the
0053 //! curve, and the last pole is the end point of the
0054 //! curve. The segment, which joins the first pole to the
0055 //! second pole, is the tangent to the curve at its start
0056 //! point, and the segment, which joins the last pole to
0057 //! the second-from-last pole, is the tangent to the
0058 //! curve at its end point. If the curve is periodic, these
0059 //! geometric properties are not verified. It is more
0060 //! difficult to give a geometric signification to the
0061 //! weights but they are useful for providing exact
0062 //! representations of the arcs of a circle or ellipse.
0063 //! Moreover, if the weights of all the poles are equal,
0064 //! the curve has a polynomial equation; it is
0065 //! therefore a non-rational curve.
0066 //! - a table of knots with their multiplicities. For a
0067 //! Geom2d_BSplineCurve, the table of knots is an
0068 //! increasing sequence of reals without repetition; the
0069 //! multiplicities define the repetition of the knots. A
0070 //! BSpline curve is a piecewise polynomial or rational
0071 //! curve. The knots are the parameters of junction
0072 //! points between two pieces. The multiplicity
0073 //! Mult(i) of the knot Knot(i) of the BSpline
0074 //! curve is related to the degree of continuity of the
0075 //! curve at the knot Knot(i), which is equal to
0076 //! Degree - Mult(i) where Degree is the
0077 //! degree of the BSpline curve.
0078 //! If the knots are regularly spaced (i.e. the difference
0079 //! between two consecutive knots is a constant), three
0080 //! specific and frequently used cases of knot distribution
0081 //! can be identified:
0082 //! - "uniform" if all multiplicities are equal to 1,
0083 //! - "quasi-uniform" if all multiplicities are equal to 1,
0084 //! except the first and the last knot which have a
0085 //! multiplicity of Degree + 1, where Degree is
0086 //! the degree of the BSpline curve,
0087 //! - "Piecewise Bezier" if all multiplicities are equal to
0088 //! Degree except the first and last knot which have
0089 //! a multiplicity of Degree + 1, where Degree is
0090 //! the degree of the BSpline curve. A curve of this
0091 //! type is a concatenation of arcs of Bezier curves.
0092 //! If the BSpline curve is not periodic:
0093 //! - the bounds of the Poles and Weights tables are 1
0094 //! and NbPoles, where NbPoles is the number of
0095 //! poles of the BSpline curve,
0096 //! - the bounds of the Knots and Multiplicities tables are
0097 //! 1 and NbKnots, where NbKnots is the number
0098 //! of knots of the BSpline curve.
0099 //! If the BSpline curve is periodic, and if there are k
0100 //! periodic knots and p periodic poles, the period is:
0101 //! period = Knot(k + 1) - Knot(1)
0102 //! and the poles and knots tables can be considered as
0103 //! infinite tables, such that:
0104 //! - Knot(i+k) = Knot(i) + period
0105 //! - Pole(i+p) = Pole(i)
0106 //! Note: data structures of a periodic BSpline curve are
0107 //! more complex than those of a non-periodic one.
0108 //! Warnings:
0109 //! In this class we consider that a weight value is zero if
0110 //! Weight <= Resolution from package gp.
0111 //! For two parametric values (or two knot values) U1, U2 we
0112 //! consider that U1 = U2 if Abs (U2 - U1) <= Epsilon (U1).
0113 //! For two weights values W1, W2 we consider that W1 = W2 if
0114 //! Abs (W2 - W1) <= Epsilon (W1). The method Epsilon is
0115 //! defined in the class Real from package Standard.
0116 //!
0117 //! References :
0118 //! . A survey of curve and surface methods in CADG Wolfgang BOHM
0119 //! CAGD 1 (1984)
0120 //! . On de Boor-like algorithms and blossoming Wolfgang BOEHM
0121 //! cagd 5 (1988)
0122 //! . Blossoming and knot insertion algorithms for B-spline curves
0123 //! Ronald N. GOLDMAN
0124 //! . Modelisation des surfaces en CAO, Henri GIAUME Peugeot SA
0125 //! . Curves and Surfaces for Computer Aided Geometric Design,
0126 //! a practical guide Gerald Farin
0127 class Geom2d_BSplineCurve : public Geom2d_BoundedCurve
0128 {
0129 
0130 public:
0131   //! Creates a non-rational B_spline curve on the
0132   //! basis <Knots, Multiplicities> of degree <Degree>.
0133   //! The following conditions must be verified.
0134   //! 0 < Degree <= MaxDegree.
0135   //!
0136   //! Knots.Length() == Mults.Length() >= 2
0137   //!
0138   //! Knots(i) < Knots(i+1) (Knots are increasing)
0139   //!
0140   //! 1 <= Mults(i) <= Degree
0141   //!
0142   //! On a non periodic curve the first and last multiplicities
0143   //! may be Degree+1 (this is even recommended if you want the
0144   //! curve to start and finish on the first and last pole).
0145   //!
0146   //! On a periodic curve the first and the last multicities
0147   //! must be the same.
0148   //!
0149   //! on non-periodic curves
0150   //!
0151   //! Poles.Length() == Sum(Mults(i)) - Degree - 1 >= 2
0152   //!
0153   //! on periodic curves
0154   //!
0155   //! Poles.Length() == Sum(Mults(i)) except the first or last
0156   Standard_EXPORT Geom2d_BSplineCurve(const NCollection_Array1<gp_Pnt2d>& Poles,
0157                                       const NCollection_Array1<double>&   Knots,
0158                                       const NCollection_Array1<int>&      Multiplicities,
0159                                       const int                           Degree,
0160                                       const bool                          Periodic = false);
0161 
0162   //! Creates a rational B_spline curve on the basis
0163   //! <Knots, Multiplicities> of degree <Degree>.
0164   //! The following conditions must be verified.
0165   //! 0 < Degree <= MaxDegree.
0166   //!
0167   //! Knots.Length() == Mults.Length() >= 2
0168   //!
0169   //! Knots(i) < Knots(i+1) (Knots are increasing)
0170   //!
0171   //! 1 <= Mults(i) <= Degree
0172   //!
0173   //! On a non periodic curve the first and last multiplicities
0174   //! may be Degree+1 (this is even recommended if you want the
0175   //! curve to start and finish on the first and last pole).
0176   //!
0177   //! On a periodic curve the first and the last multicities
0178   //! must be the same.
0179   //!
0180   //! on non-periodic curves
0181   //!
0182   //! Poles.Length() == Sum(Mults(i)) - Degree - 1 >= 2
0183   //!
0184   //! on periodic curves
0185   //!
0186   //! Poles.Length() == Sum(Mults(i)) except the first or last
0187   Standard_EXPORT Geom2d_BSplineCurve(const NCollection_Array1<gp_Pnt2d>& Poles,
0188                                       const NCollection_Array1<double>&   Weights,
0189                                       const NCollection_Array1<double>&   Knots,
0190                                       const NCollection_Array1<int>&      Multiplicities,
0191                                       const int                           Degree,
0192                                       const bool                          Periodic = false);
0193 
0194   //! Copy constructor for optimized copying without validation.
0195   Standard_EXPORT Geom2d_BSplineCurve(const Geom2d_BSplineCurve& theOther);
0196 
0197   //! Returns true if an evaluation representation is attached.
0198   bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
0199 
0200   //! Returns the current evaluation representation descriptor (may be null).
0201   const occ::handle<Geom2dEval_RepCurveDesc::Base>& EvalRepresentation() const { return myEvalRep; }
0202 
0203   //! Sets a new evaluation representation.
0204   //! Validates descriptor data and ensures no circular references.
0205   Standard_EXPORT void SetEvalRepresentation(
0206     const occ::handle<Geom2dEval_RepCurveDesc::Base>& theDesc);
0207 
0208   //! Removes the evaluation representation.
0209   void ClearEvalRepresentation() { myEvalRep.Nullify(); }
0210 
0211   //! Increases the degree of this BSpline curve to
0212   //! Degree. As a result, the poles, weights and
0213   //! multiplicities tables are modified; the knots table is
0214   //! not changed. Nothing is done if Degree is less than
0215   //! or equal to the current degree.
0216   //! Exceptions
0217   //! Standard_ConstructionError if Degree is greater than
0218   //! Geom2d_BSplineCurve::MaxDegree().
0219   Standard_EXPORT void IncreaseDegree(const int Degree);
0220 
0221   //! Increases the multiplicity of the knot <Index> to
0222   //! <M>.
0223   //!
0224   //! If <M> is lower or equal to the current multiplicity
0225   //! nothing is done. If <M> is higher than the degree,
0226   //! the degree is used.
0227   //! If <Index> is not in [FirstUKnotIndex, LastUKnotIndex]
0228   Standard_EXPORT void IncreaseMultiplicity(const int Index, const int M);
0229 
0230   //! Increases the multiplicities of the knots in
0231   //! [I1,I2] to <M>.
0232   //!
0233   //! For each knot if <M> is lower or equal to the
0234   //! current multiplicity nothing is done. If <M> is
0235   //! higher than the degree the degree is used.
0236   //! As a result, the poles and weights tables of this curve are modified.
0237   //! Warning
0238   //! It is forbidden to modify the multiplicity of the first or
0239   //! last knot of a non-periodic curve. Be careful as
0240   //! Geom2d does not protect against this.
0241   //! Exceptions
0242   //! Standard_OutOfRange if either Index, I1 or I2 is
0243   //! outside the bounds of the knots table.
0244   Standard_EXPORT void IncreaseMultiplicity(const int I1, const int I2, const int M);
0245 
0246   //! Increases by M the multiplicity of the knots of indexes
0247   //! I1 to I2 in the knots table of this BSpline curve. For
0248   //! each knot, the resulting multiplicity is limited to the
0249   //! degree of this curve. If M is negative, nothing is done.
0250   //! As a result, the poles and weights tables of this
0251   //! BSpline curve are modified.
0252   //! Warning
0253   //! It is forbidden to modify the multiplicity of the first or
0254   //! last knot of a non-periodic curve. Be careful as
0255   //! Geom2d does not protect against this.
0256   //! Exceptions
0257   //! Standard_OutOfRange if I1 or I2 is outside the
0258   //! bounds of the knots table.
0259   Standard_EXPORT void IncrementMultiplicity(const int I1, const int I2, const int M);
0260 
0261   //! Inserts a knot value in the sequence of knots. If
0262   //! <U> is an existing knot the multiplicity is
0263   //! increased by <M>.
0264   //!
0265   //! If U is not on the parameter range nothing is
0266   //! done.
0267   //!
0268   //! If the multiplicity is negative or null nothing is
0269   //! done. The new multiplicity is limited to the
0270   //! degree.
0271   //!
0272   //! The tolerance criterion for knots equality is
0273   //! the max of Epsilon(U) and ParametricTolerance.
0274   //! Warning
0275   //! - If U is less than the first parameter or greater than
0276   //! the last parameter of this BSpline curve, nothing is done.
0277   //! - If M is negative or null, nothing is done.
0278   //! - The multiplicity of a knot is limited to the degree of
0279   //! this BSpline curve.
0280   Standard_EXPORT void InsertKnot(const double U,
0281                                   const int    M                   = 1,
0282                                   const double ParametricTolerance = 0.0);
0283 
0284   //! Inserts the values of the array Knots, with the
0285   //! respective multiplicities given by the array Mults, into
0286   //! the knots table of this BSpline curve.
0287   //! If a value of the array Knots is an existing knot, its multiplicity is:
0288   //! - increased by M, if Add is true, or
0289   //! - increased to M, if Add is false (default value).
0290   //! The tolerance criterion used for knot equality is the
0291   //! larger of the values ParametricTolerance (defaulted
0292   //! to 0.) and double::Epsilon(U),
0293   //! where U is the current knot value.
0294   //! Warning
0295   //! - For a value of the array Knots which is less than
0296   //! the first parameter or greater than the last
0297   //! parameter of this BSpline curve, nothing is done.
0298   //! - For a value of the array Mults which is negative or
0299   //! null, nothing is done.
0300   //! - The multiplicity of a knot is limited to the degree of
0301   //! this BSpline curve.
0302   Standard_EXPORT void InsertKnots(const NCollection_Array1<double>& Knots,
0303                                    const NCollection_Array1<int>&    Mults,
0304                                    const double                      ParametricTolerance = 0.0,
0305                                    const bool                        Add                 = false);
0306 
0307   //! Reduces the multiplicity of the knot of index Index
0308   //! to M. If M is equal to 0, the knot is removed.
0309   //! With a modification of this type, the array of poles is also modified.
0310   //! Two different algorithms are systematically used to
0311   //! compute the new poles of the curve. If, for each
0312   //! pole, the distance between the pole calculated
0313   //! using the first algorithm and the same pole
0314   //! calculated using the second algorithm, is less than
0315   //! Tolerance, this ensures that the curve is not
0316   //! modified by more than Tolerance. Under these
0317   //! conditions, true is returned; otherwise, false is returned.
0318   //! A low tolerance is used to prevent modification of
0319   //! the curve. A high tolerance is used to "smooth" the curve.
0320   //! Exceptions
0321   //! Standard_OutOfRange if Index is outside the
0322   //! bounds of the knots table.
0323   Standard_EXPORT bool RemoveKnot(const int Index, const int M, const double Tolerance);
0324 
0325   //! The new pole is inserted after the pole of range Index.
0326   //! If the curve was non rational it can become rational.
0327   //!
0328   //! Raised if the B-spline is NonUniform or PiecewiseBezier or if
0329   //! Weight <= 0.0
0330   //! Raised if Index is not in the range [1, Number of Poles]
0331   Standard_EXPORT void InsertPoleAfter(const int       Index,
0332                                        const gp_Pnt2d& P,
0333                                        const double    Weight = 1.0);
0334 
0335   //! The new pole is inserted before the pole of range Index.
0336   //! If the curve was non rational it can become rational.
0337   //!
0338   //! Raised if the B-spline is NonUniform or PiecewiseBezier or if
0339   //! Weight <= 0.0
0340   //! Raised if Index is not in the range [1, Number of Poles]
0341   Standard_EXPORT void InsertPoleBefore(const int       Index,
0342                                         const gp_Pnt2d& P,
0343                                         const double    Weight = 1.0);
0344 
0345   //! Removes the pole of range Index
0346   //! If the curve was rational it can become non rational.
0347   //!
0348   //! Raised if the B-spline is NonUniform or PiecewiseBezier.
0349   //! Raised if the number of poles of the B-spline curve is lower or
0350   //! equal to 2 before removing.
0351   //! Raised if Index is not in the range [1, Number of Poles]
0352   Standard_EXPORT void RemovePole(const int Index);
0353 
0354   //! Reverses the orientation of this BSpline curve. As a result
0355   //! - the knots and poles tables are modified;
0356   //! - the start point of the initial curve becomes the end
0357   //! point of the reversed curve;
0358   //! - the end point of the initial curve becomes the start
0359   //! point of the reversed curve.
0360   Standard_EXPORT void Reverse() final;
0361 
0362   //! Computes the parameter on the reversed curve for
0363   //! the point of parameter U on this BSpline curve.
0364   //! The returned value is: UFirst + ULast - U,
0365   //! where UFirst and ULast are the values of the
0366   //! first and last parameters of this BSpline curve.
0367   Standard_EXPORT double ReversedParameter(const double U) const final;
0368 
0369   //! Modifies this BSpline curve by segmenting it
0370   //! between U1 and U2. Either of these values can be
0371   //! outside the bounds of the curve, but U2 must be greater than U1.
0372   //! All data structure tables of this BSpline curve are
0373   //! modified, but the knots located between U1 and U2
0374   //! are retained. The degree of the curve is not modified.
0375   //!
0376   //! Parameter theTolerance defines the possible proximity of the segment
0377   //! boundaries and B-spline knots to treat them as equal.
0378   //!
0379   //! Warnings:
0380   //! Even if <me> is not closed it can become closed after the
0381   //! segmentation for example if U1 or U2 are out of the bounds
0382   //! of the curve <me> or if the curve makes loop.
0383   //! After the segmentation the length of a curve can be null.
0384   //! - The segmentation of a periodic curve over an
0385   //! interval corresponding to its period generates a
0386   //! non-periodic curve with equivalent geometry.
0387   //! Exceptions
0388   //! Standard_DomainError if U2 is less than U1.
0389   //! raises if U2 < U1.
0390   //! Standard_DomainError if U2 - U1 exceeds the period for periodic curves.
0391   //! i.e. ((U2 - U1) - Period) > Precision::PConfusion().
0392   Standard_EXPORT void Segment(const double U1,
0393                                const double U2,
0394                                const double theTolerance = Precision::PConfusion());
0395 
0396   //! Modifies this BSpline curve by assigning the value K
0397   //! to the knot of index Index in the knots table. This is a
0398   //! relatively local modification because K must be such that:
0399   //! Knots(Index - 1) < K < Knots(Index + 1)
0400   //! Exceptions
0401   //! Standard_ConstructionError if:
0402   //! - K is not such that:
0403   //! Knots(Index - 1) < K < Knots(Index + 1)
0404   //! - M is greater than the degree of this BSpline curve
0405   //! or lower than the previous multiplicity of knot of
0406   //! index Index in the knots table.
0407   //! Standard_OutOfRange if Index is outside the bounds of the knots table.
0408   Standard_EXPORT void SetKnot(const int Index, const double K);
0409 
0410   //! Modifies this BSpline curve by assigning the array
0411   //! K to its knots table. The multiplicity of the knots is not modified.
0412   //! Exceptions
0413   //! Standard_ConstructionError if the values in the
0414   //! array K are not in ascending order.
0415   //! Standard_OutOfRange if the bounds of the array
0416   //! K are not respectively 1 and the number of knots of this BSpline curve.
0417   Standard_EXPORT void SetKnots(const NCollection_Array1<double>& K);
0418 
0419   //! Modifies this BSpline curve by assigning the value K
0420   //! to the knot of index Index in the knots table. This is a
0421   //! relatively local modification because K must be such that:
0422   //! Knots(Index - 1) < K < Knots(Index + 1)
0423   //! The second syntax allows you also to increase the
0424   //! multiplicity of the knot to M (but it is not possible to
0425   //! decrease the multiplicity of the knot with this function).
0426   //! Exceptions
0427   //! Standard_ConstructionError if:
0428   //! - K is not such that:
0429   //! Knots(Index - 1) < K < Knots(Index + 1)
0430   //! - M is greater than the degree of this BSpline curve
0431   //! or lower than the previous multiplicity of knot of
0432   //! index Index in the knots table.
0433   //! Standard_OutOfRange if Index is outside the bounds of the knots table.
0434   Standard_EXPORT void SetKnot(const int Index, const double K, const int M);
0435 
0436   //! Computes the parameter normalized within the
0437   //! "first" period of this BSpline curve, if it is periodic:
0438   //! the returned value is in the range Param1 and
0439   //! Param1 + Period, where:
0440   //! - Param1 is the "first parameter", and
0441   //! - Period the period of this BSpline curve.
0442   //! Note: If this curve is not periodic, U is not modified.
0443   Standard_EXPORT void PeriodicNormalization(double& U) const;
0444 
0445   //! Changes this BSpline curve into a periodic curve.
0446   //! To become periodic, the curve must first be closed.
0447   //! Next, the knot sequence must be periodic. For this,
0448   //! FirstUKnotIndex and LastUKnotIndex are used to
0449   //! compute I1 and I2, the indexes in the knots array
0450   //! of the knots corresponding to the first and last
0451   //! parameters of this BSpline curve.
0452   //! The period is therefore Knot(I2) - Knot(I1).
0453   //! Consequently, the knots and poles tables are modified.
0454   //! Exceptions
0455   //! Standard_ConstructionError if this BSpline curve is not closed.
0456   Standard_EXPORT void SetPeriodic();
0457 
0458   //! Assigns the knot of index Index in the knots table as
0459   //! the origin of this periodic BSpline curve. As a
0460   //! consequence, the knots and poles tables are modified.
0461   //! Exceptions
0462   //! Standard_NoSuchObject if this curve is not periodic.
0463   //! Standard_DomainError if Index is outside the
0464   //! bounds of the knots table.
0465   Standard_EXPORT void SetOrigin(const int Index);
0466 
0467   //! Changes this BSpline curve into a non-periodic
0468   //! curve. If this curve is already non-periodic, it is not modified.
0469   //! Note that the poles and knots tables are modified.
0470   //! Warning
0471   //! If this curve is periodic, as the multiplicity of the first
0472   //! and last knots is not modified, and is not equal to
0473   //! Degree + 1, where Degree is the degree of
0474   //! this BSpline curve, the start and end points of the
0475   //! curve are not its first and last poles.
0476   Standard_EXPORT void SetNotPeriodic();
0477 
0478   //! Modifies this BSpline curve by assigning P to the
0479   //! pole of index Index in the poles table.
0480   //! Exceptions
0481   //! Standard_OutOfRange if Index is outside the
0482   //! bounds of the poles table.
0483   //! Standard_ConstructionError if Weight is negative or null.
0484   Standard_EXPORT void SetPole(const int Index, const gp_Pnt2d& P);
0485 
0486   //! Modifies this BSpline curve by assigning P to the
0487   //! pole of index Index in the poles table.
0488   //! The second syntax also allows you to modify the
0489   //! weight of the modified pole, which becomes Weight.
0490   //! In this case, if this BSpline curve is non-rational, it
0491   //! can become rational and vice versa.
0492   //! Exceptions
0493   //! Standard_OutOfRange if Index is outside the
0494   //! bounds of the poles table.
0495   //! Standard_ConstructionError if Weight is negative or null.
0496   Standard_EXPORT void SetPole(const int Index, const gp_Pnt2d& P, const double Weight);
0497 
0498   //! Assigns the weight Weight to the pole of index Index of the poles table.
0499   //! If the curve was non rational it can become rational.
0500   //! If the curve was rational it can become non rational.
0501   //! Exceptions
0502   //! Standard_OutOfRange if Index is outside the
0503   //! bounds of the poles table.
0504   //! Standard_ConstructionError if Weight is negative or null.
0505   Standard_EXPORT void SetWeight(const int Index, const double Weight);
0506 
0507   //! Moves the point of parameter U of this BSpline
0508   //! curve to P. Index1 and Index2 are the indexes in the
0509   //! table of poles of this BSpline curve of the first and
0510   //! last poles designated to be moved.
0511   //! FirstModifiedPole and LastModifiedPole are the
0512   //! indexes of the first and last poles, which are
0513   //! effectively modified.
0514   //! In the event of incompatibility between Index1,
0515   //! Index2 and the value U:
0516   //! - no change is made to this BSpline curve, and
0517   //! - the FirstModifiedPole and LastModifiedPole are returned null.
0518   //! Exceptions
0519   //! Standard_OutOfRange if:
0520   //! - Index1 is greater than or equal to Index2, or
0521   //! - Index1 or Index2 is less than 1 or greater than the
0522   //! number of poles of this BSpline curve.
0523   Standard_EXPORT void MovePoint(const double    U,
0524                                  const gp_Pnt2d& P,
0525                                  const int       Index1,
0526                                  const int       Index2,
0527                                  int&            FirstModifiedPole,
0528                                  int&            LastModifiedPole);
0529 
0530   //! Move a point with parameter U to P.
0531   //! and makes it tangent at U be Tangent.
0532   //! StartingCondition = -1 means first can move
0533   //! EndingCondition   = -1 means last point can move
0534   //! StartingCondition = 0 means the first point cannot move
0535   //! EndingCondition   = 0 means the last point cannot move
0536   //! StartingCondition = 1 means the first point and tangent cannot move
0537   //! EndingCondition   = 1 means the last point and tangent cannot move
0538   //! and so forth
0539   //! ErrorStatus != 0 means that there are not enough degree of freedom
0540   //! with the constrain to deform the curve accordingly
0541   Standard_EXPORT void MovePointAndTangent(const double    U,
0542                                            const gp_Pnt2d& P,
0543                                            const gp_Vec2d& Tangent,
0544                                            const double    Tolerance,
0545                                            const int       StartingCondition,
0546                                            const int       EndingCondition,
0547                                            int&            ErrorStatus);
0548 
0549   //! Returns true if the degree of continuity of this
0550   //! BSpline curve is at least N. A BSpline curve is at least GeomAbs_C0.
0551   //! Exceptions Standard_RangeError if N is negative.
0552   Standard_EXPORT bool IsCN(const int N) const final;
0553 
0554   //! Check if curve has at least G1 continuity in interval [theTf, theTl]
0555   //! Returns true if IsCN(1)
0556   //! or
0557   //! angle between "left" and "right" first derivatives at
0558   //! knots with C0 continuity is less then theAngTol
0559   //! only knots in interval [theTf, theTl] is checked
0560   Standard_EXPORT bool IsG1(const double theTf, const double theTl, const double theAngTol) const;
0561 
0562   //! Returns true if the distance between the first point and the
0563   //! last point of the curve is lower or equal to Resolution
0564   //! from package gp.
0565   //! Warnings :
0566   //! The first and the last point can be different from the first
0567   //! pole and the last pole of the curve.
0568   Standard_EXPORT bool IsClosed() const final;
0569 
0570   //! Returns True if the curve is periodic.
0571   Standard_EXPORT bool IsPeriodic() const final;
0572 
0573   //! Returns True if the weights are not identical.
0574   //! The tolerance criterion is Epsilon of the class Real.
0575   Standard_EXPORT bool IsRational() const;
0576 
0577   //! Returns the global continuity of the curve :
0578   //! C0 : only geometric continuity,
0579   //! C1 : continuity of the first derivative all along the Curve,
0580   //! C2 : continuity of the second derivative all along the Curve,
0581   //! C3 : continuity of the third derivative all along the Curve,
0582   //! CN : the order of continuity is infinite.
0583   //! For a B-spline curve of degree d if a knot Ui has a
0584   //! multiplicity p the B-spline curve is only Cd-p continuous
0585   //! at Ui. So the global continuity of the curve can't be greater
0586   //! than Cd-p where p is the maximum multiplicity of the interior
0587   //! Knots. In the interior of a knot span the curve is infinitely
0588   //! continuously differentiable.
0589   Standard_EXPORT GeomAbs_Shape Continuity() const final;
0590 
0591   //! Returns the degree of this BSpline curve.
0592   //! In this class the degree of the basis normalized B-spline
0593   //! functions cannot be greater than "MaxDegree"
0594   //! Computation of value and derivatives
0595   Standard_EXPORT int Degree() const;
0596 
0597   Standard_EXPORT gp_Pnt2d EvalD0(const double U) const final;
0598 
0599   //! Raised if the continuity of the curve is not C1.
0600   Standard_EXPORT Geom2d_Curve::ResD1 EvalD1(const double U) const final;
0601 
0602   //! Raised if the continuity of the curve is not C2.
0603   Standard_EXPORT Geom2d_Curve::ResD2 EvalD2(const double U) const final;
0604 
0605   //! For this BSpline curve, computes
0606   //! - the point P of parameter U, or
0607   //! - the point P and one or more of the following values:
0608   //! - V1, the first derivative vector,
0609   //! - V2, the second derivative vector,
0610   //! - V3, the third derivative vector.
0611   //! Warning
0612   //! On a point where the continuity of the curve is not the
0613   //! one requested, these functions impact the part
0614   //! defined by the parameter with a value greater than U,
0615   //! i.e. the part of the curve to the "right" of the singularity.
0616   //! Raises UndefinedDerivative if the continuity of the curve is not C3.
0617   Standard_EXPORT Geom2d_Curve::ResD3 EvalD3(const double U) const final;
0618 
0619   //! For the point of parameter U of this BSpline curve,
0620   //! computes the vector corresponding to the Nth derivative.
0621   //! Warning
0622   //! On a point where the continuity of the curve is not the
0623   //! one requested, this function impacts the part defined
0624   //! by the parameter with a value greater than U, i.e. the
0625   //! part of the curve to the "right" of the singularity.
0626   //! Raises UndefinedDerivative if the continuity of the curve is not CN.
0627   //! RangeError if N < 1.
0628   //! The following functions computes the point of parameter U
0629   //! and the derivatives at this point on the B-spline curve
0630   //! arc defined between the knot FromK1 and the knot ToK2.
0631   //! U can be out of bounds [Knot (FromK1), Knot (ToK2)] but
0632   //! for the computation we only use the definition of the curve
0633   //! between these two knots. This method is useful to compute
0634   //! local derivative, if the order of continuity of the whole
0635   //! curve is not greater enough. Inside the parametric
0636   //! domain Knot (FromK1), Knot (ToK2) the evaluations are
0637   //! the same as if we consider the whole definition of the
0638   //! curve. Of course the evaluations are different outside
0639   //! this parametric domain.
0640   Standard_EXPORT gp_Vec2d EvalDN(const double U, const int N) const final;
0641 
0642   //! Raised if FromK1 = ToK2.
0643   Standard_EXPORT gp_Pnt2d LocalValue(const double U, const int FromK1, const int ToK2) const;
0644 
0645   //! Raised if FromK1 = ToK2.
0646   Standard_EXPORT void LocalD0(const double U, const int FromK1, const int ToK2, gp_Pnt2d& P) const;
0647 
0648   //! Raised if the local continuity of the curve is not C1
0649   //! between the knot K1 and the knot K2.
0650   //! Raised if FromK1 = ToK2.
0651   Standard_EXPORT void LocalD1(const double U,
0652                                const int    FromK1,
0653                                const int    ToK2,
0654                                gp_Pnt2d&    P,
0655                                gp_Vec2d&    V1) const;
0656 
0657   //! Raised if the local continuity of the curve is not C2
0658   //! between the knot K1 and the knot K2.
0659   //! Raised if FromK1 = ToK2.
0660   Standard_EXPORT void LocalD2(const double U,
0661                                const int    FromK1,
0662                                const int    ToK2,
0663                                gp_Pnt2d&    P,
0664                                gp_Vec2d&    V1,
0665                                gp_Vec2d&    V2) const;
0666 
0667   //! Raised if the local continuity of the curve is not C3
0668   //! between the knot K1 and the knot K2.
0669   //! Raised if FromK1 = ToK2.
0670   Standard_EXPORT void LocalD3(const double U,
0671                                const int    FromK1,
0672                                const int    ToK2,
0673                                gp_Pnt2d&    P,
0674                                gp_Vec2d&    V1,
0675                                gp_Vec2d&    V2,
0676                                gp_Vec2d&    V3) const;
0677 
0678   //! Raised if the local continuity of the curve is not CN
0679   //! between the knot K1 and the knot K2.
0680   //! Raised if FromK1 = ToK2.
0681   //! Raised if N < 1.
0682   Standard_EXPORT gp_Vec2d LocalDN(const double U,
0683                                    const int    FromK1,
0684                                    const int    ToK2,
0685                                    const int    N) const;
0686 
0687   //! Returns the last point of the curve.
0688   //! Warnings :
0689   //! The last point of the curve is different from the last
0690   //! pole of the curve if the multiplicity of the last knot
0691   //! is lower than Degree.
0692   Standard_EXPORT gp_Pnt2d EndPoint() const final;
0693 
0694   //! For a B-spline curve the first parameter (which gives the start
0695   //! point of the curve) is a knot value but if the multiplicity of
0696   //! the first knot index is lower than Degree + 1 it is not the
0697   //! first knot of the curve. This method computes the index of the
0698   //! knot corresponding to the first parameter.
0699   Standard_EXPORT int FirstUKnotIndex() const;
0700 
0701   //! Computes the parametric value of the start point of the curve.
0702   //! It is a knot value.
0703   Standard_EXPORT double FirstParameter() const final;
0704 
0705   //! Returns the knot of range Index. When there is a knot
0706   //! with a multiplicity greater than 1 the knot is not repeated.
0707   //! The method Multiplicity can be used to get the multiplicity
0708   //! of the Knot.
0709   //! Raised if Index < 1 or Index > NbKnots
0710   Standard_EXPORT double Knot(const int Index) const;
0711 
0712   //! returns the knot values of the B-spline curve;
0713   //!
0714   //! Raised K.Lower() is less than number of first knot or
0715   //! K.Upper() is more than number of last knot.
0716   Standard_DEPRECATED("use Knots() returning const reference instead")
0717   Standard_EXPORT void Knots(NCollection_Array1<double>& K) const;
0718 
0719   //! returns the knot values of the B-spline curve;
0720   Standard_EXPORT const NCollection_Array1<double>& Knots() const;
0721 
0722   //! Returns the knots sequence.
0723   //! In this sequence the knots with a multiplicity greater than 1
0724   //! are repeated.
0725   //! Example :
0726   //! K = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
0727   //!
0728   //! Raised if K.Lower() is less than number of first knot
0729   //! in knot sequence with repetitions or K.Upper() is more
0730   //! than number of last knot in knot sequence with repetitions.
0731   Standard_DEPRECATED("use KnotSequence() returning const reference instead")
0732   Standard_EXPORT void KnotSequence(NCollection_Array1<double>& K) const;
0733 
0734   //! Returns the knots sequence.
0735   //! In this sequence the knots with a multiplicity greater than 1
0736   //! are repeated.
0737   //! Example :
0738   //! K = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
0739   Standard_EXPORT const NCollection_Array1<double>& KnotSequence() const;
0740 
0741   //! Returns NonUniform or Uniform or QuasiUniform or PiecewiseBezier.
0742   //! If all the knots differ by a positive constant from the
0743   //! preceding knot the BSpline Curve can be :
0744   //! - Uniform if all the knots are of multiplicity 1,
0745   //! - QuasiUniform if all the knots are of multiplicity 1 except for
0746   //! the first and last knot which are of multiplicity Degree + 1,
0747   //! - PiecewiseBezier if the first and last knots have multiplicity
0748   //! Degree + 1 and if interior knots have multiplicity Degree
0749   //! A piecewise Bezier with only two knots is a BezierCurve.
0750   //! else the curve is non uniform.
0751   //! The tolerance criterion is Epsilon from class Real.
0752   Standard_EXPORT GeomAbs_BSplKnotDistribution KnotDistribution() const;
0753 
0754   //! For a BSpline curve the last parameter (which gives the
0755   //! end point of the curve) is a knot value but if the
0756   //! multiplicity of the last knot index is lower than
0757   //! Degree + 1 it is not the last knot of the curve. This
0758   //! method computes the index of the knot corresponding to
0759   //! the last parameter.
0760   Standard_EXPORT int LastUKnotIndex() const;
0761 
0762   //! Computes the parametric value of the end point of the curve.
0763   //! It is a knot value.
0764   Standard_EXPORT double LastParameter() const final;
0765 
0766   //! Locates the parametric value U in the sequence of knots.
0767   //! If "WithKnotRepetition" is True we consider the knot's
0768   //! representation with repetition of multiple knot value,
0769   //! otherwise we consider the knot's representation with
0770   //! no repetition of multiple knot values.
0771   //! Knots (I1) <= U <= Knots (I2)
0772   //! . if I1 = I2  U is a knot value (the tolerance criterion
0773   //! ParametricTolerance is used).
0774   //! . if I1 < 1  => U < Knots (1) - std::abs(ParametricTolerance)
0775   //! . if I2 > NbKnots => U > Knots (NbKnots) + std::abs(ParametricTolerance)
0776   Standard_EXPORT void LocateU(const double U,
0777                                const double ParametricTolerance,
0778                                int&         I1,
0779                                int&         I2,
0780                                const bool   WithKnotRepetition = false) const;
0781 
0782   //! Returns the multiplicity of the knots of range Index.
0783   //! Raised if Index < 1 or Index > NbKnots
0784   Standard_EXPORT int Multiplicity(const int Index) const;
0785 
0786   //! Returns the multiplicity of the knots of the curve.
0787   //!
0788   //! Raised if the length of M is not equal to NbKnots.
0789   Standard_DEPRECATED("use Multiplicities() returning const reference instead")
0790   Standard_EXPORT void Multiplicities(NCollection_Array1<int>& M) const;
0791 
0792   //! returns the multiplicity of the knots of the curve.
0793   Standard_EXPORT const NCollection_Array1<int>& Multiplicities() const;
0794 
0795   //! Returns the number of knots. This method returns the number of
0796   //! knot without repetition of multiple knots.
0797   Standard_EXPORT int NbKnots() const;
0798 
0799   //! Returns the number of poles
0800   Standard_EXPORT int NbPoles() const;
0801 
0802   //! Returns the pole of range Index.
0803   //! Raised if Index < 1 or Index > NbPoles.
0804   Standard_EXPORT const gp_Pnt2d& Pole(const int Index) const;
0805 
0806   //! Returns the poles of the B-spline curve;
0807   //!
0808   //! Raised if the length of P is not equal to the number of poles.
0809   Standard_DEPRECATED("use Poles() returning const reference instead")
0810   Standard_EXPORT void Poles(NCollection_Array1<gp_Pnt2d>& P) const;
0811 
0812   //! Returns the poles of the B-spline curve;
0813   Standard_EXPORT const NCollection_Array1<gp_Pnt2d>& Poles() const;
0814 
0815   //! Returns the start point of the curve.
0816   //! Warnings :
0817   //! This point is different from the first pole of the curve if the
0818   //! multiplicity of the first knot is lower than Degree.
0819   Standard_EXPORT gp_Pnt2d StartPoint() const final;
0820 
0821   //! Returns the weight of the pole of range Index .
0822   //! Raised if Index < 1 or Index > NbPoles.
0823   Standard_EXPORT double Weight(const int Index) const;
0824 
0825   //! Returns the weights of the B-spline curve;
0826   //!
0827   //! Raised if the length of W is not equal to NbPoles.
0828   Standard_DEPRECATED("use Weights() returning const pointer instead")
0829   Standard_EXPORT void Weights(NCollection_Array1<double>& W) const;
0830 
0831   //! Returns the weights of the B-spline curve;
0832   Standard_EXPORT const NCollection_Array1<double>* Weights() const;
0833 
0834   //! Returns a const reference to the weights array.
0835   //! For rational curves: the internal owning weights array.
0836   //! For non-rational curves: a non-owning view of unit weights from BSplCLib.
0837   //! The array is always sized to match NbPoles().
0838   //! @warning Do NOT modify elements through the returned reference.
0839   const NCollection_Array1<double>& WeightsArray() const { return myWeights; }
0840 
0841   //! Applies the transformation T to this BSpline curve.
0842   Standard_EXPORT void Transform(const gp_Trsf2d& T) final;
0843 
0844   //! Returns the value of the maximum degree of the normalized
0845   //! B-spline basis functions in this package.
0846   Standard_EXPORT static int MaxDegree();
0847 
0848   //! Computes for this BSpline curve the parametric
0849   //! tolerance UTolerance for a given tolerance
0850   //! Tolerance3D (relative to dimensions in the plane).
0851   //! If f(t) is the equation of this BSpline curve,
0852   //! UTolerance ensures that:
0853   //! | t1 - t0| < Utolerance ===>
0854   //! |f(t1) - f(t0)| < ToleranceUV
0855   Standard_EXPORT void Resolution(const double ToleranceUV, double& UTolerance);
0856 
0857   //! Creates a new object which is a copy of this BSpline curve.
0858   Standard_EXPORT occ::handle<Geom2d_Geometry> Copy() const final;
0859 
0860   //! Dumps the content of me into the stream
0861   Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const final;
0862 
0863   DEFINE_STANDARD_RTTIEXT(Geom2d_BSplineCurve, Geom2d_BoundedCurve)
0864 
0865 protected:
0866   //! Recompute the flatknots, the knotsdistribution, the continuity.
0867   void updateKnots();
0868 
0869 private:
0870   NCollection_Array1<gp_Pnt2d>               myPoles;
0871   NCollection_Array1<double>                 myWeights;
0872   NCollection_Array1<double>                 myKnots;
0873   NCollection_Array1<double>                 myFlatKnots;
0874   NCollection_Array1<int>                    myMults;
0875   occ::handle<Geom2dEval_RepCurveDesc::Base> myEvalRep;
0876   int                                        myDeg           = 0;
0877   bool                                       myPeriodic      = false;
0878   bool                                       myRational      = false;
0879   GeomAbs_BSplKnotDistribution               myKnotSet       = GeomAbs_NonUniform;
0880   GeomAbs_Shape                              mySmooth        = GeomAbs_C0;
0881   double                                     myMaxDerivInv   = 0.0;
0882   bool                                       myMaxDerivInvOk = false;
0883 };
0884 
0885 #endif // _Geom2d_BSplineCurve_HeaderFile