Obtaining the points that make up a polyline in Grasshopper/Rhino

As part of my EngD I work alongside other engineers solving day-to-day problems. James, a fellow research engineer at BuroHappold, and I regularly venture down the path of Grasshopper development. James works in Grasshopper for the majority of his work and his website (viewable here) contains a lot of hints and tips on getting Grasshopper to do what it should. However, some of his work involves coding his own components for Grasshopper, which is typically where I come in to assist with my programming knowledge and experience. Grasshopper, for those who don’t know, works in the C# language for custom components, and, as mentioned here, is capable of running anything you can do in C#. Alongside my work with James, just prior to starting this website, I posted this on James’ website detailing how to access the GH_Param by traversing up and down the inheritance tree.

Today’s task was a relatively simple one (simpler than the majority of things James and I work on) – how to obtain the points that make up a polyline. The polyline class, part of the Rhino Geometry library, does not contain a method for obtaining the points which make up the polyline. This seems to be an oversight of the Rhino developers (McNeal) as one would think this would be useful when working with polylines. Never-the-less, this functionality is not provided in the current (as of today) library for Rhino polylines. As this is something expected, I was drafted in to listen to the problem (we’re both strong believers of talking the problem through with someone and letting the answer come to us that way). However, despite looking through the list of available functions for the polyline in question, none seemed to provide what James needed – a list of the points.

The reason for this is the unintuitive way in which Rhino contains polylines. Mathematically speaking, a polyline is simply a collection of points from which we play dot-to-dot to join up. Programmatically speaking, the polyline class in Rhino is simply a class for defining and working with polylines. To the average Grasshopper user, who might only be scripting for basic geometric purposes, the ability to access the points of the polyline seems hidden. However, there are two ways to do it.

By traversing through the Rhino Common DLL source code (using IlSpy), it was found that the polyline class inherits from the Point3dList class (which makes sense for a polyline to be a collection of points that we play dot-to-dot with). From this, it became apparent that we could one of two things to obtain the control points of a polyline.

Polyline inheriting from Point3dList in Rhino Common

Polyline inheriting from Point3dList in Rhino Common

Grasshopper RunScript code for obtaining points of a polyline

The first method is also the simplest, and, once you understand the code structure behind the polyline class, also the most obvious. The issue here isn’t with the complexity of obtaining the control points, rather it lies with the unintuitive way in which they are handled and, for James and I, we don’t know if anyone else could have found how to do it without also going through the source code (which the average Grasshopper user is unlikely to do (indeed James’ tried a Google search before calling me over and could not find anything obvious)).

Because the polyline class inherits from a Point3dList, this gives it the same capabilities as a list. Although the list is of a Rhino type (and not a System list as it common in C#), it can be treated in a similar fashion. That is it has a Count variable (for the size of the list) and you can access elements of the list with the index. So, the first solution is as follows:

private void RunScript(Polyline obj, ref object A)
{
    for(int x = 0; x < obj.Count; x++) {
        Point3d pt = obj[x];
    }
}

Once you know and understand that the polyline is a list of points, you can interact with it as if it were a list. But getting this information isn't each and certainly isn't intuitive to the average Grasshopper user.

The second method involves using the inheritance of the polyline class against it. In this method, we simply cast the polyline up the inheritance tree till we hit the branch for a list of points. This is done as follows:

RhinoList pts = ((RhinoList)obj);

Then you have a Rhino List which you can interact with as you would a System list (or convert it to a System list and work from there).

A third method, and arguably more simply method pointed out to me by Brian Washburn (thanks go to Brian as a result), is the ToList() function of the polyline, which would return a System list of Point3d's, like so:

List pts = obj.ToList();

If you have a better way of obtaining the control points from a polyline in Rhino then feel free to comment. If not, then hopefully this method will save you having to search through the source code yourself to find this unintuitive answer to a very simple problem.

For those who may be interested, James' also wrote an article on the matter which can be read here

Comments

  1. By Brian Washburn

  2. By FraserG

Leave a Reply

Your email address will not be published. Required fields are marked *