Skip to content

Commit 0d23daa

Browse files
authored
Merge pull request #22 from edsaac/custom_vtkjs
Custom vtkjs for interactive view
2 parents 40f9489 + 751699f commit 0d23daa

File tree

15 files changed

+269
-19
lines changed

15 files changed

+269
-19
lines changed

stpyvista/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [v 0.0.17] - 2024-04-11
4+
- Rewrite buffer using context manager
5+
- Introduce and experimental viewer based on trame and vanilla vtk-js
6+
37
## [v 0.0.16] - 2024-03-29
48
- Add controls help description
59
- Remove network utility - it should be a different component

stpyvista/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "stpyvista"
7-
version = "0.0.16"
7+
version = "0.0.17"
88
authors = [
99
{ name="Edwin Saavedra C.", email="esaavedrac@u.northwestern.edu" },
1010
]

stpyvista/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
streamlit
22
pyvista
33
bokeh
4-
panel
4+
panel<1.4.0

stpyvista/src/stpyvista/__init__.py

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
# __init__.py
22

3-
from io import BytesIO
3+
from io import StringIO
44
from pathlib import Path
55
from typing import Optional, Literal
6+
import base64
7+
68
import streamlit.components.v1 as components
7-
import pyvista as pv
9+
from pyvista.plotting import Plotter
10+
811
import panel as pn
912

1013
from bokeh.resources import CDN, INLINE
1114

12-
BOKEH_RESOURCES = {"CDN": CDN, "INLINE": INLINE}
13-
1415
pn.extension("vtk", sizing_mode="stretch_both")
15-
16-
# Tell streamlit that there is a component called stpyvista,
17-
# and that the code to display that component is in the "frontend" folder
18-
frontend_dir = (Path(__file__).parent / "frontend").absolute()
19-
_component_func = components.declare_component("stpyvista", path=str(frontend_dir))
16+
BOKEH_RESOURCES = {"CDN": CDN, "INLINE": INLINE}
2017

2118

2219
class stpyvistaTypeError(TypeError):
@@ -27,19 +24,54 @@ class stpyvistaValueError(ValueError):
2724
pass
2825

2926

30-
# Create the python function that will be called from the front end
27+
# Tell streamlit that there is a component called `experimental_vtkjs`,
28+
# and that the code to display that component is in the "vanilla_vtkjs" folder
29+
experimental_frontend_dir = (Path(__file__).parent / "vanilla_vtkjs").absolute()
30+
_exp_component_func = components.declare_component(
31+
"experimental_vtkjs", path=str(experimental_frontend_dir)
32+
)
33+
34+
35+
def experimental_vtkjs(vtksz_data: bytes, key: Optional[str] = None):
36+
"""
37+
Renders an interactive Pyvista Plotter in streamlit.
38+
39+
Parameters
40+
----------
41+
vtksz_data: bytes
42+
Data from a vtksz in zip format.
43+
44+
Returns
45+
-------
46+
str
47+
A stringified JSON with camera view properties.
48+
"""
49+
50+
base64_str = base64.b64encode(vtksz_data).decode().replace("\n", "")
51+
52+
component_value = _exp_component_func(
53+
plotter_data=base64_str,
54+
key=key,
55+
default=0,
56+
)
57+
58+
return component_value
59+
60+
61+
frontend_dir = (Path(__file__).parent / "panel_based").absolute()
62+
_component_func = components.declare_component("stpyvista", path=str(frontend_dir))
3163

3264

3365
def stpyvista(
34-
plotter: pv.Plotter,
66+
plotter: Plotter,
3567
use_container_width: bool = True,
3668
horizontal_align: Literal["center", "left", "right"] = "center",
3769
panel_kwargs: Optional[dict] = None,
3870
bokeh_resources: Literal["CDN", "INLINE"] = "INLINE",
3971
key: Optional[str] = None,
4072
) -> None:
4173
"""
42-
Renders an interactive pyvisya Plotter in streamlit.
74+
Renders an interactive Pyvista Plotter in streamlit.
4375
4476
Parameters
4577
----------
@@ -79,7 +111,7 @@ def stpyvista(
79111
80112
"""
81113

82-
if isinstance(plotter, pv.Plotter):
114+
if isinstance(plotter, Plotter):
83115
if panel_kwargs is None:
84116
panel_kwargs = dict()
85117

@@ -95,10 +127,9 @@ def stpyvista(
95127
)
96128

97129
# Create HTML file
98-
model_bytes = BytesIO()
99-
geo_pan_pv.save(model_bytes, resources=BOKEH_RESOURCES[bokeh_resources])
100-
panel_html = model_bytes.getvalue().decode("utf-8")
101-
model_bytes.close()
130+
with StringIO() as model_bytes:
131+
geo_pan_pv.save(model_bytes, resources=BOKEH_RESOURCES[bokeh_resources])
132+
panel_html = model_bytes.getvalue()
102133

103134
component_value = _component_func(
104135
panel_html=panel_html,

stpyvista/src/stpyvista/export.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from trame.app import get_server
2+
from trame.widgets import (
3+
vuetify as vuetify,
4+
)
5+
6+
from trame.widgets.vtk import VtkLocalView
7+
from trame.ui.vuetify import SinglePageLayout
8+
9+
from pyvista.plotting import Plotter
10+
11+
SERVER_NAME = "stpyvista_server"
12+
13+
14+
async def export_vtksz(plotter: Plotter):
15+
"""Export this plotter as a VTK.js OfflineLocalView file.
16+
17+
Parameters
18+
----------
19+
plotter : Plotter
20+
PyVista Plotter object.
21+
22+
Returns
23+
-------
24+
bytes
25+
The exported plotter view.
26+
"""
27+
28+
# Get a trame server and launch it
29+
server = get_server(name=SERVER_NAME, client_type="vue2")
30+
_, ctrl = server.state, server.controller
31+
32+
with SinglePageLayout(server) as layout:
33+
with layout.content:
34+
view = VtkLocalView(plotter.ren_win)
35+
ctrl.view_update = view.update
36+
37+
server.start(
38+
exec_mode="task",
39+
host="127.0.0.1",
40+
port="0",
41+
open_browser=False,
42+
show_connection_info=False,
43+
disable_logging=True,
44+
timeout=0,
45+
backend="tornado",
46+
)
47+
48+
content = view.export(format=format)
49+
view.release_resources()
50+
51+
return content
52+
53+
File renamed without changes.
File renamed without changes.
File renamed without changes.

stpyvista/src/stpyvista/frontend/streamlit-component-lib.js renamed to stpyvista/src/stpyvista/panel_based/streamlit-component-lib.js

File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)