Speckle V2 Grasshopper client - Assign nested properties

Hi there, Speckle people!
I was testing speckle V2 and the Gh client in particular when I came across the following doubt: What is the correct way to assign nested properties to a Speckle object. I have Rhino geometry that contains custom user data in the form of nested dictionaries. I figured out a way to assign nested properties using a combination of “create Speckle object” components but this feels messy and sort of unstable as it will probably break if the structure of the original dictionary changes. Is there a better way to do that?

Here’s an example of the dictionary - it is dynamic and changes from one object to another, so I need a flexible way to do all that:

{
  "group": "group_type",
  "prop1": {
    "1": { "properties": ["prop prop"], "id": "002" },
    "2": { "properties": ["other props"], "id": "003" }
  },
  "prop2": {
    "subtype": "subtype string",
    "tags": { "tag_1": "A", "tag_2": "B", "tag_3": "C" }
  },
  "prop3": "Wall1",
  "status": "status string",
  "prop4": {
    "subtype": "subtype_type",
    "tags": { "tag_4": "0", "tag_5": "0.1" }
  },
  "prop5": {
    "subtype": "subtype_string",
    "tags": { "a": "1", "b": "2", "c": "3" }
  },
  "comments": "some comment"
}

Thanks a lot! Any help is appreciated :slight_smile:

1 Like

Hi @Mariela_Tsopanova, and welcome to the Speckle Community! You can use the Create Speckle Object by Key/Value to generate dynamic objects (each with it’s different properties and values).

Creating a single object with single item values

Creating a single object with mixed values (item and list)

Creating multiple objects with mixed values

Notice that for single item cases you don’t really need to worry about the data structure, but in order to generate multiple unique objects, the data structure must match

Meaning, all keys at path {0} will generate one object. The key at path {0}[0] will be populated with the value at path {0;0} (wether its a list or a single item), and so forth. It can get quite tricky but its also super powerful.

I’ve also attached the file so you can poke around with it. Let us know how it goes :slight_smile:

CreateObjectsByKeyValue.gh (22.3 KB)

2 Likes

Ciao Maria, good to see you here!

Another possibility is to do that in C# or python.

In C# you can either temporarily cast the Speckle Base object to dynamic, or reference Core in the C# node (more messy).

Please note that if you are editing an object in a C# node, also the upstream object will be modified!

Here is how you can add a property or a set of properties in a C# node:

  private void RunScript(object x, ref object A)
  {
    ((dynamic)x).mycustomProp = "Prop assignd in C#";
    A = x;
  }

1 Like

Thank you very much both! I had a quick look at your suggestions and I would definitely love to give the custom GH component a shot.
I have no experience in C# so this looks like it might be a challenge for me. I managed to reproduce Matteo’s 2-liner above but I am not sure how to approach the whole nested prop issue afterwards.
I do feel a bit more confident in python so it might be a better match for me.

On a slightly different topic, V1 had a wonderful documentation of the API (Speckle), any chance there might be something similar for V2? I tried following the example from here (Introduction | Speckle Docs) but I am running into an error pretty much immediately when trying to receive the commit object → ValueError: not enough values to unpack (expected 2, got 1). Not sure how to interpret that.

1 Like

Hi Mariela,

Great to hear that! @iltabe has also been using Python to attach custom props to Base objects and might have some tips to share…

Regarding the API, in v2 the graphql explorer is your best friend, which is also self-documenting. GQL has a bit of a learning curve to get comfortable with it, but it’s quite powerful! We’re due to write some more examples on how to write queries, but you can see plenty of examples in our code.

For any issues with the Pyhton SDK you can open a new thread and someone from the team will help you!

2 Likes

Ciao Mariela,

Speckle is now very smart. You can assign a python dictionary as a property and it will just expand it properly when added as input of the ExpandSpeckleObject component (thanks @AlanRynne!):


Here what I did inside the python component:

"""Provides a scripting component.
    Inputs:
        x: The x script variable
        y: The y script variable
    Output:
        a: The a output variable"""

__author__ = "iltabe"
__version__ = "2021.06.07"

myObjectExtended = myObject.ShallowCopy()

def main(myObjectExtended):
    for key, value in dictProps.items():
        myObjectExtended[key] = value

main(myObjectExtended)

Note that this might have a problem if you are relying on the Speckle kits to convert the object.
Are you using the data also outside grasshopper?
If so we can create a recursive function that create a new speckle object every time the property to assign is a dictionary itself.

Let me know how is going,
Gianluca

3 Likes