Visualization of stl files

Hey everyone,

I’m deploying an app in Streamlit where I would like to upload a .stl file, and show/visualize it within the app. I have done some research and I found at least one way to do it, with pyplot. However, that doesn’t allow me to rotate the object to see all the views. In the example below, I uploaded a stl file of a frog, and I can actually display the frog, but I can not rotate to see other views.

I would like to display the content of the .stl file like the molecules are displayed in this example https://share.streamlit.io/napoles-uach/stl2mol/main/app.py. I would appreciate any suggestions.

Best,
Paulo

Here is an idea daisy-chaining pyvista with streamlit,component.v1.html :melting_face:

renderpyvista

import streamlit as st
import pyvista as pv
from pyvista import examples

## Using pythreejs as pyvista backend
pv.set_jupyter_backend('pythreejs')

## Download an stl file
# filename = examples.download_cad_model(load=False)
uploadedFile = st.file_uploader("Upload a STL:",["stl"],False)

## Streamlit layout
st.sidebar.title("STL viewer")

if uploadedFile:
    
    stlTemp = "./temp.stl"
    with open(stlTemp, "wb") as f: 
        f.write(uploadedFile.getbuffer())

    color = st.sidebar.selectbox("Pick a color:",["white","green","blue"])

    ## Initialize pyvista reader and plotter
    reader = pv.STLReader(stlTemp)
    plotter = pv.Plotter(
        border=True,
        window_size=[580,400]) 
    plotter.background_color = "white"

    ## Read data and send to plotter
    mesh = reader.read()
    plotter.add_mesh(mesh,color=color)

    ## Export to an external pythreejs
    model_html = "model.html"
    other = plotter.export_html(model_html, backend='pythreejs')

    ## Read the exported model
    with open(model_html,'r') as file: 
        model = file.read()

    ## Show in webpage
    st.components.v1.html(model,height=500)

This could be extended to all the formats that pyvista supports, namely Paraview’s vtk.

3 Likes

Just a little refactoring to avoid writing multiple files :nerd_face:

renderpyvista_v2

import streamlit as st
import pyvista as pv
import io
import tempfile

## Using pythreejs as pyvista backend
pv.set_jupyter_backend('pythreejs')

## Upload a pyvista file
uploadedFile = st.file_uploader("Upload a STL:",["stl"],False)

## Streamlit layout
st.sidebar.title("STL viewer")

if uploadedFile:
    
    ## Color panel
    col1,col2 = st.sidebar.columns(2)
    color_stl = col1.color_picker("Element","#0BD88D")
    color_bkg = col2.color_picker("Background","#FFFFFF")

    ## Initialize pyvista reader and plotter
    plotter = pv.Plotter(border=False, window_size=[500,400]) 
    plotter.background_color = color_bkg

    ## Create a tempfile to keep the uploaded file as pyvista's API 
    ## only supports file paths but not buffers
    with tempfile.NamedTemporaryFile(suffix="_streamlit") as f: 
        f.write(uploadedFile.getbuffer())
        reader = pv.STLReader(f.name)
    
        ## Read data and send to plotter
        mesh = reader.read()
        plotter.add_mesh(mesh,color=color_stl)

        ## Export to a pythreejs HTML
        model_html = io.StringIO()
        plotter.export_html(model_html, backend='pythreejs')
        
        ## Show in webpage
        st.components.v1.html(model_html.getvalue(),height=400)
2 Likes

That looks promising, thank you. Can you please share your packages.txt and requirements.txt files that are need to make this work? Thanks!

When I try to run this on Streamlit Cloud, I get a blank page after uploading the STL file. Any ideas what could be causing this? Thanks.

1 Like

:link: Here it is on Streamlit Cloud (which to my understanding is just a Debian machine). The packages and requirements are in the repo. Hope it helps.


As per the blank page, the html file that pyvista generates with the threejs model retrieves a couple of packages that might fail to load when your browser tries to render the model. It works with those sources & requirements but something breaks with @html-manager v.1.0.3

:white_check_mark: threejs requirements that work:

<!-- Load require.js. Delete this if your page already loads require.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@jupyter-widgets/html-manager@^0.20.1/dist/embed-amd.js" crossorigin="anonymous"></script>

:x: threejs requirements that fail to load:

<!-- Load require.js. Delete this if your page already loads require.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@jupyter-widgets/html-manager@^1.0.1/dist/embed-amd.js" crossorigin="anonymous"></script>

This might be a problem from using the latest version of ipywidgets so sticking to 7.7.1 should be fix enough for the time being.

Hi,

I am using
pythreejs==2.4.2
pyvista==0.38.5
ipywidgets==7.7.1

But when i upload the file with .stl format, i get this below blockage and the image is not rendering in the webpage.

pythreejs was deprecated from pyvista so this method will likely not work anymore. But you can check stpyvista to visualize pyvista 3D models on streamlit.

1 Like

Thank you for the reply.

I get this error, when I ran the above code and upload the .stl file

PyVistaDeprecationWarning: pythreejs backend is deprecated and is planned for future removal.