feat/vtk-merged-dataset-column #10
|
|
@ -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() {
|
||||
// 先移除上一次的坐标轴 prop:render 可能在一次 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());
|
||||
|
|
|
|||
|
|
@ -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 取当前选中 dsId;setSelectedMapLines 由列表设置选中
|
||||
// (高亮,不回调,避免环)。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
|
||||
|
|
|
|||
|
|
@ -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); };
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -57,9 +57,6 @@ public:
|
|||
|
||||
public slots:
|
||||
void setViewMode(ViewMode mode);
|
||||
// 切「三维分析/二维分析」tab(A 期):按目标维度是否已有数据重置取景基线,使切换后该维度第一条
|
||||
// 数据自动取景。显隐/相机/坐标轴由 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;
|
||||
// 当前摆放模式下足迹的世界 Z(mode 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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue