#pragma once #include #include #include #include #include #include #include #include #include "I3dSceneView.hpp" #include "model/ColorScale.hpp" namespace geopro::core { class GeoLocalFrame; } namespace geopro::render { class Scene; } class vtkRenderer; class vtkRenderWindow; class vtkProp; namespace geopro::app { // I3dSceneView 的真实实现:把编排层的"加图元"指令翻译为 render actor + Scene 调用。 // 持有 Scene / renderer / renderWindow(非拥有)+ 共享 GeoLocalFrame(多视图空间配准)。 // 纵向夸张统一作用:帘面/地形 actor SetScale(1,1,VE),体素 z 原点/间距烤入 VE。 // render 层零业务:actor 只吃 core::*,本类负责装配。 class VtkSceneView : public geopro::controller::I3dSceneView { public: // 入参生命周期须覆盖本对象(由调用方保证)。zRefElev:地形 z 基准(测线地表高程)。 VtkSceneView(geopro::render::Scene& scene, vtkRenderWindow* renderWindow, std::shared_ptr frame, double zRefElev); void clear() override; void setVerticalExaggeration(double ve) override; void addSurveyLine(const geopro::core::Grid& grid) override; void addCurtain(const std::string& dsId, const geopro::core::Grid& grid, const geopro::core::ColorScale& cs) override; void addVolume(const std::string& dsId, const geopro::data::VolumeGrid& vol, const geopro::core::ColorScale& cs) override; void addTerrain(const geopro::data::TerrainPaths& paths) override; void removeDataset(const std::string& dsId) override; // 切换某数据集图元可见性(三维分析栏「显示/隐藏」;切片等非 dsProps_ 图元忽略)。 void toggleDatasetVisibility(const std::string& dsId); void setAxes(geopro::controller::AxesMode mode, geopro::controller::AxesUnit unit, int fontSize) override; void applyCameraView(geopro::controller::ViewDir dir) override; void zoom(double factor) override; void fitView() override; void render(bool is2D) override; void renderIncremental() override; // ── P3 切片交互:暴露当前体素 image(含 VE 烤入的 origin/spacing)供切片附着 ── // addVolume 用暴露 image 的 buildVoxel 重载保留;clear/无体素时置空。 vtkImageData* currentVolumeImage() const { return currentVolumeImage_.Get(); } const geopro::core::ColorScale& currentColorScale() const { return currentColorScale_; } double currentVmin() const { return currentVmin_; } double currentVmax() const { return currentVmax_; } bool hasVolume() const { return currentVolumeImage_ != nullptr; } const std::string& currentVolumeDsId() const { return volumeOwnerDs_; } // 当前体归属 ds(保存切片用) // 体素 image 变化(addVolume 附着新 image / clear 置空)时回调,供上层把新 image 推给 // InteractionManager(重附着或关闭切片)。clear 时以 nullptr 触发。 std::function onVolumeChanged; // frame 原点重锚(首个带经纬剖面到达)后回调,供底图等随之刷新到数据所在位置。 std::function onFrameReanchored; // 相机程序化变化(取景/预设/缩放)后回调,供底图按新视锥重算覆盖(否则首帧部分瓦片要手动微动才出)。 std::function onCameraChanged; private: // 按当前坐标轴设置 + 场景包围盒重建坐标轴 prop(render 末尾调)。 void rebuildAxes(); void removeProps(std::vector>& props); // 从 renderer 移除并清空 // 仅数据图元(剖面/体素/地形/测线)的包围盒,不含底图 → 坐标轴/取景不被~公里级底图撑大。 bool computeDataBounds(double out[6]) const; public: // 当前所有数据图元(剖面等)合并范围的水平半径(米);无数据返回 0。供底图动态定最大范围。 double dataHorizontalRadius() const; private: geopro::render::Scene& scene_; vtkRenderWindow* renderWindow_; std::shared_ptr frame_; double zRefElev_; double verticalExaggeration_ = 1.0; // 是否已按真实剖面 lat/lon 重锚 frame 原点(每次 clear 重置):默认原点取自样本、可能离真实数据 // 很远→局部坐标巨大、轴刻度无意义;首个带经纬剖面到达时重锚到其中心,同选择内多剖面共用配准。 bool frameAnchoredToData_ = false; // 坐标轴设置(P2):默认标准 + 米。 geopro::controller::AxesMode axesMode_ = geopro::controller::AxesMode::Standard; geopro::controller::AxesUnit axesUnit_ = geopro::controller::AxesUnit::Meter; int axesFontSize_ = 12; // 当前坐标轴 prop:render 可能多次调用 rebuildAxes(rebuild 末尾 + 异步回灌), // 持引用以便重建前移除旧 prop,避免叠加(评审 HIGH)。 vtkSmartPointer currentAxes_; // 当前体素 image + 色阶(P3 切片附着源);无体素时为空。 vtkSmartPointer currentVolumeImage_; geopro::core::ColorScale currentColorScale_; double currentVmin_ = 0.0; double currentVmax_ = 0.0; // 增量渲染:按 dsId 跟踪该数据集的 props(帘面/体素),支持单独移除而不全量重建; // miscProps_ 为非数据集 prop(地形/测线),仅随 clear 全量移除。底图由 TileBasemap 自管、不在此。 std::map>> dsProps_; std::vector> miscProps_; std::string volumeOwnerDs_; // 当前 currentVolumeImage_ 归属的 ds(其被移除时置空切片源) }; } // namespace geopro::app