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

1 Like

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.

4 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)
3 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!

1 Like

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.

2 Likes

: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.

1 Like

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.

1 Like

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.

3 Likes

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.

1 Like

Hi, I am one of the developers of PyVista. Thanks for this great thread. I have registered the script of this thread in the following repository.

Edit: Also, I really love stpyvista. It is really useful.

1 Like

There is also an example of an STL viewer in the stpyvista gallery:

The code is available at the examples repo.

1 Like

Thanks! I will add link to it in the README of the repository. I have created my repository for study purposes, but now I believe that using stpyvista is the best option.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.