mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-09-05 04:07:58 +08:00
Modeling Data, Algorithms - Always-populated weights, direct array access migration, Hermit bug fix (#1058)
Introduce always-populated weight arrays in BSpline/Bezier curve and surface classes using non-owning views over a static unit-weights buffer. Migrate ~100 callers across the codebase from deprecated copy-out APIs to direct const-reference array access. Fix a long-standing typo bug in Hermit.cxx. Infrastructure (BSplCLib, BSplSLib): - Add BSplCLib::UnitWeights(n) returning a non-owning NCollection_Array1 view over a compile-time-initialized static array of 2049 ones; falls back to heap allocation for larger sizes. - Add BSplCLib::MaxUnitWeightsSize() (constexpr 2049) and BSplCLib::UnitWeightsData() exposing the raw pointer for BSplSLib. - Add BSplSLib::UnitWeights(nU, nV) returning a non-owning NCollection_Array2 view when nU*nV <= 2049, heap-allocated otherwise. Always-populated myWeights (Geom/Geom2d curve and surface classes): - myWeights is now always sized to match poles count. Non-rational: non-owning view via UnitWeights (zero allocation). Rational: owning array with actual weight values. - Add WeightsArray() returning const NCollection_Array1<double>& (curves) or const NCollection_Array2<double>& (surfaces) that is always valid. - Update all constructors, copy constructors, and restructuring operations (IncreaseDegree, InsertKnots, RemoveKnot, Segment, SetPeriodic, SetOrigin, SetNotPeriodic, ExchangeUV, etc.) to maintain the invariant. - SetWeight: copies non-owning view to owned array before mutation when transitioning to rational; assigns UnitWeights when becoming non-rational. - Remove myRational derivation from myWeights.Size() in updateKnots(); rationality is now tracked explicitly via the myRational flag only. - Fix Geom2d_BSplineCurve::InsertPoleAfter missing myRational update after inserting a weighted pole. - Fix Geom_BSplineCurve::DumpJson stale myWeights.Size() > 0 guard (changed to myRational, matching all other classes). Caller migration to direct array access (~100 files): - Replace deprecated copy-out pattern (allocate temp + call Foo(temp)) with const-reference access for Poles(), Knots(), Multiplicities(), UKnots(), VKnots(), UMultiplicities(), VMultiplicities(), KnotSequence(), UKnotSequence(), VKnotSequence(). - Replace Weights() null-pointer patterns with WeightsArray() const-ref or *Weights() dereference where null check is still appropriate. - Affected modules: GeomConvert, Geom2dConvert, GeomLib, GeomFill, ProjLib, ShapeUpgrade, ShapeCustom, ShapeConstruct, ShapeAnalysis, ShapeAlgo, BRepLib, BRepGProp, HLRBRep, ChFi3d, ChFiKPart, BlendFunc, FairCurve, IntTools, TopOpeBRepTool, TopOpeBRepBuild, LocOpe, BRepOffset, Adaptor3d, GeomAdaptor, Geom2dAdaptor, BndLib, Extrema, DrawTrSurf, GeometryTest, GeomliteTest, SWDRAW, QABugs, GeomToIGES, IGESToBRep, GeomToStep, StdPrs. Bug fix in Hermit.cxx (PolyTest, both 3D and 2D overloads): - Fix typo: "Pole0 < 3" changed to "Pole0 < Pole3" — was comparing a double variable against the integer literal 3 instead of the variable Pole3 holding the endpoint weight value. - Fix logic: "if (boucle == 1)" changed to "else if (boucle == 1)" to make the boucle==1 and boucle==2 branches mutually exclusive. - Add explanatory comments on BSplCLib::D1 calls that intentionally pass weight values as scalar "poles" to evaluate the weight function. NCollection_PackedMapAlgo migration (TDataStd, QABugs): - Replace deprecated member functions (IsSubset, Subtraction, Subtract, Unite, Intersect, IsEqual) with NCollection_PackedMapAlgo free functions. GTests: - New BSplCLib_Test.cxx: 5 tests for UnitWeights API. - New BSplSLib_Test.cxx: 5 tests for surface UnitWeights API. - New Hermit_Test.cxx: 11 tests for Hermit::Solution (3D/2D) and Hermit::Solutionbis covering uniform, distinct, high-ratio, reversed, symmetric weights and positive-poles invariant. - Add WeightsArray tests to Geom_BSplineCurve_Test, Geom_BezierCurve_Test, Geom_BSplineSurface_Test, Geom_BezierSurface_Test (2 tests each) verifying const-ref return, non-owning for non-rational, owning for rational.
This commit is contained in:
@@ -345,9 +345,13 @@ void BRepGProp_Face::UKnots(NCollection_Array1<double>& Knots) const
|
||||
Knots(3) = M_PI * 4.0 / 3.0;
|
||||
Knots(4) = M_PI * 6.0 / 3.0;
|
||||
break;
|
||||
case GeomAbs_BSplineSurface:
|
||||
(*((occ::handle<Geom_BSplineSurface>*)&((mySurface.Surface()).Surface())))->UKnots(Knots);
|
||||
break;
|
||||
case GeomAbs_BSplineSurface: {
|
||||
const NCollection_Array1<double>& aSrcKnots =
|
||||
(*((occ::handle<Geom_BSplineSurface>*)&((mySurface.Surface()).Surface())))->UKnots();
|
||||
for (int i = Knots.Lower(); i <= Knots.Upper(); i++)
|
||||
Knots(i) = aSrcKnots(i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Knots(1) = mySurface.FirstUParameter();
|
||||
Knots(2) = mySurface.LastUParameter();
|
||||
@@ -378,9 +382,13 @@ void BRepGProp_Face::VKnots(NCollection_Array1<double>& Knots) const
|
||||
Knots(3) = M_PI * 4.0 / 3.0;
|
||||
Knots(4) = M_PI * 6.0 / 3.0;
|
||||
break;
|
||||
case GeomAbs_BSplineSurface:
|
||||
(*((occ::handle<Geom_BSplineSurface>*)&((mySurface.Surface()).Surface())))->VKnots(Knots);
|
||||
break;
|
||||
case GeomAbs_BSplineSurface: {
|
||||
const NCollection_Array1<double>& aSrcKnots =
|
||||
(*((occ::handle<Geom_BSplineSurface>*)&((mySurface.Surface()).Surface())))->VKnots();
|
||||
for (int i = Knots.Lower(); i <= Knots.Upper(); i++)
|
||||
Knots(i) = aSrcKnots(i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Knots(1) = mySurface.FirstUParameter();
|
||||
Knots(2) = mySurface.LastUParameter();
|
||||
@@ -493,9 +501,13 @@ void BRepGProp_Face::LKnots(NCollection_Array1<double>& Knots) const
|
||||
Knots(1) = myCurve.FirstParameter();
|
||||
Knots(2) = myCurve.LastParameter();
|
||||
break;
|
||||
case GeomAbs_BSplineCurve:
|
||||
(*((occ::handle<Geom2d_BSplineCurve>*)&(myCurve.Curve())))->Knots(Knots);
|
||||
break;
|
||||
case GeomAbs_BSplineCurve: {
|
||||
const NCollection_Array1<double>& aSrcKnots =
|
||||
(*((occ::handle<Geom2d_BSplineCurve>*)&(myCurve.Curve())))->Knots();
|
||||
for (int i = Knots.Lower(); i <= Knots.Upper(); i++)
|
||||
Knots(i) = aSrcKnots(i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Knots(1) = myCurve.FirstParameter();
|
||||
Knots(2) = myCurve.LastParameter();
|
||||
@@ -606,13 +618,10 @@ static void GetCurveKnots(const double theMin,
|
||||
if (isSBSpline)
|
||||
{
|
||||
occ::handle<Geom2d_BSplineCurve> aCrv;
|
||||
int aNbKnots;
|
||||
occ::handle<NCollection_HArray1<double>> aCrvKnots;
|
||||
|
||||
aCrv = occ::down_cast<Geom2d_BSplineCurve>(theCurve.Curve());
|
||||
aNbKnots = aCrv->NbKnots();
|
||||
aCrvKnots = new NCollection_HArray1<double>(1, aNbKnots);
|
||||
aCrv->Knots(aCrvKnots->ChangeArray1());
|
||||
aCrvKnots = new NCollection_HArray1<double>(aCrv->Knots());
|
||||
GetRealKnots(theMin, theMax, aCrvKnots, theKnots);
|
||||
}
|
||||
else
|
||||
@@ -649,7 +658,6 @@ void BRepGProp_Face::GetUKnots(const double theUMin
|
||||
{
|
||||
// Using span decomposition for BSpline.
|
||||
occ::handle<NCollection_HArray1<double>> aKnots;
|
||||
int aNbKnots;
|
||||
|
||||
if (isSBSpline)
|
||||
{
|
||||
@@ -658,9 +666,7 @@ void BRepGProp_Face::GetUKnots(const double theUMin
|
||||
occ::handle<Geom_BSplineSurface> aBSplSurf;
|
||||
|
||||
aBSplSurf = occ::down_cast<Geom_BSplineSurface>(aSurf);
|
||||
aNbKnots = aBSplSurf->NbUKnots();
|
||||
aKnots = new NCollection_HArray1<double>(1, aNbKnots);
|
||||
aBSplSurf->UKnots(aKnots->ChangeArray1());
|
||||
aKnots = new NCollection_HArray1<double>(aBSplSurf->UKnots());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -672,9 +678,7 @@ void BRepGProp_Face::GetUKnots(const double theUMin
|
||||
|
||||
aCurve.Load(occ::down_cast<Geom_SurfaceOfLinearExtrusion>(aSurf)->BasisCurve());
|
||||
aBSplCurve = aCurve.BSpline();
|
||||
aNbKnots = aBSplCurve->NbKnots();
|
||||
aKnots = new NCollection_HArray1<double>(1, aNbKnots);
|
||||
aBSplCurve->Knots(aKnots->ChangeArray1());
|
||||
aKnots = new NCollection_HArray1<double>(aBSplCurve->Knots());
|
||||
}
|
||||
|
||||
// Compute number of knots inside theUMin and theUMax.
|
||||
@@ -701,16 +705,13 @@ void BRepGProp_Face::GetTKnots(const double theTMin
|
||||
{
|
||||
// Using span decomposition for BSpline.
|
||||
occ::handle<NCollection_HArray1<double>> aSurfKnots;
|
||||
int aNbKnots;
|
||||
|
||||
// Get V knots of BSpline surface.
|
||||
occ::handle<Geom_Surface> aSurf = mySurface.Surface().Surface();
|
||||
occ::handle<Geom_BSplineSurface> aBSplSurf;
|
||||
|
||||
aBSplSurf = occ::down_cast<Geom_BSplineSurface>(aSurf);
|
||||
aNbKnots = aBSplSurf->NbVKnots();
|
||||
aSurfKnots = new NCollection_HArray1<double>(1, aNbKnots);
|
||||
aBSplSurf->VKnots(aSurfKnots->ChangeArray1());
|
||||
aSurfKnots = new NCollection_HArray1<double>(aBSplSurf->VKnots());
|
||||
|
||||
// occ::handle<NCollection_HArray1<double>> aCurveKnots;
|
||||
|
||||
|
||||
@@ -1348,8 +1348,7 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
|| std::abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion())
|
||||
{
|
||||
|
||||
NCollection_Array1<double> Knotbs2d(1, bs2d->NbKnots());
|
||||
bs2d->Knots(Knotbs2d);
|
||||
NCollection_Array1<double> Knotbs2d(bs2d->Knots());
|
||||
|
||||
for (int Index = 1; Index <= bs2d->NbKnots(); Index++)
|
||||
{
|
||||
@@ -1375,11 +1374,10 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
double Tol2dbail = std::min(UResbail, VResbail);
|
||||
bs2d->D0(bs2d->FirstParameter(), OriginPoint);
|
||||
|
||||
int nbp = bs2d->NbPoles();
|
||||
NCollection_Array1<gp_Pnt2d> poles(1, nbp);
|
||||
bs2d->Poles(poles);
|
||||
gp_Pnt2d p = poles(1), p1;
|
||||
double d = Precision::Infinite();
|
||||
int nbp = bs2d->NbPoles();
|
||||
const NCollection_Array1<gp_Pnt2d>& poles = bs2d->Poles();
|
||||
gp_Pnt2d p = poles(1), p1;
|
||||
double d = Precision::Infinite();
|
||||
for (int ip = 2; ip <= nbp; ip++)
|
||||
{
|
||||
p1 = poles(ip);
|
||||
@@ -1400,8 +1398,7 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
|| std::abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion())
|
||||
{
|
||||
|
||||
NCollection_Array1<double> Knotbs2d(1, bs2d->NbKnots());
|
||||
bs2d->Knots(Knotbs2d);
|
||||
const NCollection_Array1<double>& Knotbs2d = bs2d->Knots();
|
||||
|
||||
for (int Index = 1; Index <= bs2d->NbKnots(); Index++)
|
||||
{
|
||||
@@ -1431,9 +1428,7 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
{
|
||||
if (repar)
|
||||
{
|
||||
int NbKnots = bs2d->NbKnots();
|
||||
NCollection_Array1<double> Knots(1, NbKnots);
|
||||
bs2d->Knots(Knots);
|
||||
NCollection_Array1<double> Knots(bs2d->Knots());
|
||||
// BSplCLib::Reparametrize(f3d,l3d,Knots);
|
||||
BSplCLib::Reparametrize(fC0, lC0, Knots);
|
||||
bs2d->SetKnots(Knots);
|
||||
@@ -1463,13 +1458,12 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
|
||||
if (cont > GeomAbs_C0 && error > std::max(1.e-3, theTolerance))
|
||||
{
|
||||
int NbKnots = bs2d->NbKnots();
|
||||
NCollection_Array1<double> Knots(1, NbKnots);
|
||||
bs2d->Knots(Knots);
|
||||
double critratio = 10.;
|
||||
double dtprev = Knots(2) - Knots(1), dtratio = 1.;
|
||||
double dtmin = dtprev;
|
||||
double dtcur;
|
||||
int NbKnots = bs2d->NbKnots();
|
||||
const NCollection_Array1<double>& Knots = bs2d->Knots();
|
||||
double critratio = 10.;
|
||||
double dtprev = Knots(2) - Knots(1), dtratio = 1.;
|
||||
double dtmin = dtprev;
|
||||
double dtcur;
|
||||
for (int j = 2; j < NbKnots; j++)
|
||||
{
|
||||
dtcur = Knots(j + 1) - Knots(j);
|
||||
@@ -1522,9 +1516,7 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
|
||||
if (std::abs(bs2d->FirstParameter() - fC0) > TolSameRange
|
||||
|| std::abs(bs2d->LastParameter() - lC0) > TolSameRange)
|
||||
{
|
||||
int NbKnots = bs2d->NbKnots();
|
||||
NCollection_Array1<double> Knots(1, NbKnots);
|
||||
bs2d->Knots(Knots);
|
||||
NCollection_Array1<double> Knots(bs2d->Knots());
|
||||
// BSplCLib::Reparametrize(f3d,l3d,Knots);
|
||||
BSplCLib::Reparametrize(fC0, lC0, Knots);
|
||||
bs2d->SetKnots(Knots);
|
||||
|
||||
@@ -76,12 +76,9 @@ static void BCSmoothing(occ::handle<Geom_BSplineCurve>& theC,
|
||||
{
|
||||
|
||||
int aNbKnots = theC->NbKnots();
|
||||
NCollection_Array1<int> aMults(1, aNbKnots);
|
||||
NCollection_Array1<double> aKnots(1, aNbKnots);
|
||||
|
||||
theC->Multiplicities(aMults);
|
||||
theC->Knots(aKnots);
|
||||
int i, m = theC->Degree();
|
||||
NCollection_Array1<int> aMults(theC->Multiplicities());
|
||||
NCollection_Array1<double> aKnots(theC->Knots());
|
||||
int i, m = theC->Degree();
|
||||
m = m - theCont;
|
||||
|
||||
if (m < 1)
|
||||
@@ -912,9 +909,8 @@ bool BRepLib_FuseEdges::SameSupport(const TopoDS_Edge& E1, const TopoDS_Edge& E2
|
||||
return false;
|
||||
}
|
||||
|
||||
NCollection_Array1<gp_Pnt> P1(1, nbpoles), P2(1, nbpoles);
|
||||
B1->Poles(P1);
|
||||
B2->Poles(P2);
|
||||
const NCollection_Array1<gp_Pnt>& P1 = B1->Poles();
|
||||
const NCollection_Array1<gp_Pnt>& P2 = B2->Poles();
|
||||
|
||||
double tol3d = BRep_Tool::Tolerance(E1);
|
||||
for (int p = 1; p <= nbpoles; p++)
|
||||
@@ -925,13 +921,11 @@ bool BRepLib_FuseEdges::SameSupport(const TopoDS_Edge& E1, const TopoDS_Edge& E2
|
||||
}
|
||||
}
|
||||
|
||||
NCollection_Array1<double> K1(1, nbknots), K2(1, nbknots);
|
||||
B1->Knots(K1);
|
||||
B2->Knots(K2);
|
||||
const NCollection_Array1<double>& K1 = B1->Knots();
|
||||
const NCollection_Array1<double>& K2 = B2->Knots();
|
||||
|
||||
NCollection_Array1<int> M1(1, nbknots), M2(1, nbknots);
|
||||
B1->Multiplicities(M1);
|
||||
B2->Multiplicities(M2);
|
||||
const NCollection_Array1<int>& M1 = B1->Multiplicities();
|
||||
const NCollection_Array1<int>& M2 = B2->Multiplicities();
|
||||
|
||||
for (int k = 1; k <= nbknots; k++)
|
||||
{
|
||||
@@ -962,9 +956,8 @@ bool BRepLib_FuseEdges::SameSupport(const TopoDS_Edge& E1, const TopoDS_Edge& E2
|
||||
|
||||
if (B1->IsRational())
|
||||
{
|
||||
NCollection_Array1<double> W1(1, nbpoles), W2(1, nbpoles);
|
||||
B1->Weights(W1);
|
||||
B2->Weights(W2);
|
||||
const NCollection_Array1<double>& W1 = B1->WeightsArray();
|
||||
const NCollection_Array1<double>& W2 = B2->WeightsArray();
|
||||
|
||||
for (int w = 1; w <= nbpoles; w++)
|
||||
{
|
||||
@@ -995,9 +988,8 @@ bool BRepLib_FuseEdges::SameSupport(const TopoDS_Edge& E1, const TopoDS_Edge& E2
|
||||
return false;
|
||||
}
|
||||
|
||||
NCollection_Array1<gp_Pnt> P1(1, nbpoles), P2(1, nbpoles);
|
||||
B1->Poles(P1);
|
||||
B2->Poles(P2);
|
||||
const NCollection_Array1<gp_Pnt>& P1 = B1->Poles();
|
||||
const NCollection_Array1<gp_Pnt>& P2 = B2->Poles();
|
||||
|
||||
for (int p = 1; p <= nbpoles; p++)
|
||||
{
|
||||
@@ -1024,9 +1016,8 @@ bool BRepLib_FuseEdges::SameSupport(const TopoDS_Edge& E1, const TopoDS_Edge& E2
|
||||
|
||||
if (B1->IsRational())
|
||||
{
|
||||
NCollection_Array1<double> W1(1, nbpoles), W2(1, nbpoles);
|
||||
B1->Weights(W1);
|
||||
B2->Weights(W2);
|
||||
const NCollection_Array1<double>& W1 = B1->WeightsArray();
|
||||
const NCollection_Array1<double>& W2 = B2->WeightsArray();
|
||||
|
||||
for (int w = 1; w <= nbpoles; w++)
|
||||
{
|
||||
@@ -1147,8 +1138,7 @@ bool BRepLib_FuseEdges::UpdatePCurve(const TopoDS_Edge& theOl
|
||||
|| std::abs(last - el) > Precision::PConfusion())
|
||||
{
|
||||
occ::handle<Geom2d_BSplineCurve> bc = occ::down_cast<Geom2d_BSplineCurve>(Curv2d);
|
||||
NCollection_Array1<double> Knots(1, bc->NbKnots());
|
||||
bc->Knots(Knots);
|
||||
NCollection_Array1<double> Knots(bc->Knots());
|
||||
BSplCLib::Reparametrize(ef, el, Knots);
|
||||
bc->SetKnots(Knots);
|
||||
}
|
||||
|
||||
@@ -465,11 +465,10 @@ void BRepTopAdaptor_TopolTool::ComputeSamplePoints()
|
||||
{
|
||||
if (typS == GeomAbs_BSplineSurface)
|
||||
{
|
||||
const occ::handle<Geom_BSplineSurface>& Bspl = myS->BSpline();
|
||||
int nbup = Bspl->NbUPoles();
|
||||
int nbvp = Bspl->NbVPoles();
|
||||
NCollection_Array2<gp_Pnt> array2(1, nbup, 1, nbvp);
|
||||
Bspl->Poles(array2);
|
||||
const occ::handle<Geom_BSplineSurface>& Bspl = myS->BSpline();
|
||||
int nbup = Bspl->NbUPoles();
|
||||
int nbvp = Bspl->NbVPoles();
|
||||
const NCollection_Array2<gp_Pnt>& array2 = Bspl->Poles();
|
||||
Analyse(array2, nbup, nbvp, myNbSamplesU, myNbSamplesV);
|
||||
nbsu = myNbSamplesU;
|
||||
nbsv = myNbSamplesV;
|
||||
@@ -477,11 +476,10 @@ void BRepTopAdaptor_TopolTool::ComputeSamplePoints()
|
||||
}
|
||||
else if (typS == GeomAbs_BezierSurface)
|
||||
{
|
||||
const occ::handle<Geom_BezierSurface>& Bez = myS->Bezier();
|
||||
int nbup = Bez->NbUPoles();
|
||||
int nbvp = Bez->NbVPoles();
|
||||
NCollection_Array2<gp_Pnt> array2(1, nbup, 1, nbvp);
|
||||
Bez->Poles(array2);
|
||||
const occ::handle<Geom_BezierSurface>& Bez = myS->Bezier();
|
||||
int nbup = Bez->NbUPoles();
|
||||
int nbvp = Bez->NbVPoles();
|
||||
const NCollection_Array2<gp_Pnt>& array2 = Bez->Poles();
|
||||
Analyse(array2, nbup, nbvp, myNbSamplesU, myNbSamplesV);
|
||||
nbsu = myNbSamplesU;
|
||||
nbsv = myNbSamplesV;
|
||||
|
||||
Reference in New Issue
Block a user