Commit Graph

354 Commits

Author SHA1 Message Date
gaozheng 0ac2765fd7 fix(vtk): 四叉树加视锥剔除(只细分视野内瓦片,根治预算被屏幕外块耗尽致粗块/拉近无图/地形丢失)+焦点自校正平面方向 2026-06-17 14:18:04 +08:00
gaozheng ca847f5a77 refactor(vtk): 底图改真正四叉树多级LOD(按屏幕误差细分,近细远粗铺满视野)取代单层级+视野盒+独立粗底,根治倾斜模糊/黑边 2026-06-17 14:03:31 +08:00
gaozheng 63e7874175 fix(vtk): 加请求限流(最多8并发,治瓦片暴发饱和单域名致加载不进/卡死)+精细优先于粗底排队 2026-06-17 13:47:29 +08:00
gaozheng b5bab42825 fix(vtk): 加远处粗底图层(z13~34km,随地形起伏,持久不purge)填到天边治倾斜露黑边;基准高程base/detail共用保连续 2026-06-17 12:20:24 +08:00
gaozheng 52f7a7d5e8 feat(vtk): 底图按相机可视范围覆盖(视锥交z=0,治旋转黑边,带上限+回退)+影像/DEM缓存跨隐藏-重选复用(治重选慢) 2026-06-17 12:10:01 +08:00
gaozheng a4866de68c fix(vtk): 底图覆盖半径3->4治近距旋转黑边; 纹理加mipmap+各向异性16x+edgeClamp治潜在糊/接缝渗色 2026-06-17 11:47:03 +08:00
gaozheng 5f27e59685 perf(vtk): DEM源换Mapbox terrain-RGB(原版web同款,全球CDN比AWS Terrarium快)+对应解码公式 2026-06-17 11:15:45 +08:00
gaozheng 23ed390faf fix(vtk): 底图瓦片SetUseBounds(false)-不参与包围盒/相机取景,修复勾第二个ds后坐标轴被底图撑到公里级 2026-06-17 11:05:16 +08:00
gaozheng d27ef37a24 feat(vtk): VTK全屏进入时展开左侧三栏抽屉(drawer本在vtkDock内,确保可见) 2026-06-17 10:49:17 +08:00
gaozheng ad3310b5bb feat(vtk): 默认天地图底图(下拉默认项)+frame重锚后在数据位置加载(onFrameReanchored,免启动拉无关瓦片) 2026-06-17 10:49:17 +08:00
gaozheng c03dc35469 feat(vtk): 勾选/取消增量渲染-按ds跟踪图元,diff增删不全量重建;clear保留底图;增量不重置相机(全量/首批才取景) 2026-06-17 10:49:06 +08:00
gaozheng d99e5c61f4 fix(vtk): 消除地形先平面后逐块形变-改DEM到位直接铺起伏块(拉不到才降级平面)+DEM缓存(同祖先块复用)减少逐块卡顿 2026-06-17 10:15:53 +08:00
gaozheng 33e9949623 fix(vtk): 地形不出根因-看小测区LOD选z16-18>DEM上限15致fetchTerrain静默退出;改取祖先DEM瓦片按经纬采样+诊断日志 2026-06-17 10:06:43 +08:00
gaozheng 67f767d787 fix(vtk): DEM瓦片改https(S3对http返回403,实测)+失败打日志便于诊断SSL 2026-06-17 09:56:12 +08:00
gaozheng ef8a9da254 feat(vtk): 底图地面起伏-AWS Terrarium DEM瓦片位移网格+卫星贴图(平面先铺,DEM到位换起伏,拉不到则降级平面) 2026-06-17 09:47:16 +08:00
gaozheng 29ea44560d fix(vtk): 底图LOD消除缩放空白闪烁(延迟清理旧层,落地后再删)+按层级Z偏移防共面z-fighting 2026-06-17 08:54:20 +08:00
gaozheng aaf150ca2e feat(vtk): 底图LOD-按相机视距自动选瓦片层级+覆盖可视范围+增量增删(交互结束触发) 2026-06-17 08:19:04 +08:00
gaozheng 11349e533c feat(vtk): 底图(B方案)天地图改卫星影像img层(局部卫星地面,对齐原版观感) 2026-06-17 08:02:15 +08:00
gaozheng 8fceb6c1f3 fix(vtk): 二维数据集栏「地图」下拉默认隐藏(选天地图即触发显示) 2026-06-16 22:05:37 +08:00
gaozheng a588b651a6 feat(vtk): 天地图底图瓦片层 TileBasemap(③:复用WMTS token,经同一frame配准,col2D地图开关) 2026-06-16 22:01:57 +08:00
gaozheng c06f9ea0f8 refactor(vtk): GeoLocalFrame 就地 reanchor + 帘面重锚改就地(共享 frame 一致,供底图等同源对齐) 2026-06-16 22:01:57 +08:00
gaozheng 8684e52939 feat(vtk): 底图瓦片坐标数学 TileMath(EPSG:3857 经纬↔z/x/y+瓦片边界)+单测(P5基石) 2026-06-16 21:29:59 +08:00
gaozheng fe04bb1266 feat(vtk): 帘面按首个真实剖面 lat/lon 重锚 GeoLocalFrame 原点(②)
默认原点取自样本、可能离真实数据很远→局部坐标巨大、轴刻度无意义。每次 clear 后首个带经纬剖面
到达时把原点重锚到其 lat/lon 中心:坐标从0附近起、轴刻度有意义,同一选择内多剖面共用→相互地理配准。
无经纬剖面是平面、不受影响。
2026-06-16 21:00:20 +08:00
gaozheng b2740898f6 feat(vtk): parseInversionGrid 解析 lat/lon,弯曲测线渲染为曲面帘面
之前丢弃经纬度→所有剖面退化成 y=0 平面。解析后 CurtainActor 经 GeoLocalFrame 按真实测线摆位:
37/136 弯曲测线→曲面帘面,直线/无geo→平面(正确)。
2026-06-16 20:41:14 +08:00
gaozheng 37b433208e fix(vtk): 帘面消隐无数据(NaN)格,根治真实反演剖面渲染崩溃(0xc0000005)
真实反演 v 矩阵大量 null→Grid 存 NaN→vtkBandedPolyDataContourFilter 裁剪运算崩(经真实API数据+崩溃栈定位)。
消隐含 NaN 的点(ghost)使其不入表面/色带滤镜+标量填0兜底;顺带清洗色带等值线值(去非有限/去重)。保留色带功能。
2026-06-16 20:41:13 +08:00
gaozheng 5d1cf07882 fix(vtk): 抽屉折叠按钮 ◀▶ 文字改 SVG chevron 图标(根因:YaHei缺三角符→DirectWrite字体回退崩);回退GDI临时方案 2026-06-16 18:59:44 +08:00
gaozheng 5fe1c298d2 fix(vtk): 改用 GDI 字体引擎绕开 DirectWrite 字体回退崩溃(勾选数据集渲染时 QPushButton sizeHint 触发,见crash dump) 2026-06-16 18:48:29 +08:00
gaozheng e34abd271f feat(vtk): 注入 Api3dRepository 渲染真实 ERT 帘面+删样本桥(勾选真实ds→真实数据)(①.4) 2026-06-16 18:38:30 +08:00
gaozheng 2934bacd34 refactor(vtk): 帘面渲染改异步走 loadSection(QPointer+generation守护,对齐volume路径)(①.3) 2026-06-16 18:29:45 +08:00
gaozheng 2d155c864c feat(vtk): Api3dRepository(loadSection复用真实ERT反演端点;其余后端未就绪暂stub)(①.2) 2026-06-16 18:25:43 +08:00
gaozheng 744b55c1b6 feat(vtk): I3dSceneRepository 加异步 loadSection(帘面Grid+色阶)+LocalSample样本实现(①.1) 2026-06-16 18:18:38 +08:00
gaozheng 77f1b5543e feat(vtk): I3dSceneRepository 补齐切片/异常/任务接口设计(spec §6.3-6.5)+LocalSample内存态stub 2026-06-16 18:11:21 +08:00
gaozheng 624cdcbb2e fix(vtk): 本阶段勾选3D数据集渲染样本帘面(LocalSample仅样本;Api3dRepository就绪后改真id) 2026-06-16 17:51:07 +08:00
gaozheng 575529e5a0 fix(vtk): 数据集卡片代理支持复选框(可勾选项画框+点击切换)+折叠按钮加图标样式 2026-06-16 17:34:32 +08:00
gaozheng 5e15941cd2 fix(vtk): 修审查问题(H1 setDatasets信号风暴/H2异步陈旧批次竞态/I1全屏按钮互斥) 2026-06-16 17:08:45 +08:00
gaozheng 24d88530af feat(vtk): 三栏数据集列表按维度过滤数据驱动(替换grid1假实现) 2026-06-16 16:46:42 +08:00
gaozheng 2179f149b7 feat(vtk): dockState bump v3 + VTK视图/数据详情 全屏按钮(隐藏其余dock) 2026-06-16 16:17:59 +08:00
gaozheng 5e57d462c8 refactor(vtk): 删三浮层+分段切换,改挂三栏抽屉,接信号,中央改名VTK视图 2026-06-16 15:49:35 +08:00
gaozheng d81494fd5e feat(vtk): ColumnDrawer 抽屉容器(三tab+折叠) 2026-06-16 15:33:39 +08:00
gaozheng 5f19a0c0db feat(vtk): 三维分析栏 widget(对象→三维体→切片树+两套右键菜单) 2026-06-16 15:30:01 +08:00
gaozheng b6143a0cb6 fix(vtk): Column2DDataset 自定义Z整行隐藏(setRowVisible,非自定义不留孤标签) 2026-06-16 15:26:46 +08:00
gaozheng efc09a5877 feat(vtk): 二维数据集栏 widget(地图/2D视图+自定义Z输入+2D列表) 2026-06-16 15:23:25 +08:00
gaozheng 45662ff897 style(vtk): Column3DDataset 中文/×改直写字面量(去掉多余十六进制转义,对齐代码库惯例) 2026-06-16 15:20:22 +08:00
gaozheng 97d1e70099 feat(vtk): 三维数据集栏 widget(4工具条栏位+3D数据集列表,只发信号) 2026-06-16 15:16:53 +08:00
gaozheng 3f24ad81e3 feat(vtk): 维度过滤纯函数 splitByDimension + 单测 2026-06-16 15:11:07 +08:00
gaozheng 529ffc023c feat(vtk): 加 Glyph::Fullscreen 图标(三栏重构全屏按钮用) 2026-06-16 15:03:54 +08:00
gaozheng 07f2f25b58 fix(vtk): 选中切片边框改亮青(0,0.95,1)+加粗, 未选暗灰, 拉开对比 2026-06-16 11:38:53 +08:00
gaozheng 5809b88a44 fix(vtk): D39 改为自定义 Rotate 绕支点增量旋转(真不跳)
前法错: 设焦点=切片中心会把相机位置挪走(透视视差)→画面平移=跳; 诊断只验了视向、漏看位置。
正确: 按下完全不动相机(不跳); 重写 Rotate(): 有选中物时, 用 T(c)R(up)R(right)T(-c) 把
相机 position/focal/up 绕选中切片中心 c 增量旋转→c 在世界/屏幕都不动、场景绕它转、无跳。
无选中回退默认绕焦点。ctest 221/221
2026-06-16 11:33:03 +08:00
gaozheng 8d94247dd9 feat(vtk): D39 以选中三维体/切片为中心旋转视图(不跳)
正确做法: 点击只选中(不动相机)→切换点选不跳; 在'按下开始拖动'那刻才把焦点设到
选中切片中心(焦点+位置同步补偿 delta→视向/距离不变、画面不跳), 之后默认 TrackballCamera
即绕该中心旋转。PickInteractorStyle 加 getRotateCenter 回调, InteractionManager 提供
选中切片中心; 无选中则绕默认焦点。ctest 221/221
2026-06-16 11:27:42 +08:00
gaozheng 2e5cc4e6db chore(vtk): 移除未用的 InteractionManager::faceSelected(正视按钮已删, 双击走 faceSlice) 2026-06-16 11:19:03 +08:00
gaozheng a7edfa5c78 fix(vtk): 轴向切片禁用旋转(G22-24 角度不能再调整),仅任意切片可转(F25)
上一版让所有切片都能拖边缘旋转,违反 G22-24(上下/前后/左右角度不能再调整)。
修: 轴向切片 SetMarginSizeX/Y(0) 去掉旋转抓取区→只能移动不能转;
任意切片(Oblique)保留默认 margin→可拖边缘旋转(F25)。ctest 221/221
2026-06-16 11:14:05 +08:00
gaozheng f3a1ba9f99 fix(vtk): 恢复原型切片可拖动配置(SLICE_MOTION)+双击正视(去按钮)
据用户指出'原型阶段切片可拖动调整',查 git(f57291a)原型配置:
  SetLeftButtonAction(VTK_SLICE_MOTION_ACTION) + SetMiddleButtonAction(VTK_CURSOR_ACTION)
