Help troubleshooting NurbsCurve creation

I’m trying to use a custom grasshopper c# node to combine control points from several different curves in a specific way.

As far as I can tell I’m creating the curve properly, but it displays very badly and won’t bake. It seems like maybe it’s corrupting memory?

Any help would be great. I’d construct the curve from a point list, but I need rational control points.

Here’s the code:

    Rhino.Geometry.NurbsCurve nc0 = (Rhino.Geometry.NurbsCurve) L0;
    Rhino.Geometry.NurbsCurve nc1 = (Rhino.Geometry.NurbsCurve) A1;
    Rhino.Geometry.NurbsCurve nc2 = (Rhino.Geometry.NurbsCurve) L2;
    
    Print("nc0 pts: " + nc0.Points.Count.ToString());
    Print("nc1 pts: " + nc1.Points.Count.ToString());
    Print("nc2 pts: " + nc2.Points.Count.ToString());
    
    int inner_end = nc0.Points.Count - 2;
    
    List< ControlPoint > ptlist = new List< ControlPoint >();
    ptlist.Add(nc0.Points[0]);
    ptlist.Add(nc0.Points[1]);
    for( int i = 2; i < inner_end; i++ )
      ptlist.Add(nc0.Points[i]);
    ptlist.Add(nc1.Points[0]);
    for( int i = 2; i < inner_end; i++ )
      ptlist.Add(nc1.Points[i]);
    ptlist.Add(nc2.Points[0]);
    for( int i = 2; i < inner_end; i++ )
      ptlist.Add(nc2.Points[i]);
    ptlist.Add(nc2.Points[nc2.Points.Count - 2]);
    ptlist.Add(nc2.Points[nc2.Points.Count - 1]);
    
    Print("I have " + ptlist.Count.ToString() + " points");
    
    NurbsCurve nc = new NurbsCurve(3, ptlist.Count);//new NurbsCurve(3, true, 4, ptlist.Count + 1);
    nc.Points.MakeRational();
    
    for( int i = 0; i < ptlist.Count; i++ )
    {
      ControlPoint cpt = ptlist[i];
      Point4d p4 = new Point4d(cpt.Location.X, cpt.Location.Y, cpt.Location.Z, cpt.Weight);
      //nc.Points.SetPoint(i, new Point4d(0, i, 0, 1));
      nc.Points.SetPoint(i, cpt.Location.X, cpt.Location.Y, cpt.Location.Z, cpt.Weight);//cpt.Weight);
      Print(String.Format("Point {0} is ({1}, {2}, {3}, {4})", i, cpt.Location.X, cpt.Location.Y, cpt.Location.Z, cpt.Weight));
    }
    
    for( int i = 0; i < nc.Points.Count; i++ )
    {
      ControlPoint cpt = nc.Points[i];
      Print(String.Format("Point {0} is ({1}, {2}, {3}, {4})", i, cpt.Location.X, cpt.Location.Y, cpt.Location.Z, cpt.Weight));
    }
    
    NurbsCurve ncout = new NurbsCurve(nc);
    Cout = ncout;

Also here is the GH file, in case that’s easier to debug. knot_removal_test.gh(6.9 KB)

Thanks… :smile:

Hi Tom,

I think the problem is that you are not setting the knot vector properly.
The following probably works beter:

  private void RunScript(object L0, object A1, object L2, ref object Cout)
  {
    Rhino.Geometry.NurbsCurve nc0 = (Rhino.Geometry.NurbsCurve) L0;
    Rhino.Geometry.NurbsCurve nc1 = (Rhino.Geometry.NurbsCurve) A1;
    Rhino.Geometry.NurbsCurve nc2 = (Rhino.Geometry.NurbsCurve) L2;

    Print("nc0 pts: " + nc0.Points.Count.ToString());
    Print("nc1 pts: " + nc1.Points.Count.ToString());
    Print("nc2 pts: " + nc2.Points.Count.ToString());

    int inner_end = nc0.Points.Count - 2;

    List< ControlPoint > ptlist = new List< ControlPoint >();
    ptlist.Add(nc0.Points[0]);
    ptlist.Add(nc0.Points[1]);
    for( int i = 2; i < inner_end; i++ )
      ptlist.Add(nc0.Points[i]);


    ptlist.Add(nc1.Points[0]);
    for( int i = 2; i < inner_end; i++ )
      ptlist.Add(nc1.Points[i]);
    ptlist.Add(nc2.Points[0]);
    for( int i = 2; i < inner_end; i++ )
      ptlist.Add(nc2.Points[i]);
    ptlist.Add(nc2.Points[nc2.Points.Count - 2]);
    ptlist.Add(nc2.Points[nc2.Points.Count - 1]);

    Print("I have " + ptlist.Count.ToString() + " points");

    Rhino.Collections.Point3dList points3d = new Rhino.Collections.Point3dList(ptlist.Count);
    for( int i = 0; i < ptlist.Count; i++ )
    {
      ControlPoint cpt = ptlist[i];
      Point3d p3 = new Point3d(cpt.Location.X, cpt.Location.Y, cpt.Location.Z);
      points3d.Add(p3);
    }

    Rhino.Geometry.NurbsCurve nc = Rhino.Geometry.NurbsCurve.Create(false, 3, points3d);
    nc.Points.MakeRational();
    for( int i = 0; i < nc.Points.Count && i < ptlist.Count; i++ )
    {
      ControlPoint cpt = ptlist[i];
      //add the weight information
      nc.Points.SetPoint(i, cpt.Location.X, cpt.Location.Y, cpt.Location.Z, cpt.Weight);;

      cpt = nc.Points[i];
      Print(String.Format("Point {0} is ({1}, {2}, {3}, {4})", i, cpt.Location.X, cpt.Location.Y, cpt.Location.Z, cpt.Weight));
    }

    Cout = nc;
  }
1 Like

That does it, thanks… :smile: