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