Speckle Conversion Error With Structural Classes in Unity

So in the Unity plugin, I’ve added the following dlls to support structural object types and ignored the revit and gsa specific assemblies because I just what the general structural data objects:

image

When I get this stream (BCiZ-ggPn):

My Unity code is able to parse the layer heirarchy just fine but it is only able to convert the nodes and 1D element poly lines:

image

Notice how all the other layers are empty. This is because for each of those structural types the conversion fails. Aside from Structural2DElementMeshes, the other types inherit straight from SpeckleObject and I have no explicit native conversion for them. If I add the GSA and GSAInterfaces dlls the conversion still fails in the same way even though the stream is a GSA stream.

I can live with the non visual objects being unable to convert but the main problem for me is that the Structural2DElementMeshes aren’t converting because they are visible meshes that need to be rendered. Structural2DElementMesh inherits from SpeckleMesh which I have a conversion for just like I do with lines and points but I’m not getting any feedback on how this failure can be fixed.

I even tried adding an explicit conversion for it like how Unity handles breps:

But that didn’t work and the points and polylines didn’t need any extra code written to work anyway.

Thoughts?

None of the top of my head. Meshes that come from GSA have a few quirks, but that’s on the analysis side of things (storing results mostly).

One thing to check (maybe it’s obvious, and you’ve handled it already) is for quads meshes; would that throw things off? Meshe faces in that stream are actually quads ( 1 = quad, then 4 vertices, etc. ).

The analysis results are stored in the props bag, but they shouldn’t have any bearing on this.

I take it that, without the references to the structural classes, the fallback to a simple Mesh fails too?

I’ve got references to the generic SpeckleStructuralClasses assembly since it’s enabling the polylines and points to convert just fine and those properties are all visible to me. It seems that for mesh types the conversion fails and a fallback to a simple mesh never happens like you said.

What’s strange is that only some of the object types get converted and I’ve written no code to make that happen it was just the inclusion of the structural classes alone that made that work. So I can’t wrap my head around how or why mesh types won’t convert.

Also, @cwm had already covered quad mesh support back in the genesis of SpeckleUnity so I’m pretty confident that’s not a problem either. @nicburgers any idea what could be going on here?

If you step through the code, is your ToNative method actually called? It might have to do with the way Core reflects through available conversion methods. If the GSA conversion comes first, and does not return null/throw an error, Core will never attempt yours (this is something we’ll fix in 2.0).

I narrowed down the problem. It’s a bug in either speckle core or speckle structural classes:

  1. I stepped through my code and saw that my speckle mesh conversion is getting called
  2. A SerializationException is thrown when I call SpeckleObject.Scale() on the Structural2DElementMesh which I do for all objects being received to convert them into meters
  3. Not scaling meshes lets the conversion happen properly
  4. The exception says “Type ‘Newtonsoft.Json.Linq.JObject’ in Assembly 'Newtonsoft.Json is not marked as serializable”
  5. I first thought this was due to me changing SpeckleObject.BaseProperties from a dynamic to a JObject but when I reverted my change the exception still persisted
  6. Even with my change to the BaseProperties type, streams from other clients converted without a hitch
  7. The exception originates from SpeckleObject.GetMd5FromObject() which is called from the scale method
  8. Since I reverted my changes in SpeckleCore and still get the error, I’m pretty sure it’s not anything I’ve done anyway
  9. Streams not from GSA scale just fine for me so I would lean towards SpeckleStructuralClasses being the source of the bug

Does this all sound like it adds up?

Yeps, it does; I somehow think that the properties bag of these objects contain something that gets deserialised to JObjects, which can’t be serialised, which means hashing fails, etc.

You could try removing the properties all together and see if mesh conversion works ok then?

Yep that did it. Setting the properties dictionary to null allowed the scaling to work properly. Shall I submit a bug on SpeckleStructural?

I guess the web viewer had no problem because it likely doesn’t scale the stream.

What would help beforehand is if you could post a screenshot of how the properties bag looks like, to see where the JObjects are sneaking in… (can be done in the issue too!, your call!)

It took some effort but I finally found the sneaky JObject!

It seems like SpeckleStructuralClasses.StructuralResultBase.Value is a dictionary of objects and that’s where the JObject is hiding:

Any more info I need for the bug report?

1 Like

Thanks, that looks good! (i mean bad, it’s a bug, but you get it) I’m trying to parse what’s going on in there, the problem might be in core deserialisation setup, but we’ll move the convo to github onwards…

Which repo should I report it under?

@pablothedolphin, yes please post this to the SpeckleStructural repo

@daviddekoning here it is: Sneaky JObject causing SpeckleObject.GetMd5FromObject() to throw SerializationException · Issue #18 · speckleworks/SpeckleStructural · GitHub

Hi Jakir (I realise now you’re not actually called Pablo!)

The error here was caused by my removal in a recent commit of an annotation in the code to use SpeckleCore’s properties deserialiser for that “value” property, which can handle nested arrays of objects - I’ve restored it now on my branch and it’s currently undergoing some testing.

Cheers

Nic

3 Likes

Looking forward to the next release!

1 Like

Just noting here that the issue has been fixed as of SpeckleStructural 1.1.0

3 Likes