Skip to content

Commit 94c526c

Browse files
feat: Add trame remote service and client in PyVista backend (#31)
Co-authored-by: Roberto Pastor Muela <[email protected]>
1 parent 5a07486 commit 94c526c

File tree

11 files changed

+266
-4
lines changed

11 files changed

+266
-4
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
2+
# SPDX-License-Identifier: MIT
3+
#
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
23+
"""
24+
.. _ref_remote_trame_view:
25+
26+
=============================
27+
Use trame as a remote service
28+
=============================
29+
30+
This example shows how to launch a trame service and use it as a remote service.
31+
32+
First, we need to launch the trame service. We can do this by running the following code::
33+
34+
# import required libraries
35+
from ansys.tools.visualization_interface.backends.pyvista.trame_service import (
36+
TrameService,
37+
)
38+
39+
# create a trame service, in whatever port is available in your system
40+
ts = TrameService(websocket_port=8765)
41+
42+
# run the service
43+
ts.run()
44+
45+
46+
Now, we can send meshes and plotter to the trame service. We can do this by running the following code in a separate terminal::
47+
48+
# import required libraries
49+
import time
50+
51+
import pyvista as pv
52+
53+
from ansys.tools.visualization_interface.backends.pyvista.trame_remote import (
54+
send_mesh,
55+
send_pl,
56+
)
57+
58+
# create an example plotter
59+
plotter = pv.Plotter()
60+
plotter.add_mesh(pv.Cube())
61+
62+
# send some example meshes
63+
send_mesh(pv.Sphere())
64+
send_mesh(pv.Sphere(center=(3, 0, 0)))
65+
time.sleep(4)
66+
67+
# if we send a plotter, the previous meshes will be deleted.
68+
send_pl(plotter)
69+
70+
"""

pyproject.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ classifiers = [
2424
]
2525

2626
dependencies = [
27-
"pyvista >= 0.42.0",
28-
"beartype >= 0.17.0",
27+
"pyvista >= 0.42.0,<1",
28+
"beartype >= 0.17.0,<1",
29+
"websockets >= 12.0,<13",
30+
"trame >= 3.6.0,<4",
31+
"trame-vtk >= 2.8.7,<3",
32+
"trame-vuetify >= 2.4.3,<3",
2933
]
3034

3135
[project.optional-dependencies]

src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from ansys.tools.visualization_interface import USE_TRAME
3030
from ansys.tools.visualization_interface.backends._base import BaseBackend
3131
from ansys.tools.visualization_interface.backends.pyvista.pyvista_interface import PyVistaInterface
32-
from ansys.tools.visualization_interface.backends.pyvista.trame_gui import (
32+
from ansys.tools.visualization_interface.backends.pyvista.trame_local import (
3333
_HAS_TRAME,
3434
TrameVisualizer,
3535
)
@@ -280,7 +280,7 @@ def compute_edge_object_map(self) -> Dict[pv.Actor, EdgePlot]:
280280
"""Compute the mapping between plotter actors and ``EdgePlot`` objects.
281281
282282
Returns
283-
--------
283+
-------
284284
Dict[~pyvista.Actor, EdgePlot]
285285
Dictionary defining the mapping between plotter actors and ``EdgePlot`` objects.
286286
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright (C) 2024 ANSYS, Inc. and/or its affiliates.
2+
# SPDX-License-Identifier: MIT
3+
#
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
"""Module for trame websocket client functions."""
23+
import pickle
24+
25+
from beartype.typing import Union
26+
import pyvista as pv
27+
from websockets.sync.client import connect
28+
29+
30+
def send_pl(plotter: pv.Plotter, host: str = "localhost", port: int = 8765):
31+
"""Send the plotter meshes to a remote trame service.
32+
33+
Since plotter can't be pickled, we send the meshes list instead.
34+
35+
Parameters
36+
----------
37+
plotter : pv.Plotter
38+
Plotter to send.
39+
host : str, optional
40+
Websocket host to connect to, by default "localhost".
41+
port : int, optional
42+
Websocket port to connect to, by default 8765.
43+
"""
44+
with connect("ws://" + host + ":" + str(port)) as websocket:
45+
# Plotter can't be pickled, so we send the meshes list instead
46+
meshes_list_pk = pickle.dumps(plotter.meshes)
47+
websocket.send(meshes_list_pk)
48+
49+
def send_mesh(mesh: Union[pv.PolyData, pv.MultiBlock], host: str = "localhost", port: int = 8765):
50+
"""Send a mesh to a remote trame service.
51+
52+
Parameters
53+
----------
54+
mesh : Union[pv.PolyData, pv.MultiBlock]
55+
Mesh to send.
56+
host : str, optional
57+
Websocket host to connect to, by default "localhost".
58+
port : int, optional
59+
Websocket port to connect to, by default 8765.
60+
"""
61+
with connect("ws://" + host + ":" + str(port)) as websocket:
62+
mesh_pk = pickle.dumps(mesh)
63+
websocket.send(mesh_pk)

0 commit comments

Comments
 (0)