Skip to content

Commit 76b4e31

Browse files
test: Add interaction testing
1 parent 9c63667 commit 76b4e31

File tree

2 files changed

+329
-3
lines changed

2 files changed

+329
-3
lines changed

src/ansys/tools/visualization_interface/plotter.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
# SOFTWARE.
2222

2323
"""Module for the Plotter class."""
24-
from typing import Any
24+
from typing import Any, List
2525

2626
from ansys.tools.visualization_interface.backends._base import BaseBackend
2727
from ansys.tools.visualization_interface.backends.pyvista.pyvista import PyVistaBackend
@@ -67,7 +67,7 @@ def show(
6767
screenshot: str = None,
6868
name_filter: bool = None,
6969
**kwargs
70-
) -> None:
70+
) -> List:
7171
"""Show the plotted objects.
7272
7373
Parameters
@@ -80,8 +80,13 @@ def show(
8080
Flag to filter the object, by default None.
8181
kwargs : dict
8282
Additional options the selected backend accepts.
83+
84+
Returns
85+
-------
86+
List
87+
List of picked objects.
8388
"""
84-
self._backend.show(
89+
return self._backend.show(
8590
plottable_object=plottable_object,
8691
screenshot=screenshot,
8792
name_filter=name_filter,

tests/test_interactables.py

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
# Copyright (C) 2024 - 2025 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+
"""Test module for interactables in the picker."""
23+
from pathlib import Path
24+
25+
import pytest
26+
import pyvista as pv
27+
28+
from ansys.tools.visualization_interface import MeshObjectPlot, Plotter
29+
from ansys.tools.visualization_interface.backends.pyvista import PyVistaBackend
30+
31+
32+
class CustomObject:
33+
"""Mock object for testing picking functionality."""
34+
def __init__(self):
35+
"""Initialize the custom object."""
36+
self.name = "CustomObject"
37+
self.mesh = pv.Cube(center=(1, 1, 0))
38+
def get_mesh(self):
39+
"""Return the mesh of the custom object."""
40+
return self.mesh
41+
def name(self):
42+
"""Return the name of the custom object."""
43+
return self.name
44+
45+
def test_picking():
46+
"""Adds multiblock to the plotter."""
47+
pv_backend = PyVistaBackend(allow_picking=True, plot_picked_names=True)
48+
49+
pl = Plotter(backend=pv_backend)
50+
51+
# Create custom sphere
52+
custom_sphere = CustomObject()
53+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
54+
custom_sphere.name = "CustomSphere"
55+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
56+
57+
pl.plot(mesh_object_sphere)
58+
59+
60+
# Run the plotter and simulate a click
61+
pl.show(auto_close=False)
62+
63+
raw_plotter = pl.backend.scene
64+
width, height = raw_plotter.window_size
65+
raw_plotter.iren._mouse_right_button_press(width//2, height//2)
66+
raw_plotter.iren._mouse_right_button_release(width//2, height//2)
67+
raw_plotter.close()
68+
picked = pl.backend._picked_dict
69+
assert "CustomSphere" in picked
70+
71+
# TODO: View and displace arrows tests do not give expected results, PyVista issue?
72+
view = [
73+
(5, 220), # XYPLUS
74+
(5, 251), # XYMINUS
75+
(5, 282), # XZPLUS
76+
(5, 313), # XZMINUS
77+
(5, 344), # YZPLUS
78+
(5, 375), # YZMINUS
79+
(5, 406) # ISOMETRIC
80+
81+
]
82+
83+
@pytest.mark.parametrize("view", view)
84+
def test_view_buttons(view):
85+
"""Test view buttons."""
86+
pv_backend = PyVistaBackend()
87+
88+
pl = Plotter(backend=pv_backend)
89+
90+
# Create custom sphere
91+
custom_sphere = CustomObject()
92+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
93+
custom_sphere.name = "CustomSphere"
94+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
95+
96+
pl.plot(mesh_object_sphere)
97+
98+
99+
# Run the plotter and simulate a click
100+
pl.show(auto_close=False)
101+
102+
raw_plotter = pl.backend.scene
103+
width, height = raw_plotter.window_size
104+
105+
raw_plotter.iren._mouse_left_button_press(view)
106+
raw_plotter.iren._mouse_left_button_release(view)
107+
raw_plotter.close()
108+
109+
displace_arrow = [
110+
(5, 170), # XUP
111+
(5, 130), # XDOWN
112+
(35, 170), # YUP
113+
(35, 130), # YDOWN
114+
(65, 170), # ZUP
115+
(65, 130) # ZDOWN
116+
]
117+
118+
@pytest.mark.parametrize("displace_arrow", displace_arrow)
119+
def test_displace_arrow(displace_arrow):
120+
"""Test view buttons."""
121+
pv_backend = PyVistaBackend()
122+
123+
pl = Plotter(backend=pv_backend)
124+
125+
# Create custom sphere
126+
custom_sphere = CustomObject()
127+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
128+
custom_sphere.name = "CustomSphere"
129+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
130+
131+
pl.plot(mesh_object_sphere)
132+
133+
# Run the plotter and simulate a click
134+
pl.show(auto_close=False)
135+
136+
raw_plotter = pl.backend.scene
137+
width, height = raw_plotter.window_size
138+
139+
raw_plotter.iren._mouse_left_button_click(displace_arrow)
140+
raw_plotter.close()
141+
142+
143+
def test_ruler_button():
144+
"""Test ruler button interaction."""
145+
pv_backend = PyVistaBackend()
146+
147+
pl = Plotter(backend=pv_backend)
148+
149+
# Create custom sphere
150+
custom_sphere = CustomObject()
151+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
152+
custom_sphere.name = "CustomSphere"
153+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
154+
155+
pl.plot(mesh_object_sphere)
156+
157+
# Run the plotter and simulate a click
158+
pl.show(auto_close=False)
159+
160+
raw_plotter = pl.backend.scene
161+
width, height = raw_plotter.window_size
162+
163+
raw_plotter.iren._mouse_left_button_click(10, 100)
164+
raw_plotter.close()
165+
166+
167+
def test_measure_tool():
168+
"""Test measure tool interaction."""
169+
pv_backend = PyVistaBackend()
170+
171+
pl = Plotter(backend=pv_backend)
172+
173+
# Create custom sphere
174+
custom_sphere = CustomObject()
175+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
176+
custom_sphere.name = "CustomSphere"
177+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
178+
179+
pl.plot(mesh_object_sphere)
180+
181+
# Run the plotter and simulate a click
182+
pl.show(auto_close=False)
183+
184+
raw_plotter = pl.backend.scene
185+
width, height = raw_plotter.window_size
186+
187+
raw_plotter.iren._mouse_left_button_click(10, 60)
188+
raw_plotter.iren._mouse_left_button_click(200, 200)
189+
raw_plotter.iren._mouse_left_button_click(300, 300)
190+
raw_plotter.close()
191+
192+
193+
def test_measure_tool_close():
194+
"""Test measure tool interaction and closing."""
195+
pv_backend = PyVistaBackend()
196+
197+
pl = Plotter(backend=pv_backend)
198+
199+
# Create custom sphere
200+
custom_sphere = CustomObject()
201+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
202+
custom_sphere.name = "CustomSphere"
203+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
204+
205+
pl.plot(mesh_object_sphere)
206+
207+
# Run the plotter and simulate a click
208+
pl.show(auto_close=False)
209+
210+
raw_plotter = pl.backend.scene
211+
width, height = raw_plotter.window_size
212+
213+
raw_plotter.iren._mouse_left_button_click(10, 60)
214+
raw_plotter.iren._mouse_left_button_click(200, 200)
215+
raw_plotter.iren._mouse_left_button_click(300, 300)
216+
raw_plotter.iren._mouse_left_button_click(10, 60)
217+
218+
raw_plotter.close()
219+
220+
221+
def test_screenshot_button():
222+
"""Test screenshot button interaction."""
223+
pv_backend = PyVistaBackend()
224+
225+
pl = Plotter(backend=pv_backend)
226+
227+
# Create custom sphere
228+
custom_sphere = CustomObject()
229+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
230+
custom_sphere.name = "CustomSphere"
231+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
232+
233+
pl.plot(mesh_object_sphere)
234+
235+
# Run the plotter and simulate a click
236+
pl.show(auto_close=False)
237+
238+
raw_plotter = pl.backend.scene
239+
width, height = raw_plotter.window_size
240+
241+
raw_plotter.iren._mouse_left_button_click(45, 100)
242+
243+
raw_plotter.close()
244+
assert Path("screenshot.png").exists()
245+
Path("screenshot.png").unlink()
246+
assert not Path("screenshot.png").exists()
247+
248+
249+
def test_hide_button():
250+
"""Test hide button interaction."""
251+
pv_backend = PyVistaBackend()
252+
253+
pl = Plotter(backend=pv_backend)
254+
255+
# Create custom sphere
256+
custom_sphere = CustomObject()
257+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
258+
custom_sphere.name = "CustomSphere"
259+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
260+
261+
pl.plot(mesh_object_sphere)
262+
263+
# Run the plotter and simulate a click
264+
pl.show(auto_close=False)
265+
266+
raw_plotter = pl.backend.scene
267+
width, height = raw_plotter.window_size
268+
269+
raw_plotter.iren._mouse_left_button_click(10, 10)
270+
271+
raw_plotter.close()
272+
273+
274+
def test_hide_button_unclick():
275+
"""Test hide button interaction."""
276+
pv_backend = PyVistaBackend()
277+
278+
pl = Plotter(backend=pv_backend)
279+
280+
# Create custom sphere
281+
custom_sphere = CustomObject()
282+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
283+
custom_sphere.name = "CustomSphere"
284+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
285+
286+
pl.plot(mesh_object_sphere)
287+
288+
# Run the plotter and simulate a click
289+
pl.show(auto_close=False)
290+
291+
raw_plotter = pl.backend.scene
292+
width, height = raw_plotter.window_size
293+
294+
raw_plotter.iren._mouse_left_button_click(10, 10)
295+
raw_plotter.iren._mouse_left_button_click(10, 10)
296+
297+
raw_plotter.close()
298+
299+
300+
def test_slicing_tool():
301+
"""Test slicing tool interaction."""
302+
pv_backend = PyVistaBackend()
303+
304+
pl = Plotter(backend=pv_backend)
305+
306+
# Create custom sphere
307+
custom_sphere = CustomObject()
308+
custom_sphere.mesh = pv.Sphere(center=(0, 0, 5))
309+
custom_sphere.name = "CustomSphere"
310+
mesh_object_sphere = MeshObjectPlot(custom_sphere, custom_sphere.get_mesh())
311+
312+
pl.plot(mesh_object_sphere)
313+
314+
# Run the plotter and simulate a click
315+
pl.show(auto_close=False)
316+
317+
raw_plotter = pl.backend.scene
318+
width, height = raw_plotter.window_size
319+
320+
raw_plotter.iren._mouse_left_button_click(45, 60)
321+
raw_plotter.close()

0 commit comments

Comments
 (0)