Kitware / trame-router

trame-router brings Vue Router capabilities into trame widgets and ui
MIT License
1 stars 1 forks source link

Unusually long load times with trame-router and pyvista when changing actor attributes. #6

Closed MouseAndKeyboard closed 2 months ago

MouseAndKeyboard commented 2 months ago

Hello (again),

I'll preface by saying: this might be more of a pyvista issue, but I noticed it's only happening when I use it in-conjunction with trame-router.

Please see the following demo code below as well as the output of my pip freeze.

I have two RouterViewLayouts which each render a single pyvista actor (just a colored sphere). However, on each route /path1 and path2/ I have toggle buttons which are supposed to enable/disable the visibility of the actors.

Here's what I've noticed: On /path1: The visibility toggle does not work at all or works extremely slowly. On /path2 The visibility toggle is almost instant/functions as intended.

If I swap the ordering of the RouterViewLayouts in my code, this behavior swaps too: Visibility toggling in /path2 now doesn't work and it now works for /path1

Please let me know if you have any advice

from trame.app import get_server
from trame.ui.router import RouterViewLayout
from trame.widgets import vuetify3, router

from trame_vuetify.widgets import vuetify3
from trame_vuetify.ui.vuetify3 import SinglePageLayout

import pyvista as pv
from pyvista.trame.ui import plotter_ui

pv.OFF_SCREEN = True

server = get_server(client_type="vue3")
state, ctrl = server.state, server.controller

with SinglePageLayout(server) as layout:
    with layout.content as body:
        router.RouterView()

pl_1 = pv.Plotter()
actor_1 = pl_1.add_mesh(pv.Sphere(), color="red")

with RouterViewLayout(server, "/path1") as layout:
    layout.root.style = "width: 100%; height: 100%;"

    @state.change("toggle_visibility_1")
    def toggle_visibility_1(toggle_visibility_1=True, **kwargs):
        print("toggle_visibility_1")
        actor_1.visibility = toggle_visibility_1
        # Need to update the view and the image
        ctrl.view_update()
        ctrl.view_update_image()

    view_1 = plotter_ui(pl_1)
    ctrl.view_update = view_1.update
    ctrl.view_update_image = view_1.update_image
    ctrl.reset_camera = view_1.reset_camera

    with vuetify3.VAppBar() as toolbar:
        vuetify3.VSwitch(
            v_model=("toggle_visibility_1", True),
            label="Toggle visibility 1",
            hide_details=True,
        )

pl_2 = pv.Plotter()
actor_2 = pl_2.add_mesh(pv.Sphere(), color="blue")

with RouterViewLayout(server, "/path2") as layout:
    layout.root.style = "width: 100%; height: 100%;"

    @state.change("toggle_visibility_2")
    def toggle_visibility_2(toggle_visibility_2=True, **kwargs):
        print("toggle_visibility_2")
        actor_2.visibility = toggle_visibility_2
        # Need to update the view and the image
        ctrl.view_update()
        ctrl.view_update_image()

    view_2 = plotter_ui(pl_2)
    ctrl.view_update = view_2.update
    ctrl.view_update_image = view_2.update_image
    ctrl.reset_camera = view_2.reset_camera

    with vuetify3.VAppBar() as toolbar:
        vuetify3.VSwitch(
            v_model=("toggle_visibility_2", True),
            label="Toggle visibility 2",
            hide_details=True,
        )

if __name__ == "__main__":
    server.start()

Pip freeze:

aiohappyeyeballs==2.4.0
aiohttp==3.10.5
aiosignal==1.3.1
attrs==24.2.0
certifi==2024.8.30
charset-normalizer==3.3.2
contourpy==1.3.0
cycler==0.12.1
fonttools==4.53.1
frozenlist==1.4.1
idna==3.10
kiwisolver==1.4.7
matplotlib==3.9.2
more-itertools==10.5.0
msgpack==1.1.0
multidict==6.1.0
numpy==2.1.1
packaging==24.1
pillow==10.4.0
platformdirs==4.3.6
pooch==1.8.2
pyparsing==3.1.4
python-dateutil==2.9.0.post0
pyvista==0.44.1
requests==2.32.3
scooby==0.10.0
six==1.16.0
trame==3.6.5
trame-client==3.2.5
trame-router==2.3.0
trame-server==3.2.0
trame-vtk==2.8.10
trame-vuetify==2.7.1
typing_extensions==4.12.2
urllib3==2.2.3
vtk==9.3.1
wslink==2.2.1
yarl==1.11.1
jourdain commented 2 months ago

By setting ctrl.view_update twice, you endup calling the last registered one every single time regardless of which view is displayed. You can use another name or add to it instead of overriding it.