docs(spec): VTK 3D spec v2(纳入评审+web实地分析) + P1复活渲染计划
- spec v2: 纳入架构评审硬伤修正(Scene加vtkProp入口/接口异步/任意切片钉死vtkImageReslice/去裸数组出参) - 新增§1.5 web实地分析: web 3D=ThreeTile(Three.js)地球+多瓦片源;3D结果=2D反演剖面成帘面 - 关闭开放问题: 三栏=客户端新设计(web无三栏)/异常=切片面2D多边形/底图多源已确证 - 新增 P1 计划: VtkSceneController + I3dSceneRepository(LocalSample异步) + Scene加vtkProp, TDD分6步
This commit is contained in:
parent
faee28c007
commit
918088e67a
|
|
@ -0,0 +1,73 @@
|
||||||
|
# P1:复活中央 VTK 渲染(地基)
|
||||||
|
|
||||||
|
- 日期:2026-06-15
|
||||||
|
- 分支:`feat/vtk-3d-view`
|
||||||
|
- 上游 spec:`specs/2026-06-15-vtk-3d-supplementary-design.md`(§8 编排层、§5.2 Scene 缺口、§6 接口)
|
||||||
|
- 目标:把当前**空壳**中央 VTK 复活为数据驱动——勾选对象 → 经仓储取数据 → 调现有 actor → 渲染。复用 render 层零改 actor(除 Scene 加 `vtkProp` 入口)。这是后续所有 3D 功能的地基,**最低风险、最快见效**。
|
||||||
|
- 不在本期:三栏 UI、坐标轴、切片交互、异常体、任务面板(P2+)。本期只让"勾选→出图"重新跑通,并立起 `I3dSceneRepository` + `VtkSceneController` 两个骨架。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 成功判据(goal-driven)
|
||||||
|
|
||||||
|
1. 启动 → 勾选样本对象 → 中央 3D 视图出现帘面(`buildCurtain`),2D 模式出现俯视测线(`buildSurveyLine`)。
|
||||||
|
2. 「视图详情」浮层勾选 体素/地形 → 对应 actor 出现/消失(不再是死代码)。
|
||||||
|
3. `VtkSceneController` 的编排逻辑有单测(fake repo,断言 actor 集合),不依赖 GUI。
|
||||||
|
4. `main.cpp` 中死掉的 `rebuildCentral` lambda + 裸 `show*` 标志被 `VtkSceneController` 取代;`slicePlane` 等未用声明清理(仅清本期引入/相关的孤儿,不动无关代码)。
|
||||||
|
5. 构建通过 + 现有测试全绿 + 新测试通过。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 阶段(每步含 verify)
|
||||||
|
|
||||||
|
### Step 0 — 基线
|
||||||
|
- 跑现有测试与构建,记录绿基线。→ verify:`ctest` 全绿、`cmake --build` 通过。
|
||||||
|
|
||||||
|
### Step 1 — Scene 支持体绘制 vtkVolume(评审 HIGH,TDD)
|
||||||
|
- `src/render/Scene.hpp/.cpp`:新增 `void addViewProp(vtkProp* p)`(内部 `renderer_->AddViewProp`);`addActor` 保留(可改为转调 addViewProp)。
|
||||||
|
- 先写测试 `tests/render/test_scene.cpp`:加入一个 `vtkVolume`(或 mock prop)后 `renderer()->GetViewProps()` 计数 +1;`clear()` 后归零。
|
||||||
|
- → verify:RED→GREEN;体绘制 prop 能进场。
|
||||||
|
|
||||||
|
### Step 2 — I3dSceneRepository + LocalSample3dRepository(TDD)
|
||||||
|
- `src/data/repo/I3dSceneRepository.hpp`:**异步**接口(回调/Qt 信号范式,见 spec §6)。本期最小集:
|
||||||
|
- `DsDimension dimensionOf(const DsRow&)`(同步纯函数,§6.1 映射表)。
|
||||||
|
- `loadVolume(dsId, onOk(VolumeGrid), onErr)`(§6.2)。
|
||||||
|
- `loadTerrainPaths(onOk(demPath,imagePath), onErr)`(包 `LocalSampleRepository::demPath/imagePath`)。
|
||||||
|
- 切片/异常/任务等签名**本期只声明占位**(留 P3/P4),不实现。
|
||||||
|
- `src/data/repo/LocalSample3dRepository.*`:组合现有 `LocalSampleRepository`(`loadVoxelScatters`→`VoxelFromScatters` 出 `VolumeGrid`;DEM/影像路径直透)。同步数据包成异步壳。
|
||||||
|
- 测试 `tests/data/test_3d_repo.cpp`:`dimensionOf` 各 ddCode 映射正确;`loadVolume` 回调收到 `vol.nx()>0 && vmax>vmin`。
|
||||||
|
- → verify:RED→GREEN。
|
||||||
|
|
||||||
|
### Step 3 — VtkSceneController(TDD 编排逻辑)
|
||||||
|
- `src/controller/VtkSceneController.hpp/.cpp`(QObject):
|
||||||
|
- 输入(槽/setter):`setCheckedDatasets(QStringList)`、`setViewMode(Map2D/View3D)`、`setLayer(Curtain/Voxel/Terrain, bool)`、`setVerticalExaggeration(double)`。
|
||||||
|
- 内部:按维度/图层决定调哪些 actor builder;缓存 `VolumeGrid`/`Grid` 避免重复取数。
|
||||||
|
- 输出:`scene.clear()` → `addActor/addViewProp` → `renderWindow->Render()`。把现有 `rebuildCentralScene` 的帘面/测线逻辑并入,新增 voxel(`buildVoxelFromScatters`→`addViewProp`)、terrain(`buildTerrain`) 分支。
|
||||||
|
- 测试 `tests/controller/test_vtk_scene_controller.cpp`:注入 **fake repo + fake scene**(记录 add 的 prop 类型/数量),断言:
|
||||||
|
- 2D 模式 + 勾选 1 ds → 1 个测线 actor;
|
||||||
|
- 3D 模式 + showCurtain → 1 帘面 actor;+ showVoxel → 多 1 个 volume prop;+ showTerrain → 多 1 个 terrain actor;
|
||||||
|
- 取消勾选 → clear 后无 prop。
|
||||||
|
- → verify:RED→GREEN,编排逻辑脱离 GUI 可测。
|
||||||
|
|
||||||
|
### Step 4 — 接入 main.cpp(集成)
|
||||||
|
- 用 `VtkSceneController` 实例取代 `rebuildCentral` lambda(`main.cpp:508`)与裸 `show*` 标志(246–251)。
|
||||||
|
- 接线:`ObjectTreePanel` 勾选变化 → `setCheckedDatasets`;`act2D/act3D` → `setViewMode`;`chkCurtain/chkVoxel/chkTerrain` → `setLayer`;主题切换 → 触发重渲染(控制器内重跑)。
|
||||||
|
- 清理本期产生的孤儿:未用的 `slicePlane` 声明、被取代的 lambda/标志(只清相关项,遵守 surgical changes)。`chkSlice` 暂保留禁用(P3 接)。
|
||||||
|
- → verify:构建通过;启动手测达成「成功判据 1、2」。
|
||||||
|
|
||||||
|
### Step 5 — 构建 + 运行验证
|
||||||
|
- `cmake --build` + `ctest`。
|
||||||
|
- 运行客户端,勾选样本对象,截图确认帘面/体素/地形渲染。
|
||||||
|
- → verify:成功判据 1–5 全达成。
|
||||||
|
|
||||||
|
### Step 6 — 代码审查 + 提交
|
||||||
|
- `cpp-reviewer` 审查(内存安全/RAII/分层);按需修。
|
||||||
|
- 提交:`feat(vtk): P1 复活中央渲染 — VtkSceneController + I3dSceneRepository(LocalSample) + Scene 加 vtkProp 入口`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 风险 / 注意
|
||||||
|
- **Ninja 增量不可靠**(记忆 [[build-ninja-stale-shared-header]]):改 `Field/RepoTypes` 等共享头后,若崩溃先 clean 重编、验 obj 新鲜度。
|
||||||
|
- 体绘制 `vtkVolume` 经 `addViewProp` 进场;`clear()` 须用 `RemoveAllViewProps` 覆盖 volume(确认现有 `clear()` 实现)。
|
||||||
|
- LocalSample 只合成单 GS→TM→DS,勾选粒度对齐其结构即可;真实多对象/多剖面在接 Api 实现时验证。
|
||||||
|
- 接口务必异步壳,别图省事写同步(评审 HIGH,否则 P3+ 接后端返工)。
|
||||||
|
|
@ -2,11 +2,12 @@
|
||||||
|
|
||||||
- 日期:2026-06-15
|
- 日期:2026-06-15
|
||||||
- 分支建议:`feat/vtk-3d-view`
|
- 分支建议:`feat/vtk-3d-view`
|
||||||
- 状态:**设计稿(spec)**。本轮只产出设计,实现分期另立 plan。
|
- 状态:**设计稿 v2(已纳入架构评审 + web 端实地分析)**。本轮只产出设计,实现分期另立 plan。
|
||||||
- 需求来源:`D:\Projects\GEOPRO\Geopro3.0 需求表.xlsx` →「补充需求」页签(已逐行通读,§4 全文映射);交叉参考「DD类型」页签。
|
- 需求来源:`D:\Projects\GEOPRO\Geopro3.0 需求表.xlsx` →「补充需求」页签(已逐行通读,§4 全文映射);交叉参考「DD类型」页签;原版 web 实地分析见 §1.5、记忆 [[web-3d-view-threetile]]。
|
||||||
- 关键约束(用户已拍板):
|
- 关键约束(用户已拍板):
|
||||||
1. **后端 API 尚未就绪** —— 本轮用 `LocalSampleRepository` 静态数据驱动渲染与交互,**但仓储接口必须按真实后端形态设计好**(§6),将来后端到位只换实现、不动上层。
|
1. **后端 API 尚未就绪** —— 本轮用 `LocalSampleRepository` 静态数据驱动渲染与交互,**但仓储接口必须按真实后端形态设计好**(§6),将来后端到位只换实现、不动上层。
|
||||||
2. 三维相关 ddCode(`dd_Structual3D`/`dd_Property3D`/切片/异常体/任务记录)后端、客户端**都还没做**,是净增建。
|
2. 三维相关 ddCode(`dd_Structual3D`/`dd_Property3D`/切片/异常体/任务记录)后端、客户端**都还没做**,是净增建。
|
||||||
|
3. **三栏结构 + 切片是客户端新需求**(web 端没有三栏,见 §1.5)。故这两块**以 xlsx 为规格、按 VTK 工程新设计**,不受"复刻须先实地学习"约束;而"参考 Geopro 1.0"的色阶/异常框(F26/F50)属复刻项、目前无 1.0 参考、先近似后精修。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -23,6 +24,8 @@
|
||||||
|
|
||||||
> 一句话:地基(actor 管线)稳固,缺的是「编排层 + 交互层 + 三栏 UI + 真实/样本数据接入」。
|
> 一句话:地基(actor 管线)稳固,缺的是「编排层 + 交互层 + 三栏 UI + 真实/样本数据接入」。
|
||||||
|
|
||||||
|
**评审已纳入的硬伤修正**(详见各节):① `Scene` 只能加 `vtkActor`、加不了体绘制 `vtkVolume`,"actor 零改动复活"对三维体不成立 → §5.2/§8 增 `vtkProp` 入口;② `I3dSceneRepository` 必须**异步**(项目已 ApiChain 异步化,同步签名会让"换实现不动上层"破产)→ §6;③ 任意切片**钉死 `vtkImageReslice`**(`vtkCutter` 切体素只出交线不出着色剖面)→ §9.1;④ 接口数据结构去裸 `double[]`/出参 → §6.2/§6.3。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. 背景与问题
|
## 1. 背景与问题
|
||||||
|
|
@ -38,6 +41,19 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 1.5 原版(web)实地分析结论(Playwright + JS 逆推,2026-06-15)
|
||||||
|
|
||||||
|
实地分析 `http://tenant.geomative.cn/#/projectSpace/dataView`(详见记忆 [[web-3d-view-threetile]]):
|
||||||
|
|
||||||
|
- **渲染技术栈**:web 3D 地球是 **ThreeTile(Three.js 瓦片地球)**——DOM 无 `cesium-widget`、单 WebGL2 canvas、`__THREE__` 在;Cesium 1.107 虽加载但本页未用。⇒ 桌面用 VTK 是**另一套实现**,三栏/切片是桌面新设计,不存在"web 怎么做桌面照搬"。
|
||||||
|
- **底图多源已确证**(`threeMap` chunk):天地图/Google/Bing/高德/腾讯/ArcGIS/Mapbox/中科星图 ⇒ 坐实补充需求 C13 底图需求,桌面 VTK 需自建瓦片层。
|
||||||
|
- **3D 数据通路已确证**(网络):勾选 ERT 对象 → 批量 `dd/ert/inversion/rows/{id}`(2D 反演剖面) + `lvl/colorGradation` → 在 3D 地理空间摆成**竖直帘面**(= 桌面 `CurtainActor` 目标)。
|
||||||
|
- **3D 分析功能集已确证**(index chunk i18n `three*` 键):模型 选/移/转/缩放/恢复 + X·Y·Z 轴分散;剖切面 开/关/显/隐/平移/旋转;创建异常/异常列表;导出 dat/grd/bin/lvl。3D 模型从 URL 加载。⇒ 这些功能桌面要做,但**实现自定**(web 用 Three.js,桌面用 VTK)。
|
||||||
|
- **web 不是三栏**:web 是 左(数据筛选+对象树)/中(地球+显示隐藏地图+滑块)/右(异常列表)。补充需求的三栏(三维数据集/二维数据集/三维分析)是**桌面新结构**。
|
||||||
|
- **威立雅项目只有 2D 反演剖面(帘面),无真正三维体模型**;真三维体(`dd_Structual3D`,"地大展示")很可能在别的项目,待用户指认后再实地学习其切片/异常几何(不阻塞 P1–P3,因切片可对 LocalSample 体素开发)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2. 目标与范围
|
## 2. 目标与范围
|
||||||
|
|
||||||
### 2.1 总目标
|
### 2.1 总目标
|
||||||
|
|
@ -106,7 +122,7 @@
|
||||||
| D21,F22–G22 | 右键·三维体:上下切片 | 无 | §9 轴向切片工具(水平面)|
|
| D21,F22–G22 | 右键·三维体:上下切片 | 无 | §9 轴向切片工具(水平面)|
|
||||||
| F23 | 前后切片 | 无 | §9 轴向切片 |
|
| F23 | 前后切片 | 无 | §9 轴向切片 |
|
||||||
| F24 | 左右切片 | 无 | §9 轴向切片 |
|
| F24 | 左右切片 | 无 | §9 轴向切片 |
|
||||||
| F25 | 任意切片(初始 45°,可任意调整)| 无 | §9 任意角度切片(`vtkPlaneWidget`+`vtkCutter`)|
|
| F25 | 任意切片(初始 45°,可任意调整)| 无 | §9 任意角度切片(`vtkPlaneWidget` 控面 + **`vtkImageReslice`** 重采样着色,非 `vtkCutter`)|
|
||||||
| F26 | 色阶(参考 Geopro 1.0 优化)| 有 colorBar 解析 | 复用 `ColorScale` + 色阶编辑入口 |
|
| F26 | 色阶(参考 Geopro 1.0 优化)| 有 colorBar 解析 | 复用 `ColorScale` + 色阶编辑入口 |
|
||||||
| F27 | 显示/隐藏 | 无 | actor 可见性 |
|
| F27 | 显示/隐藏 | 无 | actor 可见性 |
|
||||||
| F28–G28 | 数据详情 → 详情栏 | 详情面板在 | §10 三维体详情类型 |
|
| F28–G28 | 数据详情 → 详情栏 | 详情面板在 | §10 三维体详情类型 |
|
||||||
|
|
@ -154,6 +170,7 @@
|
||||||
| ColorLutBuilder / ContourBands | `render/ColorLutBuilder.*` `ContourBands.*` | colorBar | LUT / 离线等值线几何 | 色阶 / 导出 |
|
| ColorLutBuilder / ContourBands | `render/ColorLutBuilder.*` `ContourBands.*` | colorBar | LUT / 离线等值线几何 | 色阶 / 导出 |
|
||||||
|
|
||||||
### 5.2 缺口(净增建)
|
### 5.2 缺口(净增建)
|
||||||
|
- **Scene 加不了体绘制**(评审 HIGH):`Scene::addActor(vtkActor*)`(`src/render/Scene.hpp`)只收 `vtkActor`,而 VoxelActor 产物 `vtkVolume` 是 `vtkProp3D`、**不是** `vtkActor`。三维体(核心需求)渲染必经此口 → P1 须给 Scene 加 `addViewProp(vtkProp*)`(或 `addVolume(vtkVolume*)`),5 行小改,但"actor 零改动复活"对三维体不成立。
|
||||||
- **坐标轴**:无 `vtkCubeAxesActor`/`vtkAxesActor`。
|
- **坐标轴**:无 `vtkCubeAxesActor`/`vtkAxesActor`。
|
||||||
- **相机预设**:`CameraPreset.cpp` 仅 `applyTop2D`/`applyFree3D`,缺前后左右上下 + Zoom In/Out。
|
- **相机预设**:`CameraPreset.cpp` 仅 `applyTop2D`/`applyFree3D`,缺前后左右上下 + Zoom In/Out。
|
||||||
- **底图**:无 VTK 瓦片底图层(README 提的 `ground/TileGroundLayer` 未实现)。
|
- **底图**:无 VTK 瓦片底图层(README 提的 `ground/TileGroundLayer` 未实现)。
|
||||||
|
|
@ -172,6 +189,8 @@
|
||||||
|
|
||||||
> 现状:`IDatasetRepository`(`src/data/repo/IDatasetRepository.hpp`)已有 2D 那套(loadGrid/Scatter/ColorScale/Anomalies)。本设计**新增并列接口 `I3dSceneRepository`**,承载三维体/切片/异常体/任务。本轮 `LocalSample3dRepository` 实现(读样本文件 + 内存态增删),将来 `Api3dRepository` 换实现。
|
> 现状:`IDatasetRepository`(`src/data/repo/IDatasetRepository.hpp`)已有 2D 那套(loadGrid/Scatter/ColorScale/Anomalies)。本设计**新增并列接口 `I3dSceneRepository`**,承载三维体/切片/异常体/任务。本轮 `LocalSample3dRepository` 实现(读样本文件 + 内存态增删),将来 `Api3dRepository` 换实现。
|
||||||
|
|
||||||
|
> **接口必须异步(评审 HIGH)**:项目已 ApiChain/`IAsyncProjectRepository` 异步化。`I3dSceneRepository` 取数方法**一律走回调/Qt 信号**(如 `void loadVolume(dsId, std::function<void(VolumeGrid)> onOk, OnErr onErr)`,或返回 `ApiChain`),LocalSample 同步数据也包成异步壳。否则将来换 Api 实现会阻塞 UI、上层全要改,"换实现不动上层"破产。下文签名为**简化示意(省略回调形参)**,落地按异步范式。
|
||||||
|
|
||||||
### 6.0 后端端点现状(已核对,非推测)
|
### 6.0 后端端点现状(已核对,非推测)
|
||||||
现有 `ApiClient` 仅:`dd/ert/{grid,inversion,measurement,trajectory}`、`dsObject` CRUD/import/detail、`exception/queryException`(**只读**)、`model/list`、`lvl/colorGradation`、`templateExport`。
|
现有 `ApiClient` 仅:`dd/ert/{grid,inversion,measurement,trajectory}`、`dsObject` CRUD/import/detail、`exception/queryException`(**只读**)、`model/list`、`lvl/colorGradation`、`templateExport`。
|
||||||
**缺**:三维体模型数据、切片 CRUD、异常**创建/保存**、任务记录。→ 本轮接口为这些预留方法签名,LocalSample 内存实现。
|
**缺**:三维体模型数据、切片 CRUD、异常**创建/保存**、任务记录。→ 本轮接口为这些预留方法签名,LocalSample 内存实现。
|
||||||
|
|
@ -197,28 +216,34 @@ struct VolumeModelMeta {
|
||||||
std::vector<std::string> sliceDsIds; // 切片数据集
|
std::vector<std::string> sliceDsIds; // 切片数据集
|
||||||
std::vector<std::string> anomalyBodyIds; // 异常体
|
std::vector<std::string> anomalyBodyIds; // 异常体
|
||||||
};
|
};
|
||||||
VolumeModelMeta loadVolumeMeta(const std::string& dsId);
|
// 规则体 + 原点/间距聚合返回(去 double& 出参,评审 MEDIUM)
|
||||||
geopro::core::ScalarVolume loadVolume(const std::string& dsId,
|
struct VolumeGrid {
|
||||||
double& ox,double& oy,double& oz,
|
geopro::core::ScalarVolume vol;
|
||||||
double& dx,double& dy,double& dz); // 规则体 + 原点/间距
|
std::array<double,3> origin; // ox,oy,oz
|
||||||
|
std::array<double,3> spacing; // dx,dy,dz
|
||||||
|
double vmin = 0, vmax = 0;
|
||||||
|
};
|
||||||
|
VolumeModelMeta loadVolumeMeta(const std::string& dsId); // 异步示意
|
||||||
|
VolumeGrid loadVolume(const std::string& dsId); // 异步示意
|
||||||
```
|
```
|
||||||
> LocalSample:用 `VoxelFromScatters` 把样本两条交叉剖面散点 IDW 成 `ScalarVolume` 当作一个三维体模型。
|
> LocalSample:用 `VoxelFromScatters` 把样本两条交叉剖面散点 IDW 成 `ScalarVolume` 当作一个三维体模型(产物即含 `vtkImageData`,切片直接复用)。
|
||||||
|
|
||||||
### 6.3 切片数据集(CRUD —— 后端缺,先内存实现)
|
### 6.3 切片数据集(CRUD —— 后端缺,先内存实现)
|
||||||
```cpp
|
```cpp
|
||||||
struct SliceSpec {
|
struct SliceSpec {
|
||||||
std::string volumeDsId; // 所属三维体
|
std::string volumeDsId; // 所属三维体
|
||||||
double origin[3]; // 切面一点
|
std::array<double,3> origin; // 切面一点(去裸数组,评审 MEDIUM)
|
||||||
double normal[3]; // 切面法向(轴向/任意)
|
std::array<double,3> normal; // 切面法向(轴向/任意)
|
||||||
std::string colorScaleId;
|
std::string colorScaleId;
|
||||||
};
|
};
|
||||||
struct SliceDataset { std::string dsId, name; SliceSpec spec; geopro::core::Grid section; };
|
struct SliceDataset { std::string dsId, name; SliceSpec spec; geopro::core::Grid section; };
|
||||||
SliceDataset extractSlice(const SliceSpec& spec); // 实时算切面(不落库)
|
// 落库 CRUD(进仓储):
|
||||||
std::string createSlice(const SliceSpec& spec, const std::string& name); // 保存为数据集→返回新 dsId
|
std::string createSlice(const SliceSpec& spec, const std::string& name); // 保存为数据集→返回新 dsId
|
||||||
void saveSlice(const std::string& dsId, const SliceSpec& spec); // 保存
|
void saveSlice(const std::string& dsId, const SliceSpec& spec); // 保存
|
||||||
void deleteSlice(const std::string& dsId);
|
void deleteSlice(const std::string& dsId);
|
||||||
// 导出:导图片/dat 由 UI 层用 vtkWindowToImageFilter / 采样写文件(不入仓储)
|
// 导出:导图片/dat 由 UI 层用 vtkWindowToImageFilter / 采样写文件(不入仓储)
|
||||||
```
|
```
|
||||||
|
> **实时切片不进仓储(评审 MEDIUM)**:交互拖切面时每帧重采样应直接走 VTK 管线(`vtkImageReslice` 挂在切片工具上,§9.1),**不**经 repository 回算 `Grid`(避免慢路径)。仓储只管"切片保存为数据集"这种持久化动作。
|
||||||
|
|
||||||
### 6.4 异常 / 异常体(树 + CRUD + 截图)
|
### 6.4 异常 / 异常体(树 + CRUD + 截图)
|
||||||
```cpp
|
```cpp
|
||||||
|
|
@ -249,16 +274,20 @@ std::vector<UsableTask> loadUsableTasks(const std::string& ddCode); //
|
||||||
|
|
||||||
## 7. UI 设计
|
## 7. UI 设计
|
||||||
|
|
||||||
### 7.1 三子列表栏
|
### 7.1 三子列表栏(客户端新设计 —— web 无三栏)
|
||||||
|
> 已确认(§1.5):web 端**没有三栏**,三栏是补充需求为桌面定义的新结构,以 xlsx 为准设计。
|
||||||
|
|
||||||
在 VTK dock 内(或左侧新 dock)放三个可切换 tab/分段:**三维数据集 / 二维数据集 / 三维分析**。每栏顶部是该栏专属工具条,下方是数据集勾选列表(按 §6.1 维度筛选当前勾选对象的 ds)。
|
在 VTK dock 内(或左侧新 dock)放三个可切换 tab/分段:**三维数据集 / 二维数据集 / 三维分析**。每栏顶部是该栏专属工具条,下方是数据集勾选列表(按 §6.1 维度筛选当前勾选对象的 ds)。
|
||||||
|
|
||||||
> 取舍建议:保留现有 `ObjectTreePanel`(左上勾选对象)作为"对象勾选源";三栏列表只在被勾选对象范围内、按维度过滤显示 ds。避免与现有左下数据集列表职责重叠 —— **左下数据集列表服务"详情查看",三栏列表服务"VTK 渲染勾选"**(两条线,需在 UI 上区分清楚,见 §13 开放问题)。
|
**职责切分(决策,不再是开放问题)**:保留现有 `ObjectTreePanel`(左上勾选对象)作为"对象勾选源";三栏列表只在被勾选对象范围内、按维度过滤显示 ds。**左下数据集列表服务"详情查看",三栏列表服务"VTK 渲染勾选"**——两条线并存。依据:web 端本身也是"对象树勾选 + 独立异常列表"的多列表结构,两条线与原版心智一致;且补充需求明确三栏服务于 VTK 渲染,与详情查看是不同动作。
|
||||||
|
|
||||||
### 7.2 三维数据集栏工具条
|
### 7.2 三维数据集栏工具条
|
||||||
坐标轴下拉(标准/立体/不显示)+ O 点 + 刻度(无/米/英尺/经纬度)+ 字体 | 水平/垂直比例(滑块/输入)| 快捷视图(前后左右上下 6 钮)| Zoom(In/Out/Fit)。
|
坐标轴下拉(标准/立体/不显示)+ O 点 + 刻度(无/米/英尺/经纬度)+ 字体 | 水平/垂直比例(滑块/输入)| 快捷视图(前后左右上下 6 钮)| Zoom(In/Out/Fit)。
|
||||||
|
|
||||||
### 7.3 二维数据集栏
|
### 7.3 二维数据集栏
|
||||||
底图下拉(天地图/Google/隐藏)+ 2D 视图位置(关闭/Z=0/顶部/底部/自定义 Z)。底图层:VTK 内用瓦片纹理贴 z=0 平面(天地图 WMTS);本轮先打通"能显示+隐藏",缓存优化后续。
|
底图下拉(天地图/Google/隐藏)+ 2D 视图位置(关闭/Z=0/顶部/底部/自定义 Z)。
|
||||||
|
|
||||||
|
**底图层(评审 HIGH:被低估,单列风险子项)**:web 用 ThreeTile 多源瓦片(§1.5 已确证:天地图/Google/Bing/高德/腾讯…)。桌面 VTK 无现成瓦片图层,需自建小型瓦片引擎:可视范围 → 瓦片行列号 → 异步拉 PNG → 贴 `vtkPlaneSource`+texture → 随相机换 LOD。**关键配准**:天地图瓦片是 EPSG:3857,须把每块瓦片范围反算到 `GeoLocalFrame` 局部米才能与帘面/体素对齐(复用 `TerrainActor` 已有的 3857→4326→frame 流程)。本轮先打通"天地图能显示+隐藏",Google/缓存/LOD 后续。**排 P5**(复杂度高、依赖天地图 token)。
|
||||||
|
|
||||||
### 7.4 三维分析栏
|
### 7.4 三维分析栏
|
||||||
树:对象 → 三维体模型数据集 → 切片。右键菜单按节点类型分派(三维体 / 切片,见 §4 行 D21–F36)。
|
树:对象 → 三维体模型数据集 → 切片。右键菜单按节点类型分派(三维体 / 切片,见 §4 行 D21–F36)。
|
||||||
|
|
@ -283,9 +312,9 @@ class VtkSceneController : public QObject {
|
||||||
## 9. 交互层 `src/render/interact/`(新目录,最重模块)
|
## 9. 交互层 `src/render/interact/`(新目录,最重模块)
|
||||||
|
|
||||||
### 9.1 切片工具
|
### 9.1 切片工具
|
||||||
- **轴向切片**(上下/前后/左右):`vtkImagePlaneWidget` 贴体素 `vtkImageData`(VoxelActor 已能导出 image),沿固定轴向,角度不可调(符合 G22–G24)。
|
- **轴向切片**(上下/前后/左右):`vtkImagePlaneWidget` 贴体素 `vtkImageData`(VoxelActor 已能导出 image),沿固定轴向、自动重采样着色,角度不可调(符合 G22–G24)。
|
||||||
- **任意切片**(F25):`vtkPlaneWidget` + `vtkCutter`/`vtkImageReslice`,初始 45°,可任意旋转。
|
- **任意切片**(F25):`vtkPlaneWidget`(控制面位姿)+ **`vtkImageReslice`**(按斜面对体素重采样出着色剖面),初始 45°,可任意旋转。**不用 `vtkCutter`**(评审 HIGH:cutter 切 `vtkImageData` 只产几何交线/多边形,得不到带标量的连续剖面图)。
|
||||||
- 统一抽象 `SliceTool`:持 `vtkPlane`,产出切面 `Grid`(喂 GridContourActor 着色)。
|
- 统一抽象 `SliceTool`:持切面位姿 + `vtkImageReslice`,直接产出贴 `vtkImageActor` 的着色剖面(避免回算 `core::Grid` 的绕路;仅"保存为数据集"时才转 Grid 落库)。
|
||||||
|
|
||||||
### 9.2 滚轮切片(D46)
|
### 9.2 滚轮切片(D46)
|
||||||
选中切片 → 自定义 InteractorStyle 截 `OnMouseWheel` → 沿切面法向平移 origin → 重算切面。
|
选中切片 → 自定义 InteractorStyle 截 `OnMouseWheel` → 沿切面法向平移 origin → 重算切面。
|
||||||
|
|
@ -299,6 +328,8 @@ class VtkSceneController : public QObject {
|
||||||
### 9.4 异常圈定工具(D48/E49/F49–F50)
|
### 9.4 异常圈定工具(D48/E49/F49–F50)
|
||||||
自定义 widget:光标拾取起点 → 连续描点成多边形(复用 `core::Anomaly` Polygon)→ 结束弹保存对话框(截图大小 / 异常坐标,参考 Geopro 1.0)→ `saveAnomaly(a, screenshot)`。截图用 `vtkWindowToImageFilter`。
|
自定义 widget:光标拾取起点 → 连续描点成多边形(复用 `core::Anomaly` Polygon)→ 结束弹保存对话框(截图大小 / 异常坐标,参考 Geopro 1.0)→ `saveAnomaly(a, screenshot)`。截图用 `vtkWindowToImageFilter`。
|
||||||
|
|
||||||
|
> **异常几何 = 切片面上的多边形(决策,不再是开放问题)**:需求 F49"以光标拾取点为起点圈异常"+ web 同款(在切片上描点),即异常是**画在切片平面上的多边形**——本质 2D-in-3D,把多边形顶点存为切面局部坐标 + 切面位姿即可在 3D 中定位。**不需要真三维体几何**。故 `core::Anomaly`(2D 多边形) 复用成立,§6.4 `AnomalyBody.members` 用 `core::Anomaly` + 所属切面引用即可。截图属性(B88)即圈定时的视图截图。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. 详情视图
|
## 10. 详情视图
|
||||||
|
|
@ -331,14 +362,20 @@ class VtkSceneController : public QObject {
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 13. 开放问题 / 待确认(写计划前需定)
|
## 13. 开放问题 / 待确认
|
||||||
|
|
||||||
1. **三栏列表 vs 现有左下数据集列表的职责边界**:是新增三栏(渲染勾选用)与左下(详情用)并存,还是合并改造?影响 UI 重构面。(§7.1 给了建议:并存,两条线)
|
### 已决(评审 + 实地分析后关闭)
|
||||||
2. **坐标系单位**:刻度"经纬度"用 `GeoLocalFrame` 反算到 lat/lon;"米/英尺"基于世界系米。O 点默认取世界原点还是数据包围盒?
|
- ✅ **三栏 vs 左下列表**:两条线并存(三栏=渲染勾选、左下=详情查看),web 本身即多列表结构(§7.1)。
|
||||||
3. **切片"保存为数据集"的落库形态**:后端缺接口,本轮 LocalSample 内存态。是否需要持久化到本地文件以便重启可见?
|
- ✅ **异常 3D 表达**:异常 = 切片面上的 2D 多边形,复用 `core::Anomaly`,无需真三维体几何(§9.4)。
|
||||||
4. **异常 3D 表达**:现有 `Anomaly` 是 2D(剖面坐标)。三维异常体是用包围多边形拉伸,还是需要真正的 3D 体?需求 B70 树结构清晰,但 3D 几何形态需 1.0 参考。
|
- ✅ **任意切片技术**:`vtkImageReslice`,非 `vtkCutter`(§9.1)。
|
||||||
5. **"参考 Geopro 1.0"的多处**(F26 色阶 / F50 异常保存框 / F49 圈异常):是否有 1.0 可实地学习(截图/源码/在线系统)?按记忆规约(复刻须实地学习,禁猜测),实现这些前需拿到 1.0 参考。
|
- ✅ **接口异步 + 数据结构**:异步范式 + `VolumeGrid`/`std::array` 聚合(§6)。
|
||||||
6. **底图天地图 key / Google Map 可用性**:天地图需 token;Google 在国内可用性。本轮先做天地图 + 隐藏,Google 占位?
|
|
||||||
|
### 仍开放(不阻塞 P1/P2,相关期开工前定)
|
||||||
|
1. **坐标系单位 / O 点**(§7.2,P2):刻度"经纬度"用 `GeoLocalFrame` 反算;"米/英尺"基于世界米。O 点默认世界原点还是数据包围盒角?→ P2 开工前定,倾向"数据包围盒角"。
|
||||||
|
2. **切片"保存为数据集"落库形态**(§6.3,P3):本轮 LocalSample 内存态;是否持久化到本地文件以便重启可见?
|
||||||
|
3. **真三维体项目**(§1.5,P3/P4):威立雅无真三维体;需用户指认有 `dd_Structual3D` 的项目,实地学习其切片/异常几何与交互细节。**不阻塞 P3**(切片对 LocalSample 体素先开发)。
|
||||||
|
4. **"参考 Geopro 1.0"**(F26 色阶 / F50 异常保存框,P4):目前无 1.0 参考 → 先用现有 colorBar 解析 + 标准保存框近似,拿到 1.0 后精修。
|
||||||
|
5. **底图 token / Google 可用性**(§7.3,P5):天地图需 token;Google 国内可用性。本轮先天地图 + 隐藏。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -350,4 +387,6 @@ class VtkSceneController : public QObject {
|
||||||
4. **P4 异常体 + 圈异常 + 详情 + 任务**:异常圈定工具 + 异常体树管理 + 三维体详情 + 任务面板(依赖 1.0 参考)。
|
4. **P4 异常体 + 圈异常 + 详情 + 任务**:异常圈定工具 + 异常体树管理 + 三维体详情 + 任务面板(依赖 1.0 参考)。
|
||||||
5. **P5 二维底图**:天地图瓦片层 + 2D 视图位置。
|
5. **P5 二维底图**:天地图瓦片层 + 2D 视图位置。
|
||||||
|
|
||||||
> 依赖:P3/P4 多处依赖"参考 Geopro 1.0"与后端接口,须先解 §13 开放问题。P1/P2 无外部依赖,可立即开工。
|
> 依赖:P1/P2/P3 均可用 xlsx + 现有代码 + LocalSample 开工(切片对 LocalSample 体素开发,§1.5)。P4 的色阶/异常框精修依赖 Geopro 1.0 参考(先近似);P3/P4 的真三维体细节待用户指认 3D 项目后实地补。P5 底图依赖天地图 token。
|
||||||
|
>
|
||||||
|
> **可立即开工:P1(含 Scene 加 vtkProp 入口)+ P2。** 评审结论:spec 修订后可作为 plan 基础。
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue