File size: 2,320 Bytes
16760fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
"""Best-effort smoke test of the PyVista viewer with an off-screen plotter.

Skips cleanly when no off-screen GL context is available (e.g. CI without EGL).
"""

from __future__ import annotations

import numpy as np
import pytest

pytest.importorskip("pyvista")


def test_offscreen_set_and_recolor():
    import pyvista as pv

    from toaster.viewer import PyVistaViewer

    try:
        plotter = pv.Plotter(off_screen=True)
        viewer = PyVistaViewer(plotter=plotter)
        xyz = np.random.default_rng(0).random((200, 3)).astype(np.float32)
        colors = np.zeros((200, 3), dtype=np.uint8)
        viewer.set_cloud(xyz, colors)
        viewer.update_colors(np.array([0, 1, 2]), np.array([255, 0, 0], np.uint8))
        viewer.highlight(np.array([3, 4]))
        viewer.clear_highlight()
        viewer.set_point_style(size=6, as_spheres=True)
        mask = np.ones(200, dtype=bool)
        mask[:50] = False
        viewer.set_visible_mask(mask)  # ghost-array hide
        viewer.set_visible_mask(None)  # show all
    except Exception as exc:  # pragma: no cover - depends on GL availability
        pytest.skip(f"off-screen rendering unavailable: {exc}")

    # The owned colour buffer (RGBA) was mutated in place.
    assert viewer._colors[0][:3].tolist() == [255, 0, 0]
    assert viewer.point_size == 6
    assert viewer.render_points_as_spheres is True


def test_box_to_point_restores_camera_trackball():
    """Returning to point mode after box mode must re-enable camera orbit."""
    import pyvista as pv

    from toaster.viewer import PyVistaViewer

    try:
        viewer = PyVistaViewer(plotter=pv.Plotter(off_screen=True))
        if viewer.plotter.iren is None:
            pytest.skip("no interactor available")
        viewer.set_cloud(np.zeros((10, 3), np.float32), np.zeros((10, 3), np.uint8))
        viewer.set_point_pick_callback(lambda i, m: None)
        viewer.set_box_pick_callback(lambda i, m: None)
        viewer.set_pick_mode("box")
        viewer.set_pick_mode("point")
        style = type(viewer.plotter.iren.interactor.GetInteractorStyle()).__name__
    except Exception as exc:  # pragma: no cover - depends on GL availability
        pytest.skip(f"interactor style unavailable: {exc}")

    assert "Trackball" in style, f"camera stuck on {style} after box→point"