algorithmic modeling for Rhino

RhinoCommon/Grasshopper: A New Class for Geometry with Key/Value Pairs? UserData?

This is really an open ended feature request, and if it would be a foolish feature to add, I am completely open to suggestions about how to address the functionality I'm looking for.



I'm working on several methods for importing GIS data to Rhino and Grasshopper, and I'd like to make this data as accessible as possible for scripting. Some of the simplest forms of GIS data, well expressed in the GeoJSON file format, have a form that lies in between the DocObject classes and the Rhino.Geometry classes in the RhinoCommon SDK. Essentially, with any geometry comes a set of key/value paired attributes. In JSON format, these attributes need not be strings, and they can nest other data structures within them, such as lists and dictionaries.


The Issue

ObjectAttributes objects can have UserString key/value dictionaries, which I currently use to parse GIS attributes. So when I import GIS data, I'll create DocObjects with UserStrings. This creates an awkward bridge to Grasshopper, where I would have to import the Geometry and the UserStrings as separate objects. It also means that I'm not importing directly to Grasshopper, and that all the data is created in the Rhino document before being accessed by Grasshopper. I could write some custom classes, but I'm lazy, and think many people could use this feature who are implementing plugins and trying to get data to map to Grasshopper objects.


The Request

It would be great to have some simple wrapper class for Rhino.Geometry objects which included key/value pairs. Such a simple class would be great for mapping all sorts of associated data to geometry, and could potentially simplify a lot of data translation and mapping issues. It could open up the possibility of richer associations between non-geometric data and geometric data in grasshopper, associations which could be more easily transferred between grasshopper, rhinoscripts/plugins, and rhino documents.


I know this has been touched on before, but I thought this would be a more useful description of the issue I'm encountering.

related posts:

in the latter post, David notes that he already started working on a UserData feature.


Views: 1101

Reply to This

Replies to This Discussion

another related Discussion:

In which David makes a good point about the problems of implementing UserData. So is the solution to simply separate userData from Geometry for Grasshopper? I feel like there must be some solution that would solve most of the desired use cases but which could bypass most of the problems described by David.

Hi Ben,

This is something I plan on implementing in RhinoCommon. I was thinking about adding a user dictionary to the geometry/attribute classes most likely in the form of the SerializableDictionary class

I can always add support for more data types to this class.


That's great news!


I suppose for the time being I can just make a wrapper class with UserString and Geometry attributes when I have a need for this functionality.

Hi Steve,

I'm updating a script that uses this feature, and I'm getting some strange behavior.

basically, I have a line like this, where I simply copy key value pairs of various data types into the UserDictionary of GeometryBase objects:

for k in data:
    geom.UserDictionary.Set( k, data[k] )

I assume that the overloading of the Set method can handle the different data types, and determine the appropriate storage type. However, when I set a variety of keys in this manner, and later try to access them, they have all become Boolean values, irrelevant of their previous type. Perhaps they were being cast to the first method overload? Set( key, Bool)?

Hi Benjamin,

I'm working with the UserDictionary for a while now and it's working properly. Since i'm working in C# i think it might be a problem with the DataType functionality in Python. 

In Python if you read the value of that entry in the ArchivableDictionary (type of UserDictionary) you'll get a your BaseGeometry value should be there...try this ...for me it works:


 import Rhino.Geometry as g
import rhinoscriptsyntax as rs
my = g.LineCurve(g.Point3d(0,0,0),g.Point3d(0,0,1))
other = g.LineCurve(g.Point3d(0,0,0), g.Point3d(0,0,2.64))
data = my.UserDictionary.TryGetValue("key")
print data[1].GetLength()




 thanks Florian. i thought I might be getting a tuple with a boolean value in front, but if I assigned the output to two variables, it couldn't unpack the tuple.

a, data = my.UserDictionary.TryGetValue("key") # doesn't unpack

Anyways, thanks, I'll try some other approaches.

would it be possible to serialize a System.Object?






  • Add Photos
  • View All

© 2019   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service