Understanding Rhino.Geometry and GH.Kernal.Types in GH Plugin Dev

I am attempting to develop a C# grasshopper component and am having a hard time understanding how to take Grasshopper.Kernel.Types and convert or cast them to Rhino.Geometry.

My current goal is to receive GH_Structure<GH_Curve> inputs and access their control points. I believe that this requires casting or converting to a RhinoCommon NurbesCurve or Polyline but have struggled to find examples of this. As someone new to C# I’m having trouble working from the documentation.

Am I correct in thinking that I should be working with GH_Strucuture inputs, and that these need to be turned into Rhino.Geometry so that the component can access all the great RhinoCommon Methods?

Is there any simple examples of moving from Grasshopper.Kernel.Types.GH_Curve => Rhino.Geometry.Curve?

Any advice or reference to tutorials or examples would be much appreciated.

You typically don’t have to work with either GH_Structure or IGH_Goo unless you want to operate on the data layout, rather than the values themselves.

If you’re input parameters have tree access, then I’m afraid you don’t have a choice, but item or list access works directly on the underlying type.

So for example if you have a single Curve parameter input with Item access, and a single Point paramerer output with List access, then your code will look something like this:

Rhino.Geometry.Curve curve = null;
if (!DA.GetData(0, ref curve)) return;
if (curve == null) return;

Rhino.Geometry.NurbsCurve nurbs = curve.ToNurbsCurve();
var points = nurbs.ControlPoints.ToArray();

DA.SetDataList(0, points);

(I’m typing this dry, I have no idea how to convert the nurbs control points to an array of Point3d instances)

Also if you’re looking for conversions that aren’t always exactly obvious, use the methods in the GH_Convert class.

Thanks David, this is helpful. I have played around a bit with some success, avoiding IGH_Goo is valuable!

My use does require keeping track of branches and using GH_Structure. Below is the dummy code I tested with in case anyone finds it useful.

The Rhino.Geometry.Curve curve = null; was a critical insight, looks like you have explain why in this post

            // input Tree.
            GH_Structure<GH_Curve> inputCurveTree = new GH_Structure<GH_Curve>();

            // access the input parameter by index. 
            if (!DA.GetDataTree(0, out inputCurveTree)) return;

            //create desitnation list
            List<string> pointPathOut = new List<string>();

            // for every branch  (ie feature)
            foreach (GH_Path path in inputCurveTree.Paths)
               IList branch = inputCurveTree.get_Branch(path);
                // for every curve  in branch
                foreach (GH_Curve thisGhCurve in branch)
                    Curve rhinoCurve = null;
                    GH_Convert.ToCurve(thisGhCurve, ref rhinoCurve, 0);
                    //curve to nurbes
                    NurbsCurve thisNurbsCurve = rhinoCurve.ToNurbsCurve();

                    //Get list of control points
                    Rhino.Geometry.Collections.NurbsCurvePointList theseControlPoints = thisNurbsCurve.Points; 
                    //for each control point
                    foreach (ControlPoint thisPoint in theseControlPoints)
                        pointPathOut.Add( "{ "+thisPoint.Location.ToString()+" }=> " + path.ToString() );
                    }//end each control point

                }//end of each curve in branch

            }//end of each path

            // set restults 
            DA.SetDataList(0, pointPathOut);

If a value is associated with an out keyword, you don’t have to instantiate it first. I.e. this constructor:

GH_Structure<GH_Curve> inputCurveTree = new GH_Structure<GH_Curve>();
if (!DA.GetDataTree(0, out inputCurveTree)) return;

is redundant. Just type:

GH_Structure<GH_Curve> inputCurveTree;
if (!DA.GetDataTree(0, out inputCurveTree)) return;