feat(studio-3d): 历史回放里的三维面板 —— 由「重算」通道喂它,并标注来源
- What: `VIEW_SHOWS_3D` 加入 `replay`;`app_window` 新增 `_shows_3d()`(可见性与布局共用一个判据) 与 `_splitter_sizes_for()`(预设表里的 3D 槽是"二维布局"的描述,面板打开时从最宽的面板借 `DEFAULT_3D_PANE_WIDTH=340`);`ThreeDPanel` 新增第三个来源标签(实时采集 / 回放:录像不含三维场 / 重算通道:由录像重算,非记录值)与 `set_source_kind()`;`ThreeDCoordinator.show_rest()` 把参考模型 放回屏幕并停止主张测量值(重算停止时调用,否则最后一帧会留在屏幕上);`Mesh3dPanel` 转发这两者, 并新增"加载中"状态的修正:切换传感器再切回来时若该包已加载,直接显示已就绪的画面而不是一条永远 不会被替换的"正在加载"。 - Why: 录像里没有三维场(raw_*.mp4 是原始相机图像,`depth.stored=false`,CSV 只有力值),所以纯回放只能 显示参考模型;但「从视频重算力值」本来就把同一个运行路径指向录像的原始视频,而采集线程上的三维 sink 早已注册——因此重算一开始面板就会收到真实的形变帧。这两件事必须由界面区分:一个是"没有测量", 一个是"当前算法对这段录像会说什么",把后者当成记录值展示就是另一种 `display_illustrative`。 - Verification: apps/studio 全量通过(test_scene3d_view.py 32 项,含"回放里面板可见且标注正确""重算时 标注切换""停止重算后清回参考模型""实时视图标为实时";test_scene3d_coordinator.py 15 项,含 show_rest 与"停止时在飞的帧不会随后被显示");ui_check 570 项 0 失败(新增"已安装包必须被加载并标注来源"); locale_check 0 缺失;仓库内工程包经 validate_scene 全部 ok。 - Not in this change: 逐帧保存展开场/深度(记录格式变更,设计文档明确否掉);重算通道本身(已存在,本次 只是把它的帧接到面板上);示意位移(仍需 SDK lift + 已确认尺度)。
This commit is contained in:
@@ -2830,23 +2830,67 @@ def main() -> int:
|
||||
pane.set_sensor("box")
|
||||
check(pane.showing_message, "the 3D pane kept showing a picture for a box sensor")
|
||||
|
||||
# A finger with no package names where the package belongs and how to build one.
|
||||
# A finger *without* any package names where one belongs and how to build it.
|
||||
# The search is stubbed for this check: the application's config directory may
|
||||
# or may not carry a compiled package on the machine running the check, and a
|
||||
# check that only passes without one would fail the first time one is
|
||||
# installed (the positive case is checked just below).
|
||||
import orisys_studio.ui.mesh3d_panel as _panel_module
|
||||
|
||||
real_find = _panel_module.find_package
|
||||
_panel_module.find_package = lambda *a, **k: None
|
||||
try:
|
||||
fresh_missing = _Mesh3dPanel()
|
||||
fresh_missing.set_sensor("finger")
|
||||
diagnostic = fresh_missing.last_diagnostic
|
||||
check(
|
||||
diagnostic is not None and diagnostic.code == "asset_rejected",
|
||||
f"a missing 3D scene was not reported as an asset problem: {diagnostic}",
|
||||
)
|
||||
if diagnostic is not None:
|
||||
check(
|
||||
"compile_scene.py" in diagnostic.details.get("compile", ""),
|
||||
"the missing-scene report does not say how to build one",
|
||||
)
|
||||
check(
|
||||
str(diagnostic.details.get("directory", ""))
|
||||
in fresh_missing.message.text()
|
||||
or fresh_missing.message.text().strip() != "",
|
||||
"the pane does not name the directory it looked in",
|
||||
)
|
||||
fresh_missing.deleteLater()
|
||||
finally:
|
||||
_panel_module.find_package = real_find
|
||||
|
||||
# And when a package *is* installed, the pane must actually load it: this is
|
||||
# the end-to-end check that the search path, the loader and the widget agree.
|
||||
pane.set_sensor("finger")
|
||||
diagnostic = pane.last_diagnostic
|
||||
check(
|
||||
diagnostic is not None and diagnostic.code == "asset_rejected",
|
||||
f"a missing 3D scene was not reported as an asset problem: {diagnostic}",
|
||||
)
|
||||
if diagnostic is not None:
|
||||
shipped = _panel_module.find_package("finger")
|
||||
if shipped is not None:
|
||||
view_for_load = pane.ensure_view()
|
||||
pane.set_enabled(True)
|
||||
deadline = time.time() + 15.0
|
||||
while time.time() < deadline:
|
||||
app.processEvents()
|
||||
assets = getattr(view_for_load, "assets", None) if view_for_load else None
|
||||
if assets is not None:
|
||||
break
|
||||
time.sleep(0.02)
|
||||
check(
|
||||
"compile_scene.py" in diagnostic.details.get("compile", ""),
|
||||
"the missing-scene report does not say how to build one",
|
||||
getattr(view_for_load, "assets", None) is not None,
|
||||
f"the installed 3D scene was never loaded: {pane.last_diagnostic}",
|
||||
)
|
||||
check(
|
||||
str(diagnostic.details.get("directory", "")) in pane.message.text()
|
||||
or pane.message.text().strip(),
|
||||
"the pane does not name the directory it looked in",
|
||||
not pane.showing_message,
|
||||
"the pane is still showing a message although a scene loaded",
|
||||
)
|
||||
if view_for_load is not None and view_for_load.panel is not None:
|
||||
source_text = view_for_load.panel.source_label.text()
|
||||
check(source_text.strip() != "", "the pane does not say where the field comes from")
|
||||
check(
|
||||
"实时" in source_text or "Live" in source_text,
|
||||
f"the live view does not label its source: {source_text!r}",
|
||||
)
|
||||
|
||||
# The pane's controls must fit the width the window reserves for it.
|
||||
view = pane.ensure_view()
|
||||
|
||||
Reference in New Issue
Block a user