geopro/docs/superpowers/specs/2026-06-18-vtk-3d-volume-sl...

117 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 设计:三维体/切片 数据详情(只读属性对话框)
> 日期 2026-06-18。分支 `feat/vtk-3d-view`。收尾/打磨项 #6见 `docs/superpowers/HANDOFF-vtk-3d.md` §4 末「下一步候选」)。
> 异常详情已用对话框做掉(`AnomalyPropertiesDialog`),本设计为**三维体 / 切片**补同类只读详情。
## 1. 目标与范围
三维分析栏右键「数据详情」时,弹出只读属性对话框展示该三维体 / 切片的元数据与统计。
- **形态**:只读 `QDialog`(仿 `AnomalyPropertiesDialog`),非停靠面板页签。
- 取舍理由:现成 `DatasetDetailController/Panel` 绑定 2D 的 `IAsyncDatasetRepository` + chartRegistry而体/切片数据在 `Api3dRepository`(独立 3D 仓储),硬接需跨仓储桥接 + 新策略/视图,代价大、动共享设施风险高。对话框与刚落地的异常详情 UX 一致、零侵入 2D 管线。
- **内容范围**:参数/位姿随时可取;三维体统计(值域/测点数/范围体被生成loadVolume 缓存)后才显示,未生成显「—(生成/渲染后可见)」。
## 2. 架构与新增文件
仿 `src/app/AnomalyPropertiesDialog.{hpp,cpp}``QFormLayout` + `QLabel` 只读表:
| 文件 | 职责 |
|------|------|
| `src/app/VolumePropertiesDialog.{hpp,cpp}` | 三维体属性(参数 + 统计) |
| `src/app/SlicePropertiesDialog.{hpp,cpp}` | 切片属性(位姿 + 参数) |
两个对话框各自独立、构造即填充、`exec()` 模态,无网络、无加载态。
## 3. 数据获取
只改具体类 `src/data/api/Api3dRepository.{hpp,cpp}`**接口 `I3dSceneRepository``LocalSample3dRepository` 不动**`main.cpp` 持有具体 `scene3dRepo`,见 main.cpp:266全程直接用
### 3.1 三维体 getter新增
```cpp
// Api3dRepository.hpp 内嵌结构 + 方法
struct VolumeInfo {
VolumeBuildParams params;
std::string name;
bool loaded = false; // cachedGrid 是否已就绪(= loadVolume 跑过)
// 以下仅 loaded 时有效:
double vmin = 0.0, vmax = 0.0; // 来自 cachedGrid
int nx = 0, ny = 0, nz = 0; // 网格维度
double dx = 0, dy = 0, dz = 0; // 单元间距(来自 cachedGrid.spacing
std::size_t pointCount = 0; // 聚合后参与插值的散点数
};
bool volumeInfo(const std::string& dsId, VolumeInfo& out) const; // 非体返回 false
```
- `loaded``StoredVolume::cachedGrid.has_value()`;统计字段从 `cachedGrid`vmin/vmax、`vol.nx()/ny()/nz()`、`spacing`)填。
- **测点数持久化**`StoredVolume` 增 `std::optional<std::size_t> pointCount`,在 `finalizeVolume`(散点聚合完成处)写入 `pts.v.size()`。`volumeInfo` 透出。
### 3.2 切片数据
复用已有 `bool sliceSpec(const std::string& dsId, SliceSpec& out) const`main.cpp 已在用)取位姿;名称用 `detailRequested` 信号已携带的 `name`,不新增 getter。
## 4. 触发与接线(`main.cpp`
`detailRequested` 仅来自三维分析栏(`Column3DAnalysis`,项非体即切片;右键菜单「数据详情」已接,无需改 Column3DAnalysis现连接 `detailCtrl.openDataset`(对 3D dsId 会降级失败)。改为按 ddCode 分派:
```cpp
QObject::connect(ca, &Column3DAnalysis::detailRequested, &window,
[&window, scene3dRepo](const QString& dsId, const QString& ddCode, const QString& name) {
if (ddCode == QStringLiteral("dd_slice")) {
I3dSceneRepository::SliceSpec sp;
if (scene3dRepo->sliceSpec(dsId.toStdString(), sp)) {
SlicePropertiesDialog dlg(name, sp, &window); dlg.exec();
}
} else { // dd_voxel
Api3dRepository::VolumeInfo info;
if (scene3dRepo->volumeInfo(dsId.toStdString(), info)) {
VolumePropertiesDialog dlg(name, info, &window); dlg.exec();
}
}
});
```
`src/app/CMakeLists.txt` 加两个新 `.cpp`
## 5. 内容字段
### 三维体(`VolumePropertiesDialog`
- 名称
- 源数据集(`sourceDatasetIds`,逗号连接)
- 插值模型IDW / Kriging+ 幂指数IDW 时显 `power`
- 网格间距(`XY=cellXY m Z=cellZ m`
- 超距(`maxDist m`
- 色阶来源(`colorScaleId`,空显「首个源数据集」)
- **统计**loaded 才有,否则全显「—(生成/渲染后可见)」):
- 值域(`vmin ~ vmax`
- 网格(`nx × ny × nz`
- 测点数(`pointCount`
- 范围(`nx·dx × ny·dy × nz·dz` 米)
### 切片(`SlicePropertiesDialog`
- 名称
- 所属三维体(`volumeDsId`
- 轴向0 上下 / 1 前后 / 2 左右 / 3 任意)
- 平面三点 Origin / Point1 / Point2`(x, y, z)`2 位小数)
- 色阶来源(`colorScaleId`,空显「首个源数据集」)
> 切片**不含统计项**:采样分辨率/值域来自渲染时的切面网格,仓储层不持久化(`StoredSlice` 仅存 `spec`+`name`)。回写渲染产物属额外 plumbing守 YAGNI 不做。位姿/参数已完整。
## 6. 错误处理
- `volumeInfo` / `sliceSpec` 取不到(非体/非切片)→ 返回 false不弹空对话框理论不发生触发来自该行
- 统计未就绪 → 占位「—(生成/渲染后可见)」,不报错。
## 7. 测试
- 新增 gtest`tests/` 内 Api3dRepository 测套,若无则新建)覆盖 `volumeInfo`
- `createVolume` 后、`loadVolume` 前:`volumeInfo` 返回 true、`params`/`name` 正确、`loaded=false`、`pointCount=0`。
- `loadVolume` 成功后:`loaded=true`、`vmin<vmax`、`nx/ny/nz>0`、`pointCount>0`。
- 非体 dsId返回 false。
- 对话框为纯只读 UI无逻辑分支不做单测靠 GUI 实测Claude 无法 GUI 验证,交用户)。
## 8. 影响面 / 不变量
- 接口 `I3dSceneRepository``LocalSample3dRepository` 零改动 → 真实后端就绪后切换不受影响。
- `finalizeVolume` 仅多写一个 `pointCount`,不改插值/渲染行为。
- 不与 VTK 三维视图交互(详情只读查阅,职责清晰)。