Skip to content

Commit 30215ea

Browse files
committed
docs(widget): update box example
1 parent 07220e4 commit 30215ea

File tree

2 files changed

+84
-32
lines changed

2 files changed

+84
-32
lines changed

examples/vtk/widgets_box.py

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
import os
21
from trame.app import get_server
32
from trame.ui.html import DivLayout
4-
from trame.widgets import html, client, vtk as vtk_widgets
3+
from trame.widgets import html, client
54
from trame_vtklocal.widgets import vtklocal
5+
from trame.decorators import TrameApp, change
66

77
# Required for vtk factory
88
import vtkmodules.vtkRenderingOpenGL2 # noqa
99
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa
1010

1111
from vtkmodules.vtkCommonColor import vtkNamedColors
1212
from vtkmodules.vtkFiltersSources import vtkConeSource
13-
from vtkmodules.vtkInteractionWidgets import vtkBoxWidget2
14-
from vtkmodules.vtkCommonTransforms import vtkTransform
13+
from vtkmodules.vtkInteractionWidgets import vtkBoxWidget2, vtkBoxRepresentation
1514
from vtkmodules.vtkRenderingCore import (
1615
vtkActor,
1716
vtkPolyDataMapper,
@@ -20,14 +19,6 @@
2019
vtkRenderer,
2120
)
2221

23-
WASM = "USE_WASM" in os.environ
24-
25-
26-
def box_callback(obj, event):
27-
t = vtkTransform()
28-
obj.representation.GetTransform(t)
29-
box_callback.actor.user_transform = t
30-
3122

3223
def create_vtk_pipeline():
3324
colors = vtkNamedColors()
@@ -40,7 +31,9 @@ def create_vtk_pipeline():
4031
coneActor = vtkActor()
4132
coneActor.SetMapper(coneMapper)
4233
coneActor.GetProperty().SetColor(colors.GetColor3d("BurlyWood"))
43-
coneMapper.Update()
34+
35+
cone.Update()
36+
input_bounds = cone.output.bounds
4437

4538
# A renderer and render window
4639
renderer = vtkRenderer()
@@ -49,58 +42,113 @@ def create_vtk_pipeline():
4942

5043
renwin = vtkRenderWindow()
5144
renwin.AddRenderer(renderer)
52-
renwin.SetWindowName("BoxWidget")
5345

5446
# An interactor
5547
interactor = vtkRenderWindowInteractor()
5648
interactor.SetRenderWindow(renwin)
5749
interactor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
5850

5951
# A Box widget
60-
boxWidget = vtkBoxWidget2()
61-
boxWidget.SetInteractor(interactor)
62-
boxWidget.representation.SetPlaceFactor(1.0)
63-
boxWidget.representation.PlaceWidget(coneActor.bounds)
52+
rep = vtkBoxRepresentation(place_factor=2)
53+
rep.PlaceWidget(input_bounds)
6454

65-
boxWidget.On()
55+
boxWidget = vtkBoxWidget2(interactor=interactor, representation=rep)
6656

67-
# Connect the event to a function
68-
if not WASM:
69-
box_callback.actor = coneActor
70-
boxWidget.AddObserver("InteractionEvent", box_callback)
57+
renderer.ResetCamera()
58+
renwin.Render()
7159

72-
return renwin, boxWidget
60+
boxWidget.On()
61+
62+
return renwin, boxWidget, coneActor
7363

7464

7565
# -----------------------------------------------------------------------------
7666
# GUI
7767
# -----------------------------------------------------------------------------
7868

7969

70+
@TrameApp()
8071
class App:
8172
def __init__(self, server=None):
8273
self.server = get_server(server, client_type="vue3")
8374

8475
# enable shared array buffer
8576
self.server.http_headers.shared_array_buffer = True
8677

87-
self.render_window, self.widget = create_vtk_pipeline()
78+
# Allocation state variable for widget state
79+
self.state.widget_state = None
80+
81+
self.render_window, self.widget, self.actor = create_vtk_pipeline()
8882
self.html_view = None
8983
self.ui = self._ui()
9084

85+
@property
86+
def state(self):
87+
return self.server.state
88+
89+
@change("widget_state")
90+
def _on_widget_update(self, widget_state, **_):
91+
if widget_state is None:
92+
return
93+
94+
print(f"{widget_state=}")
95+
96+
self.actor.user_transform.SetMatrix(widget_state.get("transform"))
97+
self.html_view.render_throttle()
98+
99+
def toggle_listeners(self):
100+
if self.state.wasm_listeners is not None and len(self.state.wasm_listeners):
101+
self.state.wasm_listeners = {}
102+
else:
103+
self.state.wasm_listeners = {
104+
self.widget_id: {
105+
"InteractionEvent": {
106+
"widget_state": {
107+
"transform": (
108+
self.widget_id,
109+
"WidgetRepresentation",
110+
"Transform",
111+
),
112+
}
113+
}
114+
}
115+
}
116+
117+
def one_time_update(self):
118+
self.html_view.eval(
119+
{
120+
"widget_state": {
121+
"transform": (
122+
self.widget_id,
123+
"WidgetRepresentation",
124+
"Transform",
125+
),
126+
}
127+
}
128+
)
129+
91130
def _ui(self):
92131
with DivLayout(self.server) as layout:
93132
client.Style("body { margin: 0; }")
133+
html.Button(
134+
"Toggle listeners",
135+
click=self.toggle_listeners,
136+
style="position: absolute; left: 1rem; top: 1rem; z-index: 10;",
137+
)
138+
html.Button(
139+
"Update cut",
140+
click=self.one_time_update,
141+
style="position: absolute; right: 1rem; top: 1rem; z-index: 10;",
142+
)
94143
with html.Div(
95144
style="position: absolute; left: 0; top: 0; width: 100vw; height: 100vh;"
96145
):
97-
if WASM:
98-
self.html_view = vtklocal.LocalView(self.render_window)
99-
self.html_view.register_widget(self.widget)
100-
else:
101-
self.html_view = vtk_widgets.VtkRemoteView(
102-
self.render_window, interactive_ratio=1
103-
)
146+
self.html_view = vtklocal.LocalView(
147+
self.render_window,
148+
throttle_rate=20,
149+
listeners=("wasm_listeners", {}),
150+
)
151+
self.widget_id = self.html_view.register_widget(self.widget)
104152

105153
return layout
106154

examples/vtk/widgets_camera.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# ---------------------------------------------------------
2+
# # NOT FINISHED - NOT EXPECTED TO WORK OR DO ANYTHING
3+
# ---------------------------------------------------------
4+
15
# import os
26
from pathlib import Path
37

0 commit comments

Comments
 (0)