geopro/docs/superpowers/HANDOFF-vtk-3d.md

116 lines
19 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.

# 交接VTK 三维视图feat/vtk-3d-view
> 给下一个会话无缝接手用。更新日期 2026-06-18#4 异常功能全部收口后)。分支 `feat/vtk-3d-view`,工作树:仅根目录 `grid-list-original.png`/`grid-list-small.png`/`grid-snap.yml`/`orig-dataview.png` 及 `docs/superpowers/specs/2026-06-17-web-embed-subpage-mount-design.md` 是**既有未跟踪文件,非本任务产物,勿动/勿提交**(曾被 `git add -A` 误纳、已撤回)。
>
> **进度速览2026-06-18**:补充需求 #1 生成三维体 ✅、#2 切片交互 ✅、#3 切片生命周期 ✅、#4 异常(圈定/保存/列表/异常体/过滤/显隐/删除/选中高亮/属性对话框)✅、#6 体/切片数据详情对话框 ✅ 全部完成、编译绿、用户实测通过。最新提交 `b97ea68`#6 详情对话框)。**剩下全是收尾/打磨项**(见 §4 末「下一步候选」),无进行中的半成品。下一会话应先问用户选哪个方向,或直接接其指定项。
>
> **附**Windows 安装包打包工具已落地(`installer/`,提交 `0504129``build.bat app` 后 `powershell -File installer\build_installer.ps1` 一键出 Inno Setup 安装包(自动 windeployqt 补 Qt 运行时+绕过 ADS 卡死、补 VC 运行时、中文向导)。
## 1. 背景
- 项目geopro 桌面客户端Qt6 + VTK9 + Qt-ADS dockWindows/MSVC+Ninja`build.bat`。
- 任务:实现需求表「补充需求」页 = VTK 三维视图整套结构/交互。需求源:`D:\Projects\GEOPRO\Geopro3.0 需求表.xlsx`「补充需求」页。
- 原版 web 源码在 **`D:\Git\lanbingtech\commercial-admin`**Vue + three-tile是**复刻的权威参照**threeMap.vue / mapSource.js / src/apis/)。
- 三栏结构(三维数据集 / 二维数据集 / 三维分析)+ 真实 ERT 反演剖面(帘面)+ 底图地形——这些**已完成**。本会话主要做了**底图/地形 + 剖面垂直配准 + 增量渲染**,并为下一阶段(三维体/切片/异常)做了**设计定稿**。
## 2. 本会话已完成(均已编译绿 + 提交;用户验收"差不多了"
**底图 + 真实地形**(核心在 `src/app/TileBasemap.{hpp,cpp}`
- 影像=**天地图卫星**(`img_w`tk 内嵌);地形=**Mapbox terrain-RGB DEM**(原版同源pk token 内嵌;`elev=-10000+(R*65536+G*256+B)*0.1`)。
- **四叉树多级 LOD**(按瓦片屏幕像素误差递归细分,近细远粗)。根 `kRootZoom=9`、阈值 `kTargetPx=384`、叶上限 `kMaxLeaves=200`
- **视锥剔除只用 4 个侧面**(不用近/远裁剪面——远裁剪面随已加载几何变化会误剔除远块)。`frustum_[24]` 用焦点自校正法向。
- **并发限流** `kMaxConcurrent=12`(请求队列 `netQueue_`/`pumpNetQueue`)。
- **缓存**:影像纹理 `texCache_` + DEM `demCache_`,跨隐藏/重选保留 → 重选秒出。
- **合并渲染** `requestRender()`Qt 队列合并同轮多次渲染请求为一帧;并在渲染前 `ResetCameraClippingRange`)。
- **动态范围**:底图最大距离 = 剖面合并范围半径×10夹 [2km,30km],随勾选增删自动伸缩(`dataRadiusProvider_` 查 `VtkSceneView::dataHorizontalRadius()`)。**超过范围的粗瓦也强制细分**(否则一块巨瓦盖住中心、绕过距离剔除)。
- **地形半透明 0.55**`kTerrainOpacity`)——地下剖面可从任意角度透过地面看到(地球物理标准做法;解决"前后左右预设看不到剖面=不透明地形遮挡地下")。
- **近裁剪容差 1e-5**`SetNearClippingPlaneTolerance`VtkSceneView 构造)——远处底图把近裁剪面顶出去会切掉近处剖面,调小修复。
- **就近优先加载**(离相机近的瓦片先拉)。
- 瓦片纹理 mipmap + 各向异性 16x + edgeClamp。
**剖面垂直配准 + VE**
- 剖面 Z = **`+g.y`(真实高程)**——与原版一致(实证 `threeMap.vue:676`:剖面世界竖向 = data.y。地形也用真实高程 → 同系对齐、剖面顶≈地表露出。(早期错把 y 当深度 `-y`,已改。)
- 垂直夸张默认 **1.0**,收敛为**单一来源** `kVerticalExaggeration`main.cpp下发控制器/底图/UI。剖面与地形用同一 VE。
**增量渲染**`VtkSceneController` + `VtkSceneView`
- 勾选/取消 = **按 dsId 增删图元**,不再整场 clear + 全量重建;`clear()` 保留底图;增量不重置相机(视角不跳);首批数据/全量重建才 `fitView`
- `computeDataBounds()` 只算数据图元(不含底图)→ 坐标轴/取景/预设(前后左右)不被公里级底图撑大/推远。
- `onCameraChanged` 回调:相机程序化变化(取景/预设/缩放)后通知底图按新视锥重算覆盖(治"首帧部分瓦片要微动才出")。
- 默认底图=天地图;首个剖面重锚 frame 后经 `onFrameReanchored` 在数据位置加载底图。
- VTK 全屏含左侧三栏drawer 在 vtkDock 内 + 进入全屏展开)。
## 3. 当前状态2026-06-18 更新)
- 底图/地形/剖面配准/增量渲染:**完成且可用**。编译绿。所有改动已提交到 `feat/vtk-3d-view`
- **#1 客户端「生成三维体」流程:已实现并经本会话大量使用验证**(切片/异常都在生成的体上操作过,间接验收)。详见计划 `docs/superpowers/plans/2026-06-17-vtk-3d-volume-create-flow.md`
- 已落地:`data::VolumeBuildParams`(不冻结 gridSpec源 ds 锁定不变式);`core::buildVolume` 共享管线LocalSample/Api 同源);`Api3dRepository` 内存体存储 + `createVolume/volumeRows/isVolumeDataset` + 多源 `loadVolume`(复用 `loadSection`,竖向=g.y 高程,与帘面对齐;`fitAxis` 按 extent 增大 cell 以覆盖跨 TM 全范围);`loadVolume` 回调交付 `(VolumeGrid, ColorScale)``Column3DDataset` 多选+右键「生成三维体」(按**勾选框**选中集,非行选)+ `VolumeParamsDialog`**生成的体归三维分析栏**(`Column3DAnalysis`)main.cpp `refreshAnalysis` 合并注入 + `pushChecked` 两栏勾选聚合;`VtkSceneController` 按 `isVolumeDataset` 分流体素/帘面。
- **#2/#3 切片:完成且用户实测通过**(提交 afdd98f+d56e35f。四向创建/滚轮推进/双击正视/翻转/关闭/选中高亮VTK 右键菜单(创建异常/保存/导出▸图片·dat/正视/翻转/关闭);未保存↔已保存统一状态模型(保存按状态分派、无重复切片);精确三点几何持久化;场景↔列表勾选双向同步。导出 `SliceExport`。切片持久化=`Api3dRepository` 内存 mock。
- **#4 异常:完成且用户实测通过**(见 §4 第 4 项4a→4c-3最新 c83f63a。圈定→保存→渲染→列表→异常体分组→过滤→显隐→删除→选中高亮→双击属性全链 mock。
- **剩余 = 收尾/打磨项**§4 末「下一步候选」表):体/切片详情面板、真实色阶编辑、三级树根层、坐标轴弹框、真实后端对接(阻塞)、收口 PR。**无进行中的半成品**。
## 4. 下一步计划(三维体 / 切片 / 异常)
**权威设计文档**`docs/superpowers/specs/2026-06-17-vtk-3d-volume-slice-anomaly-design.md`(数据模型 + 交互流 + 后端vs mock + 代码现状 + 实现拆解 + 持久化策略)。已与用户拍板的关键决策:
- **创建三维体 = 客户端**:「三维数据集」栏多选剖面 → 选插值模型/参数 → `core::IdwInterpolator` 生成体素。
- **异常 = 接真实后端端点**(已从 web 源码挖到,见设计文档 §3`POST/PUT/DELETE /business/exception` + `exceptionType/*` + `exceptionConsortium/*` + 读 `queryException*`/`queryExceptionTree`。`remarkSourceId/Type` 填切片数据集。
- **三维体网格 / 切片持久化 / 三维分析任务 = 后端无端点 → 先本地 mock**(保持 `I3dSceneRepository` 接口不变,端点就绪只换实现)。
- **持久化策略**(设计文档 §7三维体保存时 **参数(源数据+插值模型/参数+色阶) + 网格规格 GridSpec 必存,明细 values 可选**;加载时有明细直接渲染、无明细按参数重算填入固定 GridSpec锚定切片/异常坐标)。带切片/异常或大/慢的体建议存明细。
- 数据模型层级:**三维体(源数据+插值参数) → 切片(属于体,保存后成 dd_slice) → 异常(画在切片平面,圈定保存)**,三者皆可持久化。
**实现拆解(设计文档 §6按依赖排序**
1. ~~三维体 mock 渲染~~ **✅ 已实现(编译绿,待 GUI 实测)**——见 §3 与计划 `2026-06-17-vtk-3d-volume-create-flow.md`。`Api3dRepository::loadVolume` 已接通(多源复用 loadSection → IDW → VolumeGrid + 色阶交付);`VolumeBuildParams` 必存参数、values 惰性重算+缓存(**不冻结 gridSpec**,改用源 ds 锁定不变式,留校验 TODO
2. ~~切片交互接通三维体~~ **✅ 已有**`SliceTool`/`InteractionManager`:四向创建/滚轮推进/双击正视/翻转/关闭/选中高亮全在)。
3. **✅ 完成(3a/3b/3c已提交 afdd98f+d56e35f用户实测通过)**——切片完整生命周期(未保存↔已保存统一状态模型)
- VTK 视图切片右键菜单(`PickInteractorStyle`右键→`InteractionManager`高优先级(1.0)交互器观察者抢右键→`onSliceContextMenuRequested`→main 弹 QMenu):创建异常(占位#4)/保存/导出▸(图片·dat)/正视图/翻转/关闭。
- **保存按状态分派**:未保存→`createSlice`+`tagSelectedSlice`链接当前切片+列表自动勾选(`setItemChecked`);已保存→`saveSlice`覆盖位姿。**无重复切片**。
- **精确几何持久化**`SliceSpec`存 axis+Origin/Point1/Point2 三点;`SliceTool`还原构造逐点重建→重渲染尺寸/朝向一致。
- **已保存切片重渲染**:分析栏勾选→`syncSlices`在当前活动体上还原(`showSavedSlice`),取消→移除;靠`onVolumeChanged→syncSlices`解决父体异步到场。dd_slice 不进控制器(避免 loadSection 失败)main 编排走 InteractionManager。
- **场景↔列表同步**VTK「关闭」已保存切片→`onSliceClosed`→列表取消勾选。`Column3DAnalysis::setDatasets`按 dsId 保留勾选+仅勾选集变化才发信号(修"保存切片连带取消体勾选/列表重置")。
- 导出:`SliceExport.{hpp,cpp}`(图片=切片上采样2048上色 PNGdat=重采样标量网格)。切片持久化=`Api3dRepository` createSlice/saveSlice/deleteSlice 内存 mock + sliceRows/isSliceDataset/sliceSpec。
4. 异常(**进行中**,全量含异常体/列表/过滤,计划见 `plans/2026-06-18-vtk-3d-anomaly.md`)。**异常挂三维体**(非切片非源ds见记忆 vtk-3d-persistence-structure)mock 持久化(三维体/切片端点未就绪)。
- **4a ✅ 已提交(4e1b8e7)**`core::Anomaly` 补 3D(id/volumeDsId/consortiumId/worldPts/plane)`buildAnomaly3D``I3dSceneView`+`VtkSceneView` addAnomaly/removeAnomaly/clearAnomalies/setAnomalyVisible(按id跟踪actor)`Api3dRepository` 异常 mock(saveAnomaly/loadAnomalyTree按volumeDsId+consortiumId分组/delete)。**附带修复测试漂移→228/228 绿**。地基、尚不可见。
- **4b ✅ 已提交**:圈定工具(切片平面画多边形,黄点+橡皮筋虚线,双击/右键/Enter 闭合,Esc 取消,屏幕提示)+保存对话框(名称/类型 mock/备注/截图预览)+切片右键「创建异常」接通 → 画→存→显示→删闭环。修复:闭合手势误触切片(abort 先于 finish/teardown)。
- **4c-1 ✅ 已提交**:三维分析栏「异常」组(QSplitter:数据集树 + 异常 QGroupBox);过滤下拉(全部显示/随GS/随数据集/全部隐藏,默认随数据集);删除按 consortiumId 分组;`refreshAnomalies` 各路径补 `renderWindow->Render()`(修过滤勾选与 VTK 显隐脱节)。
- **4c-2 ✅ 已提交(44d31a8)**列表选中异常→VTK 高亮联动(R84,list→VTK)`setSelectedAnomaly`(选中 actor 加粗线宽/点尺寸,其余恢复);anomalyProps_ 改 vtkActor。**反向(VTK点异常→回选列表)未做**(需异常 actor 拾取)。
- **4c-3 ✅ 已提交(c83f63a)**:异常属性对话框(R83,双击异常列表项弹只读:名称/类型/标记类型/归属三维体/异常体/顶点世界坐标/备注)`AnomalyPropertiesDialog`。**截图字段:模型/端点均无,不展示**(保存对话框截图为 mock 未持久化)。
- **#4 异常功能收口** ✅(4a→4c-3 全做完,编译绿+用户实测通过)。**剩余已知限制**:① 反向(VTK 点异常→回选列表)未做(需异常 actor 拾取);② 单条显隐状态跨 refresh 不持久;③ 全链 mock(三维体/切片端点未就绪),端点就绪后切真实。
5. 分析栏右键接线:**已完成**(切片 保存/保存为/导出▸/删除 全接;体 切片▸/详情/色阶)`colorScaleRequested` **已接 P1 色阶编辑器**(详见下表)。已移除"显示/隐藏"(勾选即显隐)。
6. 三维体/切片/异常详情:**✅ 全部完成**——异常详情对话框(4c-3);体/切片详情对话框(#6,提交 b97ea68)。形态统一为只读属性对话框,非停靠面板。
- **其它小欠项**:三维分析栏完整三级树"对象→三维体→切片"里"对象"根层未套(体目前是顶层);真实色阶编辑。
**其它小项**坐标轴「O点位置」「字体」弹框仍是 stubmain.cpp:382 TODO P4
### 下一步候选2026-06-18主体功能已完结以下均为收尾/打磨;下一会话先与用户确认方向)
| 候选 | 性质 | 阻塞 | 要点 |
|---|---|---|---|
| ~~**#6 三维体/切片 数据详情**~~ ✅ 已完成 | 功能补全 | 否 | **已做(提交 b97ea68)**:只读属性对话框(非面板,仿异常详情)`VolumePropertiesDialog`/`SlicePropertiesDialog`,右键「数据详情」按 ddCode 分派。体=参数+统计(值域/网格/测点数/范围,仅 loaded 时显);切片=位姿/参数(不含统计,切面网格仓储不持久化)。`Api3dRepository::volumeInfo` getter + `StoredVolume.pointCount` 持久化;接口/LocalSample 零改。设计见 `specs/2026-06-18-vtk-3d-volume-slice-detail-dialog-design.md`。**已知限制**:切片采样分辨率/值域需渲染层回写仓储才有,当前不展示。 |
| **真实色阶编辑P1P4 ✅ 全期完成2D/3D 共享)** | 功能 | 否 | 编辑器**与数据集视图(2D)共用**,复刻原版四件套(`colorLevel/contourLevel/contourLine/colorEditor.vue` + `colorUtils.js`)。**P1** 主表 `ColorScaleConfigDialog`(层级/颜色 + 新增/删除 + 双击改值/改色)。**P2 层级⚙** `ContourLevelDialog`(normal/log/equalArea + 间隔↔层数双向 + 校验) + 纯算法 `ContourLevels`(6 单测) + `interpColor`(mapColors)。**P2 线形⚙** `ContourLineDialog`(线型/线显/线色/标注显/标注色) + `ContourLineConfig`。**P3 颜色⚙** `ColorGradientDialog` + 自绘 `GradientEditWidget`(可拖拽连续渐变) + 预设/反向/整体透明度 → 按层级位置采样回填。**P4** 文件 IO `ColorScaleIO.{hpp,cpp}`(纯函数 `.lvl`/`.clr` 解析生成,4 单测,与原系统互通):主表 导入/导出=`.lvl`,颜色⚙ 导入/导出=`.clr`。**接入**:① 3D 右键「色阶」→ `VtkSceneController::setVolumeColorScale` 重建体素+切片(用 colorScale 含透明度,mock 持久 `volumeScaleCache_`);② 2D `GridDataChartView`「色阶配置」→ 同编辑器 → 色阶 + 线形/标注到 `ContourPlotItem`。设计见 `specs/2026-06-19-vtk-3d-color-scale-editor-design.md`。**已知边界**:模板库(后端)以文件导入导出替代;`RawDataChartView`「色阶配置」仍占位(原始散点无等值线网格);帘面(源剖面)独立色阶不联动。 |
| **收口提 PR 合 main** | 流程 | 否 | 分支已积大量提交。`git diff main...HEAD` 起草摘要+测试计划,`-u` 推送。注意勿纳未跟踪文件。 |
| **三级树 对象→三维体→切片** | 结构打磨 | 否 | `Column3DAnalysis` 体目前是顶层,缺"对象"根层(R 结构)。 |
| **坐标轴 O点/字体弹框** | 打磨 | 否 | main.cpp 内 stub(TODO P4)落实。 |
| **真实后端对接** | 切真实 | **是** | 三维体/切片端点未就绪,现全 mock(`Api3dRepository` 内存)。端点就绪后只换 `I3dSceneRepository` 实现,接口不动。异常端点已挖到(§4 头),但其挂载目标(三维体)仍 mock故异常也整链 mock。 |
## 5. 相关文档
- **`docs/superpowers/specs/2026-06-17-vtk-3d-volume-slice-anomaly-design.md`** ← 下一阶段主依据。
- `docs/questions/2026-06-16-反演剖面竖向字段(y-z-elevation)语义待确认.md` ← 已解y=高程z=+y 与原版一致;跨数据集 y 不一致是数据层问题(原版同样存在),非客户端 bug。
- `docs/questions/2026-06-17-3D地球改造-现状与约束评估.md` ← 已决:维持局部平面方案,不做真 3D 地球opus 评审:球面=根本性重构)。
- 旧 spec/plans`2026-06-15-vtk-3d-*`、`three-column-refactor*`)为历史,留档。
## 6. 关键铁律 / 坑(务必遵守)
- **构建**`build.bat rebuild` 会**自动启动 app**(后台命令不返回);编译验证用 **`build.bat app`**。Claude 无法 GUI 验证 VTK 渲染。
- **不能靠猜**:渲染/裁剪类问题用**日志取证**`%LOCALAPPDATA%\Geomative\Geopro3\logs\geopro_YYYYMMDD.log`,含 `[basemap]`/`[view]` 的 qInfo/qWarning或读真实数据/原版源码。本会话多次因臆测被用户纠正——**贴源码/日志,别凭印象**。
- **勿动未跟踪文件**(见顶部);**勿用 `git add -A`**(会误纳)。逐个文件 `git add`
- **API 凭证不得提交**(探测脚本用完即删)。
- 原版 web 源码 `D:\Git\lanbingtech\commercial-admin` 是复刻权威;需求 xlsx 用 `python openpyxl` 读到 UTF-8 临时文件再看(控制台中文乱码)。
- 内嵌 token天地图 tk + Mapbox pk公开客户端 token同原版可提交
- 全部回复中文。
## 7. 代码地图(关键文件)
- `src/app/TileBasemap.{hpp,cpp}` — 底图+地形(四叉树/剔除/限流/缓存/动态范围/半透明/合并渲染)。
- `src/app/VtkSceneView.{hpp,cpp}` — I3dSceneView 实现clear/addCurtain(dsId)/addVolume(dsId)/removeDataset/render/renderIncremental/computeDataBounds/dataHorizontalRadius近裁剪容差onCameraChanged/onFrameReanchored 回调。
- `src/controller/VtkSceneController.{hpp,cpp}` — 增量渲染编排setCheckedDatasets diff、addDatasetAsync、fitOnArrival
- `src/render/actors/CurtainActor.cpp` — 帘面Z=+g.y 真实高程)。
- `src/render/interact/{SliceTool,InteractionManager,SlicePlaneMath}.*` — 切片交互。
- `src/render/{VoxelFromScatters,actors/VoxelActor}.*` + `src/core/algo/IdwInterpolator.*` — 体素插值/绘制(三维体复用)。
- `src/data/repo/I3dSceneRepository.hpp` — 接口loadVolume/createSlice/saveSlice/deleteSlice/loadAnomalyTree/saveAnomaly/.../loadTaskRecords
- `src/data/repo/LocalSample3dRepository.cpp`(内存 mock 参考实现)、`src/data/api/Api3dRepository.cpp`(真实路径,多为 stub `kNotReady`,待按设计文档实现)。
- `src/app/panels/columns/{Column3DDataset,Column2DDataset,Column3DAnalysis,ColumnDrawer}.*` — 三栏 UI信号定义全、main.cpp 未全接)。
- `src/app/main.cpp` — 装配/接线(搜 `basemap`/`colAnalysis`/`onCameraChanged`/`kVerticalExaggeration`)。
- `src/data/dto/DatasetChartDto.cpp``parseInversionGrid`x/y/v/lat/lon**未解析 elevation/alt**)。