5.7 KiB
5.7 KiB
P3:三维分析·切片交互(核心)
- 日期:2026-06-16
- 分支:
feat/vtk-3d-view - 上游:spec
2026-06-15-vtk-3d-supplementary-design.md§9(交互层)、§4 行 F22–F25/C38–D46/E54–E56;接 P1/P2(VtkSceneController/VtkSceneView/Scene/体素管线已就位) - 目标:补充需求最重模块。在 P1 的 LocalSample 体素上实现切片交互:轴向/任意切片、滚轮推进、拾取选中、双击正视。让用户能在三维体上切出带色阶的剖面并交互调整。
范围
范围内(P3 核心):
- 新建
src/render/interact/交互层(README 早有规划但目录不存在)。 - 切片工具:轴向(上下=水平面/前后/左右,角度固定,F22–F24)+ 任意切片(初始 45°、可旋转,F25),对体素
vtkImageData重采样出带色阶剖面。 - 滚轮切片(D46):选中切片,滚轮沿切面法向推进/后退。
- 拾取选中 + 联动(C38/D39/D40/E54/E55/E56):拾取三维体/切片 → 以其中心为相机焦点(拖动绕其旋转);双击切片 → 相机正视切面法向;视图翻转(水平 180°);关闭切片。
- 切片剖面随体素纵向夸张一致(复用 P2 VE)。
- UI 入口:在三维视图加一组切片按钮(上下/前后/左右/任意/关闭),最小可用即可(完整右键菜单 + 三维分析树留 P4)。
范围外(留 P4):切片保存/保存为/导出图片/导出dat/删除为数据集(§6.3 CRUD)、三维分析栏树列表、右键上下文菜单、异常圈定 + 异常体管理、三维体/切片详情。
关键设计
- 体素 image 暴露:
VtkSceneView::addVolume改用buildVoxel(...,outImage)重载,保留currentVolumeImage_(含 VE 烤入的 origin/spacing),供切片工具附着。无体素时切片按钮禁用/无效。 - 切片工具(
src/render/interact/SliceTool.{hpp,cpp}):- 方案优选
vtkImagePlaneWidget同时覆盖轴向与任意:SetPlaneOrientationToXAxes/Y/Z给轴向(关闭旋转交互=角度固定);任意 = 设初始法向 45° 并允许旋转。它内部 reslice + 纹理显示剖面,SetLookupTable套我们的色阶 LUT(ColorLutBuilder)。 - 若
vtkImagePlaneWidget旋转/滚轮交互不满足,再退vtkImplicitPlaneWidget2 + vtkImageReslice + vtkImageActor(spec §9.1 钉死 reslice,不用 vtkCutter)。 - 持
vtkPlane(origin/normal);产出当前切面(供 P4 保存时转 Grid)。
- 方案优选
- 滚轮推进:自定义 interactor 观察者截
MouseWheelForward/BackwardEvent,对选中切片沿法向平移 origin → 更新 widget。 - 拾取 + 自定义 InteractorStyle(
src/render/interact/PickInteractorStyle.{hpp,cpp},继承vtkInteractorStyleTrackballCamera):vtkPropPicker拾取 → 选中 prop(高亮)→ 相机 focalPoint=prop 包围盒中心(绕其旋转)。- 双击切片 → 相机 position=center+normal·dist、viewUp 取法向正交(法向竖直时兜底备用 up)→ 正视(E54)。视图翻转=Azimuth(180)(E55)。
- InteractionManager(
src/render/interact/InteractionManager.{hpp,cpp}):持 interactor + 活动切片工具列表 + 选中态;管理创建/关闭切片、滚轮分发、拾取联动。app 层 VtkSceneView 持有它并接 UI 按钮。
步骤(TDD;交互件靠 build+目视,纯逻辑单测)
- 基线
build.bat test全绿。 - 切面几何/法向数学(TDD 纯逻辑):轴向法向(上下=(0,0,1)/前后=(0,1,0)/左右=(1,0,0))、任意初始 45°;滚轮平移 origin=origin+normal·step;双击正视的相机 position/viewUp 计算(含法向竖直兜底)。抽成可测纯函数(如
SlicePlaneMath)。 - VtkSceneView 暴露体素 image:addVolume 保留 currentVolumeImage_;clear 置空。测试/目视体素仍正常。
- SliceTool(vtkImagePlaneWidget 封装):构建/附着 image/设色阶 LUT/轴向 vs 任意配置/关闭。可测部分:plane origin/normal 设置、LUT 套用;widget 交互目视。
- PickInteractorStyle + InteractionManager:拾取→focal、双击→正视、滚轮→推进、翻转、关闭。纯逻辑(focal/相机计算)单测;拾取/事件目视。
- UI 接入 main.cpp:三维视图切片按钮组(上下/前后/左右/任意/关闭),连 InteractionManager;仅三维 + 有体素时可用。深色主题(复用 P2 工具条样式)。
build.bat test全绿 +build.bat app链接;目视清单交用户。- cpp-reviewer 审查 + 提交。
风险/注意
- vtkImagePlaneWidget 生命周期:须
SetInteractor(QVTK 的renderWindow->GetInteractor()) +On();vtkSmartPointer 持有防析构;场景 clear/切视图时正确 Off()+释放,避免悬挂观察者/崩溃。 - 纵向夸张一致:切片附着的 image 已烤入 VE(P1 体素管线),切面几何与体绘制对齐;VE 变化触发体素重建 → 切片须重附着或关闭重建。
- 2D 模式无切片:切片仅三维视图;切到二维须 Off 所有切片工具。
- 自定义 InteractorStyle 与 QVTK 默认:替换 style 后须保留相机拖动等基本交互(继承 TrackballCamera)。
- 构建:增量链接错用
cmake --build build\release --clean-first,勿删 build 目录(build-vs2026-vcpkg-gotchas);app 在运行致 LNK1104 则以 ctest 为准、提示关 app 重链。 - 交互件难单测:VTK widget 需 render window/interactor,CI 无显示环境多半跳过;故纯逻辑(plane/相机数学)尽量抽出单测,widget 行为靠目视。报告标清目视项。
- 切片"标准/任意"手感、色阶、正视/翻转细节若需对齐 Geopro 1.0,先合理实现,待 1.0 实地学习再精修(study-original-via-playwright)。