我的 SliceTool 漏了这两行→默认左键是窗位调整(无用)→拖切片面无反应=用户的'不能调'。
- 补回两行: 左键拖动=移动切面; 切面边缘 margins 拖动=旋转角度(F25 任意切片可调)。
- 双击正视(D40)改用 widget StartInteractionEvent 检测(同一切片350ms内两次=双击→正视),
  恢复 spec 的双击交互, 去掉上一版擅自加的'正视'按钮(改了需求, 错)。
- 选中=触碰(onInteract); 滚轮/关闭=选中切片; 相机旋转=空白处拖动。ctest 221/221
2026-06-16 11:07:30 +08:00
gaozheng 87c5cc910e fix(vtk): 恢复任意切片可调(F25)+触碰选中+正视按钮(不再砍功能)
之前用 InteractionOff 砍掉了切片可调(F25),错。改回:
- widget 交互保持开启 → 任意切片可拖动调整角度/位置(F25 恢复); 拖切面=widget 处理。
- 选中改为监听 widget StartInteractionEvent(SliceTool::onInteract → selectByTool):
  触碰某切片即选中+高亮(widget 开交互后独占切面事件,拾取式选中失效,故改观察式)。
- 正视(E54)从双击改为工具条「正视」按钮(faceSelected): 双击会被 widget 抢、QVTK 上本不稳。
- 滚轮推进/关闭 仍作用于选中切片; 相机旋转=空白处拖动(默认 trackball)。
- ctest 221/221
2026-06-16 10:50:05 +08:00
gaozheng 43f8228e49 fix(vtk): 切片单击仅选中+高亮,不动相机(终态) — 切换切片不再跳
据用户实测: '按切片中心移焦点'(eb8cb9e)在切换两切片时仍跳(两次焦点跳动), 且切片中心≈体中心
→ 与默认绕中心旋转视觉等价、价值低。终态: 单击=仅选中+高亮, 拖动=默认 TrackballCamera 绕
场景/体中心旋转(稳定、永不跳)。spec C38 '以体为中心' 由此满足; 切片本身不自转(符合语义)。
2026-06-16 10:34:11 +08:00
gaozheng eb8cb9e7ee fix(vtk): 切片旋转支点用切片中心而非点击点(根因修复,据日志证据)
诊断日志证据: onPicked 改相机后 dir(视向) before==after, 补偿正确、点击瞬间画面不变;
但命中点 world 明显偏离体中心 → 之前以'点击点'为焦点, 拖动绕偏心点旋转→大幅摆动(=用户的'跳')。
根因修复: 旋转焦点设为**切片中心**(slices_[idx]->center(), ≈体中心, spec C38 '以切片为中心'),
焦点+位置同步平移保持画面不变 → 点击不跳、拖动绕切片中心居中旋转、不甩。
未命中切片则不动相机。
2026-06-16 10:26:29 +08:00
gaozheng 8a06014e0b fix(vtk): 切片单击=仅选中(不动相机,去跳)+高亮反馈
- onPicked 去掉改相机焦点/位置(实测仍致点击跳变)→ 单击仅选中命中切片;
  拖动旋转回归默认 TrackballCamera(绕场景中心,不跳)。'以切片为中心旋转'(C38)
  因致跳且预期不清,暂去, 后续用更稳方式再加。
