Access layers and materials Rhino/Grasshopper + Python

Hi all,

I’m developing a small app in Streamlit and Speckle for Rhino/Grasshopper. And I want to have access to turn the layers on/off through Streamlit button without opening up the Speckle setting as well as being able to control the color(material) of the blocks shown in the 3d viewer.

Is it something that’s achievable with Specklepy?

Thanks a lot :slight_smile:

Best,
Ashkan

2 Likes

Are you using the embedded viewer?

Most things you can do in the general Speckle viewer (and the embedded viewer) are possible to replicate as each interaction is recorded in the browser URL query parameters.

Colouring:

Assuming you mean controlling the colour akin to the frontend object filtering method. This is the simplest answer.

filter={"propertyInfoKey":"PROPERTY_TO_COLOR_BY"}

You may need to experiment with what values to set in a server frontend, but if you have some relative control over the content coming in from Grasshopper, this shouldn’t be too much of a stretch.

Bear in mind, there is no control by the viewer over what colours are used for each value of the coloured property. There is also NO means of overriding the appearance on an individual object basis, unless you address the object id as the property to colour by.

Isolating/Hiding:

This is more complicated and I can offer two options.

Option A. The URL method:

Objects in the viewer are hidden by a singular method: a hidden Ids array. The UI of the Speckle frontend calculates these ids for you as you interact with the object data.

filter={"hiddenIds":["05f3...","06d2...","08426..."]}

Your Streamlit code would have to parse the Commit Version data to generate these lists for you per Level. This is not HARD to do with python and specklepy, but it is work to setup your UI buttons.

Option B. The Model Branch method.

Whether this is useful to you or not is dependant on what your overall objectives are for this project. The basic principle would be that each Level in the Rhino model be sent to a separate Version Commit or Model Branch.
Your Streamlit hosted viewer would then assemble each component of the whole using the objects overlay method, again with URL construction

streams/STREAMID/commits/COMMITID_LAYER1?overlay=COMMITID_LAYER2,COMMITID_LAYER3

All you’d need to do here in your Streamlit app is keep track of the commit_ids for each branch/commit representing the layers.

Neither option is without work, but with more complex models, the latter is a lot less data processing. It somewhat depends on what you are creating to present to the viewer.


The bonus good news is that the color-by-property instruction applies to all overlaid models, not just the base model.


I can post some example python code for Option A or B if you think that either sounds close.

1 Like

@jonathon! Very much appreciate your thorough and fast reply. You’ve opened many doors to solve my problems, thanks.

For the URL I’ve tried to work with mixing branches and commits, but one of thing is that they URLs appearing in the browser they all don’t have branch name in them, and two every time I change from a commit to another I need to run the viewer by a click.

I’d love to have samples for them definitely, yet feeling bad to get much of your time :slight_smile: I’ll try to try ‘Filter’ and navigate around your solutions.

Thanks again

1 Like

Because you are proposing using the specklepy SDK, you can do this using that!

i’ll work something up

1 Like

Hey @jonathon ,

Hope you’re well.

Regarding our conversation earlier. It seems interactivity through Python SDK with Streamlit and Speckle viewer is not as smooth as I expected, and I was wondering if there is any way I could trigger viewer controllers within Python SDK/Javascript - Just being able to press the “eye buttons” remotely.

image

This is by the way my stream that I’d like to be able to turn the layers/objects on and off:
https://speckle.xyz/streams/7857470991/commits/292d968ca4

PS: I was wondering whether quarrying would be easier with Javascript SDK?

Thanks again :slight_smile:
Ashkan

Is this because the viewer reloads as you change parameters?

If I understood your question correctly, I don’t know of a way to capture events in the embedded viewer from Streamlit.

Your simplest interaction that I know works is via the URL method.

The :eye: toggle works for you in the viewer of capturing the objectIds that are affected by the interaction and adding them to the hiddenIds query parameter.

In the object data available to you at the commit, which you can retrieve with specklepy, you could mimic the UI with IPython widgets wrapped around functions that do the same thing.

I’m not familiar with Streamlit enough to know what UI you can build … is it essentially HTML?

From javascript, your interaction is still not going to be with the embedded viewer, but you could start to wrap it around a Viewer implementation, but again this may be beyond the scope of Streamlit…

This also happens, yes, and sometimes it takes a bit of time to update.

I was hoping to be able to control the user action on the viewer remotely with javascript tricks :slight_smile:

But Do I also see the changes in the viewer and 3d?

Yes, it compiles it to a React web-app at the end, very much like Dash, but also limiting to have callbacks and states.

We are describing a more complicated project than enabled by the embedded viewer. UI interactions across an iframe security sandbox boundary are notoriously difficult.

1 Like

10 posts were split to a new topic: Easiest way to add button to a page which toggles visibility in the embedded viewer?

Really impressive what you got done following my vague hand-waving! Much plaudits to you!

While we are talking feature requests, we’d need to pin down what you mean.

  • Viewer module allowing additional non-Speckle data? (i.e. threejs, powered animations)
  • Animatable Speckle Objects?

None of this exists in the OOTB Speckle platform, but none is impossible. But you need to bring-your-own-code™

:arrow_down::arrow_down::arrow_down::arrow_down::arrow_down::arrow_down::arrow_down:

Technically, the former is possible if you are already building around the viewer package. I don’t have an example to show you. The Speckle team worked on a fun POC hackathon Speckle Corrupted at our last retreat that added physics to the viewer that enabled a multiplayer gaming experience (deliciously hacky). We have discussed ways to enable Viewer plugins, but nothing concrete is in the pipeline.

The latter is not something supported right now. However, as all Speckle objects have an open data schema, I worked on adding model rigging of objects and child objects (Armateurs & Bones, etc.) as an experiment. This was to pass animatable assemblies between applications that supported them as an interop challenge. However, if Objects are entirely within a Developer’s grasp, building Viewer extensions to hook onto something like that would be fun.

Based on your @ashdotio 's recording, I wonder if you are discussing parametric objects and animating them. It’s a different sort of rigging but nominally the same idea. The issue with that is that the viewer uses the fallback displayValue mesh of objects for presentation and doesn’t use the Speckle Objects schema to present a cuboid of variable height.

Potentially easier - now you have me excited, rigging that was only Speckle Objects with a property of Path with sub-properties for speed, physics, and collisions… Again requiring Viewer modifications.

:arrow_up::arrow_up::arrow_up::arrow_up::arrow_up::arrow_up::arrow_up::arrow_up:

1 Like