I uploaded an object from Grasshopper to speckle.xyz, and received it in python (specklepy), I want to get the data from the category named “EdgesValue”, please see attached photo:
Indeed, the default behaviour of the SpeckleGH is that Brep definitions detach and chunk the content of the EdgesValue.
In this example, EdgesValue is not actually an attribute of the Brep object, but rather a dynamically computed property that is defined using the @property decorator - or in this case the equivalent in cSharp. Therefore, trying to access it with brepj['EdgesValue'] will raise a KeyError , because EdgesValue is not actually a dictionary key.
Instead, to access a computed property like EdgesValue , you need to use the regular attribute access syntax (Brep.EdgesValue ), rather than the dictionary-like syntax (Brep['EdgesValue'] ).
This is related to how we are decomposing and serializing Breps coming from Grasshopper, which detaches and chunks those values to handle them when very large.
There isn’t any way presently in the Speckle UI to distinguish these properties.
In python, you can distinguish object attributes vs object computed properties.
def list_properties(obj):
attributes = []
properties = []
for member in dir(obj):
if member.startswith('_'):
continue
if callable(getattr(obj, member)):
continue
if isinstance(getattr(type(obj), member, None), property):
properties.append(member)
else:
attributes.append(member)
print("Attributes:")
for name in attributes:
print(f"- {name}")
print("Properties:")
for name in properties:
print(f"- {name} (computed)")
list_properties(gh_data)
For this project, My main purpose is to extract the vertices and faces data from the GH_data and use them for triangulation with Trimesh library, I can extract vertices data easily with vertices = received_base[“@{0}”][0][“Vertices”], however, when I try to extract faces data using faces = received_base[“@{0}”][0][“Faces”], it gives me the same thing:
The conversion from GH Brep to Speckle uses EdgesValue just for serialization/deserialization and is 1:1 with the values used for Edges and likewise Loops, Faces and Trims
As you can see in your python example, the attribute is present, but it isn’t in the speckl stream. It simply doesn’t exist. The frontend UI only shows the raw Speckle data as far as it can. The data tree in the UI doesn’t work like the Speckle Connectors or Specklepy as it doesn’t translate those values back into the geometric primitives.
Longer answer: To save space.
e.g. The Vertices property is a List of Points which makes sense in terms of what they are computational, whereas VerticesValue is a List of double values. This makes it straightforward for Speckle to detach, chunk and then serialize the parent object - again related to the Decomposition API | Speckle Docs
–
you can access the Vertices and the Faces in the same way as I demonstrated in my last post.
I don’t know how familiar you are with Brep geometry, but whereas there is a clear relationship between Vertices and Faces in the displayValue mesh Speckle stores for objects, the same is not true for Breps. As you see the properties of a Face are the Brep Loops.
tldr; To answer your question directly, you cannot get the vertices of each face in the way you describe for Brep Faces as if they were Mesh Faces.