- SliceTool::setSelected: 选中切片边框高亮(亮黄粗线)、其余暗灰; InteractionManager
  在 单击/新增/关闭/双击 后 updateSelectionVisual → 解决'选中无视觉反馈'。
- ctest 221/221
2026-06-16 10:12:20 +08:00
gaozheng ff3ce27978 fix(vtk): 切片 widget InteractionOff —— 修点击选中/双击/绕点旋转全失效
实测根因: vtkImagePlaneWidget 默认消费落在切片面上的左键(窗位/光标), 自定义
PickInteractorStyle 收不到 → 单击选中/双击正视/绕点旋转/滚轮推进选中项 全失效;
滚轮看似只对最后新增切片有效, 实为选中从未改变(addSlice 设的 last)。
关掉 widget 自身交互(Interaction off): 其事件回调提前 return 不设 AbortFlag →
事件穿透到样式; 切片面 actor 可被 cellPicker 拾取 → 选中/双击/旋转恢复。切面移动由滚轮 advance 驱动。
2026-06-16 09:57:34 +08:00
gaozheng 87b90a2022 fix(vtk): P3 切片交互手感修复(用户实测反馈)
- 删左上「视图详情」遗留的禁用「切片」复选框(P1占位,已被P3工具条取代)
- 点击跳变 + 绕点旋转无效: onPicked 焦点与相机位置同步平移同一delta,
  图像不跳、旋转中心移到命中点(原来只改焦点致视图突变)
- 双击正视无效: 弃 vtkRenderHWindowInteractor::GetRepeatCount(QVTK+Win不可靠),
  改 std::chrono 手动判双击(间隔<350ms且位置相近); 避开 vtkTimerLog 依赖
- 选中移除: 随上面拾取修复,单击切片可选中→关闭移除选中项(不再只能倒序)
2026-06-16 09:09:38 +08:00
gaozheng 85d4ff57df feat(vtk): P3 三维分析切片交互(核心) — 轴向/任意切片+滚轮+拾取+正视
interact/ 交互层(README早规划,本期落地):
- SlicePlaneMath: 纯几何(法向/45°/滚轮平移/双击正视相机含竖直兜底/最近切片), 25 单测
- SliceTool: 封装 vtkImagePlaneWidget — 轴向(上下/前后/左右,角度固定)+任意45°(Origin/Pt1/Pt2),
  套色阶LUT, reslice着色(非cutter), close幂等
- PickInteractorStyle: 继承TrackballCamera+vtkCellPicker, 拾取/双击/滚轮回调
- InteractionManager: 活动切片/选中态/滚轮分发/拾取联动/翻转, 体素变更先closeAll再附着
- VtkSceneView 暴露 currentVolumeImage_(含VE) + onVolumeChanged; main.cpp 切片工具条(上下/前后/左右/任意/翻转/关闭)
- ctest 221/221

评审修复:
- H1 vtkTrivialProducer 提为成员(局部变量构造后析构→管线断裂崩溃)
- H2 uninstallStyle 向 interactor 注销 style
- H3 safeRender 统一守 destroying_ 跳过析构期 Render
- M1 advance 刚性平移 origin+point1+point2(只移origin致轴向切面变形)
- M2 closeSelected 选中位就近不跳0; M4 sliceBar 加 BottomLeftAnchor 随resize

