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:
Pasukhin Dmitry
2026-02-09 16:38:55 +00:00
committed by GitHub
parent 87703a2dac
commit 498e7cd173
48 changed files with 3112 additions and 1929 deletions
@@ -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;