I’m fairly new to Grasshopper and C# scripting, so I hope I’m not asking something too stupid.
So here’s my problem:
I’m using the Rhino interface of the FE software SoFiSTiK and I want to write a C# component in Grasshopper, that adds the SoFiSTiK structural data to selected Rhino Object.
A is zero, when I just select an ordinary Rhino Curve, but it changes to one when I select a curve that I manually declared as a structural item in Rhino/SoFiSTiK before. So it seems the structural data is stored as UserData.
Now I want to know what exactly the user data is, so I can just write a C# component that automatically adds that information to all curves on one layer and so on. But I can’t seem to find a way to actually read the userdata. Or is that not possible?
Can anyone help me out?
One day when I was really bored I tried to draw a class diagram of (parts of) the RhinoCommon lib, and in my archive I digged up the following diagram (Edit: Corrected a second time). Perhaps it can guide you in how to navigate the classes involved.
< snip >
Edit: See post far below for tested code that can add and retreive info from these classes. I removed the old text here (and old pictures) since they contained errors. The picture below should be correct though.
Fig.1. This updated Class Diagram (R1.2) shows how to access a UserData object by calling “Find”.
Mmmm, nice work. This could be an amazing learning resource to include in the Rhinocommon documentation…Sometimes learning/teaching these structures is not very intuitive and doesn’t help the linear way in which you can explore the current documentation (*.chm or online doc).
Currently lack of time makes it a bit risky though since it takes some testing to verify that I read the documentation right (like in this case I had overlooked that the UserData links was actually introduced on the CommonObject level and not as late as Brep as I first had drawn).
False info often is worse than no info…
But I’d happily draw more diagrams of the parts I need to explore & understand myself if I know that others would also find them useful.
Hello, I’ve been trying your suggestions, but I always get that UserDataLists can’t be indexed with .
Anyone know a way around this?
EDIT:
Even though I’m still interested in how it’s actually done, I found a way around actually writing a component myself. The attributes component in Human did the trick:
Now I just need write a component that adds user data in that manner to all my layers, which seems more simple, using UserData.Add(…).
Here’s hoping it works out the way I planned.
Human, Elefront and others can easily do what you are asking in grasshopper, but that wasn’t your question. You can reference, sort, add, revise and reapply userdata seamlessly this way, by layer or whatever.
It’s always nice to know how something actually works.
Also, I can’t reapply the userdata since that way I always need a reference object, which I usually won’t have when I start a calculation. Also the userdata always needs some editing, for example, the first value needs to increment for each object. Not sure if Elefront can do that.
You can probably add the user data when defining the geometry in gh, Bake, add more or modify, then export.
You can identify the nodes to pull info from initially; typically by proximity or a matching data structure that’s in rhino.
I’ll be in and out all day, but if you can put together a small file – with several structural components of each type in rhino – i can show the workflow. I do think you will be pleasantly surprised on its ease and potential for productivity
thanks a lot, especially for the updated diagram.
I’ll definitely try to implement this! For now I found a very inelegant way to achieve what I want using Human tools. Out of lack of time I couldn’t do it the pretty way with my own C# component (just not enough practice with C# yet…) but in the later stages of this project I will remedy that.
I’ve come up with this, so the user has to actually type in the user data.
At a later point, I’ll try to use your code and advice to make a component that creates the user data depending on various inputs that are more easily understandable for a user.
Sorry if the code example looked overly complicated. Follows a simplified code snippet which adds two rows of info and reads it again from the std UserDictionary (no null checks, just write and read):
// insert data
brep.UserDictionary.Set("SOF_ID", 1001);
brep.UserDictionary.Set("SOF_GRP", "SOF_PROP_COMBO_BYLAYER");
// read data
var str = "";
brep.UserDictionary.TryGetValue("SOF_ID", out str);
Print(str); // prints to the "out" port
brep.UserDictionary.TryGetValue("SOF_GRP", out str);
Print(str); // prints to the "out" port
// and so on