generative modeling for Rhino
I have a whopping big definition with a large set of inputs (that is, references to many separate curves and lines and etc. in the rhino file) that need to be set individually. And I need to run this definition successively, on many different sets of input geometry. Further, I will want to re-run it after changing little bits of the geometry in one or more sets.
Being basically lazy, I'm trying to find the easiest way to do this, without having to re-enter all the geometry references every time :-)
I believe that I can just set my inputs once, then save off a copy of the definition, then repeat, building up a "library" of grasshopper files with the right sets of references in them.
The big downside to this approach is that if I want to change the definition iself, I'll have to go back and change every instance in the "library". But maybe that's the price of progress.
I find myself wishing for a command like "Save State" that saves geometry references instead. Or some sort of cross-file reference, so that I could have all the inputs in one file, then hook that to the definition in another file.
Pipelines can help here, perhaps. Can anyone think of other ways to accomplish this?
Thanks, as always to this great group of Grasshopper-ers.
Use the Geometry Pipeline component.
This allows you to specify either Object Names or Rhino Layers or both. You can also use wild card characters (*).
Thanks Danny, that's partly helpful.
It's still a large manual job: instead of having to select the geometry in rhino and then do a "set multiple curves" 19 times, I have to manually edit the layer name in 19 different pipeline components. Marginally better, but I'll still need to do this operation approx. 80 times...gulp.
Here's a wishlist request for David: expose string inputs in the Geometry Pipeline for Layer and Name. If I had that, I could change one string to swap my whole geometry set! (My layers have names like "B1 red rail", "B1 blue rail" etc., then the next time I'll want "B2 red rail", "B2 blue rail" etc.)
BTW, I'm happy to script something in C# if it will help: maybe I could write something like the Geometry Pipeline that takes a string input for layer name? Hmmm...
If you know how to script in C# it's very easy to do what you are asking. Just set the pipeline layer name to something like "B1*" so that it gets all the objects in all the layers you want. Then use a scripting component to find out the actual layer of each object and arange them in a datatree accordingly.
The code (in VB) could be something like this:
Private Sub RunScript(ByVal x As List(Of Guid), ByVal y As Object, ByRef A As Object)
Dim dt As New datatree(Of geometrybase)
For Each id As guid In x
Dim obj As New docobjects.ObjRef(id)
dt.add(obj.Geometry, New gh_path(obj.Object.attributes.layerindex))
a = dt
Just connect the pipeline output directly to the x input.
Just to get closure on all this: I wrote a C# script that is sort of a special purpose geometry pipeline for my particular file, and it lets me input a simple string (like "B2) and get all the curve geometry I need, arranged into 4 tree structures. I'm very happy: now I just need to change one string and all the info falls out. That script replaces something like 24 different grasshopper components and a mess of wiring, so the definition looks nicer, too :-)
Here's a file with 2 of the "learning" scripts I wrote along the way, in the hope it will help someone. One of them takes a layer name and extracts all the curve objects from that layer, the other one is an exercise in building up multi-level tree structures for output.
Thanks, as always, for the help. And I welcome any comments, I LOVE code reviews! I'm an experienced C and C++ programmer but don't know my way around RhinoCommon and don't know anything about the specifics of C#.
The problem with this approach is that the definition won't update if you modify or create new objects in Rhino. You have to manually refresh the GH definition. That's why I suggested connecting a pipeline component to a scripting component, so you can have the best of both worlds.
I understand the distinction, and it was an excellent suggestion, thanks. For my particular purposes, it would have complicated the scripting somewhat, (finding out which layer each curve is in and routing it to the appropriate output tree). And since I won't be changing the geometry much, hitting "Recompute" once in a while is no big deal.
In any case, for me this script will avoid hours of mind-numbing clicking and typing, so I'm well satisfied.