The interrogator component for Grasshopper, written with the C# component, to extract hidden information about selected components, including its GUID, namespace and draw order

Access any component properties in C# using the Grasshopper API

In previous posts, I have touched upon the idea that it is possible to connect remotely to any component in the Grasshopper canvas and read or edit it, even when there are no wires connecting them. And in this recent post where I accessed the draw order of all components on the canvas, I found it was very easy to build a list of every component on the canvas.

So how far can we take this – is it possible to access any piece of information about any component of the entire canvas? How much can we learn and edit about components just using a bit of C#?

The code below is my attempt to find out. It is my attempt to write a code that, given any component in the canvas, will tell you as much as possible about it. For lack of a better name, I call it the Interrogator.

The Interrogator

The Interrogator is currently not very smart, but is a good start. It is a WIP and I may update this page as I teach the Interrogator more tricks. Set it up with a panel and a timer, then click on any component in the canvas. The Interrogator will tell you all it can about that component.

grasshopper-interrogator

As I learn more about the class structure of Grasshopper, I learn more about where different pieces of information are hiding, and how to access them. (Short story – the class hierarchy of Grasshopper is more a tangled web of inheritance and it’s easy to get lost!) Eventually, I want to be able to know how to access and modify everything about any component, which will help greatly in my ability to develop new and interesting Grasshopper components.

Code

For now, the limited information I can access is presented in the code below, in all its partially-commented glory. Just copy into a standard C# component, and let the Interrogator pick the brains of your components…

    var rtnlist = new List<string>();
    var rtntree = new DataTree<string>();

    //get all guids in doc - this is used to find the draw order
    var guids = new List<System.Guid>(); //guids of all componets
    foreach (IGH_DocumentObject docObject in GrasshopperDocument.Objects)
    {
      guids.Add(docObject.InstanceGuid);
    }
    //A = guids;

    foreach (IGH_DocumentObject obj in GrasshopperDocument.Objects)
    {
      if(obj.Attributes.Selected)
      {
        //find this object in the list of guids
        int loopno = 0;
        bool endloop = false;

        while (!endloop)
        {
          GH_Path pth = new GH_Path(loopno);
          //if object is selected, let's display its properties
          if(guids[loopno] == obj.InstanceGuid)
          {

            //build our component info list here!

            rtntree.Add(obj.NickName + " (" + obj.Name + ")", pth);
            rtntree.Add("Category: " + obj.Category + " > " + obj.SubCategory, pth); //the category in the GH tab
            rtntree.Add("Component GUID: " + obj.ComponentGuid.ToString(), pth);
            rtntree.Add("Description: " + obj.Description, pth);
            rtntree.Add("Draw order: " + loopno.ToString(), pth); //used for calculation order. New objects go to the end of the list by default
            rtntree.Add("Exposure: " + obj.Exposure, pth); //what is this?
            //you can  access the icon under obj.Icon
            rtntree.Add("Instance description: " + obj.InstanceDescription, pth);
            rtntree.Add("Instance GUID: " + obj.InstanceGuid.ToString(), pth);
            rtntree.Add("Attributes: " + obj.Attributes.ToString(), pth); //namespace and class in DLL

            rtntree.Add("Namespace: " + obj.Attributes.DocObject.ToString(), pth);



            //inputs
            //IList < Grasshopper.Kernel.IGH_Param > things = GrasshopperDocument.Objects as IList<Grasshopper.Kernel.IGH_Param>[0];
            //A = things;
            var para = obj as Grasshopper.Kernel.GH_ActiveObject;
            if(para != null)
            {
              rtntree.Add("Successfully cast as GH_ActiveObject", pth);
              rtntree.Add(para.ProcessorTime.ToString(), pth);
            }
            var para2 = obj as Grasshopper.Kernel.IGH_Component;
            if(para2 != null)
            {
              rtntree.Add("Successfully cast as IGH_Component", pth);
              rtntree.Add("Number of inputs: " + para2.Params.Input.Count().ToString(), pth);
            }
            //var para3 = obj as Grasshopper.Kernel.GH_PersistentParam<Grasshopper.Kernel.Types.IGH_Goo>;
            //rtntree.Add(para3.PersistentData[0].ToString(), pth);
            //var para4 = obj as Grasshopper.Kernel.Parameters.
            //if(para4 != null) rtntree.Add("yay", pth);







          }
          loopno++;
          if(loopno >= guids.Count) endloop = true;
        }
        A = rtntree;
      }
    }

3 thoughts on “Access any component properties in C# using the Grasshopper API”

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: