diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CircleToBSplineCurve.cxx b/src/FoundationClasses/TKMath/Convert/Convert_CircleToBSplineCurve.cxx index e96ddb838c..c62dff489e 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CircleToBSplineCurve.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CircleToBSplineCurve.cxx @@ -24,7 +24,6 @@ #include #include #include -#include // Attention : // To avoid use of persistent tables in the fields @@ -53,41 +52,38 @@ Convert_CircleToBSplineCurve::Convert_CircleToBSplineCurve( int ii; - double R, value; - occ::handle> CosNumeratorPtr, SinNumeratorPtr; + double R, value; + NCollection_Array1 CosNumerator, SinNumerator; R = C.Radius(); if (Parameterisation != Convert_TgtThetaOver2 && Parameterisation != Convert_RationalC1) { // In case if BuildCosAndSin does not know how to manage the periodicity // => trim on 0,2*PI - isperiodic = false; + myIsPeriodic = false; Convert_ConicToBSplineCurve::BuildCosAndSin(Parameterisation, 0, 2 * M_PI, - CosNumeratorPtr, - SinNumeratorPtr, - weights, - degree, - knots, - mults); + CosNumerator, + SinNumerator, + myWeights, + myDegree, + myKnots, + myMults); } else { - isperiodic = true; + myIsPeriodic = true; Convert_ConicToBSplineCurve::BuildCosAndSin(Parameterisation, - CosNumeratorPtr, - SinNumeratorPtr, - weights, - degree, - knots, - mults); + CosNumerator, + SinNumerator, + myWeights, + myDegree, + myKnots, + myMults); } - nbPoles = CosNumeratorPtr->Length(); - nbKnots = knots->Length(); - - poles = new NCollection_HArray1(1, nbPoles); + myPoles = NCollection_Array1(1, CosNumerator.Length()); gp_Dir2d Ox = C.XAxis().Direction(); gp_Dir2d Oy = C.YAxis().Direction(); @@ -105,11 +101,11 @@ Convert_CircleToBSplineCurve::Convert_CircleToBSplineCurve( // Replace the bspline in the reference of the circle. // and calculate the weight of the bspline. - for (ii = 1; ii <= nbPoles; ii++) + for (ii = 1; ii <= myPoles.Length(); ii++) { - poles->ChangeArray1()(ii).SetCoord(1, R * CosNumeratorPtr->Value(ii)); - poles->ChangeArray1()(ii).SetCoord(2, value * SinNumeratorPtr->Value(ii)); - poles->ChangeArray1()(ii).Transform(Trsf); + myPoles(ii).SetCoord(1, R * CosNumerator(ii)); + myPoles(ii).SetCoord(2, value * SinNumerator(ii)); + myPoles(ii).Transform(Trsf); } } @@ -133,26 +129,23 @@ Convert_CircleToBSplineCurve::Convert_CircleToBSplineCurve( throw Standard_DomainError("Convert_CircleToBSplineCurve"); } - int ii; - double R, value; - occ::handle> CosNumeratorPtr, SinNumeratorPtr; + int ii; + double R, value; + NCollection_Array1 CosNumerator, SinNumerator; - R = C.Radius(); - isperiodic = false; + R = C.Radius(); + myIsPeriodic = false; Convert_ConicToBSplineCurve::BuildCosAndSin(Parameterisation, UFirst, ULast, - CosNumeratorPtr, - SinNumeratorPtr, - weights, - degree, - knots, - mults); + CosNumerator, + SinNumerator, + myWeights, + myDegree, + myKnots, + myMults); - nbPoles = CosNumeratorPtr->Length(); - nbKnots = knots->Length(); - - poles = new NCollection_HArray1(1, nbPoles); + myPoles = NCollection_Array1(1, CosNumerator.Length()); gp_Dir2d Ox = C.XAxis().Direction(); gp_Dir2d Oy = C.YAxis().Direction(); @@ -170,10 +163,10 @@ Convert_CircleToBSplineCurve::Convert_CircleToBSplineCurve( // Replace the bspline in the reference of the circle. // and calculate the weight of the bspline. - for (ii = 1; ii <= nbPoles; ii++) + for (ii = 1; ii <= myPoles.Length(); ii++) { - poles->ChangeArray1()(ii).SetCoord(1, R * CosNumeratorPtr->Value(ii)); - poles->ChangeArray1()(ii).SetCoord(2, value * SinNumeratorPtr->Value(ii)); - poles->ChangeArray1()(ii).Transform(Trsf); + myPoles(ii).SetCoord(1, R * CosNumerator(ii)); + myPoles(ii).SetCoord(2, value * SinNumerator(ii)); + myPoles(ii).Transform(Trsf); } } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurves2dToBSplineCurve2d.cxx b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurves2dToBSplineCurve2d.cxx index bdd1ce9968..0896b95cfc 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurves2dToBSplineCurve2d.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurves2dToBSplineCurve2d.cxx @@ -14,203 +14,12 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include #include -#include -#include -#include -#include -#include -#include -//================================================================================================= +//================================================================================================== Convert_CompBezierCurves2dToBSplineCurve2d::Convert_CompBezierCurves2dToBSplineCurve2d( - const double AngularTolerance) - : myDegree(0), - myAngular(AngularTolerance), - myDone(false) + const double theAngularTolerance) + : Convert_CompBezierCurvesToBSplineCurveBase(theAngularTolerance) { } - -//================================================================================================= - -void Convert_CompBezierCurves2dToBSplineCurve2d::AddCurve(const NCollection_Array1& Poles) -{ - if (!mySequence.IsEmpty()) - { - gp_Pnt2d P1, P2; - P1 = mySequence.Last()->Value(mySequence.Last()->Upper()); - P2 = Poles(Poles.Lower()); - - // User defined tolerance NYI - // Standard_ConstructionError_Raise_if - // ( !P1.IsEqual(P2,Precision::Confusion()), - // "Convert_CompBezierCurves2dToBSplineCurve2d::Addcurve"); - } - myDone = false; - occ::handle> HPoles = - new NCollection_HArray1(Poles.Lower(), Poles.Upper()); - HPoles->ChangeArray1() = Poles; - mySequence.Append(HPoles); -} - -//================================================================================================= - -int Convert_CompBezierCurves2dToBSplineCurve2d::Degree() const -{ - return myDegree; -} - -//================================================================================================= - -int Convert_CompBezierCurves2dToBSplineCurve2d::NbPoles() const -{ - return CurvePoles.Length(); -} - -//================================================================================================= - -void Convert_CompBezierCurves2dToBSplineCurve2d::Poles(NCollection_Array1& Poles) const -{ - int i, Lower = Poles.Lower(), Upper = Poles.Upper(); - int k = 1; - for (i = Lower; i <= Upper; i++) - { - Poles(i) = CurvePoles(k++); - } -} - -//================================================================================================= - -int Convert_CompBezierCurves2dToBSplineCurve2d::NbKnots() const -{ - return CurveKnots.Length(); -} - -//================================================================================================= - -void Convert_CompBezierCurves2dToBSplineCurve2d::KnotsAndMults(NCollection_Array1& Knots, - NCollection_Array1& Mults) const -{ - int i, LowerK = Knots.Lower(), UpperK = Knots.Upper(); - int LowerM = Mults.Lower(), UpperM = Mults.Upper(); - int k = 1; - for (i = LowerK; i <= UpperK; i++) - { - Knots(i) = CurveKnots(k++); - } - k = 1; - for (i = LowerM; i <= UpperM; i++) - { - Mults(i) = KnotsMultiplicities(k++); - } -} - -//================================================================================================= - -void Convert_CompBezierCurves2dToBSplineCurve2d::Perform() -{ - myDone = true; - CurvePoles.Clear(); - CurveKnots.Clear(); - KnotsMultiplicities.Clear(); - int LowerI = 1; - int UpperI = mySequence.Length(); - int NbrCurv = UpperI - LowerI + 1; - // int NbKnotsSpl = NbrCurv + 1 ; - NCollection_Array1 CurveKnVals(1, NbrCurv); - - int i; - myDegree = 0; - for (i = 1; i <= mySequence.Length(); i++) - { - myDegree = std::max(myDegree, (mySequence(i))->Length() - 1); - } - - double Det = 0; - gp_Pnt2d P1, P2, P3; - int Deg, Inc, MaxDegree = myDegree; - NCollection_Array1 Points(1, myDegree + 1); - - for (i = LowerI; i <= UpperI; i++) - { - // 1- Rise Bezier curve to the maximum degree. - Deg = mySequence(i)->Length() - 1; - Inc = myDegree - Deg; - if (Inc > 0) - { - BSplCLib::IncreaseDegree(myDegree, - mySequence(i)->Array1(), - BSplCLib::NoWeights(), - Points, - BSplCLib::NoWeights()); - } - else - { - Points = mySequence(i)->Array1(); - } - - // 2- Process the node of junction between Bezier curves. - if (i == LowerI) - { - // Processing of initial node of the BSpline. - for (int j = 1; j <= MaxDegree; j++) - { - CurvePoles.Append(Points(j)); - } - CurveKnVals(1) = 1.; // To begin the series. - KnotsMultiplicities.Append(MaxDegree + 1); - Det = 1.; - } - - if (i != LowerI) - { - P2 = Points(1); - P3 = Points(2); - gp_Vec2d V1(P1, P2), V2(P2, P3); - - // Processing of the tangency between the Bezier and the previous. - // This allows guaranteeing at least continuity C1 if the tangents are coherent. - // Test of angle at myAngular - double D1 = V1.SquareMagnitude(); - double D2 = V2.SquareMagnitude(); - if (MaxDegree > 1 && // rln 20.06.99 work-around - D1 > gp::Resolution() && D2 > gp::Resolution() && V1.IsParallel(V2, myAngular)) - { - double Lambda = std::sqrt(D2 / D1); - KnotsMultiplicities.Append(MaxDegree - 1); - CurveKnVals(i) = CurveKnVals(i - 1) * Lambda; - } - else - { - CurvePoles.Append(Points(1)); - KnotsMultiplicities.Append(MaxDegree); - CurveKnVals(i) = 1.0; - } - Det += CurveKnVals(i); - - // Store poles. - for (int j = 2; j <= MaxDegree; j++) - { - CurvePoles.Append(Points(j)); - } - } - - if (i == UpperI) - { - // Process end node of the BSpline. - CurvePoles.Append(Points(MaxDegree + 1)); - KnotsMultiplicities.Append(MaxDegree + 1); - } - P1 = Points(MaxDegree); - } - - // Correct nodal values to make them variable within [0.,1.]. - CurveKnots.Append(0.0); - for (i = 2; i <= NbrCurv; i++) - { - CurveKnots.Append(CurveKnots(i - 1) + (CurveKnVals(i - 1) / Det)); - } - CurveKnots.Append(1.0); -} diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurves2dToBSplineCurve2d.hxx b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurves2dToBSplineCurve2d.hxx index 5fccee21e3..88db9a0d75 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurves2dToBSplineCurve2d.hxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurves2dToBSplineCurve2d.hxx @@ -17,161 +17,26 @@ #ifndef _Convert_CompBezierCurves2dToBSplineCurve2d_HeaderFile #define _Convert_CompBezierCurves2dToBSplineCurve2d_HeaderFile -#include -#include - +#include #include -#include -#include -#include -#include +#include //! Converts a list of connecting Bezier Curves 2d to a //! BSplineCurve 2d. //! if possible, the continuity of the BSpline will be //! increased to more than C0. class Convert_CompBezierCurves2dToBSplineCurve2d + : public Convert_CompBezierCurvesToBSplineCurveBase { public: DEFINE_STANDARD_ALLOC //! Constructs a framework for converting a sequence of //! adjacent non-rational Bezier curves into a BSpline curve. - //! Knots will be created on the computed BSpline curve at - //! each junction point of two consecutive Bezier curves. The - //! degree of continuity of the BSpline curve will be increased at - //! the junction point of two consecutive Bezier curves if their - //! tangent vectors at this point are parallel. AngularTolerance - //! (given in radians, and defaulted to 1.0 e-4) will be used - //! to check the parallelism of the two tangent vectors. - //! Use the following functions: - //! - AddCurve to define in sequence the adjacent Bezier - //! curves to be converted, - //! - Perform to compute the data needed to build the BSpline curve, - //! - and the available consultation functions to access the - //! computed data. This data may be used to construct the BSpline curve. + //! @param[in] theAngularTolerance angular tolerance in radians + //! for checking tangent parallelism at junction points Standard_EXPORT Convert_CompBezierCurves2dToBSplineCurve2d( - const double AngularTolerance = 1.0e-4); - - //! Adds the Bezier curve defined by the table of poles Poles, to - //! the sequence (still contained in this framework) of adjacent - //! Bezier curves to be converted into a BSpline curve. - //! Only polynomial (i.e. non-rational) Bezier curves are - //! converted using this framework. - //! If this is not the first call to the function (i.e. if this framework - //! still contains data in its sequence of Bezier curves), the - //! degree of continuity of the BSpline curve will be increased at - //! the time of computation at the first point of the added Bezier - //! curve (i.e. the first point of the Poles table). This will be the - //! case if the tangent vector of the curve at this point is - //! parallel to the tangent vector at the end point of the - //! preceding Bezier curve in the sequence of Bezier curves still - //! contained in this framework. An angular tolerance given at - //! the time of construction of this framework, will be used to - //! check the parallelism of the two tangent vectors. This - //! checking procedure, and all the relative computations will be - //! performed by the function Perform. - //! When the sequence of adjacent Bezier curves is complete, - //! use the following functions: - //! - Perform to compute the data needed to build the BSpline curve, - //! - and the available consultation functions to access the - //! computed data. This data may be used to construct the BSpline curve. - //! Warning - //! The sequence of Bezier curves treated by this framework is - //! automatically initialized with the first Bezier curve when the - //! function is first called. During subsequent use of this function, - //! ensure that the first point of the added Bezier curve (i.e. the - //! first point of the Poles table) is coincident with the last point - //! of the sequence (i.e. the last point of the preceding Bezier - //! curve in the sequence) of Bezier curves still contained in - //! this framework. An error may occur at the time of - //! computation if this condition is not satisfied. Particular care - //! must be taken with respect to the above, as this condition is - //! not checked either when defining the sequence of Bezier - //! curves or at the time of computation. - Standard_EXPORT void AddCurve(const NCollection_Array1& Poles); - - //! Computes all the data needed to build a BSpline curve - //! equivalent to the sequence of adjacent Bezier curves still - //! contained in this framework. - //! A knot is inserted on the computed BSpline curve at the - //! junction point of two consecutive Bezier curves. The - //! degree of continuity of the BSpline curve will be increased - //! at the junction point of two consecutive Bezier curves if - //! their tangent vectors at this point are parallel. An angular - //! tolerance given at the time of construction of this - //! framework is used to check the parallelism of the two - //! tangent vectors. - //! Use the available consultation functions to access the - //! computed data. This data may then be used to construct - //! the BSpline curve. - //! Warning - //! Ensure that the curves in the sequence of Bezier curves - //! contained in this framework are adjacent. An error may - //! occur at the time of computation if this condition is not - //! satisfied. Particular care must be taken with respect to the - //! above as this condition is not checked, either when - //! defining the Bezier curve sequence or at the time of computation. - Standard_EXPORT void Perform(); - - //! Returns the degree of the BSpline curve whose data is - //! computed in this framework. - //! Warning - //! Take particular care not to use this function before the - //! computation is performed (Perform function), as this - //! condition is not checked and an error may therefore occur. - Standard_EXPORT int Degree() const; - - //! Returns the number of poles of the BSpline curve whose - //! data is computed in this framework. - //! Warning - //! Take particular care not to use this function before the - //! computation is performed (Perform function), as this - //! condition is not checked and an error may therefore occur. - Standard_EXPORT int NbPoles() const; - - //! Loads the Poles table with the poles of the BSpline curve - //! whose data is computed in this framework. - //! Warning - //! - Do not use this function before the computation is - //! performed (Perform function). - //! - The length of the Poles array must be equal to the - //! number of poles of the BSpline curve whose data is - //! computed in this framework. - //! Particular care must be taken with respect to the above, as - //! these conditions are not checked, and an error may occur. - Standard_EXPORT void Poles(NCollection_Array1& Poles) const; - - //! Returns the number of knots of the BSpline curve whose - //! data is computed in this framework. - //! Warning - //! Take particular care not to use this function before the - //! computation is performed (Perform function), as this - //! condition is not checked and an error may therefore occur. - Standard_EXPORT int NbKnots() const; - - //! Loads the Knots table with the knots - //! and the Mults table with the corresponding multiplicities - //! of the BSpline curve whose data is computed in this framework. - //! Warning - //! - Do not use this function before the computation is - //! performed (Perform function). - //! - The length of the Knots and Mults arrays must be equal - //! to the number of knots in the BSpline curve whose data is - //! computed in this framework. - //! Particular care must be taken with respect to the above as - //! these conditions are not checked, and an error may occur. - Standard_EXPORT void KnotsAndMults(NCollection_Array1& Knots, - NCollection_Array1& Mults) const; - -private: - NCollection_Sequence>> mySequence; - NCollection_Sequence CurvePoles; - NCollection_Sequence CurveKnots; - NCollection_Sequence KnotsMultiplicities; - int myDegree; - double myAngular; - bool myDone; + const double theAngularTolerance = 1.0e-4); }; #endif // _Convert_CompBezierCurves2dToBSplineCurve2d_HeaderFile diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurve.cxx b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurve.cxx index a9a0ebfe13..23a9fdb1ef 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurve.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurve.cxx @@ -14,214 +14,12 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include #include -#include -#include -#include -#include -#include -#include -//================================================================================================= +//================================================================================================== Convert_CompBezierCurvesToBSplineCurve::Convert_CompBezierCurvesToBSplineCurve( - const double AngularTolerance) - : myDegree(0), - myAngular(AngularTolerance), - myDone(false) + const double theAngularTolerance) + : Convert_CompBezierCurvesToBSplineCurveBase(theAngularTolerance) { } - -//================================================================================================= - -void Convert_CompBezierCurvesToBSplineCurve::AddCurve(const NCollection_Array1& Poles) -{ - if (!mySequence.IsEmpty()) - { - gp_Pnt P1, P2; - P1 = mySequence.Last()->Value(mySequence.Last()->Upper()); - P2 = Poles(Poles.Lower()); - -#ifdef OCCT_DEBUG - if (!P1.IsEqual(P2, Precision::Confusion())) - std::cout << "Convert_CompBezierCurvesToBSplineCurve::Addcurve" << std::endl; -#endif - } - myDone = false; - occ::handle> HPoles = - new NCollection_HArray1(Poles.Lower(), Poles.Upper()); - HPoles->ChangeArray1() = Poles; - mySequence.Append(HPoles); -} - -//================================================================================================= - -int Convert_CompBezierCurvesToBSplineCurve::Degree() const -{ - return myDegree; -} - -//================================================================================================= - -int Convert_CompBezierCurvesToBSplineCurve::NbPoles() const -{ - return CurvePoles.Length(); -} - -//================================================================================================= - -void Convert_CompBezierCurvesToBSplineCurve::Poles(NCollection_Array1& Poles) const -{ - int i, Lower = Poles.Lower(), Upper = Poles.Upper(); - int k = 1; - for (i = Lower; i <= Upper; i++) - { - Poles(i) = CurvePoles(k++); - } -} - -//================================================================================================= - -int Convert_CompBezierCurvesToBSplineCurve::NbKnots() const -{ - return CurveKnots.Length(); -} - -//================================================================================================= - -void Convert_CompBezierCurvesToBSplineCurve::KnotsAndMults(NCollection_Array1& Knots, - NCollection_Array1& Mults) const -{ - int i, LowerK = Knots.Lower(), UpperK = Knots.Upper(); - int LowerM = Mults.Lower(), UpperM = Mults.Upper(); - int k = 1; - for (i = LowerK; i <= UpperK; i++) - { - Knots(i) = CurveKnots(k++); - } - k = 1; - for (i = LowerM; i <= UpperM; i++) - { - Mults(i) = KnotsMultiplicities(k++); - } -} - -//================================================================================================= - -void Convert_CompBezierCurvesToBSplineCurve::Perform() -{ - myDone = true; - CurvePoles.Clear(); - CurveKnots.Clear(); - KnotsMultiplicities.Clear(); - int LowerI = 1; - int UpperI = mySequence.Length(); - int NbrCurv = UpperI - LowerI + 1; - // int NbKnotsSpl = NbrCurv + 1 ; - NCollection_Array1 CurveKnVals(1, NbrCurv); - - int i; - myDegree = 0; - for (i = 1; i <= mySequence.Length(); i++) - { - myDegree = std::max(myDegree, (mySequence(i))->Length() - 1); - } - - double Det = 0; - gp_Pnt P1, P2, P3; - int Deg, Inc, MaxDegree = myDegree; - NCollection_Array1 Points(1, myDegree + 1); - - for (i = LowerI; i <= UpperI; i++) - { - // 1- Raise the Bezier curve to the maximum degree. - Deg = mySequence(i)->Length() - 1; - Inc = myDegree - Deg; - if (Inc > 0) - { - BSplCLib::IncreaseDegree(myDegree, - mySequence(i)->Array1(), - BSplCLib::NoWeights(), - Points, - BSplCLib::NoWeights()); - } - else - { - Points = mySequence(i)->Array1(); - } - - // 2- Process the node of junction between 2 Bezier curves. - if (i == LowerI) - { - // Processing of the initial node of the BSpline. - for (int j = 1; j <= MaxDegree; j++) - { - CurvePoles.Append(Points(j)); - } - CurveKnVals(1) = 1.; // To begin the series. - KnotsMultiplicities.Append(MaxDegree + 1); - Det = 1.; - } - - if (i != LowerI) - { - P2 = Points(1); - P3 = Points(2); - gp_Vec V1(P1, P2), V2(P2, P3); - - // Processing of the tangency between Bezier and the previous. - // This allows to guarantee at least a C1 continuity if the tangents are - // coherent. - - double D1 = V1.SquareMagnitude(); - double D2 = V2.SquareMagnitude(); - if (MaxDegree > 1 && // rln 20.06.99 work-around - D1 > gp::Resolution() && D2 > gp::Resolution() && V1.IsParallel(V2, myAngular)) - { - double Lambda = std::sqrt(D2 / D1); - if (CurveKnVals(i - 1) * Lambda > 10. * Epsilon(Det)) - { - KnotsMultiplicities.Append(MaxDegree - 1); - CurveKnVals(i) = CurveKnVals(i - 1) * Lambda; - } - else - { - CurvePoles.Append(Points(1)); - KnotsMultiplicities.Append(MaxDegree); - CurveKnVals(i) = 1.0; - } - } - else - { - CurvePoles.Append(Points(1)); - KnotsMultiplicities.Append(MaxDegree); - CurveKnVals(i) = 1.0; - } - Det += CurveKnVals(i); - - // Store the poles. - for (int j = 2; j <= MaxDegree; j++) - { - CurvePoles.Append(Points(j)); - } - } - - if (i == UpperI) - { - // Processing of the end node of the BSpline. - CurvePoles.Append(Points(MaxDegree + 1)); - KnotsMultiplicities.Append(MaxDegree + 1); - } - P1 = Points(MaxDegree); - } - - // Correct nodal values to make them variable within [0.,1.]. - CurveKnots.Append(0.0); - // std::cout << "Convert : Det = " << Det << std::endl; - for (i = 2; i <= NbrCurv; i++) - { - CurveKnots.Append(CurveKnots(i - 1) + (CurveKnVals(i - 1) / Det)); - } - CurveKnots.Append(1.0); -} diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurve.hxx b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurve.hxx index 8565abd2ad..76dfa7b8fd 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurve.hxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurve.hxx @@ -17,14 +17,9 @@ #ifndef _Convert_CompBezierCurvesToBSplineCurve_HeaderFile #define _Convert_CompBezierCurvesToBSplineCurve_HeaderFile -#include -#include - +#include #include -#include -#include -#include -#include +#include //! An algorithm to convert a sequence of adjacent //! non-rational Bezier curves into a BSpline curve. @@ -36,146 +31,16 @@ //! Warning //! Do not attempt to convert rational Bezier curves using this type of algorithm. class Convert_CompBezierCurvesToBSplineCurve + : public Convert_CompBezierCurvesToBSplineCurveBase { public: DEFINE_STANDARD_ALLOC //! Constructs a framework for converting a sequence of //! adjacent non-rational Bezier curves into a BSpline curve. - //! Knots will be created on the computed BSpline curve at - //! each junction point of two consecutive Bezier curves. The - //! degree of continuity of the BSpline curve will be increased at - //! the junction point of two consecutive Bezier curves if their - //! tangent vectors at this point are parallel. AngularTolerance - //! (given in radians, and defaulted to 1.0 e-4) will be used - //! to check the parallelism of the two tangent vectors. - //! Use the following functions: - //! - AddCurve to define in sequence the adjacent Bezier - //! curves to be converted, - //! - Perform to compute the data needed to build the BSpline curve, - //! - and the available consultation functions to access the - //! computed data. This data may be used to construct the BSpline curve. - Standard_EXPORT Convert_CompBezierCurvesToBSplineCurve(const double AngularTolerance = 1.0e-4); - - //! Adds the Bezier curve defined by the table of poles Poles, to - //! the sequence (still contained in this framework) of adjacent - //! Bezier curves to be converted into a BSpline curve. - //! Only polynomial (i.e. non-rational) Bezier curves are - //! converted using this framework. - //! If this is not the first call to the function (i.e. if this framework - //! still contains data in its Bezier curve sequence), the degree - //! of continuity of the BSpline curve will be increased at the - //! time of computation at the first point of the added Bezier - //! curve (i.e. the first point of the Poles table). This will be the - //! case if the tangent vector of the curve at this point is - //! parallel to the tangent vector at the end point of the - //! preceding Bezier curve in the Bezier curve sequence still - //! contained in this framework. An angular tolerance given at - //! the time of construction of this framework will be used to - //! check the parallelism of the two tangent vectors. This - //! checking procedure and all related computations will be - //! performed by the Perform function. - //! When the adjacent Bezier curve sequence is complete, use - //! the following functions: - //! - Perform to compute the data needed to build the BSpline curve, - //! - and the available consultation functions to access the - //! computed data. This data may be used to construct the BSpline curve. - //! Warning - //! The Bezier curve sequence treated by this framework is - //! automatically initialized with the first Bezier curve when the - //! function is first called. During subsequent use of this function, - //! ensure that the first point of the added Bezier curve (i.e. the - //! first point of the Poles table) is coincident with the last point - //! of the Bezier curve sequence (i.e. the last point of the - //! preceding Bezier curve in the sequence) still contained in - //! this framework. An error may occur at the time of - //! computation if this condition is not satisfied. Particular care - //! must be taken with respect to the above, as this condition is - //! not checked either when defining the Bezier curve - //! sequence or at the time of computation. - Standard_EXPORT void AddCurve(const NCollection_Array1& Poles); - - //! Computes all the data needed to build a BSpline curve - //! equivalent to the adjacent Bezier curve sequence still - //! contained in this framework. - //! A knot is inserted on the computed BSpline curve at the - //! junction point of two consecutive Bezier curves. The - //! degree of continuity of the BSpline curve will be increased - //! at the junction point of two consecutive Bezier curves if - //! their tangent vectors at this point are parallel. An angular - //! tolerance given at the time of construction of this - //! framework is used to check the parallelism of the two - //! tangent vectors. - //! Use the available consultation functions to access the - //! computed data. This data may then be used to construct - //! the BSpline curve. - //! Warning - //! Make sure that the curves in the Bezier curve sequence - //! contained in this framework are adjacent. An error may - //! occur at the time of computation if this condition is not - //! satisfied. Particular care must be taken with respect to the - //! above as this condition is not checked, either when - //! defining the Bezier curve sequence or at the time of computation. - Standard_EXPORT void Perform(); - - //! Returns the degree of the BSpline curve whose data is - //! computed in this framework. - //! Warning - //! Take particular care not to use this function before the - //! computation is performed (Perform function), as this - //! condition is not checked and an error may therefore occur. - Standard_EXPORT int Degree() const; - - //! Returns the number of poles of the BSpline curve whose - //! data is computed in this framework. - //! Warning - //! Take particular care not to use this function before the - //! computation is performed (Perform function), as this - //! condition is not checked and an error may therefore occur. - Standard_EXPORT int NbPoles() const; - - //! Loads the Poles table with the poles of the BSpline curve - //! whose data is computed in this framework. - //! Warning - //! - Do not use this function before the computation is - //! performed (Perform function). - //! - The length of the Poles array must be equal to the - //! number of poles of the BSpline curve whose data is - //! computed in this framework. - //! Particular care must be taken with respect to the above, as - //! these conditions are not checked, and an error may occur. - Standard_EXPORT void Poles(NCollection_Array1& Poles) const; - - //! Returns the number of knots of the BSpline curve whose - //! data is computed in this framework. - //! Warning - //! Take particular care not to use this function before the - //! computation is performed (Perform function), as this - //! condition is not checked and an error may therefore occur. - Standard_EXPORT int NbKnots() const; - - //! - loads the Knots table with the knots, - //! - and loads the Mults table with the corresponding multiplicities - //! of the BSpline curve whose data is computed in this framework. - //! Warning - //! - Do not use this function before the computation is - //! performed (Perform function). - //! - The length of the Knots and Mults arrays must be equal - //! to the number of knots in the BSpline curve whose data is - //! computed in this framework. - //! Particular care must be taken with respect to the above as - //! these conditions are not checked, and an error may occur. - Standard_EXPORT void KnotsAndMults(NCollection_Array1& Knots, - NCollection_Array1& Mults) const; - -private: - NCollection_Sequence>> mySequence; - NCollection_Sequence CurvePoles; - NCollection_Sequence CurveKnots; - NCollection_Sequence KnotsMultiplicities; - int myDegree; - double myAngular; - bool myDone; + //! @param[in] theAngularTolerance angular tolerance in radians + //! for checking tangent parallelism at junction points + Standard_EXPORT Convert_CompBezierCurvesToBSplineCurve(const double theAngularTolerance = 1.0e-4); }; #endif // _Convert_CompBezierCurvesToBSplineCurve_HeaderFile diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurveBase.hxx b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurveBase.hxx new file mode 100644 index 0000000000..bf8e090171 --- /dev/null +++ b/src/FoundationClasses/TKMath/Convert/Convert_CompBezierCurvesToBSplineCurveBase.hxx @@ -0,0 +1,222 @@ +// Copyright (c) 2025 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Convert_CompBezierCurvesToBSplineCurveBase_HeaderFile +#define _Convert_CompBezierCurvesToBSplineCurveBase_HeaderFile + +#include +#include +#include +#include +#include + +class gp_Pnt; +class gp_Pnt2d; + +//! Template base class for converting a sequence of adjacent +//! non-rational Bezier curves into a BSpline curve. +//! PointType is gp_Pnt or gp_Pnt2d; VecType is gp_Vec or gp_Vec2d. +template +class Convert_CompBezierCurvesToBSplineCurveBase +{ +public: + //! Constructs a framework for converting a sequence of + //! adjacent non-rational Bezier curves into a BSpline curve. + //! @param[in] theAngularTolerance angular tolerance in radians + //! for checking tangent parallelism at junction points + explicit Convert_CompBezierCurvesToBSplineCurveBase(const double theAngularTolerance = 1.0e-4) + : myDegree(0), + myAngular(theAngularTolerance) + { + } + + //! Adds the Bezier curve defined by the table of poles to + //! the sequence of adjacent Bezier curves to be converted. + //! @param[in] thePoles poles of the Bezier curve to add + void AddCurve(const NCollection_Array1& thePoles) { mySequence.Append(thePoles); } + + //! Computes all the data needed to build a BSpline curve + //! equivalent to the adjacent Bezier curve sequence. + void Perform() + { + myCurvePoles.Clear(); + myCurveKnots.Clear(); + myKnotsMults.Clear(); + if (mySequence.IsEmpty()) + { + return; + } + const int aLowerI = 1; + const int anUpperI = mySequence.Length(); + const int aNbrCurv = anUpperI - aLowerI + 1; + NCollection_Array1 aCurveKnVals(1, aNbrCurv); + + myDegree = 0; + for (int i = 1; i <= mySequence.Length(); i++) + { + myDegree = std::max(myDegree, mySequence(i).Length() - 1); + } + + double aDet = 0; + PointType aP1, aP2, aP3; + const int aMaxDegree = myDegree; + NCollection_Array1 aPoints(1, myDegree + 1); + + for (int i = aLowerI; i <= anUpperI; i++) + { + // 1- Raise the Bezier curve to the maximum degree. + const int aDeg = mySequence(i).Length() - 1; + const int anInc = myDegree - aDeg; + if (anInc > 0) + { + BSplCLib::IncreaseDegree(myDegree, + mySequence(i), + BSplCLib::NoWeights(), + aPoints, + BSplCLib::NoWeights()); + } + else + { + aPoints = mySequence(i); + } + + // 2- Process the node of junction between 2 Bezier curves. + if (i == aLowerI) + { + // Processing of the initial node of the BSpline. + for (int j = 1; j <= aMaxDegree; j++) + { + myCurvePoles.Append(aPoints(j)); + } + aCurveKnVals(1) = 1.; // To begin the series. + myKnotsMults.Append(aMaxDegree + 1); + aDet = 1.; + } + + if (i != aLowerI) + { + aP2 = aPoints(1); + aP3 = aPoints(2); + VecType aV1(aP1, aP2), aV2(aP2, aP3); + + // Processing of the tangency between Bezier and the previous. + // This allows to guarantee at least a C1 continuity if the tangents are coherent. + const double aD1 = aV1.SquareMagnitude(); + const double aD2 = aV2.SquareMagnitude(); + if (aMaxDegree > 1 && aD1 > gp::Resolution() && aD2 > gp::Resolution() + && aV1.IsParallel(aV2, myAngular)) + { + const double aLambda = std::sqrt(aD2 / aD1); + if constexpr (std::is_same_v) + { + // 3D-specific epsilon guard to avoid numerical issues + // when accumulated knot values become too small relative to Det. + if (aCurveKnVals(i - 1) * aLambda > 10. * Epsilon(aDet)) + { + myKnotsMults.Append(aMaxDegree - 1); + aCurveKnVals(i) = aCurveKnVals(i - 1) * aLambda; + } + else + { + myCurvePoles.Append(aPoints(1)); + myKnotsMults.Append(aMaxDegree); + aCurveKnVals(i) = 1.0; + } + } + else + { + myKnotsMults.Append(aMaxDegree - 1); + aCurveKnVals(i) = aCurveKnVals(i - 1) * aLambda; + } + } + else + { + myCurvePoles.Append(aPoints(1)); + myKnotsMults.Append(aMaxDegree); + aCurveKnVals(i) = 1.0; + } + aDet += aCurveKnVals(i); + + // Store the poles. + for (int j = 2; j <= aMaxDegree; j++) + { + myCurvePoles.Append(aPoints(j)); + } + } + + if (i == anUpperI) + { + // Processing of the end node of the BSpline. + myCurvePoles.Append(aPoints(aMaxDegree + 1)); + myKnotsMults.Append(aMaxDegree + 1); + } + aP1 = aPoints(aMaxDegree); + } + + // Correct nodal values to make them variable within [0.,1.]. + myCurveKnots.Append(0.0); + for (int i = 2; i <= aNbrCurv; i++) + { + myCurveKnots.Append(myCurveKnots(i - 1) + (aCurveKnVals(i - 1) / aDet)); + } + myCurveKnots.Append(1.0); + } + + //! Returns the degree of the BSpline curve. + [[nodiscard]] int Degree() const { return myDegree; } + + //! Returns the number of poles of the BSpline curve. + [[nodiscard]] int NbPoles() const { return myCurvePoles.Length(); } + + //! Loads the Poles table with the poles of the BSpline curve. + //! @param[out] thePoles array to fill with poles + void Poles(NCollection_Array1& thePoles) const + { + int k = 1; + for (int i = thePoles.Lower(); i <= thePoles.Upper(); i++) + { + thePoles(i) = myCurvePoles(k++); + } + } + + //! Returns the number of knots of the BSpline curve. + [[nodiscard]] int NbKnots() const { return myCurveKnots.Length(); } + + //! Loads the Knots and Mults tables with the knots + //! and corresponding multiplicities of the BSpline curve. + //! @param[out] theKnots array to fill with knots + //! @param[out] theMults array to fill with multiplicities + void KnotsAndMults(NCollection_Array1& theKnots, NCollection_Array1& theMults) const + { + int k = 1; + for (int i = theKnots.Lower(); i <= theKnots.Upper(); i++) + { + theKnots(i) = myCurveKnots(k++); + } + k = 1; + for (int i = theMults.Lower(); i <= theMults.Upper(); i++) + { + theMults(i) = myKnotsMults(k++); + } + } + +private: + NCollection_Sequence> mySequence; + NCollection_Sequence myCurvePoles; + NCollection_Sequence myCurveKnots; + NCollection_Sequence myKnotsMults; + int myDegree; + double myAngular; +}; + +#endif // _Convert_CompBezierCurvesToBSplineCurveBase_HeaderFile diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CompPolynomialToPoles.cxx b/src/FoundationClasses/TKMath/Convert/Convert_CompPolynomialToPoles.cxx index 7469653464..57842c0885 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CompPolynomialToPoles.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CompPolynomialToPoles.cxx @@ -22,17 +22,16 @@ // 15-04-97 : PMN : Constructeurs avec un seul segement ou differentes // continuitees. -#define No_Standard_OutOfRange - #include #include -#include -#include -#include #include #include +#include +#include +#include +#include -//================================================================================================= +//================================================================================================== Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles( const int NumCurves, @@ -43,19 +42,18 @@ Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles( const occ::handle>& Coefficients, const occ::handle>& PolynomialIntervals, const occ::handle>& TrueIntervals) - : myDone(false) + : myDegree(0), + myDone(false) { - int ii, delta; if (NumCurves <= 0 || NumCoeffPerCurve.IsNull() || Coefficients.IsNull() || PolynomialIntervals.IsNull() || TrueIntervals.IsNull() || Continuity < 0 || MaxDegree <= 0 || Dimension <= 0 || PolynomialIntervals->RowLength() != 2) { throw Standard_ConstructionError("Convert_CompPolynomialToPoles:bad arguments"); } - myDegree = 0; - delta = NumCurves - 1; - for (ii = NumCoeffPerCurve->Lower(); ii <= NumCoeffPerCurve->Lower() + delta; ii++) + const int aDelta = NumCurves - 1; + for (int ii = NumCoeffPerCurve->Lower(); ii <= NumCoeffPerCurve->Lower() + aDelta; ii++) { myDegree = std::max(NumCoeffPerCurve->Value(ii) - 1, myDegree); } @@ -63,25 +61,21 @@ Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles( { throw Standard_ConstructionError("Convert_CompPolynomialToPoles:Continuity is too great"); } - // - // prepare output - // - int Tindex, multiplicities; - myKnots = new NCollection_HArray1(1, NumCurves + 1); - for (ii = 1, Tindex = TrueIntervals->Lower(); ii <= NumCurves + 1; ii++, Tindex++) + myKnots = NCollection_Array1(1, NumCurves + 1); + for (int ii = 1, Tindex = TrueIntervals->Lower(); ii <= NumCurves + 1; ii++, Tindex++) { - myKnots->ChangeArray1().SetValue(ii, TrueIntervals->Value(Tindex)); + myKnots.SetValue(ii, TrueIntervals->Value(Tindex)); } - multiplicities = myDegree - Continuity; - myMults = new NCollection_HArray1(1, NumCurves + 1); - for (ii = 2; ii < NumCurves + 1; ii++) + const int aMultiplicities = myDegree - Continuity; + myMults = NCollection_Array1(1, NumCurves + 1); + for (int ii = 2; ii < NumCurves + 1; ii++) { - myMults->SetValue(ii, multiplicities); + myMults.SetValue(ii, aMultiplicities); } - myMults->SetValue(1, myDegree + 1); - myMults->SetValue(NumCurves + 1, myDegree + 1); + myMults.SetValue(1, myDegree + 1); + myMults.SetValue(NumCurves + 1, myDegree + 1); Perform(NumCurves, MaxDegree, @@ -101,45 +95,39 @@ Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles( const NCollection_Array1& Coefficients, const NCollection_Array2& PolynomialIntervals, const NCollection_Array1& TrueIntervals) - : myDone(false) + : myDegree(0), + myDone(false) { - int ii, delta; if (NumCurves <= 0 || MaxDegree <= 0 || Dimension <= 0 || PolynomialIntervals.RowLength() != 2) { throw Standard_ConstructionError("Convert_CompPolynomialToPoles:bad arguments"); } - myDegree = 0; - delta = NumCurves - 1; - for (ii = NumCoeffPerCurve.Lower(); ii <= NumCoeffPerCurve.Lower() + delta; ii++) + const int aDelta = NumCurves - 1; + for (int ii = NumCoeffPerCurve.Lower(); ii <= NumCoeffPerCurve.Lower() + aDelta; ii++) { myDegree = std::max(NumCoeffPerCurve.Value(ii) - 1, myDegree); } - // - // prepare output - // - int Tindex; - myKnots = new NCollection_HArray1(1, NumCurves + 1); - for (ii = 1, Tindex = TrueIntervals.Lower(); ii <= NumCurves + 1; ii++, Tindex++) + myKnots = NCollection_Array1(1, NumCurves + 1); + for (int ii = 1, Tindex = TrueIntervals.Lower(); ii <= NumCurves + 1; ii++, Tindex++) { - myKnots->ChangeArray1().SetValue(ii, TrueIntervals.Value(Tindex)); + myKnots.SetValue(ii, TrueIntervals.Value(Tindex)); } - myMults = new NCollection_HArray1(1, NumCurves + 1); - for (ii = 2; ii < NumCurves + 1; ii++) + myMults = NCollection_Array1(1, NumCurves + 1); + for (int ii = 2; ii < NumCurves + 1; ii++) { if ((Continuity(ii) > myDegree) && (NumCurves > 1)) { throw Standard_ConstructionError("Convert_CompPolynomialToPoles:Continuity is too great"); } - myMults->SetValue(ii, myDegree - Continuity(ii)); + myMults.SetValue(ii, myDegree - Continuity(ii)); } - myMults->SetValue(1, myDegree + 1); - myMults->SetValue(NumCurves + 1, myDegree + 1); + myMults.SetValue(1, myDegree + 1); + myMults.SetValue(NumCurves + 1, myDegree + 1); - // Calculs Perform(NumCurves, MaxDegree, Dimension, @@ -158,7 +146,6 @@ Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles( const NCollection_Array1& TrueIntervals) : myDegree(Degree), myDone(false) - { if (MaxDegree <= 0 || Dimension <= 0 || PolynomialIntervals.Length() != 2) { @@ -172,14 +159,13 @@ Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles( NCollection_Array1 NumCoeffPerCurve(1, 1); NumCoeffPerCurve(1) = Degree + 1; - myKnots = new NCollection_HArray1(1, 2); - myKnots->ChangeArray1().SetValue(1, TrueIntervals.Value(TrueIntervals.Lower())); - myKnots->ChangeArray1().SetValue(2, TrueIntervals.Value(TrueIntervals.Lower() + 1)); + myKnots = NCollection_Array1(1, 2); + myKnots.SetValue(1, TrueIntervals.Value(TrueIntervals.Lower())); + myKnots.SetValue(2, TrueIntervals.Value(TrueIntervals.Lower() + 1)); - myMults = new NCollection_HArray1(1, 2); - myMults->Init(myDegree + 1); + myMults = NCollection_Array1(1, 2); + myMults.Init(myDegree + 1); - // Calculs Perform(1, MaxDegree, Dimension, @@ -202,26 +188,22 @@ void Convert_CompPolynomialToPoles::Perform(const int Nu double normalized_value, *coefficient_array, *poles_array; num_flat_knots = 2 * myDegree + 2; - for (ii = 2; ii < myMults->Length(); ii++) + for (ii = 2; ii < myMults.Length(); ii++) { - num_flat_knots += myMults->Value(ii); + num_flat_knots += myMults.Value(ii); } num_poles = num_flat_knots - myDegree - 1; - myFlatKnots = new NCollection_HArray1(1, num_flat_knots); - BSplCLib::KnotSequence(myKnots->Array1(), - myMults->Array1(), - myDegree, - false, - myFlatKnots->ChangeArray1()); + myFlatKnots = NCollection_Array1(1, num_flat_knots); + BSplCLib::KnotSequence(myKnots, myMults, myDegree, false, myFlatKnots); NCollection_Array1 parameters(1, num_poles); - BSplCLib::BuildSchoenbergPoints(myDegree, myFlatKnots->Array1(), parameters); - myPoles = new NCollection_HArray2(1, num_poles, 1, Dimension); + BSplCLib::BuildSchoenbergPoints(myDegree, myFlatKnots, parameters); + myPoles = NCollection_Array2(1, num_poles, 1, Dimension); index = 2; Tindex = TrueIntervals.Lower() + 1; Pindex = PolynomialIntervals.LowerRow(); - poles_array = (double*)&(myPoles->ChangeArray2()).Value(1, 1); + poles_array = (double*)&myPoles.ChangeValue(1, 1); NCollection_Array1 contact_array(1, num_poles); @@ -262,7 +244,7 @@ void Convert_CompPolynomialToPoles::Perform(const int Nu // result // BSplCLib::Interpolate(myDegree, - myFlatKnots->Array1(), + myFlatKnots, parameters, contact_array, Dimension, @@ -275,68 +257,94 @@ void Convert_CompPolynomialToPoles::Perform(const int Nu myDone = true; } -//================================================================================================= +//================================================================================================== int Convert_CompPolynomialToPoles::NbPoles() const { if (myDone) { - return myPoles->ColLength(); + return myPoles.ColLength(); } - else - return 0; + return 0; } -//================================================================================================= +//================================================================================================== -void Convert_CompPolynomialToPoles::Poles(occ::handle>& P) const +const NCollection_Array2& Convert_CompPolynomialToPoles::Poles() const +{ + StdFail_NotDone_Raise_if(!myDone, "Convert_CompPolynomialToPoles::Poles"); + return myPoles; +} + +//================================================================================================== + +Standard_DISABLE_DEPRECATION_WARNINGS void Convert_CompPolynomialToPoles::Poles( + occ::handle>& P) const { if (myDone) { - P = myPoles; + P = new NCollection_HArray2(myPoles); } } -//================================================================================================= +//================================================================================================== int Convert_CompPolynomialToPoles::NbKnots() const { if (myDone) { - return myKnots->Length(); + return myKnots.Length(); } - else - return 0; + return 0; } -//================================================================================================= +//================================================================================================== + +const NCollection_Array1& Convert_CompPolynomialToPoles::Knots() const +{ + StdFail_NotDone_Raise_if(!myDone, "Convert_CompPolynomialToPoles::Knots"); + return myKnots; +} + +//================================================================================================== void Convert_CompPolynomialToPoles::Knots(occ::handle>& K) const { if (myDone) { - K = myKnots; + K = new NCollection_HArray1(myKnots); } } -//================================================================================================= +//================================================================================================== + +const NCollection_Array1& Convert_CompPolynomialToPoles::Multiplicities() const +{ + StdFail_NotDone_Raise_if(!myDone, "Convert_CompPolynomialToPoles::Multiplicities"); + return myMults; +} + +//================================================================================================== void Convert_CompPolynomialToPoles::Multiplicities(occ::handle>& M) const { if (myDone) { - M = myMults; + M = new NCollection_HArray1(myMults); } } -//================================================================================================= +Standard_ENABLE_DEPRECATION_WARNINGS -bool Convert_CompPolynomialToPoles::IsDone() const + //================================================================================================== + + bool + Convert_CompPolynomialToPoles::IsDone() const { return myDone; } -//================================================================================================= +//================================================================================================== int Convert_CompPolynomialToPoles::Degree() const { diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CompPolynomialToPoles.hxx b/src/FoundationClasses/TKMath/Convert/Convert_CompPolynomialToPoles.hxx index 6d5b84b191..5e4a56da76 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CompPolynomialToPoles.hxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CompPolynomialToPoles.hxx @@ -20,10 +20,10 @@ #include #include #include +#include #include #include -#include #include #include @@ -109,26 +109,40 @@ public: const NCollection_Array1& PolynomialIntervals, const NCollection_Array1& TrueIntervals); - //! number of poles of the n-dimensional BSpline - Standard_EXPORT int NbPoles() const; + //! Returns the number of poles of the n-dimensional BSpline. + [[nodiscard]] Standard_EXPORT int NbPoles() const; - //! returns the poles of the n-dimensional BSpline - //! in the following format : + //! Returns the poles of the n-dimensional BSpline + //! in the following format: //! [1..NumPoles][1..Dimension] - Standard_EXPORT void Poles(occ::handle>& Poles) const; + [[nodiscard]] Standard_EXPORT const NCollection_Array2& Poles() const; - Standard_EXPORT int Degree() const; + //! Returns the poles of the n-dimensional BSpline via output parameter. + Standard_DEPRECATED("Use Poles() returning const reference instead") + Standard_EXPORT void Poles(occ::handle>& thePoles) const; - //! Degree of the n-dimensional Bspline - Standard_EXPORT int NbKnots() const; + //! Returns the degree of the n-dimensional BSpline. + [[nodiscard]] Standard_EXPORT int Degree() const; - //! Knots of the n-dimensional Bspline - Standard_EXPORT void Knots(occ::handle>& K) const; + //! Returns the number of knots of the n-dimensional BSpline. + [[nodiscard]] Standard_EXPORT int NbKnots() const; - //! Multiplicities of the knots in the BSpline - Standard_EXPORT void Multiplicities(occ::handle>& M) const; + //! Returns the knots of the n-dimensional BSpline. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& Knots() const; - Standard_EXPORT bool IsDone() const; + //! Returns the knots of the n-dimensional BSpline via output parameter. + Standard_DEPRECATED("Use Knots() returning const reference instead") + Standard_EXPORT void Knots(occ::handle>& theKnots) const; + + //! Returns the multiplicities of the knots in the BSpline. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& Multiplicities() const; + + //! Returns the multiplicities of the knots via output parameter. + Standard_DEPRECATED("Use Multiplicities() returning const reference instead") + Standard_EXPORT void Multiplicities(occ::handle>& theMults) const; + + //! Returns true if the conversion was successful. + [[nodiscard]] Standard_EXPORT bool IsDone() const; private: Standard_EXPORT void Perform(const int NumCurves, @@ -139,12 +153,12 @@ private: const NCollection_Array2& PolynomialIntervals, const NCollection_Array1& TrueIntervals); - occ::handle> myFlatKnots; - occ::handle> myKnots; - occ::handle> myMults; - occ::handle> myPoles; - int myDegree; - bool myDone; + NCollection_Array1 myFlatKnots; + NCollection_Array1 myKnots; + NCollection_Array1 myMults; + NCollection_Array2 myPoles; + int myDegree; + bool myDone; }; #endif // _Convert_CompPolynomialToPoles_HeaderFile diff --git a/src/FoundationClasses/TKMath/Convert/Convert_ConeToBSplineSurface.cxx b/src/FoundationClasses/TKMath/Convert/Convert_ConeToBSplineSurface.cxx index 65ff1606bf..e5dfef81f3 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_ConeToBSplineSurface.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_ConeToBSplineSurface.cxx @@ -20,6 +20,8 @@ #include #include +#include + namespace { constexpr int TheUDegree = 2; @@ -46,8 +48,8 @@ static void ComputePoles(const double R, int nbUSpans = (int)std::trunc(1.2 * deltaU / M_PI) + 1; double AlfaU = deltaU / (nbUSpans * 2); - double x[TheNbVPoles]; - double z[TheNbVPoles]; + std::array x; + std::array z; x[0] = R + V1 * std::sin(A); z[0] = V1 * std::cos(A); @@ -93,8 +95,8 @@ Convert_ConeToBSplineSurface::Convert_ConeToBSplineSurface(const gp_Cone& C, || (deltaU < 0.), "Convert_ConeToBSplineSurface"); - isuperiodic = false; - isvperiodic = false; + myIsUPeriodic = false; + myIsVPeriodic = false; int i, j; // construction of cone in the reference mark xOy. @@ -103,28 +105,28 @@ Convert_ConeToBSplineSurface::Convert_ConeToBSplineSurface(const gp_Cone& C, int nbUSpans = (int)std::trunc(1.2 * deltaU / M_PI) + 1; double AlfaU = deltaU / (nbUSpans * 2); - nbUPoles = 2 * nbUSpans + 1; - nbUKnots = nbUSpans + 1; + myNbUPoles = 2 * nbUSpans + 1; + myNbUKnots = nbUSpans + 1; - nbVPoles = 2; - nbVKnots = 2; + myNbVPoles = 2; + myNbVKnots = 2; double R = C.RefRadius(); double A = C.SemiAngle(); - ComputePoles(R, A, U1, U2, V1, V2, poles); + ComputePoles(R, A, U1, U2, V1, V2, myPoles); - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = U1 + (i - 1) * 2 * AlfaU; - umults(i) = 2; + myUKnots(i) = U1 + (i - 1) * 2 * AlfaU; + myUMults(i) = 2; } - umults(1)++; - umults(nbUKnots)++; - vknots(1) = V1; - vmults(1) = 2; - vknots(2) = V2; - vmults(2) = 2; + myUMults(1)++; + myUMults(myNbUKnots)++; + myVKnots(1) = V1; + myVMults(1) = 2; + myVKnots(2) = V2; + myVMults(2) = 2; // Replace the bspline in the mark of the sphere. // and calculate the weight of the bspline. @@ -132,19 +134,20 @@ Convert_ConeToBSplineSurface::Convert_ConeToBSplineSurface(const gp_Cone& C, gp_Trsf Trsf; Trsf.SetTransformation(C.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W1 = std::cos(AlfaU); else W1 = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { - weights(i, j) = W1; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W1; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } //================================================================================================= @@ -164,30 +167,30 @@ Convert_ConeToBSplineSurface::Convert_ConeToBSplineSurface(const gp_Cone& C, int i, j; - isuperiodic = true; - isvperiodic = false; + myIsUPeriodic = true; + myIsVPeriodic = false; // construction of the cone in the reference mark xOy. double R = C.RefRadius(); double A = C.SemiAngle(); - ComputePoles(R, A, 0., 2. * M_PI, V1, V2, poles); + ComputePoles(R, A, 0., 2. * M_PI, V1, V2, myPoles); - nbUPoles = 6; - nbUKnots = 4; - nbVPoles = 2; - nbVKnots = 2; + myNbUPoles = 6; + myNbUKnots = 4; + myNbVPoles = 2; + myNbVKnots = 2; - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = (i - 1) * 2. * M_PI / 3.; - umults(i) = 2; + myUKnots(i) = (i - 1) * 2. * M_PI / 3.; + myUMults(i) = 2; } - vknots(1) = V1; - vmults(1) = 2; - vknots(2) = V2; - vmults(2) = 2; + myVKnots(1) = V1; + myVMults(1) = 2; + myVKnots(2) = V2; + myVMults(2) = 2; // replace bspline in the mark of the cone. // and calculate the weight of bspline. @@ -195,17 +198,18 @@ Convert_ConeToBSplineSurface::Convert_ConeToBSplineSurface(const gp_Cone& C, gp_Trsf Trsf; Trsf.SetTransformation(C.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W = 0.5; // = std::cos(pi /3) else W = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { - weights(i, j) = W; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_ConicToBSplineCurve.cxx b/src/FoundationClasses/TKMath/Convert/Convert_ConicToBSplineCurve.cxx index 1956f56c58..4f76660b27 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_ConicToBSplineCurve.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_ConicToBSplineCurve.cxx @@ -14,107 +14,196 @@ // JCV 16/10/91 -#define No_Standard_OutOfRange - #include #include #include #include -#include -#include -#include -#include #include +#include #include #include +#include +#include #include +#include -//================================================================================================= - -Convert_ConicToBSplineCurve::Convert_ConicToBSplineCurve(const int NbPoles, - const int NbKnots, - const int Degree) - : degree(Degree), - nbPoles(NbPoles), - nbKnots(NbKnots), - isperiodic(false) +//================================================================================================== +Convert_ConicToBSplineCurve::Convert_ConicToBSplineCurve(const int theNumberOfPoles, + const int theNumberOfKnots, + const int theDegree) + : myDegree(theDegree) { - if (NbPoles >= 2) + if (theNumberOfPoles >= 2) { - poles = new NCollection_HArray1(1, NbPoles); - - weights = new NCollection_HArray1(1, NbPoles); + myPoles = NCollection_Array1(1, theNumberOfPoles); + myWeights = NCollection_Array1(1, theNumberOfPoles); } - if (NbKnots >= 2) + if (theNumberOfKnots >= 2) { - knots = new NCollection_HArray1(1, NbKnots); - mults = new NCollection_HArray1(1, NbKnots); + myKnots = NCollection_Array1(1, theNumberOfKnots); + myMults = NCollection_Array1(1, theNumberOfKnots); } } -//================================================================================================= +//================================================================================================== int Convert_ConicToBSplineCurve::Degree() const { - return degree; + return myDegree; } -//================================================================================================= +//================================================================================================== int Convert_ConicToBSplineCurve::NbPoles() const { - return nbPoles; + return myPoles.Length(); } -//================================================================================================= +//================================================================================================== int Convert_ConicToBSplineCurve::NbKnots() const { - return nbKnots; + return myKnots.Length(); } -//================================================================================================= +//================================================================================================== bool Convert_ConicToBSplineCurve::IsPeriodic() const { - return isperiodic; + return myIsPeriodic; } -//================================================================================================= +//================================================================================================== -gp_Pnt2d Convert_ConicToBSplineCurve::Pole(const int Index) const +Standard_DISABLE_DEPRECATION_WARNINGS gp_Pnt2d + Convert_ConicToBSplineCurve::Pole(const int theIndex) const { - if (Index < 1 || Index > nbPoles) - throw Standard_OutOfRange(" "); - return poles->Value(Index); + if (theIndex < 1 || theIndex > myPoles.Length()) + throw Standard_OutOfRange("Convert_ConicToBSplineCurve::Pole: Index out of range"); + return myPoles(theIndex); } -//================================================================================================= +//================================================================================================== -double Convert_ConicToBSplineCurve::Weight(const int Index) const +double Convert_ConicToBSplineCurve::Weight(const int theIndex) const { - if (Index < 1 || Index > nbPoles) - throw Standard_OutOfRange(" "); - return weights->Value(Index); + if (theIndex < 1 || theIndex > myPoles.Length()) + throw Standard_OutOfRange("Convert_ConicToBSplineCurve::Weight: Index out of range"); + return myWeights(theIndex); } -//================================================================================================= +//================================================================================================== -double Convert_ConicToBSplineCurve::Knot(const int Index) const +double Convert_ConicToBSplineCurve::Knot(const int theIndex) const { - if (Index < 1 || Index > nbKnots) - throw Standard_OutOfRange(" "); - return knots->Value(Index); + if (theIndex < 1 || theIndex > myKnots.Length()) + throw Standard_OutOfRange("Convert_ConicToBSplineCurve::Knot: Index out of range"); + return myKnots(theIndex); } -//================================================================================================= +//================================================================================================== -int Convert_ConicToBSplineCurve::Multiplicity(const int Index) const +int Convert_ConicToBSplineCurve::Multiplicity(const int theIndex) const { - if (Index < 1 || Index > nbKnots) - throw Standard_OutOfRange(" "); - return mults->Value(Index); + if (theIndex < 1 || theIndex > myKnots.Length()) + throw Standard_OutOfRange("Convert_ConicToBSplineCurve::Multiplicity: Index out of range"); + return myMults(theIndex); +} + +Standard_ENABLE_DEPRECATION_WARNINGS + + //================================================================================================== + + const NCollection_Array1& + Convert_ConicToBSplineCurve::Poles() const +{ + return myPoles; +} + +//================================================================================================== + +const NCollection_Array1& Convert_ConicToBSplineCurve::Weights() const +{ + return myWeights; +} + +//================================================================================================== + +const NCollection_Array1& Convert_ConicToBSplineCurve::Knots() const +{ + return myKnots; +} + +//================================================================================================== + +const NCollection_Array1& Convert_ConicToBSplineCurve::Multiplicities() const +{ + return myMults; +} + +//================================================================================================== + +void Convert_ConicToBSplineCurve::BuildCosAndSin( + const Convert_ParameterisationType theParametrisation, + occ::handle>& theCosNumerator, + occ::handle>& theSinNumerator, + occ::handle>& theDenominator, + int& theDegree, + occ::handle>& theKnots, + occ::handle>& theMults) const +{ + NCollection_Array1 aCosNumerator; + NCollection_Array1 aSinNumerator; + NCollection_Array1 aDenominator; + NCollection_Array1 aKnots; + NCollection_Array1 aMults; + BuildCosAndSin(theParametrisation, + aCosNumerator, + aSinNumerator, + aDenominator, + theDegree, + aKnots, + aMults); + theCosNumerator = new NCollection_HArray1(aCosNumerator); + theSinNumerator = new NCollection_HArray1(aSinNumerator); + theDenominator = new NCollection_HArray1(aDenominator); + theKnots = new NCollection_HArray1(aKnots); + theMults = new NCollection_HArray1(aMults); +} + +//================================================================================================== + +void Convert_ConicToBSplineCurve::BuildCosAndSin( + const Convert_ParameterisationType theParametrisation, + const double theUFirst, + const double theULast, + occ::handle>& theCosNumerator, + occ::handle>& theSinNumerator, + occ::handle>& theDenominator, + int& theDegree, + occ::handle>& theKnots, + occ::handle>& theMults) const +{ + NCollection_Array1 aCosNumerator; + NCollection_Array1 aSinNumerator; + NCollection_Array1 aDenominator; + NCollection_Array1 aKnots; + NCollection_Array1 aMults; + BuildCosAndSin(theParametrisation, + theUFirst, + theULast, + aCosNumerator, + aSinNumerator, + aDenominator, + theDegree, + aKnots, + aMults); + theCosNumerator = new NCollection_HArray1(aCosNumerator); + theSinNumerator = new NCollection_HArray1(aSinNumerator); + theDenominator = new NCollection_HArray1(aDenominator); + theKnots = new NCollection_HArray1(aKnots); + theMults = new NCollection_HArray1(aMults); } //======================================================================= @@ -126,7 +215,6 @@ int Convert_ConicToBSplineCurve::Multiplicity(const int Index) const // 2 2 // U + V // - // 2 * U*V // sin (theta(t)) = ---------- // 2 2 @@ -136,12 +224,12 @@ int Convert_ConicToBSplineCurve::Multiplicity(const int Index) const // with is helpful when having to make a C1 BSpline by merging two BSpline together //======================================================================= -void CosAndSinRationalC1(double Parameter, - const int EvalDegree, - const NCollection_Array1& EvalPoles, - const NCollection_Array1& EvalKnots, - const NCollection_Array1* EvalMults, - double Result[2]) +static void CosAndSinRationalC1(double Parameter, + const int EvalDegree, + const NCollection_Array1& EvalPoles, + const NCollection_Array1& EvalKnots, + const NCollection_Array1* EvalMults, + double Result[2]) { gp_Pnt2d a_point; BSplCLib::D0(Parameter, @@ -166,50 +254,57 @@ void CosAndSinRationalC1(double Parameter, // 2 2 // U + V // - // 2 * U*V // sin (theta(t)) = ---------- // 2 2 // U + V //======================================================================= -void CosAndSinQuasiAngular(double Parameter, - const int EvalDegree, - const NCollection_Array1& EvalPoles, - // const NCollection_Array1& EvalKnots, - const NCollection_Array1&, - // const NCollection_Array1& EvalMults, - const NCollection_Array1*, - double Result[2]) +static void CosAndSinQuasiAngular(double Parameter, + const int EvalDegree, + const NCollection_Array1& EvalPoles, + const NCollection_Array1&, + const NCollection_Array1*, + double Result[2]) { - double param, *coeff; - - coeff = (double*)&EvalPoles(EvalPoles.Lower()); + // Extract X,Y coordinates from all EvalPoles into a flat double array + // to safely pass to PLib::NoDerivativeEvalPolynomial. + Standard_OutOfRange_Raise_if(EvalPoles.Length() != EvalDegree + 1, + "CosAndSinQuasiAngular: EvalPoles size mismatch"); + const int aNumCoords = (EvalDegree + 1) * 2; + NCollection_Array1 aCoeffs(0, aNumCoords - 1); + for (int i = EvalPoles.Lower(); i <= EvalPoles.Upper(); i++) + { + const int anIdx = (i - EvalPoles.Lower()) * 2; + aCoeffs(anIdx) = EvalPoles(i).X(); + aCoeffs(anIdx + 1) = EvalPoles(i).Y(); + } // // rational_function_coeff represent a rational approximation // of U ---> cotan( PI * U /2) between [0 1] // rational_function_coeff[i][0] is the denominator // rational_function_coeff[i][1] is the numerator // - param = Parameter * 0.5e0; - PLib::NoDerivativeEvalPolynomial(param, EvalDegree, 2, EvalDegree << 1, coeff[0], Result[0]); + const double param = Parameter * 0.5e0; + PLib::NoDerivativeEvalPolynomial(param, EvalDegree, 2, EvalDegree << 1, aCoeffs(0), Result[0]); } //======================================================================= -// function : function that build the Bspline Representation of -// an algorithmic description of the function cos and sin -// purpose : +// function : AlgorithmicCosAndSin +// purpose : Build the Bspline representation of +// an algorithmic description of the function cos and sin //======================================================================= -void AlgorithmicCosAndSin(int Degree, - const NCollection_Array1& FlatKnots, - const int EvalDegree, - const NCollection_Array1& EvalPoles, - const NCollection_Array1& EvalKnots, - const NCollection_Array1* EvalMults, - Convert_CosAndSinEvalFunction Evaluator, - NCollection_Array1& CosNumerator, - NCollection_Array1& SinNumerator, - NCollection_Array1& Denominator) + +static void AlgorithmicCosAndSin(int Degree, + const NCollection_Array1& FlatKnots, + const int EvalDegree, + const NCollection_Array1& EvalPoles, + const NCollection_Array1& EvalKnots, + const NCollection_Array1* EvalMults, + Convert_CosAndSinEvalFunction Evaluator, + NCollection_Array1& CosNumerator, + NCollection_Array1& SinNumerator, + NCollection_Array1& Denominator) { int order, num_poles, pivot_index_problem, ii; @@ -251,18 +346,18 @@ void AlgorithmicCosAndSin(int Degree, } } -//================================================================================================= +//================================================================================================== void Convert_ConicToBSplineCurve::BuildCosAndSin( - const Convert_ParameterisationType Parameterisation, - const double UFirst, - const double ULast, - occ::handle>& CosNumeratorPtr, - occ::handle>& SinNumeratorPtr, - occ::handle>& DenominatorPtr, - int& Degree, - occ::handle>& KnotsPtr, - occ::handle>& MultsPtr) const + const Convert_ParameterisationType Parameterisation, + const double UFirst, + const double ULast, + NCollection_Array1& CosNumerator, + NCollection_Array1& SinNumerator, + NCollection_Array1& Denominator, + int& Degree, + NCollection_Array1& Knots, + NCollection_Array1& Mults) const { double delta = ULast - UFirst, direct, inverse, value1, value2, cos_beta, sin_beta, alpha = 0, alpha_2, alpha_4, tan_alpha_2, beta, p_param, q_param, param; @@ -336,35 +431,35 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( num_poles = 2 * num_spans + 1; } - CosNumeratorPtr = new NCollection_HArray1(1, num_poles); - SinNumeratorPtr = new NCollection_HArray1(1, num_poles); - DenominatorPtr = new NCollection_HArray1(1, num_poles); - KnotsPtr = new NCollection_HArray1(1, num_spans + 1); - MultsPtr = new NCollection_HArray1(1, num_spans + 1); + CosNumerator = NCollection_Array1(1, num_poles); + SinNumerator = NCollection_Array1(1, num_poles); + Denominator = NCollection_Array1(1, num_poles); + Knots = NCollection_Array1(1, num_spans + 1); + Mults = NCollection_Array1(1, num_spans + 1); if (tgt_theta_flag) { - param = UFirst; - CosNumeratorPtr->SetValue(1, std::cos(UFirst)); - SinNumeratorPtr->SetValue(1, std::sin(UFirst)); - DenominatorPtr->SetValue(1, 1.0e0); - KnotsPtr->SetValue(1, param); - MultsPtr->SetValue(1, Degree + 1); - direct = std::cos(alpha); - inverse = 1.0e0 / direct; + param = UFirst; + CosNumerator(1) = std::cos(UFirst); + SinNumerator(1) = std::sin(UFirst); + Denominator(1) = 1.0e0; + Knots(1) = param; + Mults(1) = Degree + 1; + direct = std::cos(alpha); + inverse = 1.0e0 / direct; for (ii = 1; ii <= num_spans; ii++) { - CosNumeratorPtr->SetValue(2 * ii, inverse * std::cos(param + alpha)); - SinNumeratorPtr->SetValue(2 * ii, inverse * std::sin(param + alpha)); - DenominatorPtr->SetValue(2 * ii, direct); - CosNumeratorPtr->SetValue(2 * ii + 1, std::cos(param + 2 * alpha)); - SinNumeratorPtr->SetValue(2 * ii + 1, std::sin(param + 2 * alpha)); - DenominatorPtr->SetValue(2 * ii + 1, 1.0e0); - KnotsPtr->SetValue(ii + 1, param + 2 * alpha); - MultsPtr->SetValue(ii + 1, 2); + CosNumerator(2 * ii) = inverse * std::cos(param + alpha); + SinNumerator(2 * ii) = inverse * std::sin(param + alpha); + Denominator(2 * ii) = direct; + CosNumerator(2 * ii + 1) = std::cos(param + 2 * alpha); + SinNumerator(2 * ii + 1) = std::sin(param + 2 * alpha); + Denominator(2 * ii + 1) = 1.0e0; + Knots(ii + 1) = param + 2 * alpha; + Mults(ii + 1) = 2; param += 2 * alpha; } - MultsPtr->SetValue(num_spans + 1, Degree + 1); + Mults(num_spans + 1) = Degree + 1; } else if (Parameterisation != Convert_Polynomial) { @@ -389,10 +484,10 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( flat_knots(ii) = -alpha; flat_knots(ii + num_poles) = alpha; } - KnotsPtr->SetValue(1, UFirst); - KnotsPtr->SetValue(num_knots, ULast); - MultsPtr->SetValue(1, order); - MultsPtr->SetValue(num_knots, order); + Knots(1) = UFirst; + Knots(num_knots) = ULast; + Mults(1) = order; + Mults(num_knots) = order; switch (Parameterisation) { @@ -458,8 +553,8 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( { flat_knots(ii) = 0.0e0; } - KnotsPtr->SetValue(2, UFirst + alpha); - MultsPtr->SetValue(2, Degree - 1); + Knots(2) = UFirst + alpha; + Mults(2) = Degree - 1; temp_degree = 2; alpha_2 = alpha * 0.5e0; alpha_4 = alpha * 0.25e0; @@ -494,49 +589,42 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( temp_knots, &temp_mults, *EvaluatorPtr, - CosNumeratorPtr->ChangeArray1(), - SinNumeratorPtr->ChangeArray1(), - DenominatorPtr->ChangeArray1()); + CosNumerator, + SinNumerator, + Denominator); for (ii = 1; ii <= num_poles; ii++) { - value1 = cos_beta * CosNumeratorPtr->Value(ii) - sin_beta * SinNumeratorPtr->Value(ii); - value2 = sin_beta * CosNumeratorPtr->Value(ii) + cos_beta * SinNumeratorPtr->Value(ii); - CosNumeratorPtr->SetValue(ii, value1); - SinNumeratorPtr->SetValue(ii, value2); + value1 = cos_beta * CosNumerator(ii) - sin_beta * SinNumerator(ii); + value2 = sin_beta * CosNumerator(ii) + cos_beta * SinNumerator(ii); + CosNumerator(ii) = value1; + SinNumerator(ii) = value2; } } else { // Convert_Polynomial - KnotsPtr->SetValue(1, 0.); - KnotsPtr->SetValue(num_knots, 1.); - MultsPtr->SetValue(1, num_poles); - MultsPtr->SetValue(num_knots, num_poles); + Knots(1) = 0.; + Knots(num_knots) = 1.; + Mults(1) = num_poles; + Mults(num_knots) = num_poles; - BuildPolynomialCosAndSin(UFirst, - ULast, - num_poles, - CosNumeratorPtr, - SinNumeratorPtr, - DenominatorPtr); + BuildPolynomialCosAndSin(UFirst, ULast, num_poles, CosNumerator, SinNumerator, Denominator); } } -//================================================================================================= +//================================================================================================== void Convert_ConicToBSplineCurve::BuildCosAndSin( - const Convert_ParameterisationType Parameterisation, - occ::handle>& CosNumeratorPtr, - occ::handle>& SinNumeratorPtr, - occ::handle>& DenominatorPtr, - int& Degree, - occ::handle>& KnotsPtr, - occ::handle>& MultsPtr) const + const Convert_ParameterisationType Parameterisation, + NCollection_Array1& CosNumerator, + NCollection_Array1& SinNumerator, + NCollection_Array1& Denominator, + int& Degree, + NCollection_Array1& Knots, + NCollection_Array1& Mults) const { - double half_pi, param, first_param, last_param, - // direct, - inverse, value1, value2, value3; + double half_pi, param, first_param, last_param, inverse, value1, value2, value3; int ii, jj, index, num_poles, num_periodic_poles, temp_degree, pivot_index_problem, num_flat_knots, num_knots; @@ -545,32 +633,31 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( { throw Standard_ConstructionError(); } - occ::handle> temp_cos_ptr, temp_sin_ptr, temp_denominator_ptr, - temp_knots_ptr; - occ::handle> temp_mults_ptr; + NCollection_Array1 temp_cos, temp_sin, temp_denominator, temp_knots; + NCollection_Array1 temp_mults; if (Parameterisation == Convert_TgtThetaOver2) { BuildCosAndSin(Convert_TgtThetaOver2_3, 0.0e0, 2 * M_PI, - temp_cos_ptr, - temp_sin_ptr, - temp_denominator_ptr, + temp_cos, + temp_sin, + temp_denominator, Degree, - KnotsPtr, - MultsPtr); - CosNumeratorPtr = new NCollection_HArray1(1, temp_cos_ptr->Length() - 1); - SinNumeratorPtr = new NCollection_HArray1(1, temp_cos_ptr->Length() - 1); - DenominatorPtr = new NCollection_HArray1(1, temp_cos_ptr->Length() - 1); - for (ii = temp_cos_ptr->Lower(); ii <= temp_cos_ptr->Upper() - 1; ii++) + Knots, + Mults); + CosNumerator = NCollection_Array1(1, temp_cos.Length() - 1); + SinNumerator = NCollection_Array1(1, temp_cos.Length() - 1); + Denominator = NCollection_Array1(1, temp_cos.Length() - 1); + for (ii = temp_cos.Lower(); ii <= temp_cos.Upper() - 1; ii++) { - CosNumeratorPtr->SetValue(ii, temp_cos_ptr->Value(ii)); - SinNumeratorPtr->SetValue(ii, temp_sin_ptr->Value(ii)); - DenominatorPtr->SetValue(ii, temp_denominator_ptr->Value(ii)); + CosNumerator(ii) = temp_cos(ii); + SinNumerator(ii) = temp_sin(ii); + Denominator(ii) = temp_denominator(ii); } - for (ii = MultsPtr->Lower(); ii <= MultsPtr->Upper(); ii++) + for (ii = Mults.Lower(); ii <= Mults.Upper(); ii++) { - MultsPtr->SetValue(ii, Degree); + Mults(ii) = Degree; } } else if (Parameterisation == Convert_RationalC1) @@ -580,12 +667,12 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( BuildCosAndSin(Convert_RationalC1, first_param, last_param, - temp_cos_ptr, - temp_sin_ptr, - temp_denominator_ptr, + temp_cos, + temp_sin, + temp_denominator, temp_degree, - temp_knots_ptr, - temp_mults_ptr); + temp_knots, + temp_mults); Degree = 4; num_knots = 5; @@ -593,9 +680,9 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( num_poles = num_flat_knots - Degree - 1; num_periodic_poles = num_poles - 2; NCollection_Array1 flat_knots(1, num_flat_knots); - CosNumeratorPtr = new NCollection_HArray1(1, num_periodic_poles); - SinNumeratorPtr = new NCollection_HArray1(1, num_periodic_poles); - DenominatorPtr = new NCollection_HArray1(1, num_periodic_poles); + CosNumerator = NCollection_Array1(1, num_periodic_poles); + SinNumerator = NCollection_Array1(1, num_periodic_poles); + Denominator = NCollection_Array1(1, num_periodic_poles); half_pi = M_PI * 0.5e0; index = 1; @@ -618,12 +705,12 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( flat_knots(index) = 2 * M_PI + half_pi; index += 1; } - KnotsPtr = new NCollection_HArray1(1, num_knots); - MultsPtr = new NCollection_HArray1(1, num_knots); + Knots = NCollection_Array1(1, num_knots); + Mults = NCollection_Array1(1, num_knots); for (ii = 1; ii <= num_knots; ii++) { - KnotsPtr->SetValue(ii, (ii - 1) * half_pi); - MultsPtr->SetValue(ii, Degree - 1); + Knots(ii) = (ii - 1) * half_pi; + Mults(ii) = Degree - 1; } NCollection_Array1 parameters(1, num_poles); @@ -643,29 +730,29 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( 0, temp_degree, false, - temp_cos_ptr->Array1(), - &temp_denominator_ptr->Array1(), - temp_knots_ptr->Array1(), - &temp_mults_ptr->Array1(), + temp_cos, + &temp_denominator, + temp_knots, + &temp_mults, value1); BSplCLib::D0(param, 0, temp_degree, false, - temp_sin_ptr->Array1(), - &temp_denominator_ptr->Array1(), - temp_knots_ptr->Array1(), - &temp_mults_ptr->Array1(), + temp_sin, + &temp_denominator, + temp_knots, + &temp_mults, value2); BSplCLib::D0(param, 0, temp_degree, false, - temp_denominator_ptr->Array1(), + temp_denominator, BSplCLib::NoWeights(), - temp_knots_ptr->Array1(), - &temp_mults_ptr->Array1(), + temp_knots, + &temp_mults, value3); contact_order_array(ii) = 0; @@ -681,10 +768,10 @@ void Convert_ConicToBSplineCurve::BuildCosAndSin( pivot_index_problem); for (ii = 1; ii <= num_periodic_poles; ii++) { - inverse = 1.0e0 / poles_array(ii).Coord(3); - CosNumeratorPtr->ChangeArray1()(ii) = poles_array(ii).Coord(1) * inverse; - SinNumeratorPtr->ChangeArray1()(ii) = poles_array(ii).Coord(2) * inverse; - DenominatorPtr->ChangeArray1()(ii) = poles_array(ii).Coord(3); + inverse = 1.0e0 / poles_array(ii).Coord(3); + CosNumerator(ii) = poles_array(ii).Coord(1) * inverse; + SinNumerator(ii) = poles_array(ii).Coord(2) * inverse; + Denominator(ii) = poles_array(ii).Coord(3); } } } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_ConicToBSplineCurve.hxx b/src/FoundationClasses/TKMath/Convert/Convert_ConicToBSplineCurve.hxx index 600f4d5bbb..e8378b9779 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_ConicToBSplineCurve.hxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_ConicToBSplineCurve.hxx @@ -20,13 +20,12 @@ #include #include #include +#include +#include #include #include #include -#include -#include -class gp_Pnt2d; //! Root class for algorithms which convert a conic curve into //! a BSpline curve (CircleToBSplineCurve, EllipseToBSplineCurve, @@ -40,17 +39,6 @@ class gp_Pnt2d; //! - a knots table with associated multiplicities. //! The abstract class ConicToBSplineCurve provides a //! framework for storing and consulting this computed data. -//! The data may then be used to construct a -//! Geom2d_BSplineCurve curvSuper class of the following classes : -//! This abstract class implements the methods to get the geometric -//! representation of the B-spline curve equivalent to the conic. -//! The B-spline is computed at the creation time in the sub classes. -//! The B-spline curve is defined with its degree, its control points -//! (Poles), its weights, its knots and their multiplicity. -//! All the geometric entities used in this package are defined in 2D -//! space. -//! KeyWords : -//! Convert, Conic, BSplineCurve, 2D. class Convert_ConicToBSplineCurve { public: @@ -58,79 +46,116 @@ public: //! Returns the degree of the BSpline curve whose data is //! computed in this framework. - Standard_EXPORT int Degree() const; + [[nodiscard]] Standard_EXPORT int Degree() const; //! Returns the number of poles of the BSpline curve whose //! data is computed in this framework. - Standard_EXPORT int NbPoles() const; + [[nodiscard]] Standard_EXPORT int NbPoles() const; //! Returns the number of knots of the BSpline curve whose //! data is computed in this framework. - Standard_EXPORT int NbKnots() const; + [[nodiscard]] Standard_EXPORT int NbKnots() const; //! Returns true if the BSpline curve whose data is computed in //! this framework is periodic. - Standard_EXPORT bool IsPeriodic() const; + [[nodiscard]] Standard_EXPORT bool IsPeriodic() const; //! Returns the pole of index Index to the poles table of the //! BSpline curve whose data is computed in this framework. - //! Exceptions - //! Standard_OutOfRange if Index is outside the bounds of - //! the poles table of the BSpline curve whose data is computed in this framework. - Standard_EXPORT gp_Pnt2d Pole(const int Index) const; + //! @param[in] theIndex pole index (1-based) + //! @return pole at the given index + //! @throws Standard_OutOfRange if theIndex is out of bounds + Standard_DEPRECATED("Use Poles() batch accessor instead") + Standard_EXPORT gp_Pnt2d Pole(const int theIndex) const; //! Returns the weight of the pole of index Index to the poles //! table of the BSpline curve whose data is computed in this framework. - //! Exceptions - //! Standard_OutOfRange if Index is outside the bounds of - //! the poles table of the BSpline curve whose data is computed in this framework. - Standard_EXPORT double Weight(const int Index) const; + //! @param[in] theIndex weight index (1-based) + //! @return weight at the given index + //! @throws Standard_OutOfRange if theIndex is out of bounds + Standard_DEPRECATED("Use Weights() batch accessor instead") + Standard_EXPORT double Weight(const int theIndex) const; //! Returns the knot of index Index to the knots table of the //! BSpline curve whose data is computed in this framework. - //! Exceptions - //! Standard_OutOfRange if Index is outside the bounds of - //! the knots table of the BSpline curve whose data is computed in this framework. - Standard_EXPORT double Knot(const int Index) const; + //! @param[in] theIndex knot index (1-based) + //! @return knot at the given index + //! @throws Standard_OutOfRange if theIndex is out of bounds + Standard_DEPRECATED("Use Knots() batch accessor instead") + Standard_EXPORT double Knot(const int theIndex) const; //! Returns the multiplicity of the knot of index Index to the //! knots table of the BSpline curve whose data is computed in this framework. - //! Exceptions - //! Standard_OutOfRange if Index is outside the bounds of - //! the knots table of the BSpline curve whose data is computed in this framework. - Standard_EXPORT int Multiplicity(const int Index) const; + //! @param[in] theIndex multiplicity index (1-based) + //! @return multiplicity at the given index + //! @throws Standard_OutOfRange if theIndex is out of bounds + Standard_DEPRECATED("Use Multiplicities() batch accessor instead") + Standard_EXPORT int Multiplicity(const int theIndex) const; - Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType Parametrisation, - occ::handle>& CosNumerator, - occ::handle>& SinNumerator, - occ::handle>& Denominator, - int& Degree, - occ::handle>& Knots, - occ::handle>& Mults) const; + //! Returns the poles of the BSpline curve. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& Poles() const; - Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType Parametrisation, - const double UFirst, - const double ULast, - occ::handle>& CosNumerator, - occ::handle>& SinNumerator, - occ::handle>& Denominator, - int& Degree, - occ::handle>& Knots, - occ::handle>& Mults) const; + //! Returns the weights of the BSpline curve. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& Weights() const; + + //! Returns the knots of the BSpline curve. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& Knots() const; + + //! Returns the multiplicities of the BSpline curve. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& Multiplicities() const; + + //! Legacy API returning handle arrays for compatibility. + Standard_DEPRECATED("Use array-based BuildCosAndSin() overload instead") + Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType theParametrisation, + occ::handle>& theCosNumerator, + occ::handle>& theSinNumerator, + occ::handle>& theDenominator, + int& theDegree, + occ::handle>& theKnots, + occ::handle>& theMults) const; + + //! Legacy API returning handle arrays for compatibility. + Standard_DEPRECATED("Use array-based BuildCosAndSin() overload instead") + Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType theParametrisation, + const double theUFirst, + const double theULast, + occ::handle>& theCosNumerator, + occ::handle>& theSinNumerator, + occ::handle>& theDenominator, + int& theDegree, + occ::handle>& theKnots, + occ::handle>& theMults) const; protected: - Standard_EXPORT Convert_ConicToBSplineCurve(const int NumberOfPoles, - const int NumberOfKnots, - const int Degree); + Standard_EXPORT Convert_ConicToBSplineCurve(const int theNumberOfPoles, + const int theNumberOfKnots, + const int theDegree); - occ::handle> poles; - occ::handle> weights; - occ::handle> knots; - occ::handle> mults; - int degree; - int nbPoles; - int nbKnots; - bool isperiodic; + Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType theParametrisation, + NCollection_Array1& theCosNumerator, + NCollection_Array1& theSinNumerator, + NCollection_Array1& theDenominator, + int& theDegree, + NCollection_Array1& theKnots, + NCollection_Array1& theMults) const; + + Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType theParametrisation, + const double theUFirst, + const double theULast, + NCollection_Array1& theCosNumerator, + NCollection_Array1& theSinNumerator, + NCollection_Array1& theDenominator, + int& theDegree, + NCollection_Array1& theKnots, + NCollection_Array1& theMults) const; + +protected: + NCollection_Array1 myPoles; + NCollection_Array1 myWeights; + NCollection_Array1 myKnots; + NCollection_Array1 myMults; + int myDegree = 0; + bool myIsPeriodic = false; }; #endif // _Convert_ConicToBSplineCurve_HeaderFile diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CosAndSinEvalFunction.hxx b/src/FoundationClasses/TKMath/Convert/Convert_CosAndSinEvalFunction.hxx index 41b3d6c6a9..5d5417b854 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CosAndSinEvalFunction.hxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CosAndSinEvalFunction.hxx @@ -21,7 +21,9 @@ #include #include -typedef void Convert_CosAndSinEvalFunction(double, +//! Function type for evaluating cos and sin representations +//! used in rational curve parameterization. +using Convert_CosAndSinEvalFunction = void(double, const int, const NCollection_Array1&, const NCollection_Array1&, diff --git a/src/FoundationClasses/TKMath/Convert/Convert_CylinderToBSplineSurface.cxx b/src/FoundationClasses/TKMath/Convert/Convert_CylinderToBSplineSurface.cxx index f058ab2d5c..46cc318897 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_CylinderToBSplineSurface.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_CylinderToBSplineSurface.cxx @@ -84,8 +84,8 @@ Convert_CylinderToBSplineSurface::Convert_CylinderToBSplineSurface(const gp_Cyli || (deltaU < 0.), "Convert_CylinderToBSplineSurface"); - isuperiodic = false; - isvperiodic = false; + myIsUPeriodic = false; + myIsVPeriodic = false; int i, j; // construction of the cylinder in the reference mark xOy. @@ -94,27 +94,27 @@ Convert_CylinderToBSplineSurface::Convert_CylinderToBSplineSurface(const gp_Cyli int nbUSpans = (int)std::trunc(1.2 * deltaU / M_PI) + 1; double AlfaU = deltaU / (nbUSpans * 2); - nbUPoles = 2 * nbUSpans + 1; - nbUKnots = nbUSpans + 1; + myNbUPoles = 2 * nbUSpans + 1; + myNbUKnots = nbUSpans + 1; - nbVPoles = 2; - nbVKnots = 2; + myNbVPoles = 2; + myNbVKnots = 2; double R = Cyl.Radius(); - ComputePoles(R, U1, U2, V1, V2, poles); + ComputePoles(R, U1, U2, V1, V2, myPoles); - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = U1 + (i - 1) * 2 * AlfaU; - umults(i) = 2; + myUKnots(i) = U1 + (i - 1) * 2 * AlfaU; + myUMults(i) = 2; } - umults(1)++; - umults(nbUKnots)++; - vknots(1) = V1; - vmults(1) = 2; - vknots(2) = V2; - vmults(2) = 2; + myUMults(1)++; + myUMults(myNbUKnots)++; + myVKnots(1) = V1; + myVMults(1) = 2; + myVKnots(2) = V2; + myVMults(2) = 2; // Replace bspline in the mark of the sphere. // and calculate the weight of the bspline. @@ -122,19 +122,20 @@ Convert_CylinderToBSplineSurface::Convert_CylinderToBSplineSurface(const gp_Cyli gp_Trsf Trsf; Trsf.SetTransformation(Cyl.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W1 = std::cos(AlfaU); else W1 = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { - weights(i, j) = W1; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W1; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } //================================================================================================= @@ -154,29 +155,29 @@ Convert_CylinderToBSplineSurface::Convert_CylinderToBSplineSurface(const gp_Cyli int i, j; - isuperiodic = true; - isvperiodic = false; + myIsUPeriodic = true; + myIsVPeriodic = false; // construction of the cylinder in the reference mark xOy. double R = Cyl.Radius(); - ComputePoles(R, 0., 2. * M_PI, V1, V2, poles); + ComputePoles(R, 0., 2. * M_PI, V1, V2, myPoles); - nbUPoles = 6; - nbUKnots = 4; - nbVPoles = 2; - nbVKnots = 2; + myNbUPoles = 6; + myNbUKnots = 4; + myNbVPoles = 2; + myNbVKnots = 2; - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = (i - 1) * 2. * M_PI / 3.; - umults(i) = 2; + myUKnots(i) = (i - 1) * 2. * M_PI / 3.; + myUMults(i) = 2; } - vknots(1) = V1; - vmults(1) = 2; - vknots(2) = V2; - vmults(2) = 2; + myVKnots(1) = V1; + myVMults(1) = 2; + myVKnots(2) = V2; + myVMults(2) = 2; // Replace the bspline inn the mark of the cone. // and calculate the weight of the bspline. @@ -184,17 +185,18 @@ Convert_CylinderToBSplineSurface::Convert_CylinderToBSplineSurface(const gp_Cyli gp_Trsf Trsf; Trsf.SetTransformation(Cyl.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W = 0.5; // = std::cos(pi /3) else W = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { - weights(i, j) = W; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_ElementarySurfaceToBSplineSurface.cxx b/src/FoundationClasses/TKMath/Convert/Convert_ElementarySurfaceToBSplineSurface.cxx index bc5ace97f5..50755a0872 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_ElementarySurfaceToBSplineSurface.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_ElementarySurfaceToBSplineSurface.cxx @@ -18,135 +18,219 @@ #include #include -//================================================================================================= +//================================================================================================== + +void Convert_ElementarySurfaceToBSplineSurface::Finalize() +{ + // Trim oversized arrays down to actual sizes, preserving 2D element positions. + if (myPoles.NbRows() != myNbUPoles || myPoles.NbColumns() != myNbVPoles) + { + myPoles.ResizeWithTrim(1, myNbUPoles, 1, myNbVPoles, true); + } + if (myWeights.NbRows() != myNbUPoles || myWeights.NbColumns() != myNbVPoles) + { + myWeights.ResizeWithTrim(1, myNbUPoles, 1, myNbVPoles, true); + } + if (myUKnots.Length() != myNbUKnots) + { + myUKnots.Resize(1, myNbUKnots, true); + } + if (myUMults.Length() != myNbUKnots) + { + myUMults.Resize(1, myNbUKnots, true); + } + if (myVKnots.Length() != myNbVKnots) + { + myVKnots.Resize(1, myNbVKnots, true); + } + if (myVMults.Length() != myNbVKnots) + { + myVMults.Resize(1, myNbVKnots, true); + } +} + +//================================================================================================== Convert_ElementarySurfaceToBSplineSurface::Convert_ElementarySurfaceToBSplineSurface( - const int NbUPoles, - const int NbVPoles, - const int NbUKnots, - const int NbVKnots, - const int UDegree, - const int VDegree) - : poles(1, NbUPoles, 1, NbVPoles), - weights(1, NbUPoles, 1, NbVPoles), - uknots(1, NbUKnots), - umults(1, NbUKnots), - vknots(1, NbVKnots), - vmults(1, NbVKnots), - udegree(UDegree), - vdegree(VDegree), - nbUPoles(NbUPoles), - nbVPoles(NbVPoles), - nbUKnots(NbUKnots), - nbVKnots(NbVKnots), - isuperiodic(false), - isvperiodic(false) - + const int theNbUPoles, + const int theNbVPoles, + const int theNbUKnots, + const int theNbVKnots, + const int theUDegree, + const int theVDegree) + : myPoles(1, theNbUPoles, 1, theNbVPoles), + myWeights(1, theNbUPoles, 1, theNbVPoles), + myUKnots(1, theNbUKnots), + myVKnots(1, theNbVKnots), + myUMults(1, theNbUKnots), + myVMults(1, theNbVKnots), + myUDegree(theUDegree), + myVDegree(theVDegree), + myNbUPoles(theNbUPoles), + myNbVPoles(theNbVPoles), + myNbUKnots(theNbUKnots), + myNbVKnots(theNbVKnots) { } -//================================================================================================= +//================================================================================================== int Convert_ElementarySurfaceToBSplineSurface::UDegree() const { - return udegree; + return myUDegree; } -//================================================================================================= +//================================================================================================== int Convert_ElementarySurfaceToBSplineSurface::VDegree() const { - return vdegree; + return myVDegree; } -//================================================================================================= +//================================================================================================== int Convert_ElementarySurfaceToBSplineSurface::NbUPoles() const { - return nbUPoles; + return myNbUPoles; } -//================================================================================================= +//================================================================================================== int Convert_ElementarySurfaceToBSplineSurface::NbVPoles() const { - return nbVPoles; + return myNbVPoles; } -//================================================================================================= +//================================================================================================== int Convert_ElementarySurfaceToBSplineSurface::NbUKnots() const { - return nbUKnots; + return myNbUKnots; } -//================================================================================================= +//================================================================================================== int Convert_ElementarySurfaceToBSplineSurface::NbVKnots() const { - return nbVKnots; + return myNbVKnots; } -//================================================================================================= +//================================================================================================== bool Convert_ElementarySurfaceToBSplineSurface::IsUPeriodic() const { - return isuperiodic; + return myIsUPeriodic; } -//================================================================================================= +//================================================================================================== bool Convert_ElementarySurfaceToBSplineSurface::IsVPeriodic() const { - return isvperiodic; + return myIsVPeriodic; } -//================================================================================================= +//================================================================================================== -gp_Pnt Convert_ElementarySurfaceToBSplineSurface::Pole(const int UIndex, const int VIndex) const +Standard_DISABLE_DEPRECATION_WARNINGS gp_Pnt + Convert_ElementarySurfaceToBSplineSurface::Pole(const int UIndex, const int VIndex) const { - Standard_OutOfRange_Raise_if(UIndex < 1 || UIndex > nbUPoles || VIndex < 1 || VIndex > nbVPoles, - " "); - return poles(UIndex, VIndex); + Standard_OutOfRange_Raise_if( + UIndex < 1 || UIndex > myNbUPoles || VIndex < 1 || VIndex > myNbVPoles, + "Convert_ElementarySurfaceToBSplineSurface::Pole: Index out of range"); + return myPoles(UIndex, VIndex); } -//================================================================================================= +//================================================================================================== double Convert_ElementarySurfaceToBSplineSurface::Weight(const int UIndex, const int VIndex) const { - Standard_OutOfRange_Raise_if(UIndex < 1 || UIndex > nbUPoles || VIndex < 1 || VIndex > nbVPoles, - " "); - return weights(UIndex, VIndex); + Standard_OutOfRange_Raise_if( + UIndex < 1 || UIndex > myNbUPoles || VIndex < 1 || VIndex > myNbVPoles, + "Convert_ElementarySurfaceToBSplineSurface::Weight: Index out of range"); + return myWeights(UIndex, VIndex); } -//================================================================================================= +//================================================================================================== double Convert_ElementarySurfaceToBSplineSurface::UKnot(const int UIndex) const { - Standard_OutOfRange_Raise_if(UIndex < 1 || UIndex > nbUKnots, " "); - return uknots(UIndex); + Standard_OutOfRange_Raise_if( + UIndex < 1 || UIndex > myNbUKnots, + "Convert_ElementarySurfaceToBSplineSurface::UKnot: Index out of range"); + return myUKnots(UIndex); } -//================================================================================================= +//================================================================================================== double Convert_ElementarySurfaceToBSplineSurface::VKnot(const int VIndex) const { - Standard_OutOfRange_Raise_if(VIndex < 1 || VIndex > nbVKnots, " "); - return vknots(VIndex); + Standard_OutOfRange_Raise_if( + VIndex < 1 || VIndex > myNbVKnots, + "Convert_ElementarySurfaceToBSplineSurface::VKnot: Index out of range"); + return myVKnots(VIndex); } -//================================================================================================= +//================================================================================================== int Convert_ElementarySurfaceToBSplineSurface::UMultiplicity(const int UIndex) const { - Standard_OutOfRange_Raise_if(UIndex < 1 || UIndex > nbUKnots, " "); - return umults(UIndex); + Standard_OutOfRange_Raise_if( + UIndex < 1 || UIndex > myNbUKnots, + "Convert_ElementarySurfaceToBSplineSurface::UMultiplicity: Index out of range"); + return myUMults(UIndex); } -//================================================================================================= +//================================================================================================== int Convert_ElementarySurfaceToBSplineSurface::VMultiplicity(const int VIndex) const { - Standard_OutOfRange_Raise_if(VIndex < 1 || VIndex > nbVKnots, " "); - return vmults(VIndex); + Standard_OutOfRange_Raise_if( + VIndex < 1 || VIndex > myNbVKnots, + "Convert_ElementarySurfaceToBSplineSurface::VMultiplicity: Index out of range"); + return myVMults(VIndex); +} + +Standard_ENABLE_DEPRECATION_WARNINGS + + //================================================================================================== + + const NCollection_Array2& + Convert_ElementarySurfaceToBSplineSurface::Poles() const +{ + return myPoles; +} + +//================================================================================================== + +const NCollection_Array2& Convert_ElementarySurfaceToBSplineSurface::Weights() const +{ + return myWeights; +} + +//================================================================================================== + +const NCollection_Array1& Convert_ElementarySurfaceToBSplineSurface::UKnots() const +{ + return myUKnots; +} + +//================================================================================================== + +const NCollection_Array1& Convert_ElementarySurfaceToBSplineSurface::VKnots() const +{ + return myVKnots; +} + +//================================================================================================== + +const NCollection_Array1& Convert_ElementarySurfaceToBSplineSurface::UMultiplicities() const +{ + return myUMults; +} + +//================================================================================================== + +const NCollection_Array1& Convert_ElementarySurfaceToBSplineSurface::VMultiplicities() const +{ + return myVMults; } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_ElementarySurfaceToBSplineSurface.hxx b/src/FoundationClasses/TKMath/Convert/Convert_ElementarySurfaceToBSplineSurface.hxx index 5ba07c6a34..cb6284b626 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_ElementarySurfaceToBSplineSurface.hxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_ElementarySurfaceToBSplineSurface.hxx @@ -20,132 +20,126 @@ #include #include #include +#include #include -#include #include -#include -#include -class gp_Pnt; +#include //! Root class for algorithms which convert an elementary -//! surface (cylinder, cone, sphere or torus) into a BSpline -//! surface (CylinderToBSplineSurface, ConeToBSplineSurface, -//! SphereToBSplineSurface, TorusToBSplineSurface). +//! surface (cylinder, cone, sphere or torus) into a BSpline surface. //! These algorithms all work on elementary surfaces from //! the gp package and compute all the data needed to //! construct a BSpline surface equivalent to the cylinder, -//! cone, sphere or torus. This data consists of the following: -//! - degrees in the u and v parametric directions, -//! - periodic characteristics in the u and v parametric directions, -//! - a poles table with associated weights, -//! - a knots table (for the u and v parametric directions) -//! with associated multiplicities. -//! The abstract class -//! ElementarySurfaceToBSplineSurface provides a -//! framework for storing and consulting this computed data. -//! This data may then be used to construct a -//! Geom_BSplineSurface surface, for example. -//! All those classes define algorithms to convert an -//! ElementarySurface into a B-spline surface. -//! This abstract class implements the methods to get -//! the geometric representation of the B-spline surface. -//! The B-spline representation is computed at the creation -//! time in the sub classes. -//! The B-spline surface is defined with its degree in the -//! parametric U and V directions, its control points (Poles), -//! its weights, its knots and their multiplicity. -//! KeyWords : -//! Convert, ElementarySurface, BSplineSurface. +//! cone, sphere or torus. class Convert_ElementarySurfaceToBSplineSurface { public: DEFINE_STANDARD_ALLOC - Standard_EXPORT int UDegree() const; + //! Returns the degree in the U parametric direction. + [[nodiscard]] Standard_EXPORT int UDegree() const; - //! Returns the degree for the u or v parametric direction of - //! the BSpline surface whose data is computed in this framework. - Standard_EXPORT int VDegree() const; + //! Returns the degree in the V parametric direction. + [[nodiscard]] Standard_EXPORT int VDegree() const; - Standard_EXPORT int NbUPoles() const; + //! Returns the number of poles in the U parametric direction. + [[nodiscard]] Standard_EXPORT int NbUPoles() const; - //! Returns the number of poles for the u or v parametric - //! direction of the BSpline surface whose data is computed in this framework. - Standard_EXPORT int NbVPoles() const; + //! Returns the number of poles in the V parametric direction. + [[nodiscard]] Standard_EXPORT int NbVPoles() const; - Standard_EXPORT int NbUKnots() const; + //! Returns the number of knots in the U parametric direction. + [[nodiscard]] Standard_EXPORT int NbUKnots() const; - //! Returns the number of knots for the u or v parametric - //! direction of the BSpline surface whose data is computed in this framework . - Standard_EXPORT int NbVKnots() const; + //! Returns the number of knots in the V parametric direction. + [[nodiscard]] Standard_EXPORT int NbVKnots() const; - Standard_EXPORT bool IsUPeriodic() const; + //! Returns true if the surface is periodic in the U parametric direction. + [[nodiscard]] Standard_EXPORT bool IsUPeriodic() const; - //! Returns true if the BSpline surface whose data is computed - //! in this framework is periodic in the u or v parametric direction. - Standard_EXPORT bool IsVPeriodic() const; + //! Returns true if the surface is periodic in the V parametric direction. + [[nodiscard]] Standard_EXPORT bool IsVPeriodic() const; - //! Returns the pole of index (UIndex,VIndex) to the poles - //! table of the BSpline surface whose data is computed in this framework. - //! Exceptions - //! Standard_OutOfRange if, for the BSpline surface whose - //! data is computed in this framework: - //! - UIndex is outside the bounds of the poles table in the u - //! parametric direction, or - //! - VIndex is outside the bounds of the poles table in the v - //! parametric direction. + //! Returns the pole of index (UIndex, VIndex). + //! @throws Standard_OutOfRange if indices are out of bounds + Standard_DEPRECATED("Use Poles() batch accessor instead") Standard_EXPORT gp_Pnt Pole(const int UIndex, const int VIndex) const; - //! Returns the weight of the pole of index (UIndex,VIndex) to - //! the poles table of the BSpline surface whose data is computed in this framework. - //! Exceptions - //! Standard_OutOfRange if, for the BSpline surface whose - //! data is computed in this framework: - //! - UIndex is outside the bounds of the poles table in the u - //! parametric direction, or - //! - VIndex is outside the bounds of the poles table in the v - //! parametric direction. + //! Returns the weight of the pole of index (UIndex, VIndex). + //! @throws Standard_OutOfRange if indices are out of bounds + Standard_DEPRECATED("Use Weights() batch accessor instead") Standard_EXPORT double Weight(const int UIndex, const int VIndex) const; //! Returns the U-knot of range UIndex. - //! Raised if UIndex < 1 or UIndex > NbUKnots. + //! @throws Standard_OutOfRange if UIndex is out of bounds + Standard_DEPRECATED("Use UKnots() batch accessor instead") Standard_EXPORT double UKnot(const int UIndex) const; //! Returns the V-knot of range VIndex. - //! Raised if VIndex < 1 or VIndex > NbVKnots. - Standard_EXPORT double VKnot(const int UIndex) const; + //! @throws Standard_OutOfRange if VIndex is out of bounds + Standard_DEPRECATED("Use VKnots() batch accessor instead") + Standard_EXPORT double VKnot(const int VIndex) const; //! Returns the multiplicity of the U-knot of range UIndex. - //! Raised if UIndex < 1 or UIndex > NbUKnots. + //! @throws Standard_OutOfRange if UIndex is out of bounds + Standard_DEPRECATED("Use UMultiplicities() batch accessor instead") Standard_EXPORT int UMultiplicity(const int UIndex) const; //! Returns the multiplicity of the V-knot of range VIndex. - //! Raised if VIndex < 1 or VIndex > NbVKnots. + //! @throws Standard_OutOfRange if VIndex is out of bounds + Standard_DEPRECATED("Use VMultiplicities() batch accessor instead") Standard_EXPORT int VMultiplicity(const int VIndex) const; -protected: - Standard_EXPORT Convert_ElementarySurfaceToBSplineSurface(const int NumberOfUPoles, - const int NumberOfVPoles, - const int NumberOfUKnots, - const int NumberOfVKnots, - const int UDegree, - const int VDegree); + //! Returns the poles of the BSpline surface. + [[nodiscard]] Standard_EXPORT const NCollection_Array2& Poles() const; - NCollection_Array2 poles; - NCollection_Array2 weights; - NCollection_Array1 uknots; - NCollection_Array1 umults; - NCollection_Array1 vknots; - NCollection_Array1 vmults; - int udegree; - int vdegree; - int nbUPoles; - int nbVPoles; - int nbUKnots; - int nbVKnots; - bool isuperiodic; - bool isvperiodic; + //! Returns the weights of the BSpline surface. + [[nodiscard]] Standard_EXPORT const NCollection_Array2& Weights() const; + + //! Returns the U-knots of the BSpline surface. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& UKnots() const; + + //! Returns the V-knots of the BSpline surface. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& VKnots() const; + + //! Returns the U-multiplicities of the BSpline surface. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& UMultiplicities() const; + + //! Returns the V-multiplicities of the BSpline surface. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& VMultiplicities() const; + +protected: + Standard_EXPORT Convert_ElementarySurfaceToBSplineSurface(const int theNbUPoles, + const int theNbVPoles, + const int theNbUKnots, + const int theNbVKnots, + const int theUDegree, + const int theVDegree); + + //! Resizes internal arrays (poles, weights, knots, multiplicities) + //! to match the actual sizes stored in myNbUPoles, myNbVPoles, + //! myNbUKnots, and myNbVKnots. This is intended to be called at the + //! end of derived class constructors when the base class constructor + //! allocates arrays with maximum possible sizes but the derived + //! constructor uses fewer elements. + Standard_EXPORT void Finalize(); + +protected: + NCollection_Array2 myPoles; + NCollection_Array2 myWeights; + NCollection_Array1 myUKnots; + NCollection_Array1 myVKnots; + NCollection_Array1 myUMults; + NCollection_Array1 myVMults; + int myUDegree = 0; + int myVDegree = 0; + bool myIsUPeriodic = false; + bool myIsVPeriodic = false; + int myNbUPoles; + int myNbVPoles; + int myNbUKnots; + int myNbVKnots; }; #endif // _Convert_ElementarySurfaceToBSplineSurface_HeaderFile diff --git a/src/FoundationClasses/TKMath/Convert/Convert_EllipseToBSplineCurve.cxx b/src/FoundationClasses/TKMath/Convert/Convert_EllipseToBSplineCurve.cxx index 663923390c..f152182e75 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_EllipseToBSplineCurve.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_EllipseToBSplineCurve.cxx @@ -24,14 +24,13 @@ #include #include #include -#include // Attention : // To avoid use of persistent tables in the fields // the tables are dimensioned to the maximum (TheNbKnots and TheNbPoles) // that correspond to the full circle. For an arc of circle there is a // need of less poles and nodes, that is why the fields -// nbKnots and nbPoles are present and updated in the +// myNbKnots and myNbPoles are present and updated in the // constructor of an arc of B-spline circle to take into account // the real number of poles and nodes. // parameterization : @@ -53,8 +52,8 @@ Convert_EllipseToBSplineCurve::Convert_EllipseToBSplineCurve( int ii; - double R, r, value; - occ::handle> CosNumeratorPtr, SinNumeratorPtr; + double R, r, value; + NCollection_Array1 CosNumerator, SinNumerator; R = E.MajorRadius(); r = E.MinorRadius(); @@ -63,33 +62,30 @@ Convert_EllipseToBSplineCurve::Convert_EllipseToBSplineCurve( { // If BuildCosAndSin cannot manage the periodicity // => trim on 0,2*PI - isperiodic = false; + myIsPeriodic = false; Convert_ConicToBSplineCurve::BuildCosAndSin(Parameterisation, 0, 2 * M_PI, - CosNumeratorPtr, - SinNumeratorPtr, - weights, - degree, - knots, - mults); + CosNumerator, + SinNumerator, + myWeights, + myDegree, + myKnots, + myMults); } else { - isperiodic = true; + myIsPeriodic = true; Convert_ConicToBSplineCurve::BuildCosAndSin(Parameterisation, - CosNumeratorPtr, - SinNumeratorPtr, - weights, - degree, - knots, - mults); + CosNumerator, + SinNumerator, + myWeights, + myDegree, + myKnots, + myMults); } - nbPoles = CosNumeratorPtr->Length(); - nbKnots = knots->Length(); - - poles = new NCollection_HArray1(1, nbPoles); + myPoles = NCollection_Array1(1, CosNumerator.Length()); gp_Dir2d Ox = E.XAxis().Direction(); gp_Dir2d Oy = E.YAxis().Direction(); @@ -107,11 +103,11 @@ Convert_EllipseToBSplineCurve::Convert_EllipseToBSplineCurve( // Replace the bspline in the mark of the circle. // and calculate the weight of the bspline. - for (ii = 1; ii <= nbPoles; ii++) + for (ii = 1; ii <= myPoles.Length(); ii++) { - poles->ChangeArray1()(ii).SetCoord(1, R * CosNumeratorPtr->Value(ii)); - poles->ChangeArray1()(ii).SetCoord(2, value * SinNumeratorPtr->Value(ii)); - poles->ChangeArray1()(ii).Transform(Trsf); + myPoles(ii).SetCoord(1, R * CosNumerator(ii)); + myPoles(ii).SetCoord(2, value * SinNumerator(ii)); + myPoles(ii).Transform(Trsf); } } @@ -133,28 +129,25 @@ Convert_EllipseToBSplineCurve::Convert_EllipseToBSplineCurve( #endif Standard_DomainError_Raise_if((delta > (2 * M_PI + Tol)) || (delta <= 0.0e0), "Convert_EllipseToBSplineCurve"); - int ii; - double R, r, value; - occ::handle> CosNumeratorPtr, SinNumeratorPtr; + int ii; + double R, r, value; + NCollection_Array1 CosNumerator, SinNumerator; R = E.MajorRadius(); r = E.MinorRadius(); - isperiodic = false; + myIsPeriodic = false; Convert_ConicToBSplineCurve::BuildCosAndSin(Parameterisation, UFirst, ULast, - CosNumeratorPtr, - SinNumeratorPtr, - weights, - degree, - knots, - mults); + CosNumerator, + SinNumerator, + myWeights, + myDegree, + myKnots, + myMults); - nbPoles = CosNumeratorPtr->Length(); - nbKnots = knots->Length(); - - poles = new NCollection_HArray1(1, nbPoles); + myPoles = NCollection_Array1(1, CosNumerator.Length()); gp_Dir2d Ox = E.XAxis().Direction(); gp_Dir2d Oy = E.YAxis().Direction(); @@ -172,10 +165,10 @@ Convert_EllipseToBSplineCurve::Convert_EllipseToBSplineCurve( // Replace the bspline in the mark of the circle. // and calculate the weight of the bspline. - for (ii = 1; ii <= nbPoles; ii++) + for (ii = 1; ii <= myPoles.Length(); ii++) { - poles->ChangeArray1()(ii).SetCoord(1, R * CosNumeratorPtr->Value(ii)); - poles->ChangeArray1()(ii).SetCoord(2, value * SinNumeratorPtr->Value(ii)); - poles->ChangeArray1()(ii).Transform(Trsf); + myPoles(ii).SetCoord(1, R * CosNumerator(ii)); + myPoles(ii).SetCoord(2, value * SinNumerator(ii)); + myPoles(ii).Transform(Trsf); } } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_GridPolynomialToPoles.cxx b/src/FoundationClasses/TKMath/Convert/Convert_GridPolynomialToPoles.cxx index 842a45e5a2..6d82e8c752 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_GridPolynomialToPoles.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_GridPolynomialToPoles.cxx @@ -33,7 +33,9 @@ Convert_GridPolynomialToPoles::Convert_GridPolynomialToPoles( const occ::handle>& Coefficients, const occ::handle>& PolynomialUIntervals, const occ::handle>& PolynomialVIntervals) - : myDone(false) + : myUDegree(0), + myVDegree(0), + myDone(false) { // Les Controles if ((NumCoeffPerSurface->Lower() != 1) || (NumCoeffPerSurface->Upper() != 2)) @@ -84,13 +86,12 @@ Convert_GridPolynomialToPoles::Convert_GridPolynomialToPoles( const occ::handle>& PolynomialVIntervals, const occ::handle>& TrueUIntervals, const occ::handle>& TrueVIntervals) - : myDone(false) + : myUDegree(0), + myVDegree(0), + myDone(false) { - int ii; int RealUDegree = std::max(MaxUDegree, 2 * UContinuity + 1); int RealVDegree = std::max(MaxVDegree, 2 * VContinuity + 1); - myUDegree = 0; - myVDegree = 0; // Les controles if ((NumCoeffPerSurface->LowerRow() != 1) @@ -108,7 +109,7 @@ Convert_GridPolynomialToPoles::Convert_GridPolynomialToPoles( } // Calcul des degree - for (ii = 1; ii <= NbUSurfaces * NbVSurfaces; ii++) + for (int ii = 1; ii <= NbUSurfaces * NbVSurfaces; ii++) { if (NumCoeffPerSurface->Value(ii, 1) > myUDegree + 1) myUDegree = NumCoeffPerSurface->Value(ii, 1) - 1; @@ -146,11 +147,9 @@ void Convert_GridPolynomialToPoles::Perform( const occ::handle>& TrueVIntervals) { // (1) Construction des Tables monodimensionnelles ---------------------------- - occ::handle> UParameters, VParameters; - myUKnots = new (NCollection_HArray1)(1, TrueUIntervals->Length()); - myUKnots->ChangeArray1() = TrueUIntervals->Array1(); - myVKnots = new (NCollection_HArray1)(1, TrueVIntervals->Length()); - myVKnots->ChangeArray1() = TrueVIntervals->Array1(); + NCollection_Array1 UParameters, VParameters; + myUKnots = NCollection_Array1(TrueUIntervals->Array1()); + myVKnots = NCollection_Array1(TrueVIntervals->Array1()); BuildArray(myUDegree, myUKnots, UContinuity, myUFlatKnots, myUMults, UParameters); @@ -163,46 +162,46 @@ void Convert_GridPolynomialToPoles::Perform( double NValue, UValue, VValue; int dimension = 3 * (myVDegree + 1); int SizPatch = 3 * (MaxUDegree + 1) * (MaxVDegree + 1); - myPoles = new (NCollection_HArray2)(1, UParameters->Length(), 1, VParameters->Length()); + myPoles = NCollection_Array2(1, UParameters.Length(), 1, VParameters.Length()); NCollection_Array1 Patch(1, (myUDegree + 1) * dimension); NCollection_Array1 Point(1, 3); double* Coeffs = (double*)&Patch.ChangeValue(1); double* Digit = (double*)&Point.ChangeValue(1); - for (ii = 1, Uindex = 1; ii <= UParameters->Length(); ii++) + for (ii = 1, Uindex = 1; ii <= UParameters.Length(); ii++) { - while (UParameters->Value(ii) > TrueUIntervals->Value(Uindex + 1) - && Uindex < myUKnots->Length() - 1) + while (UParameters.Value(ii) > TrueUIntervals->Value(Uindex + 1) + && Uindex < myUKnots.Length() - 1) { Uindex++; } - NValue = (UParameters->Value(ii) - TrueUIntervals->Value(Uindex)) + NValue = (UParameters.Value(ii) - TrueUIntervals->Value(Uindex)) / (TrueUIntervals->Value(Uindex + 1) - TrueUIntervals->Value(Uindex)); UValue = (1 - NValue) * PolynomialUIntervals->Value(1) + NValue * PolynomialUIntervals->Value(2); - for (jj = 1, Vindex = 1; jj <= VParameters->Length(); jj++) + for (jj = 1, Vindex = 1; jj <= VParameters.Length(); jj++) { - while (VParameters->Value(jj) > TrueVIntervals->Value(Vindex + 1) - && Vindex < myVKnots->Length() - 1) + while (VParameters.Value(jj) > TrueVIntervals->Value(Vindex + 1) + && Vindex < myVKnots.Length() - 1) { Vindex++; } - NValue = (VParameters->Value(jj) - TrueVIntervals->Value(Vindex)) + NValue = (VParameters.Value(jj) - TrueVIntervals->Value(Vindex)) / (TrueVIntervals->Value(Vindex + 1) - TrueVIntervals->Value(Vindex)); VValue = (1 - NValue) * PolynomialVIntervals->Value(1) + NValue * PolynomialVIntervals->Value(2); // (2.1) Extraction du bon Patch - if (Patch_Indice != Uindex + (myUKnots->Length() - 1) * (Vindex - 1)) + if (Patch_Indice != Uindex + (myUKnots.Length() - 1) * (Vindex - 1)) { int k1, k2, pos, ll = 1; - Patch_Indice = Uindex + (myUKnots->Length() - 1) * (Vindex - 1); + Patch_Indice = Uindex + (myUKnots.Length() - 1) * (Vindex - 1); for (k1 = 1; k1 <= NumCoeffPerSurface->Value(Patch_Indice, 1); k1++) { pos = SizPatch * (Patch_Indice - 1) + 3 * (MaxVDegree + 1) * (k1 - 1) + 1; @@ -227,7 +226,7 @@ void Convert_GridPolynomialToPoles::Perform( Coeffs[0], Digit[0]); - myPoles->SetValue(ii, jj, gp_Pnt(Digit[0], Digit[1], Digit[2])); + myPoles.SetValue(ii, jj, gp_Pnt(Digit[0], Digit[1], Digit[2])); } } @@ -236,121 +235,139 @@ void Convert_GridPolynomialToPoles::Perform( int InversionProblem; BSplSLib::Interpolate(myUDegree, myVDegree, - myUFlatKnots->Array1(), - myVFlatKnots->Array1(), - UParameters->Array1(), - VParameters->Array1(), - myPoles->ChangeArray2(), + myUFlatKnots, + myVFlatKnots, + UParameters, + VParameters, + myPoles, InversionProblem); myDone = (InversionProblem == 0); } -void Convert_GridPolynomialToPoles::BuildArray( - const int Degree, - const occ::handle>& Knots, - const int Continuity, - occ::handle>& FlatKnots, - occ::handle>& Mults, - occ::handle>& Parameters) const +void Convert_GridPolynomialToPoles::BuildArray(const int Degree, + const NCollection_Array1& Knots, + const int Continuity, + NCollection_Array1& FlatKnots, + NCollection_Array1& Mults, + NCollection_Array1& Parameters) const { - int NumCurves = Knots->Length() - 1; + const int NumCurves = Knots.Length() - 1; // Calcul des Multiplicites - int ii; - int multiplicities = Degree - Continuity; - Mults = new (NCollection_HArray1)(1, Knots->Length()); + const int multiplicities = Degree - Continuity; + Mults = NCollection_Array1(1, Knots.Length()); - for (ii = 2; ii < Knots->Length(); ii++) + for (int ii = 2; ii < Knots.Length(); ii++) { - Mults->SetValue(ii, multiplicities); + Mults.SetValue(ii, multiplicities); } - Mults->SetValue(1, Degree + 1); - Mults->SetValue(NumCurves + 1, Degree + 1); + Mults.SetValue(1, Degree + 1); + Mults.SetValue(NumCurves + 1, Degree + 1); // Calcul des Noeuds Plats - int num_flat_knots = multiplicities * (NumCurves - 1) + 2 * Degree + 2; - FlatKnots = new NCollection_HArray1(1, num_flat_knots); + const int num_flat_knots = multiplicities * (NumCurves - 1) + 2 * Degree + 2; + FlatKnots = NCollection_Array1(1, num_flat_knots); - BSplCLib::KnotSequence(Knots->Array1(), - Mults->Array1(), - Degree, - false, - FlatKnots->ChangeArray1()); + BSplCLib::KnotSequence(Knots, Mults, Degree, false, FlatKnots); // Calcul du nombre de Poles - int num_poles = num_flat_knots - Degree - 1; + const int num_poles = num_flat_knots - Degree - 1; // Cacul des parametres d'interpolation - Parameters = new (NCollection_HArray1)(1, num_poles); - BSplCLib::BuildSchoenbergPoints(Degree, FlatKnots->Array1(), Parameters->ChangeArray1()); + Parameters = NCollection_Array1(1, num_poles); + BSplCLib::BuildSchoenbergPoints(Degree, FlatKnots, Parameters); } +//================================================================================================== + int Convert_GridPolynomialToPoles::NbUPoles() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); - return myPoles->ColLength(); + return myPoles.ColLength(); } +//================================================================================================== + int Convert_GridPolynomialToPoles::NbVPoles() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); - return myPoles->RowLength(); + return myPoles.RowLength(); } -const occ::handle>& Convert_GridPolynomialToPoles::Poles() const +//================================================================================================== + +const NCollection_Array2& Convert_GridPolynomialToPoles::Poles() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); return myPoles; } +//================================================================================================== + int Convert_GridPolynomialToPoles::UDegree() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); return myUDegree; } +//================================================================================================== + int Convert_GridPolynomialToPoles::VDegree() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); return myVDegree; } +//================================================================================================== + int Convert_GridPolynomialToPoles::NbUKnots() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); - return myUKnots->Length(); + return myUKnots.Length(); } +//================================================================================================== + int Convert_GridPolynomialToPoles::NbVKnots() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); - return myVKnots->Length(); + return myVKnots.Length(); } -const occ::handle>& Convert_GridPolynomialToPoles::UKnots() const +//================================================================================================== + +const NCollection_Array1& Convert_GridPolynomialToPoles::UKnots() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); return myUKnots; } -const occ::handle>& Convert_GridPolynomialToPoles::VKnots() const +//================================================================================================== + +const NCollection_Array1& Convert_GridPolynomialToPoles::VKnots() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); return myVKnots; } -const occ::handle>& Convert_GridPolynomialToPoles::UMultiplicities() const +//================================================================================================== + +const NCollection_Array1& Convert_GridPolynomialToPoles::UMultiplicities() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); return myUMults; } -const occ::handle>& Convert_GridPolynomialToPoles::VMultiplicities() const +//================================================================================================== + +const NCollection_Array1& Convert_GridPolynomialToPoles::VMultiplicities() const { StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); return myVMults; } +//================================================================================================== + bool Convert_GridPolynomialToPoles::IsDone() const { return myDone; diff --git a/src/FoundationClasses/TKMath/Convert/Convert_GridPolynomialToPoles.hxx b/src/FoundationClasses/TKMath/Convert/Convert_GridPolynomialToPoles.hxx index 6473e03499..4e2fc6b1d3 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_GridPolynomialToPoles.hxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_GridPolynomialToPoles.hxx @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -81,6 +80,43 @@ public: const occ::handle>& TrueUIntervals, const occ::handle>& TrueVIntervals); + //! Returns the number of poles in the U parametric direction. + [[nodiscard]] Standard_EXPORT int NbUPoles() const; + + //! Returns the number of poles in the V parametric direction. + [[nodiscard]] Standard_EXPORT int NbVPoles() const; + + //! Returns the poles of the BSpline Surface. + [[nodiscard]] Standard_EXPORT const NCollection_Array2& Poles() const; + + //! Returns the degree in the U parametric direction. + [[nodiscard]] Standard_EXPORT int UDegree() const; + + //! Returns the degree in the V parametric direction. + [[nodiscard]] Standard_EXPORT int VDegree() const; + + //! Returns the number of knots in the U parametric direction. + [[nodiscard]] Standard_EXPORT int NbUKnots() const; + + //! Returns the number of knots in the V parametric direction. + [[nodiscard]] Standard_EXPORT int NbVKnots() const; + + //! Returns the knots in the U direction. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& UKnots() const; + + //! Returns the knots in the V direction. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& VKnots() const; + + //! Returns the multiplicities of the knots in the U direction. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& UMultiplicities() const; + + //! Returns the multiplicities of the knots in the V direction. + [[nodiscard]] Standard_EXPORT const NCollection_Array1& VMultiplicities() const; + + //! Returns true if the conversion was successful. + [[nodiscard]] Standard_EXPORT bool IsDone() const; + +private: Standard_EXPORT void Perform(const int UContinuity, const int VContinuity, const int MaxUDegree, @@ -92,53 +128,24 @@ public: const occ::handle>& TrueUIntervals, const occ::handle>& TrueVIntervals); - Standard_EXPORT int NbUPoles() const; - - Standard_EXPORT int NbVPoles() const; - - //! returns the poles of the BSpline Surface - Standard_EXPORT const occ::handle>& Poles() const; - - Standard_EXPORT int UDegree() const; - - Standard_EXPORT int VDegree() const; - - Standard_EXPORT int NbUKnots() const; - - Standard_EXPORT int NbVKnots() const; - - //! Knots in the U direction - Standard_EXPORT const occ::handle>& UKnots() const; - - //! Knots in the V direction - Standard_EXPORT const occ::handle>& VKnots() const; - - //! Multiplicities of the knots in the U direction - Standard_EXPORT const occ::handle>& UMultiplicities() const; - - //! Multiplicities of the knots in the V direction - Standard_EXPORT const occ::handle>& VMultiplicities() const; - - Standard_EXPORT bool IsDone() const; + Standard_EXPORT void BuildArray(const int Degree, + const NCollection_Array1& Knots, + const int Continuity, + NCollection_Array1& FlatKnots, + NCollection_Array1& Mults, + NCollection_Array1& Parameters) const; private: - Standard_EXPORT void BuildArray(const int Degree, - const occ::handle>& Knots, - const int Continuty, - occ::handle>& FlatKnots, - occ::handle>& Mults, - occ::handle>& Parameters) const; - - occ::handle> myUFlatKnots; - occ::handle> myVFlatKnots; - occ::handle> myUKnots; - occ::handle> myVKnots; - occ::handle> myUMults; - occ::handle> myVMults; - occ::handle> myPoles; - int myUDegree; - int myVDegree; - bool myDone; + NCollection_Array1 myUFlatKnots; + NCollection_Array1 myVFlatKnots; + NCollection_Array1 myUKnots; + NCollection_Array1 myVKnots; + NCollection_Array1 myUMults; + NCollection_Array1 myVMults; + NCollection_Array2 myPoles; + int myUDegree; + int myVDegree; + bool myDone; }; #endif // _Convert_GridPolynomialToPoles_HeaderFile diff --git a/src/FoundationClasses/TKMath/Convert/Convert_HyperbolaToBSplineCurve.cxx b/src/FoundationClasses/TKMath/Convert/Convert_HyperbolaToBSplineCurve.cxx index d7065b24c3..a39c6c359b 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_HyperbolaToBSplineCurve.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_HyperbolaToBSplineCurve.cxx @@ -18,17 +18,16 @@ #include #include #include -#include #include +#include #include -#include #include -static int TheDegree = 2; -static int MaxNbKnots = 2; -static int MaxNbPoles = 3; +constexpr int TheDegree = 2; +constexpr int MaxNbKnots = 2; +constexpr int MaxNbPoles = 3; -//================================================================================================= +//================================================================================================== Convert_HyperbolaToBSplineCurve::Convert_HyperbolaToBSplineCurve(const gp_Hypr2d& H, const double U1, @@ -36,18 +35,16 @@ Convert_HyperbolaToBSplineCurve::Convert_HyperbolaToBSplineCurve(const gp_Hypr2d : Convert_ConicToBSplineCurve(MaxNbPoles, MaxNbKnots, TheDegree) { - Standard_DomainError_Raise_if(std::abs(U2 - U1) < Epsilon(0.), "Convert_ParabolaToBSplineCurve"); + Standard_DomainError_Raise_if(std::abs(U2 - U1) < Epsilon(0.), "Convert_HyperbolaToBSplineCurve"); double UF = std::min(U1, U2); double UL = std::max(U1, U2); - nbPoles = 3; - nbKnots = 2; - isperiodic = false; - knots->ChangeArray1()(1) = UF; - mults->ChangeArray1()(1) = 3; - knots->ChangeArray1()(2) = UL; - mults->ChangeArray1()(2) = 3; + myIsPeriodic = false; + myKnots(1) = UF; + myMults(1) = 3; + myKnots(2) = UL; + myMults(2) = 3; // construction of hyperbola in the reference xOy. @@ -62,21 +59,21 @@ Convert_HyperbolaToBSplineCurve::Convert_HyperbolaToBSplineCurve(const gp_Hypr2d // at points P(UF), P(UL) // the weight of this pole is equal to : std::cosh((UL-UF)/2) - weights->ChangeArray1()(1) = 1.; - weights->ChangeArray1()(2) = std::cosh((UL - UF) / 2); - weights->ChangeArray1()(3) = 1.; + myWeights(1) = 1.; + myWeights(2) = std::cosh((UL - UF) / 2); + myWeights(3) = 1.; - double delta = std::sinh(UL - UF); - double x = R * (std::sinh(UL) - std::sinh(UF)) / delta; - double y = S * r * (std::cosh(UL) - std::cosh(UF)) / delta; - poles->ChangeArray1()(1) = gp_Pnt2d(R * std::cosh(UF), S * r * std::sinh(UF)); - poles->ChangeArray1()(2) = gp_Pnt2d(x, y); - poles->ChangeArray1()(3) = gp_Pnt2d(R * std::cosh(UL), S * r * std::sinh(UL)); + double delta = std::sinh(UL - UF); + double x = R * (std::sinh(UL) - std::sinh(UF)) / delta; + double y = S * r * (std::cosh(UL) - std::cosh(UF)) / delta; + myPoles(1) = gp_Pnt2d(R * std::cosh(UF), S * r * std::sinh(UF)); + myPoles(2) = gp_Pnt2d(x, y); + myPoles(3) = gp_Pnt2d(R * std::cosh(UL), S * r * std::sinh(UL)); // replace the bspline in the mark of the hyperbola gp_Trsf2d Trsf; Trsf.SetTransformation(H.Axis().XAxis(), gp::OX2d()); - poles->ChangeArray1()(1).Transform(Trsf); - poles->ChangeArray1()(2).Transform(Trsf); - poles->ChangeArray1()(3).Transform(Trsf); + myPoles(1).Transform(Trsf); + myPoles(2).Transform(Trsf); + myPoles(3).Transform(Trsf); } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_ParabolaToBSplineCurve.cxx b/src/FoundationClasses/TKMath/Convert/Convert_ParabolaToBSplineCurve.cxx index aa301e8095..3972a88bd2 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_ParabolaToBSplineCurve.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_ParabolaToBSplineCurve.cxx @@ -18,17 +18,16 @@ #include #include #include -#include #include +#include #include -#include #include -static int TheDegree = 2; -static int MaxNbKnots = 2; -static int MaxNbPoles = 3; +constexpr int TheDegree = 2; +constexpr int MaxNbKnots = 2; +constexpr int MaxNbPoles = 3; -//================================================================================================= +//================================================================================================== Convert_ParabolaToBSplineCurve::Convert_ParabolaToBSplineCurve(const gp_Parab2d& Prb, const double U1, @@ -42,31 +41,29 @@ Convert_ParabolaToBSplineCurve::Convert_ParabolaToBSplineCurve(const gp_Parab2d& double p = Prb.Parameter(); - nbPoles = 3; - nbKnots = 2; - isperiodic = false; - knots->ChangeArray1()(1) = UF; - mults->ChangeArray1()(1) = 3; - knots->ChangeArray1()(2) = UL; - mults->ChangeArray1()(2) = 3; + myIsPeriodic = false; + myKnots(1) = UF; + myMults(1) = 3; + myKnots(2) = UL; + myMults(2) = 3; - weights->ChangeArray1()(1) = 1.; - weights->ChangeArray1()(2) = 1.; - weights->ChangeArray1()(3) = 1.; + myWeights(1) = 1.; + myWeights(2) = 1.; + myWeights(3) = 1.; gp_Dir2d Ox = Prb.Axis().XDirection(); gp_Dir2d Oy = Prb.Axis().YDirection(); double S = (Ox.X() * Oy.Y() - Ox.Y() * Oy.X() > 0.) ? 1 : -1; // poles expressed in the reference mark - poles->ChangeArray1()(1) = gp_Pnt2d((UF * UF) / (2. * p), S * UF); - poles->ChangeArray1()(2) = gp_Pnt2d((UF * UL) / (2. * p), S * (UF + UL) / 2.); - poles->ChangeArray1()(3) = gp_Pnt2d((UL * UL) / (2. * p), S * UL); + myPoles(1) = gp_Pnt2d((UF * UF) / (2. * p), S * UF); + myPoles(2) = gp_Pnt2d((UF * UL) / (2. * p), S * (UF + UL) / 2.); + myPoles(3) = gp_Pnt2d((UL * UL) / (2. * p), S * UL); // replace the bspline in the mark of the parabola gp_Trsf2d Trsf; Trsf.SetTransformation(Prb.Axis().XAxis(), gp::OX2d()); - poles->ChangeArray1()(1).Transform(Trsf); - poles->ChangeArray1()(2).Transform(Trsf); - poles->ChangeArray1()(3).Transform(Trsf); + myPoles(1).Transform(Trsf); + myPoles(2).Transform(Trsf); + myPoles(3).Transform(Trsf); } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_PolynomialCosAndSin.cxx b/src/FoundationClasses/TKMath/Convert/Convert_PolynomialCosAndSin.cxx index b8c07d66b9..1709afc37f 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_PolynomialCosAndSin.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_PolynomialCosAndSin.cxx @@ -20,9 +20,11 @@ #include #include +#include #include #include -#include + +#include static double Locate(const double Angfin, const NCollection_Array1& TPoles, @@ -59,12 +61,12 @@ static double Locate(const double Angfin, return (umin + umax) / 2.; } -void BuildPolynomialCosAndSin(const double UFirst, - const double ULast, - const int num_poles, - occ::handle>& CosNumeratorPtr, - occ::handle>& SinNumeratorPtr, - occ::handle>& DenominatorPtr) +void BuildPolynomialCosAndSin(const double UFirst, + const double ULast, + const int num_poles, + NCollection_Array1& CosNumerator, + NCollection_Array1& SinNumerator, + NCollection_Array1& Denominator) { double Delta, locUFirst, @@ -89,16 +91,14 @@ void BuildPolynomialCosAndSin(const double UFirst, Delta = ULast - UFirst; middle = 0.5e0 * Delta; - // coincide the required bisector of the angular sector with - // axis -Ox definition of the circle in Bezier of degree 7 so that - // parametre 1/2 of Bezier was exactly a point of the bissectrice + // Coincide the required bisector of the angular sector with + // axis -Ox. Definition of the circle in Bezier of degree 7 so that + // parameter 1/2 of Bezier is exactly a point of the bisectrix // of the required angular sector. - // Angle = middle - M_PI; - // - // Circle of radius 1. See Euclid - // + // Bezier control points for a unit circle (degree-7 polynomial approximation). + // Coefficients from Tiller's algorithm for polynomial cos/sin representation. NCollection_Array1 TPoles(1, 8), NewTPoles(1, 8); TPoles(1).SetCoord(1., 0.); TPoles(2).SetCoord(1., 1.013854); @@ -128,12 +128,8 @@ void BuildPolynomialCosAndSin(const double UFirst, trim_min = 1.0e0 - trim_max; // - double knot_array[2]; - int mults_array[2]; - knot_array[0] = 0.0e0; - knot_array[1] = 1.0e0; - mults_array[0] = degree + 1; - mults_array[1] = degree + 1; + std::array knot_array = {0.0e0, 1.0e0}; + std::array mults_array = {degree + 1, degree + 1}; NCollection_Array1 the_knots(knot_array[0], 1, 2), the_new_knots(knot_array[0], 1, 2); NCollection_Array1 the_mults(mults_array[0], 1, 2), the_new_mults(mults_array[0], 1, 2); @@ -178,109 +174,8 @@ void BuildPolynomialCosAndSin(const double UFirst, for (ii = 1; ii <= num_poles; ii++) { - CosNumeratorPtr->SetValue(ii, NewTPoles(ii).X()); - SinNumeratorPtr->SetValue(ii, NewTPoles(ii).Y()); - DenominatorPtr->SetValue(ii, 1.); + CosNumerator(ii) = NewTPoles(ii).X(); + SinNumerator(ii) = NewTPoles(ii).Y(); + Denominator(ii) = 1.; } } - -/* -void BuildHermitePolynomialCosAndSin - (const double UFirst, - const double ULast, - const int num_poles, - occ::handle>& CosNumeratorPtr, - occ::handle>& SinNumeratorPtr, - occ::handle>& DenominatorPtr) -{ - - if (num_poles%2 != 0) { - throw Standard_ConstructionError(); - } - int ii; - int ordre_deriv = num_poles/2; - double ang = ULast - UFirst; - double Cd = std::cos(UFirst); - double Sd = std::sin(UFirst); - double Cf = std::cos(ULast); - double Sf = std::sin(ULast); - - int Degree = num_poles-1; - NCollection_Array1 FlatKnots(1,2*num_poles); - NCollection_Array1 Parameters(1,num_poles); - NCollection_Array1 ContactOrderArray(1,num_poles); - NCollection_Array1 Poles(1,num_poles); - NCollection_Array1 TPoles(1,num_poles); - - for (ii=1; ii<=num_poles; ii++) { - FlatKnots(ii) = 0.; - FlatKnots(ii+num_poles) = 1.; - } - - double coef = 1.; - double xd,yd,xf,yf; - - for (ii=1; ii<=ordre_deriv; ii++) { - Parameters(ii) = 0.; - Parameters(ii+ordre_deriv) = 1.; - - ContactOrderArray(ii) = ContactOrderArray(num_poles-ii+1) = ii-1; - - switch ((ii-1)%4) { - case 0: - { - xd = Cd*coef; - yd = Sd*coef; - xf = Cf*coef; - yf = Sf*coef; - } - break; - case 1: - { - xd = -Sd*coef; - yd = Cd*coef; - xf = -Sf*coef; - yf = Cf*coef; - } - break; - case 2: - { - xd = -Cd*coef; - yd = -Sd*coef; - xf = -Cf*coef; - yf = -Sf*coef; - } - break; - case 3: - { - xd = Sd*coef; - yd = -Cd*coef; - xf = Sf*coef; - yf = -Cf*coef; - } - break; - } - - Poles(ii).SetX(xd); - Poles(ii).SetY(yd); - Poles(num_poles-ii+1).SetX(xf); - Poles(num_poles-ii+1).SetY(yf); - - coef *= ang; - } - - int InversionPb; - BSplCLib::Interpolate(Degree,FlatKnots,Parameters, - ContactOrderArray,Poles,InversionPb); - - if (InversionPb !=0) { - throw Standard_ConstructionError(); - } - for (ii=1; ii<=num_poles; ii++) { - CosNumeratorPtr->SetValue(ii,Poles(ii).X()); - SinNumeratorPtr->SetValue(ii,Poles(ii).Y()); - DenominatorPtr->SetValue(ii,1.); - } - -} -*/ diff --git a/src/FoundationClasses/TKMath/Convert/Convert_PolynomialCosAndSin.hxx b/src/FoundationClasses/TKMath/Convert/Convert_PolynomialCosAndSin.hxx index 1bac72e845..e57d460d22 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_PolynomialCosAndSin.hxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_PolynomialCosAndSin.hxx @@ -18,14 +18,13 @@ #define Convert_PolynomialCosAndSin_HeaderFile #include -#include #include -void BuildPolynomialCosAndSin(const double, - const double, - const int, - occ::handle>&, - occ::handle>&, - occ::handle>&); +void BuildPolynomialCosAndSin(const double theUFirst, + const double theULast, + const int theNumPoles, + NCollection_Array1& theCosNumerator, + NCollection_Array1& theSinNumerator, + NCollection_Array1& theDenominator); #endif diff --git a/src/FoundationClasses/TKMath/Convert/Convert_SphereToBSplineSurface.cxx b/src/FoundationClasses/TKMath/Convert/Convert_SphereToBSplineSurface.cxx index 9e93f27bf4..493c97207c 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_SphereToBSplineSurface.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_SphereToBSplineSurface.cxx @@ -20,6 +20,8 @@ #include #include +#include + namespace { constexpr int TheUDegree = 2; @@ -50,8 +52,8 @@ static void ComputePoles(const double R, int nbVP = 2 * nbVSpans + 1; - double x[MaxNbVPoles]; - double z[MaxNbVPoles]; + std::array x; + std::array z; x[0] = R * std::cos(V1); z[0] = R * std::sin(V1); @@ -106,8 +108,8 @@ Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface(const gp_Sphere& || (V2 > M_PI / 2), "Convert_SphereToBSplineSurface"); - isuperiodic = false; - isvperiodic = false; + myIsUPeriodic = false; + myIsVPeriodic = false; int i, j; // construction of the sphere in the reference mark xOy. @@ -118,29 +120,29 @@ Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface(const gp_Sphere& double AlfaU = deltaU / (nbUSpans * 2); double AlfaV = deltaV / (nbVSpans * 2); - nbUPoles = 2 * nbUSpans + 1; - nbVPoles = 2 * nbVSpans + 1; - nbUKnots = nbUSpans + 1; - nbVKnots = nbVSpans + 1; + myNbUPoles = 2 * nbUSpans + 1; + myNbVPoles = 2 * nbVSpans + 1; + myNbUKnots = nbUSpans + 1; + myNbVKnots = nbVSpans + 1; double R = Sph.Radius(); - ComputePoles(R, U1, U2, V1, V2, poles); + ComputePoles(R, U1, U2, V1, V2, myPoles); - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = U1 + (i - 1) * 2 * AlfaU; - umults(i) = 2; + myUKnots(i) = U1 + (i - 1) * 2 * AlfaU; + myUMults(i) = 2; } - umults(1)++; - umults(nbUKnots)++; - for (i = 1; i <= nbVKnots; i++) + myUMults(1)++; + myUMults(myNbUKnots)++; + for (i = 1; i <= myNbVKnots; i++) { - vknots(i) = V1 + (i - 1) * 2 * AlfaV; - vmults(i) = 2; + myVKnots(i) = V1 + (i - 1) * 2 * AlfaV; + myVMults(i) = 2; } - vmults(1)++; - vmults(nbVKnots)++; + myVMults(1)++; + myVMults(myNbVKnots)++; // Replace the bspline in the reference of the sphere. // and calculate the weight of the bspline. @@ -148,24 +150,25 @@ Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface(const gp_Sphere& gp_Trsf Trsf; Trsf.SetTransformation(Sph.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W1 = std::cos(AlfaU); else W1 = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { if (j % 2 == 0) W2 = std::cos(AlfaV); else W2 = 1.; - weights(i, j) = W1 * W2; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W1 * W2; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } //================================================================================================= @@ -190,68 +193,68 @@ Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface(const gp_Sphere& int i, j; double deltaU, deltaV; - isuperiodic = !UTrim; - isvperiodic = false; + myIsUPeriodic = !UTrim; + myIsVPeriodic = false; double R = Sph.Radius(); double W1, W2, CosU, CosV; - if (isuperiodic) + if (myIsUPeriodic) { - ComputePoles(R, 0., 2. * M_PI, Param1, Param2, poles); + ComputePoles(R, 0., 2. * M_PI, Param1, Param2, myPoles); - nbUPoles = 6; - nbUKnots = 4; + myNbUPoles = 6; + myNbUKnots = 4; deltaV = Param2 - Param1; int nbVSpans = (int)std::trunc(1.2 * deltaV / M_PI) + 1; double AlfaV = deltaV / (nbVSpans * 2); - nbVPoles = 2 * nbVSpans + 1; - nbVKnots = nbVSpans + 1; + myNbVPoles = 2 * nbVSpans + 1; + myNbVKnots = nbVSpans + 1; - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = (i - 1) * 2. * M_PI / 3.; - umults(i) = 2; + myUKnots(i) = (i - 1) * 2. * M_PI / 3.; + myUMults(i) = 2; } - for (i = 1; i <= nbVKnots; i++) + for (i = 1; i <= myNbVKnots; i++) { - vknots(i) = Param1 + (i - 1) * 2 * AlfaV; - vmults(i) = 2; + myVKnots(i) = Param1 + (i - 1) * 2 * AlfaV; + myVMults(i) = 2; } - vmults(1)++; - vmults(nbVKnots)++; + myVMults(1)++; + myVMults(myNbVKnots)++; CosU = 0.5; // = std::cos(pi /3) CosV = std::cos(AlfaV); } else { - ComputePoles(R, Param1, Param2, -M_PI / 2., M_PI / 2., poles); + ComputePoles(R, Param1, Param2, -M_PI / 2., M_PI / 2., myPoles); - nbVPoles = 5; - nbVKnots = 3; + myNbVPoles = 5; + myNbVKnots = 3; deltaU = Param2 - Param1; int nbUSpans = (int)std::trunc(1.2 * deltaU / M_PI) + 1; double AlfaU = deltaU / (nbUSpans * 2); - nbUPoles = 2 * nbUSpans + 1; - nbUKnots = nbUSpans + 1; + myNbUPoles = 2 * nbUSpans + 1; + myNbUKnots = nbUSpans + 1; - vknots(1) = -M_PI / 2.; - vmults(1) = 3; - vknots(2) = 0.; - vmults(2) = 2; - vknots(3) = M_PI / 2.; - vmults(3) = 3; - for (i = 1; i <= nbUKnots; i++) + myVKnots(1) = -M_PI / 2.; + myVMults(1) = 3; + myVKnots(2) = 0.; + myVMults(2) = 2; + myVKnots(3) = M_PI / 2.; + myVMults(3) = 3; + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = Param1 + (i - 1) * 2 * AlfaU; - umults(i) = 2; + myUKnots(i) = Param1 + (i - 1) * 2 * AlfaU; + myUMults(i) = 2; } - umults(1)++; - umults(nbUKnots)++; + myUMults(1)++; + myUMults(myNbUKnots)++; CosV = 0.5; // = std::cos(pi /3) CosU = std::cos(AlfaU); @@ -262,24 +265,25 @@ Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface(const gp_Sphere& gp_Trsf Trsf; Trsf.SetTransformation(Sph.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W1 = CosU; else W1 = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { if (j % 2 == 0) W2 = CosV; else W2 = 1.; - weights(i, j) = W1 * W2; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W1 * W2; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } //================================================================================================= @@ -292,58 +296,59 @@ Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface(const gp_Sphere& TheUDegree, TheVDegree) { - isuperiodic = true; - isvperiodic = false; + myIsUPeriodic = true; + myIsVPeriodic = false; double W1, W2; int i, j; - nbUPoles = 6; - nbVPoles = 5; - nbUKnots = 4; - nbVKnots = 3; + myNbUPoles = 6; + myNbVPoles = 5; + myNbUKnots = 4; + myNbVKnots = 3; // Construction of the sphere in the reference mark xOy. double R = Sph.Radius(); - ComputePoles(R, 0., 2. * M_PI, -M_PI / 2., M_PI / 2., poles); + ComputePoles(R, 0., 2. * M_PI, -M_PI / 2., M_PI / 2., myPoles); - uknots(1) = 0.; - uknots(2) = 2. * M_PI / 3.; - uknots(3) = 4. * M_PI / 3.; - uknots(4) = 2. * M_PI; - vknots(1) = -M_PI / 2.; - vknots(2) = 0.; - vknots(3) = M_PI / 2.; + myUKnots(1) = 0.; + myUKnots(2) = 2. * M_PI / 3.; + myUKnots(3) = 4. * M_PI / 3.; + myUKnots(4) = 2. * M_PI; + myVKnots(1) = -M_PI / 2.; + myVKnots(2) = 0.; + myVKnots(3) = M_PI / 2.; for (i = 1; i <= 4; i++) { - umults(i) = 2; + myUMults(i) = 2; } - vmults(1) = vmults(3) = 3; - vmults(2) = 2; + myVMults(1) = myVMults(3) = 3; + myVMults(2) = 2; // Replace the bspline in the mark of the sphere. // and calculate the weight of the bspline. gp_Trsf Trsf; Trsf.SetTransformation(Sph.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W1 = 0.5; else W1 = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { if (j % 2 == 0) W2 = std::sqrt(2.) / 2.; else W2 = 1.; - weights(i, j) = W1 * W2; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W1 * W2; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } diff --git a/src/FoundationClasses/TKMath/Convert/Convert_TorusToBSplineSurface.cxx b/src/FoundationClasses/TKMath/Convert/Convert_TorusToBSplineSurface.cxx index bdd204f5e7..69bc70290c 100644 --- a/src/FoundationClasses/TKMath/Convert/Convert_TorusToBSplineSurface.cxx +++ b/src/FoundationClasses/TKMath/Convert/Convert_TorusToBSplineSurface.cxx @@ -20,6 +20,8 @@ #include #include +#include + namespace { constexpr int TheUDegree = 2; @@ -51,8 +53,8 @@ static void ComputePoles(const double R, int nbVP = 2 * nbVSpans + 1; - double x[MaxNbVPoles]; - double z[MaxNbVPoles]; + std::array x; + std::array z; x[0] = R + r * std::cos(V1); z[0] = r * std::sin(V1); @@ -107,8 +109,8 @@ Convert_TorusToBSplineSurface::Convert_TorusToBSplineSurface(const gp_Torus& T, || (deltaV < 0.), "Convert_TorusToBSplineSurface"); - isuperiodic = false; - isvperiodic = false; + myIsUPeriodic = false; + myIsVPeriodic = false; int i, j; // construction of the torus in the reference mark xOy. @@ -119,30 +121,30 @@ Convert_TorusToBSplineSurface::Convert_TorusToBSplineSurface(const gp_Torus& T, double AlfaU = deltaU / (nbUSpans * 2); double AlfaV = deltaV / (nbVSpans * 2); - nbUPoles = 2 * nbUSpans + 1; - nbVPoles = 2 * nbVSpans + 1; - nbUKnots = nbUSpans + 1; - nbVKnots = nbVSpans + 1; + myNbUPoles = 2 * nbUSpans + 1; + myNbVPoles = 2 * nbVSpans + 1; + myNbUKnots = nbUSpans + 1; + myNbVKnots = nbVSpans + 1; double R = T.MajorRadius(); double r = T.MinorRadius(); - ComputePoles(R, r, U1, U2, V1, V2, poles); + ComputePoles(R, r, U1, U2, V1, V2, myPoles); - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = U1 + (i - 1) * 2 * AlfaU; - umults(i) = 2; + myUKnots(i) = U1 + (i - 1) * 2 * AlfaU; + myUMults(i) = 2; } - umults(1)++; - umults(nbUKnots)++; - for (i = 1; i <= nbVKnots; i++) + myUMults(1)++; + myUMults(myNbUKnots)++; + for (i = 1; i <= myNbVKnots; i++) { - vknots(i) = V1 + (i - 1) * 2 * AlfaV; - vmults(i) = 2; + myVKnots(i) = V1 + (i - 1) * 2 * AlfaV; + myVMults(i) = 2; } - vmults(1)++; - vmults(nbVKnots)++; + myVMults(1)++; + myVMults(myNbVKnots)++; // Replace the bspline in the reference of the torus. // and calculate the weight of the bspline. @@ -150,24 +152,25 @@ Convert_TorusToBSplineSurface::Convert_TorusToBSplineSurface(const gp_Torus& T, gp_Trsf Trsf; Trsf.SetTransformation(T.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W1 = std::cos(AlfaU); else W1 = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { if (j % 2 == 0) W2 = std::cos(AlfaV); else W2 = 1.; - weights(i, j) = W1 * W2; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W1 * W2; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } //================================================================================================= @@ -192,68 +195,68 @@ Convert_TorusToBSplineSurface::Convert_TorusToBSplineSurface(const gp_Torus& T, int i, j; double deltaU, deltaV; - isuperiodic = !UTrim; - isvperiodic = UTrim; + myIsUPeriodic = !UTrim; + myIsVPeriodic = UTrim; double R = T.MajorRadius(); double r = T.MinorRadius(); double W1, W2, CosU, CosV; - if (isuperiodic) + if (myIsUPeriodic) { - ComputePoles(R, r, 0, 2. * M_PI, Param1, Param2, poles); + ComputePoles(R, r, 0, 2. * M_PI, Param1, Param2, myPoles); - nbUPoles = 6; - nbUKnots = 4; + myNbUPoles = 6; + myNbUKnots = 4; deltaV = Param2 - Param1; int nbVSpans = (int)std::trunc(1.2 * deltaV / M_PI) + 1; double AlfaV = deltaV / (nbVSpans * 2); - nbVPoles = 2 * nbVSpans + 1; - nbVKnots = nbVSpans + 1; + myNbVPoles = 2 * nbVSpans + 1; + myNbVKnots = nbVSpans + 1; - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = (i - 1) * 2. * M_PI / 3.; - umults(i) = 2; + myUKnots(i) = (i - 1) * 2. * M_PI / 3.; + myUMults(i) = 2; } - for (i = 1; i <= nbVKnots; i++) + for (i = 1; i <= myNbVKnots; i++) { - vknots(i) = Param1 + (i - 1) * 2 * AlfaV; - vmults(i) = 2; + myVKnots(i) = Param1 + (i - 1) * 2 * AlfaV; + myVMults(i) = 2; } - vmults(1)++; - vmults(nbVKnots)++; + myVMults(1)++; + myVMults(myNbVKnots)++; CosU = 0.5; // = std::cos(pi /3) CosV = std::cos(AlfaV); } else { - ComputePoles(R, r, Param1, Param2, 0., 2. * M_PI, poles); + ComputePoles(R, r, Param1, Param2, 0., 2. * M_PI, myPoles); - nbVPoles = 6; - nbVKnots = 4; + myNbVPoles = 6; + myNbVKnots = 4; deltaU = Param2 - Param1; int nbUSpans = (int)std::trunc(1.2 * deltaU / M_PI) + 1; double AlfaU = deltaU / (nbUSpans * 2); - nbUPoles = 2 * nbUSpans + 1; - nbUKnots = nbUSpans + 1; + myNbUPoles = 2 * nbUSpans + 1; + myNbUKnots = nbUSpans + 1; - for (i = 1; i <= nbVKnots; i++) + for (i = 1; i <= myNbVKnots; i++) { - vknots(i) = (i - 1) * 2. * M_PI / 3.; - vmults(i) = 2; + myVKnots(i) = (i - 1) * 2. * M_PI / 3.; + myVMults(i) = 2; } - for (i = 1; i <= nbUKnots; i++) + for (i = 1; i <= myNbUKnots; i++) { - uknots(i) = Param1 + (i - 1) * 2 * AlfaU; - umults(i) = 2; + myUKnots(i) = Param1 + (i - 1) * 2 * AlfaU; + myUMults(i) = 2; } - umults(1)++; - umults(nbUKnots)++; + myUMults(1)++; + myUMults(myNbUKnots)++; CosV = 0.5; // = std::cos(pi /3) CosU = std::cos(AlfaU); @@ -264,24 +267,25 @@ Convert_TorusToBSplineSurface::Convert_TorusToBSplineSurface(const gp_Torus& T, gp_Trsf Trsf; Trsf.SetTransformation(T.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W1 = CosU; else W1 = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { if (j % 2 == 0) W2 = CosV; else W2 = 1.; - weights(i, j) = W1 * W2; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W1 * W2; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } //================================================================================================= @@ -294,31 +298,31 @@ Convert_TorusToBSplineSurface::Convert_TorusToBSplineSurface(const gp_Torus& T) TheUDegree, TheVDegree) { - isuperiodic = true; - isvperiodic = true; + myIsUPeriodic = true; + myIsVPeriodic = true; double W1, W2; int i, j; - nbUPoles = 6; - nbVPoles = 6; - nbUKnots = 4; - nbVKnots = 4; + myNbUPoles = 6; + myNbVPoles = 6; + myNbUKnots = 4; + myNbVKnots = 4; // Construction of the Torus in the reference mark xOy. double R = T.MajorRadius(); double r = T.MinorRadius(); - ComputePoles(R, r, 0., 2. * M_PI, 0., 2. * M_PI, poles); + ComputePoles(R, r, 0., 2. * M_PI, 0., 2. * M_PI, myPoles); - uknots(1) = vknots(1) = 0.; - uknots(2) = vknots(2) = 2. * M_PI / 3.; - uknots(3) = vknots(3) = 4. * M_PI / 3.; - uknots(4) = vknots(4) = 2. * M_PI; + myUKnots(1) = myVKnots(1) = 0.; + myUKnots(2) = myVKnots(2) = 2. * M_PI / 3.; + myUKnots(3) = myVKnots(3) = 4. * M_PI / 3.; + myUKnots(4) = myVKnots(4) = 2. * M_PI; for (i = 1; i <= 4; i++) { - umults(i) = vmults(i) = 2; + myUMults(i) = myVMults(i) = 2; } // Replace the bspline in the mark of the torus. @@ -326,22 +330,23 @@ Convert_TorusToBSplineSurface::Convert_TorusToBSplineSurface(const gp_Torus& T) gp_Trsf Trsf; Trsf.SetTransformation(T.Position(), gp::XOY()); - for (i = 1; i <= nbUPoles; i++) + for (i = 1; i <= myNbUPoles; i++) { if (i % 2 == 0) W1 = 0.5; else W1 = 1.; - for (j = 1; j <= nbVPoles; j++) + for (j = 1; j <= myNbVPoles; j++) { if (j % 2 == 0) W2 = 0.5; else W2 = 1.; - weights(i, j) = W1 * W2; - poles(i, j).Transform(Trsf); + myWeights(i, j) = W1 * W2; + myPoles(i, j).Transform(Trsf); } } + Finalize(); } diff --git a/src/FoundationClasses/TKMath/Convert/FILES.cmake b/src/FoundationClasses/TKMath/Convert/FILES.cmake index b4911d5b35..f7651cf4fd 100644 --- a/src/FoundationClasses/TKMath/Convert/FILES.cmake +++ b/src/FoundationClasses/TKMath/Convert/FILES.cmake @@ -8,6 +8,7 @@ set(OCCT_Convert_FILES Convert_CompBezierCurves2dToBSplineCurve2d.hxx Convert_CompBezierCurvesToBSplineCurve.cxx Convert_CompBezierCurvesToBSplineCurve.hxx + Convert_CompBezierCurvesToBSplineCurveBase.hxx Convert_CompPolynomialToPoles.cxx Convert_CompPolynomialToPoles.hxx Convert_ConeToBSplineSurface.cxx diff --git a/src/FoundationClasses/TKMath/GTests/Convert_CircleToBSplineCurve_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_CircleToBSplineCurve_Test.cxx new file mode 100644 index 0000000000..adf4fb0824 --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_CircleToBSplineCurve_Test.cxx @@ -0,0 +1,163 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include + +TEST(Convert_CircleToBSplineCurveTest, FullCircle_TgtThetaOver2) +{ + const gp_Circ2d aCirc(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 5.0); + const Convert_CircleToBSplineCurve aConv(aCirc, Convert_TgtThetaOver2); + + EXPECT_EQ(aConv.Degree(), 2); + EXPECT_TRUE(aConv.IsPeriodic()); + EXPECT_GT(aConv.NbPoles(), 0); + EXPECT_GT(aConv.NbKnots(), 0); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } +} + +TEST(Convert_CircleToBSplineCurveTest, FullCircle_RationalC1) +{ + const gp_Circ2d aCirc(gp_Ax2d(gp_Pnt2d(1.0, 2.0), gp_Dir2d(1.0, 0.0)), 3.0); + const Convert_CircleToBSplineCurve aConv(aCirc, Convert_RationalC1); + + EXPECT_TRUE(aConv.IsPeriodic()); + EXPECT_GT(aConv.NbPoles(), 0); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } +} + +TEST(Convert_CircleToBSplineCurveTest, Arc_TgtThetaOver2) +{ + const gp_Circ2d aCirc(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 1.0); + const double aU1 = M_PI / 6.0; + const double aU2 = 5.0 * M_PI / 3.0; + const Convert_CircleToBSplineCurve aConv(aCirc, aU1, aU2, Convert_TgtThetaOver2); + + EXPECT_FALSE(aConv.IsPeriodic()); + EXPECT_EQ(aConv.Degree(), 2); + EXPECT_GT(aConv.NbPoles(), 0); + + // Verify first pole matches conic point at U1 + const NCollection_Array1& aPoles = aConv.Poles(); + const double aR = aCirc.Radius(); + const gp_Pnt2d aCenter = aCirc.Location(); + const gp_Dir2d aXDir = aCirc.XAxis().Direction(); + const gp_Dir2d aYDir = aCirc.YAxis().Direction(); + + const double aFirstX = aCenter.X() + aR * (std::cos(aU1) * aXDir.X() + std::sin(aU1) * aYDir.X()); + const double aFirstY = aCenter.Y() + aR * (std::cos(aU1) * aXDir.Y() + std::sin(aU1) * aYDir.Y()); + EXPECT_NEAR(aPoles(1).X(), aFirstX, 1.0e-10); + EXPECT_NEAR(aPoles(1).Y(), aFirstY, 1.0e-10); + + // Verify last pole matches conic point at U2 + const double aLastX = aCenter.X() + aR * (std::cos(aU2) * aXDir.X() + std::sin(aU2) * aYDir.X()); + const double aLastY = aCenter.Y() + aR * (std::cos(aU2) * aXDir.Y() + std::sin(aU2) * aYDir.Y()); + EXPECT_NEAR(aPoles(aConv.NbPoles()).X(), aLastX, 1.0e-10); + EXPECT_NEAR(aPoles(aConv.NbPoles()).Y(), aLastY, 1.0e-10); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } +} + +TEST(Convert_CircleToBSplineCurveTest, Arc_QuasiAngular) +{ + const gp_Circ2d aCirc(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 2.0); + const double aU1 = 0.0; + const double aU2 = M_PI; + const Convert_CircleToBSplineCurve aConv(aCirc, aU1, aU2, Convert_QuasiAngular); + + EXPECT_FALSE(aConv.IsPeriodic()); + EXPECT_EQ(aConv.Degree(), 6); + EXPECT_GT(aConv.NbPoles(), 0); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } +} + +TEST(Convert_CircleToBSplineCurveTest, Arc_Polynomial) +{ + const gp_Circ2d aCirc(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 1.0); + const double aU1 = 0.0; + const double aU2 = M_PI * 0.5; + const Convert_CircleToBSplineCurve aConv(aCirc, aU1, aU2, Convert_Polynomial); + + EXPECT_FALSE(aConv.IsPeriodic()); + EXPECT_EQ(aConv.Degree(), 7); + EXPECT_EQ(aConv.NbPoles(), 8); +} + +TEST(Convert_CircleToBSplineCurveTest, WeightsArePositive) +{ + const gp_Circ2d aCirc(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 1.0); + const Convert_CircleToBSplineCurve aConv(aCirc, Convert_TgtThetaOver2); + + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0); + } +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_CompBezierCurvesToBSplineCurve_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_CompBezierCurvesToBSplineCurve_Test.cxx new file mode 100644 index 0000000000..bc3402f9f7 --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_CompBezierCurvesToBSplineCurve_Test.cxx @@ -0,0 +1,197 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include + +TEST(Convert_CompBezierCurvesToBSplineCurveTest, SingleLinearBezier) +{ + Convert_CompBezierCurvesToBSplineCurve aConv; + + NCollection_Array1 aPoles(1, 2); + aPoles(1) = gp_Pnt(0.0, 0.0, 0.0); + aPoles(2) = gp_Pnt(1.0, 1.0, 0.0); + + aConv.AddCurve(aPoles); + aConv.Perform(); + + EXPECT_GE(aConv.Degree(), 1); + EXPECT_EQ(aConv.NbPoles(), 2); + EXPECT_EQ(aConv.NbKnots(), 2); + + NCollection_Array1 aResPoles(1, aConv.NbPoles()); + aConv.Poles(aResPoles); + EXPECT_NEAR(aResPoles(1).X(), 0.0, 1.0e-15); + EXPECT_NEAR(aResPoles(2).X(), 1.0, 1.0e-15); +} + +TEST(Convert_CompBezierCurvesToBSplineCurveTest, SingleCubicBezier) +{ + Convert_CompBezierCurvesToBSplineCurve aConv; + + NCollection_Array1 aPoles(1, 4); + aPoles(1) = gp_Pnt(0.0, 0.0, 0.0); + aPoles(2) = gp_Pnt(1.0, 2.0, 0.0); + aPoles(3) = gp_Pnt(3.0, 2.0, 0.0); + aPoles(4) = gp_Pnt(4.0, 0.0, 0.0); + + aConv.AddCurve(aPoles); + aConv.Perform(); + + EXPECT_EQ(aConv.Degree(), 3); + EXPECT_EQ(aConv.NbPoles(), 4); + EXPECT_EQ(aConv.NbKnots(), 2); +} + +TEST(Convert_CompBezierCurvesToBSplineCurveTest, TwoAdjacentBeziers_C0) +{ + Convert_CompBezierCurvesToBSplineCurve aConv; + + // First linear segment + NCollection_Array1 aPoles1(1, 2); + aPoles1(1) = gp_Pnt(0.0, 0.0, 0.0); + aPoles1(2) = gp_Pnt(1.0, 1.0, 0.0); + + // Second linear segment, adjacent but not tangent + NCollection_Array1 aPoles2(1, 2); + aPoles2(1) = gp_Pnt(1.0, 1.0, 0.0); + aPoles2(2) = gp_Pnt(2.0, 0.0, 0.0); + + aConv.AddCurve(aPoles1); + aConv.AddCurve(aPoles2); + aConv.Perform(); + + EXPECT_GE(aConv.Degree(), 1); + EXPECT_EQ(aConv.NbKnots(), 3); + + NCollection_Array1 aResPoles(1, aConv.NbPoles()); + NCollection_Array1 aKnots(1, aConv.NbKnots()); + NCollection_Array1 aMults(1, aConv.NbKnots()); + aConv.Poles(aResPoles); + aConv.KnotsAndMults(aKnots, aMults); + + // First and last knot multiplicities should be degree+1 + EXPECT_EQ(aMults(1), aConv.Degree() + 1); + EXPECT_EQ(aMults(aConv.NbKnots()), aConv.Degree() + 1); +} + +TEST(Convert_CompBezierCurvesToBSplineCurveTest, TwoAdjacentBeziers_C1) +{ + Convert_CompBezierCurvesToBSplineCurve aConv; + + // Two cubic Beziers with parallel tangent at junction + NCollection_Array1 aPoles1(1, 4); + aPoles1(1) = gp_Pnt(0.0, 0.0, 0.0); + aPoles1(2) = gp_Pnt(1.0, 1.0, 0.0); + aPoles1(3) = gp_Pnt(2.0, 1.0, 0.0); + aPoles1(4) = gp_Pnt(3.0, 0.0, 0.0); + + NCollection_Array1 aPoles2(1, 4); + aPoles2(1) = gp_Pnt(3.0, 0.0, 0.0); + aPoles2(2) = gp_Pnt(4.0, -1.0, 0.0); + aPoles2(3) = gp_Pnt(5.0, -1.0, 0.0); + aPoles2(4) = gp_Pnt(6.0, 0.0, 0.0); + + aConv.AddCurve(aPoles1); + aConv.AddCurve(aPoles2); + aConv.Perform(); + + EXPECT_EQ(aConv.Degree(), 3); + EXPECT_EQ(aConv.NbKnots(), 3); + + // Check that junction has multiplicity Degree-1 (C1) + NCollection_Array1 aMults(1, aConv.NbKnots()); + NCollection_Array1 aKnots(1, aConv.NbKnots()); + aConv.KnotsAndMults(aKnots, aMults); + EXPECT_EQ(aMults(2), aConv.Degree() - 1); +} + +TEST(Convert_CompBezierCurvesToBSplineCurveTest, MixedDegreeBeziers) +{ + Convert_CompBezierCurvesToBSplineCurve aConv; + + // Linear segment + NCollection_Array1 aPoles1(1, 2); + aPoles1(1) = gp_Pnt(0.0, 0.0, 0.0); + aPoles1(2) = gp_Pnt(1.0, 0.0, 0.0); + + // Cubic segment + NCollection_Array1 aPoles2(1, 4); + aPoles2(1) = gp_Pnt(1.0, 0.0, 0.0); + aPoles2(2) = gp_Pnt(2.0, 1.0, 0.0); + aPoles2(3) = gp_Pnt(3.0, 1.0, 0.0); + aPoles2(4) = gp_Pnt(4.0, 0.0, 0.0); + + aConv.AddCurve(aPoles1); + aConv.AddCurve(aPoles2); + aConv.Perform(); + + // Degree should be raised to the maximum + EXPECT_EQ(aConv.Degree(), 3); +} + +// 2D variant tests +TEST(Convert_CompBezierCurves2dToBSplineCurve2dTest, SingleLinear2d) +{ + Convert_CompBezierCurves2dToBSplineCurve2d aConv; + + NCollection_Array1 aPoles(1, 2); + aPoles(1) = gp_Pnt2d(0.0, 0.0); + aPoles(2) = gp_Pnt2d(1.0, 1.0); + + aConv.AddCurve(aPoles); + aConv.Perform(); + + EXPECT_GE(aConv.Degree(), 1); + EXPECT_EQ(aConv.NbPoles(), 2); + EXPECT_EQ(aConv.NbKnots(), 2); + + NCollection_Array1 aResPoles(1, aConv.NbPoles()); + aConv.Poles(aResPoles); + EXPECT_NEAR(aResPoles(1).X(), 0.0, 1.0e-15); + EXPECT_NEAR(aResPoles(2).X(), 1.0, 1.0e-15); +} + +TEST(Convert_CompBezierCurves2dToBSplineCurve2dTest, TwoAdjacent2d_C1) +{ + Convert_CompBezierCurves2dToBSplineCurve2d aConv; + + NCollection_Array1 aPoles1(1, 4); + aPoles1(1) = gp_Pnt2d(0.0, 0.0); + aPoles1(2) = gp_Pnt2d(1.0, 1.0); + aPoles1(3) = gp_Pnt2d(2.0, 1.0); + aPoles1(4) = gp_Pnt2d(3.0, 0.0); + + NCollection_Array1 aPoles2(1, 4); + aPoles2(1) = gp_Pnt2d(3.0, 0.0); + aPoles2(2) = gp_Pnt2d(4.0, -1.0); + aPoles2(3) = gp_Pnt2d(5.0, -1.0); + aPoles2(4) = gp_Pnt2d(6.0, 0.0); + + aConv.AddCurve(aPoles1); + aConv.AddCurve(aPoles2); + aConv.Perform(); + + EXPECT_EQ(aConv.Degree(), 3); + EXPECT_EQ(aConv.NbKnots(), 3); + + NCollection_Array1 aMults(1, aConv.NbKnots()); + NCollection_Array1 aKnots(1, aConv.NbKnots()); + aConv.KnotsAndMults(aKnots, aMults); + EXPECT_EQ(aMults(2), aConv.Degree() - 1); +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_CompPolynomialToPoles_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_CompPolynomialToPoles_Test.cxx new file mode 100644 index 0000000000..c449505a81 --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_CompPolynomialToPoles_Test.cxx @@ -0,0 +1,153 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include + +TEST(Convert_CompPolynomialToPolesTest, SingleLinearPolynomial) +{ + // Convert f(x) = 2*x + 1 on [-1,1] to BSpline + // Polynomial domain [-1,1], True interval [-1,1] + const int aDim = 1; + const int aMaxDeg = 1; + const int aDeg = 1; + + NCollection_Array1 aCoeffs(1, 2); + aCoeffs(1) = 1.0; // constant term + aCoeffs(2) = 2.0; // linear term + + NCollection_Array1 aPolyIntervals(1, 2); + aPolyIntervals(1) = -1.0; + aPolyIntervals(2) = 1.0; + + NCollection_Array1 aTrueIntervals(1, 2); + aTrueIntervals(1) = -1.0; + aTrueIntervals(2) = 1.0; + + Convert_CompPolynomialToPoles aConv(aDim, aMaxDeg, aDeg, aCoeffs, aPolyIntervals, aTrueIntervals); + + EXPECT_TRUE(aConv.IsDone()); + EXPECT_EQ(aConv.Degree(), 1); + EXPECT_EQ(aConv.NbKnots(), 2); + EXPECT_GT(aConv.NbPoles(), 0); +} + +TEST(Convert_CompPolynomialToPolesTest, SingleQuadraticPolynomial) +{ + // Convert f(x) = x^2 on [0,1] to BSpline + const int aDim = 1; + const int aMaxDeg = 2; + const int aDeg = 2; + + NCollection_Array1 aCoeffs(1, 3); + aCoeffs(1) = 0.0; // x^0 + aCoeffs(2) = 0.0; // x^1 + aCoeffs(3) = 1.0; // x^2 + + NCollection_Array1 aPolyIntervals(1, 2); + aPolyIntervals(1) = 0.0; + aPolyIntervals(2) = 1.0; + + NCollection_Array1 aTrueIntervals(1, 2); + aTrueIntervals(1) = 0.0; + aTrueIntervals(2) = 1.0; + + Convert_CompPolynomialToPoles aConv(aDim, aMaxDeg, aDeg, aCoeffs, aPolyIntervals, aTrueIntervals); + + EXPECT_TRUE(aConv.IsDone()); + EXPECT_EQ(aConv.Degree(), 2); +} + +TEST(Convert_CompPolynomialToPolesTest, TwoSpansUniformContinuity) +{ + // Two linear polynomials with C0 continuity + const int aNumCurves = 2; + const int aContinuity = 0; + const int aDim = 1; + const int aMaxDeg = 1; + + occ::handle> aNumCoeff = new NCollection_HArray1(1, 2); + aNumCoeff->SetValue(1, 2); // linear = 2 coefficients + aNumCoeff->SetValue(2, 2); + + // Coefficients: [curve1: c0, c1] [curve2: c0, c1] + occ::handle> aCoeffs = new NCollection_HArray1(1, 4); + aCoeffs->SetValue(1, 0.0); + aCoeffs->SetValue(2, 1.0); + aCoeffs->SetValue(3, 1.0); + aCoeffs->SetValue(4, -1.0); + + occ::handle> aPolyIntervals = + new NCollection_HArray2(1, 2, 1, 2); + aPolyIntervals->SetValue(1, 1, 0.0); + aPolyIntervals->SetValue(1, 2, 1.0); + aPolyIntervals->SetValue(2, 1, 0.0); + aPolyIntervals->SetValue(2, 2, 1.0); + + occ::handle> aTrueIntervals = new NCollection_HArray1(1, 3); + aTrueIntervals->SetValue(1, 0.0); + aTrueIntervals->SetValue(2, 0.5); + aTrueIntervals->SetValue(3, 1.0); + + Convert_CompPolynomialToPoles aConv(aNumCurves, + aContinuity, + aDim, + aMaxDeg, + aNumCoeff, + aCoeffs, + aPolyIntervals, + aTrueIntervals); + + EXPECT_TRUE(aConv.IsDone()); + EXPECT_EQ(aConv.Degree(), 1); + EXPECT_EQ(aConv.NbKnots(), 3); +} + +TEST(Convert_CompPolynomialToPolesTest, ThreeDimensional) +{ + // 3D linear curve + const int aDim = 3; + const int aMaxDeg = 1; + const int aDeg = 1; + + // Coefficients for 3D: [x0, y0, z0, x1, y1, z1] + NCollection_Array1 aCoeffs(1, 6); + aCoeffs(1) = 0.0; + aCoeffs(2) = 0.0; + aCoeffs(3) = 0.0; // constant + aCoeffs(4) = 1.0; + aCoeffs(5) = 2.0; + aCoeffs(6) = 3.0; // linear + + NCollection_Array1 aPolyIntervals(1, 2); + aPolyIntervals(1) = 0.0; + aPolyIntervals(2) = 1.0; + + NCollection_Array1 aTrueIntervals(1, 2); + aTrueIntervals(1) = 0.0; + aTrueIntervals(2) = 1.0; + + Convert_CompPolynomialToPoles aConv(aDim, aMaxDeg, aDeg, aCoeffs, aPolyIntervals, aTrueIntervals); + + EXPECT_TRUE(aConv.IsDone()); + EXPECT_EQ(aConv.Degree(), 1); + + const NCollection_Array2& aPoles = aConv.Poles(); + // Poles should be [1..NbPoles][1..3] + EXPECT_EQ(aPoles.RowLength(), 3); +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_ConeToBSplineSurface_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_ConeToBSplineSurface_Test.cxx new file mode 100644 index 0000000000..1f7c9f4df0 --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_ConeToBSplineSurface_Test.cxx @@ -0,0 +1,112 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include +#include + +TEST(Convert_ConeToBSplineSurfaceTest, FullCone) +{ + const gp_Cone aCone(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), M_PI / 6.0, 3.0); + const Convert_ConeToBSplineSurface aConv(aCone, 0.0, 10.0); + + EXPECT_EQ(aConv.UDegree(), 2); + EXPECT_EQ(aConv.VDegree(), 1); + EXPECT_TRUE(aConv.IsUPeriodic()); + EXPECT_FALSE(aConv.IsVPeriodic()); + EXPECT_GT(aConv.NbUPoles(), 0); + EXPECT_GT(aConv.NbVPoles(), 0); +} + +TEST(Convert_ConeToBSplineSurfaceTest, TrimmedCone) +{ + const gp_Cone aCone(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), M_PI / 4.0, 2.0); + const double aU1 = 0.0, aU2 = M_PI; + const double aV1 = 0.0, aV2 = 5.0; + const Convert_ConeToBSplineSurface aConv(aCone, aU1, aU2, aV1, aV2); + + EXPECT_FALSE(aConv.IsUPeriodic()); + EXPECT_FALSE(aConv.IsVPeriodic()); +} + +TEST(Convert_ConeToBSplineSurfaceTest, WeightsArePositive) +{ + const gp_Cone aCone(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), M_PI / 6.0, 1.0); + const Convert_ConeToBSplineSurface aConv(aCone, 0.0, 5.0); + + const NCollection_Array2& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbUPoles(); ++i) + { + for (int j = 1; j <= aConv.NbVPoles(); ++j) + { + EXPECT_GT(aWeights(i, j), 0.0); + } + } +} + +TEST(Convert_ConeToBSplineSurfaceTest, GeometricVerification) +{ + const double aSemiAngle = M_PI / 6.0; + const double aRadius = 3.0; + const gp_Ax3 anAx3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)); + const gp_Cone aCone(anAx3, aSemiAngle, aRadius); + const Convert_ConeToBSplineSurface aConv(aCone, 0.0, M_PI, 0.0, 10.0); + + const double aTol = 1.0e-10; + const NCollection_Array1& aUK = aConv.UKnots(); + const NCollection_Array1& aVK = aConv.VKnots(); + const double aUMin = aUK(aUK.Lower()), aUMax = aUK(aUK.Upper()); + const double aVMin = aVK(aVK.Lower()), aVMax = aVK(aVK.Upper()); + + for (int i = 0; i <= 4; ++i) + { + const double aU = aUMin + i * (aUMax - aUMin) / 4.0; + for (int j = 0; j <= 4; ++j) + { + const double aV = aVMin + j * (aVMax - aVMin) / 4.0; + + gp_Pnt aPnt; + BSplSLib::D0(aU, + aV, + 0, + 0, + aConv.Poles(), + &aConv.Weights(), + aConv.UKnots(), + aConv.VKnots(), + &aConv.UMultiplicities(), + &aConv.VMultiplicities(), + aConv.UDegree(), + aConv.VDegree(), + true, + false, + false, + false, + aPnt); + + // Verify the point lies on the cone: + // For a cone with axis Z, semi-angle a, reference radius R: + // r(z) = R + z * tan(a), distance from axis = r + const double aDistFromAxis = std::sqrt(aPnt.X() * aPnt.X() + aPnt.Y() * aPnt.Y()); + const double aExpectedR = aRadius + aPnt.Z() * std::tan(aSemiAngle); + EXPECT_NEAR(aDistFromAxis, aExpectedR, aTol) + << "Point not on cone at U=" << aU << " V=" << aV; + } + } +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_CylinderToBSplineSurface_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_CylinderToBSplineSurface_Test.cxx new file mode 100644 index 0000000000..91f6c7591b --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_CylinderToBSplineSurface_Test.cxx @@ -0,0 +1,132 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include +#include + +TEST(Convert_CylinderToBSplineSurfaceTest, FullCylinder) +{ + const gp_Cylinder aCyl(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 3.0); + const Convert_CylinderToBSplineSurface aConv(aCyl, 0.0, 10.0); + + EXPECT_EQ(aConv.UDegree(), 2); + EXPECT_EQ(aConv.VDegree(), 1); + EXPECT_TRUE(aConv.IsUPeriodic()); + EXPECT_FALSE(aConv.IsVPeriodic()); + EXPECT_GT(aConv.NbUPoles(), 0); + EXPECT_GT(aConv.NbVPoles(), 0); +} + +TEST(Convert_CylinderToBSplineSurfaceTest, TrimmedCylinder) +{ + const gp_Cylinder aCyl(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 2.0); + const double aU1 = 0.0, aU2 = M_PI; + const double aV1 = -5.0, aV2 = 5.0; + const Convert_CylinderToBSplineSurface aConv(aCyl, aU1, aU2, aV1, aV2); + + EXPECT_FALSE(aConv.IsUPeriodic()); + EXPECT_FALSE(aConv.IsVPeriodic()); + EXPECT_GT(aConv.NbUPoles(), 0); + EXPECT_GT(aConv.NbVPoles(), 0); +} + +TEST(Convert_CylinderToBSplineSurfaceTest, WeightsArePositive) +{ + const gp_Cylinder aCyl(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 1.0); + const Convert_CylinderToBSplineSurface aConv(aCyl, 0.0, 1.0); + + const NCollection_Array2& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbUPoles(); ++i) + { + for (int j = 1; j <= aConv.NbVPoles(); ++j) + { + EXPECT_GT(aWeights(i, j), 0.0); + } + } +} + +TEST(Convert_CylinderToBSplineSurfaceTest, KnotsAreMonotonic) +{ + const gp_Cylinder aCyl(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 1.0); + const Convert_CylinderToBSplineSurface aConv(aCyl, 0.0, 1.0); + + const NCollection_Array1& aUKnots = aConv.UKnots(); + for (int i = 2; i <= aConv.NbUKnots(); ++i) + { + EXPECT_GT(aUKnots(i), aUKnots(i - 1)); + } + const NCollection_Array1& aVKnots = aConv.VKnots(); + for (int i = 2; i <= aConv.NbVKnots(); ++i) + { + EXPECT_GT(aVKnots(i), aVKnots(i - 1)); + } +} + +TEST(Convert_CylinderToBSplineSurfaceTest, GeometricVerification) +{ + const double aRadius = 3.0; + const double aV1 = -5.0, aV2 = 5.0; + const gp_Ax3 anAx3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)); + const gp_Cylinder aCyl(anAx3, aRadius); + const Convert_CylinderToBSplineSurface aConv(aCyl, 0.0, M_PI, aV1, aV2); + + const double aTol = 1.0e-10; + // Sample 5x5 grid of BSpline parameters within the domain + const NCollection_Array1& aUK = aConv.UKnots(); + const NCollection_Array1& aVK = aConv.VKnots(); + const double aUMin = aUK(aUK.Lower()), aUMax = aUK(aUK.Upper()); + const double aVMin = aVK(aVK.Lower()), aVMax = aVK(aVK.Upper()); + + for (int i = 0; i <= 4; ++i) + { + const double aU = aUMin + i * (aUMax - aUMin) / 4.0; + for (int j = 0; j <= 4; ++j) + { + const double aV = aVMin + j * (aVMax - aVMin) / 4.0; + + gp_Pnt aPnt; + BSplSLib::D0(aU, + aV, + 0, + 0, + aConv.Poles(), + &aConv.Weights(), + aConv.UKnots(), + aConv.VKnots(), + &aConv.UMultiplicities(), + &aConv.VMultiplicities(), + aConv.UDegree(), + aConv.VDegree(), + true, + false, + false, + false, + aPnt); + + // Verify the point lies on the cylinder: distance from Z axis = R + const double aDistFromAxis = std::sqrt(aPnt.X() * aPnt.X() + aPnt.Y() * aPnt.Y()); + EXPECT_NEAR(aDistFromAxis, aRadius, aTol) + << "Point not on cylinder at U=" << aU << " V=" << aV; + // Verify Z is within the V range + EXPECT_GE(aPnt.Z(), aV1 - aTol); + EXPECT_LE(aPnt.Z(), aV2 + aTol); + } + } +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_EllipseToBSplineCurve_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_EllipseToBSplineCurve_Test.cxx new file mode 100644 index 0000000000..d97622c36f --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_EllipseToBSplineCurve_Test.cxx @@ -0,0 +1,139 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include + +TEST(Convert_EllipseToBSplineCurveTest, FullEllipse_TgtThetaOver2) +{ + const gp_Elips2d anElips(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 5.0, 3.0); + const Convert_EllipseToBSplineCurve aConv(anElips, Convert_TgtThetaOver2); + + EXPECT_TRUE(aConv.IsPeriodic()); + EXPECT_EQ(aConv.Degree(), 2); + EXPECT_GT(aConv.NbPoles(), 0); + EXPECT_GT(aConv.NbKnots(), 0); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } + + // Verify multiplicities are within valid range + const NCollection_Array1& aMults = aConv.Multiplicities(); + for (int i = 1; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aMults(i), 0); + EXPECT_LE(aMults(i), aConv.Degree() + 1); + } +} + +TEST(Convert_EllipseToBSplineCurveTest, Arc_TgtThetaOver2) +{ + const gp_Elips2d anElips(gp_Ax2d(gp_Pnt2d(1.0, 1.0), gp_Dir2d(1.0, 0.0)), 4.0, 2.0); + const double aU1 = M_PI / 4.0; + const double aU2 = 3.0 * M_PI / 2.0; + const Convert_EllipseToBSplineCurve aConv(anElips, aU1, aU2, Convert_TgtThetaOver2); + + EXPECT_FALSE(aConv.IsPeriodic()); + EXPECT_GT(aConv.NbPoles(), 0); + EXPECT_GT(aConv.NbKnots(), 0); + + // Verify first pole matches ellipse point at U1 + const NCollection_Array1& aPoles = aConv.Poles(); + const double aMajR = anElips.MajorRadius(); + const double aMinR = anElips.MinorRadius(); + const gp_Pnt2d aCenter = anElips.Location(); + const gp_Dir2d aXDir = anElips.XAxis().Direction(); + const gp_Dir2d aYDir = anElips.YAxis().Direction(); + + const double aFirstX = + aCenter.X() + aMajR * std::cos(aU1) * aXDir.X() + aMinR * std::sin(aU1) * aYDir.X(); + const double aFirstY = + aCenter.Y() + aMajR * std::cos(aU1) * aXDir.Y() + aMinR * std::sin(aU1) * aYDir.Y(); + EXPECT_NEAR(aPoles(1).X(), aFirstX, 1.0e-10); + EXPECT_NEAR(aPoles(1).Y(), aFirstY, 1.0e-10); + + // Verify last pole matches ellipse point at U2 + const double aLastX = + aCenter.X() + aMajR * std::cos(aU2) * aXDir.X() + aMinR * std::sin(aU2) * aYDir.X(); + const double aLastY = + aCenter.Y() + aMajR * std::cos(aU2) * aXDir.Y() + aMinR * std::sin(aU2) * aYDir.Y(); + EXPECT_NEAR(aPoles(aConv.NbPoles()).X(), aLastX, 1.0e-10); + EXPECT_NEAR(aPoles(aConv.NbPoles()).Y(), aLastY, 1.0e-10); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } +} + +TEST(Convert_EllipseToBSplineCurveTest, FullEllipse_RationalC1) +{ + const gp_Elips2d anElips(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 3.0, 1.0); + const Convert_EllipseToBSplineCurve aConv(anElips, Convert_RationalC1); + + EXPECT_TRUE(aConv.IsPeriodic()); + EXPECT_GT(aConv.NbPoles(), 0); + EXPECT_GT(aConv.NbKnots(), 0); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } +} + +TEST(Convert_EllipseToBSplineCurveTest, WeightsArePositive) +{ + const gp_Elips2d anElips(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 5.0, 3.0); + const Convert_EllipseToBSplineCurve aConv(anElips, Convert_TgtThetaOver2); + + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0); + } +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_GridPolynomialToPoles_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_GridPolynomialToPoles_Test.cxx new file mode 100644 index 0000000000..90f57fc2a1 --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_GridPolynomialToPoles_Test.cxx @@ -0,0 +1,124 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include + +TEST(Convert_GridPolynomialToPolesTest, SinglePlanarPatch) +{ + // A single bilinear patch: z = 0, x = u, y = v + // MaxUDegree = 1, MaxVDegree = 1 + // Coefficients as "C array" [MaxUDegree+1][MaxVDegree+1][3] + // For P(u,v) = (u, v, 0): coefficients in polynomial form + const int aMaxUDeg = 1; + const int aMaxVDeg = 1; + + occ::handle> aNumCoeff = new NCollection_HArray1(1, 2); + aNumCoeff->SetValue(1, 2); // U degree + 1 + aNumCoeff->SetValue(2, 2); // V degree + 1 + + // Coefficients [2][2][3] = 12 values + // Layout: for u_i, v_j: coeff(u_i, v_j) = {x, y, z} + // P(u,v) = sum c_{ij} * u^i * v^j + // c_{00} = (0,0,0), c_{10} = (1,0,0), c_{01} = (0,1,0), c_{11} = (0,0,0) + occ::handle> aCoeffs = new NCollection_HArray1(1, 12); + // c_{00}: x=0,y=0,z=0 + aCoeffs->SetValue(1, 0.0); + aCoeffs->SetValue(2, 0.0); + aCoeffs->SetValue(3, 0.0); + // c_{01}: x=0,y=1,z=0 + aCoeffs->SetValue(4, 0.0); + aCoeffs->SetValue(5, 1.0); + aCoeffs->SetValue(6, 0.0); + // c_{10}: x=1,y=0,z=0 + aCoeffs->SetValue(7, 1.0); + aCoeffs->SetValue(8, 0.0); + aCoeffs->SetValue(9, 0.0); + // c_{11}: x=0,y=0,z=0 + aCoeffs->SetValue(10, 0.0); + aCoeffs->SetValue(11, 0.0); + aCoeffs->SetValue(12, 0.0); + + occ::handle> aPolyU = new NCollection_HArray1(1, 2); + aPolyU->SetValue(1, 0.0); + aPolyU->SetValue(2, 1.0); + + occ::handle> aPolyV = new NCollection_HArray1(1, 2); + aPolyV->SetValue(1, 0.0); + aPolyV->SetValue(2, 1.0); + + Convert_GridPolynomialToPoles aConv(aMaxUDeg, aMaxVDeg, aNumCoeff, aCoeffs, aPolyU, aPolyV); + + EXPECT_TRUE(aConv.IsDone()); + EXPECT_GT(aConv.NbUPoles(), 0); + EXPECT_GT(aConv.NbVPoles(), 0); + EXPECT_EQ(aConv.UDegree(), 1); + EXPECT_EQ(aConv.VDegree(), 1); + EXPECT_GT(aConv.NbUKnots(), 0); + EXPECT_GT(aConv.NbVKnots(), 0); + + // Check poles are accessible + const NCollection_Array2& aPoles = aConv.Poles(); + EXPECT_GT(aPoles.Size(), 0); +} + +TEST(Convert_GridPolynomialToPolesTest, QueryMethods) +{ + const int aMaxUDeg = 1; + const int aMaxVDeg = 1; + + occ::handle> aNumCoeff = new NCollection_HArray1(1, 2); + aNumCoeff->SetValue(1, 2); + aNumCoeff->SetValue(2, 2); + + occ::handle> aCoeffs = new NCollection_HArray1(1, 12); + for (int i = 1; i <= 12; ++i) + { + aCoeffs->SetValue(i, 0.0); + } + // Just set x = u coefficient + aCoeffs->SetValue(7, 1.0); + // y = v coefficient + aCoeffs->SetValue(5, 1.0); + + occ::handle> aPolyU = new NCollection_HArray1(1, 2); + aPolyU->SetValue(1, 0.0); + aPolyU->SetValue(2, 1.0); + + occ::handle> aPolyV = new NCollection_HArray1(1, 2); + aPolyV->SetValue(1, 0.0); + aPolyV->SetValue(2, 1.0); + + Convert_GridPolynomialToPoles aConv(aMaxUDeg, aMaxVDeg, aNumCoeff, aCoeffs, aPolyU, aPolyV); + + ASSERT_TRUE(aConv.IsDone()); + + // Verify knot data is accessible + const NCollection_Array1& aUKnots = aConv.UKnots(); + const NCollection_Array1& aVKnots = aConv.VKnots(); + const NCollection_Array1& aUMults = aConv.UMultiplicities(); + const NCollection_Array1& aVMults = aConv.VMultiplicities(); + + EXPECT_GT(aUKnots.Size(), 0); + EXPECT_GT(aVKnots.Size(), 0); + EXPECT_GT(aUMults.Size(), 0); + EXPECT_GT(aVMults.Size(), 0); + + EXPECT_EQ(aUKnots.Length(), aConv.NbUKnots()); + EXPECT_EQ(aVKnots.Length(), aConv.NbVKnots()); +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_HyperbolaToBSplineCurve_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_HyperbolaToBSplineCurve_Test.cxx new file mode 100644 index 0000000000..f956be781a --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_HyperbolaToBSplineCurve_Test.cxx @@ -0,0 +1,139 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include + +TEST(Convert_HyperbolaToBSplineCurveTest, BasicConversion) +{ + const gp_Hypr2d aHypr(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 3.0, 2.0); + const double aU1 = -1.0; + const double aU2 = 1.0; + const Convert_HyperbolaToBSplineCurve aConv(aHypr, aU1, aU2); + + EXPECT_FALSE(aConv.IsPeriodic()); + EXPECT_EQ(aConv.Degree(), 2); + EXPECT_GT(aConv.NbPoles(), 0); + EXPECT_GT(aConv.NbKnots(), 0); + + // Verify first pole matches hyperbola point at U1 + const NCollection_Array1& aPoles = aConv.Poles(); + const double aMajR = aHypr.MajorRadius(); + const double aMinR = aHypr.MinorRadius(); + const gp_Pnt2d aCenter = aHypr.Location(); + const gp_Dir2d aXDir = aHypr.XAxis().Direction(); + const gp_Dir2d aYDir = aHypr.YAxis().Direction(); + + const double aFirstX = + aCenter.X() + aMajR * std::cosh(aU1) * aXDir.X() + aMinR * std::sinh(aU1) * aYDir.X(); + const double aFirstY = + aCenter.Y() + aMajR * std::cosh(aU1) * aXDir.Y() + aMinR * std::sinh(aU1) * aYDir.Y(); + EXPECT_NEAR(aPoles(1).X(), aFirstX, 1.0e-10); + EXPECT_NEAR(aPoles(1).Y(), aFirstY, 1.0e-10); + + // Verify last pole matches hyperbola point at U2 + const double aLastX = + aCenter.X() + aMajR * std::cosh(aU2) * aXDir.X() + aMinR * std::sinh(aU2) * aYDir.X(); + const double aLastY = + aCenter.Y() + aMajR * std::cosh(aU2) * aXDir.Y() + aMinR * std::sinh(aU2) * aYDir.Y(); + EXPECT_NEAR(aPoles(aConv.NbPoles()).X(), aLastX, 1.0e-10); + EXPECT_NEAR(aPoles(aConv.NbPoles()).Y(), aLastY, 1.0e-10); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } + + // Verify multiplicities are within valid range + const NCollection_Array1& aMults = aConv.Multiplicities(); + for (int i = 1; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aMults(i), 0); + EXPECT_LE(aMults(i), aConv.Degree() + 1); + } +} + +TEST(Convert_HyperbolaToBSplineCurveTest, LargeRange) +{ + const gp_Hypr2d aHypr(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 1.0, 1.0); + const double aU1 = -2.0; + const double aU2 = 2.0; + const Convert_HyperbolaToBSplineCurve aConv(aHypr, aU1, aU2); + + EXPECT_FALSE(aConv.IsPeriodic()); + EXPECT_GT(aConv.NbPoles(), 0); + EXPECT_GT(aConv.NbKnots(), 0); + + // Verify first pole matches hyperbola point at U1 + const NCollection_Array1& aPoles = aConv.Poles(); + const double aMajR = aHypr.MajorRadius(); + const double aMinR = aHypr.MinorRadius(); + const gp_Pnt2d aCenter = aHypr.Location(); + const gp_Dir2d aXDir = aHypr.XAxis().Direction(); + const gp_Dir2d aYDir = aHypr.YAxis().Direction(); + + const double aFirstX = + aCenter.X() + aMajR * std::cosh(aU1) * aXDir.X() + aMinR * std::sinh(aU1) * aYDir.X(); + const double aFirstY = + aCenter.Y() + aMajR * std::cosh(aU1) * aXDir.Y() + aMinR * std::sinh(aU1) * aYDir.Y(); + EXPECT_NEAR(aPoles(1).X(), aFirstX, 1.0e-10); + EXPECT_NEAR(aPoles(1).Y(), aFirstY, 1.0e-10); + + // Verify last pole matches hyperbola point at U2 + const double aLastX = + aCenter.X() + aMajR * std::cosh(aU2) * aXDir.X() + aMinR * std::sinh(aU2) * aYDir.X(); + const double aLastY = + aCenter.Y() + aMajR * std::cosh(aU2) * aXDir.Y() + aMinR * std::sinh(aU2) * aYDir.Y(); + EXPECT_NEAR(aPoles(aConv.NbPoles()).X(), aLastX, 1.0e-10); + EXPECT_NEAR(aPoles(aConv.NbPoles()).Y(), aLastY, 1.0e-10); + + // Verify all weights are positive + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0) << "Weight at index " << i << " is not positive"; + } + + // Verify knots are monotonically increasing + const NCollection_Array1& aKnots = aConv.Knots(); + for (int i = 2; i <= aConv.NbKnots(); ++i) + { + EXPECT_GT(aKnots(i), aKnots(i - 1)) << "Knots not monotonically increasing at index " << i; + } +} + +TEST(Convert_HyperbolaToBSplineCurveTest, WeightsArePositive) +{ + const gp_Hypr2d aHypr(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 3.0, 2.0); + const Convert_HyperbolaToBSplineCurve aConv(aHypr, -1.0, 1.0); + + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbPoles(); ++i) + { + EXPECT_GT(aWeights(i), 0.0); + } +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_ParabolaToBSplineCurve_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_ParabolaToBSplineCurve_Test.cxx new file mode 100644 index 0000000000..166963bf60 --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_ParabolaToBSplineCurve_Test.cxx @@ -0,0 +1,100 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +void checkParabolaPoint(const Convert_ParabolaToBSplineCurve& theConv, + const gp_Parab2d& theParab, + const double theParam) +{ + const NCollection_Array1& aPoles = theConv.Poles(); + const NCollection_Array1& aWeights = theConv.Weights(); + const NCollection_Array1& aKnots = theConv.Knots(); + const NCollection_Array1& aMults = theConv.Multiplicities(); + gp_Pnt2d aBSPnt; + BSplCLib::D0(theParam, + 0, + theConv.Degree(), + theConv.IsPeriodic(), + aPoles, + &aWeights, + aKnots, + &aMults, + aBSPnt); + + // Use ElCLib to evaluate the reference point on the parabola + const gp_Pnt2d aExpPnt = ElCLib::Value(theParam, theParab); + const double aExpX = aExpPnt.X(); + const double aExpY = aExpPnt.Y(); + + EXPECT_NEAR(aBSPnt.X(), aExpX, 1.0e-10); + EXPECT_NEAR(aBSPnt.Y(), aExpY, 1.0e-10); +} +} // namespace + +TEST(Convert_ParabolaToBSplineCurveTest, BasicConversion) +{ + const gp_Parab2d aParab(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 1.0); + const double aU1 = -2.0; + const double aU2 = 2.0; + const Convert_ParabolaToBSplineCurve aConv(aParab, aU1, aU2); + + EXPECT_FALSE(aConv.IsPeriodic()); + EXPECT_EQ(aConv.Degree(), 2); + EXPECT_GT(aConv.NbPoles(), 0); + EXPECT_GT(aConv.NbKnots(), 0); + + for (int i = 0; i <= 4; ++i) + { + const double aParam = aU1 + i * (aU2 - aU1) / 4.0; + checkParabolaPoint(aConv, aParab, aParam); + } +} + +TEST(Convert_ParabolaToBSplineCurveTest, SmallRange) +{ + const gp_Parab2d aParab(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 0.5); + const double aU1 = -0.5; + const double aU2 = 0.5; + const Convert_ParabolaToBSplineCurve aConv(aParab, aU1, aU2); + + for (int i = 0; i <= 4; ++i) + { + const double aParam = aU1 + i * (aU2 - aU1) / 4.0; + checkParabolaPoint(aConv, aParab, aParam); + } +} + +TEST(Convert_ParabolaToBSplineCurveTest, AllWeightsAreOne) +{ + // Parabola conversion produces non-rational (polynomial) BSpline + const gp_Parab2d aParab(gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0)), 1.0); + const Convert_ParabolaToBSplineCurve aConv(aParab, -1.0, 1.0); + + const NCollection_Array1& aWeights = aConv.Weights(); + for (int i = aWeights.Lower(); i <= aWeights.Upper(); ++i) + { + EXPECT_NEAR(aWeights(i), 1.0, 1.0e-15); + } +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_SphereToBSplineSurface_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_SphereToBSplineSurface_Test.cxx new file mode 100644 index 0000000000..354aea5e67 --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_SphereToBSplineSurface_Test.cxx @@ -0,0 +1,141 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include +#include + +TEST(Convert_SphereToBSplineSurfaceTest, FullSphere) +{ + const gp_Sphere aSphere(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0); + const Convert_SphereToBSplineSurface aConv(aSphere); + + EXPECT_EQ(aConv.UDegree(), 2); + EXPECT_EQ(aConv.VDegree(), 2); + EXPECT_TRUE(aConv.IsUPeriodic()); + EXPECT_FALSE(aConv.IsVPeriodic()); + EXPECT_GT(aConv.NbUPoles(), 0); + EXPECT_GT(aConv.NbVPoles(), 0); + EXPECT_GT(aConv.NbUKnots(), 0); + EXPECT_GT(aConv.NbVKnots(), 0); + + // Check all weights are non-negative (sphere poles may have zero weights) + const NCollection_Array2& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbUPoles(); ++i) + { + for (int j = 1; j <= aConv.NbVPoles(); ++j) + { + EXPECT_GE(aWeights(i, j), 0.0); + } + } +} + +TEST(Convert_SphereToBSplineSurfaceTest, TrimmedUV) +{ + const gp_Sphere aSphere(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 3.0); + const double aU1 = 0.0, aU2 = M_PI; + const double aV1 = -M_PI / 4.0, aV2 = M_PI / 4.0; + const Convert_SphereToBSplineSurface aConv(aSphere, aU1, aU2, aV1, aV2); + + EXPECT_FALSE(aConv.IsUPeriodic()); + EXPECT_FALSE(aConv.IsVPeriodic()); + EXPECT_GT(aConv.NbUPoles(), 0); + EXPECT_GT(aConv.NbVPoles(), 0); +} + +TEST(Convert_SphereToBSplineSurfaceTest, UTrimmed) +{ + const gp_Sphere aSphere(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 2.0); + const Convert_SphereToBSplineSurface aConv(aSphere, 0.0, M_PI, true); + + EXPECT_FALSE(aConv.IsUPeriodic()); +} + +TEST(Convert_SphereToBSplineSurfaceTest, VTrimmed) +{ + const gp_Sphere aSphere(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 2.0); + const Convert_SphereToBSplineSurface aConv(aSphere, -M_PI / 4.0, M_PI / 4.0, false); + + EXPECT_TRUE(aConv.IsUPeriodic()); +} + +TEST(Convert_SphereToBSplineSurfaceTest, KnotsAreMonotonic) +{ + const gp_Sphere aSphere(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 1.0); + const Convert_SphereToBSplineSurface aConv(aSphere); + + const NCollection_Array1& aUKnots = aConv.UKnots(); + for (int i = 2; i <= aConv.NbUKnots(); ++i) + { + EXPECT_GT(aUKnots(i), aUKnots(i - 1)); + } + const NCollection_Array1& aVKnots = aConv.VKnots(); + for (int i = 2; i <= aConv.NbVKnots(); ++i) + { + EXPECT_GT(aVKnots(i), aVKnots(i - 1)); + } +} + +TEST(Convert_SphereToBSplineSurfaceTest, GeometricVerification) +{ + const double aRadius = 5.0; + const gp_Ax3 anAx3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)); + const gp_Sphere aSphere(anAx3, aRadius); + // Use trimmed sphere to avoid degenerate poles + const Convert_SphereToBSplineSurface aConv(aSphere, 0.0, M_PI, -M_PI / 4.0, M_PI / 4.0); + + const double aTol = 1.0e-10; + const NCollection_Array1& aUK = aConv.UKnots(); + const NCollection_Array1& aVK = aConv.VKnots(); + const double aUMin = aUK(aUK.Lower()), aUMax = aUK(aUK.Upper()); + const double aVMin = aVK(aVK.Lower()), aVMax = aVK(aVK.Upper()); + + for (int i = 0; i <= 4; ++i) + { + const double aU = aUMin + i * (aUMax - aUMin) / 4.0; + for (int j = 0; j <= 4; ++j) + { + const double aV = aVMin + j * (aVMax - aVMin) / 4.0; + + gp_Pnt aPnt; + BSplSLib::D0(aU, + aV, + 0, + 0, + aConv.Poles(), + &aConv.Weights(), + aConv.UKnots(), + aConv.VKnots(), + &aConv.UMultiplicities(), + &aConv.VMultiplicities(), + aConv.UDegree(), + aConv.VDegree(), + true, + true, + false, + false, + aPnt); + + // Verify the point lies on the sphere: x^2 + y^2 + z^2 = R^2 + const double aDistFromOrigin = aPnt.Distance(gp_Pnt(0.0, 0.0, 0.0)); + EXPECT_NEAR(aDistFromOrigin, aRadius, aTol) + << "Point not on sphere at U=" << aU << " V=" << aV; + } + } +} diff --git a/src/FoundationClasses/TKMath/GTests/Convert_TorusToBSplineSurface_Test.cxx b/src/FoundationClasses/TKMath/GTests/Convert_TorusToBSplineSurface_Test.cxx new file mode 100644 index 0000000000..6a7aef220b --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Convert_TorusToBSplineSurface_Test.cxx @@ -0,0 +1,148 @@ +// Copyright (c) 2026 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include +#include + +TEST(Convert_TorusToBSplineSurfaceTest, FullTorus) +{ + const gp_Torus aTorus(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0, 2.0); + const Convert_TorusToBSplineSurface aConv(aTorus); + + EXPECT_EQ(aConv.UDegree(), 2); + EXPECT_EQ(aConv.VDegree(), 2); + EXPECT_TRUE(aConv.IsUPeriodic()); + EXPECT_TRUE(aConv.IsVPeriodic()); + EXPECT_GT(aConv.NbUPoles(), 0); + EXPECT_GT(aConv.NbVPoles(), 0); +} + +TEST(Convert_TorusToBSplineSurfaceTest, TrimmedUV) +{ + const gp_Torus aTorus(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0, 2.0); + const double aU1 = 0.0, aU2 = M_PI; + const double aV1 = 0.0, aV2 = M_PI; + const Convert_TorusToBSplineSurface aConv(aTorus, aU1, aU2, aV1, aV2); + + EXPECT_FALSE(aConv.IsUPeriodic()); + EXPECT_FALSE(aConv.IsVPeriodic()); + EXPECT_GT(aConv.NbUPoles(), 0); + EXPECT_GT(aConv.NbVPoles(), 0); +} + +TEST(Convert_TorusToBSplineSurfaceTest, UTrimmed) +{ + const gp_Torus aTorus(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0, 2.0); + const Convert_TorusToBSplineSurface aConv(aTorus, 0.0, M_PI, true); + + EXPECT_FALSE(aConv.IsUPeriodic()); + EXPECT_TRUE(aConv.IsVPeriodic()); +} + +TEST(Convert_TorusToBSplineSurfaceTest, VTrimmed) +{ + const gp_Torus aTorus(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0, 2.0); + const Convert_TorusToBSplineSurface aConv(aTorus, 0.0, M_PI, false); + + EXPECT_TRUE(aConv.IsUPeriodic()); + EXPECT_FALSE(aConv.IsVPeriodic()); +} + +TEST(Convert_TorusToBSplineSurfaceTest, WeightsArePositive) +{ + const gp_Torus aTorus(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0, 2.0); + const Convert_TorusToBSplineSurface aConv(aTorus); + + const NCollection_Array2& aWeights = aConv.Weights(); + for (int i = 1; i <= aConv.NbUPoles(); ++i) + { + for (int j = 1; j <= aConv.NbVPoles(); ++j) + { + EXPECT_GT(aWeights(i, j), 0.0); + } + } +} + +TEST(Convert_TorusToBSplineSurfaceTest, KnotsAreMonotonic) +{ + const gp_Torus aTorus(gp_Ax3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0, 2.0); + const Convert_TorusToBSplineSurface aConv(aTorus); + + const NCollection_Array1& aUKnots = aConv.UKnots(); + for (int i = 2; i <= aConv.NbUKnots(); ++i) + { + EXPECT_GT(aUKnots(i), aUKnots(i - 1)); + } + const NCollection_Array1& aVKnots = aConv.VKnots(); + for (int i = 2; i <= aConv.NbVKnots(); ++i) + { + EXPECT_GT(aVKnots(i), aVKnots(i - 1)); + } +} + +TEST(Convert_TorusToBSplineSurfaceTest, GeometricVerification) +{ + const double aMajorRadius = 5.0; + const double aMinorRadius = 2.0; + const gp_Ax3 anAx3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)); + const gp_Torus aTorus(anAx3, aMajorRadius, aMinorRadius); + const Convert_TorusToBSplineSurface aConv(aTorus, 0.0, M_PI, 0.0, M_PI); + + const double aTol = 1.0e-10; + const NCollection_Array1& aUK = aConv.UKnots(); + const NCollection_Array1& aVK = aConv.VKnots(); + const double aUMin = aUK(aUK.Lower()), aUMax = aUK(aUK.Upper()); + const double aVMin = aVK(aVK.Lower()), aVMax = aVK(aVK.Upper()); + + for (int i = 0; i <= 4; ++i) + { + const double aU = aUMin + i * (aUMax - aUMin) / 4.0; + for (int j = 0; j <= 4; ++j) + { + const double aV = aVMin + j * (aVMax - aVMin) / 4.0; + + gp_Pnt aPnt; + BSplSLib::D0(aU, + aV, + 0, + 0, + aConv.Poles(), + &aConv.Weights(), + aConv.UKnots(), + aConv.VKnots(), + &aConv.UMultiplicities(), + &aConv.VMultiplicities(), + aConv.UDegree(), + aConv.VDegree(), + true, + true, + false, + false, + aPnt); + + // Verify the point lies on the torus: + // (sqrt(x^2 + y^2) - R_major)^2 + z^2 = R_minor^2 + const double aRxy = std::sqrt(aPnt.X() * aPnt.X() + aPnt.Y() * aPnt.Y()); + const double aDistSq = (aRxy - aMajorRadius) * (aRxy - aMajorRadius) + aPnt.Z() * aPnt.Z(); + EXPECT_NEAR(aDistSq, aMinorRadius * aMinorRadius, aTol) + << "Point not on torus at U=" << aU << " V=" << aV; + } + } +} diff --git a/src/FoundationClasses/TKMath/GTests/FILES.cmake b/src/FoundationClasses/TKMath/GTests/FILES.cmake index 490df12353..2d8ec9607d 100644 --- a/src/FoundationClasses/TKMath/GTests/FILES.cmake +++ b/src/FoundationClasses/TKMath/GTests/FILES.cmake @@ -22,6 +22,18 @@ set(OCCT_TKMath_GTests_FILES BVH_Traverse_Test.cxx BVH_Triangulation_Test.cxx BVH_Tree_Test.cxx + # Convert tests + Convert_CircleToBSplineCurve_Test.cxx + Convert_CompBezierCurvesToBSplineCurve_Test.cxx + Convert_CompPolynomialToPoles_Test.cxx + Convert_ConeToBSplineSurface_Test.cxx + Convert_CylinderToBSplineSurface_Test.cxx + Convert_EllipseToBSplineCurve_Test.cxx + Convert_GridPolynomialToPoles_Test.cxx + Convert_HyperbolaToBSplineCurve_Test.cxx + Convert_ParabolaToBSplineCurve_Test.cxx + Convert_SphereToBSplineSurface_Test.cxx + Convert_TorusToBSplineSurface_Test.cxx CSLib_Test.cxx ElCLib_Test.cxx gp_Ax3_Test.cxx diff --git a/src/FoundationClasses/TKernel/NCollection/NCollection_Sequence.hxx b/src/FoundationClasses/TKernel/NCollection/NCollection_Sequence.hxx index 8c6c1f951a..85c9de3836 100644 --- a/src/FoundationClasses/TKernel/NCollection/NCollection_Sequence.hxx +++ b/src/FoundationClasses/TKernel/NCollection/NCollection_Sequence.hxx @@ -41,16 +41,16 @@ public: public: //! Constructor Node(const TheItemType& theItem) - : NCollection_SeqNode() + : NCollection_SeqNode(), + myValue(theItem) { - myValue = theItem; } //! Constructor Node(TheItemType&& theItem) - : NCollection_SeqNode() + : NCollection_SeqNode(), + myValue(std::forward(theItem)) { - myValue = std::forward(theItem); } //! Constructor with in-place value construction diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_PolynomialConvertor.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_PolynomialConvertor.cxx index f34e420f42..10dfc1e13d 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_PolynomialConvertor.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_PolynomialConvertor.cxx @@ -20,8 +20,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -77,7 +77,7 @@ void GeomFill_PolynomialConvertor::Init() Coeffs, Inter, TrueInter); En attente du bon Geomlite*/ - AConverter.Poles(Poles1d); + Poles1d = new NCollection_HArray2(AConverter.Poles()); for (jj = 1; jj <= Ordre; jj++) { diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_QuasiAngularConvertor.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_QuasiAngularConvertor.cxx index 236f00d5bc..be6466d898 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_QuasiAngularConvertor.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_QuasiAngularConvertor.cxx @@ -93,7 +93,7 @@ void GeomFill_QuasiAngularConvertor::Init() // Convertion Convert_CompPolynomialToPoles AConverter(Ordre, Ordre - 1, Ordre - 1, Coeffs, Inter, TrueInter); - AConverter.Poles(Poles1d); + Poles1d = new NCollection_HArray2(AConverter.Poles()); for (jj = 1; jj <= Ordre; jj++) { diff --git a/src/ModelingData/TKG3d/AdvApprox/AdvApprox_ApproxAFunction.cxx b/src/ModelingData/TKG3d/AdvApprox/AdvApprox_ApproxAFunction.cxx index dabda27b36..af595c3a23 100644 --- a/src/ModelingData/TKG3d/AdvApprox/AdvApprox_ApproxAFunction.cxx +++ b/src/ModelingData/TKG3d/AdvApprox/AdvApprox_ApproxAFunction.cxx @@ -844,22 +844,21 @@ void AdvApprox_ApproxAFunction::Perform(const int Num1DSS, if (AConverter.IsDone()) { - occ::handle> PolesPtr; - AConverter.Poles(PolesPtr); - AConverter.Knots(myKnots); - AConverter.Multiplicities(myMults); + const NCollection_Array2& aPoles = AConverter.Poles(); + myKnots = new NCollection_HArray1(AConverter.Knots()); + myMults = new NCollection_HArray1(AConverter.Multiplicities()); myDegree = AConverter.Degree(); index = 0; if (myNumSubSpaces[0] > 0) { - my1DPoles = new NCollection_HArray2(1, PolesPtr->ColLength(), 1, myNumSubSpaces[0]); - my1DMaxError = new NCollection_HArray1(1, myNumSubSpaces[0]); + my1DPoles = new NCollection_HArray2(1, aPoles.ColLength(), 1, myNumSubSpaces[0]); + my1DMaxError = new NCollection_HArray1(1, myNumSubSpaces[0]); my1DAverageError = new NCollection_HArray1(1, myNumSubSpaces[0]); - for (ii = 1; ii <= PolesPtr->ColLength(); ii++) + for (ii = 1; ii <= aPoles.ColLength(); ii++) { for (jj = 1; jj <= myNumSubSpaces[0]; jj++) { - my1DPoles->SetValue(ii, jj, PolesPtr->Value(ii, jj)); + my1DPoles->SetValue(ii, jj, aPoles.Value(ii, jj)); } } @@ -892,18 +891,17 @@ void AdvApprox_ApproxAFunction::Perform(const int Num1DSS, if (myNumSubSpaces[1] > 0) { gp_Pnt2d Point2d; - my2DPoles = - new NCollection_HArray2(1, PolesPtr->ColLength(), 1, myNumSubSpaces[1]); + my2DPoles = new NCollection_HArray2(1, aPoles.ColLength(), 1, myNumSubSpaces[1]); my2DMaxError = new NCollection_HArray1(1, myNumSubSpaces[1]); my2DAverageError = new NCollection_HArray1(1, myNumSubSpaces[1]); - for (ii = 1; ii <= PolesPtr->ColLength(); ii++) + for (ii = 1; ii <= aPoles.ColLength(); ii++) { for (jj = 1; jj <= myNumSubSpaces[1]; jj++) { local_index = index + (jj - 1) * 2; for (kk = 1; kk <= 2; kk++) { - Point2d.SetCoord(kk, PolesPtr->Value(ii, local_index + kk)); + Point2d.SetCoord(kk, aPoles.Value(ii, local_index + kk)); } my2DPoles->SetValue(ii, jj, Point2d); } @@ -938,17 +936,17 @@ void AdvApprox_ApproxAFunction::Perform(const int Num1DSS, if (myNumSubSpaces[2] > 0) { gp_Pnt Point; - my3DPoles = new NCollection_HArray2(1, PolesPtr->ColLength(), 1, myNumSubSpaces[2]); - my3DMaxError = new NCollection_HArray1(1, myNumSubSpaces[2]); + my3DPoles = new NCollection_HArray2(1, aPoles.ColLength(), 1, myNumSubSpaces[2]); + my3DMaxError = new NCollection_HArray1(1, myNumSubSpaces[2]); my3DAverageError = new NCollection_HArray1(1, myNumSubSpaces[2]); - for (ii = 1; ii <= PolesPtr->ColLength(); ii++) + for (ii = 1; ii <= aPoles.ColLength(); ii++) { for (jj = 1; jj <= myNumSubSpaces[2]; jj++) { local_index = dim_index + (jj - 1) * 3; for (kk = 1; kk <= 3; kk++) { - Point.SetCoord(kk, PolesPtr->Value(ii, local_index + kk)); + Point.SetCoord(kk, aPoles.Value(ii, local_index + kk)); } my3DPoles->SetValue(ii, jj, Point); } diff --git a/src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.cxx b/src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.cxx index 8e63516a6d..5251ad9aa9 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.cxx @@ -683,11 +683,11 @@ bool Geom_OsculatingSurface::buildOsculatingSurface(double theParam, TrueUIntervals, TrueVIntervals); - theBSpl = new Geom_BSplineSurface(Data.Poles()->Array2(), - Data.UKnots()->Array1(), - Data.VKnots()->Array1(), - Data.UMultiplicities()->Array1(), - Data.VMultiplicities()->Array1(), + theBSpl = new Geom_BSplineSurface(Data.Poles(), + Data.UKnots(), + Data.VKnots(), + Data.UMultiplicities(), + Data.VMultiplicities(), Data.UDegree(), Data.VDegree(), false, diff --git a/src/ModelingData/TKGeomBase/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx b/src/ModelingData/TKGeomBase/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx index 40961c2d78..fa7d876de8 100644 --- a/src/ModelingData/TKGeomBase/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx +++ b/src/ModelingData/TKGeomBase/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx @@ -972,11 +972,11 @@ void AdvApp2Var_ApproxAFunc2Var::ConvertBS() } // Conversion into BSpline - mySurfaces->ChangeValue(SSP) = new (Geom_BSplineSurface)(CvP.Poles()->Array2(), - CvP.UKnots()->Array1(), - CvP.VKnots()->Array1(), - CvP.UMultiplicities()->Array1(), - CvP.VMultiplicities()->Array1(), + mySurfaces->ChangeValue(SSP) = new (Geom_BSplineSurface)(CvP.Poles(), + CvP.UKnots(), + CvP.VKnots(), + CvP.UMultiplicities(), + CvP.VMultiplicities(), CvP.UDegree(), CvP.VDegree()); } diff --git a/src/ModelingData/TKGeomBase/AdvApp2Var/AdvApp2Var_Patch.cxx b/src/ModelingData/TKGeomBase/AdvApp2Var/AdvApp2Var_Patch.cxx index f522efe5f8..5d9279345d 100644 --- a/src/ModelingData/TKGeomBase/AdvApp2Var/AdvApp2Var_Patch.cxx +++ b/src/ModelingData/TKGeomBase/AdvApp2Var/AdvApp2Var_Patch.cxx @@ -1157,7 +1157,7 @@ occ::handle> AdvApp2Var_Patch::Poles( Intervalle, Intervalle); - return Conv.Poles(); + return new NCollection_HArray2(Conv.Poles()); } //============================================================================ diff --git a/src/ModelingData/TKGeomBase/AppDef/AppDef_Variational.cxx b/src/ModelingData/TKGeomBase/AppDef/AppDef_Variational.cxx index e96a06f1f2..2268209784 100644 --- a/src/ModelingData/TKGeomBase/AppDef/AppDef_Variational.cxx +++ b/src/ModelingData/TKGeomBase/AppDef/AppDef_Variational.cxx @@ -28,8 +28,6 @@ #define No_Standard_DimensionError #define No_Standard_ConstructionError -#include - #include #include @@ -551,24 +549,23 @@ void AppDef_Variational::Approximate() IntervallesPtr); if (AConverter.IsDone()) { - occ::handle> PolesPtr; - occ::handle> Mults; - int NbPoles = AConverter.NbPoles(); + occ::handle> Mults; + int NbPoles = AConverter.NbPoles(); // int Deg=AConverter.Degree(); NCollection_Array1 TabMU(1, NbPoles); - AConverter.Poles(PolesPtr); - AConverter.Knots(myKnots); - AConverter.Multiplicities(Mults); + const NCollection_Array2& aPoles = AConverter.Poles(); + myKnots = new NCollection_HArray1(AConverter.Knots()); + Mults = new NCollection_HArray1(AConverter.Multiplicities()); - for (ipole = PolesPtr->LowerRow(); ipole <= PolesPtr->UpperRow(); ipole++) + for (ipole = aPoles.LowerRow(); ipole <= aPoles.UpperRow(); ipole++) { - int index = PolesPtr->LowerCol(); + int index = aPoles.LowerCol(); /* if(myNbP2d !=0 ) { for (jp2d=1;jp2d<=myNbP2d;jp2d++) { - P2d.SetX(PolesPtr->Value(ipole,index++)); - P2d.SetY(PolesPtr->Value(ipole,index++)); + P2d.SetX(aPoles.Value(ipole,index++)); + P2d.SetY(aPoles.Value(ipole,index++)); TabP2d.SetValue(jp2d,P2d); } }*/ @@ -577,14 +574,14 @@ void AppDef_Variational::Approximate() for (jp3d = 1; jp3d <= myNbP3d; jp3d++) { // std::cout << "\n Poles(ipole,1)" << - // PolesPtr->Value(ipole,index); - P3d.SetX(PolesPtr->Value(ipole, index++)); + // aPoles.Value(ipole,index); + P3d.SetX(aPoles.Value(ipole, index++)); // std::cout << "\n Poles(ipole,1)" << - // PolesPtr->Value(ipole,index); - P3d.SetY(PolesPtr->Value(ipole, index++)); + // aPoles.Value(ipole,index); + P3d.SetY(aPoles.Value(ipole, index++)); // std::cout << "\n Poles(ipole,1)" << - // PolesPtr->Value(ipole,index); - P3d.SetZ(PolesPtr->Value(ipole, index++)); + // aPoles.Value(ipole,index); + P3d.SetZ(aPoles.Value(ipole, index++)); TabP3d.SetValue(jp3d, P3d); } } @@ -592,8 +589,8 @@ void AppDef_Variational::Approximate() { for (jp2d = 1; jp2d <= myNbP2d; jp2d++) { - P2d.SetX(PolesPtr->Value(ipole, index++)); - P2d.SetY(PolesPtr->Value(ipole, index++)); + P2d.SetX(aPoles.Value(ipole, index++)); + P2d.SetY(aPoles.Value(ipole, index++)); TabP2d.SetValue(jp2d, P2d); } } diff --git a/src/ModelingData/TKGeomBase/Geom2dConvert/Geom2dConvert.cxx b/src/ModelingData/TKGeomBase/Geom2dConvert/Geom2dConvert.cxx index 86861d4ad4..61e52f1751 100644 --- a/src/ModelingData/TKGeomBase/Geom2dConvert/Geom2dConvert.cxx +++ b/src/ModelingData/TKGeomBase/Geom2dConvert/Geom2dConvert.cxx @@ -74,24 +74,12 @@ static occ::handle BSplineCurveBuilder( { occ::handle TheCurve; - int NbPoles = Convert.NbPoles(); - int NbKnots = Convert.NbKnots(); - Array1OfPnt2d Poles(1, NbPoles); - Array1OfReal Weights(1, NbPoles); - Array1OfReal Knots(1, NbKnots); - Array1OfInteger Mults(1, NbKnots); - int i; - for (i = 1; i <= NbPoles; i++) - { - Poles(i) = Convert.Pole(i); - Weights(i) = Convert.Weight(i); - } - for (i = 1; i <= NbKnots; i++) - { - Knots(i) = Convert.Knot(i); - Mults(i) = Convert.Multiplicity(i); - } - TheCurve = new BSplineCurve(Poles, Weights, Knots, Mults, Convert.Degree(), Convert.IsPeriodic()); + TheCurve = new BSplineCurve(Convert.Poles(), + Convert.Weights(), + Convert.Knots(), + Convert.Multiplicities(), + Convert.Degree(), + Convert.IsPeriodic()); gp_Ax22d Axis = TheConic->Position(); if ((Axis.XDirection() ^ Axis.YDirection()) < 0.) diff --git a/src/ModelingData/TKGeomBase/GeomConvert/GeomConvert.cxx b/src/ModelingData/TKGeomBase/GeomConvert/GeomConvert.cxx index 9b5629698e..bbccaa65f2 100644 --- a/src/ModelingData/TKGeomBase/GeomConvert/GeomConvert.cxx +++ b/src/ModelingData/TKGeomBase/GeomConvert/GeomConvert.cxx @@ -62,30 +62,19 @@ static occ::handle BSplineCurveBuilder( const Convert_ConicToBSplineCurve& Convert) { - occ::handle TheCurve; - int NbPoles = Convert.NbPoles(); - int NbKnots = Convert.NbKnots(); - NCollection_Array1 Poles(1, NbPoles); - NCollection_Array1 Weights(1, NbPoles); - NCollection_Array1 Knots(1, NbKnots); - NCollection_Array1 Mults(1, NbKnots); - int i; - gp_Pnt2d P2d; - gp_Pnt P3d; - for (i = 1; i <= NbPoles; i++) + occ::handle TheCurve; + const NCollection_Array1& aPoles2d = Convert.Poles(); + const NCollection_Array1& aWeights = Convert.Weights(); + const NCollection_Array1& aKnots = Convert.Knots(); + const NCollection_Array1& aMults = Convert.Multiplicities(); + NCollection_Array1 Poles(1, aPoles2d.Length()); + for (int i = aPoles2d.Lower(); i <= aPoles2d.Upper(); i++) { - P2d = Convert.Pole(i); - P3d.SetCoord(P2d.X(), P2d.Y(), 0.0); - Poles(i) = P3d; - Weights(i) = Convert.Weight(i); - } - for (i = 1; i <= NbKnots; i++) - { - Knots(i) = Convert.Knot(i); - Mults(i) = Convert.Multiplicity(i); + const gp_Pnt2d& aP2d = aPoles2d(i); + Poles(i).SetCoord(aP2d.X(), aP2d.Y(), 0.0); } TheCurve = - new Geom_BSplineCurve(Poles, Weights, Knots, Mults, Convert.Degree(), Convert.IsPeriodic()); + new Geom_BSplineCurve(Poles, aWeights, aKnots, aMults, Convert.Degree(), Convert.IsPeriodic()); gp_Trsf T; T.SetTransformation(TheConic->Position(), gp::XOY()); occ::handle Cres; diff --git a/src/ModelingData/TKGeomBase/GeomConvert/GeomConvert_1.cxx b/src/ModelingData/TKGeomBase/GeomConvert/GeomConvert_1.cxx index 0f12775710..f31cd03a07 100644 --- a/src/ModelingData/TKGeomBase/GeomConvert/GeomConvert_1.cxx +++ b/src/ModelingData/TKGeomBase/GeomConvert/GeomConvert_1.cxx @@ -48,15 +48,9 @@ #include #include #include -#include -typedef Geom_Surface Surface; -typedef Geom_BSplineSurface BSplineSurface; -typedef NCollection_Array1 Array1OfReal; -typedef NCollection_Array2 Array2OfReal; -typedef NCollection_Array1 Array1OfInteger; -typedef NCollection_Array2 Array2OfPnt; -typedef gp_Pnt Pnt; +typedef Geom_Surface Surface; +typedef Geom_BSplineSurface BSplineSurface; //================================================================================================= @@ -64,45 +58,14 @@ static occ::handle BSplineSurfaceBuilder( const Convert_ElementarySurfaceToBSplineSurface& Convert) { occ::handle TheSurface; - int UDegree = Convert.UDegree(); - int VDegree = Convert.VDegree(); - int NbUPoles = Convert.NbUPoles(); - int NbVPoles = Convert.NbVPoles(); - int NbUKnots = Convert.NbUKnots(); - int NbVKnots = Convert.NbVKnots(); - Array2OfPnt Poles(1, NbUPoles, 1, NbVPoles); - Array2OfReal Weights(1, NbUPoles, 1, NbVPoles); - Array1OfReal UKnots(1, NbUKnots); - Array1OfReal VKnots(1, NbVKnots); - Array1OfInteger UMults(1, NbUKnots); - Array1OfInteger VMults(1, NbVKnots); - int i, j; - for (j = 1; j <= NbVPoles; j++) - { - for (i = 1; i <= NbUPoles; i++) - { - Poles(i, j) = Convert.Pole(i, j); - Weights(i, j) = Convert.Weight(i, j); - } - } - for (i = 1; i <= NbUKnots; i++) - { - UKnots(i) = Convert.UKnot(i); - UMults(i) = Convert.UMultiplicity(i); - } - for (i = 1; i <= NbVKnots; i++) - { - VKnots(i) = Convert.VKnot(i); - VMults(i) = Convert.VMultiplicity(i); - } - TheSurface = new BSplineSurface(Poles, - Weights, - UKnots, - VKnots, - UMults, - VMults, - UDegree, - VDegree, + TheSurface = new BSplineSurface(Convert.Poles(), + Convert.Weights(), + Convert.UKnots(), + Convert.VKnots(), + Convert.UMultiplicities(), + Convert.VMultiplicities(), + Convert.UDegree(), + Convert.VDegree(), Convert.IsUPeriodic(), Convert.IsVPeriodic()); return TheSurface;