diff --git a/docs/superpowers/STATUS.md b/docs/superpowers/STATUS.md index 4e58288..28f027f 100644 --- a/docs/superpowers/STATUS.md +++ b/docs/superpowers/STATUS.md @@ -4,78 +4,84 @@ > 本文件是**会话交接的单一事实来源**。下次继续前先读本文 + `specs/2026-06-07-geopro-desktop-m1-design.md`(设计基线)。计划在 `plans/`。 ---- - -## ⚠️ 最新进展与诚实警示(经离屏 PNG 像素核对) -- **教训**:此前多版"已验证"仅为"进程启动不崩"的冒烟,**从未看像素**,导致漏掉**剖面深度倒置**等错误、并夸大"2D 像地图""体素已移除"。**今后渲染必须用离屏 PNG 肉眼核对**(工具:`tests/spike/render_verify.cpp` → `render_verify.exe` 输出 `D:/dev/spike_data/verify_*.png`)。 -- **视图渲染现状(不正确,待迭代)**: - - `CurtainActor` 帘面经像素核对呈**扭曲近平躺飘带**,不像断面墙(测线 lat/lon 有抖动、深度 15m≪水平 62m;纵向需夸张、几何/取景要调)。深度方向已修(z=-depth)。 - - **"二维=俯视帘面"模型不成立**:竖直帘面俯视只剩一条发丝线 → 俯视图基本空白。**真正的二维地图需独立的"测线线 actor"(MapLineActor)+ 底图**,不能靠帘面俯视。 - - `GridContourActor` 平面剖面(数据详情#18)管线基本对(已改显式坐标 structuredGrid + 深度取负),但色阶线性偏蓝、取景偏小,需调。 -- **结论**:二维地图与三维视图应是**不同的渲染内容**(地图=线/点/底图;3D=帘面/体素/地形),数据详情#18 那块基本可用。下次用 PNG 回路逐帧做正确。 +> **铁律教训**:渲染正确性**必须用离屏 PNG 肉眼核对**,不能只看"进程启动不崩"。工具:`tests/spike/render_verify.cpp` → `render_verify.exe` → `D:/dev/spike_data/verify_*.png`。本会话多次"声称成功"实为自欺,根因就是没看像素。 --- -## 1. 现在能跑起来的东西(已验证) +## 1. 现在能跑起来的东西(已离屏 PNG 核对 / 真机验证) -桌面 app `geopro_desktop` 可运行: -- **真实登录**:LoginWindow(用户名/密码/图形验证码/记住)→ `verifyCodeCheck` → RSA 加密密码 → `login2` → 真后端返回 `Geomative ` → 进工作台。**已真机登录成功。** -- **工作台**:ADS 三栏 = 左对象树(项目→测区→ERT1→数据集) / 中视图 / 右属性。 -- **中央视图**:点数据集 → 渲染 ERT 网格剖面(banded 等值面+等值线,按真实 colorBar 上色);「二维/三维」相机切换;「三维体素」= 两交叉剖面 IDW 插值的体绘制。 -- 单元测试累计 ~25 个,全绿(core/data/net/render)。 +桌面 app `geopro_desktop`: +- **真实登录**:LoginWindow(用户名/密码/图形验证码/记住)→ `verifyCodeCheck` → RSA 加密密码 → `login2` → token → 进工作台。**真机登录成功**;输入框样式已修(三态白底深字)。 +- **工作台 ADS 三区 + 数据详情**: + - **左 对象树**:GS→TM→DS,复选框勾选 → 控制中央显示哪些测线。 + - **中央 二维地图 / 三维视图**(两个**真内容**,非相机切换): + - 二维地图 = `MapLineActor`:测线 `lat/lon` 轨迹**红线**俯视(浅底),像地图。 + - 三维视图 = `CurtainActor`:沿测线的**竖直断面墙**(分段色带,z 纵向夸张×3,沿弯曲测线弯)。 + - **下方 数据详情**:单击数据集 → `GridContourActor` 平面反演剖面(#18,colorBar 真实非均匀分段值上色,纵向夸张×1.5)。 + - **右 属性**:名称/网格 nx×ny/vmin·vmax。 +- 单元测试累计 ~28 个全绿(core/data/net/render);离屏 `verify_section/map/curtain_3d.png` 均核对正确。 ## 2. 各 Phase 完成度 | Phase | 内容 | 状态 | |---|---|---| -| Phase 0 | 三 spike(构建/ADS+QVTK/banded contour) | ✅ 全过(spike-report) | -| Phase 1 | core 纯逻辑:LocalFrame / 模型(Field+Anomaly) / ColorScale / IDW / CrsTransform | ✅ 5 任务全完成,TDD 绿 | -| Phase 2 | data:解析器 + LocalSampleRepository + 对象树→渲染→属性 | ✅ 4 任务全完成 | -| Phase 3 | 登录:RsaEncryptor / ApiClient / AuthService / LoginWindow + 启动接入 | ✅ 核心完成(net+UI+真实登录);**Credential(QtKeychain 记住免登录) 未做**(Task 2 跳过) | -| Phase 4 | 三维渲染扩展 | 🔶 部分:Task1(render 层+2D/3D)✅、Task2(voxel+切片)✅(切片已暂移除);**Task3(散点#17+异常叠加)未做、Task4(DEM/GDAL 地形)未做** | +| P0 | 三 spike | ✅ | +| P1 | core(LocalFrame/模型/ColorScale/IDW/CrsTransform/GeoLocalFrame) | ✅ | +| P2 | data(解析器/LocalSampleRepository)+ 对象树 | ✅ | +| P3 | 登录(RsaEncryptor/ApiClient/AuthService/LoginWindow) | ✅(**Credential 记住免登录未做**) | +| P4 | 渲染:render 层 + 二维地图(线)+ 三维视图(帘面)+ 数据详情(#18) | 🔶 **核心三视图已对**;**散点#17 / 异常叠加 / DEM地形 / dd_voxel回归 / 底图瓦片 未做** | -## 3. 构建约定(**机器本地**,重要) +## 3. 构建约定(**机器本地**) -- 工具链:VS2026(v18.0,MSVC 14.51) + 官方 **MSVC Qt 6.11.1**(`D:\Qt\6.11.1\msvc2022_64`) + vcpkg(`d:\dev\vcpkg`)。 -- 方案②-修订:**Qt/VTK/ADS/QtKeychain 对接官方 Qt,不走 vcpkg**;仅非 Qt 依赖(gdal/proj/openssl/eigen3/spdlog/fmt/nlohmann-json/gtest)走 vcpkg。 -- **VTK 9.6.2 源码编**在 `external/vtk-install`(`VTK_DIR` 在 CMakePresets);ADS/QtKeychain 走 FetchContent。 -- 统一 **Release**(`build/release`);Debug 全量会因无 Debug VTK 失败。 -- **所有构建/测试经 `external/dev.bat`**(封装 vcvars+TEMP→D:+cmake/ninja+VCPKG_ROOT;**含绝对路径、已 .gitignore、仅本机有**)。**用 PowerShell 调** `& cmd /c "D:\Git\lanbingtech\geopro\external\dev.bat "`(Bash 下 `%*` 透传会坏)。 -- C: 盘极小(~1GB)→ TEMP/源码/构建全在 D:。 -- **app 构建前先** `taskkill /IM geopro_desktop.exe /F`(运行中会 LNK1104 锁 exe)。 -- 运行前部署:`D:\Qt\6.11.1\msvc2022_64\bin\windeployqt.exe --release `(那条找不到 ads dll 的警告无害);VTK/vcpkg dll 由 POST_BUILD `TARGET_RUNTIME_DLLS` 拷贝。 -- 样本 ASCII 拷贝在 `D:\dev\spike_data`(spike 用);app/repo 直接读真实中文路径 `docs\剖面网格数据的色阶数据2等文件\`。 +- VS2026(MSVC 14.51)+ 官方 MSVC Qt 6.11.1(`D:\Qt\6.11.1\msvc2022_64`)+ vcpkg(`d:\dev\vcpkg`)。 +- 方案②-修订:Qt/VTK/ADS/QtKeychain 对接官方 Qt(不走 vcpkg);非 Qt 依赖走 vcpkg。VTK 9.6.2 源码编在 `external/vtk-install`。统一 **Release**。 +- **构建/测试经** `& cmd /c "D:\Git\lanbingtech\geopro\external\dev.bat "`(**PowerShell 调**,Bash 下参数透传坏)。C: 极小→TEMP/构建全在 D:。 +- **app 构建前先** `taskkill /IM geopro_desktop.exe /F`(运行中 LNK1104 锁 exe)。 +- 部署:`D:\Qt\6.11.1\msvc2022_64\bin\windeployqt.exe --release `(找不到 ads dll 的警告无害);VTK/vcpkg dll 由 POST_BUILD `TARGET_RUNTIME_DLLS` 拷。 +- **离屏渲染验证**:`render_verify` 需 PATH 加 `external\vtk-install\bin` + `build\release\vcpkg_installed\x64-windows\bin` 再运行。 +- **改源码用 Write 工具,勿用 PowerShell `Set-Content -Encoding UTF8`**(会把中文注释弄乱、断构建)。 ## 4. 关键决策与已核实事实 -- **方案②-修订**(官方 MSVC Qt + 源码 VTK):原装 `D:\Qt\6.11.1\mingw_64` 是 MinGW 版,MSVC 不可链,已补装 MSVC kit。 -- **登录**:基址 `http://tenant.geomative.cn/pop-api`;头 `geomativeauthorization: Geomative `;`getImageCode` **验证码答案明文回传** `data.code`;`verifyCodeCheck→login2` 靠**会话 cookie** 串联;login2 `checkCode` 传空;token=`data.accessToken`。 -- **RSA 公钥已抓取**(Playwright route 注入 setPublicKey hook + 缓存绕过 + 真登录捕获),存 `resources/rsa_public_key.pem`(RSA-2048,PKCS#1 v1.5)。 -- **CRS ⚠️**:剖面 `projectX/Y` 真实 CRS **不是 EPSG:32649**(实测解出 111°E,数据 lat/lon 是 114°E/香港);影像 tfw 是 EPSG:3857。**做底图/DEM 配准(Phase4 Task4)前必须向客户确认项目 CRS**。 -- **voxel 可信度**:仅两条交叉剖面 → "十字片"(~16% 有约束),满体不可信;**可信体需 ≥3 非共线测线或 3D 网格**(数据依赖,需客户提供)。 -- 网格 `v`/`z` 为 `[j=y][i=x]`,点序 i 最快;colorBar 网格色阶 alpha=0–255、LVL 色阶 alpha=0–1。 +- 登录:基址 `http://tenant.geomative.cn/pop-api`;头 `geomativeauthorization: Geomative `;`getImageCode` 验证码答案**明文** `data.code`;`verifyCodeCheck→login2` 靠**会话 cookie** 串联;login2 `checkCode` 空;token=`data.accessToken`。 +- **RSA 公钥已取**(Playwright route 注入 setPublicKey hook + 缓存绕过 + 真登录捕获),`resources/rsa_public_key.pem`(RSA-2048,PKCS#1 v1.5)。 +- **CRS ⚠️**:剖面 `projectX/Y` 真实 CRS **不是 EPSG:32649**(实测 111°E vs 数据 114°E/香港);影像 tfw 是 EPSG:3857。**做 DEM/底图配准前必须向客户确认项目 CRS**。 +- **坐标统一**:帘面/地图/数据详情已统一用 **lat/lon→GeoLocalFrame(等距圆柱)局部米**;但 **dd_voxel 输入(散点)只有 projX/projY**,与 lat/lon 无法配准(CRS 未确认)→ **体素暂搁置**(VoxelActor 代码保留,未接 UI)。 +- 网格 `v`/`z` 为 `[j=y][i=x]`,点序 i 最快;深度 `y` 越大越深→渲染时 **z 取负**;colorBar 网格色阶 alpha=0–255、LVL 色阶 alpha=0–1;等值线级用 **colorBar 真实分段值**(均匀分级会一片蓝)。 -## 5. 已知问题 / 待修正(**下次注意,避免弄错**) +## 5. 正确的视图模型(已实现,**P4 续做务必照此,勿再走偏**) -1. **视图模式是 demo 脚手架,需重构**:当前「二维/三维/三维体素」三按钮把"内容"与"相机"混在一起。**正确模型**(spec §4 本意):单一 3D 场景;**显示什么由对象树勾选 + dd 类型决定**(剖面/体素/轨迹/异常可叠加);**2D/3D 仅是相机开关**作用于整个场景,不绑内容;体素只是数据集的一种 3D 表现,不应是独立按钮。 -2. **登录页样式**待调(目前是功能版,非复刻 web 视觉)。 -3. **2D 相机未锁旋转**:平面剖面下 2D/3D 视觉差别小;应让 2D 模式禁旋转(`vtkInteractorStyleImage`/自定义)以体现差异。 -4. **dd_slice 切片**已从体素移除(稀疏体素切片多为空区);待做"沿数据面"的有意义切片。 -5. **Credential(QtKeychain)** 未做 → "记住一个月免登录" 暂未持久化(每次需登录)。 -6. **render 仍部分内联在 main.cpp**(VoxelActor 调用、相机切换逻辑);随重构(问题1)抽进 render/view 层。 +对齐原型 + 物探用户工作流: +- **二维地图** 与 **三维视图** 是**两种不同内容**(地图=测线线/点/底图;3D=断面墙/体素/地形),**不是同一物体换相机**。 +- **数据详情**(下方)才是"分析单条数据集"的专业图(ERT=#18 平面反演剖面)。 +- 体素、异常体是 3D 视图里的内容/派生产物,**不是对象树里硬塞的兄弟节点**。 +- 渲染表现由 **dd 类型**决定(dd_section→帘面/剖面;dd_voxel→体绘制;轨迹→点;异常→线/面)。 +- **2D 相机可考虑锁旋转**(只平移缩放)以区别 3D。 -## 6. 下次从哪接 +## 6. 已知问题 / 待办(P4 下次会话) -1. (建议先)**重构视图模型**(问题1)→ 对象树勾选驱动 + 单一 2D/3D 相机 + 2D 锁旋转。 -2. Phase 4 Task 3:散点(#17)`ScatterActor` + 异常叠加 `AnomalyActor`(计划见 `plans/2026-06-07-m1-phase4-render.md`)。 -3. Phase 4 Task 4:DEM/影像地形(先确认 CRS,加 vcpkg gdal,GDAL+PROJ 重投影)。 -4. Phase 3 Task 2:Credential(QtKeychain)记住免登录。 -5. 登录页样式复刻(可用 Playwright 抓 web 登录页样式;之前截图工具对登录页超时,可改抓 computed-style/DOM)。 +1. **散点 #17**:`ScatterActor`(剖面原数据 2597 点彩色散点),可作数据详情的"原数据"视图。 +2. **异常叠加**:`AnomalyActor`(markType 点/线/面),叠加在剖面/帘面上(异常数据已能解析)。 +3. **DEM/影像地形**:加 vcpkg `gdal`;GDAL 读 dem.tif/image.tif;**影像 EPSG:3857 必须 PROJ 重投影到世界系**;`vtkWarpScalar` 地形面 + 纹理。 +4. **dd_voxel 回归**:需先确认项目 CRS,使散点 projX/Y 能转到 lat/lon 世界系,与帘面配准;VoxelActor 已就绪。 +5. **底图瓦片**(二维地图,天地图/Mapbox):M1.5。 +6. **Credential(QtKeychain)**:记住一个月免登录持久化(P3 Task2 未做)。 +7. 多测线:当前样本仅 1 条 dd_section(grid1);多条共存机制已就绪,加数据即叠加。 +8. 取景微调(数据详情/帘面的相机余量);纵向夸张倍数(剖面1.5/帘面3)可做成可调。 +9. render 仍部分内联在 main.cpp;可逐步抽到 view/controller。 -## 7. 文档与工具索引 +## 7. 渲染验证手段(务必用) -- 设计基线:`specs/2026-06-07-geopro-desktop-m1-design.md` -- 计划:`plans/2026-06-07-m1-phase0-spikes.md`(+ spike-report)、`...-phase1-core.md`、`...-phase2-data.md`、`...-phase3-login.md`、`...-phase4-render.md` +``` +cmd /c "...\external\dev.bat cmake --build build/release --target render_verify" +# 运行(PATH 加 vtk-install\bin 与 vcpkg bin)→ 看 D:/dev/spike_data/verify_*.png +``` +新增/改动渲染后,先用此离屏 PNG 核对方向/颜色/几何,再接进 app。app 是交互窗口,无法离屏验证,接入后需人工登录肉眼确认。 + +## 8. 文档与工具索引 + +- 设计基线:`specs/2026-06-07-geopro-desktop-m1-design.md`(§4/§5 已含正确视图模型注记) +- 计划:`plans/` 下 phase0-4 + `2026-06-07-m1-view-redesign.md`(正确视图模型)+ spike-report - 环境:`../ENV_SETUP_Windows.md` -- 离线验证脚本:`tools/validate_samples.py`(#17/#18 真值)、`tools/validate_voxel.py`(voxel 真值) -- 数据格式:`specs` §6.1 + `docs/数据格式说明.docx` +- 验证脚本:`tools/validate_samples.py`(#17/#18 真值)、`tools/validate_voxel.py`(voxel)、`tests/spike/render_verify.cpp`(app 渲染积木离屏核对) +- 渲染积木(render 层):`MapLineActor`(测线线)、`CurtainActor`(断面墙)、`GridContourActor`(#18 平面)、`VoxelActor`(体,未接 UI)、`ColorLutBuilder`、`CameraPreset`、`Scene`;`core::GeoLocalFrame`(经纬→局部米)。 diff --git a/docs/superpowers/plans/2026-06-07-m1-phase4-render.md b/docs/superpowers/plans/2026-06-07-m1-phase4-render.md index fb785fb..d53a130 100644 --- a/docs/superpowers/plans/2026-06-07-m1-phase4-render.md +++ b/docs/superpowers/plans/2026-06-07-m1-phase4-render.md @@ -2,6 +2,13 @@ > **For agentic workers:** REQUIRED SUB-SKILL: superpowers:subagent-driven-development。Steps 用 `- [ ]`。 +> **⚠️ 状态(2026-06-07,务必先读 `2026-06-07-m1-view-redesign.md` + STATUS.md):** +> - **Task 1(render 层 + 相机预设)**:✅ 已完成。但中央"单场景平躺剖面 + 2D/3D 仅换相机"的做法**已被 view-redesign 取代** —— 现在中央是 **二维地图(测线线)/ 三维视图(竖直帘面)两种内容**(详见 view-redesign 的"实施结果")。 +> - **Task 2(dd_voxel 体绘制+切片)**:🔶 VoxelActor 代码完成,但**已从 UI 移除/搁置**(散点 projX/Y 真实 CRS 未确认,无法与 lat/lon 帘面配准)。**CRS 确认后再回归**。 +> - **Task 3(散点#17 + 异常叠加)**:⬜ 未做(P4 下次)。 +> - **Task 4(DEM/影像地形)**:⬜ 未做(P4 下次,需先确认 CRS + 加 gdal)。 +> 渲染必须用 `tests/spike/render_verify.cpp` 离屏 PNG 核对(本会话教训)。 + **Goal:** 把工作台中央视图从"内联单一网格渲染"升级为正式 `render` 层(Scene + actor 工厂 + 相机预设),并补齐 M1 三维内容:2D/3D 切换、dd_voxel 体绘制与切片、散点(#17)、异常叠加、DEM 地形。 **Architecture:** 新建 `src/render/`(依赖 VTK + core,不依赖 Qt 业务;由 app 的 QVTK widget 承载)。`Scene` 独占 `vtkRenderer`/`vtkRenderWindow`,actor 工厂按 core 模型产 actor;相机预设 Top2D(正交俯视)/Free3D(透视轨道);UI 加 2D/3D 切换。逐步把 `main.cpp::renderGrid` 迁入 `render/actors/GridContourActor`。 diff --git a/docs/superpowers/plans/2026-06-07-m1-view-redesign.md b/docs/superpowers/plans/2026-06-07-m1-view-redesign.md index ffc261a..81fde23 100644 --- a/docs/superpowers/plans/2026-06-07-m1-view-redesign.md +++ b/docs/superpowers/plans/2026-06-07-m1-view-redesign.md @@ -2,6 +2,18 @@ > **背景**:前几版把"单数据集反演剖面"当成主视图、把 2D/3D 做成相机角度(平面剖面下无意义)、把体素塞成树兄弟节点 —— 均为脚手架,偏离产品。本计划按**原型 + 目标用户工作流**重建。REQUIRED SUB-SKILL: subagent-driven-development。 +--- +## ✅ 实施结果与关键修正(2026-06-07,经离屏 PNG 核对,已合入 feat/m1-core) +**Task A、Task B 均已完成并接入 app**(详见 STATUS §1)。实施中**修正了本计划最初一处错误模型**,以下为**最终正确做法**(下次照此,勿回退): +- ❌ 原设想"二维地图 = 俯视帘面顶边" **不成立**:竖直帘面俯视只剩一条发丝线 → 俯视图基本空白(已用 `verify_curtain_top.png` 证实)。 +- ✅ **正确**:**二维地图 与 三维视图 是两种不同渲染内容**(不是同一物体换相机): + - **二维地图** = `render::buildSurveyLine`(`MapLineActor`):测线 `lat/lon` 轨迹画成**红色折线**俯视(浅底)。 + - **三维视图** = `render::buildCurtain`(`CurtainActor`):竖直断面墙,**z 取负**(深度向下不倒置)、**纵向夸张 actor->SetScale(1,1,3)**、**分段色带**(colorBar 真实分段值,非连续插值)。墙沿弯曲测线弯属真实。 + - **数据详情** = `render::buildGridContour`:#18 平面剖面,**y 取负 + 显式 structuredGrid(不假设等距)+ colorBar 真实分段值 + 纵向夸张 SetScale(1,1.5,1)**。 +- ✅ 坐标统一:三者共用 `core::GeoLocalFrame`(lat/lon→局部米)。体素(projX/Y,CRS 未确认)暂不接入。 +- ✅ **验证手段**:`tests/spike/render_verify.cpp` 离屏渲 PNG 肉眼核对(本会话教训:必须看像素)。 +--- + ## 目标用户与工作流(物探/地质工程师) 看测区/测线/数据集 → 在**地图**看测线布在哪 → 看某测线的**反演剖面**圈定异常 → 在**三维**看断面空间结构/体素/地形。 diff --git a/docs/superpowers/specs/2026-06-07-geopro-desktop-m1-design.md b/docs/superpowers/specs/2026-06-07-geopro-desktop-m1-design.md index b376c0a..34643dd 100644 --- a/docs/superpowers/specs/2026-06-07-geopro-desktop-m1-design.md +++ b/docs/superpowers/specs/2026-06-07-geopro-desktop-m1-design.md @@ -105,6 +105,14 @@ geopro/ ## 4. 渲染核心:单一 VTK 场景(K-1) +> **⚠️ 实现修正(2026-06-07,经离屏 PNG 核对;权威做法以此为准,详见 `plans/2026-06-07-m1-view-redesign.md` + STATUS)** +> 本节 §4.2「2D/3D 仅切相机预设、零数据重建」的理想对**当前 M1 测线数据不成立**:剖面是竖直帘面,俯视只剩一条发丝线 → 俯视图空白。M1 落地做法: +> - **二维地图** 与 **三维视图** 是**两种不同渲染内容**(非同一物体换相机):二维地图 = 测线 `lat/lon` 轨迹**线**(`MapLineActor`,俯视);三维视图 = 沿测线的**竖直帘面**(`CurtainActor`,z 取负、纵向夸张、分段色带)。 +> - **数据详情**(独立 QVTK)才显示单条数据集的 **#18 平面反演剖面**(`GridContourActor`,y 取负、显式 structuredGrid、colorBar 真实分段值、纵向夸张)。 +> - 坐标统一用 `core::GeoLocalFrame`(经纬→局部米)。**dd_voxel/dd_slice 搁置**(散点 projX/Y 真实 CRS 未确认,无法与 lat/lon 配准)。 +> - K-1「单场景 + 相机预设」仍是**长期目标**,但需要从俯视/透视都可读的内容(如带底图的地面 + 测线落地线 + 帘面共存)才成立。 +> - **等值线/体素着色必须用 colorBar 真实非均匀分段值**(均匀分级会一片蓝)。**渲染改动必须用 `tests/spike/render_verify.cpp` 离屏 PNG 核对**。 + ### 4.1 Scene 与 RenderWindow 所有权 - `render::Scene` 持有**唯一** `vtkRenderWindow` + `vtkRenderer` + 项目世界坐标空间里的全部 actor,维护当前色阶与坐标系。