#pragma once #include #include #include #include #include #include #include #include #include "I3dSceneView.hpp" #include "model/ColorScale.hpp" #include "model/Field.hpp" #include "repo/I3dSceneRepository.hpp" namespace geopro::data { class IDatasetRepository; } namespace geopro::controller { class DatasetViewState; // 跨视图共享色阶真源(统一同步机制) // 中央视图模式:二维地图(俯视测线)/ 三维视图(帘面/体素/地形)。 enum class ViewMode { Map2D, View3D }; // 三维图层("视图详情"浮层勾选)。 enum class SceneLayer { Curtain, Voxel, Terrain }; // 中央 VTK 渲染编排(spec §8):聚合 勾选数据集 + 视图模式 + 图层开关 + 纵向比例, // 经仓储取 core::* 数据,命令 I3dSceneView 重建场景。取代 main.cpp 的 rebuildCentral lambda。 // 异步:经 I3dSceneRepository 回调取体素/地形(回调内置幂请求标记防迟到回灌)。 // 缓存:Grid / VolumeGrid 按 dsId 缓存,避免重复取数。 // 不持有 widget;不认 vtkActor/vtkVolume(全交给 I3dSceneView)。 class VtkSceneController : public QObject { Q_OBJECT public: VtkSceneController(data::IDatasetRepository& dsRepo, data::I3dSceneRepository& sceneRepo, I3dSceneView& view, QObject* parent = nullptr); // 注入跨视图色阶真源(统一同步):连 colorScaleChanged → 就地按 dsId 重着色帘面/体。 // 构造后由 main.cpp 注入一次。 void setViewState(DatasetViewState* state); public slots: void setCheckedDatasets(const QStringList& dsIds); // 二维数据集栏勾选(足迹型测线/轨迹)→ 平铺进 View3D 地图。与 3D 勾选集独立,按 dsId 增量。 void setChecked2DDatasets(const QStringList& dsIds); // 二维足迹摆放高度(mode:0关闭 /1 Z=0 /2 顶部 /3 底部 /4 自定义;customZ 仅 mode=4 用)。 void set2DPlacement(int mode, double customZ); void setViewMode(ViewMode mode); // 切「三维分析/二维分析」tab(A 期):按目标维度是否已有数据重置取景基线,使切换后该维度第一条 // 数据自动取景。显隐/相机/坐标轴由 VtkSceneView::setAnalysisMode2D 负责(上层在同一处一并调用)。 void onAnalysisModeChanged(bool is2D); void setLayer(SceneLayer layer, bool on); void setVerticalExaggeration(double ve); // 三维体透明度调节(工具条滑块):运行时更新已渲染体的不透明度,并作为后续新体默认(0~1)。 void setVolumeOpacity(double maxOpacity); void rebuild(); // 主题切换等外部触发的重渲染 // 雷达体增益模式切换后重建:仓储已切模式+清缓存(setRadarGainMode),此处清控制器缓存/旧色阶 // 并(若勾选中)异步用新增益重建体、重渲。 void rebuildRadarVolume(const std::string& dsId); // 色阶编辑器「确定」:写入色阶真源(state_),经 colorScaleChanged 统一就地重着色(体/帘面 + 切片)。 // 兼容旧调用点;真正的重着色在 recolorDataset()。无 state_ 时退化为直连重建。 void setVolumeColorScale(const std::string& dsId, const geopro::core::ColorScale& cs); // ── P2 三维数据集栏 ── void setAxesMode(AxesMode mode); void setAxesUnit(AxesUnit unit); // 坐标轴设置面板「应用」:一次性下发 显示方式 + 单位 + per-axis 可见性/范围(单次重建)。 void setAxesConfig(AxesMode mode, AxesUnit unit, const AxisRangeCfg& x, const AxisRangeCfg& y, const AxisRangeCfg& z); void applyView(ViewDir dir); // 6 向快捷视图 void zoomIn(); // Zoom In (×1.2) void zoomOut(); // Zoom Out (×1/1.2) void fit(); // Fit (ResetCamera) signals: void loadFailed(const QString& message); // 三维体异步建体+落地渲染完成(dsId)。供 UI 撤回该体列表项的等待 spinner、复原复选框。 void volumeRendered(const QString& dsId); // 任一数据集(剖面/体)异步加载开始 / 渲染完成:上层据此把该列表项复选框↔等待 spinner 切换。 // 仅异步路径发(缓存命中即时完成只发 rendered);覆盖非三维体(剖面首次渲染也较慢,用户反馈)。 void datasetLoading(const QString& dsId); void datasetRendered(const QString& dsId); private: void rebuildInternal(); // colorScaleChanged(dsId) 槽:从 state_ 取新色阶,就地重建该 dsId 的帘面/体(及体下切片)。只渲染,不回写。 void recolorDataset(const QString& dsId); // 增量加入单个 ds(帘面/体素,按图层开关);回调按 gen + 仍勾选 守护,落地后增量渲染。 void addDatasetAsync(const std::string& dsId, unsigned long long gen); // 增量加入单个 2D 足迹(异步 loadMapLine → addMapLine at 当前摆放 Z);回调按 gen + 仍勾选 守护。 void add2DDatasetAsync(const std::string& dsId, unsigned long long gen); void onDatasetArrived(); // 单个 ds 落地后:增量渲染 + 首批数据自动取景 bool isChecked(const std::string& dsId) const; bool is2DChecked(const std::string& dsId) const; // 当前摆放模式下足迹的世界 Z(mode 0=关闭由调用方拦截;此处算 1/2/3/4 的 Z)。 double placementZ() const; data::IDatasetRepository& dsRepo_; data::I3dSceneRepository& sceneRepo_; I3dSceneView& view_; std::vector checkedDs_; // 二维足迹勾选集(与 checkedDs_ 独立;都画进 View3D 场景)。按 dsId 增量加/删。 std::vector checked2dDs_; // 二维足迹摆放:mode 0关闭/1 Z=0/2顶部/3底部/4自定义;customZ2d_ 仅 mode=4 用。 // 默认 Z=0(1) 与 Column2DDataset「2D视图」下拉可见默认项一致——避免「下拉显示 Z=0 但 // 控制器实为关闭」的初始信号丢失desync(组合框 setCurrentIndex 在 connect 前发射、且 // 组件早于 main.cpp 接线构造,初始 view2DModeChanged 永不送达),致勾选足迹静默不渲染。 int placement2dMode_ = 1; double customZ2d_ = 0.0; ViewMode mode_ = ViewMode::Map2D; bool showCurtain_ = true; bool showVoxel_ = false; bool showTerrain_ = false; double verticalExaggeration_ = 1.0; bool preserveCameraOnRebuild_ = false; // 改放大系数等:全量重建但保留当前相机(不跳远视角) // 坐标轴设置(P2):默认标准 + 米;字号固定 12(字体设置待 1.0 确认)。 AxesMode axesMode_ = AxesMode::Standard; AxesUnit axesUnit_ = AxesUnit::Meter; AxisRangeCfg axisX_, axisY_, axisZ_; // 坐标轴设置面板的 per-axis 可见性 + 自定义范围 static constexpr int kAxesFontSize = 12; QPointer state_; // 跨视图色阶真源(注入;编辑/加载/重着色都经它;QPointer 防悬挂) // 缓存(按 dsId):避免重复读盘/插值。 std::map gridCache_; std::map colorScaleCache_; // 帘面源网格缓存:帘面重着色需 grid 重建 addCurtain(loadSection 的 s.grid 不在 gridCache_)。 std::map sectionGridCache_; std::map volumeCache_; // 三维体色阶缓存:mock 体在 dsRepo_ 无条目,色阶随 loadVolume 一起交付并缓存于此。 std::map volumeScaleCache_; // 异步回灌防护:每次全量 rebuild 自增,回调比对丢弃迟到结果。 unsigned long long rebuildGeneration_ = 0; // 增量渲染状态:本批数据到场是否自动取景(全量重建/从空开始=true;增量追加=false,保持相机)。 bool fitOnArrival_ = true; // 场景是否已有数据到场过:取景意图据此判定,避免连续快速勾选时 checkedDs_ 已非空但首批未到场 // 被误判为「增量追加」而不取景(连续勾两个 ds 看似不渲染的根因)。全取消勾选时复位。 bool hadArrivedData_ = false; // 正在加载的 ds:防重复勾选竞态重复请求;全量重建时清空。 std::set loadingDs_; const geopro::core::Grid& grid(const std::string& dsId); const geopro::core::ColorScale& colorScale(const std::string& dsId); }; } // namespace geopro::controller