geopro/src/controller/VtkSceneController.hpp

155 lines
8.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
// 二维足迹摆放高度mode0关闭 /1 Z=0 /2 顶部 /3 底部 /4 自定义customZ 仅 mode=4 用)。
void set2DPlacement(int mode, double customZ);
void setViewMode(ViewMode mode);
// 切「三维分析/二维分析」tabA 期):按目标维度是否已有数据重置取景基线,使切换后该维度第一条
// 数据自动取景。显隐/相机/坐标轴由 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;
// 当前摆放模式下足迹的世界 Zmode 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 重建 addCurtainloadSection 的 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