algorithmic modeling for Rhino
I'm trying to replicate the "ctrl+shift+left arrow" behaviour inside a scripting component (c#): would like to get all the components that "flow" into it.
First step, all cool:
foreach (IGH_Param input in Component.Params.Input)
foreach (IGH_Param source in input.Sources)
guids.Add(source.InstanceGuid);
Now, how do I get a component from the canvas by its guid, and check his dependents out?
Noob alert. It's been ages since I touched the sdk, and am completely lost...
Tags:
Ok, I'm going to have a dialogue with myself for a bit. I'm slowly getting there:
GH_Document g = new GH_Document();
A = g.FindAllDownstreamObjects(Component);
Works fine for all the downstream (ie to the right) components. Unfortunately there's no... "FindAllUpstreamObjects(this)" :(
Assuming you have a component called comp and you want to find all top level objects that are immediate sources, here's what you can do (top of my head code):
HashSet<Guid> ids = new HashSet<Guid>();
foreach (IGH_Param param in comp.Params.Inputs)
foreach (IGH_Param source in param.Sources)
{
Guid id = source.Attributes.GetTopLevel.DocObject.InstanceGuid;
ids.Add(id);
}
List<IGH_DocumentObject> objects = new List<IGH_DocumentObject>();
foreach (Guid id in ids)
{
IGH_DocumentObject obj = doc.FindObject(id, true);
if (obj != null)
objects.Add(obj);
}
You need to always use GetTopLevel() because a parameter source may be an output parameter of a component, and that is a subobject. If you want the component itself you'll need to use Attributes.GetTopLevel.DocObject
The reason to use a HashSet is because a specific object may be a source for the current object more than once. The HashSet prevents double entries.
All smooth. Works! Minor typos needed a fix.
Now i'm in another fix though. How do I get the input sources of the IGH_DocumentObject? Hopefully once I get my head around the GH principles I'll stop asking annoying questions!
Before I get bashed, I am reading and searching through the Grasshopper SDK :)
Answering my own question:
Simple, just cast to IGH_Component instead of IGH_DocumentObject.
I am though wondering what the difference is between IGH_Component and IGH_DocumentObject. I'm sure I'm missing some rather important logic here! Asking in the hope of putting less annoying questions in the future, obviously.
IGH_DocumentObject is anything that exists on the canvas. Components, sliders, scribbles, groups, jumps, panels, everything except the widgets like Compass and Profiler. IGH_ActiveObject are those objects on the canvas that participate in solutions. This includes all components and parameter, but does not include groups, scribbles, sketches, etc. IGH_Param is for parameters, be they freefloating or attached to components, IGH_Component is for components. What IGH_Component adds to IGH_ActiveObject is little more than a unified way to access the input and output parameters. The abstract GH_Component class (which implements IGH_Component) does a lot of stuff, but usually you're better off casting to IGH_Component than GH_Component.
Thanks for the explanation - it clarifies a lot!
I did stumble ina problem last eve, IGH_Component could not be cast to a number slider - when I was reaching that point I figured I started looking again, and probably end up using IGH_ActiveObject.
All cool, progress is being made (painfully slow).
Correct, a number slider is a GH_Param<GH_Number> or IGH_Param. Most of those special objects are IGH_Params with the notable exception of Gradients and Legends. Parameters are much easier to modify and tweak, but they can only have a single input and a single output, which is some rare cases is insufficient.
Just incase someone is ever looking for something like this I wrote a recursive function which will find all the upstream components (and params) that are connected to a particular component.
It was written for the ghPython components, but the code could be converted to C#
Hey dimitrie, how are you?
Do you mean this?
var document = this.GrasshopperDocument;
A = document.FindAllDownstreamObjects(this.Component);
Mmm, kind-of, though what I'm trying to do now is akin to document.FindAllUpstreamObject(etc)!
Will share some final code once I've glued my hack to something usable.
Welcome to
Grasshopper
© 2025 Created by Scott Davidson.
Powered by