mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-08-08 23:07:28 +08:00
Foundation Classes, Convert - Replace handle-based APIs with direct array access (#1057)
Refactor the Convert package to eliminate heap-allocated handle-based storage in favor of direct NCollection_Array members, improving performance and simplifying the API. Deprecate single-element accessors (Pole, Knot, etc.) in favor of batch const-reference accessors (Poles, Knots, etc.). Convert_ConicToBSplineCurve: - Replace handle members (poles, weights, knots, mults) with direct NCollection_Array1 fields (myPoles, myWeights, myKnots, myMults). - Replace BuildCosAndSin handle-based parameters with array references. - Add batch accessors: Poles(), Weights(), Knots(), Multiplicities(). - Deprecate single-element accessors: Pole(), Weight(), Knot(), Multiplicity(). - Update all conic subclasses: Circle, Ellipse, Hyperbola, Parabola. Convert_ElementarySurfaceToBSplineSurface: - Replace handle members with direct NCollection_Array fields (myPoles, myWeights, myUKnots, myVKnots, myUMults, myVMults). - Add Finalize() to trim oversized arrays in derived constructors. - Add batch accessors: Poles(), Weights(), UKnots(), VKnots(), UMultiplicities(), VMultiplicities(). - Deprecate single-element accessors: Pole(), Weight(), UKnot(), VKnot(), UMultiplicity(), VMultiplicity(). - Update all surface subclasses: Cone, Cylinder, Sphere, Torus. Convert_CompPolynomialToPoles / Convert_GridPolynomialToPoles: - Replace handle-based output parameters with direct const-reference accessors for Poles, Knots, Multiplicities. - Deprecate old handle-based Poles(), Knots(), Multiplicities() overloads. Convert_CompBezierCurvesToBSplineCurve (2D and 3D): - Extract common logic into Convert_CompBezierCurvesToBSplineCurveBase template header to eliminate code duplication. - Replace handle<HArray1> members with direct NCollection_Array1 storage in the internal sequence, removing unnecessary heap indirection. NCollection_Sequence: - Fix Node constructors to use member initializer lists (copy/move construction) instead of default-construct + assign, which failed for types like NCollection_Array1 where operator= requires matching sizes. Downstream callers migrated: - AdvApprox_ApproxAFunction: use new const-ref Knots()/Multiplicities(). - AppDef_Variational: use new const-ref Knots()/Multiplicities(). - AdvApp2Var_ApproxAFunc2Var, AdvApp2Var_Patch: use new const-ref API. - Geom2dConvert, GeomConvert, GeomConvert_1: use new const-ref API. - GeomFill_PolynomialConvertor, GeomFill_QuasiAngularConvertor: adapted. - Geom_OsculatingSurface: use direct array references instead of handle->Array*() calls. Added GTests for all Convert classes covering conic curves, elementary surfaces, CompBezier, CompPolynomial, and GridPolynomial conversions.
This commit is contained in:
@@ -24,7 +24,6 @@
|
||||
#include <Standard_DomainError.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
|
||||
// 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<NCollection_HArray1<double>> CosNumeratorPtr, SinNumeratorPtr;
|
||||
double R, value;
|
||||
NCollection_Array1<double> 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<gp_Pnt2d>(1, nbPoles);
|
||||
myPoles = NCollection_Array1<gp_Pnt2d>(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<NCollection_HArray1<double>> CosNumeratorPtr, SinNumeratorPtr;
|
||||
int ii;
|
||||
double R, value;
|
||||
NCollection_Array1<double> 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<gp_Pnt2d>(1, nbPoles);
|
||||
myPoles = NCollection_Array1<gp_Pnt2d>(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);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-194
@@ -14,203 +14,12 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Convert_CompBezierCurves2dToBSplineCurve2d.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
|
||||
//=================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
Convert_CompBezierCurves2dToBSplineCurve2d::Convert_CompBezierCurves2dToBSplineCurve2d(
|
||||
const double AngularTolerance)
|
||||
: myDegree(0),
|
||||
myAngular(AngularTolerance),
|
||||
myDone(false)
|
||||
const double theAngularTolerance)
|
||||
: Convert_CompBezierCurvesToBSplineCurveBase<gp_Pnt2d, gp_Vec2d>(theAngularTolerance)
|
||||
{
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Convert_CompBezierCurves2dToBSplineCurve2d::AddCurve(const NCollection_Array1<gp_Pnt2d>& 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<NCollection_HArray1<gp_Pnt2d>> HPoles =
|
||||
new NCollection_HArray1<gp_Pnt2d>(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<gp_Pnt2d>& 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<double>& Knots,
|
||||
NCollection_Array1<int>& 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<double> 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<gp_Pnt2d> 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);
|
||||
}
|
||||
|
||||
+6
-141
@@ -17,161 +17,26 @@
|
||||
#ifndef _Convert_CompBezierCurves2dToBSplineCurve2d_HeaderFile
|
||||
#define _Convert_CompBezierCurves2dToBSplineCurve2d_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
|
||||
#include <Convert_CompBezierCurvesToBSplineCurveBase.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
|
||||
//! 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<gp_Pnt2d, gp_Vec2d>
|
||||
{
|
||||
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<gp_Pnt2d>& 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<gp_Pnt2d>& 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<double>& Knots,
|
||||
NCollection_Array1<int>& Mults) const;
|
||||
|
||||
private:
|
||||
NCollection_Sequence<occ::handle<NCollection_HArray1<gp_Pnt2d>>> mySequence;
|
||||
NCollection_Sequence<gp_Pnt2d> CurvePoles;
|
||||
NCollection_Sequence<double> CurveKnots;
|
||||
NCollection_Sequence<int> KnotsMultiplicities;
|
||||
int myDegree;
|
||||
double myAngular;
|
||||
bool myDone;
|
||||
const double theAngularTolerance = 1.0e-4);
|
||||
};
|
||||
|
||||
#endif // _Convert_CompBezierCurves2dToBSplineCurve2d_HeaderFile
|
||||
|
||||
@@ -14,214 +14,12 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Convert_CompBezierCurvesToBSplineCurve.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
|
||||
//=================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
Convert_CompBezierCurvesToBSplineCurve::Convert_CompBezierCurvesToBSplineCurve(
|
||||
const double AngularTolerance)
|
||||
: myDegree(0),
|
||||
myAngular(AngularTolerance),
|
||||
myDone(false)
|
||||
const double theAngularTolerance)
|
||||
: Convert_CompBezierCurvesToBSplineCurveBase<gp_Pnt, gp_Vec>(theAngularTolerance)
|
||||
{
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Convert_CompBezierCurvesToBSplineCurve::AddCurve(const NCollection_Array1<gp_Pnt>& 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<NCollection_HArray1<gp_Pnt>> HPoles =
|
||||
new NCollection_HArray1<gp_Pnt>(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<gp_Pnt>& 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<double>& Knots,
|
||||
NCollection_Array1<int>& 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<double> 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<gp_Pnt> 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);
|
||||
}
|
||||
|
||||
@@ -17,14 +17,9 @@
|
||||
#ifndef _Convert_CompBezierCurvesToBSplineCurve_HeaderFile
|
||||
#define _Convert_CompBezierCurvesToBSplineCurve_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
|
||||
#include <Convert_CompBezierCurvesToBSplineCurveBase.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
|
||||
//! 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<gp_Pnt, gp_Vec>
|
||||
{
|
||||
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<gp_Pnt>& 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<gp_Pnt>& 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<double>& Knots,
|
||||
NCollection_Array1<int>& Mults) const;
|
||||
|
||||
private:
|
||||
NCollection_Sequence<occ::handle<NCollection_HArray1<gp_Pnt>>> mySequence;
|
||||
NCollection_Sequence<gp_Pnt> CurvePoles;
|
||||
NCollection_Sequence<double> CurveKnots;
|
||||
NCollection_Sequence<int> 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
|
||||
|
||||
@@ -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 <BSplCLib.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
#include <type_traits>
|
||||
|
||||
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 <typename PointType, typename VecType>
|
||||
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<PointType>& 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<double> 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<PointType> 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<PointType, gp_Pnt>)
|
||||
{
|
||||
// 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<PointType>& 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<double>& theKnots, NCollection_Array1<int>& 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<NCollection_Array1<PointType>> mySequence;
|
||||
NCollection_Sequence<PointType> myCurvePoles;
|
||||
NCollection_Sequence<double> myCurveKnots;
|
||||
NCollection_Sequence<int> myKnotsMults;
|
||||
int myDegree;
|
||||
double myAngular;
|
||||
};
|
||||
|
||||
#endif // _Convert_CompBezierCurvesToBSplineCurveBase_HeaderFile
|
||||
@@ -22,17 +22,16 @@
|
||||
// 15-04-97 : PMN : Constructeurs avec un seul segement ou differentes
|
||||
// continuitees.
|
||||
|
||||
#define No_Standard_OutOfRange
|
||||
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Convert_CompPolynomialToPoles.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <NCollection_HArray2.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <StdFail_NotDone.hxx>
|
||||
|
||||
//=================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles(
|
||||
const int NumCurves,
|
||||
@@ -43,19 +42,18 @@ Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles(
|
||||
const occ::handle<NCollection_HArray1<double>>& Coefficients,
|
||||
const occ::handle<NCollection_HArray2<double>>& PolynomialIntervals,
|
||||
const occ::handle<NCollection_HArray1<double>>& 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<double>(1, NumCurves + 1);
|
||||
for (ii = 1, Tindex = TrueIntervals->Lower(); ii <= NumCurves + 1; ii++, Tindex++)
|
||||
myKnots = NCollection_Array1<double>(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<int>(1, NumCurves + 1);
|
||||
for (ii = 2; ii < NumCurves + 1; ii++)
|
||||
const int aMultiplicities = myDegree - Continuity;
|
||||
myMults = NCollection_Array1<int>(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<double>& Coefficients,
|
||||
const NCollection_Array2<double>& PolynomialIntervals,
|
||||
const NCollection_Array1<double>& 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<double>(1, NumCurves + 1);
|
||||
for (ii = 1, Tindex = TrueIntervals.Lower(); ii <= NumCurves + 1; ii++, Tindex++)
|
||||
myKnots = NCollection_Array1<double>(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<int>(1, NumCurves + 1);
|
||||
for (ii = 2; ii < NumCurves + 1; ii++)
|
||||
myMults = NCollection_Array1<int>(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<double>& TrueIntervals)
|
||||
: myDegree(Degree),
|
||||
myDone(false)
|
||||
|
||||
{
|
||||
if (MaxDegree <= 0 || Dimension <= 0 || PolynomialIntervals.Length() != 2)
|
||||
{
|
||||
@@ -172,14 +159,13 @@ Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles(
|
||||
NCollection_Array1<int> NumCoeffPerCurve(1, 1);
|
||||
NumCoeffPerCurve(1) = Degree + 1;
|
||||
|
||||
myKnots = new NCollection_HArray1<double>(1, 2);
|
||||
myKnots->ChangeArray1().SetValue(1, TrueIntervals.Value(TrueIntervals.Lower()));
|
||||
myKnots->ChangeArray1().SetValue(2, TrueIntervals.Value(TrueIntervals.Lower() + 1));
|
||||
myKnots = NCollection_Array1<double>(1, 2);
|
||||
myKnots.SetValue(1, TrueIntervals.Value(TrueIntervals.Lower()));
|
||||
myKnots.SetValue(2, TrueIntervals.Value(TrueIntervals.Lower() + 1));
|
||||
|
||||
myMults = new NCollection_HArray1<int>(1, 2);
|
||||
myMults->Init(myDegree + 1);
|
||||
myMults = NCollection_Array1<int>(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<double>(1, num_flat_knots);
|
||||
BSplCLib::KnotSequence(myKnots->Array1(),
|
||||
myMults->Array1(),
|
||||
myDegree,
|
||||
false,
|
||||
myFlatKnots->ChangeArray1());
|
||||
myFlatKnots = NCollection_Array1<double>(1, num_flat_knots);
|
||||
BSplCLib::KnotSequence(myKnots, myMults, myDegree, false, myFlatKnots);
|
||||
|
||||
NCollection_Array1<double> parameters(1, num_poles);
|
||||
BSplCLib::BuildSchoenbergPoints(myDegree, myFlatKnots->Array1(), parameters);
|
||||
myPoles = new NCollection_HArray2<double>(1, num_poles, 1, Dimension);
|
||||
BSplCLib::BuildSchoenbergPoints(myDegree, myFlatKnots, parameters);
|
||||
myPoles = NCollection_Array2<double>(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<int> 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<NCollection_HArray2<double>>& P) const
|
||||
const NCollection_Array2<double>& Convert_CompPolynomialToPoles::Poles() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if(!myDone, "Convert_CompPolynomialToPoles::Poles");
|
||||
return myPoles;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
Standard_DISABLE_DEPRECATION_WARNINGS void Convert_CompPolynomialToPoles::Poles(
|
||||
occ::handle<NCollection_HArray2<double>>& P) const
|
||||
{
|
||||
if (myDone)
|
||||
{
|
||||
P = myPoles;
|
||||
P = new NCollection_HArray2<double>(myPoles);
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
int Convert_CompPolynomialToPoles::NbKnots() const
|
||||
{
|
||||
if (myDone)
|
||||
{
|
||||
return myKnots->Length();
|
||||
return myKnots.Length();
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<double>& Convert_CompPolynomialToPoles::Knots() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if(!myDone, "Convert_CompPolynomialToPoles::Knots");
|
||||
return myKnots;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
void Convert_CompPolynomialToPoles::Knots(occ::handle<NCollection_HArray1<double>>& K) const
|
||||
{
|
||||
if (myDone)
|
||||
{
|
||||
K = myKnots;
|
||||
K = new NCollection_HArray1<double>(myKnots);
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<int>& Convert_CompPolynomialToPoles::Multiplicities() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if(!myDone, "Convert_CompPolynomialToPoles::Multiplicities");
|
||||
return myMults;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
void Convert_CompPolynomialToPoles::Multiplicities(occ::handle<NCollection_HArray1<int>>& M) const
|
||||
{
|
||||
if (myDone)
|
||||
{
|
||||
M = myMults;
|
||||
M = new NCollection_HArray1<int>(myMults);
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
Standard_ENABLE_DEPRECATION_WARNINGS
|
||||
|
||||
bool Convert_CompPolynomialToPoles::IsDone() const
|
||||
//==================================================================================================
|
||||
|
||||
bool
|
||||
Convert_CompPolynomialToPoles::IsDone() const
|
||||
{
|
||||
return myDone;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
int Convert_CompPolynomialToPoles::Degree() const
|
||||
{
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
#include <NCollection_HArray2.hxx>
|
||||
|
||||
@@ -109,26 +109,40 @@ public:
|
||||
const NCollection_Array1<double>& PolynomialIntervals,
|
||||
const NCollection_Array1<double>& 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<NCollection_HArray2<double>>& Poles) const;
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array2<double>& 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<NCollection_HArray2<double>>& 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<NCollection_HArray1<double>>& 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<NCollection_HArray1<int>>& M) const;
|
||||
//! Returns the knots of the n-dimensional BSpline.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<double>& 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<NCollection_HArray1<double>>& theKnots) const;
|
||||
|
||||
//! Returns the multiplicities of the knots in the BSpline.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<int>& 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<NCollection_HArray1<int>>& 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<double>& PolynomialIntervals,
|
||||
const NCollection_Array1<double>& TrueIntervals);
|
||||
|
||||
occ::handle<NCollection_HArray1<double>> myFlatKnots;
|
||||
occ::handle<NCollection_HArray1<double>> myKnots;
|
||||
occ::handle<NCollection_HArray1<int>> myMults;
|
||||
occ::handle<NCollection_HArray2<double>> myPoles;
|
||||
int myDegree;
|
||||
bool myDone;
|
||||
NCollection_Array1<double> myFlatKnots;
|
||||
NCollection_Array1<double> myKnots;
|
||||
NCollection_Array1<int> myMults;
|
||||
NCollection_Array2<double> myPoles;
|
||||
int myDegree;
|
||||
bool myDone;
|
||||
};
|
||||
|
||||
#endif // _Convert_CompPolynomialToPoles_HeaderFile
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <Standard_DomainError.hxx>
|
||||
|
||||
#include <array>
|
||||
|
||||
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<double, TheNbVPoles> x;
|
||||
std::array<double, TheNbVPoles> 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();
|
||||
}
|
||||
|
||||
@@ -14,107 +14,196 @@
|
||||
|
||||
// JCV 16/10/91
|
||||
|
||||
#define No_Standard_OutOfRange
|
||||
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Convert_ConicToBSplineCurve.hxx>
|
||||
#include <Convert_CosAndSinEvalFunction.hxx>
|
||||
#include <Convert_PolynomialCosAndSin.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
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<gp_Pnt2d>(1, NbPoles);
|
||||
|
||||
weights = new NCollection_HArray1<double>(1, NbPoles);
|
||||
myPoles = NCollection_Array1<gp_Pnt2d>(1, theNumberOfPoles);
|
||||
myWeights = NCollection_Array1<double>(1, theNumberOfPoles);
|
||||
}
|
||||
if (NbKnots >= 2)
|
||||
if (theNumberOfKnots >= 2)
|
||||
{
|
||||
knots = new NCollection_HArray1<double>(1, NbKnots);
|
||||
mults = new NCollection_HArray1<int>(1, NbKnots);
|
||||
myKnots = NCollection_Array1<double>(1, theNumberOfKnots);
|
||||
myMults = NCollection_Array1<int>(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<gp_Pnt2d>&
|
||||
Convert_ConicToBSplineCurve::Poles() const
|
||||
{
|
||||
return myPoles;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<double>& Convert_ConicToBSplineCurve::Weights() const
|
||||
{
|
||||
return myWeights;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<double>& Convert_ConicToBSplineCurve::Knots() const
|
||||
{
|
||||
return myKnots;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<int>& Convert_ConicToBSplineCurve::Multiplicities() const
|
||||
{
|
||||
return myMults;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
void Convert_ConicToBSplineCurve::BuildCosAndSin(
|
||||
const Convert_ParameterisationType theParametrisation,
|
||||
occ::handle<NCollection_HArray1<double>>& theCosNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& theSinNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& theDenominator,
|
||||
int& theDegree,
|
||||
occ::handle<NCollection_HArray1<double>>& theKnots,
|
||||
occ::handle<NCollection_HArray1<int>>& theMults) const
|
||||
{
|
||||
NCollection_Array1<double> aCosNumerator;
|
||||
NCollection_Array1<double> aSinNumerator;
|
||||
NCollection_Array1<double> aDenominator;
|
||||
NCollection_Array1<double> aKnots;
|
||||
NCollection_Array1<int> aMults;
|
||||
BuildCosAndSin(theParametrisation,
|
||||
aCosNumerator,
|
||||
aSinNumerator,
|
||||
aDenominator,
|
||||
theDegree,
|
||||
aKnots,
|
||||
aMults);
|
||||
theCosNumerator = new NCollection_HArray1<double>(aCosNumerator);
|
||||
theSinNumerator = new NCollection_HArray1<double>(aSinNumerator);
|
||||
theDenominator = new NCollection_HArray1<double>(aDenominator);
|
||||
theKnots = new NCollection_HArray1<double>(aKnots);
|
||||
theMults = new NCollection_HArray1<int>(aMults);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
void Convert_ConicToBSplineCurve::BuildCosAndSin(
|
||||
const Convert_ParameterisationType theParametrisation,
|
||||
const double theUFirst,
|
||||
const double theULast,
|
||||
occ::handle<NCollection_HArray1<double>>& theCosNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& theSinNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& theDenominator,
|
||||
int& theDegree,
|
||||
occ::handle<NCollection_HArray1<double>>& theKnots,
|
||||
occ::handle<NCollection_HArray1<int>>& theMults) const
|
||||
{
|
||||
NCollection_Array1<double> aCosNumerator;
|
||||
NCollection_Array1<double> aSinNumerator;
|
||||
NCollection_Array1<double> aDenominator;
|
||||
NCollection_Array1<double> aKnots;
|
||||
NCollection_Array1<int> aMults;
|
||||
BuildCosAndSin(theParametrisation,
|
||||
theUFirst,
|
||||
theULast,
|
||||
aCosNumerator,
|
||||
aSinNumerator,
|
||||
aDenominator,
|
||||
theDegree,
|
||||
aKnots,
|
||||
aMults);
|
||||
theCosNumerator = new NCollection_HArray1<double>(aCosNumerator);
|
||||
theSinNumerator = new NCollection_HArray1<double>(aSinNumerator);
|
||||
theDenominator = new NCollection_HArray1<double>(aDenominator);
|
||||
theKnots = new NCollection_HArray1<double>(aKnots);
|
||||
theMults = new NCollection_HArray1<int>(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<gp_Pnt2d>& EvalPoles,
|
||||
const NCollection_Array1<double>& EvalKnots,
|
||||
const NCollection_Array1<int>* EvalMults,
|
||||
double Result[2])
|
||||
static void CosAndSinRationalC1(double Parameter,
|
||||
const int EvalDegree,
|
||||
const NCollection_Array1<gp_Pnt2d>& EvalPoles,
|
||||
const NCollection_Array1<double>& EvalKnots,
|
||||
const NCollection_Array1<int>* 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<gp_Pnt2d>& EvalPoles,
|
||||
// const NCollection_Array1<double>& EvalKnots,
|
||||
const NCollection_Array1<double>&,
|
||||
// const NCollection_Array1<int>& EvalMults,
|
||||
const NCollection_Array1<int>*,
|
||||
double Result[2])
|
||||
static void CosAndSinQuasiAngular(double Parameter,
|
||||
const int EvalDegree,
|
||||
const NCollection_Array1<gp_Pnt2d>& EvalPoles,
|
||||
const NCollection_Array1<double>&,
|
||||
const NCollection_Array1<int>*,
|
||||
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<double> 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<double>& FlatKnots,
|
||||
const int EvalDegree,
|
||||
const NCollection_Array1<gp_Pnt2d>& EvalPoles,
|
||||
const NCollection_Array1<double>& EvalKnots,
|
||||
const NCollection_Array1<int>* EvalMults,
|
||||
Convert_CosAndSinEvalFunction Evaluator,
|
||||
NCollection_Array1<double>& CosNumerator,
|
||||
NCollection_Array1<double>& SinNumerator,
|
||||
NCollection_Array1<double>& Denominator)
|
||||
|
||||
static void AlgorithmicCosAndSin(int Degree,
|
||||
const NCollection_Array1<double>& FlatKnots,
|
||||
const int EvalDegree,
|
||||
const NCollection_Array1<gp_Pnt2d>& EvalPoles,
|
||||
const NCollection_Array1<double>& EvalKnots,
|
||||
const NCollection_Array1<int>* EvalMults,
|
||||
Convert_CosAndSinEvalFunction Evaluator,
|
||||
NCollection_Array1<double>& CosNumerator,
|
||||
NCollection_Array1<double>& SinNumerator,
|
||||
NCollection_Array1<double>& 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<NCollection_HArray1<double>>& CosNumeratorPtr,
|
||||
occ::handle<NCollection_HArray1<double>>& SinNumeratorPtr,
|
||||
occ::handle<NCollection_HArray1<double>>& DenominatorPtr,
|
||||
int& Degree,
|
||||
occ::handle<NCollection_HArray1<double>>& KnotsPtr,
|
||||
occ::handle<NCollection_HArray1<int>>& MultsPtr) const
|
||||
const Convert_ParameterisationType Parameterisation,
|
||||
const double UFirst,
|
||||
const double ULast,
|
||||
NCollection_Array1<double>& CosNumerator,
|
||||
NCollection_Array1<double>& SinNumerator,
|
||||
NCollection_Array1<double>& Denominator,
|
||||
int& Degree,
|
||||
NCollection_Array1<double>& Knots,
|
||||
NCollection_Array1<int>& 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<double>(1, num_poles);
|
||||
SinNumeratorPtr = new NCollection_HArray1<double>(1, num_poles);
|
||||
DenominatorPtr = new NCollection_HArray1<double>(1, num_poles);
|
||||
KnotsPtr = new NCollection_HArray1<double>(1, num_spans + 1);
|
||||
MultsPtr = new NCollection_HArray1<int>(1, num_spans + 1);
|
||||
CosNumerator = NCollection_Array1<double>(1, num_poles);
|
||||
SinNumerator = NCollection_Array1<double>(1, num_poles);
|
||||
Denominator = NCollection_Array1<double>(1, num_poles);
|
||||
Knots = NCollection_Array1<double>(1, num_spans + 1);
|
||||
Mults = NCollection_Array1<int>(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<NCollection_HArray1<double>>& CosNumeratorPtr,
|
||||
occ::handle<NCollection_HArray1<double>>& SinNumeratorPtr,
|
||||
occ::handle<NCollection_HArray1<double>>& DenominatorPtr,
|
||||
int& Degree,
|
||||
occ::handle<NCollection_HArray1<double>>& KnotsPtr,
|
||||
occ::handle<NCollection_HArray1<int>>& MultsPtr) const
|
||||
const Convert_ParameterisationType Parameterisation,
|
||||
NCollection_Array1<double>& CosNumerator,
|
||||
NCollection_Array1<double>& SinNumerator,
|
||||
NCollection_Array1<double>& Denominator,
|
||||
int& Degree,
|
||||
NCollection_Array1<double>& Knots,
|
||||
NCollection_Array1<int>& 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<NCollection_HArray1<double>> temp_cos_ptr, temp_sin_ptr, temp_denominator_ptr,
|
||||
temp_knots_ptr;
|
||||
occ::handle<NCollection_HArray1<int>> temp_mults_ptr;
|
||||
NCollection_Array1<double> temp_cos, temp_sin, temp_denominator, temp_knots;
|
||||
NCollection_Array1<int> 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<double>(1, temp_cos_ptr->Length() - 1);
|
||||
SinNumeratorPtr = new NCollection_HArray1<double>(1, temp_cos_ptr->Length() - 1);
|
||||
DenominatorPtr = new NCollection_HArray1<double>(1, temp_cos_ptr->Length() - 1);
|
||||
for (ii = temp_cos_ptr->Lower(); ii <= temp_cos_ptr->Upper() - 1; ii++)
|
||||
Knots,
|
||||
Mults);
|
||||
CosNumerator = NCollection_Array1<double>(1, temp_cos.Length() - 1);
|
||||
SinNumerator = NCollection_Array1<double>(1, temp_cos.Length() - 1);
|
||||
Denominator = NCollection_Array1<double>(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<double> flat_knots(1, num_flat_knots);
|
||||
CosNumeratorPtr = new NCollection_HArray1<double>(1, num_periodic_poles);
|
||||
SinNumeratorPtr = new NCollection_HArray1<double>(1, num_periodic_poles);
|
||||
DenominatorPtr = new NCollection_HArray1<double>(1, num_periodic_poles);
|
||||
CosNumerator = NCollection_Array1<double>(1, num_periodic_poles);
|
||||
SinNumerator = NCollection_Array1<double>(1, num_periodic_poles);
|
||||
Denominator = NCollection_Array1<double>(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<double>(1, num_knots);
|
||||
MultsPtr = new NCollection_HArray1<int>(1, num_knots);
|
||||
Knots = NCollection_Array1<double>(1, num_knots);
|
||||
Mults = NCollection_Array1<int>(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<double> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,12 @@
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
#include <Convert_ParameterisationType.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Convert_ParameterisationType.hxx>
|
||||
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<NCollection_HArray1<double>>& CosNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& SinNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& Denominator,
|
||||
int& Degree,
|
||||
occ::handle<NCollection_HArray1<double>>& Knots,
|
||||
occ::handle<NCollection_HArray1<int>>& Mults) const;
|
||||
//! Returns the poles of the BSpline curve.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<gp_Pnt2d>& Poles() const;
|
||||
|
||||
Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType Parametrisation,
|
||||
const double UFirst,
|
||||
const double ULast,
|
||||
occ::handle<NCollection_HArray1<double>>& CosNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& SinNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& Denominator,
|
||||
int& Degree,
|
||||
occ::handle<NCollection_HArray1<double>>& Knots,
|
||||
occ::handle<NCollection_HArray1<int>>& Mults) const;
|
||||
//! Returns the weights of the BSpline curve.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<double>& Weights() const;
|
||||
|
||||
//! Returns the knots of the BSpline curve.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<double>& Knots() const;
|
||||
|
||||
//! Returns the multiplicities of the BSpline curve.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<int>& 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<NCollection_HArray1<double>>& theCosNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& theSinNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& theDenominator,
|
||||
int& theDegree,
|
||||
occ::handle<NCollection_HArray1<double>>& theKnots,
|
||||
occ::handle<NCollection_HArray1<int>>& 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<NCollection_HArray1<double>>& theCosNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& theSinNumerator,
|
||||
occ::handle<NCollection_HArray1<double>>& theDenominator,
|
||||
int& theDegree,
|
||||
occ::handle<NCollection_HArray1<double>>& theKnots,
|
||||
occ::handle<NCollection_HArray1<int>>& 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<NCollection_HArray1<gp_Pnt2d>> poles;
|
||||
occ::handle<NCollection_HArray1<double>> weights;
|
||||
occ::handle<NCollection_HArray1<double>> knots;
|
||||
occ::handle<NCollection_HArray1<int>> mults;
|
||||
int degree;
|
||||
int nbPoles;
|
||||
int nbKnots;
|
||||
bool isperiodic;
|
||||
Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType theParametrisation,
|
||||
NCollection_Array1<double>& theCosNumerator,
|
||||
NCollection_Array1<double>& theSinNumerator,
|
||||
NCollection_Array1<double>& theDenominator,
|
||||
int& theDegree,
|
||||
NCollection_Array1<double>& theKnots,
|
||||
NCollection_Array1<int>& theMults) const;
|
||||
|
||||
Standard_EXPORT void BuildCosAndSin(const Convert_ParameterisationType theParametrisation,
|
||||
const double theUFirst,
|
||||
const double theULast,
|
||||
NCollection_Array1<double>& theCosNumerator,
|
||||
NCollection_Array1<double>& theSinNumerator,
|
||||
NCollection_Array1<double>& theDenominator,
|
||||
int& theDegree,
|
||||
NCollection_Array1<double>& theKnots,
|
||||
NCollection_Array1<int>& theMults) const;
|
||||
|
||||
protected:
|
||||
NCollection_Array1<gp_Pnt2d> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
NCollection_Array1<double> myKnots;
|
||||
NCollection_Array1<int> myMults;
|
||||
int myDegree = 0;
|
||||
bool myIsPeriodic = false;
|
||||
};
|
||||
|
||||
#endif // _Convert_ConicToBSplineCurve_HeaderFile
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
|
||||
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<gp_Pnt2d>&,
|
||||
const NCollection_Array1<double>&,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
+143
-59
@@ -18,135 +18,219 @@
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
|
||||
//=================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
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<gp_Pnt>&
|
||||
Convert_ElementarySurfaceToBSplineSurface::Poles() const
|
||||
{
|
||||
return myPoles;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array2<double>& Convert_ElementarySurfaceToBSplineSurface::Weights() const
|
||||
{
|
||||
return myWeights;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<double>& Convert_ElementarySurfaceToBSplineSurface::UKnots() const
|
||||
{
|
||||
return myUKnots;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<double>& Convert_ElementarySurfaceToBSplineSurface::VKnots() const
|
||||
{
|
||||
return myVKnots;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<int>& Convert_ElementarySurfaceToBSplineSurface::UMultiplicities() const
|
||||
{
|
||||
return myUMults;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<int>& Convert_ElementarySurfaceToBSplineSurface::VMultiplicities() const
|
||||
{
|
||||
return myVMults;
|
||||
}
|
||||
|
||||
+83
-89
@@ -20,132 +20,126 @@
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
class gp_Pnt;
|
||||
#include <NCollection_Array2.hxx>
|
||||
|
||||
//! 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<gp_Pnt>& Poles() const;
|
||||
|
||||
NCollection_Array2<gp_Pnt> poles;
|
||||
NCollection_Array2<double> weights;
|
||||
NCollection_Array1<double> uknots;
|
||||
NCollection_Array1<int> umults;
|
||||
NCollection_Array1<double> vknots;
|
||||
NCollection_Array1<int> 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<double>& Weights() const;
|
||||
|
||||
//! Returns the U-knots of the BSpline surface.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<double>& UKnots() const;
|
||||
|
||||
//! Returns the V-knots of the BSpline surface.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<double>& VKnots() const;
|
||||
|
||||
//! Returns the U-multiplicities of the BSpline surface.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<int>& UMultiplicities() const;
|
||||
|
||||
//! Returns the V-multiplicities of the BSpline surface.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<int>& 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<gp_Pnt> myPoles;
|
||||
NCollection_Array2<double> myWeights;
|
||||
NCollection_Array1<double> myUKnots;
|
||||
NCollection_Array1<double> myVKnots;
|
||||
NCollection_Array1<int> myUMults;
|
||||
NCollection_Array1<int> 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
|
||||
|
||||
@@ -24,14 +24,13 @@
|
||||
#include <Standard_DomainError.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
|
||||
// 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<NCollection_HArray1<double>> CosNumeratorPtr, SinNumeratorPtr;
|
||||
double R, r, value;
|
||||
NCollection_Array1<double> 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<gp_Pnt2d>(1, nbPoles);
|
||||
myPoles = NCollection_Array1<gp_Pnt2d>(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<NCollection_HArray1<double>> CosNumeratorPtr, SinNumeratorPtr;
|
||||
int ii;
|
||||
double R, r, value;
|
||||
NCollection_Array1<double> 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<gp_Pnt2d>(1, nbPoles);
|
||||
myPoles = NCollection_Array1<gp_Pnt2d>(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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,9 @@ Convert_GridPolynomialToPoles::Convert_GridPolynomialToPoles(
|
||||
const occ::handle<NCollection_HArray1<double>>& Coefficients,
|
||||
const occ::handle<NCollection_HArray1<double>>& PolynomialUIntervals,
|
||||
const occ::handle<NCollection_HArray1<double>>& 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<NCollection_HArray1<double>>& PolynomialVIntervals,
|
||||
const occ::handle<NCollection_HArray1<double>>& TrueUIntervals,
|
||||
const occ::handle<NCollection_HArray1<double>>& 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<NCollection_HArray1<double>>& TrueVIntervals)
|
||||
{
|
||||
// (1) Construction des Tables monodimensionnelles ----------------------------
|
||||
occ::handle<NCollection_HArray1<double>> UParameters, VParameters;
|
||||
myUKnots = new (NCollection_HArray1<double>)(1, TrueUIntervals->Length());
|
||||
myUKnots->ChangeArray1() = TrueUIntervals->Array1();
|
||||
myVKnots = new (NCollection_HArray1<double>)(1, TrueVIntervals->Length());
|
||||
myVKnots->ChangeArray1() = TrueVIntervals->Array1();
|
||||
NCollection_Array1<double> UParameters, VParameters;
|
||||
myUKnots = NCollection_Array1<double>(TrueUIntervals->Array1());
|
||||
myVKnots = NCollection_Array1<double>(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<gp_Pnt>)(1, UParameters->Length(), 1, VParameters->Length());
|
||||
myPoles = NCollection_Array2<gp_Pnt>(1, UParameters.Length(), 1, VParameters.Length());
|
||||
|
||||
NCollection_Array1<double> Patch(1, (myUDegree + 1) * dimension);
|
||||
NCollection_Array1<double> 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<NCollection_HArray1<double>>& Knots,
|
||||
const int Continuity,
|
||||
occ::handle<NCollection_HArray1<double>>& FlatKnots,
|
||||
occ::handle<NCollection_HArray1<int>>& Mults,
|
||||
occ::handle<NCollection_HArray1<double>>& Parameters) const
|
||||
void Convert_GridPolynomialToPoles::BuildArray(const int Degree,
|
||||
const NCollection_Array1<double>& Knots,
|
||||
const int Continuity,
|
||||
NCollection_Array1<double>& FlatKnots,
|
||||
NCollection_Array1<int>& Mults,
|
||||
NCollection_Array1<double>& 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<int>)(1, Knots->Length());
|
||||
const int multiplicities = Degree - Continuity;
|
||||
Mults = NCollection_Array1<int>(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<double>(1, num_flat_knots);
|
||||
const int num_flat_knots = multiplicities * (NumCurves - 1) + 2 * Degree + 2;
|
||||
FlatKnots = NCollection_Array1<double>(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<double>)(1, num_poles);
|
||||
BSplCLib::BuildSchoenbergPoints(Degree, FlatKnots->Array1(), Parameters->ChangeArray1());
|
||||
Parameters = NCollection_Array1<double>(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<NCollection_HArray2<gp_Pnt>>& Convert_GridPolynomialToPoles::Poles() const
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array2<gp_Pnt>& 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<NCollection_HArray1<double>>& Convert_GridPolynomialToPoles::UKnots() const
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<double>& Convert_GridPolynomialToPoles::UKnots() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
|
||||
return myUKnots;
|
||||
}
|
||||
|
||||
const occ::handle<NCollection_HArray1<double>>& Convert_GridPolynomialToPoles::VKnots() const
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<double>& Convert_GridPolynomialToPoles::VKnots() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
|
||||
return myVKnots;
|
||||
}
|
||||
|
||||
const occ::handle<NCollection_HArray1<int>>& Convert_GridPolynomialToPoles::UMultiplicities() const
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<int>& Convert_GridPolynomialToPoles::UMultiplicities() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
|
||||
return myUMults;
|
||||
}
|
||||
|
||||
const occ::handle<NCollection_HArray1<int>>& Convert_GridPolynomialToPoles::VMultiplicities() const
|
||||
//==================================================================================================
|
||||
|
||||
const NCollection_Array1<int>& Convert_GridPolynomialToPoles::VMultiplicities() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
|
||||
return myVMults;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
bool Convert_GridPolynomialToPoles::IsDone() const
|
||||
{
|
||||
return myDone;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
#include <NCollection_HArray2.hxx>
|
||||
@@ -81,6 +80,43 @@ public:
|
||||
const occ::handle<NCollection_HArray1<double>>& TrueUIntervals,
|
||||
const occ::handle<NCollection_HArray1<double>>& 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<gp_Pnt>& 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<double>& UKnots() const;
|
||||
|
||||
//! Returns the knots in the V direction.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<double>& VKnots() const;
|
||||
|
||||
//! Returns the multiplicities of the knots in the U direction.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<int>& UMultiplicities() const;
|
||||
|
||||
//! Returns the multiplicities of the knots in the V direction.
|
||||
[[nodiscard]] Standard_EXPORT const NCollection_Array1<int>& 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<NCollection_HArray1<double>>& TrueUIntervals,
|
||||
const occ::handle<NCollection_HArray1<double>>& TrueVIntervals);
|
||||
|
||||
Standard_EXPORT int NbUPoles() const;
|
||||
|
||||
Standard_EXPORT int NbVPoles() const;
|
||||
|
||||
//! returns the poles of the BSpline Surface
|
||||
Standard_EXPORT const occ::handle<NCollection_HArray2<gp_Pnt>>& 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<NCollection_HArray1<double>>& UKnots() const;
|
||||
|
||||
//! Knots in the V direction
|
||||
Standard_EXPORT const occ::handle<NCollection_HArray1<double>>& VKnots() const;
|
||||
|
||||
//! Multiplicities of the knots in the U direction
|
||||
Standard_EXPORT const occ::handle<NCollection_HArray1<int>>& UMultiplicities() const;
|
||||
|
||||
//! Multiplicities of the knots in the V direction
|
||||
Standard_EXPORT const occ::handle<NCollection_HArray1<int>>& VMultiplicities() const;
|
||||
|
||||
Standard_EXPORT bool IsDone() const;
|
||||
Standard_EXPORT void BuildArray(const int Degree,
|
||||
const NCollection_Array1<double>& Knots,
|
||||
const int Continuity,
|
||||
NCollection_Array1<double>& FlatKnots,
|
||||
NCollection_Array1<int>& Mults,
|
||||
NCollection_Array1<double>& Parameters) const;
|
||||
|
||||
private:
|
||||
Standard_EXPORT void BuildArray(const int Degree,
|
||||
const occ::handle<NCollection_HArray1<double>>& Knots,
|
||||
const int Continuty,
|
||||
occ::handle<NCollection_HArray1<double>>& FlatKnots,
|
||||
occ::handle<NCollection_HArray1<int>>& Mults,
|
||||
occ::handle<NCollection_HArray1<double>>& Parameters) const;
|
||||
|
||||
occ::handle<NCollection_HArray1<double>> myUFlatKnots;
|
||||
occ::handle<NCollection_HArray1<double>> myVFlatKnots;
|
||||
occ::handle<NCollection_HArray1<double>> myUKnots;
|
||||
occ::handle<NCollection_HArray1<double>> myVKnots;
|
||||
occ::handle<NCollection_HArray1<int>> myUMults;
|
||||
occ::handle<NCollection_HArray1<int>> myVMults;
|
||||
occ::handle<NCollection_HArray2<gp_Pnt>> myPoles;
|
||||
int myUDegree;
|
||||
int myVDegree;
|
||||
bool myDone;
|
||||
NCollection_Array1<double> myUFlatKnots;
|
||||
NCollection_Array1<double> myVFlatKnots;
|
||||
NCollection_Array1<double> myUKnots;
|
||||
NCollection_Array1<double> myVKnots;
|
||||
NCollection_Array1<int> myUMults;
|
||||
NCollection_Array1<int> myVMults;
|
||||
NCollection_Array2<gp_Pnt> myPoles;
|
||||
int myUDegree;
|
||||
int myVDegree;
|
||||
bool myDone;
|
||||
};
|
||||
|
||||
#endif // _Convert_GridPolynomialToPoles_HeaderFile
|
||||
|
||||
@@ -18,17 +18,16 @@
|
||||
#include <gp.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
#include <gp_Hypr2d.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -18,17 +18,16 @@
|
||||
#include <gp.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
#include <gp_Parab2d.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_XY.hxx>
|
||||
|
||||
#include <BSplCLib.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
|
||||
#include <array>
|
||||
|
||||
static double Locate(const double Angfin,
|
||||
const NCollection_Array1<gp_Pnt2d>& 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<NCollection_HArray1<double>>& CosNumeratorPtr,
|
||||
occ::handle<NCollection_HArray1<double>>& SinNumeratorPtr,
|
||||
occ::handle<NCollection_HArray1<double>>& DenominatorPtr)
|
||||
void BuildPolynomialCosAndSin(const double UFirst,
|
||||
const double ULast,
|
||||
const int num_poles,
|
||||
NCollection_Array1<double>& CosNumerator,
|
||||
NCollection_Array1<double>& SinNumerator,
|
||||
NCollection_Array1<double>& 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<gp_Pnt2d> 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<double, 2> knot_array = {0.0e0, 1.0e0};
|
||||
std::array<int, 2> mults_array = {degree + 1, degree + 1};
|
||||
|
||||
NCollection_Array1<double> the_knots(knot_array[0], 1, 2), the_new_knots(knot_array[0], 1, 2);
|
||||
NCollection_Array1<int> 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<NCollection_HArray1<double>>& CosNumeratorPtr,
|
||||
occ::handle<NCollection_HArray1<double>>& SinNumeratorPtr,
|
||||
occ::handle<NCollection_HArray1<double>>& 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<double> FlatKnots(1,2*num_poles);
|
||||
NCollection_Array1<double> Parameters(1,num_poles);
|
||||
NCollection_Array1<int> ContactOrderArray(1,num_poles);
|
||||
NCollection_Array1<gp_Pnt2d> Poles(1,num_poles);
|
||||
NCollection_Array1<gp_Pnt2d> 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.);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -18,14 +18,13 @@
|
||||
#define Convert_PolynomialCosAndSin_HeaderFile
|
||||
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
|
||||
void BuildPolynomialCosAndSin(const double,
|
||||
const double,
|
||||
const int,
|
||||
occ::handle<NCollection_HArray1<double>>&,
|
||||
occ::handle<NCollection_HArray1<double>>&,
|
||||
occ::handle<NCollection_HArray1<double>>&);
|
||||
void BuildPolynomialCosAndSin(const double theUFirst,
|
||||
const double theULast,
|
||||
const int theNumPoles,
|
||||
NCollection_Array1<double>& theCosNumerator,
|
||||
NCollection_Array1<double>& theSinNumerator,
|
||||
NCollection_Array1<double>& theDenominator);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <Standard_DomainError.hxx>
|
||||
|
||||
#include <array>
|
||||
|
||||
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<double, MaxNbVPoles> x;
|
||||
std::array<double, MaxNbVPoles> 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();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <Standard_DomainError.hxx>
|
||||
|
||||
#include <array>
|
||||
|
||||
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<double, MaxNbVPoles> x;
|
||||
std::array<double, MaxNbVPoles> 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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <Convert_CircleToBSplineCurve.hxx>
|
||||
#include <Convert_ParameterisationType.hxx>
|
||||
#include <gp_Ax2d.hxx>
|
||||
#include <gp_Circ2d.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
|
||||
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<double>& 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<double>& 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<double>& 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<double>& 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<gp_Pnt2d>& 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<double>& 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<double>& 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<double>& 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<double>& 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<double>& aWeights = aConv.Weights();
|
||||
for (int i = 1; i <= aConv.NbPoles(); ++i)
|
||||
{
|
||||
EXPECT_GT(aWeights(i), 0.0);
|
||||
}
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <Convert_CompBezierCurvesToBSplineCurve.hxx>
|
||||
#include <Convert_CompBezierCurves2dToBSplineCurve2d.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
|
||||
TEST(Convert_CompBezierCurvesToBSplineCurveTest, SingleLinearBezier)
|
||||
{
|
||||
Convert_CompBezierCurvesToBSplineCurve aConv;
|
||||
|
||||
NCollection_Array1<gp_Pnt> 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<gp_Pnt> 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<gp_Pnt> 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<gp_Pnt> 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<gp_Pnt> 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<gp_Pnt> aResPoles(1, aConv.NbPoles());
|
||||
NCollection_Array1<double> aKnots(1, aConv.NbKnots());
|
||||
NCollection_Array1<int> 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<gp_Pnt> 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<gp_Pnt> 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<int> aMults(1, aConv.NbKnots());
|
||||
NCollection_Array1<double> 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<gp_Pnt> 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<gp_Pnt> 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<gp_Pnt2d> 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<gp_Pnt2d> 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<gp_Pnt2d> 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<gp_Pnt2d> 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<int> aMults(1, aConv.NbKnots());
|
||||
NCollection_Array1<double> aKnots(1, aConv.NbKnots());
|
||||
aConv.KnotsAndMults(aKnots, aMults);
|
||||
EXPECT_EQ(aMults(2), aConv.Degree() - 1);
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <Convert_CompPolynomialToPoles.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <NCollection_HArray2.hxx>
|
||||
|
||||
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<double> aCoeffs(1, 2);
|
||||
aCoeffs(1) = 1.0; // constant term
|
||||
aCoeffs(2) = 2.0; // linear term
|
||||
|
||||
NCollection_Array1<double> aPolyIntervals(1, 2);
|
||||
aPolyIntervals(1) = -1.0;
|
||||
aPolyIntervals(2) = 1.0;
|
||||
|
||||
NCollection_Array1<double> 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<double> aCoeffs(1, 3);
|
||||
aCoeffs(1) = 0.0; // x^0
|
||||
aCoeffs(2) = 0.0; // x^1
|
||||
aCoeffs(3) = 1.0; // x^2
|
||||
|
||||
NCollection_Array1<double> aPolyIntervals(1, 2);
|
||||
aPolyIntervals(1) = 0.0;
|
||||
aPolyIntervals(2) = 1.0;
|
||||
|
||||
NCollection_Array1<double> 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<NCollection_HArray1<int>> aNumCoeff = new NCollection_HArray1<int>(1, 2);
|
||||
aNumCoeff->SetValue(1, 2); // linear = 2 coefficients
|
||||
aNumCoeff->SetValue(2, 2);
|
||||
|
||||
// Coefficients: [curve1: c0, c1] [curve2: c0, c1]
|
||||
occ::handle<NCollection_HArray1<double>> aCoeffs = new NCollection_HArray1<double>(1, 4);
|
||||
aCoeffs->SetValue(1, 0.0);
|
||||
aCoeffs->SetValue(2, 1.0);
|
||||
aCoeffs->SetValue(3, 1.0);
|
||||
aCoeffs->SetValue(4, -1.0);
|
||||
|
||||
occ::handle<NCollection_HArray2<double>> aPolyIntervals =
|
||||
new NCollection_HArray2<double>(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<NCollection_HArray1<double>> aTrueIntervals = new NCollection_HArray1<double>(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<double> 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<double> aPolyIntervals(1, 2);
|
||||
aPolyIntervals(1) = 0.0;
|
||||
aPolyIntervals(2) = 1.0;
|
||||
|
||||
NCollection_Array1<double> 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<double>& aPoles = aConv.Poles();
|
||||
// Poles should be [1..NbPoles][1..3]
|
||||
EXPECT_EQ(aPoles.RowLength(), 3);
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <BSplSLib.hxx>
|
||||
#include <Convert_ConeToBSplineSurface.hxx>
|
||||
#include <gp_Cone.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
|
||||
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<double>& 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<double>& aUK = aConv.UKnots();
|
||||
const NCollection_Array1<double>& 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <BSplSLib.hxx>
|
||||
#include <Convert_CylinderToBSplineSurface.hxx>
|
||||
#include <gp_Cylinder.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
|
||||
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<double>& 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<double>& aUKnots = aConv.UKnots();
|
||||
for (int i = 2; i <= aConv.NbUKnots(); ++i)
|
||||
{
|
||||
EXPECT_GT(aUKnots(i), aUKnots(i - 1));
|
||||
}
|
||||
const NCollection_Array1<double>& 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<double>& aUK = aConv.UKnots();
|
||||
const NCollection_Array1<double>& 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <Convert_EllipseToBSplineCurve.hxx>
|
||||
#include <Convert_ParameterisationType.hxx>
|
||||
#include <gp_Ax2d.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
#include <gp_Elips2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
|
||||
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<double>& 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<double>& 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<int>& 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<gp_Pnt2d>& 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<double>& 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<double>& 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<double>& 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<double>& 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<double>& aWeights = aConv.Weights();
|
||||
for (int i = 1; i <= aConv.NbPoles(); ++i)
|
||||
{
|
||||
EXPECT_GT(aWeights(i), 0.0);
|
||||
}
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <Convert_GridPolynomialToPoles.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
|
||||
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<NCollection_HArray1<int>> aNumCoeff = new NCollection_HArray1<int>(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<NCollection_HArray1<double>> aCoeffs = new NCollection_HArray1<double>(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<NCollection_HArray1<double>> aPolyU = new NCollection_HArray1<double>(1, 2);
|
||||
aPolyU->SetValue(1, 0.0);
|
||||
aPolyU->SetValue(2, 1.0);
|
||||
|
||||
occ::handle<NCollection_HArray1<double>> aPolyV = new NCollection_HArray1<double>(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<gp_Pnt>& aPoles = aConv.Poles();
|
||||
EXPECT_GT(aPoles.Size(), 0);
|
||||
}
|
||||
|
||||
TEST(Convert_GridPolynomialToPolesTest, QueryMethods)
|
||||
{
|
||||
const int aMaxUDeg = 1;
|
||||
const int aMaxVDeg = 1;
|
||||
|
||||
occ::handle<NCollection_HArray1<int>> aNumCoeff = new NCollection_HArray1<int>(1, 2);
|
||||
aNumCoeff->SetValue(1, 2);
|
||||
aNumCoeff->SetValue(2, 2);
|
||||
|
||||
occ::handle<NCollection_HArray1<double>> aCoeffs = new NCollection_HArray1<double>(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<NCollection_HArray1<double>> aPolyU = new NCollection_HArray1<double>(1, 2);
|
||||
aPolyU->SetValue(1, 0.0);
|
||||
aPolyU->SetValue(2, 1.0);
|
||||
|
||||
occ::handle<NCollection_HArray1<double>> aPolyV = new NCollection_HArray1<double>(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<double>& aUKnots = aConv.UKnots();
|
||||
const NCollection_Array1<double>& aVKnots = aConv.VKnots();
|
||||
const NCollection_Array1<int>& aUMults = aConv.UMultiplicities();
|
||||
const NCollection_Array1<int>& 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());
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <Convert_HyperbolaToBSplineCurve.hxx>
|
||||
#include <gp_Ax2d.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
#include <gp_Hypr2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
|
||||
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<gp_Pnt2d>& 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<double>& 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<double>& 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<int>& 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<gp_Pnt2d>& 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<double>& 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<double>& 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<double>& aWeights = aConv.Weights();
|
||||
for (int i = 1; i <= aConv.NbPoles(); ++i)
|
||||
{
|
||||
EXPECT_GT(aWeights(i), 0.0);
|
||||
}
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <Convert_ParabolaToBSplineCurve.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
#include <gp_Parab2d.hxx>
|
||||
#include <gp_Ax2d.hxx>
|
||||
#include <gp_Ax22d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
void checkParabolaPoint(const Convert_ParabolaToBSplineCurve& theConv,
|
||||
const gp_Parab2d& theParab,
|
||||
const double theParam)
|
||||
{
|
||||
const NCollection_Array1<gp_Pnt2d>& aPoles = theConv.Poles();
|
||||
const NCollection_Array1<double>& aWeights = theConv.Weights();
|
||||
const NCollection_Array1<double>& aKnots = theConv.Knots();
|
||||
const NCollection_Array1<int>& 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<double>& aWeights = aConv.Weights();
|
||||
for (int i = aWeights.Lower(); i <= aWeights.Upper(); ++i)
|
||||
{
|
||||
EXPECT_NEAR(aWeights(i), 1.0, 1.0e-15);
|
||||
}
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <BSplSLib.hxx>
|
||||
#include <Convert_SphereToBSplineSurface.hxx>
|
||||
#include <gp_Sphere.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
|
||||
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<double>& 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<double>& aUKnots = aConv.UKnots();
|
||||
for (int i = 2; i <= aConv.NbUKnots(); ++i)
|
||||
{
|
||||
EXPECT_GT(aUKnots(i), aUKnots(i - 1));
|
||||
}
|
||||
const NCollection_Array1<double>& 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<double>& aUK = aConv.UKnots();
|
||||
const NCollection_Array1<double>& 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <gtest/gtest.h>
|
||||
|
||||
#include <BSplSLib.hxx>
|
||||
#include <Convert_TorusToBSplineSurface.hxx>
|
||||
#include <gp_Torus.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
|
||||
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<double>& 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<double>& aUKnots = aConv.UKnots();
|
||||
for (int i = 2; i <= aConv.NbUKnots(); ++i)
|
||||
{
|
||||
EXPECT_GT(aUKnots(i), aUKnots(i - 1));
|
||||
}
|
||||
const NCollection_Array1<double>& 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<double>& aUK = aConv.UKnots();
|
||||
const NCollection_Array1<double>& 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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<TheItemType>(theItem))
|
||||
{
|
||||
myValue = std::forward<TheItemType>(theItem);
|
||||
}
|
||||
|
||||
//! Constructor with in-place value construction
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <StdFail_NotDone.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <StdFail_NotDone.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
@@ -77,7 +77,7 @@ void GeomFill_PolynomialConvertor::Init()
|
||||
Coeffs,
|
||||
Inter,
|
||||
TrueInter); En attente du bon Geomlite*/
|
||||
AConverter.Poles(Poles1d);
|
||||
Poles1d = new NCollection_HArray2<double>(AConverter.Poles());
|
||||
|
||||
for (jj = 1; jj <= Ordre; jj++)
|
||||
{
|
||||
|
||||
@@ -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<double>(AConverter.Poles());
|
||||
|
||||
for (jj = 1; jj <= Ordre; jj++)
|
||||
{
|
||||
|
||||
@@ -844,22 +844,21 @@ void AdvApprox_ApproxAFunction::Perform(const int Num1DSS,
|
||||
|
||||
if (AConverter.IsDone())
|
||||
{
|
||||
occ::handle<NCollection_HArray2<double>> PolesPtr;
|
||||
AConverter.Poles(PolesPtr);
|
||||
AConverter.Knots(myKnots);
|
||||
AConverter.Multiplicities(myMults);
|
||||
const NCollection_Array2<double>& aPoles = AConverter.Poles();
|
||||
myKnots = new NCollection_HArray1<double>(AConverter.Knots());
|
||||
myMults = new NCollection_HArray1<int>(AConverter.Multiplicities());
|
||||
myDegree = AConverter.Degree();
|
||||
index = 0;
|
||||
if (myNumSubSpaces[0] > 0)
|
||||
{
|
||||
my1DPoles = new NCollection_HArray2<double>(1, PolesPtr->ColLength(), 1, myNumSubSpaces[0]);
|
||||
my1DMaxError = new NCollection_HArray1<double>(1, myNumSubSpaces[0]);
|
||||
my1DPoles = new NCollection_HArray2<double>(1, aPoles.ColLength(), 1, myNumSubSpaces[0]);
|
||||
my1DMaxError = new NCollection_HArray1<double>(1, myNumSubSpaces[0]);
|
||||
my1DAverageError = new NCollection_HArray1<double>(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<gp_Pnt2d>(1, PolesPtr->ColLength(), 1, myNumSubSpaces[1]);
|
||||
my2DPoles = new NCollection_HArray2<gp_Pnt2d>(1, aPoles.ColLength(), 1, myNumSubSpaces[1]);
|
||||
my2DMaxError = new NCollection_HArray1<double>(1, myNumSubSpaces[1]);
|
||||
my2DAverageError = new NCollection_HArray1<double>(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<gp_Pnt>(1, PolesPtr->ColLength(), 1, myNumSubSpaces[2]);
|
||||
my3DMaxError = new NCollection_HArray1<double>(1, myNumSubSpaces[2]);
|
||||
my3DPoles = new NCollection_HArray2<gp_Pnt>(1, aPoles.ColLength(), 1, myNumSubSpaces[2]);
|
||||
my3DMaxError = new NCollection_HArray1<double>(1, myNumSubSpaces[2]);
|
||||
my3DAverageError = new NCollection_HArray1<double>(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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -1157,7 +1157,7 @@ occ::handle<NCollection_HArray2<gp_Pnt>> AdvApp2Var_Patch::Poles(
|
||||
Intervalle,
|
||||
Intervalle);
|
||||
|
||||
return Conv.Poles();
|
||||
return new NCollection_HArray2<gp_Pnt>(Conv.Poles());
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#define No_Standard_DimensionError
|
||||
#define No_Standard_ConstructionError
|
||||
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <iomanip>
|
||||
@@ -551,24 +549,23 @@ void AppDef_Variational::Approximate()
|
||||
IntervallesPtr);
|
||||
if (AConverter.IsDone())
|
||||
{
|
||||
occ::handle<NCollection_HArray2<double>> PolesPtr;
|
||||
occ::handle<NCollection_HArray1<int>> Mults;
|
||||
int NbPoles = AConverter.NbPoles();
|
||||
occ::handle<NCollection_HArray1<int>> Mults;
|
||||
int NbPoles = AConverter.NbPoles();
|
||||
// int Deg=AConverter.Degree();
|
||||
NCollection_Array1<AppParCurves_MultiPoint> TabMU(1, NbPoles);
|
||||
AConverter.Poles(PolesPtr);
|
||||
AConverter.Knots(myKnots);
|
||||
AConverter.Multiplicities(Mults);
|
||||
const NCollection_Array2<double>& aPoles = AConverter.Poles();
|
||||
myKnots = new NCollection_HArray1<double>(AConverter.Knots());
|
||||
Mults = new NCollection_HArray1<int>(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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,24 +74,12 @@ static occ::handle<Geom2d_BSplineCurve> BSplineCurveBuilder(
|
||||
{
|
||||
|
||||
occ::handle<Geom2d_BSplineCurve> 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.)
|
||||
|
||||
@@ -62,30 +62,19 @@ static occ::handle<Geom_BSplineCurve> BSplineCurveBuilder(
|
||||
const Convert_ConicToBSplineCurve& Convert)
|
||||
|
||||
{
|
||||
occ::handle<Geom_BSplineCurve> TheCurve;
|
||||
int NbPoles = Convert.NbPoles();
|
||||
int NbKnots = Convert.NbKnots();
|
||||
NCollection_Array1<gp_Pnt> Poles(1, NbPoles);
|
||||
NCollection_Array1<double> Weights(1, NbPoles);
|
||||
NCollection_Array1<double> Knots(1, NbKnots);
|
||||
NCollection_Array1<int> Mults(1, NbKnots);
|
||||
int i;
|
||||
gp_Pnt2d P2d;
|
||||
gp_Pnt P3d;
|
||||
for (i = 1; i <= NbPoles; i++)
|
||||
occ::handle<Geom_BSplineCurve> TheCurve;
|
||||
const NCollection_Array1<gp_Pnt2d>& aPoles2d = Convert.Poles();
|
||||
const NCollection_Array1<double>& aWeights = Convert.Weights();
|
||||
const NCollection_Array1<double>& aKnots = Convert.Knots();
|
||||
const NCollection_Array1<int>& aMults = Convert.Multiplicities();
|
||||
NCollection_Array1<gp_Pnt> 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<Geom_BSplineCurve> Cres;
|
||||
|
||||
@@ -48,15 +48,9 @@
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_Array2.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
|
||||
typedef Geom_Surface Surface;
|
||||
typedef Geom_BSplineSurface BSplineSurface;
|
||||
typedef NCollection_Array1<double> Array1OfReal;
|
||||
typedef NCollection_Array2<double> Array2OfReal;
|
||||
typedef NCollection_Array1<int> Array1OfInteger;
|
||||
typedef NCollection_Array2<gp_Pnt> Array2OfPnt;
|
||||
typedef gp_Pnt Pnt;
|
||||
typedef Geom_Surface Surface;
|
||||
typedef Geom_BSplineSurface BSplineSurface;
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -64,45 +58,14 @@ static occ::handle<Geom_BSplineSurface> BSplineSurfaceBuilder(
|
||||
const Convert_ElementarySurfaceToBSplineSurface& Convert)
|
||||
{
|
||||
occ::handle<Geom_BSplineSurface> 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;
|
||||
|
||||
Reference in New Issue
Block a user