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:
ykcheungab
2026-09-14 17:13:37 +08:00
parent 2226bdde68
commit 981c250559
13 changed files with 515 additions and 27 deletions
+21 -5
View File
@@ -234,21 +234,37 @@ shared 全部 **262 项**。`ui_check.py` **566 项检查 0 失败**(新增 "3
- 运行时**只**读 `.oryscene` 包;旧的 Blender 导出目录仍由 `LegacyFingerImporter`(离线工具/测试)导入,
单位与变换必须显式给出。包缺失/被拒/无 GL 时:面板一行文字说明原因,采集、记录、力曲线、标定、回放全部照常
(`ui_check` 566 项与 `test_ui_smoke.py` 全绿即为证)。
(`ui_check` 570 项与 `test_ui_smoke.py` 全绿即为证)。
- 仓库现在**带一个已编译的工程包**:`apps/studio/config/sensors/finger/scene/finger-display-1.0.0.oryscene`
(明文、未签名、即 `v1` 封套,1032 顶点;生成命令与单位依据写在 `tools/scene_assets/README.md`)。
它只是工程用包,发布时用同一工具换成签名/加密/锁定的版本即可,加载路径不变。
- `gl_profile`(`desktop33` 默认 / `gles30`)在 `QApplication` 之前生效,一进程一个;未知取值退回默认而不是
让窗口起不来。
- 3D 的显示设置(放大、色标、外壳、显示帧率)持久化在 `scene3d_display`;**色标的 descriptor 不恢复**,
永远来自当前帧,因此一个旧文件不可能把测量标成另一种量。
**明确未做(留给阶段 5 或按用户要求暂缓)**:
- **示意位移(`displacement_sensor_m`)仍未接入**:需要 SDK 的 lift 与一个已确认的空间尺度;在拿到
"这个尺度是怎么标定出来的"之前,适配器继续只着色不位移(阶段 3 的原则不变)。
- ARM 板卡适配:按用户要求暂缓;`probe_gl.py` 可在板上直接跑出报告,据此定 `gl_profile` 与
`MIN_*`/预算(阶段 5 的两平台报告)。
- `session.json` 的 `visualization3d` 能力块、包签名/AES-GCM、性能与长时报告:阶段 5。
- 3D 包尚未随仓库提供(仓库里没有 `.oryscene`):这是**有意的**,包是发布产物(阶段 5 管签名与平台锁定),
并且它必须携带只能由人声明的单位与变换。
- `session.json` 的 `visualization3d` 能力块、包签名/AES-GCM、性能与长时报告:阶段 5(已完成)。
**后续补充(同一功能,历史回放接入)**:
`VIEW_SHOWS_3D` 原先只有 `custom`/`live`。现在**回放也能打开三维面板**,但要分清两件事,
因为这是两种不同的主张:
- 录像里**没有**三维场:`raw_*.mp4` 是原始相机图像,`session.json` 里 `depth.stored=false` 是当初定的,
CSV 只有力值。所以纯回放时面板只显示**参考模型**,并写明"录像不含三维场"。
- 打开「从视频重算力值」后,重算通道本来就是把**同一个运行路径**指向录像的原始视频(手指 worker 支持文件源),
而采集线程上的三维 sink 早已注册(`_start_run`),所以面板会**自动**收到重算出来的帧。
此时面板标注"重算通道:由录像重算,非记录值"——那是"这个算法版本对这段录像会说什么",
不是当初记录到的测量值(和 `display_illustrative` 同样的思路)。
实现要点:`ThreeDCoordinator.show_rest()`(把参考模型放回屏幕并停止主张测量值)、
`ThreeDPanel.set_source_kind()`(第三个来源标签)、`app_window._shows_3d()`/`_splitter_sizes_for()`
(表格里 3D 槽是 0——二维布局的描述——面板打开时从最宽的其它面板借走 `DEFAULT_3D_PANE_WIDTH=340`)。
---