Change control point weight in Rhino6

Hi everyone,

I tried to change the weight of one control point of an initially equally weighted NURBS curve (B-Spline). This is my code in the GH-C#-component, where w is the list of the new weights and C is the B-Spline curve.

private void RunScript(Curve C, List<double> w, ref object NC)
  {
    //construct NURBS curve
    NurbsCurve nurbs_crv = new NurbsCurve(C.ToNurbsCurve());
    //check if sufficient control points are available
    if(nurbs_crv.Points.Count != w.Count)
    {
      Component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Number of control points and weights do not match!");
      return;
    }
    for(int i = 0; i < nurbs_crv.Points.Count; i++)
    {
      nurbs_crv.Points.SetWeight(i, w[i]);
    }

    NC = nurbs_crv;
  }


The outcoming curve (red) is wrong. ( Only the weight of the second point is set to 2.8, the rest is still 1.0). The initial B-Spline curve is represented in blue. If every entry in the w-list is 1.0, the two curves coincide.

This happens also if I use the initial working code, which I had in Rhino5:

nurbs_crv.Points[i] = new ControlPoint(nurbs_crv.Points[i].Location.X, nurbs_crv.Points[i].Location.Y, nurbs_crv.Points[i].Location.Z, w[i]);

Are there some changes which might cause this error? I would be grateful for every type of hint!

Anna

1 Like

Hello,

for me this works as expected (RH.6).
Can you share the file? I suspect wrong input. Which version are you using?

It is GH Version Sunday, 29 July 2018 11:28 Build 1.0.0007 and Rhino Version 6 SR7
(6.7.18210.11281, 07/29/2018)

I updated today but had this problem already before.

And here is a simplified version of the file:
change_weight_of_cp.gh (6.0 KB)

You are right. Same issue for me with that curve. Changing the weight shouldn’t modify the controlpoint location.

@dale @piac

I remember @dale making changes in this area.
See RH-39253.

Its funny that if you do it manually in Rhino it works. when looking at OpenNurbs the problem seems to be in MakeRational()

Hi @am.bauer,

Let me know if this past thread is helpful.

Rhino 6 Nurbs curve control points

– Dale

Thank you everyone! The solution proposed by Dale worked.

nurbs_crv.Points.SetPoint(i, new Point3d(nurbs_crv.Points[i].X, nurbs_crv.Points[i].Y, nurbs_crv.Points[i].Z), w[i]);

@dale

good that it works like this, but using SetWeight still shouldn‘t change cv location?!

So to me this method does not work as expected. Especially if you change the weight by the native Rhino command it works as before, but using the RC equivalent behaves differently is a problem. If it works correctly it might be at least helpful to add a comment to the method signature that it changes cv location, because otherwise this leads to lot of confusion and hard to debug behaviour.

Hi @TomTom,

NurbsCurvePointList.SetWeight is just a wrapper for ON_NurbsCurve::SetWeight, which is the openNURBS implementation. If you are curious what it does, then you can download the openNURBS toolkit and look at the source code.

Well that depends.

If you have a rational NURBS curve (setting a control point weight to something other than 1.0 will make the curve rational) and you request a Euclidean point using NurbsCurvePointList.GetPoint(int index, out Point3d point), then the components of the out point will have been multiplied by the weight.

There are comments on both NurbsCurvePointList.GetPoint and NurbsCurvePointList.SetPoint methods that explain this.

Free free to post some sample code that doesn’t behave in an expected manner, and I’ll try my best to explain what is going on.

Thanks,

– Dale

1 Like

Thank you Dale,

I wasn’t aware that the weight is multiplied to the 3 other coordinates. I always assumed that the weight only determines the impact of a control point in the calculation of the point-on-curve algorithm, which basically just pulls the spline closer or more away from the actual cp location. Basically it just adds a fourth dimension. Furthermore this is what I only referred as “rational”. So my assumption was, that if you set the weight, you just modify the fourth coordinate, but not the others. Thank you for clarifying this.