refactor(vtk): 删维度相机/显隐耦合与逐ds拖Z(单一自由场景)

This commit is contained in:
gaozheng 2026-06-30 23:09:58 +08:00
parent ef56529d8c
commit 24b53f5e0c
5 changed files with 12 additions and 267 deletions

View File

@ -11,7 +11,6 @@
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkBoundingBox.h>
#include <vtkCellPicker.h>
#include <vtkCubeAxesActor.h>
#include <vtkNew.h>
#include <vtkProp.h>
@ -110,8 +109,7 @@ void VtkSceneView::clear() {
// 只移除数据 prop按 ds 跟踪)+ 杂项(地形/测线)+ 坐标轴;不动底图(TileBasemap 自管)→ 重建不丢图。
for (auto& kv : dsProps_) removeProps(kv.second);
dsProps_.clear();
mapLineDs_.clear(); // 2D 足迹维度记录随数据图元一并清(模式标志保留)
selectedMapLines_.clear(); // 选中态随图元清(actor 已销毁)Z 偏移 mapLineZOffset_ 保留→重建后复位高度
mapLineDs_.clear(); // 2D 足迹归属记录随数据图元一并清
removeProps(miscProps_);
clearAnomalies(); // 异常 actor 随清场一并移除
if (currentAxes_) {
@ -164,7 +162,6 @@ void VtkSceneView::addCurtain(const std::string& dsId, const geopro::core::Grid&
auto curtain = geopro::render::buildCurtain(grid, cs, *frame_);
if (curtain) {
curtain->SetScale(1.0, 1.0, verticalExaggeration_); // 纵向夸张成墙
curtain->SetVisibility(analysisMode2D_ ? 0 : 1); // 帘面=3D内容二维分析下隐藏
scene_.addActor(curtain);
dsProps_[dsId].push_back(curtain);
}
@ -206,7 +203,6 @@ void VtkSceneView::addVolume(const std::string& dsId, const geopro::data::Volume
// 体 actor 不参与拾取切片选中靠点中切片平面widget 交互/拾取)。否则点击落到体内部时
// picker 命中体、worldPoint 落体内 → nearestSlice 按平面距离选错切片(用户 ④ 串选)。
volume->PickableOff();
volume->SetVisibility(analysisMode2D_ ? 0 : 1); // 体=3D内容二维分析下隐藏
scene_.addViewProp(volume);
dsProps_[dsId].push_back(volume);
currentVolumeImage_ = image;
@ -228,7 +224,6 @@ void VtkSceneView::addVolume(const std::string& dsId, const geopro::data::Volume
auto iso = geopro::render::buildIsosurface(image, cs, vol.vmin, vol.vmax, isoVal);
if (iso) {
iso->PickableOff(); // 不参与拾取(同体 actor避免串选
iso->SetVisibility(analysisMode2D_ ? 0 : 1); // 3D 内容:二维分析下隐藏
scene_.addActor(iso);
dsProps_[dsId].push_back(iso);
}
@ -260,12 +255,9 @@ void VtkSceneView::addMapLine(const std::string& dsId, const geopro::data::MapLi
anchorFrameIfNeeded(line.lat, line.lon, static_cast<int>(line.lat.size()));
auto actor = geopro::render::buildMapLine(line.lat, line.lon, worldZ, *frame_);
if (actor) {
actor->SetVisibility(analysisMode2D_ ? 1 : 0); // 足迹=2D内容仅二维分析下显示
auto off = mapLineZOffset_.find(dsId); // B 期:复用持久 Z 偏移(全量重建后仍在该高度)
if (off != mapLineZOffset_.end()) actor->AddPosition(0.0, 0.0, off->second);
scene_.addActor(actor);
dsProps_[dsId].push_back(actor);
mapLineDs_.insert(dsId); // 记录此 ds 为 2D 足迹(切 tab 按维度翻可见)
mapLineDs_.insert(dsId); // 记录此 ds 为 2D 足迹(供足迹归属识别)
}
}
@ -417,137 +409,6 @@ void VtkSceneView::fitView() {
if (onCameraChanged) onCameraChanged(); // 取景后 → 底图按新视锥重算覆盖(治首帧部分瓦片不出)
}
void VtkSceneView::setAnalysisMode2D(bool is2D) {
if (is2D == analysisMode2D_) return; // 幂等:同模式重复切不做事
analysisMode2D_ = is2D;
if (!is2D) clearMapLineSelection(); // 离开二维分析:清足迹选中(三维下不可拖 Z)Z 偏移仍持久
// ① 按维度翻可见标志(不清空、不重建→切换瞬时)2D 足迹↔3D 帘面/体;异常属 3D。
// 地形/测线(miscProps_)与底图(TileBasemap 自管)两边常驻、不动。
for (auto& kv : dsProps_) {
const bool is2dContent = mapLineDs_.count(kv.first) > 0;
const bool vis = is2D ? is2dContent : !is2dContent;
for (auto& p : kv.second)
if (p) p->SetVisibility(vis ? 1 : 0);
}
for (auto& kv : anomalyProps_)
if (kv.second) kv.second->SetVisibility(is2D ? 0 : 1); // 异常=3D内容
// ② 取景 + 坐标轴 + 渲染统一走 render():朝向按 analysisMode2D_(已设)选近俯视/自由透视;
// ResetCamera 到"可见"数据包围盒(computeDataBounds 只计可见 prop)rebuildAxes 在二维下自移除;
// 末尾 Render + onCameraChanged(底图按新视锥重算)。不再用相机快照(陈旧易错),每次按可见内容取景。
render(/*is2D ViewMode=*/false, /*resetCamera=*/true);
}
// ── 二维分析改造 B 期:选中 2D 足迹沿高程 Z 拖动 ───────────────────────────────────
void VtkSceneView::applyMapLineSelectionVisual() {
for (auto& kv : dsProps_) {
if (!mapLineDs_.count(kv.first)) continue;
const bool sel = selectedMapLines_.count(kv.first) > 0;
for (auto& p : kv.second) {
auto* a = vtkActor::SafeDownCast(p);
if (!a) continue;
if (sel) { // 选中:黄高亮 + 加粗
a->GetProperty()->SetColor(1.0, 0.85, 0.2);
a->GetProperty()->SetLineWidth(6.0);
} else { // 未选:复原 buildMapLine 默认(橙 3.0)
a->GetProperty()->SetColor(0.95, 0.55, 0.10);
a->GetProperty()->SetLineWidth(3.0);
}
}
}
}
void VtkSceneView::clearMapLineSelection() {
if (selectedMapLines_.empty()) return;
selectedMapLines_.clear();
applyMapLineSelectionVisual();
if (renderWindow_) renderWindow_->Render();
if (onMapLineSelectionChanged) onMapLineSelectionChanged(); // VTK→列表同步清空
}
std::vector<std::string> VtkSceneView::selectedMapLines() const {
return std::vector<std::string>(selectedMapLines_.begin(), selectedMapLines_.end());
}
void VtkSceneView::setSelectedMapLines(const std::vector<std::string>& dsIds) {
// 列表→VTK按 dsId 设选中(仅已渲染足迹),高亮+渲染;不回调 onMapLineSelectionChanged(防回环)。
selectedMapLines_.clear();
for (const auto& id : dsIds)
if (mapLineDs_.count(id)) selectedMapLines_.insert(id);
applyMapLineSelectionVisual();
if (renderWindow_) renderWindow_->Render();
}
bool VtkSceneView::pickMapLineAt(int screenX, int screenY, bool additive) {
auto* ren = scene_.renderer();
if (!ren) return false;
// 只在"可见足迹"中拾取(PickFromList):避免地形/底图/隐藏的 3D 体抢命中。
vtkNew<vtkCellPicker> picker;
picker->SetTolerance(0.012);
picker->PickFromListOn();
bool any = false;
for (auto& kv : dsProps_) {
if (!mapLineDs_.count(kv.first)) continue;
for (auto& p : kv.second)
if (p && p->GetVisibility()) { picker->AddPickList(p); any = true; }
}
if (!any) return false; // 无可见足迹 → 不拦截(交由平移)
if (!picker->Pick(screenX, screenY, 0.0, ren)) {
if (!additive) clearMapLineSelection(); // 点空白(非多选)→ 取消选中
return false;
}
vtkProp* hit = picker->GetViewProp();
std::string hitDs;
for (auto& kv : dsProps_) {
if (!mapLineDs_.count(kv.first)) continue;
for (auto& p : kv.second)
if (p.Get() == hit) { hitDs = kv.first; break; }
if (!hitDs.empty()) break;
}
if (hitDs.empty()) {
if (!additive) clearMapLineSelection();
return false;
}
if (additive) { // Ctrl 多选:切换该足迹
if (selectedMapLines_.count(hitDs)) selectedMapLines_.erase(hitDs);
else selectedMapLines_.insert(hitDs);
} else if (!selectedMapLines_.count(hitDs)) { // 单击未选中的线 → 替换为它
selectedMapLines_.clear();
selectedMapLines_.insert(hitDs);
}
// 单击已选中的线(可能为多选之一):保持当前选中集 → 起手即可整体拖动,不塌缩为单选。
applyMapLineSelectionVisual();
if (renderWindow_) renderWindow_->Render();
if (onMapLineSelectionChanged) onMapLineSelectionChanged(); // VTK→列表同步选中
return !selectedMapLines_.empty(); // 有选中 → 交互样式进入 Z 拖动
}
void VtkSceneView::nudgeSelectedMapLinesZ(double worldDz) {
if (selectedMapLines_.empty() || worldDz == 0.0) return;
for (const auto& dsId : selectedMapLines_) {
mapLineZOffset_[dsId] += worldDz; // 持久累计(全量重建后 addMapLine 复用)
auto it = dsProps_.find(dsId);
if (it == dsProps_.end()) continue;
for (auto& p : it->second) {
auto* a = vtkActor::SafeDownCast(p);
if (a) a->AddPosition(0.0, 0.0, worldDz); // 仅改 Z锁 XY
}
}
if (scene_.renderer()) scene_.renderer()->ResetCameraClippingRange(); // Z 抬升后防被裁剪面切
if (renderWindow_) renderWindow_->Render();
}
double VtkSceneView::selectedMapLineZ() const {
if (selectedMapLines_.empty()) return 0.0;
// 代表性 Z = 任一选中足迹 actor 的包围盒中心 Z(含 placement worldZ + 已累计偏移)。
auto it = dsProps_.find(*selectedMapLines_.begin());
if (it == dsProps_.end()) return 0.0;
for (const auto& p : it->second)
if (p) { if (double* b = p->GetBounds()) return 0.5 * (b[4] + b[5]); }
return 0.0;
}
void VtkSceneView::rebuildAxes() {
// 先移除上一次的坐标轴 proprender 可能在一次 rebuild 内多次调用(末尾统一 render +
// 异步回灌 render不先移除会叠加坐标轴评审 HIGH。移除后再算 bounds仅数据图元
@ -555,9 +416,6 @@ void VtkSceneView::rebuildAxes() {
scene_.renderer()->RemoveViewProp(currentAxes_);
currentAxes_ = nullptr;
}
// 二维分析无立体坐标轴:任何渲染路径(全量/增量/切模式)走到此都不重建坐标轴,
// 保证切到二维分析后坐标轴消失、且后续增量渲染不把它带回来。
if (analysisMode2D_) return;
// 坐标轴随数据包围盒重建:仅按数据图元算 bounds(不含底图,否则被~公里级底图撑大)
// 再造 vtkCubeAxesActor 入场。None 模式或无数据 → buildAxes 返回 nullptr场景无坐标轴。
double bounds[6];
@ -588,12 +446,9 @@ void VtkSceneView::render(bool is2D, bool resetCamera) {
// 坐标轴仅三维视图显示2D 俯视测线不需要立体坐标轴)。
if (!is2D) rebuildAxes();
// 相机预设(朝向)只在取景时应用——保留相机的重建(改放大系数)不重设朝向,否则也会跳视角。
// 朝向优先看二维分析模式(本期 A):处二维分析→近俯视;否则按 ViewMode(旧 Map2D 正俯视/三维自由)。
// 这样 VE 改/项目切等全量重建在二维分析下仍保持近俯视,不跳回三维自由视角。
// 朝向按 is2D俯视(Map2D)/三维自由透视。
if (resetCamera) {
if (analysisMode2D_)
geopro::render::applyNearTop2D(scene_.renderer());
else if (is2D)
if (is2D)
geopro::render::applyTop2D(scene_.renderer());
else
geopro::render::applyFree3D(scene_.renderer());

View File

@ -87,13 +87,6 @@ public:
// 相机程序化变化(取景/预设/缩放)后回调,供底图按新视锥重算覆盖(否则首帧部分瓦片要手动微动才出)。
std::function<void()> onCameraChanged;
// ── 二维分析改造 A 期:一场景两相机 ──────────────────────────────────────────
// 切「二维分析」(is2D=true):相机锁近俯视、显 2D 足迹/隐 3D(体/帘面/异常);切回反之。
// 只翻 actor 可见标志(不清空、不重建)→ 切换瞬时、零重插值。地形/底图常驻不动。
// 切片显隐 + 交互锁由 InteractionManager::setMode2D 配合(上层在同一处调两者)。
void setAnalysisMode2D(bool is2D);
bool isAnalysisMode2D() const { return analysisMode2D_; }
// ── B 方案#2沿线位置巡航雷达超长测线──────────────────────────────────────
// t∈[0,1] 沿数据【最长轴】定位;取景到该位置一段【窗口】(windowFrac=窗口占长轴比例)
// 保持当前朝向(ResetCamera 只重定位+缩放、不转向)→ 像滚动读长 radargram。短轴满幅、长轴只取一段。
@ -101,22 +94,6 @@ public:
// 数据包围盒长短轴比(max/min 跨度)。用于判是否细长(雷达)→ 决定沿线滑块显隐。无数据返回 0。
double longAxisElongation() const;
// ── 二维分析改造 B 期:选中 2D 足迹沿高程 Z 拖动 ───────────────────────────────
// 仅二维分析下用。pickMapLineAt在屏幕(x,y)拾取足迹(只考虑可见足迹,不被地形/底图干扰);命中则
// 选中(additive=Ctrl 多选切换,否则单选替换)并高亮,返回是否有选中(交互样式据此决定 Z 拖动/平移)。
// nudgeSelectedMapLinesZ选中足迹世界 Z += worldDz(锁 XY);偏移按 dsId 持久(切走再回/全量重建保留)。
// selectedMapLineZ代表性当前世界 Z(高程读数浮层用);无选中返回 0。
bool pickMapLineAt(int screenX, int screenY, bool additive);
void clearMapLineSelection();
bool hasMapLineSelection() const { return !selectedMapLines_.empty(); }
void nudgeSelectedMapLinesZ(double worldDz);
double selectedMapLineZ() const;
// 双向选择联动列表↔VTK。selectedMapLines 取当前选中 dsIdsetSelectedMapLines 由列表设置选中
// (高亮,不回调,避免环)。VTK 内拾取改变选中时触发 onMapLineSelectionChanged → 上层同步列表。
std::vector<std::string> selectedMapLines() const;
void setSelectedMapLines(const std::vector<std::string>& dsIds);
std::function<void()> onMapLineSelectionChanged;
private:
// 首个带经纬数据(剖面/足迹)到达时把共享 frame 重锚到其 lat/lon 包围盒中心:使数据落在世界原点近旁
// (否则样本默认原点可能离真实数据数百公里→图元在视锥外、移动视角也找不到)。已锚或无经纬则跳过。
@ -183,15 +160,8 @@ private:
std::string volumeOwnerDs_; // 当前 currentVolumeImage_ 归属的 ds其被移除时置空切片源
std::map<std::string, vtkSmartPointer<vtkActor>> anomalyProps_; // 异常 id → 3D actor
// ── 二维分析改造 A 期 ──
// 哪些 dsProps_ 条目是 2D 足迹(addMapLine):切 tab 按此区分维度翻可见(其余 dsProps_=帘面/体=3D)。
// 哪些 dsProps_ 条目是 2D 足迹(addMapLine):供足迹 actor 归属识别(Task E2/F2 用)。
std::set<std::string> mapLineDs_;
bool analysisMode2D_ = false; // 当前是否处二维分析(默认三维启动在「三维分析」tab)
// B 期:选中的足迹 dsId(Z 拖动目标) + 各足迹累计 Z 偏移(持久,全量重建后 addMapLine 复用)。
std::set<std::string> selectedMapLines_;
std::map<std::string, double> mapLineZOffset_;
void applyMapLineSelectionVisual(); // 选中足迹加粗变亮、其余复原(橙 3.0)
};
} // namespace geopro::app

View File

@ -482,27 +482,6 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
// 子视图(表头+左树+画布)并 raise 到顶层;保存阶段显示,完成即撤。复用于其他需要整窗等待的场景。
auto* vtkLoading = new geopro::app::LoadingOverlay(centerWidget);
// ── 二维分析 B 期:高程 Z 拖动读数浮层(顶部居中)+ 足迹拾取/拖动回调注入交互样式 ──────────
// 拖动选中足迹时显示其当前世界 Z松开隐藏不挡画布鼠标。深底方角同异常提示坑规避
auto* elevHint = new QLabel(vtkWidget);
elevHint->setObjectName(QStringLiteral("elevHint"));
elevHint->setAttribute(Qt::WA_TransparentForMouseEvents);
geopro::app::applyTokenizedStyleSheet(
elevHint, QStringLiteral("QLabel#elevHint{background:#0E1A2D;color:#E6ECF5;"
"border:1px solid {{accent/primary}};padding:6px 12px;}"));
elevHint->hide();
// 滚轮升降时读数浮层 1.2s 后自动隐藏(拖动则在松开时隐藏)。
auto* zHideTimer = new QTimer(vtkWidget);
zHideTimer->setSingleShot(true);
QObject::connect(zHideTimer, &QTimer::timeout, elevHint, [elevHint]() { elevHint->hide(); });
auto showZReadout = std::make_shared<std::function<void()>>([sceneView, elevHint, vtkWidget]() {
elevHint->setText(
QStringLiteral("高程 Z%1 m").arg(sceneView->selectedMapLineZ(), 0, 'f', 1));
elevHint->adjustSize();
elevHint->move((vtkWidget->width() - elevHint->width()) / 2, 12); // 顶部居中
elevHint->show();
elevHint->raise();
});
// ── B 方案#2雷达沿线位置滑块超长测线巡航────────────────────────────────────
// 拖动 → 相机沿数据最长轴 dolly 到该位置的一段窗口(focusAlongLongAxis)。仅细长(雷达)体显示。
auto* alongLineBar = new QWidget(vtkWidget);
@ -528,34 +507,13 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
auto* alongLineOverlay = new BottomBarOverlay(alongLineBar, vtkWidget);
QObject::connect(alongLineSlider, &QSlider::valueChanged, vtkWidget,
[sceneView](int v) { sceneView->focusAlongLongAxis(v / 1000.0, 0.12); });
// 显隐刷新:仅三维分析 + 细长(长短轴比≥4即雷达)体时显示沿线滑块。
// 显隐刷新:细长(长短轴比≥4即雷达)体时显示沿线滑块。
auto refreshAlongLineBar = std::make_shared<std::function<void()>>(
[sceneView, alongLineBar, alongLineOverlay]() {
const bool show = !sceneView->isAnalysisMode2D() && sceneView->longAxisElongation() >= 4.0;
const bool show = sceneView->longAxisElongation() >= 4.0;
alongLineBar->setVisible(show);
if (show) alongLineOverlay->reposition();
});
if (auto* style = interactionMgr->pickStyle()) {
// 命中可见足迹→选中(Ctrl 多选)并返回是否进入 Z 拖动;未命中(返回 false)→交互样式回退平移。
style->onPick2D = [sceneView](int x, int y, bool additive) {
return sceneView->pickMapLineAt(x, y, additive);
};
// 拖动中:施加世界 Z 增量(仅改 Z),并把选中足迹当前高程显示在顶部读数浮层。
style->onDrag2D = [sceneView, showZReadout](double worldDz) {
sceneView->nudgeSelectedMapLinesZ(worldDz);
(*showZReadout)();
};
style->onDrag2DEnd = [elevHint]() { elevHint->hide(); };
// 滚轮升降:有选中足迹则施加 Z 增量并显示读数(1.2s 后自动隐藏),返回 true 消费滚轮;否则缩放。
style->onWheel2D = [sceneView, showZReadout, zHideTimer](double worldDz) {
if (!sceneView->hasMapLineSelection()) return false;
sceneView->nudgeSelectedMapLinesZ(worldDz);
(*showZReadout)();
zHideTimer->start(1200);
return true;
};
}
// 双向选择联动B2去 col2D 后由统一段 datasetSelected 承担 2D 选中,此处旧 col2D 链已移除)。
// 坐标轴设置抽屉面板:叠加 vtkWidget、工具条右侧滑出默认隐藏点设置 toggle
@ -1441,7 +1399,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
auto* emptyCentering = new CenterOverlay(emptyState, vtkWidget);
// 引导层定位后,把工具条与提示浮层 raise 到其上 → 工具条永在最上层(修:缩小渲染区时引导层挡工具条)。
emptyCentering->setRaiseAfter({viewToolbar, anomalyHint, elevHint, alongLineBar});
emptyCentering->setRaiseAfter({viewToolbar, anomalyHint, alongLineBar});
emptyCentering->reposition();
// 引导层隐藏器就位(见 pushChecked 处声明):场景(剖面∪三维分析)有勾选 → 隐藏不透明引导层、露出渲染。
*setSceneEmptyVisible = [emptyState](bool empty) { emptyState->setVisible(empty); };

View File

@ -15,13 +15,6 @@
namespace geopro::controller {
namespace {
// 二维足迹「顶部/底部」摆放相对参考高程(Z=0)的偏移(米):控制器无地形/参考高程源
// (地形异步、帘面经纬未必到场),故退化为 Z=0 上/下固定偏移,使足迹不与帘面顶/底面重叠遮挡。
constexpr double kTopOffsetZ = 50.0; // 顶部:参考面上方
constexpr double kBottomOffsetZ = -50.0; // 底部:参考面下方
} // namespace
VtkSceneController::VtkSceneController(data::IDatasetRepository& dsRepo,
data::I3dSceneRepository& sceneRepo, I3dSceneView& view,
QObject* parent)
@ -107,17 +100,6 @@ void VtkSceneController::setCheckedDatasets(
view_.renderIncremental(); // 立即反映移除 / 触发坐标轴重算
}
double VtkSceneController::placementZ() const {
const double surf = view_.zRefElev(); // 真实地表高程基准(测线地表高程)
switch (placement2dMode_) {
case 1: return 0.0; // Z=0世界原点
case 2: return surf + kTopOffsetZ; // 顶部:贴真实地表上方
case 3: return surf + kBottomOffsetZ; // 底部:真实地表下方
case 4: return customZ2d_; // 自定义
default: return 0.0; // 关闭(0) 不应走到此(调用方拦截)
}
}
void VtkSceneController::add2DDatasetAsync(const std::string& dsId, unsigned long long gen) {
if (loadingDs_.count(dsId)) return; // 已在加载(重复勾选竞态)→ 不重复请求
loadingDs_.insert(dsId);
@ -127,13 +109,12 @@ void VtkSceneController::add2DDatasetAsync(const std::string& dsId, unsigned lon
[self, gen, dsId](data::MapLine line) {
if (!self) return;
self->loadingDs_.erase(dsId);
// gen 作废 / 已取消勾选 / 摆放已关闭 → 丢弃迟到回调。
if (gen != self->rebuildGeneration_ || !self->is2DChecked(dsId) ||
self->placement2dMode_ == 0) {
// gen 作废 / 已取消勾选 → 丢弃迟到回调。
if (gen != self->rebuildGeneration_ || !self->is2DChecked(dsId)) {
return;
}
// 落地时按当前摆放 Z非请求时快照→ 加载期间摆放变化也取最新高程
self->view_.addMapLine(dsId, line, self->placementZ());
// 单一自由场景:足迹统一摆到 Z=0按类型平面 z 由 Phase E2 接入)
self->view_.addMapLine(dsId, line, 0.0);
self->onDatasetArrived();
},
[self, gen, dsId](const std::string& m) {
@ -243,16 +224,6 @@ void VtkSceneController::setViewMode(ViewMode mode) {
rebuildInternal();
}
void VtkSceneController::onAnalysisModeChanged(bool is2D) {
// 切「三维分析/二维分析」tab按目标维度是否已有数据重置取景基线。
// 目标维度空 → hadArrivedData_=false切换后该维度第一条数据自动取景(治"3D 数据不知生成到哪")。
// 目标维度非空 → hadArrivedData_=true视图切换时已 fit 到该维度,后续勾选不再跳(与三维一致)。
// 显隐/相机/坐标轴由 VtkSceneView::setAnalysisMode2D 处理(上层在同一处调用);此处只管取景基线。
// 注B2 重构后抽屉去 tab、analysisModeChanged 接线移除,本槽暂无调用方(保留待 C2/D3 复用)。
(void)is2D;
hadArrivedData_ = !checked_.empty();
}
void VtkSceneController::setLayer(SceneLayer layer, bool on) {
switch (layer) {
case SceneLayer::Curtain: showCurtain_ = on; break;

View File

@ -57,9 +57,6 @@ public:
public slots:
void setViewMode(ViewMode mode);
// 切「三维分析/二维分析」tabA 期):按目标维度是否已有数据重置取景基线,使切换后该维度第一条
// 数据自动取景。显隐/相机/坐标轴由 VtkSceneView::setAnalysisMode2D 负责(上层在同一处一并调用)。
void onAnalysisModeChanged(bool is2D);
void setLayer(SceneLayer layer, bool on);
void setVerticalExaggeration(double ve);
// 三维体透明度调节工具条滑块运行时更新已渲染体的不透明度并作为后续新体默认0~1
@ -106,8 +103,6 @@ private:
bool is2DChecked(const std::string& dsId) const;
// 按 typeId 查其渲染策略catalog[typeId].renderStrategyId → registry_。未知 typeId 返回 nullptr。
IDatasetRenderStrategy* strategyForType(const std::string& typeId) const;
// 当前摆放模式下足迹的世界 Zmode 0=关闭由调用方拦截;此处算 1/2/3/4 的 Z
double placementZ() const;
data::IDatasetRepository& dsRepo_;
data::I3dSceneRepository& sceneRepo_;
@ -119,10 +114,6 @@ private:
std::map<std::string, int> typeActive_;
// 渲染策略注册表(构造时注册 volume/curtain/plane2d 三策略,各持本控制器引用)。
RenderStrategyRegistry registry_;
// 二维足迹摆放mode 0关闭/1 Z=0/2顶部/3底部/4自定义customZ2d_ 仅 mode=4 用。
// 默认 Z=0(1);摆放 UI平面 z 滑块/底图)由 Phase E/F 重接,当前固定默认。
int placement2dMode_ = 1;
double customZ2d_ = 0.0;
ViewMode mode_ = ViewMode::Map2D;
bool showCurtain_ = true;
bool showVoxel_ = false;