|
|
|||
File indexing completed on 2026-09-29 09:19:30
0001 // Created on: 1995-10-20 0002 // Created by: Laurent BOURESCHE 0003 // Copyright (c) 1995-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 _Law_BSpline_HeaderFile 0018 #define _Law_BSpline_HeaderFile 0019 0020 #include <Standard.hxx> 0021 #include <Standard_Type.hxx> 0022 0023 #include <GeomAbs_BSplKnotDistribution.hxx> 0024 #include <GeomAbs_Shape.hxx> 0025 #include <Standard_Integer.hxx> 0026 #include <NCollection_Array1.hxx> 0027 #include <NCollection_HArray1.hxx> 0028 #include <Standard_Transient.hxx> 0029 0030 //! Definition of the 1D B_spline curve. 0031 //! 0032 //! Uniform or non-uniform 0033 //! Rational or non-rational 0034 //! Periodic or non-periodic 0035 //! 0036 //! A b-spline curve is defined by: 0037 //! 0038 //! The Degree (up to 25) 0039 //! 0040 //! The Poles (and the weights if it is rational) 0041 //! 0042 //! The Knots and Multiplicities 0043 //! 0044 //! The knot vector is an increasing sequence of 0045 //! reals without repetition. The multiplicities are 0046 //! the repetition of the knots. 0047 //! 0048 //! If the knots are regularly spaced (the difference 0049 //! of two consecutive knots is a constant), the 0050 //! knots repartition is: 0051 //! 0052 //! - Uniform if all multiplicities are 1. 0053 //! 0054 //! - Quasi-uniform if all multiplicities are 1 0055 //! but the first and the last which are Degree+1. 0056 //! 0057 //! - PiecewiseBezier if all multiplicities are 0058 //! Degree but the first and the last which are 0059 //! Degree+1. 0060 //! 0061 //! The curve may be periodic. 0062 //! 0063 //! On a periodic curve if there are k knots and p 0064 //! poles. the period is knot(k) - knot(1) 0065 //! 0066 //! the poles and knots are infinite vectors with: 0067 //! 0068 //! knot(i+k) = knot(i) + period 0069 //! 0070 //! pole(i+p) = pole(i) 0071 //! 0072 //! References : 0073 //! . A survey of curve and surface methods in CADG Wolfgang BOHM 0074 //! CAGD 1 (1984) 0075 //! . On de Boor-like algorithms and blossoming Wolfgang BOEHM 0076 //! cagd 5 (1988) 0077 //! . Blossoming and knot insertion algorithms for B-spline curves 0078 //! Ronald N. GOLDMAN 0079 //! . Modelisation des surfaces en CAO, Henri GIAUME Peugeot SA 0080 //! . Curves and Surfaces for Computer Aided Geometric Design, 0081 //! a practical guide Gerald Farin 0082 class Law_BSpline : public Standard_Transient 0083 { 0084 0085 public: 0086 //! Creates a non-rational B_spline curve on the 0087 //! basis <Knots, Multiplicities> of degree <Degree>. 0088 Standard_EXPORT Law_BSpline(const NCollection_Array1<double>& Poles, 0089 const NCollection_Array1<double>& Knots, 0090 const NCollection_Array1<int>& Multiplicities, 0091 const int Degree, 0092 const bool Periodic = false); 0093 0094 //! Creates a rational B_spline curve on the basis 0095 //! <Knots, Multiplicities> of degree <Degree>. 0096 Standard_EXPORT Law_BSpline(const NCollection_Array1<double>& Poles, 0097 const NCollection_Array1<double>& Weights, 0098 const NCollection_Array1<double>& Knots, 0099 const NCollection_Array1<int>& Multiplicities, 0100 const int Degree, 0101 const bool Periodic = false); 0102 0103 //! Increase the degree to <Degree>. Nothing is done 0104 //! if <Degree> is lower or equal to the current 0105 //! degree. 0106 Standard_EXPORT void IncreaseDegree(const int Degree); 0107 0108 //! Increases the multiplicity of the knot <Index> to 0109 //! <M>. 0110 //! 0111 //! If <M> is lower or equal to the current multiplicity 0112 //! nothing is done. If <M> is higher than the degree 0113 //! the degree is used. 0114 //! If <Index> is not in [FirstUKnotIndex, LastUKnotIndex] 0115 Standard_EXPORT void IncreaseMultiplicity(const int Index, const int M); 0116 0117 //! Increases the multiplicities of the knots in 0118 //! [I1,I2] to <M>. 0119 //! 0120 //! For each knot if <M> is lower or equal to the 0121 //! current multiplicity nothing is done. If <M> is 0122 //! higher than the degree the degree is used. 0123 //! If <I1,I2> are not in [FirstUKnotIndex, LastUKnotIndex] 0124 Standard_EXPORT void IncreaseMultiplicity(const int I1, const int I2, const int M); 0125 0126 //! Increment the multiplicities of the knots in 0127 //! [I1,I2] by <M>. 0128 //! 0129 //! If <M> is not positive nothing is done. 0130 //! 0131 //! For each knot the resulting multiplicity is 0132 //! limited to the Degree. 0133 //! If <I1,I2> are not in [FirstUKnotIndex, LastUKnotIndex] 0134 Standard_EXPORT void IncrementMultiplicity(const int I1, const int I2, const int M); 0135 0136 //! Inserts a knot value in the sequence of knots. 0137 //! If <U> is an existing knot the multiplicity is 0138 //! increased by <M>. 0139 //! 0140 //! If U is not on the parameter range nothing is 0141 //! done. 0142 //! 0143 //! If the multiplicity is negative or null nothing is 0144 //! done. The new multiplicity is limited to the 0145 //! degree. 0146 //! 0147 //! The tolerance criterion for knots equality is 0148 //! the max of Epsilon(U) and ParametricTolerance. 0149 Standard_EXPORT void InsertKnot(const double U, 0150 const int M = 1, 0151 const double ParametricTolerance = 0.0, 0152 const bool Add = true); 0153 0154 //! Inserts a set of knots values in the sequence of 0155 //! knots. 0156 //! 0157 //! For each U = Knots(i), M = Mults(i) 0158 //! 0159 //! If <U> is an existing knot the multiplicity is 0160 //! increased by <M> if <Add> is True, increased to 0161 //! <M> if <Add> is False. 0162 //! 0163 //! If U is not on the parameter range nothing is 0164 //! done. 0165 //! 0166 //! If the multiplicity is negative or null nothing is 0167 //! done. The new multiplicity is limited to the 0168 //! degree. 0169 //! 0170 //! The tolerance criterion for knots equality is 0171 //! the max of Epsilon(U) and ParametricTolerance. 0172 Standard_EXPORT void InsertKnots(const NCollection_Array1<double>& Knots, 0173 const NCollection_Array1<int>& Mults, 0174 const double ParametricTolerance = 0.0, 0175 const bool Add = false); 0176 0177 //! Decrement the knots multiplicity to <M>. If M is 0178 //! 0 the knot is removed. The Poles sequence is 0179 //! modified. 0180 //! 0181 //! As there are two ways to compute the new poles the 0182 //! average is computed if the distance is lower than 0183 //! the <Tolerance>, else False is returned. 0184 //! 0185 //! A low tolerance is used to prevent the modification 0186 //! of the curve. 0187 //! 0188 //! A high tolerance is used to "smooth" the curve. 0189 //! 0190 //! Raised if Index is not in the range 0191 //! [FirstUKnotIndex, LastUKnotIndex] 0192 //! pole insertion and pole removing 0193 //! this operation is limited to the Uniform or QuasiUniform 0194 //! BSplineCurve. The knot values are modified. If the BSpline is 0195 //! NonUniform or Piecewise Bezier an exception Construction error 0196 //! is raised. 0197 Standard_EXPORT bool RemoveKnot(const int Index, const int M, const double Tolerance); 0198 0199 //! Changes the direction of parametrization of <me>. The Knot 0200 //! sequence is modified, the FirstParameter and the 0201 //! LastParameter are not modified. The StartPoint of the 0202 //! initial curve becomes the EndPoint of the reversed curve 0203 //! and the EndPoint of the initial curve becomes the StartPoint 0204 //! of the reversed curve. 0205 Standard_EXPORT void Reverse(); 0206 0207 //! Returns the parameter on the reversed curve for 0208 //! the point of parameter U on <me>. 0209 //! 0210 //! returns UFirst + ULast - U 0211 Standard_EXPORT double ReversedParameter(const double U) const; 0212 0213 //! Segments the curve between U1 and U2. 0214 //! The control points are modified, the first and the last point 0215 //! are not the same. 0216 //! Warnings : 0217 //! Even if <me> is not closed it can become closed after the 0218 //! segmentation for example if U1 or U2 are out of the bounds 0219 //! of the curve <me> or if the curve makes loop. 0220 //! After the segmentation the length of a curve can be null. 0221 //! raises if U2 < U1. 0222 Standard_EXPORT void Segment(const double U1, const double U2); 0223 0224 //! Changes the knot of range Index. 0225 //! The multiplicity of the knot is not modified. 0226 //! Raised if K >= Knots(Index+1) or K <= Knots(Index-1). 0227 //! Raised if Index < 1 || Index > NbKnots 0228 Standard_EXPORT void SetKnot(const int Index, const double K); 0229 0230 //! Changes all the knots of the curve 0231 //! The multiplicity of the knots are not modified. 0232 //! 0233 //! Raised if there is an index such that K (Index+1) <= K (Index). 0234 //! 0235 //! Raised if K.Lower() < 1 or K.Upper() > NbKnots 0236 Standard_EXPORT void SetKnots(const NCollection_Array1<double>& K); 0237 0238 //! Changes the knot of range Index with its multiplicity. 0239 //! You can increase the multiplicity of a knot but it is 0240 //! not allowed to decrease the multiplicity of an existing knot. 0241 //! 0242 //! Raised if K >= Knots(Index+1) or K <= Knots(Index-1). 0243 //! Raised if M is greater than Degree or lower than the previous 0244 //! multiplicity of knot of range Index. 0245 //! Raised if Index < 1 || Index > NbKnots 0246 Standard_EXPORT void SetKnot(const int Index, const double K, const int M); 0247 0248 //! returns the parameter normalized within 0249 //! the period if the curve is periodic : otherwise 0250 //! does not do anything 0251 Standard_EXPORT void PeriodicNormalization(double& U) const; 0252 0253 //! Makes a closed B-spline into a periodic curve. The curve is 0254 //! periodic if the knot sequence is periodic and if the curve is 0255 //! closed (The tolerance criterion is Resolution from gp). 0256 //! The period T is equal to Knot(LastUKnotIndex) - 0257 //! Knot(FirstUKnotIndex). A periodic B-spline can be uniform 0258 //! or not. 0259 //! Raised if the curve is not closed. 0260 Standard_EXPORT void SetPeriodic(); 0261 0262 //! Set the origin of a periodic curve at Knot(index) 0263 //! KnotVector and poles are modified. 0264 //! Raised if the curve is not periodic 0265 //! Raised if index not in the range 0266 //! [FirstUKnotIndex , LastUKnotIndex] 0267 Standard_EXPORT void SetOrigin(const int Index); 0268 0269 //! Makes a non periodic curve. If the curve was non periodic 0270 //! the curve is not modified. 0271 Standard_EXPORT void SetNotPeriodic(); 0272 0273 //! Substitutes the Pole of range Index with P. 0274 //! 0275 //! Raised if Index < 1 || Index > NbPoles 0276 Standard_EXPORT void SetPole(const int Index, const double P); 0277 0278 //! Substitutes the pole and the weight of range Index. 0279 //! If the curve <me> is not rational it can become rational 0280 //! If the curve was rational it can become non rational 0281 //! 0282 //! Raised if Index < 1 || Index > NbPoles 0283 //! Raised if Weight <= 0.0 0284 Standard_EXPORT void SetPole(const int Index, const double P, const double Weight); 0285 0286 //! Changes the weight for the pole of range Index. 0287 //! If the curve was non rational it can become rational. 0288 //! If the curve was rational it can become non rational. 0289 //! 0290 //! Raised if Index < 1 || Index > NbPoles 0291 //! Raised if Weight <= 0.0 0292 Standard_EXPORT void SetWeight(const int Index, const double Weight); 0293 0294 //! Returns the continuity of the curve, the curve is at least C0. 0295 //! Raised if N < 0. 0296 Standard_EXPORT bool IsCN(const int N) const; 0297 0298 //! Returns true if the distance between the first point and the 0299 //! last point of the curve is lower or equal to Resolution 0300 //! from package gp. 0301 //! Warnings : 0302 //! The first and the last point can be different from the first 0303 //! pole and the last pole of the curve. 0304 Standard_EXPORT bool IsClosed() const; 0305 0306 //! Returns True if the curve is periodic. 0307 Standard_EXPORT bool IsPeriodic() const; 0308 0309 //! Returns True if the weights are not identical. 0310 //! The tolerance criterion is Epsilon of the class Real. 0311 Standard_EXPORT bool IsRational() const; 0312 0313 //! Returns the global continuity of the curve : 0314 //! C0 : only geometric continuity, 0315 //! C1 : continuity of the first derivative all along the Curve, 0316 //! C2 : continuity of the second derivative all along the Curve, 0317 //! C3 : continuity of the third derivative all along the Curve, 0318 //! CN : the order of continuity is infinite. 0319 //! For a B-spline curve of degree d if a knot Ui has a 0320 //! multiplicity p the B-spline curve is only Cd-p continuous 0321 //! at Ui. So the global continuity of the curve can't be greater 0322 //! than Cd-p where p is the maximum multiplicity of the interior 0323 //! Knots. In the interior of a knot span the curve is infinitely 0324 //! continuously differentiable. 0325 Standard_EXPORT GeomAbs_Shape Continuity() const; 0326 0327 //! Computation of value and derivatives 0328 Standard_EXPORT int Degree() const; 0329 0330 Standard_EXPORT double Value(const double U) const; 0331 0332 Standard_EXPORT void D0(const double U, double& P) const; 0333 0334 Standard_EXPORT void D1(const double U, double& P, double& V1) const; 0335 0336 Standard_EXPORT void D2(const double U, double& P, double& V1, double& V2) const; 0337 0338 Standard_EXPORT void D3(const double U, double& P, double& V1, double& V2, double& V3) const; 0339 0340 //! The following functions computes the point of parameter U and 0341 //! the derivatives at this point on the B-spline curve arc 0342 //! defined between the knot FromK1 and the knot ToK2. U can be 0343 //! out of bounds [Knot (FromK1), Knot (ToK2)] but for the 0344 //! computation we only use the definition of the curve between 0345 //! these two knots. This method is useful to compute local 0346 //! derivative, if the order of continuity of the whole curve is 0347 //! not greater enough. Inside the parametric domain Knot 0348 //! (FromK1), Knot (ToK2) the evaluations are the same as if we 0349 //! consider the whole definition of the curve. Of course the 0350 //! evaluations are different outside this parametric domain. 0351 Standard_EXPORT double DN(const double U, const int N) const; 0352 0353 Standard_EXPORT double LocalValue(const double U, const int FromK1, const int ToK2) const; 0354 0355 Standard_EXPORT void LocalD0(const double U, const int FromK1, const int ToK2, double& P) const; 0356 0357 Standard_EXPORT void LocalD1(const double U, 0358 const int FromK1, 0359 const int ToK2, 0360 double& P, 0361 double& V1) const; 0362 0363 Standard_EXPORT void LocalD2(const double U, 0364 const int FromK1, 0365 const int ToK2, 0366 double& P, 0367 double& V1, 0368 double& V2) const; 0369 0370 Standard_EXPORT void LocalD3(const double U, 0371 const int FromK1, 0372 const int ToK2, 0373 double& P, 0374 double& V1, 0375 double& V2, 0376 double& V3) const; 0377 0378 Standard_EXPORT double LocalDN(const double U, 0379 const int FromK1, 0380 const int ToK2, 0381 const int N) const; 0382 0383 //! Returns the last point of the curve. 0384 //! Warnings : 0385 //! The last point of the curve is different from the last 0386 //! pole of the curve if the multiplicity of the last knot 0387 //! is lower than Degree. 0388 Standard_EXPORT double EndPoint() const; 0389 0390 //! For a B-spline curve the first parameter (which gives the start 0391 //! point of the curve) is a knot value but if the multiplicity of 0392 //! the first knot index is lower than Degree + 1 it is not the 0393 //! first knot of the curve. This method computes the index of the 0394 //! knot corresponding to the first parameter. 0395 Standard_EXPORT int FirstUKnotIndex() const; 0396 0397 //! Computes the parametric value of the start point of the curve. 0398 //! It is a knot value. 0399 Standard_EXPORT double FirstParameter() const; 0400 0401 //! Returns the knot of range Index. When there is a knot 0402 //! with a multiplicity greater than 1 the knot is not repeated. 0403 //! The method Multiplicity can be used to get the multiplicity 0404 //! of the Knot. 0405 //! Raised if Index < 1 or Index > NbKnots 0406 Standard_EXPORT double Knot(const int Index) const; 0407 0408 //! returns the knot values of the B-spline curve; 0409 //! 0410 //! Raised if the length of K is not equal to the number of knots. 0411 Standard_EXPORT void Knots(NCollection_Array1<double>& K) const; 0412 0413 //! Returns the knots sequence. 0414 //! In this sequence the knots with a multiplicity greater than 1 0415 //! are repeated. 0416 //! Example : 0417 //! K = {k1, k1, k1, k2, k3, k3, k4, k4, k4} 0418 //! 0419 //! Raised if the length of K is not equal to NbPoles + Degree + 1 0420 Standard_EXPORT void KnotSequence(NCollection_Array1<double>& K) const; 0421 0422 //! Returns NonUniform or Uniform or QuasiUniform or PiecewiseBezier. 0423 //! If all the knots differ by a positive constant from the 0424 //! preceding knot the BSpline Curve can be : 0425 //! - Uniform if all the knots are of multiplicity 1, 0426 //! - QuasiUniform if all the knots are of multiplicity 1 except for 0427 //! the first and last knot which are of multiplicity Degree + 1, 0428 //! - PiecewiseBezier if the first and last knots have multiplicity 0429 //! Degree + 1 and if interior knots have multiplicity Degree 0430 //! A piecewise Bezier with only two knots is a BezierCurve. 0431 //! else the curve is non uniform. 0432 //! The tolerance criterion is Epsilon from class Real. 0433 Standard_EXPORT GeomAbs_BSplKnotDistribution KnotDistribution() const; 0434 0435 //! For a BSpline curve the last parameter (which gives the 0436 //! end point of the curve) is a knot value but if the 0437 //! multiplicity of the last knot index is lower than 0438 //! Degree + 1 it is not the last knot of the curve. This 0439 //! method computes the index of the knot corresponding to 0440 //! the last parameter. 0441 Standard_EXPORT int LastUKnotIndex() const; 0442 0443 //! Computes the parametric value of the end point of the curve. 0444 //! It is a knot value. 0445 Standard_EXPORT double LastParameter() const; 0446 0447 //! Locates the parametric value U in the sequence of knots. 0448 //! If "WithKnotRepetition" is True we consider the knot's 0449 //! representation with repetition of multiple knot value, 0450 //! otherwise we consider the knot's representation with 0451 //! no repetition of multiple knot values. 0452 //! Knots (I1) <= U <= Knots (I2) 0453 //! . if I1 = I2 U is a knot value (the tolerance criterion 0454 //! ParametricTolerance is used). 0455 //! . if I1 < 1 => U < Knots (1) - std::abs(ParametricTolerance) 0456 //! . if I2 > NbKnots => U > Knots (NbKnots) + std::abs(ParametricTolerance) 0457 Standard_EXPORT void LocateU(const double U, 0458 const double ParametricTolerance, 0459 int& I1, 0460 int& I2, 0461 const bool WithKnotRepetition = false) const; 0462 0463 //! Returns the multiplicity of the knots of range Index. 0464 //! Raised if Index < 1 or Index > NbKnots 0465 Standard_EXPORT int Multiplicity(const int Index) const; 0466 0467 //! Returns the multiplicity of the knots of the curve. 0468 //! 0469 //! Raised if the length of M is not equal to NbKnots. 0470 Standard_EXPORT void Multiplicities(NCollection_Array1<int>& M) const; 0471 0472 //! Returns the number of knots. This method returns the number of 0473 //! knot without repetition of multiple knots. 0474 Standard_EXPORT int NbKnots() const; 0475 0476 //! Returns the number of poles 0477 Standard_EXPORT int NbPoles() const; 0478 0479 //! Returns the pole of range Index. 0480 //! Raised if Index < 1 or Index > NbPoles. 0481 Standard_EXPORT double Pole(const int Index) const; 0482 0483 //! Returns the poles of the B-spline curve; 0484 //! 0485 //! Raised if the length of P is not equal to the number of poles. 0486 Standard_EXPORT void Poles(NCollection_Array1<double>& P) const; 0487 0488 //! Returns the start point of the curve. 0489 //! Warnings : 0490 //! This point is different from the first pole of the curve if the 0491 //! multiplicity of the first knot is lower than Degree. 0492 Standard_EXPORT double StartPoint() const; 0493 0494 //! Returns the weight of the pole of range Index . 0495 //! Raised if Index < 1 or Index > NbPoles. 0496 Standard_EXPORT double Weight(const int Index) const; 0497 0498 //! Returns the weights of the B-spline curve; 0499 //! 0500 //! Raised if the length of W is not equal to NbPoles. 0501 Standard_EXPORT void Weights(NCollection_Array1<double>& W) const; 0502 0503 //! Returns the value of the maximum degree of the normalized 0504 //! B-spline basis functions in this package. 0505 Standard_EXPORT static int MaxDegree(); 0506 0507 //! Changes the value of the Law at parameter U to NewValue. 0508 //! and makes its derivative at U be derivative. 0509 //! StartingCondition = -1 means first can move 0510 //! EndingCondition = -1 means last point can move 0511 //! StartingCondition = 0 means the first point cannot move 0512 //! EndingCondition = 0 means the last point cannot move 0513 //! StartingCondition = 1 means the first point and tangent cannot move 0514 //! EndingCondition = 1 means the last point and tangent cannot move 0515 //! and so forth 0516 //! ErrorStatus != 0 means that there are not enough degree of freedom 0517 //! with the constrain to deform the curve accordingly 0518 Standard_EXPORT void MovePointAndTangent(const double U, 0519 const double NewValue, 0520 const double Derivative, 0521 const double Tolerance, 0522 const int StartingCondition, 0523 const int EndingCondition, 0524 int& ErrorStatus); 0525 0526 //! given Tolerance3D returns UTolerance 0527 //! such that if f(t) is the curve we have 0528 //! | t1 - t0| < Utolerance ===> 0529 //! |f(t1) - f(t0)| < Tolerance3D 0530 Standard_EXPORT void Resolution(const double Tolerance3D, double& UTolerance) const; 0531 0532 Standard_EXPORT occ::handle<Law_BSpline> Copy() const; 0533 0534 DEFINE_STANDARD_RTTIEXT(Law_BSpline, Standard_Transient) 0535 0536 private: 0537 //! Tells whether the Cache is valid for the 0538 //! given parameter 0539 //! Warnings : the parameter must be normalized within 0540 //! the period if the curve is periodic. Otherwise 0541 //! the answer will be false 0542 Standard_EXPORT bool IsCacheValid(const double Parameter) const; 0543 0544 //! Recompute the flatknots, the knotsdistribution, the 0545 //! continuity. 0546 Standard_EXPORT void UpdateKnots(); 0547 0548 bool rational; 0549 bool periodic; 0550 GeomAbs_BSplKnotDistribution knotSet; 0551 GeomAbs_Shape smooth; 0552 int deg; 0553 occ::handle<NCollection_HArray1<double>> poles; 0554 occ::handle<NCollection_HArray1<double>> weights; 0555 occ::handle<NCollection_HArray1<double>> flatknots; 0556 occ::handle<NCollection_HArray1<double>> knots; 0557 occ::handle<NCollection_HArray1<int>> mults; 0558 }; 0559 0560 #endif // _Law_BSpline_HeaderFile
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|