修复 Studio 失败测试并新增合并门禁
把丢失的 box 录像放回 apps/studio/tests/data/,修掉第 3 节 3–10 号与两处过时测试桩, 注册 timing 标记并让根目录收集零错误;新增 tools/gate.ps1 与可选的 pre-push 钩子。 验证:studio 524 通过 19 跳过、shared 467 通过 18 跳过、ui_check 632 项 0 失败、gate.ps1 退出码 0。 细节见 docs/test-repair-plan.zh.md。
This commit is contained in:
@@ -403,7 +403,31 @@ class AnalysisSession:
|
||||
if self._overlay is None:
|
||||
self._overlay_failed = True
|
||||
return None
|
||||
return self._overlay.project(video_bgr, frame_id=frame_id)
|
||||
projected = self._overlay.project(video_bgr, frame_id=frame_id)
|
||||
if projected is None:
|
||||
# Sticky, as the docstring above says. A projector that cannot map this
|
||||
# result's footage — measured: every frame of a real box recording, where the
|
||||
# stitch rebuild raises inside the SDK — will not start working mid-session,
|
||||
# and retrying per cursor move would rebuild the same failing stitch on every
|
||||
# scrub. The session records the answer so a caller can pick a view this
|
||||
# result *can* draw instead of leaving a refusal on screen.
|
||||
self._overlay_failed = True
|
||||
return projected
|
||||
|
||||
@property
|
||||
def overlay_unavailable(self) -> bool:
|
||||
"""Whether this result has been asked for an overlay base and could not give one.
|
||||
|
||||
The overlay views (``arrows_stitched``, ``depth_arrows``) paint on the same
|
||||
UV-unrolled or stitched picture live publishes, which a stored result does not
|
||||
contain: it is rebuilt from the result's provenance on first use. A **box**
|
||||
result has no stored unroll map, and the box stitch rebuild can fail on real
|
||||
footage, so the answer is only known after one attempt — and it is then sticky
|
||||
for the session (see :meth:`overlay_base`). The caller that *picks* the first
|
||||
view for an adopted result reads this, so the operator is not left on a view
|
||||
that cannot be drawn.
|
||||
"""
|
||||
return bool(self._overlay_failed)
|
||||
|
||||
def close(self) -> None:
|
||||
"""Release the overlay projector; the reader is closed by :class:`ResultLibrary`."""
|
||||
|
||||
@@ -29,6 +29,7 @@ from typing import Any
|
||||
|
||||
import numpy as np
|
||||
from orisys_app_shared.acquisition.image_backend import (
|
||||
ARROW_PURE,
|
||||
ARROW_STITCHED,
|
||||
DERIVED_MODES,
|
||||
RESULT_FAILED,
|
||||
@@ -1032,14 +1033,29 @@ class ReplayController(QObject):
|
||||
The first processed view is arrows over the unrolled / stitched base: the same
|
||||
texture live uses. A derived selection the operator already chose is left
|
||||
alone — that mode is not this method's to override.
|
||||
|
||||
**But only a view this result can actually draw.** The base is rebuilt from the
|
||||
result's provenance, which a box result cannot always do (no stored unroll map,
|
||||
and the box stitch rebuild can fail on real footage: measured, every frame of the
|
||||
restored 33-frame box recording). Offering the overlay there would leave the
|
||||
operator on a blank panel reading "capture unavailable" while the pure-colour
|
||||
arrows sit one step away, so the fallback is the drawable view — the overlay is
|
||||
still in the selector, and choosing it still says why it cannot be drawn.
|
||||
"""
|
||||
current = str(getattr(self._image_panel, "view_mode", lambda: "")() or "")
|
||||
if current in DERIVED_MODES:
|
||||
return False
|
||||
session = self.available_result()
|
||||
# The plan for the frame just drawn offers the derived modes (the frame carries
|
||||
# ``result_available``), so this selection is one the panel can honour.
|
||||
self._image_panel.set_view_mode(ARROW_STITCHED)
|
||||
overlay_failed = bool(getattr(session, "overlay_unavailable", False))
|
||||
self._image_panel.set_view_mode(ARROW_PURE if overlay_failed else ARROW_STITCHED)
|
||||
self.render_frame()
|
||||
if not overlay_failed and getattr(session, "overlay_unavailable", False):
|
||||
# The first attempt is what tells us: the base could not be rebuilt, so draw
|
||||
# the view that needs no base instead of leaving a refusal on screen.
|
||||
self._image_panel.set_view_mode(ARROW_PURE)
|
||||
self.render_frame()
|
||||
return True
|
||||
|
||||
def _display_policy(self) -> Any:
|
||||
|
||||
Reference in New Issue
Block a user