Skip to content

Commit 50ec886

Browse files
committed
add trame example with client side clipping
1 parent fc412d2 commit 50ec886

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Should import classes from vtkmodules
2+
# but as an example we use vtk for simplicity
3+
import vtk
4+
5+
from pathlib import Path
6+
7+
from trame.app import TrameApp
8+
from trame.decorators import change
9+
from trame.ui.vuetify3 import SinglePageLayout
10+
from trame.widgets import vuetify3, vtklocal, client
11+
12+
DATA_PATH = str(Path(__file__).with_name("star-fighter.vtp").resolve())
13+
14+
15+
class Clip(TrameApp):
16+
def __init__(self, server=None):
17+
super().__init__(server)
18+
self._setup_vtk()
19+
self._build_ui()
20+
21+
def _setup_vtk(self):
22+
renderer = vtk.vtkRenderer()
23+
renderWindow = vtk.vtkRenderWindow()
24+
renderWindow.AddRenderer(renderer)
25+
renderWindow.OffScreenRenderingOn()
26+
27+
renderWindowInteractor = vtk.vtkRenderWindowInteractor()
28+
renderWindowInteractor.SetRenderWindow(renderWindow)
29+
renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
30+
31+
reader = vtk.vtkXMLPolyDataReader(file_name=DATA_PATH)
32+
bounds = reader().GetBounds()
33+
34+
plane = vtk.vtkPlane(
35+
origin=(
36+
0.5 * (bounds[0] + bounds[1]),
37+
0.5 * (bounds[2] + bounds[3]),
38+
0.5 * (bounds[4] + bounds[5]),
39+
),
40+
)
41+
mapper = vtk.vtkPolyDataMapper()
42+
mapper.AddClippingPlane(plane)
43+
reader >> mapper
44+
45+
actor = vtk.vtkActor(mapper=mapper)
46+
renderer.AddActor(actor)
47+
48+
renderer.ResetCamera()
49+
renderWindow.Render()
50+
51+
# region widget
52+
# Widget setup
53+
rep = vtk.vtkImplicitPlaneRepresentation(
54+
place_factor=1.25,
55+
outline_translation=False,
56+
)
57+
rep.DrawPlaneOff()
58+
rep.PlaceWidget(bounds)
59+
rep.normal = plane.normal
60+
rep.origin = plane.origin
61+
62+
plane_widget = vtk.vtkImplicitPlaneWidget2(
63+
interactor=renderWindowInteractor, representation=rep
64+
)
65+
plane_widget.On()
66+
# endregion widget
67+
68+
self.plane = plane
69+
self.render_window = renderWindow
70+
self.actor = actor
71+
self.mapper = mapper
72+
self.widget = plane_widget
73+
self.widget_rep = rep
74+
75+
def _build_ui(self):
76+
with SinglePageLayout(self.server) as layout:
77+
self.ui = layout
78+
79+
layout.title.set_text("WASM Widget")
80+
layout.icon.click = self.ctrl.view_reset_camera
81+
layout.toolbar.density = "compact"
82+
83+
with layout.content:
84+
# from trame.widgets.vtk import VtkRemoteView
85+
# with VtkRemoteView(self.render_window) as view:
86+
# self.ctrl.view_update = view.update
87+
# self.ctrl.view_reset_camera = view.reset_camera
88+
89+
# def update_plane(*_):
90+
# self.plane.SetOrigin(self.widget_rep.GetOrigin())
91+
# self.plane.SetNormal(self.widget_rep.GetNormal())
92+
# self.ctrl.view_update()
93+
94+
# self.widget.AddObserver("InteractionEvent", update_plane)
95+
with vtklocal.LocalView(
96+
self.render_window,
97+
throttle_rate=20,
98+
ctx_name="wasm_view",
99+
updated="utils.get('setupWidget')()",
100+
) as view:
101+
self.ctrl.view_update = view.update_throttle
102+
self.ctrl.view_reset_camera = view.reset_camera
103+
104+
client.Script(f"""
105+
function setupWidget() {{
106+
const widget = trame.refs.{self.ctx.wasm_view.ref_name}.getVtkObject({self.ctx.wasm_view.register_vtk_object(self.widget)});
107+
const plane = trame.refs.{self.ctx.wasm_view.ref_name}.getVtkObject({self.ctx.wasm_view.register_vtk_object(self.plane)});
108+
widget.observe("InteractionEvent", () => {{
109+
plane.origin = widget.widgetRepresentation.origin;
110+
plane.normal = widget.widgetRepresentation.normal;
111+
}});
112+
console.log("widget", widget.id);
113+
console.log("plane", plane.id);
114+
}}
115+
window.setupWidget = setupWidget;
116+
""")
117+
118+
119+
def main():
120+
# region export
121+
import sys
122+
123+
app = Clip()
124+
if "--export" in sys.argv:
125+
app.ctx.wasm_view.save("star-fighter2.wazex")
126+
127+
app.server.start()
128+
# endregion export
129+
130+
131+
if __name__ == "__main__":
132+
main()

0 commit comments

Comments
 (0)