I’m building a library with a lightweight Speckle API.
I want to be able to filter through a Stream’s objects for specific types, as recorded in their speckle_type attribute (as strings)
When I view the object in the viewer, the speckle_type is correct (e.g. “Objects.Geometry.Brep”)
In order to get their types, you need to first deserialize the objects received from the API, then something like this.GetType().Name should give you the actual class/name.
Unfortunately I still get “Speckle.Core.Models.Base” on performing .GetType() on this object.
Is it something to do with the .Flatten() method that has internal casts to Base? I notice that the speckle_type property of the Base class has a dynamic getter that composes the string from .GetType()…?
In any case, why does the viewer app produce the correct speckle_type (in the example – “Objects.Geometry.Brep”) while my C# code does not?
Thanks @dimitrie.
I’m using the Speckle.Core.Api helpers which (correct me if I’m wrong) do the deserialization for me?
I’m not sure what you mean by loading the objects kit. On getting a commit I do see a message that a ‘Kit Manager’ was initialized–
var commit = client.CommitGet("c0f66c35e3", "9a9670946f").Result; var root = Operations.Receive(commit?.referencedObject, transport).Result;
Results in:
[22:25:34 INF] Initialized logger inside Coreunknown/2.18.0/2.18.0.13567 for user 91C733C10DF1496893028551A8BB138C. Path info /Users/daniel/Library/Application Support /Users/daniel/Library/Application Support.
[22:25:34 INF] Initializing a new Remote Transport for https://speckle.xyz/
[22:25:34 DBG] Starting execution of graphql request to get StreamData
[22:25:34 DBG] Starting execution of http request to https://speckle.xyz/graphql
[22:25:34 INF] Execution of http request to https://speckle.xyz//graphql succeeded with OK after 0.9099276 seconds and 0 retries
[22:25:34 INF] Execution of graphql request to get StreamData succeeded after 0.9457364 seconds
[22:25:34 INF] Starting receive e7acaac21ae7e9369339900a4aaeb827 from transports SQLite / RemoteTransport
[22:25:35 INF] Initializing Kit Manager in /Users/daniel/Library/Application Support/Speckle/Kits
[22:25:35 INF] Finished receiving e7acaac21ae7e9369339900a4aaeb827 from RemoteTransport in 0.4712478 seconds
Once there, I simply flatten all children and find a match for the object’s Id I’m looking for: var children = root.Flatten().ToList(); var foo = children.First(item => item.id == "ef629b7b125e750815bb25d0e209b675");
foo["speckle_type"] gives me “Base”…
If I haven’t loaded the Objects Kit, how do I do so?
To frame the question another way:
How can I deserialize this object (which is an “Objects.Geometry.Brep” according to the webviewer), into an instance of a Objects.Geometry.Brep using the Speckle C# libraries?
I think you’re doing everything right, and it might be due to the environment provided by polyglot notebooks; .NET lazy loads assemblies on need, so at the point of deserialisation the objects kit is not actually loaded yet. I might be wrong, and I have no clue how assemblies are managed in that environment
Could you create that point within the same codeblock where you’re receiving things, just before the actual code (commit get, operations receive)?
The last thing is for us to try and reproduce locally if this doesn’t work out.
Thanks @dimitrie! Utilizing the Objects Kit in the same cell as a deserialization operation (e.g. with .Receive()) does produce accurate typing of objects, so it seems like it’s to do with how dotnet loads assemblies as needed within a notebook’s cells.
Not sure what an overall fix for Speckle might look like if use of notebooks is more generally supported (maybe some way of inviting a user to specify namepsaces/assemblies for use during deserialization?)
Happy to hear it worked out! I’m not sure there’s a proper “fix” from our end - it would mean doing things against how .NET is meant to work, even though it’s what you would expect in a code notebook.
What I can do is edit the title of this post and have it read loud and clear what we solved for so others can find it down the line.