fix Studio reset, 3D base colour and arrow-trigger defects

The tracker reset was decided by which panel was on screen rather than by the
session, the automatic colour range moved the 3D surface's base colour on the first
press, and the 2D canvas and the 3D overlay applied different flow thresholds (622
arrows against 432 on a real recording). ui_check 600/0; apps/studio 380 items and
shared 390 items with no failures; real-GL 18 items, only the pre-existing
colour-scale failure; AutoCal 358 passed; both views now select identical arrows on
all 42 frames of a real video.
This commit is contained in:
ykcheungab
2026-10-01 14:40:33 +08:00
parent 33a3d8c9c2
commit e0156a14c6
14 changed files with 446 additions and 72 deletions
@@ -266,6 +266,85 @@ def test_the_rest_frame_is_drawn_neutral_not_as_measurement_zero(gl_widget, qt_a
widget.set_settings(DisplaySettings(housing_visible=True))
def _plate_mode_rgb(pixels: np.ndarray) -> np.ndarray:
"""The most common colour of the drawn surface: its *base* colour.
The resting area is the largest uniform region of a depth picture, so the modal
colour is the colour the ramp gives "no response" — the thing that must not move
when the operator presses.
"""
drawn = _drawn(pixels)
assert drawn.size, "nothing was drawn"
quantised = (drawn // 4) * 4
values, counts = np.unique(quantised, axis=0, return_counts=True)
return values[int(np.argmax(counts))].astype(float)
def test_a_press_does_not_move_the_surfaces_base_colour(gl_widget, qt_app):
"""The base colour follows the field, not the frame's current response.
Reported as "the base color of 3d depth view will change upon pressing". Measured
before the fix on a real recording, with the automatic colour scale: the resting
plate was drawn RGB [248, 0, 240] (the middle of the ramp, because a flat field was
centred on its own midpoint) and the first press moved it to [8, 24, 48] (the first
colour), where it stayed after the release. The automatic range is now anchored at
the field's own zero, so the base colour is the ramp's first colour throughout and
only the upper bound follows the press.
"""
widget, renderer, _ = gl_widget
from orisys_studio.scene3d.gl_backend import lut_rgba
assets = synthetic.poc_scene()
descriptor = FieldDescriptor("depth_response", "1", "approximate", False)
automatic = DisplaySettings(
housing_visible=False,
color_scale=ColorScale(
descriptor=descriptor,
lower=0.0,
upper=1.0,
lut_id="sequential",
mode="automatic",
),
)
widget.set_settings(automatic)
rest = np.zeros(assets.shape_hw, dtype=np.float32)
widget.present(_frame(assets, rest, frame_id=21))
rest_base = _plate_mode_rgb(_render(widget, qt_app))
rest_range = renderer._scalar_range
# A press on one cell of the 3x3 PoC plate: the rest of the plate is still "no
# response", so the modal colour is still the base colour.
pressed = rest.copy()
pressed[1, 1] = 1.0
widget.present(_frame(assets, pressed, frame_id=22))
pressed_base = _plate_mode_rgb(_render(widget, qt_app))
table = lut_rgba("sequential")[:, 0, :3].astype(float)
first_colour = table[0]
assert np.abs(rest_base - first_colour).max() <= 6.0, (
f"the resting plate is not drawn in the ramp's first colour: {rest_base} vs "
f"{first_colour}"
)
assert np.abs(pressed_base - rest_base).max() <= 6.0, (
"pressing changed the surface's base colour: "
f"{rest_base} at rest against {pressed_base} pressed"
)
# The press still has to show: the range's upper bound follows the response.
scale = renderer._last_scale
assert scale is not None and scale[0] == 0.0, (
f"the automatic range is not anchored at the field's zero: {scale}"
)
assert (
renderer._scalar_range is not None
and rest_range is not None
and renderer._scalar_range[1] > rest_range[1]
), (
"the press did not reach the colour scale: "
f"{rest_range} at rest against {renderer._scalar_range} pressed"
)
def test_a_frame_updates_only_the_sensing_buffers(gl_widget, qt_app):
widget, renderer, _ = gl_widget
assets = synthetic.poc_scene()