范围外(P4): 切片保存/导出/删除为数据集/三维分析树/右键菜单/异常圈定/详情
2026-06-16 08:23:16 +08:00
gaozheng 86e07722e5 fix(ui): P2 工具条去 border-radius,消除原生GL上四角浅色直角
对齐左上「视图详情」浮层做法:悬于 GL 画布的浮层不设圆角(圆角四角露父级浅底),
改直角矩形+不透明底。控件自身圆角(落在不透明frame上)保留。
2026-06-16 07:48:12 +08:00
gaozheng 73deb2b159 fix(ui): P2 三维数据集栏控件深色主题 — 修白底浅字看不清
工具条只设了文字色未设控件背景,下拉/按钮保持默认白底→浅字不可读。
补:QComboBox/QPushButton/QSlider 深色背景+边框+hover/pressed+下拉弹窗配色(canvas/* token)。
2026-06-16 07:45:07 +08:00
gaozheng 3dea339ddc feat(vtk): P2 三维数据集栏 — 坐标轴/比例/快捷视图/Zoom
- CameraPreset 扩 6 向快捷视图(前后左右上下) + zoomBy(透视改视角/正交改parallelScale) + fitView
- AxesActor(新, vtkCubeAxesActor): 显示模式 标准(外缘)/三维立体(静态边+网格线)/不显示;
  刻度 无/米/英尺(×3.28084)/经纬度(GeoLocalFrame反算); 字号12(字体待1.0确认)
- GeoLocalFrame 补 toLatLon 反算(等距圆柱)
- I3dSceneView 扩 setAxes/applyCameraView/zoom/fitView; VtkSceneController 加对应槽
  (坐标轴随场景重建; 快捷视图/zoom 仅改相机不重建)
- main.cpp 三维视图工具条: 坐标轴/刻度下拉(枚举绑itemData)+比例滑块(1-10)+6向钮+Zoom钮, 仅3D显示
- 测试 +24(toLatLon往返/相机6向/坐标轴单位换算/控制器编排), ctest 196/196

评审修复:
- HIGH rebuildAxes 异步路径坐标轴 prop 累积 → 持 currentAxes_ 重建前先移除(幂等)
- MEDIUM combo index 魔数 → itemData/currentData 取枚举值(防项序调整静默错位)

注: 坐标轴标准/立体语义 + 字体 + O点 为合理近似, 待 Geopro 1.0 实地确认精修
2026-06-15 21:54:48 +08:00
gaozheng 53ccdc07b0 fix(vtk): 勾选数据集时隐藏中央引导层,露出 P1 渲染
P1 接了 VtkSceneController 渲染但漏接 emptyState 显隐(main.cpp:368 注释本就要求
'接入真实数据后依是否为空调 setVisible'),不透明引导层盖住渲染。补:勾选有数据→隐藏、
取消→恢复。
2026-06-15 21:17:23 +08:00
gaozheng 0f521c5b24 feat(vtk): P1 复活中央渲染 — VtkSceneController + I3dSceneRepository + Scene加vtkProp
复活被 6241eb3 摘除的中央 VTK 数据驱动渲染:
- Scene 新增 addViewProp(vtkProp*):体绘制 vtkVolume(非 vtkActor)经此进场
- I3dSceneRepository(异步回调契约) + LocalSample3dRepository:dimensionOf 维度映射 /
  loadVolume→VolumeGrid(std::array 去裸数组) / loadTerrainPaths;data 层零 VTK 依赖
- VtkSceneController(QObject) 取代 main.cpp 死掉的 rebuildCentral lambda + 裸 show* 标志:
  勾选数据集/视图模式/图层/比例 → 经仓储取 core::* → I3dSceneView 重建场景;
  QPointer+generation 守异步回调生命周期与新鲜度;inRebuild_ 避免同步路径双 render
- I3dSceneView 抽象解耦编排与 VTK(VtkSceneView 真实现 + 测试 fake)
- 删除被取代的 CentralScene;main.cpp 接线 对象勾选/2D-3D/图层/主题(主题 context 用 sceneCtrl 防悬垂)
- 新增测试 14(Scene/3d-repo/VtkSceneController),ctest 172/172 全绿

构建基建修复(本就潜在缺陷,任何 clean 构建/新人 checkout 都会撞):
- vcpkg.json 加 builtin-baseline:新版 vcpkg manifest 模式必需,否则全新 checkout 无法 configure
- build.bat 修 vswhere(VS2026 预览 -latest 恒空 → -all -prerelease -requires VC.Tools)
  + 括号块内路径变量加引号(防 Program Files (x86) 的 ) 提前闭合)
2026-06-15 21:01:26 +08:00
gaozheng 85e455ae4b feat(workbench): 对象/数据集交互对齐规格 + 属性面板可编辑保存
提交体按 bundle/OpenAPI 源码确证修正(替换早期推断版本):
- 新建/编辑 GS:{gsTypeId,parentId(仅新建),projectId,name,responsiblePersonName,properties}
- 新建/编辑 TM:{tmTypeId,id?,name,properties,projectId,parentId,parentType:"1"}
- 去除误用的 typeId/type/structParentId/structParentConfType

动态表单:
- displayComponentType 全集控件映射(1-11 + 默认步进数字)
- requiredType 语义:1=必填、2=只读禁用、其他=可选
- 顶层固定字段(gsTypeId/tmTypeId/name/responsiblePersonName)

新建对象:
- 单弹框 + 框内类型下拉,选后刷新动态表单(GS/TM 对称)
- 方法类型用全局 project/tmList;GS 类型用 project/gsList
- 父对象按节点类型解析:选 TM 仅新建同级 TM(父=其GS/根);项目根按 GS 处理
- 对象树右键 + 面板「添加+」按钮按节点类型分项

属性面板可编辑保存:
- 对象属性面板可编辑 → PUT gsObject/tmObject
- 数据集属性面板:元字段只读 + 描述可编辑 → updateDsObject
  {dsObjectId,description,attachedParameters:{deltaContent}}

数据集:导入向导(multipart) + 模板导出对话框(templateExport/export)

文档:spec(§B 提交体/§E 源码补全) 与 plan 同步更新
2026-06-15 11:52:41 +08:00
gaozheng 1f0081ee34 feat(workbench): 对象/数据集视图交互 — 右键菜单/筛选/删除 + 动态表单编辑保存与新建TM
Batch1(骨架+读联动+删除+筛选):
- ApiClient 补 putJsonAsync/deleteAsync
- 删除 GS/TM/DS(真实 DELETE + 确认框 + 成功刷新)
- 对象树右键菜单(9项)/数据集右键菜单:属性·异常详情·详情联动接现有面板;显示隐藏/定位等 2D/3D 占位
- 快速筛选器(对象按类型批量勾选/反选;数据集按类型+创建日期客户端过滤)+ 数据集单击 tooltip
- 复选框手势修复:点勾选不再触发"选中"重载(viewport 事件过滤 + 复选框命中判定)

Batch2(动态表单引擎+写操作):
- DynamicFormEditor:getDynamicForm schema 驱动(comp1/4/6/7/8 + 必填校验 + properties 预填)
- ObjectFormDialog:拉真实表单→校验→提交
- 编辑保存 PUT /business/{gs|tm}Object(成功刷新,失败回显后端 msg)
- 新建 TM:queryTmType 选型→空表单→POST(带父 GS 上下文)
- 插件子菜单:列出真实 model/list(启动缓存)

数据层:
- EditableForm/TmTypeOption/ModelInfo DTO + parseEditableForm/parseTmTypes/parseModels
- StructNode.typeId;repo loadEditableForm/queryTmTypes/submitObject/listModels;controller currentProjectId()

注:保存/新建请求体为推断(OpenAPI 未文档化提交 body),待真实提交验证后定版。
docs: plans/2026-06-13-object-dataset-interactions.md, specs/2026-06-13-batch2-object-dataset-dialogs.md
2026-06-13 20:03:30 +08:00
gaozheng 2cf2b6aaa7 feat(dataset-detail): dd_grid 白化数据列表 + 引擎服务端分页(vxe-pager)
⑤ dd_grid 详情:单「列表」页签,序号/x/y 三列(均居中),服务端分页。
按原版(vxe-table)实测复刻:序号列前插、按页偏移自增;total 取 data.total;
分页器对齐 vxe-pager(上一页/页码…/下一页 + 前往N页 + 每页条数 50/100/500/1000 默认50 + 共N条记录)。

引擎新增分页能力(通用,后续分页型详情复用):
- TablePayload 加 pageNo/pageSize(>0 才渲染分页器;0=全量列表,measurement/trajectory 不受影响)
- GridDto.parseGridTable 复用通用 parseGridHeaderTable,前插序号列 + 回填分页态
- 仓储 loadAsync 增 pageNo/pageSize 透传,新增 grid.rows 加载器(端点 dd/ert/grid/rows,默认50条/页)
- 控制器新增 loadTabPaged(保留 3 参 loadTab 以维持 tabNeeded 连接)
- TablePager 分页器组件 + DataTableView 按 pageSize>0 显隐并转发 pageRequested
  → DatasetDetailPage/Panel.tabPageNeeded → Controller.loadTabPaged 反向链路
- GridStrategy(dd_grid 单分页页签) 注册入 main

测试:test_grid_dto(序号偏移/total/分页态/空数据) + grid.rows 分派 + GridStrategy 注册
+ 控制器 loadTabPaged 透传/默认页参;154/154 通过。
ABI 关键头(DetailPayloads.hpp)变更后全量重编 geopro 代码并验 obj 新鲜度。
2026-06-13 17:27:39 +08:00
gaozheng b033dc2a2c feat(dataset-detail): dd_trajectory_data 轨迹详情(地图+列表+高程)
在按类型渲染引擎上落地轨迹三页签,新增 LineProfile + WebMap 两个视图 kind。

- 地图(TrajectoryMapView:QWebEngineView + 本地 MapLibre GL JS 4.7.1):
  WebGL 引擎,天地图栅格 WMTS 底图(街道 vec_w+cva_w / 卫星 img_w+cia_w,token,
  t0-t7 子域,逐层 maxzoom);over-zoom 上采样平滑;街道/卫星图层切换 + 回到当前
  位置定位按钮;实心橙点(#ff8c00 白环)+ 连线 + 起点标;经纬度取自
  trajectory/line?frontCrsCode=EPSG:4326(服务端转 WGS84);runJavaScript 喂点(无 WebChannel)
- 高程(LineChartView:QwtPlot + QwtPlotCurve):X=电极号 #1..#40,Y=高程,
  数据空间预算样条平滑(非 Fitted,避免像素重拟合漂移);hover 用 QwtWidgetOverlay
  画虚线参考线+实心点(叠加层不 replot 主图→曲线零漂移)+ 自定义浮动框(#编号/●高程(m) 值)
- 列表:复用通用 DataTableView + 通用 gridHeaderDisplay→TablePayload 解析(14 列)
- LinePayload/MapPayload(DetailPayloads.hpp 加性);TrajectoryDto;TrajectoryStrategy
  (地图/WebMap+列表/Table+高程/LineProfile);ApiDatasetRepository loaderKey
  traj.map/traj.rows/traj.elev;DetailViewFactory LineProfile/WebMap;main 注册
- 构建:geopro_desktop 链接 Qt6::WebEngineWidgets/WebEngineQuick;main 加
  QtWebEngineQuick::initialize()+AA_ShareOpenGLContexts;CMake 部署 WebEngine 运行时

测试 143→148 全绿。夹具 tests/fixtures/dd/ert-trajectory-{rows,line}.json。
2026-06-13 16:36:28 +08:00
gaozheng bc5613f0d2 feat(dataset-detail): dd_ert_measurement_gr_data 接地电阻柱状图详情
在按类型渲染引擎上新增 Bar 视图 kind。

- 柱状图(BarChartView:QwtPlotBarChart 单系列 / QwtPlotMultiBarChart 分组):
  X=电极点 #1..#40(electrodeId),Y=电阻(欧姆)=p1Rg,单系列 P1 实心 #5470c6
  (任一行 p2Rg 非空时加分组系列 P2);Y 轴标题「电阻(单位:欧姆)」横排左上、
  X 轴标题「电极点」、图例 P1;主题跟随;析构 clearSeries 防悬垂
- 列表:复用通用 DataTableView,固定 7 列(ID/日期/时间/P1 Rg(Ω)/P1状态/
  P2 Rg(Ω)/P2状态)
- BarPayload(DetailPayloads.hpp 加性);GrMeasurementDto(parseGrBar/parseGrTable,
  响应为 JSON 数组,p1/p2 isDouble 守卫);GrMeasurementStrategy(柱状图/Bar+列表/Table);
  ApiDatasetRepository loaderKey gr.bar/gr.rows(同一端点不同解析);
  DetailViewFactory Bar case;main 注册

测试 138→143 全绿。夹具 tests/fixtures/dd/ert-gr-rows.json。
2026-06-13 11:46:47 +08:00
gaozheng a00aeb9a56 feat(dataset-detail): 按类型渲染引擎 + inversion 迁移 + dd_ert_measurement_data 详情
将数据集详情从硬编码 ERT 反演重构为通用「ddCode→页签→视图kind」渲染引擎,
把已验收的 dd_inversion_data 迁入新引擎(渲染零变化),并在引擎上实现
dd_ert_measurement_data(ERT原始数据)详情。

引擎:
- 策略声明页签:IDatasetChartStrategy::tabs()→vector<TabSpec{title,ViewKind,
  loaderKey,lazy}> 取代 hasGridPhase();控制器通用化(datasetOpened/loadTab/
  tabReady),按页签槽位保留 abort-and-replace + 句柄身份比对 + deleteLater 三件套
- 单一异步句柄 DetailLoad/ApiDetailLoad(QVariant 载荷),仓储 loadAsync(loaderKey,
  dsId) 扁平分派;删 ChartLoad/GridLoad/loadChartAsync/loadGridAsync/DatasetLoads.hpp
- 视图 IDetailView{widget,setPayload(QVariant)} + DetailViewFactory 按 ViewKind 实例化;
  载荷 Scatter/Contour/TablePayload(core/model/detail/DetailPayloads.hpp)
- Page 按 TabSpec 建页签 + 通用 lazy;inversion 散点/网格迁入,渲染代码未改

dd_ert_measurement_data(③散点伪剖面 + 列表):
- 散点复用 RawDataChartView/ScatterPlotItem:x=斜距/y=伪深度(负向)/色=视电阻率,
  连续 cauto(含负离群值),colorBar 取自 colorGradation businessCode=R0&type=3(混合
  hex+rgba/AlphaScale::Unit);电极灰菱形(#BEBEBE实心+白描边 size16);A/B/M/N 与电极
  浮动 hover;数据点尺寸对齐原版 12px;色阶底部横向(与反演一致)
- 通用 DataTableView(gridHeaderDisplay/filedList+rowList,均衡等宽列+居中+隐藏/显示
  开关列);MeasurementDto 解析(散点位置数组 + vmap 摊平)
- 工具条视觉 1:1(信息/框选/显示/隐藏/数据过滤/x·y·v·计算方法下拉/色阶配置/生成视电阻
  率/反演运算/另存为);显示隐藏+x/y 下拉轻交互,其余占位

测试 75→138 全绿。Phase0 真实响应夹具 tests/fixtures/dd/*。
2026-06-13 10:51:24 +08:00
gaozheng 10072eb4b3 feat(dataset-detail+app): 数据集树/按根分页 + 暗色主题保真 + 详情图保真 + 桌面日志崩溃捕获
本分支累积的数据集详情与桌面端健壮性工作(多轮迭代,已逐项实测/用户验收),一次性提交。

数据集列表树化 + 按根分页:
- 原版数据列表为 el-table 树(派生数据按 sourceShowParentId 挂源「原始数据」下);
  DsRow 加 parentId,parseDsRows 解析 sourceShowParentId(回退 parentId),
  DatasetListPanel 由 QListWidget 改建 QTreeWidget(卡片委托泛化到 QAbstractItemView)。
- 后端 data/page 按扁平 DS 分页 → 改为客户端按「第一层节点(根)」分页:
  loadRowsAsync 加 pageSize,selectObject 一次取全,新增 emitNextDataRootPage 按根切页(5根/页),
  loadMoreData 改同步切页;main.cpp 加载更多计数改按根。

暗色主题保真(浅色保持与原版 1:1,仅暗色改 token):
- 新增 ChartTheme::applyChartPlotTheme:按 isDarkTheme() 设 QwtPlot 画布/轴字/网格/零线配色,连 ThemeManager::changed 热切换。
- ColorBarWidget、LoadingOverlay 底色/蒙板/文字同步跟随主题。

详情图渲染保真:
- colorBar alpha 标度修复(混合 hex+rgba 格式,rgba alpha 为 0–1,Bit255→Unit)。
- 散点 cauto 归一化(ColorMapService.setDataRange 解耦色阶形状与数据归一化)。
- 散点 hover 提示(ScatterHoverTip,X/Y/值 3 位小数,canvas mouseTracking)。
- 详情页签用数据名命名。

桌面端日志 + 崩溃捕获:
- Logging:滚动日志 + MiniDump 崩溃捕获 + VEH 抛点符号化;main.cpp GuardedApplication::notify 顶层异常护栏。
- 根 CMakeLists Release 产出 PDB(/Zi /DEBUG);ColorMapService NaN/Inf 守卫。

测试 116→122 全绿(+ParseDsRowsParentIdForTree / DataPaginatesByRootNodeNotFlatCount / 散点/colormap 回归)。
2026-06-12 19:00:32 +08:00
gaozheng 5f00cdce7a refactor(net+data+app): ProjectListDialog 异步化 + 删同步 IProjectRepository/RepoResult/ApiClient.get|postJson(清除过渡技术债,全 App 网络层异步)
- ProjectListDialog 迁到 IAsyncProjectRepository:fillTypeFilter/query 改 abort-and-replace + 身份比对 + done/failed 双分支;析构 abort 在飞请求(退出契约)
- main.cpp buildWorkbench 形参改 IAsyncProjectRepository&
- ApiProjectRepository 删 public IProjectRepository 与 9 个同步方法实现;删不再用的 ok()/errorOf() helper
- 删除 src/data/repo/IProjectRepository.hpp(含 RepoResult,已无消费者)
- ApiClient 删同步 get/postJson + Impl::await + <QEventLoop>/ApiResponseParse.hpp include
2026-06-12 09:31:54 +08:00
gaozheng 6b4267d78a harden(net+app): 登录句柄终态置 aborted_ + connect 用成员 QPointer + ApiChain 首步同步契约注释 + LoginLoad step 抛异常离线测 + 注释更正(Part B 评审 I-1/I-2/I-3/M-2/M-4) 2026-06-12 09:11:54 +08:00
gaozheng d1c1bf96b1 feat(net+app): AuthService/登录异步化(CaptchaLoad/LoginLoad+ApiChain, LoginWindow 不冻可取消, test_auth 异步化)
B1: AuthService 改异步——新增 net 层句柄 CaptchaLoad/LoginLoad(AuthLoads.{hpp,cpp}),
    fetchCaptchaAsync 返回 CaptchaLoad;loginAsync 用 ApiChain 编排 verifyCodeCheck->RSA->login2
    返回 LoginLoad。删同步 fetchCaptcha/login/LoginResult。句柄遵 spec §5.0(aborted_ 守卫/deleteLater)。
B2: LoginWindow 异步化——refreshCaptcha/attemptLogin 连句柄信号(身份比对),删 repaint() hack,
    析构 abort 在飞句柄(退出契约)。公共 API(token/remember/exec)不变。
B4: test_auth.cpp 改 QSignalSpy::wait 异步等待(仍 live)。
新增离线句柄单测 test_auth_loads.cpp(CaptchaLoad/LoginLoad done/failed/abort)。
[B3 删 ApiClient 同步 get/postJson 因 ProjectListDialog/ApiProjectRepository 仍同步而 BLOCKED,故保留]
2026-06-12 09:01:07 +08:00
gaozheng 4ca5893800 harden(controller): ChartStrategyRegistry 显式禁拷贝/保留移动(保护 find() 裸指针,评审 I-1) 2026-06-12 08:20:20 +08:00
gaozheng 0cb0ed8aa0 refactor(detail): 控制器按 ddCode 走 ChartStrategyRegistry 分派, 未注册优雅降级 (替代硬编码 dd_inversion_data)
- IDatasetChartStrategy + ChartStrategyRegistry 下移到控制器层 (src/controller, namespace geopro::controller), 删 app 层那份, 修层级倒置 (控制器不得依赖 app)
- 接口加 hasGridPhase(); ErtInversionStrategy 留 app 层, 改继承 controller 接口, hasGridPhase()=true
- DatasetDetailController 构造注入 ChartStrategyRegistry&; openDataset 用 registry.supports 降级; loadGridData 用 strategy->hasGridPhase 判定
- main.cpp 构造 registry 注册 ErtInversionStrategy 并注入 (registry 先于 detailCtrl 声明)
- 测试: registry 加 hasGridPhase 断言; 控制器加空注册表降级 + 无网格阶段跳过网格加载用例; 全量 109/109 绿 (基线 106)
2026-06-12 08:14:19 +08:00
gaozheng 62352395ba harden(controller+net): setCheckedTms 去重 + loadMore 失败回滚页号 + 非拥有所有权注释更正 + ApiChain 待用注释 + selectObject 部分失败测试(Part A 评审 I-2/I-3/I-4/M-1/M-4) 2026-06-12 08:04:08 +08:00
gaozheng b097fa6e56 feat(controller): WorkbenchNavController 异步化(NavRequest续延+并发计数, abort-and-replace+身份比对, 删busy_/drain/BusyGuard, busyChanged=在飞存在性) + 单测
- 控制器依赖切换到 IAsyncProjectRepository(异步句柄)
- 删除 busy_/BusyGuard/drainPendingCheckedTms/checkedTmsPending_/pendingCheckedTms_/friend struct BusyGuard
- start/switchWorkspace 用 NavRequest 续延依赖链(startStepReq_ 跟踪当前在飞级)
- switchProject/loadMore*/selectDataset 单请求 + abort-and-replace + 身份比对
- selectObject 三并发(data/file/detail), 各自身份比对独立 emit
- setCheckedTms 并发拉取未命中缓存项, 计数汇聚; 新勾选 abort 旧批(以最后一次为准); tmExceptionCache_ 命中不发请求
- busyChanged 由 anyInflight() 驱动(emitBusyIfChanged 去抖, 值变才发)
- 析构 abortAll() 退出契约
- 对外信号面零改动, main.cpp 接线据引用绑定自动切换(无需改)
- 新增 9 个控制器单测(依赖链/并发/abort-and-replace/busyChanged/缓存语义/回灌防护/失败路径)
- 测试 96 -> 105 全绿
2026-06-12 07:51:35 +08:00
gaozheng 05f0bf3d4f feat(data): ApiProjectRepository 实现 IAsyncProjectRepository(9方法,Async后缀,薄封装,新旧并存) 2026-06-12 07:42:00 +08:00
gaozheng 2ee1ccdb0f feat(data): IAsyncProjectRepository 异步导航仓储抽象(薄封装,返回NavRequest,Async后缀) 2026-06-12 07:39:41 +08:00
gaozheng 4beb7a9523 feat(data): NavRequest 单请求异步句柄(QVariant payload, abort闸门) + 元类型声明 + 离线单测 2026-06-12 07:38:59 +08:00
gaozheng 22a7f2339e feat(net): ApiChain 顺序依赖链原语(fail-fast+abort闸门+工厂可抛) + 离线单测 2026-06-12 07:36:50 +08:00
gaozheng 8b3bc50f58 harden(app): setData 重置遮罩 + loadFailed context=detailPanel(防野指针) + LoadingOverlay Q_ASSERT(parent) + 删未用 include(评审 I-1/I-2/M-3/4/5) 2026-06-11 21:06:35 +08:00
gaozheng dc9506c260 feat(app): 网格懒加载「加载中」遮罩(LoadingOverlay) 接 loadStarted/隐藏于就绪或失败 2026-06-11 20:59:32 +08:00
gaozheng eaa3770f93 feat(app): qRegisterMetaType<ApiResponse> 注册(异步信号元类型,防御性) 2026-06-11 20:53:58 +08:00
gaozheng 350f46060d harden(controller): 析构 abort 在飞句柄(退出契约 spec §7) + Grid 路径回灌/失败用例对称覆盖(评审 I-1/M-3/M-4) 2026-06-11 20:51:45 +08:00
gaozheng e57985c057 feat(data+controller): ApiDatasetRepository 改异步 + DatasetDetailController abort-and-replace+句柄身份比对+loadStarted(移除 busy_/catch)+ 回灌防护测试 2026-06-11 20:37:10 +08:00
gaozheng 8cdd6679a9 harden(data): 句柄 emit done 移出 try + catch(...) 兜底 + parse 抛异常测试(评审 I-1/M-5) 2026-06-11 20:31:07 +08:00
gaozheng bb602e2011 feat(data): 异步仓储接口 + ChartLoad/GridLoad 句柄(抽象基+Api实现) + 离线单测 2026-06-11 20:19:32 +08:00
gaozheng e980ddd346 harden(net): ApiBatch 契约断言(非空calls/非空谓词)+fail-fast注释+单元素测试(评审 I-1/I-2/M-1/M-2) 2026-06-11 20:13:48 +08:00
gaozheng 72b300d722 feat(net): ApiBatch 并发汇聚+fail-fast+abort闸门 + 离线单测 2026-06-11 20:05:53 +08:00
gaozheng f74d47e62e harden(net): ApiCall onFinished reply 快照防御 + 构造 Q_ASSERT(reply)(评审 H3/L1) 2026-06-11 19:59:23 +08:00
gaozheng 8f94443323 feat(net): ApiClient.getAsync/postJsonAsync + IApiCall/ApiCall 异步句柄(abort+aborted_ 闸门,AUTOMOC ON) 2026-06-11 19:51:48 +08:00
gaozheng c90ea83a04 refactor(net): 抽出 buildResponse,sync/async 共用响应解析(DRY,行为不变) 2026-06-11 19:43:37 +08:00
gaozheng 78f96dbc08 fix(review): 修 cpp-review HIGH/MEDIUM —散点ys越界/colorSvc析构泄漏/QwtPlot autoDelete注释/控制器catch(...)防busy死锁 + 清死代码simplifyInPlace/simplifyTol + 填充等比限幅 + DTO行数校验+枚举钳制 + ContourLine.level默认NaN 2026-06-11 18:59:19 +08:00
gaozheng 57c14ae8b4 fix(ui): 等值线每条只标注一个(弧长中点),对齐原版(移除周期重复标注) 2026-06-11 18:36:22 +08:00
gaozheng 48d21b82e9 fix(ui): 等值线 vtkSplineFilter 样条平滑(去DP简化,贴近原版圆滑曲线) + 标注沿线周期重复+降阈值(小等值线也标注) 2026-06-11 18:33:12 +08:00
gaozheng 4fbab033f0 fix(ui): 等值线用vtkStripper连成长折线(使沿线数值标注可落上) + 网格页(图+异常)分割器放入页签内QScrollArea(滚动限页签内) + 等值线测试 2026-06-11 18:21:52 +08:00
gaozheng 53dbcee052 fix(ui): 数据详情dock设ForceNoScrollArea(禁ADS把标题/页签卷入整体滚动条),内容自适应填充 2026-06-11 17:57:54 +08:00
gaozheng 03a6622dea fix(ui): 滚轮缩放并入LivePanner并消费事件(不再触发外层滚动条) + 网格页底部改QSplitter(去固定200px,两页高度解耦/不溢出) 2026-06-11 17:22:39 +08:00
gaozheng f14902cdd4 feat(ui): GridDataChartView 接入 QwtPlot+ContourPlotItem(真实比尺,白底,色阶条)
plotArea 占位换 QwtPlot(仿 RawDataChartView: 白底浅 palette, x 轴 xBottom/y 轴 yLeft,
LivePanner 实时平移, Magnifier setWheelFactor(1/0.9), QwtPlotRescaler ref=xBottom
aspect=1 真实比尺; 网格线/过原点零线省去, 被填充覆盖)。色阶占位换 ColorBarWidget。
setGridData: 建 ColorMapService(gridScale) + ContourPlotItem.setData → attach,
按数据 bbox setAxisScale + rescale + replot, 更新色阶条与底部异常表。
工具条「显示异常/显示等值线标注」复选框 → 切 ContourPlotItem 开关并 replot。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:00:36 +08:00
gaozheng 32e0aaec28 feat(ui): ContourPlotItem 网格填充栅格热力图 + 矢量等值线/标注/异常叠加
QwtPlotItem(非 Q_OBJECT)。填充用预渲染 ARGB32 QImage(每格细分 K=4,
双线性插值, 离散色带取色 → 平滑填充带边界; 含 NaN 格的像素透明 → 不规则白边),
draw 时按数据 bbox 映射目标矩形 blit + SmoothPixmapTransform(拖动/缩放快)。
等值线复用 buildContourBands 的 lines(矢量), 黑 cosmetic 细线;
level 由线上代表点采网格值吸附最近色阶级回填(管线恒 0), 沿线方向旋转标注(字号10)。
异常按 markType 画 点(方块)/线(折线)/面(闭合多边形), lineColor + dashed->虚线。
x 轴绑 xBottom, y 轴绑 yLeft。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:00:22 +08:00
gaozheng bac0a198ff feat(ui): 网格数据懒加载接线(控制器 gridReady + 页签首次激活触发)
DatasetDetailController 新增 GridData 内嵌结构 + loadGridData slot
(busy 守卫, 仅 dd_inversion_data; 拉 rows+色阶type2+异常) + gridReady 信号。
buildTabbedPanel 暴露 tabGroup 供调用方监听页签切换。
DatasetDetailPage 在「网格数据」页签首次激活且未加载时 emit gridDataNeeded;
setGridData 转发给 GridDataChartView 并标记已加载(切 ds 重置)。
DatasetDetailPanel 透传 gridDataNeeded / 按 dsId 路由 setGridData。
main.cpp 接线 gridDataNeeded->loadGridData, gridReady->setGridData。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:00:07 +08:00
gaozheng e54a28e571 perf(ui): 原数据加载严格对齐原版只拉散点+色阶2个(异常随网格懒加载) 2026-06-11 16:41:56 +08:00
gaozheng 1054c227e1 perf/fix(ui): 详情懒加载(双击只拉散点~0.8s,网格4s推迟) + 实时拖动平移(LivePanner替换像素抓取) + 横纵网格线 2026-06-11 16:33:35 +08:00
gaozheng 525c123211 feat(ui): 原数据散点锁定 x:y 真实比尺(QwtPlotRescaler aspect=1, Expanding) 2026-06-11 16:14:37 +08:00
gaozheng cf47314500 fix(ui): 散点 滚轮缩放方向反转(上滚=放大)+放开最小宽度(随面板收缩) + 色阶条居中74%宽(非满宽,对齐原版) 2026-06-11 16:09:00 +08:00
gaozheng 1f28505227 fix(ui): 原数据散点 白底+散点项关联xTop轴(修x压缩)+过原点零线 + 色阶条等宽色带/深色文字/白底 2026-06-11 15:55:32 +08:00
gaozheng e405fc1565 feat(ui): 原数据散点视图(QwtPlot x顶轴+Panner/Magnifier+连续色阶+方块散点+独立色阶条)
- ColorBarWidget:独立 QWidget 色阶条,水平离散色带 + 断点刻度,固定高 36px,
  作为 QwtPlot 兄弟 widget 布局在图表下方,不进 Qwt 坐标系(不随缩放移动)。
- ScatterPlotItem:QwtPlotItem 子类,每点画固定 7px 方块(kHalfSide=3.5px),
  白色描边(1px),颜色由 ColorMapService::colorAtContinuous 连续插值决定。
- RawDataChartView:plotArea 换成 QwtPlot,x 轴顶部(xTop)、关闭 xBottom、yLeft 正常;
  QwtPlotPanner(左键拖动平移)+ QwtPlotMagnifier(滚轮缩放);
  setData 时重建 ColorMapService + ScatterPlotItem,按数据包围盒设轴范围;
  独立色阶条随 setData 更新。
2026-06-11 15:40:43 +08:00
gaozheng c7fec86d3b feat(core+chart): ColorScale::stops() 暴露断点 + ColorMapService 连续插值色阶服务
- core::ColorScale 新增 stops() 方法,返回升序 (value, Rgba) 断点列表,供连续插值用。
- app::ColorMapService:从 ColorScale 构建,支持 normalized()/colorAtContinuous()/colorAtDiscrete();
  连续模式在归一化断点位置间线性插值 RGB,与原版 Plotly colorscale 一致。
- cmake/qwt.cmake 补加 QWT_MOC_INCLUDE=1,修复 Qwt AUTOMOC self-include 宏保护缺失导致
  Q_OBJECT MOC 代码不编入 .obj 的链接错误(LNK2019 x61 系列)。
- 新增 TDD 测试 ColorMapService.*(4 个用例,全绿)。
2026-06-11 15:40:27 +08:00
gaozheng 7808b8422a feat(ui): 数据集详情三层UI骨架(下划线页签+原数据/网格各自工具条+网格页底部异常列表/描述)
- 新建 DescriptionPanel:只读 QTextEdit,供网格数据底部「描述」页签使用
- 新建 RawDataChartView:工具条(网格/色阶配置/图形类型ComboBox/另存为) + 图表占位(stretch) + 色阶占位(36px)
- 新建 GridDataChartView:工具条(网格/色阶配置/白化/滤波/显示开关/简化容差滑块/异常标注/自动标注/另存为) + 图表占位(stretch) + 色阶占位(36px) + 底部200px双页签(异常列表/描述)
- 重写 DatasetDetailPage:用 buildTabbedPanel 做「原数据/网格数据」下划线页签 + 右侧「导出」HeaderAction
- 删除 DatasetChartView(已被 RawDataChartView/GridDataChartView 替代)
- CMakeLists:注册新 .cpp,移除 DatasetChartView,条件链接 qwt 目标
2026-06-11 15:04:34 +08:00
gaozheng 82b654176e fix(ui): 审查修复 loadFailed接线/控制器重入守卫+ddCode降级/散点越界/点异常/Tab deleteLater/makeLines
- main.cpp: DatasetDetailController::loadFailed 连接到 statusBar,5s 显示失败消息
- DatasetDetailController: 加 busy_ 重入守卫;ddCode 非 dd_inversion_data 时直接 loadFailed 降级
- DatasetChartView::showScatter: 按 x/y/v 三者最短长度循环,防越界;加 #include <algorithm>
- DatasetChartView::rebuildAnomalyItems: 先处理 markType==1 点异常(小方块),再走原折线/多边形分支
- DatasetChartView::clearChart: 加注释说明 scene_->clear() + anomalyItems_.clear() 不变式
- DatasetDetailPanel: tabCloseRequested 改用 deleteLater,避免在事件处理期间同步析构
- ContourBands: buildContourBands 按 opt.makeLines 决定是否开 GenerateContourEdgesOn 及提取等值线
2026-06-11 12:42:04 +08:00
gaozheng 08ba483550 feat(ui): 接线数据详情面板(移除旧VTK详情)+单击聚焦/双击打开/反向联动
- 移除旧 VTK 数据详情 dock(detailWidget/独立 renderer/工具条 原数据·网格数据·显示异常/电极/等值线)
  及 rebuildDetail lambda、共享态(currentDsId/detailMode/showAnomalies/...)与相关连接
- 清理因删除产生的孤儿:animateReveal、DetailMode、kScatterPointSize、kBarBtnQss
- 新建 DatasetDetailPanel 多 Tab 面板 dock(QGraphicsView 平面图表)
- buildWorkbench 加参 DatasetDetailController&;main() 构造 ApiDatasetRepository + DatasetDetailController
- 单击=属性表单+聚焦已开页;双击=openDataset(dsId,ddCode);chartReady→openOrUpdate;
  focusRequested→focusDataset;activeDatasetChanged→反向高亮列表
- 新增 kDsDdCodeRole(0x0104),populateDatasetList 写入 ddCode
- 保留 rebuildCentral 及中央场景、repo.loadGrid(grid1)
2026-06-11 12:18:18 +08:00
gaozheng 88d2fea9df feat(ui): DatasetDetailPanel 多Tab壳(按dsId去重+反向联动信号) 2026-06-11 12:09:38 +08:00
gaozheng b8c74962e8 feat(ui): DatasetDetailPage 原数据/网格切换+叠加开关+异常联动 2026-06-11 12:08:13 +08:00
gaozheng 535db496c4 feat(ui): AnomalyTablePanel ds级异常表(行眼睛→隐藏集信号) 2026-06-11 12:07:06 +08:00
gaozheng d61775a3bc feat(controller): DatasetDetailController 编排 + ErtInversionStrategy 标识 2026-06-11 12:04:12 +08:00
gaozheng 46c75ed419 feat(ui): dd 图表策略接口 + 注册表(未注册降级) 2026-06-11 12:01:31 +08:00
gaozheng facb812bca feat(ui): DatasetChartView 散点/等值面/异常叠加(QGraphicsView) 2026-06-11 11:57:49 +08:00
gaozheng 3192cf24cf feat(data): ApiDatasetRepository 接真实 API + loadScatterColorScale 提到接口 2026-06-11 11:52:05 +08:00
gaozheng e1bbf39d6d feat(data): DatasetChartDto 解析 inversion网格/散点/colorBar/异常 2026-06-11 11:50:08 +08:00
gaozheng 00c42f7a8d feat(render): ContourBands NaN 凸包裁剪(剔除无效quad)+等值线DP简化 2026-06-11 11:41:26 +08:00
gaozheng b7e0a2034d feat(render): ContourBands 双线性上采样+盒式平滑预处理(对齐 web 2x+smooth) 2026-06-11 11:39:05 +08:00
gaozheng f1ad490096 feat(render): ContourBands 从 VTK banded 提取色带多边形+等值线几何 2026-06-11 11:37:09 +08:00
gaozheng 179f46b42c feat(core): Grid 增 NaN 约定 + hasValue(凸包裁剪用) 2026-06-11 11:34:11 +08:00
gaozheng 72abeaa1d8 fix(ui): 修复 DynamicFormView::clear() 对嵌套布局重复释放导致的崩溃
it==it->layout()(QLayout 即 QLayoutItem),原代码 delete sub 后又 delete it 双重释放。
触发:clear 一个已填充表单时(切项目/重选对象→showMessage/setForm)崩溃。
2026-06-10 21:31:00 +08:00
gaozheng 3daaad3de3 fix(controller): setCheckedTms busy 时挂起重放(不丢弃) + 切项目清 currentParentId/挂起态 2026-06-10 21:22:39 +08:00
gaozheng d435fca32d feat(ui): 属性面板改两列卡片式表单(边框/底色/分隔线,主题协调) 2026-06-10 21:18:12 +08:00
gaozheng 7a56e49584 feat(ui): 接线 对象单击/勾选/数据集单击 → 三面板(移除占位) 2026-06-10 21:04:38 +08:00
gaozheng 0d17a00931 fix(ui): 对象树项目根设为非交互容器(仅 GS/TM 可勾选/单击) 2026-06-10 20:58:09 +08:00
gaozheng 68296a5d36 feat(ui): ObjectTreePanel GS三态勾选 + objectClicked/checkedTmsChanged 合并发射 2026-06-10 20:50:51 +08:00
gaozheng 595d65cd3b feat(ui): ObjectExceptionPanel 异常+异常体只读树(含详情展开) 2026-06-10 20:44:25 +08:00
gaozheng 5686155faa feat(ui): DynamicFormView 动态表单分组键值渲染器 2026-06-10 20:36:03 +08:00
gaozheng 6cf53ab199 fix(controller): 无条件清异常缓存(跨空间) + 移动语义 + 信号参数正名 2026-06-10 20:29:46 +08:00
gaozheng 8cab498f81 feat(controller): selectObject/setCheckedTms/selectDataset 编排 + 异常缓存 2026-06-10 20:22:09 +08:00
gaozheng 4621e11c73 feat(data): 仓储泛化 loadRows + 对象/数据集详情 + 按TM异常 接口实现 2026-06-10 20:15:00 +08:00
gaozheng a21d392816 feat(data): groupExceptionsByConsortium 按异常体分组 + 独立异常 2026-06-10 20:09:37 +08:00
gaozheng acf71bdaef feat(data): parseExceptions 映射异常字段 + 详情摘要 2026-06-10 20:03:28 +08:00
gaozheng 0018c11e0a feat(data): parseDynamicForm 合并动态表单字段定义与值(含排序) 2026-06-10 19:56:55 +08:00
gaozheng d1be0567de fix(ui): 统一图标-文字间距到6px——给切换器/页签图标加2px右内边距(Fusion内置4px+2),与面板标题(6px)一致(§6.7) 2026-06-10 18:39:49 +08:00
gaozheng 9680fefbe3 feat(topbar): 用户区按样图重做(头像竖直居中+姓名/职务两行左对齐+下拉箭头,整块可点) + 加宽下拉菜单(账户/个人资料/偏好设置/API密钥/退出登录) 2026-06-10 17:59:10 +08:00
gaozheng 3ccb8df4ed fix(ui): 修复改名导致的停靠布局丢失(bump dockState键丢弃失配旧布局) + 用户区改回QToolButton(头像图标+姓名职务一行,整块可点)修复挤成一团 2026-06-10 17:41:46 +08:00
gaozheng c953b35334 feat(topbar): 切换器下拉箭头换高清chevron(替代粗糙▾) + 用户区头像/姓名/职务同行且整块可点击 2026-06-10 17:27:37 +08:00
gaozheng 9e80b2fea1 feat(ui): 面板改名(对象/数据集/异常/数据集属性) + 原数据/网格数据改为下划线页签(与其他切换一致) + 表头图标间距对齐规范6px(§6.7) 2026-06-10 17:21:36 +08:00
gaozheng 5f02d494dc fix(theme): 复选指示器全局统一(清晰可见,规避Fusion浅底过淡) + 失焦保持选中,移除对象树本地重复样式 2026-06-10 17:09:09 +08:00
gaozheng 2a666663e7 refactor(theme): 全部项目对话框迁移令牌 + 清理委托接管后失效的列表选中/前景死代码 2026-06-10 17:02:03 +08:00
gaozheng b78969471e refactor(theme): 登录/设置迁移令牌 + 删除遗留 kDarkMap 字符串替换路径(暗色全由令牌双值驱动)(规范§13.1) 2026-06-10 16:57:10 +08:00
gaozheng 8f31f043df feat(panels): 异常列表卡片化(色条+类型标签+显隐眼睛,真实数据)(规范§6.3) 2026-06-10 16:44:35 +08:00
gaozheng b26dcc1ca7 feat(panels): 数据/文件列表卡片化(标题+元信息双行+选中竖条)(规范§6.2) 2026-06-10 16:40:14 +08:00
gaozheng 824e8bdf62 refactor(theme): 工作台内联色(对象树/数据详情工具条/停靠分隔)迁移到令牌(规范§4.2/§6.1/§6.12) 2026-06-10 16:27:57 +08:00