Custom kit conversions wrapping objects with a base tree

I’ve been building out a custom kit to handle the conversion process in gh and I’ve noticed that anytime I pass an object to into the sender that it gets wrapped in a empty base object that acts like a tree. I stepped through the sender component to get a bit more familiar with what’s happening, and it seems like this is the expected behavior from that component, but I wanted to ask the crew if there was any sort of modification/hack that component might have to not break the object into a tree? Here is the object in a stream that is being wrapped

The issue with it going into a tree is that it gets a little bit lost in the converting process when I bring that object into any other connector. Lil’ example - in unity I wrote a simple converter that picks up any of my custom objects and handles those conversions, but with the wrapper around it I have to rely on the recursion helper method to step through all the objects. I wouldn’t say it’s issue since I can copy+pasta the helpers the crew has already cooked up and modify it to work for my custom objects, but maybe (if this is the expected behavior from the gh sender) the ISpeckleKit could have a recursive check method too?


Hey @haitheredavid,

I can’t seem to be able to access the stream. Could you give me access to the stream at I do think I know what you’re referring to, so here it goes:

As you suspected, this is the way the sender works. Since we do not know in advance if you are sending an item, a list, or a tree of data, we handle everything as a tree and try to convert it… meaning:

When sending any object in grasshopper, it will preserve everything (including the useless leading paths such as {0;0;0;0;0;0}. So in this case you would have 6 nested lists before you send the object.

We could, in theory, handle this on a case by case if you make a powerful argument for it :wink: But for now, if you want to just reduce the useless nesting in your @data prop, I would suggest to always simplify the D input in the sender (this will collapse all the useless nesting).

Even an individual item will be sent wrapped in a list, so simplifying will only get you so far… but at least it will be more predictable than whatever random path GH decides to throw at you!

Anyway, you’ll still be stuck with 2 levels of lists (1 representing the data tree and one for each branch

I’ll have a chat with the team about this, as it currently stands, you do need to understand quite a bit of how GH works to get why you always get those pesky lists even when you just sent a single item.

Sorry to not be of much help…

Thanks for reporting this, as always!!


Just to add on top of what Alan already said, that extra level of wrapping that you are seeing is probably due to some logic (writte by yours truly) that is attempting at preserving the GH data structure in a way that can then be easily unpacked in Dynamo as nested lists.

I don’t think any other Speckle connector is relying on that so, if you’re not concerned about Dynamo in you Kit you can probably get away without all that recursive madness!

1 Like

@AlanRynne coming through with the info :rocket: ! Side note - i set the stream to public so if you want to poke around feel free :eyes:

I had a feeling that this was the case when I saw the input parameter being set to AsTree, and that makes a lot more sense now with your explanation. I tried smashing the branches of the tree down as far as I could but like you said there is still a single wrapper around the object at all times.

I don’t think I could make any sort of reasoning for this type of support to be implemented for my use case, I see it causing more headache than happiness. I ended up adding a hacky solution that uses the SyncSenderLogic and allows me to setup a simple commit from that node rather than using the Sender node. This new commit is the expected format I was hoping for

I still think the shared logic of wrapping all the objects as nested lists makes sense with how data is structured in dyn/gh…But I can imagine other custom kitters might find themselves in the same position where they don’t need that wrapper. Just a random idea so take it with a grain of :salt: but maybe there could be an additional method on the ISpeckleConverter that for dealing with nested list objects? That could possibly be integrated in the TryConvertToSpeckle since that is where I think tree is sprouted :christmas_tree:. Or Or! Maybe each kit should link to a simple object like base that can do all the nesting? That way the logic for breaking down objects from connectors could be the same but a custom converter could detect that the object as one of it’s homies without having to rely on the Objects recursive method? (feeling like i’m pointing to a very simplified solution that has no real understanding of the complexity it could create )

@teocomi :hocho: Cutting up data in all forms! I might need to study up on the kits some more, but does the ISpeckleKit offer this type of support of dancing around nested lists?

Not really, the ISpeckleKit is just an interface, so it proves a common structure for other Kits to follow. How the conversions are implemented is entirely up to the kit author!


To extend on @teocomi’s answer, you can also recycle our converters in your kit so you don’t duplicate the logic (using our nuget packages :wink: ) process is not very “dev-friendly” as there is a lot of boilerplate, but does work just fine :partying_face:

You can check out a test custom converter I threw together here speckle-examples/dotnet/custom-gh-converter/CustomGrasshopperConverter at alan/dotnet/custom-kit-example · specklesystems/speckle-examples · GitHub

Side node on the objects data structure

From 2.7 onwards you won’t have to worry about the “data structure” of objects anymore (that is… if you don’t care about it :sweat_smile:)

Next version will have 2 new extension methods Traverse and Flatten that will allow you to run through all objects in a speckle object and operate on them as you wish (Documentation is being updated…)

You can have a peek at them here speckle-sharp/Extensions.cs at main · specklesystems/speckle-sharp · GitHub