feat/vtk-3d-view #7
|
|
@ -0,0 +1,134 @@
|
||||||
|
#include "AxesSettingsPanel.hpp"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "Theme.hpp"
|
||||||
|
|
||||||
|
namespace geopro::app {
|
||||||
|
|
||||||
|
AxesSettingsPanel::AxesSettingsPanel(QWidget* parent) : QFrame(parent) {
|
||||||
|
setFrameShape(QFrame::StyledPanel);
|
||||||
|
applyTokenizedStyleSheet(
|
||||||
|
this, QStringLiteral("QFrame{background:{{bg/panel}};border:1px solid {{border/default}};"
|
||||||
|
"border-radius:10px;}"));
|
||||||
|
setFixedWidth(320);
|
||||||
|
|
||||||
|
auto* v = new QVBoxLayout(this);
|
||||||
|
v->setContentsMargins(space::kMd, space::kMd, space::kMd, space::kMd);
|
||||||
|
v->setSpacing(space::kSm);
|
||||||
|
|
||||||
|
// 标题行:坐标轴设置 + × 关闭。
|
||||||
|
auto* titleRow = new QHBoxLayout();
|
||||||
|
auto* title = new QLabel(QStringLiteral("坐标轴设置"), this);
|
||||||
|
title->setStyleSheet(QStringLiteral("font-weight:600;font-size:15px;border:none;"));
|
||||||
|
auto* close = new QPushButton(QStringLiteral("✕"), this);
|
||||||
|
close->setFlat(true);
|
||||||
|
close->setFixedSize(24, 24);
|
||||||
|
connect(close, &QPushButton::clicked, this, &AxesSettingsPanel::closed);
|
||||||
|
titleRow->addWidget(title);
|
||||||
|
titleRow->addStretch(1);
|
||||||
|
titleRow->addWidget(close);
|
||||||
|
v->addLayout(titleRow);
|
||||||
|
|
||||||
|
// 坐标轴单位。
|
||||||
|
auto* unitLbl = new QLabel(QStringLiteral("坐标轴单位"), this);
|
||||||
|
unitLbl->setStyleSheet(QStringLiteral("border:none;"));
|
||||||
|
v->addWidget(unitLbl);
|
||||||
|
unit_ = new QComboBox(this);
|
||||||
|
unit_->addItems({QStringLiteral("米"), QStringLiteral("英尺")});
|
||||||
|
v->addWidget(unit_);
|
||||||
|
|
||||||
|
// X / Y / Z 三轴(各:显示开关 + 最小值/最大值)。
|
||||||
|
x_ = addAxisRow(v, QStringLiteral("X轴"), {true, -500, 500});
|
||||||
|
y_ = addAxisRow(v, QStringLiteral("Y轴"), {true, -500, 500});
|
||||||
|
z_ = addAxisRow(v, QStringLiteral("Z轴"), {true, 0, 200});
|
||||||
|
|
||||||
|
// 放大系数(=垂直夸张)。
|
||||||
|
auto* scaleLbl = new QLabel(QStringLiteral("放大系数"), this);
|
||||||
|
scaleLbl->setStyleSheet(QStringLiteral("border:none;"));
|
||||||
|
v->addWidget(scaleLbl);
|
||||||
|
scale_ = new QComboBox(this);
|
||||||
|
scale_->addItems({QStringLiteral("0.1"), QStringLiteral("0.5"), QStringLiteral("1"),
|
||||||
|
QStringLiteral("2"), QStringLiteral("5")});
|
||||||
|
scale_->setCurrentText(QStringLiteral("1"));
|
||||||
|
v->addWidget(scale_);
|
||||||
|
|
||||||
|
// 取消 / 应用。
|
||||||
|
auto* btns = new QHBoxLayout();
|
||||||
|
auto* cancel = new QPushButton(QStringLiteral("取消"), this);
|
||||||
|
auto* apply = new QPushButton(QStringLiteral("应用"), this);
|
||||||
|
apply->setStyleSheet(QStringLiteral(
|
||||||
|
"QPushButton{background:#2f6fed;color:white;border:none;border-radius:6px;padding:6px 18px;}"
|
||||||
|
"QPushButton:hover{background:#2a63d4;}"));
|
||||||
|
connect(cancel, &QPushButton::clicked, this, &AxesSettingsPanel::closed);
|
||||||
|
connect(apply, &QPushButton::clicked, this, [this] {
|
||||||
|
auto rd = [](const Row& r) {
|
||||||
|
return AxisRange{r.show->isChecked(), r.lo->value(), r.hi->value()};
|
||||||
|
};
|
||||||
|
emit applied(rd(x_), rd(y_), rd(z_), unit_->currentIndex(), scale_->currentText().toDouble());
|
||||||
|
});
|
||||||
|
btns->addStretch(1);
|
||||||
|
btns->addWidget(cancel);
|
||||||
|
btns->addWidget(apply);
|
||||||
|
v->addLayout(btns);
|
||||||
|
}
|
||||||
|
|
||||||
|
AxesSettingsPanel::Row AxesSettingsPanel::addAxisRow(QVBoxLayout* col, const QString& title,
|
||||||
|
const AxisRange& def) {
|
||||||
|
Row r;
|
||||||
|
auto* head = new QHBoxLayout();
|
||||||
|
auto* lbl = new QLabel(title, this);
|
||||||
|
lbl->setStyleSheet(QStringLiteral("font-weight:600;border:none;"));
|
||||||
|
head->addWidget(lbl);
|
||||||
|
head->addStretch(1);
|
||||||
|
auto* showLbl = new QLabel(QStringLiteral("显示"), this);
|
||||||
|
showLbl->setStyleSheet(QStringLiteral("border:none;"));
|
||||||
|
head->addWidget(showLbl);
|
||||||
|
r.show = new QCheckBox(this);
|
||||||
|
r.show->setChecked(def.show);
|
||||||
|
head->addWidget(r.show);
|
||||||
|
col->addLayout(head);
|
||||||
|
|
||||||
|
auto* range = new QHBoxLayout();
|
||||||
|
auto* loCol = new QVBoxLayout();
|
||||||
|
auto* loLbl = new QLabel(QStringLiteral("最小值"), this);
|
||||||
|
loLbl->setStyleSheet(QStringLiteral("border:none;color:#888;"));
|
||||||
|
loCol->addWidget(loLbl);
|
||||||
|
r.lo = new QDoubleSpinBox(this);
|
||||||
|
r.lo->setRange(-1e6, 1e6);
|
||||||
|
r.lo->setValue(def.min);
|
||||||
|
loCol->addWidget(r.lo);
|
||||||
|
range->addLayout(loCol);
|
||||||
|
auto* hiCol = new QVBoxLayout();
|
||||||
|
auto* hiLbl = new QLabel(QStringLiteral("最大值"), this);
|
||||||
|
hiLbl->setStyleSheet(QStringLiteral("border:none;color:#888;"));
|
||||||
|
hiCol->addWidget(hiLbl);
|
||||||
|
r.hi = new QDoubleSpinBox(this);
|
||||||
|
r.hi->setRange(-1e6, 1e6);
|
||||||
|
r.hi->setValue(def.max);
|
||||||
|
hiCol->addWidget(r.hi);
|
||||||
|
range->addLayout(hiCol);
|
||||||
|
col->addLayout(range);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxesSettingsPanel::setValues(AxisRange x, AxisRange y, AxisRange z, int unitIdx, double scale) {
|
||||||
|
auto wr = [](const Row& r, const AxisRange& a) {
|
||||||
|
r.show->setChecked(a.show);
|
||||||
|
r.lo->setValue(a.min);
|
||||||
|
r.hi->setValue(a.max);
|
||||||
|
};
|
||||||
|
wr(x_, x);
|
||||||
|
wr(y_, y);
|
||||||
|
wr(z_, z);
|
||||||
|
unit_->setCurrentIndex(unitIdx);
|
||||||
|
scale_->setCurrentText(QString::number(scale)); // 命中预设项则选中,否则保持
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace geopro::app
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
#include "AxesSettingsDialog.hpp" // AxisRange
|
||||||
|
|
||||||
|
class QCheckBox;
|
||||||
|
class QComboBox;
|
||||||
|
class QDoubleSpinBox;
|
||||||
|
class QVBoxLayout;
|
||||||
|
|
||||||
|
namespace geopro::app {
|
||||||
|
|
||||||
|
// 坐标轴设置抽屉面板(原型):工具条右侧滑出、非模态。
|
||||||
|
// 内容:坐标轴单位(米/英尺) → X/Y/Z 三轴(显示开关 + 最小值/最大值) → 放大系数(0.1/0.5/1/2/5) → 取消/应用。
|
||||||
|
class AxesSettingsPanel : public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit AxesSettingsPanel(QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
// 打开前回灌当前值(单位 0=米/1=英尺;scale=放大系数=垂直夸张)。
|
||||||
|
void setValues(AxisRange x, AxisRange y, AxisRange z, int unitIdx, double scale);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void applied(AxisRange x, AxisRange y, AxisRange z, int unitIdx, double scale);
|
||||||
|
void closed(); // × 或 取消
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Row {
|
||||||
|
QCheckBox* show = nullptr;
|
||||||
|
QDoubleSpinBox* lo = nullptr;
|
||||||
|
QDoubleSpinBox* hi = nullptr;
|
||||||
|
};
|
||||||
|
Row addAxisRow(QVBoxLayout* col, const QString& title, const AxisRange& def);
|
||||||
|
|
||||||
|
QComboBox* unit_ = nullptr; // 坐标轴单位:米 / 英尺
|
||||||
|
QComboBox* scale_ = nullptr; // 放大系数:0.1 / 0.5 / 1 / 2 / 5
|
||||||
|
Row x_, y_, z_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace geopro::app
|
||||||
|
|
@ -113,6 +113,7 @@ add_executable(geopro_desktop WIN32
|
||||||
DatasetCategory.cpp
|
DatasetCategory.cpp
|
||||||
VtkViewToolbar.cpp
|
VtkViewToolbar.cpp
|
||||||
AxesSettingsDialog.cpp
|
AxesSettingsDialog.cpp
|
||||||
|
AxesSettingsPanel.cpp
|
||||||
TileBasemap.cpp)
|
TileBasemap.cpp)
|
||||||
|
|
||||||
target_include_directories(geopro_desktop PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(geopro_desktop PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@
|
||||||
#include "panels/columns/CategorySection.hpp"
|
#include "panels/columns/CategorySection.hpp"
|
||||||
#include "VtkViewToolbar.hpp"
|
#include "VtkViewToolbar.hpp"
|
||||||
#include "AxesSettingsDialog.hpp"
|
#include "AxesSettingsDialog.hpp"
|
||||||
|
#include "AxesSettingsPanel.hpp"
|
||||||
#include "repo/DatasetFieldDictionary.hpp"
|
#include "repo/DatasetFieldDictionary.hpp"
|
||||||
#include "panels/columns/Column3DDataset.hpp"
|
#include "panels/columns/Column3DDataset.hpp"
|
||||||
#include "panels/columns/Column2DDataset.hpp"
|
#include "panels/columns/Column2DDataset.hpp"
|
||||||
|
|
@ -395,6 +396,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
viewToolbar->move(12, 12);
|
viewToolbar->move(12, 12);
|
||||||
viewToolbar->raise();
|
viewToolbar->raise();
|
||||||
viewToolbar->show();
|
viewToolbar->show();
|
||||||
|
// 坐标轴设置抽屉面板:叠加 vtkWidget、工具条右侧滑出,默认隐藏(点设置 toggle)。
|
||||||
|
auto* axesPanel = new geopro::app::AxesSettingsPanel(vtkWidget);
|
||||||
|
axesPanel->hide();
|
||||||
|
|
||||||
// 3b:三维分析栏勾选的已保存切片(dd_slice) id 集合 + 调和函数。
|
// 3b:三维分析栏勾选的已保存切片(dd_slice) id 集合 + 调和函数。
|
||||||
// syncSlices:按"当前活动体 dsId"调和 InteractionManager 上显示的已保存切片——
|
// syncSlices:按"当前活动体 dsId"调和 InteractionManager 上显示的已保存切片——
|
||||||
|
|
@ -713,15 +717,20 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
&geopro::controller::VtkSceneController::zoomOut);
|
&geopro::controller::VtkSceneController::zoomOut);
|
||||||
QObject::connect(viewToolbar, &geopro::app::VtkViewToolbar::fitRequested, sceneCtrl,
|
QObject::connect(viewToolbar, &geopro::app::VtkViewToolbar::fitRequested, sceneCtrl,
|
||||||
&geopro::controller::VtkSceneController::fit);
|
&geopro::controller::VtkSceneController::fit);
|
||||||
|
// 设置(⚙)→ 工具条右侧 toggle 抽屉面板(非模态弹窗)。
|
||||||
QObject::connect(viewToolbar, &geopro::app::VtkViewToolbar::axesSettingsRequested, &window,
|
QObject::connect(viewToolbar, &geopro::app::VtkViewToolbar::axesSettingsRequested, &window,
|
||||||
[&window, sceneCtrl]() {
|
[axesPanel, viewToolbar]() {
|
||||||
geopro::app::AxesSettingsDialog dlg({}, {}, {}, &window);
|
if (axesPanel->isVisible()) {
|
||||||
if (dlg.exec() != QDialog::Accepted) return;
|
axesPanel->hide();
|
||||||
const bool anyShow = dlg.x().show || dlg.y().show || dlg.z().show;
|
return;
|
||||||
sceneCtrl->setAxesMode(anyShow ? geopro::controller::AxesMode::Standard
|
}
|
||||||
: geopro::controller::AxesMode::None);
|
axesPanel->adjustSize();
|
||||||
// per-axis min/max 范围待 VtkSceneController 加坐标轴范围 API 后接入。
|
axesPanel->move(viewToolbar->x() + viewToolbar->width() + 8, viewToolbar->y());
|
||||||
|
axesPanel->raise();
|
||||||
|
axesPanel->show();
|
||||||
});
|
});
|
||||||
|
QObject::connect(axesPanel, &geopro::app::AxesSettingsPanel::closed, &window,
|
||||||
|
[axesPanel]() { axesPanel->hide(); });
|
||||||
// 三维数据集栏勾选(反演剖面)→ 并入渲染勾选集(剖面走帘面路径)。
|
// 三维数据集栏勾选(反演剖面)→ 并入渲染勾选集(剖面走帘面路径)。
|
||||||
QObject::connect(c3, &geopro::app::Column3DDataset::checkedDatasetsChanged, sceneCtrl,
|
QObject::connect(c3, &geopro::app::Column3DDataset::checkedDatasetsChanged, sceneCtrl,
|
||||||
[checkedProfiles, pushChecked](const QStringList& ids) {
|
[checkedProfiles, pushChecked](const QStringList& ids) {
|
||||||
|
|
@ -1071,6 +1080,20 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
// 单一来源:kVerticalExaggeration 一处定义,组合根下发到 控制器(上方259) / 底图 / UI 显示。
|
// 单一来源:kVerticalExaggeration 一处定义,组合根下发到 控制器(上方259) / 底图 / UI 显示。
|
||||||
basemap->setVerticalExaggeration(kVerticalExaggeration);
|
basemap->setVerticalExaggeration(kVerticalExaggeration);
|
||||||
drawer->col3D()->setVerticalExaggeration(kVerticalExaggeration);
|
drawer->col3D()->setVerticalExaggeration(kVerticalExaggeration);
|
||||||
|
// 坐标轴设置抽屉「应用」:轴显示开关 + 放大系数(=垂直夸张,下发控制器+底图);范围/单位待控制器 API。
|
||||||
|
QObject::connect(axesPanel, &geopro::app::AxesSettingsPanel::applied, &window,
|
||||||
|
[axesPanel, sceneCtrl, basemap](geopro::app::AxisRange x, geopro::app::AxisRange y,
|
||||||
|
geopro::app::AxisRange z, int /*unitIdx*/,
|
||||||
|
double scale) {
|
||||||
|
const bool anyShow = x.show || y.show || z.show;
|
||||||
|
sceneCtrl->setAxesMode(anyShow ? geopro::controller::AxesMode::Standard
|
||||||
|
: geopro::controller::AxesMode::None);
|
||||||
|
if (scale > 0) {
|
||||||
|
sceneCtrl->setVerticalExaggeration(scale);
|
||||||
|
basemap->setVerticalExaggeration(scale);
|
||||||
|
}
|
||||||
|
axesPanel->hide();
|
||||||
|
});
|
||||||
|
|
||||||
// ── 中央“空状态”引导浮层:未接入真实 sections 时,引导首次使用者从左侧入手。──
|
// ── 中央“空状态”引导浮层:未接入真实 sections 时,引导首次使用者从左侧入手。──
|
||||||
// 透明背景 + 鼠标穿透(不挡 QVTK 交互);CenterOverlay 随视口尺寸保持居中;
|
// 透明背景 + 鼠标穿透(不挡 QVTK 交互);CenterOverlay 随视口尺寸保持居中;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue