155 lines
8.5 KiB
C++
155 lines
8.5 KiB
C++
#pragma once
|
||
#include <QObject>
|
||
#include <QPointer>
|
||
#include <QString>
|
||
#include <QStringList>
|
||
#include <map>
|
||
#include <optional>
|
||
#include <set>
|
||
#include <string>
|
||
|
||
#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<std::string> checkedDs_;
|
||
// 二维足迹勾选集(与 checkedDs_ 独立;都画进 View3D 场景)。按 dsId 增量加/删。
|
||
std::vector<std::string> 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<DatasetViewState> state_; // 跨视图色阶真源(注入;编辑/加载/重着色都经它;QPointer 防悬挂)
|
||
|
||
// 缓存(按 dsId):避免重复读盘/插值。
|
||
std::map<std::string, geopro::core::Grid> gridCache_;
|
||
std::map<std::string, geopro::core::ColorScale> colorScaleCache_;
|
||
// 帘面源网格缓存:帘面重着色需 grid 重建 addCurtain(loadSection 的 s.grid 不在 gridCache_)。
|
||
std::map<std::string, geopro::core::Grid> sectionGridCache_;
|
||
std::map<std::string, data::VolumeGrid> volumeCache_;
|
||
// 三维体色阶缓存:mock 体在 dsRepo_ 无条目,色阶随 loadVolume 一起交付并缓存于此。
|
||
std::map<std::string, geopro::core::ColorScale> volumeScaleCache_;
|
||
|
||
// 异步回灌防护:每次全量 rebuild 自增,回调比对丢弃迟到结果。
|
||
unsigned long long rebuildGeneration_ = 0;
|
||
|
||
// 增量渲染状态:本批数据到场是否自动取景(全量重建/从空开始=true;增量追加=false,保持相机)。
|
||
bool fitOnArrival_ = true;
|
||
// 场景是否已有数据到场过:取景意图据此判定,避免连续快速勾选时 checkedDs_ 已非空但首批未到场
|
||
// 被误判为「增量追加」而不取景(连续勾两个 ds 看似不渲染的根因)。全取消勾选时复位。
|
||
bool hadArrivedData_ = false;
|
||
// 正在加载的 ds:防重复勾选竞态重复请求;全量重建时清空。
|
||
std::set<std::string> loadingDs_;
|
||
|
||
const geopro::core::Grid& grid(const std::string& dsId);
|
||
const geopro::core::ColorScale& colorScale(const std::string& dsId);
|
||
};
|
||
|
||
} // namespace geopro::controller
|