From faee28c007700ed2cfef44ff28d12ba094146a7c Mon Sep 17 00:00:00 2001 From: gaozheng Date: Mon, 15 Jun 2026 12:30:53 +0800 Subject: [PATCH] =?UTF-8?q?docs(spec):=20VTK=20=E4=B8=89=E7=BB=B4=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E8=A1=A5=E5=85=85=E9=9C=80=E6=B1=82=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E7=A8=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 通读需求表「补充需求」页签 + 源码核实 VTK 现状 - 关键判断:中央 VTK 当前为空壳(编排层喂空数据,图层勾选死代码), 但 render 层 actor 完整有测试,原型渲染原语未丢 - 逐行映射补充需求 → 现状/落地方式(§4) - 设计 I3dSceneRepository 仓储接口(维度筛选/三维体/切片CRUD/异常体/任务), 本轮 LocalSample 静态数据实现,预留后端 - 编排层 VtkSceneController + 交互层 interact/(切片/拾取/圈异常) - 分期建议 P1复活渲染 → P2三维数据集栏 → P3切片交互 → P4异常/详情/任务 → P5二维底图 --- .../2026-06-15-vtk-3d-supplementary-design.md | 353 ++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-15-vtk-3d-supplementary-design.md diff --git a/docs/superpowers/specs/2026-06-15-vtk-3d-supplementary-design.md b/docs/superpowers/specs/2026-06-15-vtk-3d-supplementary-design.md new file mode 100644 index 0000000..eeab870 --- /dev/null +++ b/docs/superpowers/specs/2026-06-15-vtk-3d-supplementary-design.md @@ -0,0 +1,353 @@ +# VTK 三维视图「补充需求」设计 + +- 日期:2026-06-15 +- 分支建议:`feat/vtk-3d-view` +- 状态:**设计稿(spec)**。本轮只产出设计,实现分期另立 plan。 +- 需求来源:`D:\Projects\GEOPRO\Geopro3.0 需求表.xlsx` →「补充需求」页签(已逐行通读,§4 全文映射);交叉参考「DD类型」页签。 +- 关键约束(用户已拍板): + 1. **后端 API 尚未就绪** —— 本轮用 `LocalSampleRepository` 静态数据驱动渲染与交互,**但仓储接口必须按真实后端形态设计好**(§6),将来后端到位只换实现、不动上层。 + 2. 三维相关 ddCode(`dd_Structual3D`/`dd_Property3D`/切片/异常体/任务记录)后端、客户端**都还没做**,是净增建。 + +--- + +## 0. TL;DR(一页结论) + +「补充需求」整页都是 **VTK 中央视图**的规格:把视图区拆成三个子列表栏(**三维数据集 / 二维数据集 / 三维分析**),并补齐坐标轴、相机预设、底图、**切片交互**、**异常体管理**、三维体详情、任务管理。 + +**当前真实状态(已源码核实,非推测):中央 VTK 是空壳。** +- `rebuildCentral`(`src/app/main.cpp:508-512`)只捕获 `showCurtain`,喂入**空 `sections`**;启动后中央区只有背景色 + 相机,不渲染任何数据。 +- 浮层勾选框 `chkVoxel/chkSlice/chkTerrain`(`main.cpp:603-617`)只改 `bool`,而 `rebuildCentralScene`(`src/app/CentralScene.cpp:16-47`)只处理 `is2D`/`showCurtain` 两支 —— 体素/切片/地形勾选**当前什么都不做**。 +- `slicePlane`(`vtkImagePlaneWidget`,`main.cpp:251`)声明后**全代码零使用**;`buildVoxelFromScatters/buildTerrain/loadVoxelScatters` 在 app 层**零调用**。 + +**好消息:render 层 actor 全部完整且有测试**(§5.1),数据源 `LocalSampleRepository` 也在。"之前用静态数据做的原型渲染"(git `7007619`/`9b77d07` 等)的**装配代码**在 `6241eb3`"CentralScene 数据驱动重构"时被摘除,但**渲染原语没丢**。 + +> 一句话:地基(actor 管线)稳固,缺的是「编排层 + 交互层 + 三栏 UI + 真实/样本数据接入」。 + +--- + +## 1. 背景与问题 + +需求表「补充需求」页签定义的是 Geopro 1.0 风格的三维工作台 —— VTK 视图不再是"二维地图/三维视图"二选一的展示器,而是一个带**子列表 + 工具栏 + 右键菜单 + 切片/异常交互**的分析环境。 + +当前客户端(M1)的 VTK 现状与之差距: + +1. **结构不符**:现在是单一 `QVTKOpenGLStereoWidget` + 顶部「二维地图/三维视图」互斥分段按钮(`main.cpp:308-316`),左下一个统一数据集列表。需求要的是**视图内置三个子列表栏**。 +2. **不渲染数据**:见 §0,编排层喂空数据,所有图层勾选是死代码。 +3. **无坐标轴 / 无相机预设 / 无底图 / 无切片交互 / 无拾取联动 / 无 3D 异常体 / 无任务面板**:这些都是净增建。 +4. **后端缺接口**:已核对 `ApiClient` 端点(§6.0),只有 2D ERT 那套;三维体模型/切片保存/异常创建/任务记录端点客户端都没有,且后端也未做。 + +--- + +## 2. 目标与范围 + +### 2.1 总目标 +在现有 render actor 地基上,复活并扩展中央 VTK 为「补充需求」描述的三维分析工作台;**用静态样本数据驱动**,但所有数据出入口走**为真实后端预留的仓储接口**(§6)。 + +### 2.2 范围内(本设计覆盖) +- 三子列表栏 UI 结构(三维数据集 / 二维数据集 / 三维分析)。 +- 三维数据集栏:坐标轴设置、水平/垂直比例、快捷视图(前后左右上下)、Zoom(In/Out/Fit)、数据集勾选 → 渲染。 +- 二维数据集栏:底图(天地图/Google/隐藏)、2D 视图切面位置、数据集勾选 → 渲染。 +- 三维分析栏:体模型/切片树、右键菜单、切片交互工具、拾取选中联动、切片分析(含创建异常、保存为数据集、导出、正视/翻转/关闭)。 +- 三维体数据集详情、切片数据集详情。 +- 异常/异常体管理(树、删除、属性、VTK 联动、显示过滤、截图属性)。 +- 任务管理(任务记录 + 可使用任务列表)。 +- **仓储接口设计**(§6)—— 本设计的重头,决定将来接后端的成本。 + +### 2.3 范围外 / 后续 +- 后端真实接口实现(本轮仅设计接口 + LocalSample 实现)。 +- 克里金插值(IDW 已有;克里金作为插值模型选项后续补)。 +- 二维底图的高保真瓦片缓存/离线(本轮先打通"能显示底图")。 +- 与 Web 端完全像素级一致的色阶编辑器(沿用现有 colorBar 解析)。 + +### 2.4 设计原则 +- **render 层零业务**:actor 只吃 `core::*` 数据结构(`Grid/ScalarVolume/ScatterField/Anomaly`),不认 ds/API。复活编排即可,不改 actor。 +- **接口先行**:上层只依赖 `I3dSceneRepository`(§6),`LocalSample3dRepository` 与未来 `Api3dRepository` 可互换。 +- **交互独立成层**:新建 `src/render/interact/`(README 早有规划但目录不存在),切片/拾取/圈异常都是 `InteractionTool`。 + +--- + +## 3. 与既有架构的关系 + +``` + ┌─────────────────────────── 中央 VTK 工作台 ───────────────────────────┐ + ObjectTreePanel │ ┌ 子列表栏(三选一/并列)────────┐ ┌ VTK 视图区 ──────────────────┐ │ + (左上,勾选对象) │ │ [三维数据集] [二维数据集] [三维分析]│ │ Scene(renderer) + actors │ │ + │勾选 │ │ · 坐标轴/比例/快捷视图/Zoom 工具条 │ │ + CubeAxes + 底图层 │ │ + ▼ │ │ · 数据集勾选列表(按维度属性筛) │ │ + InteractionManager(切片/拾取)│ │ + VtkSceneController ─┼─→ I3dSceneRepository ─→ core::数据 ─→ render actors ─→ Scene │ │ + │ └────────────────────────────────┘ └──────────────────────────────┘ │ + └──────────────────────────────────────────────────────────────────────┘ + 右栏: 三维体/切片 详情 · 异常体树 · 任务管理(任务记录 + 可用任务列表) +``` + +- `VtkSceneController`(新)取代当前散落在 `main.cpp` 的 lambda 编排,订阅"勾选对象/数据集/图层/视图模式"变化,经 `I3dSceneRepository` 取数据,调 render actor 重建场景。 +- 现有 `WorkbenchNavController`(对象/数据集导航)、`DatasetDetailController`(详情)保持职责不变,新控制器与之并列。 + +--- + +## 4. 「补充需求」全文逐行映射(权威对照表) + +> 维度属性来源:需求称"ds 类型的显示属性为 3D/2D",即**维度属性挂在 ds 类型上**(非单条 ds)。`DsRow` 当前无此字段(`src/data/repo/RepoTypes.hpp:10`),须由 §6.1 的类型→维度映射补。 + +| 行 | 需求原文(摘) | 现状 | 落地方式 | +|---|---|---|---| +| A1 | VTK 提供三子列表栏:三维数据集/二维数据集/三维分析 | 单一 2D/3D 切换 | §7.1 三栏 UI | +| C3–I3 | 坐标轴显示方式:标准/三维立体/不显示 | 无坐标轴 | `vtkCubeAxesActor`(标准)/`vtkAxesActor`(立体)/隐藏;§7.2 | +| D4 | O 点位置 | 无 | 坐标轴原点配置(世界系原点 / 数据包围盒角)| +| D5–I5 | 刻度:无刻度/米/英尺/经纬度/字体 | 无 | 刻度单位换算 + 经纬度用 `GeoLocalFrame` 反算 + 字体设置 | +| C6 | 水平/垂直比例 | 硬编码 `kVerticalExaggeration=2.0`(`main.cpp:208`)| 做成可调,作用于全部 3D actor `SetScale(1,1,VE)` | +| C7 / D7–I7 | 快捷视图:前/后/左/右/上/下 | `CameraPreset` 仅 Top2D/Free3D | 新增 6 方向预设(§5.3)| +| C8 / D8–F8 | Zoom:In/Out/Fit | 仅 `ResetCamera`(=Fit) | In/Out 调 `camera->Zoom()`;Fit=ResetCamera | +| C9–D10 | 三维数据集列表:筛勾选对象中 ds 维度=3D;勾选多个显示 | sections 为空 | §6.1 维度筛选 + §8 编排复活 | +| C13–F13 | 地图:天地图/Google Map/隐藏 | 中央无底图 | §7.3 底图层(VTK 瓦片)| +| C14 | 2D 视图:关闭/Z=0/顶部/底部/自定义 Z | 无 | 切面高度控制 | +| C15–D16 | 二维数据集列表:ds 维度=2D | 同上 | §6.1 + §8 | +| C19–D20 | 三维分析列表:按 对象/三维体模型/切片 树 | 无 | §7.4 分析树 | +| D21,F22–G22 | 右键·三维体:上下切片 | 无 | §9 轴向切片工具(水平面)| +| F23 | 前后切片 | 无 | §9 轴向切片 | +| F24 | 左右切片 | 无 | §9 轴向切片 | +| F25 | 任意切片(初始 45°,可任意调整)| 无 | §9 任意角度切片(`vtkPlaneWidget`+`vtkCutter`)| +| F26 | 色阶(参考 Geopro 1.0 优化)| 有 colorBar 解析 | 复用 `ColorScale` + 色阶编辑入口 | +| F27 | 显示/隐藏 | 无 | actor 可见性 | +| F28–G28 | 数据详情 → 详情栏 | 详情面板在 | §10 三维体详情类型 | +| E29,F30–F36 | 右键·切片数据集:保存/保存为/导出/删除/色阶/显隐/详情 | 无 | §6.3 切片 CRUD 接口 + §10 | +| C38,D39 | 选中三维体/切片为中心拖动旋转 | 无拾取/自定义 style | §9.3 拾取 + 自定义 InteractorStyle | +| D40 | 双击切片 → 正视该切片 | 无 | §9.3 双击→相机正视切面法向 | +| C44,D44 | 右键三维体创建切片工具 | 无 | §9 | +| D45 | 双击切片工具正视 | 无 | §9.3 | +| D46 | 选中切片滚轮 → 内外切片(对象=所属三维体)| 无 | §9.2 滚轮沿法向平移切面 | +| D47 | 切片任一位置可保存为新切片数据集 | 无 | §6.3 createSlice | +| D48,E49,F49–F50 | 创建异常:异常工具,光标拾取起点;结束保存弹框(确定截图大小/异常坐标,参考 1.0)| 有 2D `AnomalyActor`,无创建流 | §9.4 异常圈定工具 + §6.4 saveAnomaly + 截图 | +| E51–F51 | 保存为数据集 | 无 | §6.3 | +| E52–F52 | 导出为图片 | 无 | `vtkWindowToImageFilter` | +| E53–F53 | 导出到 dat | 无 | 切面采样导出 | +| E54–F54 | 正视图 | 无 | §9.3 | +| E55–F55 | 视图翻转(水平旋转 180°)| 无 | 相机 `Azimuth(180)` | +| E56–F56 | 关闭(取消当前切片)| 无 | 移除切片工具 | +| A58,B59–B65 | 三维体详情:源数据/切片数据/异常/插值模型(克里金,IDW)/插值参数/色阶参数/测量(点数,体积)| 详情引擎在,类型未做 | §10.1 | +| A67 | 切片详情:参照 dd_Section | `dd_section` 渲染已有 | §10.2 复用 | +| A69,B70,C71–D77 | 异常体列表树:异常体→分组→异常 | `ObjectExceptionPanel` 只读树在 | §11 扩展为可操作 | +| C79,D80–D81 | 操作:删除/删除分组 | 无 | §6.4 delete/deleteGroup | +| C83,C84 | 异常属性 + VTK↔列表 双向选中联动 | 无联动 | §9.3 + §11 | +| B86,C87–F87 | 异常体显示过滤:全部显示/随GS/随数据集/全部隐藏 | 无 | §11 过滤模式 | +| B88,C88 | 异常增加截图属性(保存标识时截图)| 无 | §6.4 截图字段 | +| A90,C90 | 任务管理:任务记录 + 可使用任务列表 | 有 `model/list`,无任务面板 | §12 | +| B91,C91 | 任务记录:当前数据集调用任务的记录 | 无 | §6.5 taskRecords | +| B92,C92 | 可使用任务列表:与 ds 类型相符的任务插件 | `ModelInfo`(model/list) 在 | §6.5 usableTasks(按 ddType 过滤) | + +--- + +## 5. 现状资产盘点(render 层,已源码核实) + +### 5.1 可直接复用的 actor(完整 + 有测试) +| 组件 | 文件 | 吃什么 | 产出 | 复用于补充需求 | +|---|---|---|---|---| +| ScatterActor | `src/render/actors/ScatterActor.*` | `ScatterField+ColorScale` | 散点 actor | 三维体源数据点 | +| GridContourActor | `actors/GridContourActor.*` | `Grid+ColorScale` | 色带+等值线 | 切片面着色 | +| VoxelActor | `actors/VoxelActor.*` | `ScalarVolume+ColorScale+原点/间距` | **GPU 体绘制 `vtkVolume`**,可导出内部 `vtkImageData` | 三维体模型渲染 + 切片输入 | +| VoxelFromScatters | `render/VoxelFromScatters.*` | 多剖面散点+CRS+frame | IDW→体绘制+image | 三维体(散点插值)| +| AnomalyActor | `actors/AnomalyActor.*` | `vector` | 点/折线/多边形(**2D 剖面**)| 切片上异常圈定(需扩 3D 异常体)| +| TerrainActor | `actors/TerrainActor.*` | DEM+影像 GeoTIFF | 纹理地形 | 三维场景地形图层 | +| CurtainActor | `actors/CurtainActor.*` | `Grid+ColorScale+frame` | 竖直帘面 | dd_section 三维帘面 | +| MapLineActor | `actors/MapLineActor.*` | `Grid+frame` | 俯视红线 | 二维数据集测线 | +| ElectrodeActor | `actors/ElectrodeActor.*` | `Grid` | 电极 ▼ | 剖面电极 | +| ColorLutBuilder / ContourBands | `render/ColorLutBuilder.*` `ContourBands.*` | colorBar | LUT / 离线等值线几何 | 色阶 / 导出 | + +### 5.2 缺口(净增建) +- **坐标轴**:无 `vtkCubeAxesActor`/`vtkAxesActor`。 +- **相机预设**:`CameraPreset.cpp` 仅 `applyTop2D`/`applyFree3D`,缺前后左右上下 + Zoom In/Out。 +- **底图**:无 VTK 瓦片底图层(README 提的 `ground/TileGroundLayer` 未实现)。 +- **切片交互**:`vtkImagePlaneWidget` 声明未用;无 reslice/cutter/任意角度切片;`src/render/interact/` 目录不存在。 +- **拾取/选中联动**:无 picker、无自定义 `vtkInteractorStyle`。 +- **3D 异常体**:`AnomalyActor` 仅 2D 剖面;无三维异常体 actor、无 VTK↔列表联动。 +- **截图**:无 `vtkWindowToImageFilter` 接线。 +- **编排层**:`rebuildCentralScene` 喂空数据;图层勾选死代码。 + +### 5.3 CameraPreset 扩展(小量、低风险,可独立先做) +新增 `applyView(vtkRenderer*, ViewDir)`,`ViewDir ∈ {Front,Back,Left,Right,Top,Bottom}`,设置 position/focalPoint/viewUp 后 `ResetCamera`;`zoomIn/zoomOut` 调 `camera->Zoom(1.2 / 0.83)` 后 `Render`。 + +--- + +## 6. 仓储接口设计(本设计重头 —— 用户要求"接口设计好") + +> 现状:`IDatasetRepository`(`src/data/repo/IDatasetRepository.hpp`)已有 2D 那套(loadGrid/Scatter/ColorScale/Anomalies)。本设计**新增并列接口 `I3dSceneRepository`**,承载三维体/切片/异常体/任务。本轮 `LocalSample3dRepository` 实现(读样本文件 + 内存态增删),将来 `Api3dRepository` 换实现。 + +### 6.0 后端端点现状(已核对,非推测) +现有 `ApiClient` 仅:`dd/ert/{grid,inversion,measurement,trajectory}`、`dsObject` CRUD/import/detail、`exception/queryException`(**只读**)、`model/list`、`lvl/colorGradation`、`templateExport`。 +**缺**:三维体模型数据、切片 CRUD、异常**创建/保存**、任务记录。→ 本轮接口为这些预留方法签名,LocalSample 内存实现。 + +### 6.1 维度属性(解决"ds 维度=3D/2D"筛选) +```cpp +enum class DsDimension { Dim2D, Dim3D, Analysis3D, Other }; +// 由 ds 类型(ddCode / dsTypeId)决定。LocalSample 用内置映射表; +// 未来后端可在 dsObject/getDetail 返回 dimension 字段。 +DsDimension dimensionOf(const DsRow& ds) const; // 列表筛选用 +``` +> LocalSample 映射(依据「DD类型」页签语义):`dd_Structual3D`/`dd_Property3D`/`dd_voxel` → `Dim3D`/`Analysis3D`;`dd_section`/`dd_inversion_data` 帘面可入 3D,俯视测线入 2D;`dd_trajectory_data` → `Dim2D`。 + +### 6.2 三维体模型数据集 +```cpp +struct VolumeModelMeta { + std::string dsId, name; + std::string interpMethod; // "IDW" / "Kriging" / ... + std::vector interpParams; // 插值参数(复用既有动态表单字段) + std::string colorScaleId; // 色阶参数引用 + double pointCount = 0, volume = 0; // 测量数据(点数/体积) + std::vector sourceDsIds; // 源数据集 + std::vector sliceDsIds; // 切片数据集 + std::vector anomalyBodyIds; // 异常体 +}; +VolumeModelMeta loadVolumeMeta(const std::string& dsId); +geopro::core::ScalarVolume loadVolume(const std::string& dsId, + double& ox,double& oy,double& oz, + double& dx,double& dy,double& dz); // 规则体 + 原点/间距 +``` +> LocalSample:用 `VoxelFromScatters` 把样本两条交叉剖面散点 IDW 成 `ScalarVolume` 当作一个三维体模型。 + +### 6.3 切片数据集(CRUD —— 后端缺,先内存实现) +```cpp +struct SliceSpec { + std::string volumeDsId; // 所属三维体 + double origin[3]; // 切面一点 + double normal[3]; // 切面法向(轴向/任意) + std::string colorScaleId; +}; +struct SliceDataset { std::string dsId, name; SliceSpec spec; geopro::core::Grid section; }; +SliceDataset extractSlice(const SliceSpec& spec); // 实时算切面(不落库) +std::string createSlice(const SliceSpec& spec, const std::string& name); // 保存为数据集→返回新 dsId +void saveSlice(const std::string& dsId, const SliceSpec& spec); // 保存 +void deleteSlice(const std::string& dsId); +// 导出:导图片/dat 由 UI 层用 vtkWindowToImageFilter / 采样写文件(不入仓储) +``` + +### 6.4 异常 / 异常体(树 + CRUD + 截图) +```cpp +struct AnomalyBody { // 对应"异常体"(树中间层) + std::string id, name, typeName; + std::vector members; // 组内异常(复用既有 2D Anomaly;3D 用包围几何) +}; +struct AnomalyTree { // 对象 → 异常体/分组 → 异常 + std::vector bodies; + std::vector loose; // 未分组异常 +}; +AnomalyTree loadAnomalyTree(const std::string& objectId); +std::string saveAnomaly(const core::Anomaly& a, const std::string& screenshotPngPath); // 截图属性 +void deleteAnomaly(const std::string& anomalyId); +void deleteAnomalyGroup(const std::string& bodyId); +// 显示过滤是 UI/渲染层状态,不进仓储:enum AnomalyFilter{All,FollowGs,FollowDs,None} +``` + +### 6.5 任务管理 +```cpp +struct TaskRecord { std::string id, taskName, status, createTime; }; // 任务记录 +struct UsableTask { std::string scriptId, scriptCode, name; int opType; }; // = 既有 ModelInfo +std::vector loadTaskRecords(const std::string& dsId); // 当前 ds 的调用记录(后端缺→空/样本) +std::vector loadUsableTasks(const std::string& ddCode); // 按 ds 类型过滤插件(复用 model/list) +``` + +--- + +## 7. UI 设计 + +### 7.1 三子列表栏 +在 VTK dock 内(或左侧新 dock)放三个可切换 tab/分段:**三维数据集 / 二维数据集 / 三维分析**。每栏顶部是该栏专属工具条,下方是数据集勾选列表(按 §6.1 维度筛选当前勾选对象的 ds)。 + +> 取舍建议:保留现有 `ObjectTreePanel`(左上勾选对象)作为"对象勾选源";三栏列表只在被勾选对象范围内、按维度过滤显示 ds。避免与现有左下数据集列表职责重叠 —— **左下数据集列表服务"详情查看",三栏列表服务"VTK 渲染勾选"**(两条线,需在 UI 上区分清楚,见 §13 开放问题)。 + +### 7.2 三维数据集栏工具条 +坐标轴下拉(标准/立体/不显示)+ O 点 + 刻度(无/米/英尺/经纬度)+ 字体 | 水平/垂直比例(滑块/输入)| 快捷视图(前后左右上下 6 钮)| Zoom(In/Out/Fit)。 + +### 7.3 二维数据集栏 +底图下拉(天地图/Google/隐藏)+ 2D 视图位置(关闭/Z=0/顶部/底部/自定义 Z)。底图层:VTK 内用瓦片纹理贴 z=0 平面(天地图 WMTS);本轮先打通"能显示+隐藏",缓存优化后续。 + +### 7.4 三维分析栏 +树:对象 → 三维体模型数据集 → 切片。右键菜单按节点类型分派(三维体 / 切片,见 §4 行 D21–F36)。 + +--- + +## 8. 渲染编排层 `VtkSceneController`(复活原型) + +职责:聚合"勾选对象 + 当前栏 + 图层开关 + 视图模式"→ 经 `I3dSceneRepository` 取 `core::*` → 调 actor → `Scene`。**取代 `main.cpp` 里的 `rebuildCentral` lambda 与死掉的图层标志。** + +```cpp +class VtkSceneController : public QObject { + // 输入信号:勾选对象变 / 栏切换 / 图层勾选 / 比例变 / 快捷视图 / 切片增删 + // 内部:维护 ScalarVolume/Grid 缓存,按需重建;统一 SetScale(1,1,VE) + // 输出:scene.clear()+addActor()+renderWindow->Render() +}; +``` +落地第一步(最低风险、最快见效):把 `extractSlice`/`loadVolume`/`buildCurtain`/`buildVoxelFromScatters`/`buildTerrain` 用真实勾选 ds 接通 —— **render actor 零改动即复活**。 + +--- + +## 9. 交互层 `src/render/interact/`(新目录,最重模块) + +### 9.1 切片工具 +- **轴向切片**(上下/前后/左右):`vtkImagePlaneWidget` 贴体素 `vtkImageData`(VoxelActor 已能导出 image),沿固定轴向,角度不可调(符合 G22–G24)。 +- **任意切片**(F25):`vtkPlaneWidget` + `vtkCutter`/`vtkImageReslice`,初始 45°,可任意旋转。 +- 统一抽象 `SliceTool`:持 `vtkPlane`,产出切面 `Grid`(喂 GridContourActor 着色)。 + +### 9.2 滚轮切片(D46) +选中切片 → 自定义 InteractorStyle 截 `OnMouseWheel` → 沿切面法向平移 origin → 重算切面。 + +### 9.3 拾取 + 选中联动(C38/D39/D40/C84) +`vtkPropPicker` + 自定义 `vtkInteractorStyle`: +- 选中三维体/切片 → 以其包围盒中心设相机 focalPoint(拖动绕其旋转)。 +- 双击切片 → 相机正视切面法向(D40/D45/E54)。 +- 拾取异常体 ↔ 异常树列表双向高亮(C84)。 + +### 9.4 异常圈定工具(D48/E49/F49–F50) +自定义 widget:光标拾取起点 → 连续描点成多边形(复用 `core::Anomaly` Polygon)→ 结束弹保存对话框(截图大小 / 异常坐标,参考 Geopro 1.0)→ `saveAnomaly(a, screenshot)`。截图用 `vtkWindowToImageFilter`。 + +--- + +## 10. 详情视图 + +### 10.1 三维体详情类型(新) +详情面板(`DatasetDetailPanel`,ddCode 驱动)新增三维体详情:源数据 / 切片数据 / 异常 / 插值模型(IDW·克里金) / 插值参数 / 色阶参数 / 测量(点数·体积)。数据来自 `VolumeModelMeta`(§6.2),多为表单/列表展示。 + +### 10.2 切片详情 +参照 `dd_section`(已有渲染),复用现有等值面+等值线引擎。 + +--- + +## 11. 异常体管理面板 + +扩展现有 `ObjectExceptionPanel`(当前只读树)为可操作: +- 树:对象 → 异常体 → 异常(含未分组异常)。 +- 操作:删除 / 删除分组(§6.4)。 +- 异常属性面板(选中异常显详情)。 +- VTK↔列表双向选中联动(§9.3)。 +- 显示过滤:全部显示 / 随 GS / 随数据集 / 全部隐藏(渲染层可见性状态)。 +- 异常截图属性(保存时存截图,§6.4)。 + +--- + +## 12. 任务管理面板(新) + +两段: +- **任务记录**:当前数据集的任务调用记录(`loadTaskRecords`,后端缺→样本/空态)。 +- **可使用任务列表**:按当前 ds 的 ddCode 过滤的任务插件(`loadUsableTasks`,复用 `model/list`)。 + +--- + +## 13. 开放问题 / 待确认(写计划前需定) + +1. **三栏列表 vs 现有左下数据集列表的职责边界**:是新增三栏(渲染勾选用)与左下(详情用)并存,还是合并改造?影响 UI 重构面。(§7.1 给了建议:并存,两条线) +2. **坐标系单位**:刻度"经纬度"用 `GeoLocalFrame` 反算到 lat/lon;"米/英尺"基于世界系米。O 点默认取世界原点还是数据包围盒? +3. **切片"保存为数据集"的落库形态**:后端缺接口,本轮 LocalSample 内存态。是否需要持久化到本地文件以便重启可见? +4. **异常 3D 表达**:现有 `Anomaly` 是 2D(剖面坐标)。三维异常体是用包围多边形拉伸,还是需要真正的 3D 体?需求 B70 树结构清晰,但 3D 几何形态需 1.0 参考。 +5. **"参考 Geopro 1.0"的多处**(F26 色阶 / F50 异常保存框 / F49 圈异常):是否有 1.0 可实地学习(截图/源码/在线系统)?按记忆规约(复刻须实地学习,禁猜测),实现这些前需拿到 1.0 参考。 +6. **底图天地图 key / Google Map 可用性**:天地图需 token;Google 在国内可用性。本轮先做天地图 + 隐藏,Google 占位? + +--- + +## 14. 分期建议(详细 plan 另立,此处仅排序) + +1. **P1 复活渲染(地基,低风险)**:`VtkSceneController` + `I3dSceneRepository`/`LocalSample3dRepository` + 勾选 ds → 真实/样本数据 → actor。复活帘面/体素/地形/切面着色。 +2. **P2 三维数据集栏(纯前端,独立)**:坐标轴 + 水平/垂直比例 + 快捷视图 6 向 + Zoom。 +3. **P3 三维分析·切片交互(最重)**:`interact/` + 轴向/任意切片 + 滚轮 + 拾取联动 + 双击正视 + 正视/翻转/关闭 + 切片 CRUD + 导出。 +4. **P4 异常体 + 圈异常 + 详情 + 任务**:异常圈定工具 + 异常体树管理 + 三维体详情 + 任务面板(依赖 1.0 参考)。 +5. **P5 二维底图**:天地图瓦片层 + 2D 视图位置。 + +> 依赖:P3/P4 多处依赖"参考 Geopro 1.0"与后端接口,须先解 §13 开放问题。P1/P2 无外部依赖,可立即开工。