From 0139b77ad4e6d62bb447f0a9c03dd12c1052be59 Mon Sep 17 00:00:00 2001 From: Corentin MUNOZ Date: Wed, 19 Feb 2025 15:06:45 +0100 Subject: [PATCH 1/3] feat: add WebXR Helper widget --- src/trame_vtk/widgets/vtk/__init__.py | 2 + src/trame_vtk/widgets/vtk/common.py | 58 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/trame_vtk/widgets/vtk/__init__.py b/src/trame_vtk/widgets/vtk/__init__.py index b4ebc18..64ea421 100644 --- a/src/trame_vtk/widgets/vtk/__init__.py +++ b/src/trame_vtk/widgets/vtk/__init__.py @@ -14,6 +14,7 @@ VtkPolyData, VtkReader, VtkShareDataset, + VtkWebXRHelper, ) __all__ = [ @@ -32,4 +33,5 @@ "VtkPolyData", "VtkReader", "VtkShareDataset", + "VtkWebXRHelper", ] diff --git a/src/trame_vtk/widgets/vtk/common.py b/src/trame_vtk/widgets/vtk/common.py index fabc5ac..1699e4c 100644 --- a/src/trame_vtk/widgets/vtk/common.py +++ b/src/trame_vtk/widgets/vtk/common.py @@ -1,6 +1,7 @@ import io import json import zipfile +from enum import IntEnum from trame_client.widgets.core import AbstractElement @@ -1130,3 +1131,60 @@ def set_camera(self, camera): @property def ref_name(self): return self._ref + + +class VtkWebXRHelper(HtmlElement): + """ + The VtkWebXRHelper component provides an easy way to add WebXR support to + a VtkView or a VtkLocalView. Just add this widget in a VtkView or + VtkLocalView widget and start an XR session with `start_xr()`. + This widget will fire the `enterXR` and `exitXR` events when an XR session + is effectively entered and exited. + + >>> webxr_helper = vtk.VtkWebXRHelper( + ... ref=..., # Identifier for this component + ... draw_controllers_ray=True, # Enable XR controllers rays + ... ) + """ + + _next_id = 0 + + class XrSessionTypes(IntEnum): + """ + WebXR Session Types supported by vtk.js + """ + + HmdVR = 0 + MobileAR = 1 + LookingGlassVR = 2 + HmdAR = 3 + + def __init__(self, ref=None, **kwargs): + super().__init__( + "vtk-webXR-helper", + **kwargs, + ) + + if ref is None: + VtkWebXRHelper._next_id += 1 + ref = f"trame__webxr_helper_{VtkWebXRHelper._next_id}" + + self.__ref = ref + self._attributes["ref"] = f'ref="{ref}"' + self._attr_names += [("draw_controllers_ray", "drawControllersRay")] + self._event_names += [ + ("enter_xr", "enterXR"), + ("exit_xr", "exitXR"), + ] + + def start_xr(self, session_type: XrSessionTypes): + """ + Start a WebXR session + """ + self.server.js_call(self.__ref, "startXR", session_type) + + def stop_xr(self): + """ + Stop the current WebXR session + """ + self.server.js_call(self.__ref, "stopXR") From 18a6bfdbc0fd68d6d9379cab380ce610a9f812a1 Mon Sep 17 00:00:00 2001 From: Corentin MUNOZ Date: Fri, 21 Feb 2025 11:31:58 +0100 Subject: [PATCH 2/3] fix(vue-vtk-js): Bump vue-vtk-js to 3.3.1 --- .externals.sha256 | 4 ++-- .fetch_externals.sh | 2 +- README.rst | 2 +- tests/refs/test_rendering_lut/ref3.png | Bin 0 -> 54488 bytes 4 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 tests/refs/test_rendering_lut/ref3.png diff --git a/.externals.sha256 b/.externals.sha256 index a5e4b9d..530f1e7 100644 --- a/.externals.sha256 +++ b/.externals.sha256 @@ -1,2 +1,2 @@ -1903a27bff9c2d7a6b3896e08c2cb19efd38b43a98f6089992d6df6719a3d187 ./src/trame_vtk/tools/static_viewer.html -42656ef471a77ba90930a3991fcf3cb2af647eb4c8eb29a434183596ed7c68da ./src/trame_vtk/modules/common/serve/trame-vtk.js +03e0b143a4fdd86fb0f3ad8ea2d25b450deaa514beb6a9a5b6574d32ede82748 ./src/trame_vtk/tools/static_viewer.html +0e90343e47c368d671716df64ed93b6596cd0b70518bb76b428b1cb501c8beab ./src/trame_vtk/modules/common/serve/trame-vtk.js diff --git a/.fetch_externals.sh b/.fetch_externals.sh index 293d5e5..1dd5286 100755 --- a/.fetch_externals.sh +++ b/.fetch_externals.sh @@ -3,7 +3,7 @@ set -e mkdir -p ./src/trame_vtk/modules/common/serve -curl https://unpkg.com/vue-vtk-js@3.2.2 -Lo ./src/trame_vtk/modules/common/serve/trame-vtk.js +curl https://unpkg.com/vue-vtk-js@3.3.1 -Lo ./src/trame_vtk/modules/common/serve/trame-vtk.js curl https://kitware.github.io/vtk-js/examples/OfflineLocalView/OfflineLocalView.html -Lo ./src/trame_vtk/tools/static_viewer.html if ! sha256sum --check .externals.sha256 ; then diff --git a/README.rst b/README.rst index 5255f93..fc1879a 100644 --- a/README.rst +++ b/README.rst @@ -323,4 +323,4 @@ Examples JavaScript dependency ----------------------------------------------------------- -This Python package bundle the ``vue-vtk-js@3.2.2`` JavaScript library. If you would like us to upgrade it, `please reach out `_. +This Python package bundle the ``vue-vtk-js@3.3.0`` JavaScript library. If you would like us to upgrade it, `please reach out `_. diff --git a/tests/refs/test_rendering_lut/ref3.png b/tests/refs/test_rendering_lut/ref3.png new file mode 100644 index 0000000000000000000000000000000000000000..558e7b6581aa56aa22df8aa9ad041c8b984a407d GIT binary patch literal 54488 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

