Skip to content

paraview gui will be lagging when I drag mouse to change camera with --multi-clients mode #850

@mhao1999

Description

@mhao1999

Describe the bug

paraview gui first connect to a pvserver.exe --server-port=11111 --multi-clients, and then load a local obj file, then start a trame application which will only render the read-only obj file, but when I drag mouse, paraview gui will be lagging and even hang. we need to keep refreshing the browser, the camera of trame will change per each refresh.

To Reproduce

Steps to reproduce the behavior:

  1. start pvserver.exe --server-port=11111 --multi-clients
  2. start paraview gui and connect to the server
  3. pvpython.exe --venv .pvenv trame_collabration_callback.py
  4. drag mouse on paraview gui obj model
  5. the trame will response to change camera, but immediately paraview gui is lagging.

Code

import paraview.web.venv
import logging
import asyncio
from trame.app import get_server, asynchronous
from trame.ui.vuetify3 import SinglePageLayout
from trame.widgets import paraview as pv_widgets, vuetify3
from paraview import servermanager, simple
from paraview.simple import Connect, CreateRenderView, Render
from paraview.modules.vtkRemotingServerManager import vtkSMCollaborationManager

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("trame_collab")

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

connection = Connect("localhost", 11111)
if connection is None:
    raise RuntimeError(
        "Failed to connect to pvserver. Start: pvserver --multi-clients --server-port=11111"
    )
logger.info("Connected to pvserver: %s", connection)

pxm = servermanager.ProxyManager()
if hasattr(pxm, "UpdateRPCState"):
    pxm.UpdateRPCState()

if hasattr(simple, "GetRenderViews"):
    all_views = simple.GetRenderViews()
    view = all_views[0] if all_views else None

Render(view)

session = servermanager.ActiveConnection.Session
collab_mgr = session.GetCollaborationManager() if session else None

if collab_mgr is None:
    logger.warning("CollaborationManager is not available (single client or not connected to pvserver).")
else:
    logger.info("CollaborationManager available. Multi-clients: %s", session.IsMultiClients())

CollaborationNotification = getattr(vtkSMCollaborationManager, "CollaborationNotification", 12345)
CameraChanged = getattr(vtkSMCollaborationManager, "CameraChanged", 12350)


def on_collaboration_notification(caller, event_id, *args):
    """收到协作广播时仅打日志。不调用 view_update(),以免向 pvserver 发 StillRender 导致死锁。"""
    pass
    # logger.info("CollaborationNotification received (event_id=%s). State synced via ProcessEvents; use Refresh to update image.", event_id)


def on_camera_changed(caller, event_id, *args):
    """相机变化时仅打日志。不调用 view_update(),以免 pvserver 死锁。"""
    pass
    #logger.info("CameraChanged received. Use Refresh button or resize window to update image.")


observer_tag_collab = None
observer_tag_camera = None
if collab_mgr:
    observer_tag_collab = collab_mgr.AddObserver(CollaborationNotification, on_collaboration_notification)
    observer_tag_camera = collab_mgr.AddObserver(CameraChanged, on_camera_changed)
    logger.info("Callbacks registered: CollaborationNotification, CameraChanged")

NAM = servermanager.vtkProcessModule.GetProcessModule().GetNetworkAccessManager()


def process_server_events_once():
    if servermanager.ActiveConnection and session.IsMultiClients() and session.IsNotBusy():
        NAM.ProcessEvents(100)


async def event_loop():
    while True:
        process_server_events_once()
        await asyncio.sleep(0.05)  # about 20 times per secod


@ctrl.add("on_server_ready")
def start_event_loop(**kwargs):
    if collab_mgr is not None:
        asynchronous.create_task(event_loop())
        logger.info("Server event loop started for collaboration messages.")


with SinglePageLayout(server, full_height=True) as layout:
    layout.title.set_text("Trame Collaboration (Callback)")
    with layout.toolbar:
        vuetify3.VSpacer()
        vuetify3.VTooltip(
            vuetify3.VChip(
                "update render:refresh browser",
                size="small",
                variant="tonal",
                color="primary",
            ),
            location="bottom",
        )
    with layout.content:
        with vuetify3.VContainer(fluid=True, classes="pa-0 fill-height", style="pointer-events: none;"):
            view_component = pv_widgets.VtkRemoteView(view, interactive_events=False)
            ctrl.view_update = view_component.update

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

Expected behavior

the trame application should render the obj with the same camera properties like position, rotation, etc.

Screenshots

Image

Platform:

Device:
paraview gui, pvserver, trame application all run in a windows 10 laptop.

OS:

  • [yes ] Windows

Browsers Affected:

  • [yes ] Chrome

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions