feat(vtk): 2D 段 z值滑块整体升降类型平面
This commit is contained in:
parent
989158427e
commit
352e60d37b
|
|
@ -1273,6 +1273,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
}
|
}
|
||||||
renderWindowPtr->Render();
|
renderWindowPtr->Render();
|
||||||
});
|
});
|
||||||
|
// 2D 段「z 值」滑块 → 整体升降该 2D 类型平面(Plane2DRenderStrategy 重摆其全部足迹)。
|
||||||
|
QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::planeZChanged, sceneCtrl,
|
||||||
|
&geopro::controller::VtkSceneController::setPlaneZ);
|
||||||
// 反向 VTK→list:在 VTK 里点中/选中一张切片 → 在三维体段树里同步选中该切片行(②反向)。
|
// 反向 VTK→list:在 VTK 里点中/选中一张切片 → 在三维体段树里同步选中该切片行(②反向)。
|
||||||
// 点空白/清选(dsId 空) → 一并清 VTK 异常高亮(否则取消选中后异常图形仍高亮,用户反馈)。
|
// 点空白/清选(dsId 空) → 一并清 VTK 异常高亮(否则取消选中后异常图形仍高亮,用户反馈)。
|
||||||
interactionMgr->onSliceSelectionChanged = [drawer, sceneView, renderWindowPtr](
|
interactionMgr->onSliceSelectionChanged = [drawer, sceneView, renderWindowPtr](
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ CategoryAnalysisTab::CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* d
|
||||||
connect(sec, &CategorySection::anomalyVisibilityChanged, this,
|
connect(sec, &CategorySection::anomalyVisibilityChanged, this,
|
||||||
&CategoryAnalysisTab::anomalyVisibilityChanged);
|
&CategoryAnalysisTab::anomalyVisibilityChanged);
|
||||||
connect(sec, &CategorySection::datasetSelected, this, &CategoryAnalysisTab::datasetSelected);
|
connect(sec, &CategorySection::datasetSelected, this, &CategoryAnalysisTab::datasetSelected);
|
||||||
|
connect(sec, &CategorySection::planeZChanged, this, &CategoryAnalysisTab::planeZChanged);
|
||||||
// #7:各段等分 stretch → 内容都少时四段平分高度填满面板(初始与 VTK 区等高、不出滚动条);
|
// #7:各段等分 stretch → 内容都少时四段平分高度填满面板(初始与 VTK 区等高、不出滚动条);
|
||||||
// 某段内容增多时其最小高度(=内容总高)撑大,超出视口则由外层 QScrollArea 统一出纵向滚动条。
|
// 某段内容增多时其最小高度(=内容总高)撑大,超出视口则由外层 QScrollArea 统一出纵向滚动条。
|
||||||
col->addWidget(sec, 1);
|
col->addWidget(sec, 1);
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ signals:
|
||||||
void sliceExportDatRequested(const QString& dsId);
|
void sliceExportDatRequested(const QString& dsId);
|
||||||
void anomalyVisibilityChanged(const QString& dsId, bool vis);
|
void anomalyVisibilityChanged(const QString& dsId, bool vis);
|
||||||
void datasetSelected(const QString& dsId, const QString& ddCode); // 树选中→VTK 高亮联动
|
void datasetSelected(const QString& dsId, const QString& ddCode); // 树选中→VTK 高亮联动
|
||||||
|
void planeZChanged(const QString& typeId, double z); // 2D 段 z 值滑块:整体升降该类型平面
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void recomputeCheckedUnion();
|
void recomputeCheckedUnion();
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QSignalBlocker>
|
#include <QSignalBlocker>
|
||||||
|
#include <QSlider>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
#include <QWidgetAction>
|
||||||
#include <QTreeWidgetItemIterator>
|
#include <QTreeWidgetItemIterator>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
|
@ -82,9 +84,7 @@ CategorySection::CategorySection(const geopro::data::CategoryDescriptor& desc,
|
||||||
break;
|
break;
|
||||||
case geopro::data::OpKind::PlaneZ:
|
case geopro::data::OpKind::PlaneZ:
|
||||||
acts.push_back({QStringLiteral("collapse"), QStringLiteral("z 值"), {},
|
acts.push_back({QStringLiteral("collapse"), QStringLiteral("z 值"), {},
|
||||||
[this](QToolButton*) { // Task E3 建滑块 popup;当前先发请求信号
|
[this](QToolButton* host) { showPlaneZPopup(host); }});
|
||||||
emit zSliderRequested(QString::fromStdString(desc_.id));
|
|
||||||
}});
|
|
||||||
break;
|
break;
|
||||||
case geopro::data::OpKind::Basemap:
|
case geopro::data::OpKind::Basemap:
|
||||||
acts.push_back({QStringLiteral("map"), QStringLiteral("底图"), {},
|
acts.push_back({QStringLiteral("map"), QStringLiteral("底图"), {},
|
||||||
|
|
@ -457,4 +457,34 @@ void CategorySection::showContextMenu(const QPoint& pos) {
|
||||||
menu.exec(list_->viewport()->mapToGlobal(pos));
|
menu.exec(list_->viewport()->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CategorySection::showPlaneZPopup(QToolButton* host) {
|
||||||
|
// z 值滑块 popup(仿工具条底图滑块):拖动整体升降本类型平面(含其上全部足迹)。
|
||||||
|
// 范围 ±500 米:覆盖常见场景高程量级;滑块值即平面绝对高程(米),首开回显 lastPlaneZ_(无则 0)。
|
||||||
|
constexpr int kPlaneZRangeM = 500;
|
||||||
|
QMenu menu(this);
|
||||||
|
auto* wa = new QWidgetAction(&menu);
|
||||||
|
auto* box = new QWidget(&menu);
|
||||||
|
auto* lay = new QVBoxLayout(box);
|
||||||
|
lay->setContentsMargins(space::kMd, space::kSm, space::kMd, space::kSm);
|
||||||
|
lay->setSpacing(space::kXs);
|
||||||
|
auto* lab = new QLabel(box);
|
||||||
|
auto* sld = new QSlider(Qt::Horizontal, box);
|
||||||
|
sld->setRange(-kPlaneZRangeM, kPlaneZRangeM);
|
||||||
|
sld->setValue(static_cast<int>(lastPlaneZ_));
|
||||||
|
sld->setMinimumWidth(160);
|
||||||
|
sld->setToolTip(QStringLiteral("平面高程 z(米)"));
|
||||||
|
auto syncLabel = [lab](int v) { lab->setText(QStringLiteral("平面 z:%1 米").arg(v)); };
|
||||||
|
syncLabel(sld->value());
|
||||||
|
connect(sld, &QSlider::valueChanged, this, [this, syncLabel](int v) {
|
||||||
|
lastPlaneZ_ = v;
|
||||||
|
syncLabel(v);
|
||||||
|
emit planeZChanged(QString::fromStdString(desc_.id), static_cast<double>(v));
|
||||||
|
});
|
||||||
|
lay->addWidget(lab);
|
||||||
|
lay->addWidget(sld);
|
||||||
|
wa->setDefaultWidget(box);
|
||||||
|
menu.addAction(wa);
|
||||||
|
menu.exec(host->mapToGlobal(QPoint(0, host->height())));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace geopro::app
|
} // namespace geopro::app
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ signals:
|
||||||
void checkedDatasetsChanged(const QStringList& dsIds); // 数据行勾选=渲染
|
void checkedDatasetsChanged(const QStringList& dsIds); // 数据行勾选=渲染
|
||||||
void collapsedChanged(); // 折叠/展开切换 → 外层 CategoryAnalysisTab 重排各段 stretch
|
void collapsedChanged(); // 折叠/展开切换 → 外层 CategoryAnalysisTab 重排各段 stretch
|
||||||
void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds); // 段头「+新增三维体」(接收方按 sourceIds 解析类型)
|
void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds); // 段头「+新增三维体」(接收方按 sourceIds 解析类型)
|
||||||
void zSliderRequested(const QString& typeId); // PlaneZ 图标:弹 z 值滑块 popup(Task E3 实现)
|
void planeZChanged(const QString& typeId, double z); // PlaneZ 滑块:整体升降该 2D 类型平面(z=绝对高程,米)
|
||||||
void basemapPopupRequested(const QString& typeId); // Basemap 图标:弹底图选择 popup(Task F2 实现)
|
void basemapPopupRequested(const QString& typeId); // Basemap 图标:弹底图选择 popup(Task F2 实现)
|
||||||
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 双击/右键=详情
|
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 双击/右键=详情
|
||||||
void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除(切片/异常)
|
void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除(切片/异常)
|
||||||
|
|
@ -70,6 +70,7 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void showContextMenu(const QPoint& pos); // 段体树右键菜单(详情 + 删除)
|
void showContextMenu(const QPoint& pos); // 段体树右键菜单(详情 + 删除)
|
||||||
|
void showPlaneZPopup(QToolButton* host); // PlaneZ 图标:弹 z 值滑块 popup → planeZChanged
|
||||||
void rebuildList(); // 据 rows_(经装置/日期筛选)重建段体树并复原勾选
|
void rebuildList(); // 据 rows_(经装置/日期筛选)重建段体树并复原勾选
|
||||||
void refreshArrayCombo(); // 据当前 rows_ 重填装置类型下拉项(经字典 value→中文)
|
void refreshArrayCombo(); // 据当前 rows_ 重填装置类型下拉项(经字典 value→中文)
|
||||||
void emitChecked(); // 收集勾选 → checkedDatasetsChanged
|
void emitChecked(); // 收集勾选 → checkedDatasetsChanged
|
||||||
|
|
@ -90,6 +91,7 @@ private:
|
||||||
QTreeWidget* list_ = nullptr;
|
QTreeWidget* list_ = nullptr;
|
||||||
QTimer* spinTimer_ = nullptr; // 驱动 busy 行 spinner 旋转(有 busy 行时运行)
|
QTimer* spinTimer_ = nullptr; // 驱动 busy 行 spinner 旋转(有 busy 行时运行)
|
||||||
int spinAngle_ = 0; // 当前 spinner 角度(度)
|
int spinAngle_ = 0; // 当前 spinner 角度(度)
|
||||||
|
double lastPlaneZ_ = 0.0; // 上次 z 值滑块设定的平面高程(重开 popup 时回显,无则 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace geopro::app
|
} // namespace geopro::app
|
||||||
|
|
|
||||||
|
|
@ -33,4 +33,16 @@ void Plane2DRenderStrategy::remove(const std::string& dsId) {
|
||||||
// 该类型全消(控制器活跃计数归零):此时 planeReg_.hasPlane==false。Phase F2 在此销毁平面底图。
|
// 该类型全消(控制器活跃计数归零):此时 planeReg_.hasPlane==false。Phase F2 在此销毁平面底图。
|
||||||
void Plane2DRenderStrategy::onTypeDeactivated(const std::string& /*typeId*/) {}
|
void Plane2DRenderStrategy::onTypeDeactivated(const std::string& /*typeId*/) {}
|
||||||
|
|
||||||
|
void Plane2DRenderStrategy::setPlaneZ(const std::string& typeId, double z) {
|
||||||
|
planeReg_.setPlaneZ(typeId, z); // 平面 z 真源更新(类型不存在则无操作)
|
||||||
|
// 重摆该类型全部已勾选足迹:移除旧 actor,按既有 add 路径在新 z 重新加载摆放。
|
||||||
|
// add2DDatasetAsync 复用 rebuildGeneration_ + loadingDs_/is2DChecked 防迟到/防重复(与 add 同护栏)。
|
||||||
|
for (const auto& [dsId, t] : dsToType_) {
|
||||||
|
if (t != typeId) continue;
|
||||||
|
ctrl_.view_.removeDataset(dsId);
|
||||||
|
ctrl_.add2DDatasetAsync(dsId, ctrl_.rebuildGeneration_, z);
|
||||||
|
}
|
||||||
|
ctrl_.view_.renderIncremental();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace geopro::controller
|
} // namespace geopro::controller
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ public:
|
||||||
void add(const std::string& typeId, const std::string& dsId) override;
|
void add(const std::string& typeId, const std::string& dsId) override;
|
||||||
void remove(const std::string& dsId) override;
|
void remove(const std::string& dsId) override;
|
||||||
void onTypeDeactivated(const std::string& typeId) override;
|
void onTypeDeactivated(const std::string& typeId) override;
|
||||||
|
// 滑块整体升降该类型平面 z:更新 planeReg_ 后,对该类型已勾选足迹移除并按新 z 重摆。
|
||||||
|
void setPlaneZ(const std::string& typeId, double z);
|
||||||
private:
|
private:
|
||||||
VtkSceneController& ctrl_;
|
VtkSceneController& ctrl_;
|
||||||
PlaneZRegistry planeReg_; // 按类型的平面 z 生命周期
|
PlaneZRegistry planeReg_; // 按类型的平面 z 生命周期
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,13 @@ VtkSceneController::VtkSceneController(data::IDatasetRepository& dsRepo,
|
||||||
// add/remove 委托回既有渲染路径(addDatasetAsync/add2DDatasetAsync/view_.removeDataset)。
|
// add/remove 委托回既有渲染路径(addDatasetAsync/add2DDatasetAsync/view_.removeDataset)。
|
||||||
registry_.registerStrategy("volume", std::make_unique<VolumeRenderStrategy>(*this));
|
registry_.registerStrategy("volume", std::make_unique<VolumeRenderStrategy>(*this));
|
||||||
registry_.registerStrategy("curtain", std::make_unique<CurtainRenderStrategy>(*this));
|
registry_.registerStrategy("curtain", std::make_unique<CurtainRenderStrategy>(*this));
|
||||||
registry_.registerStrategy("plane2d", std::make_unique<Plane2DRenderStrategy>(*this));
|
auto plane2d = std::make_unique<Plane2DRenderStrategy>(*this);
|
||||||
|
plane2d_ = plane2d.get(); // 留裸指针供 setPlaneZ 直呼(registry_ 持所有权)
|
||||||
|
registry_.registerStrategy("plane2d", std::move(plane2d));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VtkSceneController::setPlaneZ(const QString& typeId, double z) {
|
||||||
|
if (plane2d_) plane2d_->setPlaneZ(typeId.toStdString(), z);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDatasetRenderStrategy* VtkSceneController::strategyForType(const std::string& typeId) const {
|
IDatasetRenderStrategy* VtkSceneController::strategyForType(const std::string& typeId) const {
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@ public slots:
|
||||||
// 坐标轴设置面板「应用」:一次性下发 显示方式 + 单位 + per-axis 可见性/范围(单次重建)。
|
// 坐标轴设置面板「应用」:一次性下发 显示方式 + 单位 + per-axis 可见性/范围(单次重建)。
|
||||||
void setAxesConfig(AxesMode mode, AxesUnit unit, const AxisRangeCfg& x, const AxisRangeCfg& y,
|
void setAxesConfig(AxesMode mode, AxesUnit unit, const AxisRangeCfg& x, const AxisRangeCfg& y,
|
||||||
const AxisRangeCfg& z);
|
const AxisRangeCfg& z);
|
||||||
|
// 2D 段「z 值」滑块:整体升降某 2D 类型平面(含其上全部已勾选足迹)。转交 Plane2DRenderStrategy。
|
||||||
|
void setPlaneZ(const QString& typeId, double z);
|
||||||
|
|
||||||
void applyView(ViewDir dir); // 6 向快捷视图
|
void applyView(ViewDir dir); // 6 向快捷视图
|
||||||
void zoomIn(); // Zoom In (×1.2)
|
void zoomIn(); // Zoom In (×1.2)
|
||||||
void zoomOut(); // Zoom Out (×1/1.2)
|
void zoomOut(); // Zoom Out (×1/1.2)
|
||||||
|
|
@ -115,6 +118,7 @@ private:
|
||||||
std::map<std::string, int> typeActive_;
|
std::map<std::string, int> typeActive_;
|
||||||
// 渲染策略注册表(构造时注册 volume/curtain/plane2d 三策略,各持本控制器引用)。
|
// 渲染策略注册表(构造时注册 volume/curtain/plane2d 三策略,各持本控制器引用)。
|
||||||
RenderStrategyRegistry registry_;
|
RenderStrategyRegistry registry_;
|
||||||
|
Plane2DRenderStrategy* plane2d_ = nullptr; // registry_ 中 plane2d 策略的裸指针(setPlaneZ 免下转型)
|
||||||
ViewMode mode_ = ViewMode::Map2D;
|
ViewMode mode_ = ViewMode::Map2D;
|
||||||
bool showCurtain_ = true;
|
bool showCurtain_ = true;
|
||||||
bool showVoxel_ = false;
|
bool showVoxel_ = false;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue