Bug: conversion of text to plane fails

Just noticed that there seems to be a bug in Grasshopper in Rhino V7 in converting planes to text and then back to planes.

I am trying to save a bunch of planes as a text file and then read them back again. I noticed that converting to planes from text fails and returns NULL (and is super slow).

convert_text_to_plane_bug.gh (395.8 KB)

The text conversion that GH does is used to represent the object in a human-understandable way, not to define the state of the object in string type, so you are not getting the state of the object in text but a representation. Even for simple types like point or vector that GH can create them from text you lose some information in decimals since the conversion to string is designed to be a human-friendly representation so its may ignore some decimals.

On the other hand, if you look at the text representation in GH of a plane, the format used is point and normal, and so you can’t recover the original plane as you have 360 degrees of freedom to place the other axes.

You have to make your own format and conversion method.

1 Like

I used to save plane information of a block as key/value data. My first approach was to save the whole string output but I ended up deconstructing the plane info into origin, X, Y and Z vectors and save those as individual values.

One way to serialize a plane is by converting it to JSON with JSwan (or a C# script) and then using a short script to deserialize it:

Note that the script will need to be given a reference to Newtonsoft.Json.dll in the “Manage Assemblies” right click menu.

1 Like

text_to_plane_2021_Jul26a.gh (283.5 KB)

@Dani_Abalde Thanks for the explanation. That makes total sense actually that it doesn’t sufficiently describe a plane. I will create my own format, probably just going straight for a transformation matrix.

@andheum cool idea to convert to json format. Took me a while to figure out JSwan and that you have to zoom in to add an input. I have not seen that in any other plugin - maybe you could add a small gif of that in food4rhino. You only show the deserializing part, but not the serializing.

@Joseph_Oster thanks for the super quick way of doing it. I will add some IDs and make sure it’s all in one line per plane for a text file. Right now it would just flatten everything into lines, so you would have 3 lines per plane. So to better simulate what will happen you would have to flatten the text output and then reconstruct from there. But I will do that part.

IDs? Like data tree paths?

I’ve used GH Python to produce (json.dumps()) and read (json.load()) JSON successfully but hesitate to wade into it for this…


By the way, working with 14,400 planes as test data is a pain! (SLOW)

P.S. Here is a single line per plane text format using “|” as a separator.:

text_to_plane_2021_Jul26b.gh (287.8 KB)

Thank you. Yes, I know having that large a data set is a pain, but it’s the data set I have to work with, so its nice to keep it realistic and see also which solutions are slower than others.

I am still kind of baffled why Grasshopper is so terrible at dealing with large datasets. Anything above say 10.000 list length and it seems to really get slow.

Try whether disabling the autosave speed up your workflow.

I just disabled it, but it seems just as slow. A lot of things you don’t realise are slow until you really crank the numbers. I will post a separate issue as to why ScaleNU is so much slower than Scale (factor 20x). Understanding these things is the first step in working around it.

Here is a version that includes the original data tree paths as IDs, flattens the “text file” (yellow group), then reconstructs the original data tree. The bottlenecks here are Construct Plane (17.5 secs.) and Replace Paths (6.3 secs.).

text_to_plane_2021_Jul26c.gh (289.0 KB)

1 Like

@andheum I just gave your suggestion a go in the hopes it would be faster/better, but get stuck on getting the C# to work.

I have added the Newtonsoft.Json.dll file to the assemblies and added in the code with “using…”.

But I somehow get lots of error messages:

Any idea what I am doing wrong?

Also what does the “Deserialize” do if not convert it back to its original data format? At least that is what other deserializer do that I have coded myself!?

json_serialize_planes.gh (7.4 KB)

I tried Python and C# versions of Construct Plane and discovered some interesting things:

  1. Python and C# are almost identical in Profiler times.
  2. A substantial part of the time in all cases is converting the X and Y vectors from text, as you can see by passing the text versions through Vector params first (or not).
  3. Python and C# are both slower than the standard GH component. (or nearly the same when vector conversions are included)

text_to_plane_2021_Jul26d.gh (283.0 KB)

objet to string = SErialize.
string to object = DEserialize.

You are using the wrong method.

@Joseph_Oster I noticed the same actually, in most cases of very slow components with lots of data it is because of the type conversion. Thanks for verifying this on your end as well. Such a shame that it is that slow and kind of not understandable. I use the same kind of datasets in other tools like vvvv and if you convert from string to number there it barely makes a dent in the 60fps it normally runs at.

@Dani_Abalde wait, I am confused now. That is what Andrew shows in his screenshot though!? I want to convert the JSON string into an object again of datatype plane.

Ok then you have to DEserialize but in your screenshot your input is Plane type instead of string type, but even so you are sending a Json Object.

Right click on “x” input > type hint > string and plug the panel to “x”.

1 Like

So I just gave it a go with actually writing and then reading a JSON file and it doesn’t seem to want to work.

In the documentation it says you can just plug a path to a .json file into the deserializer. But it always says “no valid JSON properties found”, even though the file literally just contains the same output as what the serializer outputs.

json_serialize_planes_read.gh (20.4 KB)

So from what I gather the Deserialise compontent of jSwan just splits the JSON data into its groups, but does no data type conversion the way the serializer does!? Just trying to wrap my head around what jSwan does and does not do.

I guess that JSwan component input is asking you for json data, not file path data.

ObjectToStringJSON.gh (8.2 KB)

In C:\Program Files\Rhino 7\System you can find the library Newtonsoft.Json.Rhino.dll to add in the C# Script components if needed.

  private void RunScript(object obj, ref object Json)
    Json = Newtonsoft.Json.JsonConvert.SerializeObject(obj); 
  private void RunScript(string json, object type, ref object Obj)
    Obj = JsonConvert.DeserializeObject(json, type.GetType()); 

Thanks I will take a look at your implementation!

Here is the documentation for jSwan. You can apparently either input json data or a file path to a .json file.

JSwan supports a file path as input — it will read it in. The problem is that you’re not writing a valid json file — you’re writing a bunch of individually valid JSON files into one file (without grouping them). This is valid:

"property": "value"

but this is not:

"property": "value"
"property": "value"

To remedy this, right click the “planes” input to your Construct JSON component and set it to “list access” instead of “item access” so that it will produce a single valid JSON from your list.

1 Like