Baking from Grasshopper using C# script

I want to make a C# script in GH that will bake a brep into my Rhino document. This will eventually be part of a larger program using a button in UI. I don’t want to have to go back to the GH document and right click on the Swp2 component in order to bake the brep.
Here is a very simple GH file that creates a thing and the C# module that I have started. It shows that it recognizes the object as a Brep.simple-bake-C#.gh (8.7 KB)

I did something similar to this a while ago in Python but that was only a curve where I used code like this

#switch contect to Rhino
 scriptcontext.doc = Rhino.RhinoDoc.ActiveDoc
 #add the geometry
curve= scriptcontext.doc.Objects.Add(geometry)
 #switch contect back to gh
 scriptcontext.doc = ghdoc

But now I am in C# and I can’t figure out the equivalent C# thing for “scriptcontext.doc”.
It’s probably very simple, but remember I’m just learning C# and still have a long way to go learning the Rhino classes.

What about specifying which layer you are baking to? And delete by layer? And materials?

This is done with Python:

Here is a little C# component that will bake a Brep. It should let you know how to do it.
You can add attributes by using the objectAttributes class, in this case I’ve just baked the object onto the third layer to show how it’s accessed:

  private void RunScript(bool Go, Brep B)
  {
    if(Go)
    {
      Rhino.DocObjects.ObjectAttributes objectAttributes = new Rhino.DocObjects.ObjectAttributes();
      objectAttributes.LayerIndex = 2;
      Rhino.RhinoDoc.ActiveDoc.Objects.AddBrep(B, objectAttributes);
    }
  }

Many thanks John. That worked like a charm. I had found Rhino.RhinoDoc.ActiveDoc but had not gone further. The intellisense was telling me not to use ActiveDoc unless I meant it and I wasn’t sure.
And there is something here that I don’t understand. In the API documentation I found that ActiveDoc was a property of RhinoDoc class. So I am unclear on how it works to extend that last line with .Objects.AddBrep(). It certainly works. But what am I missing? I thought ActiveDoc only worked to get or set something. It is in this case I guess setting something but I am obviously unclear on the syntax.

Thanks for the suggestions Joseph but I’m trying to get away from Python. After working with it for a year, I find I don’t care for it. Too many years writing C I guess. I’m feeling more at home with C#.

I got that. I mentioned it because I found the additional features to be critical: bake to layer, delete by layer and materials. The Rhino API is the same so translation shouldn’t be too difficult?

I think it depends on how you’re accessing your document within your “larger program”. Technically, in the example I gave you, I really should be using the grasshopper document referenced rather than ActiveDoc, i.e.:

RhinoDocument.Objects.AddBrep(B, objectAttributes);

Which is a member hidden at the top of the C# script instance. So best to use this for the time being I would say. ActiveDoc I think was the way I used to do it, but it’s bad practice now I guess. Maybe someone from McNeel can help us!

Hey @Joe4

a bit late for the topic

just wanted you to have this snippet that works fine for me, checks if a layer named exists and creates one if not existent before baking on this layer including layer color. (this example for breps):

private void RunScript(Brep B, bool T, string L, System.Drawing.Color C)
  {
    if(T)
    {
      Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc;

      //add layer
      System.Drawing.Color col = new System.Drawing.Color();
      //col = System.Drawing.Color.FromArgb(255, 0, 0, 255);
      col = C;

      var layer = doc.Layers.FindName(L, RhinoMath.UnsetIntIndex);
      if (layer == null)
      {
        doc.Layers.Add(L, col);
      }

      int layerIndex = doc.Layers.FindName(L, RhinoMath.UnsetIntIndex).Index;
      //set attributes
      Rhino.DocObjects.ObjectAttributes att = new Rhino.DocObjects.ObjectAttributes();
      att.Name = "AjourCutter";
      att.LayerIndex = layerIndex;
      //bake with attributes
      RhinoDocument.Objects.AddBrep(B, att);
    }
  }
2 Likes

You know, I had found that up in the Members section but didn’t have a clue how to use it. Going to developer.rhino3D.com and searching on RhinoDocument didn’t really give any direct help.
So yeah, it would be nice if someone could expound on this.

Thanks, Ben. I can use all the examples I can get.

All,
I think I’ve got it now. RhinoDocument returns something that points to a current Rhino document that is running. Looking at Ben’s code you can assign that something to a variable like
Rhino.RhinoDoc doc = RhinoDocument;
which seems to be the same as
Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc;
but without the warnings about ActiveDoc.
OR, similar to John’s code you can write
RhinoDocument.Object.AddBrep(brep); where the RhinoDocument is in the background returning the active Rhino document.
So, ActiveDoc really is a property that ‘gets’ the handle or whatever it’s called to the current document, and RhinoDocument must do the same thing.

Hi Ben,

Not too late. I’m really glad that you shared that. I used your code to make a version that bakes objects to child layers. Not the most beautiful code, but I’ll post it in case someone finds it useful:

 private void RunScript(string parent, string child, System.Drawing.Color colour, GeometryBase Geo, bool toggle)
  {

    if(colour.GetHashCode() == 0) colour = System.Drawing.Color.Black;

    if (toggle){

      int index = doc.Layers.FindByFullPath(parent, -1);
      if (index < 0) doc.Layers.Add(parent, System.Drawing.Color.Black);
      index = doc.Layers.FindByFullPath(parent, -1);
      Rhino.DocObjects.Layer parent_layer = doc.Layers[index];


      // Create a child layer

      string child_name = child;
      Rhino.DocObjects.Layer childlayer = new Rhino.DocObjects.Layer();
      childlayer.ParentLayerId = parent_layer.Id;
      childlayer.Name = child_name;
      childlayer.Color = colour;

      string children_name = parent + "::" + child;

      index = doc.Layers.FindByFullPath(children_name, -1);
      if (index < 0) index = doc.Layers.Add(childlayer);

      Rhino.DocObjects.ObjectAttributes att = new Rhino.DocObjects.ObjectAttributes();

      att.LayerIndex = index;
      doc.Objects.Add(Geo, att);


    }
  }

Ash

1 Like