Thu, 11/13/2014 - 11:13
I created non-rational BSpline curve
m_geomBSpline = new Geom_BSplineCurve(Poles, Knots, Mults, degree);
and then added a weight
m_geomBSpline->SetWeight(2,0.5);
After that I received an error in
BSplCLib::BuildCache
in code
for (ii = 1 ; ii CacheWeights(ii) = dc.poles[LocalIndex] * LocalValue ;
LocalIndex += Dimension_gen + 1;
LocalValue *= SpanDomain / (Standard_Real) ii ;
}
CacheWeights is a Null handler.
I searched the difference between Geom_BSplineCurve constructors with and without Weights. In the last case you create cacheweights:
if (rational) {
weights = new TColStd_HArray1OfReal(1,Weights.Length());
weights->ChangeArray1() = Weights;
cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
}
May be you must do so when you set a weight? But in SetWeight function we see only
if (rat && !IsRational()) {
weights = new TColStd_HArray1OfReal(1,poles->Length());
weights->Init(1.);
}
When I used constructor with weight=0.999 there was no error.
Mon, 11/17/2014 - 07:25
Hello Vladimir,
This really looks like a bug, so could you please report an issue in official BT? Your suggestion seems to fix the case.
In the meanwhile the workaround can be using rational form of B-curve from the very beginning. E.g:
// Prepare poles for B-spline curve gp_Pnt Q1( 10.0, 0.0, -5.0 ); gp_Pnt Q2( 0.00, 0.0, 0.0 ); gp_Pnt Q3( 0.00, 0.0, 2.0 ); gp_Pnt Q4(-5.00, 0.0, 5.0 ); TColgp_Array1OfPnt Poles(1, 4); Poles(1) = Q1; Poles(2) = Q2; Poles(3) = Q3; Poles(4) = Q4; // Degree const Standard_Integer degree = 2; // Knots with their multiplicities TColStd_Array1OfReal Knots(1, 3); TColStd_Array1OfInteger Mults(1, 3); Mults.SetValue(1, 3); Mults.SetValue(2, 1); Mults.SetValue(3, 3); Knots.SetValue(1, 0.0); Knots.SetValue(2, 0.5); Knots.SetValue(3, 1.0); // Weights: notice that all are equal to 1 TColStd_Array1OfReal Weights(1, 4); Weights(1) = 1.0; Weights(2) = 1.0; Weights(3) = 1.0; Weights(4) = 1.0; // Notice 'Standard_False' at the end Handle(Geom_BSplineCurve) curve = new Geom_BSplineCurve(Poles, Weights, Knots, Mults, degree, Standard_False, Standard_False); // Now it works curve->SetWeight(2, 10.0);As you can see, all weights are initially unit. Therefore, if you do not pass Standard_False as the last argument to Geom_BSplineCurve constructor, it will recognize it as non-rational and you will experience the mentioned bug. However, if you pass Standard_True, this "smart check" will not occur and SetWeight() invocation will succeed.
Mon, 11/17/2014 - 09:31
Thank you for attracting my attention to the last parameter.