r2RyzQ}&Wp{jyFb4R-Ynx_2;U|5V%LUJqdYMM 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%0As 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 nF+FJc6V?=|OecgQJzHOODi*1;-L-v6I%esK z%lZ>XjWGxq)dFOBY|4aLNeeF3X=1HvRa92jYRs!{R>hSu`4Uc0ZeK?k5VU;~2`#I~ z*L8?2r`8l)YICnT6MFCI3Cg8>6%iTeZI?M$xs8vlgr9%(5^-5hWO4mi{|R0ZnM_jX zr1ke6>Ul@|wnJHkC17q5GJIic#a036-#RteKy<36FL!hm`rx{2WHzaxHbYe^HUh5) z&7)K+Nn{f_(qj!JoNuM~9cwlnr7A2Jxffv5LymiF1g?ARZz|xiwFa*mtoSfFS#feqLN+LR>Qsp>(&A7ckqGmFsg9h+HJ6EZpY8ga z$S6y#V;dSpSti5!Y~tpP1~_pY(61;ixu{Hb)}5!wRJx0*QgTA>Lk!8x6=PYWrw(X-m#AsRe)GTF z>zJ2QN_I~|2hNN{-+X2ILf5z^XQtZXWkp;K2G>^;UkHKMy!vDHK)iyPj$!hLYy)4G znhh=bk-B}u50)AK91|t!;NYr3lQok2lifE%eQ~<+Q;Xy0eoXxl)c($VEYZ#_*rVoG zMY6F=nm9wgX~VgeJ$3XOTPC$Z-X8i>KHyz&rI7-zwsa3@`$Ma($QzC?G$q+68%~q5Vfq&({Ma4t^DBbirCqq9b(yykfq1j_CZ(o?g-XK83OVA47{&6m`B0k^0V$P6$!|lR8|OfskVTGF)c7u5P_cjt z$!}GwTd~VG;m6YAd_v8)L$Gx}0ncd!=0R2x!%3V)xcq(LR<~-cj`cO?@KK1PNL9U= zr$5ztb$e=8G=P_x0e1OHG>U2DU9^<4!+MX6Kw8=51=nt?g?~!oIED3XGwyWSZ?J7x zX#H|^7TSoE`qpac=`p^nW`mo92YrWCz3#lXppnXijvvNg-7Q*xa+W-qerxVe1zcy} z8NqSc{?W@kH1^NBt$FH6^JgWhc0a{+(G}!?0jnv&)t=csp-^co6*|AJ?KiINQfv7Y zQMlHc*GAXY{8I=pZe+hVy!-C0KXP@d4i*Z)x6uxgm`OHu*79$E5AEICkE;wpQ+IzzsMF=>Yk zM}Qt>MNf#XV_7~!e9f3iUmWwF7tXVZPa~OfCs%0Ayruxz&o!pA;0FlTMtJ;+cHwyV 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

gNE3EnwVLb0 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 literal 0 HcmV?d00001 From 7adf4c573261e30f7c465d22a4593483edbdfc38 Mon Sep 17 00:00:00 2001 From: Corentin MUNOZ Date: Wed, 18 Jun 2025 10:15:58 +0200 Subject: [PATCH 3/3] docs(webxr): add webxr example --- README.rst | 1 + examples/vue3/cone-webxr.py | 111 ++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 examples/vue3/cone-webxr.py diff --git a/README.rst b/README.rst index fc1879a..91ad296 100644 --- a/README.rst +++ b/README.rst @@ -121,6 +121,7 @@ The vtkRenderWindow is only used to retrieve the scene data and parameters (colo By relying on the same vtkRenderWindow, you can easily switch from a `VtkRemoteView` to a `VtkLocalView` or vice-versa. This component gives you controls on how you want to map mouse interaction with the camera. The default setting mimic default VTK interactor style so you will rarely have to override to the `interactor_settings`. +The VtkLocalView supports WebXR thanks to the `VtkWebXRHelper` component. Please refer to the examples for details on how to use it. How to use it? ``````````````````````````````````````````````````````````` diff --git a/examples/vue3/cone-webxr.py b/examples/vue3/cone-webxr.py new file mode 100644 index 0000000..a9c3334 --- /dev/null +++ b/examples/vue3/cone-webxr.py @@ -0,0 +1,111 @@ +from trame.app import get_server +from trame.widgets import vuetify3, vtk as vtk_widgets +from trame.ui.vuetify3 import SinglePageLayout + +from vtkmodules.vtkFiltersSources import vtkConeSource +from vtkmodules.vtkRenderingCore import ( + vtkRenderer, + vtkRenderWindow, + vtkRenderWindowInteractor, + vtkPolyDataMapper, + vtkActor, +) + +# VTK factory initialization +from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa +import vtkmodules.vtkRenderingOpenGL2 # noqa + +# ----------------------------------------------------------------------------- +# Trame initialization +# ----------------------------------------------------------------------------- + +server = get_server() +server.client_type = "vue3" +state, ctrl = server.state, server.controller + +state.trame__title = "VTK Local rendering" +state.xr_active = False + +DEFAULT_RESOLUTION = 6 + +# ----------------------------------------------------------------------------- +# VTK code +# ----------------------------------------------------------------------------- + +renderer = vtkRenderer() +renderer.SetBackground(0.0231, 0.4194, 0.5592) +renderWindow = vtkRenderWindow() +renderWindow.AddRenderer(renderer) +renderWindow.OffScreenRenderingOn() # Prevent popup window + +renderWindowInteractor = vtkRenderWindowInteractor() +renderWindowInteractor.SetRenderWindow(renderWindow) +renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() + +cone_source = vtkConeSource() +mapper = vtkPolyDataMapper() +actor = vtkActor() +mapper.SetInputConnection(cone_source.GetOutputPort()) +actor.SetMapper(mapper) +renderer.AddActor(actor) +renderer.ResetCamera() +renderWindow.Render() + + +@state.change("resolution") +def update_cone(resolution=DEFAULT_RESOLUTION, **kwargs): + cone_source.SetResolution(resolution) + ctrl.view_update() + + +def update_reset_resolution(): + state.resolution = DEFAULT_RESOLUTION + + +def toggle_xr(): + if state.xr_active: + ctrl.stop_xr() + else: + ctrl.start_xr(vtk_widgets.VtkWebXRHelper.XrSessionTypes.HmdVR) + + +with SinglePageLayout(server) as layout: + layout.title.set_text("WebXR Cone") + + with layout.toolbar: + vuetify3.VSpacer() + vuetify3.VSlider( + density="compact", + v_model=("resolution", DEFAULT_RESOLUTION), + min=3, + max=60, + step=1, + hide_details=True, + dense=True, + style="max-width: 300px", + ) + vuetify3.VDivider(vertical=True, classes="mx-2") + with vuetify3.VBtn(icon=True, click=toggle_xr): + vuetify3.VIcon("mdi-virtual-reality") + + with layout.content: + with vuetify3.VContainer( + fluid=True, + classes="pa-0 fill-height", + ): + with vtk_widgets.VtkLocalView(renderWindow) as view: + ctrl.view_update = view.update + + def on_enter_xr(): + state.xr_active = True + + def on_exit_xr(): + state.xr_active = False + + webxr_helper = vtk_widgets.VtkWebXRHelper( + draw_controllers_ray=True, enter_xr=on_enter_xr, exit_xr=on_exit_xr + ) + ctrl.start_xr = webxr_helper.start_xr + ctrl.stop_xr = webxr_helper.stop_xr + +server.start()