Getting and setting object name in GHPython

Hi everyone,
I’m very new to Grasshopper/Rhino, trying to get my head around Python scripting for various bespoke workflows I am developing. In the code below I am comparing the User Dictionary values of two sets of breps. When two breps have matching User Dictionary values, I want to take the Object Name of the first brep, and apply it to the second brep. However, I’m confused, as while the Brep Class has a User Dictionary property, it doesn’t have an ObjectName property. And I can’t use rhinoscriptsyntax.ObjectName() function because I’m not dealing with the Rhino context at this point- all of these Breps only existing in Grasshopper, right?

I obviously don’t understand some fundamental stuff here around object types, interfacing with rhino syntax, and also around lists vs trees etc!

Any help much appreciated!

"""Matches up breps using User Dictionary id given by me, then takes the object names from one, applies to the other.
    Inputs:
        breps: breps without an object name set
        mat_breps: breps with an object name set
    Output:
        a: breps- with object name set to match mat_breps"""

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

for i in breps:
    ref1=i.UserDictionary.GetString('ref')
    for j in mat_breps:
        ref2=j.UserDictionary.GetString('ref')
        if ref1==ref2:
            print("match")
            #Now get the object name from brep i, and set the object name of brep j to match.

a=breps

I think, you are missing the fact that usually the ‘RhinoObject’ is the class containing an ID, various meta-data (name, layer, colors…) and geometry (e.g. the actual BRep). The ‘RhinoObject’ is then part of the ‘RhinoDocument’. Using ‘Rhinoscriptsyntax’ directly within Rhino always deals with RhinoObjects. This is fundamental different to Grasshopper. In Grasshopper, you only create and modify raw geometry (“Rhino.Geometry”).

“Baking” in Grasshopper means, you output your geometrical data into new RhinoObjects, which are then attached to the active RhinoDocument. In that regard, you have no chance injecting any meta-data before referencing something from the document.

But of course you are always free to create your own wrapper around a geometry instance. You either create a tuple out of a geometrical instance and a custom meta-data dictionary, or you deal with meta-data independently. But somehow you need to ensure that you are not messing this up. It always depends on the use-case and personal preference…

  1. As Tom said.
  2. The general way to do this is to define a suitable Class(*) where there’s Properties containing any “meta data” (so to speak). Like some sort of ID (“name” ??) some sort of Connectivity/Relation/Classification, some/any other thing … blah, blah. Then you can query your collection(s) via classic LINQ/PLINQ stuff etc etc. “Kinda” like a BIM approach in some AEC app.

(*) Say:

public class BInfo{

public Brep BREP {get;set;}
public int PARENT_ID {get;set;}
public int ID {get;set;}
public string NAME {get; set;}
public int[ ] CONN {get;set;}
public BrepFace[ ] FACES {get;set;}

public BInfo(Brep brep, int par_id, int id, string name, int[ ] conn, BrepFace[  ] faces){
   this.BREP = brep; .... blah, blah

}
}

Hi Tom, thanks very much for this. I think that makes sense. So basically, object names only existing the Rhino world, but are not a property of Grasshopper geometry.

User Dictionaries, do however appear to cross over between worlds. I gave give Grasshopper geometry a User Dictionary key and value, bake it, then retrieve the same key and value when I bring the geometry back into Grasshopper. So it looks like this would be the best way to transfer “names” from GH to Rhino and back again.

Thanks @PeterFotiadis - will take me a while to figure out what you’ve done here! :blush: Can I not just achieve all this with User Dictionaries as I describe above?

If you get your data from the RhinoDocument, then you should not reference the Geometry but the RhinoObject. This way you can utilize the User Information within your script. This is only doable by script, because Grasshopper does not officially support this way of working with data.

Again, if you bake it, you create a new RhinoObject attaching your Geometry. By doing that, of course you can also specify any meta-data you like, such as giving a name, layer or color.

  1. If you are in the broad AEC market sector … forget all that > go for a proper AEC BIM thingy.
  2. Using Classes open roads/paths that are far and away from what an UD can do> always focus to future things: the present is dead already.

I’m not entirely sure what you’re aiming for, but this example might help with reading object attribute user texts in GHPython:

If you want to also set these, you can use rs.SetUserText:

https://developer.rhino3d.com/api/RhinoScriptSyntax/#userdata-SetUserText

1 Like