So I’d need first a C# script to make the conversion from Rhino object to string, then a Python script to insert the string in a SQlite database, and then another C# script to convert the string back to geometry.
OK, so I might be better-off not using the SQLite library for Iron Python which is already available with Rhino then, and rather use C# and bring about the proper dependencies.
Seriously, Nathan, I’m a complete Python noob, and yesterday, it took me half an hour to realize my script was not working because of a friggin’ coma.
How am I suppose to guess how to type that in if it’s not documented ?
Just went through the Rhinocommon API documentation , and I realize that there’s no help whatsoever for Python what’s the deal here ?
Since I love it when people resurrect this old thread (no irony!) and the JSON thingy got me really interested aswell, I threw together a really minimal example in the hope that it might help @osuire and others:
# import RhinoCommon
import Rhino
# create serialization options
options = Rhino.FileIO.SerializationOptions()
# set RhinoVersion (optional)
if RhinoVersion:
options.RhinoVersion = RhinoVersion
# set if userdata should be written (optional)
options.WriteUserData = WriteUserData
# get json string
JSONString = Geometry.ToJSON(options)
Code for Deserialization:
# import RhinoCommon
import Rhino
import json
import System
# convert the JSON String to python dictionary using the json module
PyDict = json.loads(JSONString)
# create a new .NET dictionary
SysDict = System.Collections.Generic.Dictionary[str, str]()
# loop through python dict and fill .NET dict
for key in PyDict.keys():
value = str(PyDict[key])
SysDict.Add(key, value)
# de-serialize the geometry by creating geometry from the json dict
Geometry = Rhino.Geometry.GeometryBase.FromJSON(SysDict)
A few things come to mind while doing this (ping @nathanletwory) :
It works, which is really cool in my opinion - have searched for an easy way to serialize rhino geometry since a bit. Thanks for this!
I would really appreciate if some overload could be implemented so that the FromJSON method accepts a python dict object
To me it seems a bit strange that ToJSON produces a string but FromJSON absolutely needs to have a .NET Dictionary[str, str]. In my opinion the method should be able to deal with whatever comes out of ToJSON itself. But maybe I’m wrong?
And last but not least something a bit off-topic: Please, McNeel, you have to realize that a lot of the developer documentation - especially regarding python - is in an absolutely horrible state since years!
There are not only missing examples but completely missing documentation items. This makes working with some parts of RhinoCommon a nightmare. I would strongly advise you to just hire one Rhino scripting nerd whose job it is to collect all the terrible loose-ends in the documentation.
Maybe I’m naive here but it can’t be that big of a problem - I’ve been thinking about this for 2+ years and often was on the edge of writing docs myself and send it to you, just because I’m so immensely tired of having to look at things like this all over the place:
Although I have a job at the moment, please do let me know if a position as ‘documentation slave’ is available. This is not a joke, I would be more than happy to do this! I have the sickest OCD which will not let me stop until everything is super nice, tidy and shiny and on top 3+ years of experience in digging through missing documentation and getting it to work in python anyway. Interested?
With that all being said I hope the provided example is useful. It could also be added to the… *cough* documentation *cough* …
Let me tag @stevebaer for these bits of feedback as well.
It isn’t indeed the best there can be. I’m sure we have numerous excuses, non of which improve the quality of our documentation in the short term.
There have been efforts in getting a better site, and filling out the doc strings in code is an ongoing process. For the JSON functions it happens to be @stevebaer who probably forgot to type out every bit, but there are probably enough cases where the shortcoming is my blame.
Hey @osuire, I just had some minutes to look into this.
There is a difference between Attribute UserData and Object UserData, as you can see in the following screenshots
I don’t have time to investigate the specifics here, but Attribute UserData can not be read/evaluated by GH - at least I have no idea how to do it. Maybe @stevebaer or @nathanletwory are able to clarify here. If I had to make a guess, I’d say Attribute UserData is not attached to the Geometry itself but to the Document Object in Rhino somehow. But to be honest that’s just a guess and quite frankly I don’t know why there are two kinds of userdata in the first place.
Setting userdata to the Object works fine for me, though. I am also able to serialize/deserialize it correctly. Since I do not know which component you used to retrieve the userdata, I built my own in python.
My opinion is that no real thought has been put in the subject of metadata in Rhino.
McNeel spurted out some stuff which I’m not sure they really understand themselves, and never bothered to try and make it actually useful and practical.
There are no native search, sorting, presentation features based on metadata…
We just have an archaïc key and value input which in my case even makes Rhino crash when used in conjunction with Human UI.
Actually, this is why I’m working on pushing the metadata in a SQLite database in the first place.
The worst omission is that attributes on sub-block instances just can’t be changed programatically, and no one seems to realize how crippling this is to manage data within an organized model.
In short, this has not been thought-out because of lack of ambition.
Bob still thinks his software is for week-end hobbyists…
Human and Elefront have components that allow to read and write metadata, but I agree it’s nice to make one’s own components.
I’m not sure what can be gained by serializing the geometry and it’s metadata.
If it takes 114 ms to serialize a sphere and a pair of attributes, I’m a bit scared of the running time for some of my 1.4 GB models
I still don’t know the difference between the two types, but Attribute UserData can at least be searched etc using the (new?) interface. But it seems the same does not apply to Object UserData. Anyhow, would love if someone from McNeel could elaborate on the difference/concepts. Because I agree that it could be a lot more useful given the proper interfaces (in regards to Rhino as well as to the API).
While I have not used it in a real world scenario, the benefit of serialization is that you end up with an “environment agnostic” form of the data, since a string is pretty universal. My impression is that once external databases come into play it could actually be useful to keep the serialized version of geometry inside the database instead of keeping thousands of files for example (which also would mean to maintain correct folder structure etc.).
In regards to computation time my educated guess would be that serialization can’t outperform saving because saving a file/model is basically just serialization. Heavy models take ages saving and so will serialization of a lot of geometry/data. In regards to this particular case, python might also “make things worse” but I haven’t cross-tested with C# and I’m frankly too lazy to do it until a real usecase arises for me