fix(app): 视图模式三按钮(二维/三维/三维体素)互斥连贯 — 切2D/3D回剖面,体素自身高亮
This commit is contained in:
parent
0413e4359a
commit
39b97ffb70
|
|
@ -220,6 +220,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
act2D->setChecked(true); // 默认二维
|
act2D->setChecked(true); // 默认二维
|
||||||
viewToolBar->addSeparator();
|
viewToolBar->addSeparator();
|
||||||
auto* actVoxel = viewToolBar->addAction(QStringLiteral("三维体素"));
|
auto* actVoxel = viewToolBar->addAction(QStringLiteral("三维体素"));
|
||||||
|
// 三按钮做成统一互斥的"3 路视图模式":任意时刻恰一个勾选。
|
||||||
|
actVoxel->setCheckable(true);
|
||||||
|
cameraGroup->addAction(actVoxel);
|
||||||
centerLayout->addWidget(viewToolBar);
|
centerLayout->addWidget(viewToolBar);
|
||||||
centerLayout->addWidget(vtkWidget, 1);
|
centerLayout->addWidget(vtkWidget, 1);
|
||||||
|
|
||||||
|
|
@ -231,21 +234,6 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
if (sliceWidget->Get()) (*sliceWidget)->Off();
|
if (sliceWidget->Get()) (*sliceWidget)->Off();
|
||||||
};
|
};
|
||||||
|
|
||||||
QObject::connect(act2D, &QAction::triggered, vtkWidget,
|
|
||||||
[cameraMode, rendererPtr, renderWindowPtr, hideSlice]() {
|
|
||||||
*cameraMode = CameraMode::Top2D;
|
|
||||||
hideSlice(); // 切回剖面视图:关闭体素切片
|
|
||||||
geopro::render::applyTop2D(rendererPtr);
|
|
||||||
renderWindowPtr->Render();
|
|
||||||
});
|
|
||||||
QObject::connect(act3D, &QAction::triggered, vtkWidget,
|
|
||||||
[cameraMode, rendererPtr, renderWindowPtr, hideSlice]() {
|
|
||||||
*cameraMode = CameraMode::Free3D;
|
|
||||||
hideSlice();
|
|
||||||
geopro::render::applyFree3D(rendererPtr);
|
|
||||||
renderWindowPtr->Render();
|
|
||||||
});
|
|
||||||
|
|
||||||
auto* vtkDock = new ads::CDockWidget(QStringLiteral("剖面视图"));
|
auto* vtkDock = new ads::CDockWidget(QStringLiteral("剖面视图"));
|
||||||
vtkDock->setWidget(centerWidget);
|
vtkDock->setWidget(centerWidget);
|
||||||
dockManager->addDockWidget(ads::CenterDockWidgetArea, vtkDock);
|
dockManager->addDockWidget(ads::CenterDockWidgetArea, vtkDock);
|
||||||
|
|
@ -267,16 +255,21 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
rightDock->setWidget(propLabel);
|
rightDock->setWidget(propLabel);
|
||||||
dockManager->addDockWidget(ads::RightDockWidgetArea, rightDock);
|
dockManager->addDockWidget(ads::RightDockWidgetArea, rightDock);
|
||||||
|
|
||||||
// 联动:点击 DS 项 → 加载 grid/colorScale → 渲染 + 更新属性。
|
// 视图模式状态:当前数据集 id / 名称(供「二维/三维」按钮重渲染剖面用)。
|
||||||
|
auto currentDsId = std::make_shared<QString>();
|
||||||
|
auto currentDsName = std::make_shared<QString>();
|
||||||
|
|
||||||
|
// 渲染当前数据集的【剖面】:按 *cameraMode 选相机;体素态切回剖面也走这里。
|
||||||
// Scene/renderWindow 按【裸指针值】捕获:Scene 挂 window 父链、renderer 被 renderWindow
|
// Scene/renderWindow 按【裸指针值】捕获:Scene 挂 window 父链、renderer 被 renderWindow
|
||||||
// 引用计数持有,生命周期覆盖事件循环。repo 由调用方保活。
|
// 引用计数持有,生命周期覆盖事件循环。repo 由调用方保活。
|
||||||
auto renderDataset = [&repo, scene, renderWindowPtr, applyCurrentCamera, propLabel](
|
auto renderSectionCurrent =
|
||||||
QTreeWidgetItem* item) {
|
[&repo, scene, renderWindowPtr, applyCurrentCamera, hideSlice, propLabel, currentDsId,
|
||||||
const QString id = item->data(0, Qt::UserRole).toString();
|
currentDsName]() {
|
||||||
if (id.isEmpty()) return; // GS/TM 节点无 dsId,忽略
|
if (currentDsId->isEmpty()) return; // 还没有选中任何数据集
|
||||||
const std::string dsId = id.toStdString();
|
const std::string dsId = currentDsId->toStdString();
|
||||||
const auto g = repo.loadGrid(dsId);
|
const auto g = repo.loadGrid(dsId);
|
||||||
const auto cs = repo.loadColorScale(dsId);
|
const auto cs = repo.loadColorScale(dsId);
|
||||||
|
hideSlice(); // 回到剖面视图:关闭可能存在的体素切片
|
||||||
scene->clear();
|
scene->clear();
|
||||||
const auto actors = geopro::render::buildGridContour(g, cs);
|
const auto actors = geopro::render::buildGridContour(g, cs);
|
||||||
scene->addActor(actors.bands);
|
scene->addActor(actors.bands);
|
||||||
|
|
@ -284,22 +277,46 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
applyCurrentCamera(); // 按当前 2D/3D 模式重设相机
|
applyCurrentCamera(); // 按当前 2D/3D 模式重设相机
|
||||||
renderWindowPtr->Render();
|
renderWindowPtr->Render();
|
||||||
propLabel->setText(QStringLiteral("数据集: %1\n网格: %2 x %3\nvmin / vmax: %4 / %5")
|
propLabel->setText(QStringLiteral("数据集: %1\n网格: %2 x %3\nvmin / vmax: %4 / %5")
|
||||||
.arg(item->text(0))
|
.arg(*currentDsName)
|
||||||
.arg(g.nx())
|
.arg(g.nx())
|
||||||
.arg(g.ny())
|
.arg(g.ny())
|
||||||
.arg(g.vmin)
|
.arg(g.vmin)
|
||||||
.arg(g.vmax));
|
.arg(g.vmax));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 联动:点击 DS 项 → 记为当前数据集 → 默认回到二维剖面(勾「二维」+ 俯视)。
|
||||||
|
auto renderDataset = [currentDsId, currentDsName, cameraMode, act2D, renderSectionCurrent](
|
||||||
|
QTreeWidgetItem* item) {
|
||||||
|
const QString id = item->data(0, Qt::UserRole).toString();
|
||||||
|
if (id.isEmpty()) return; // GS/TM 节点无 dsId,忽略
|
||||||
|
*currentDsId = id;
|
||||||
|
*currentDsName = item->text(0);
|
||||||
|
*cameraMode = CameraMode::Top2D;
|
||||||
|
act2D->setChecked(true); // 点数据集默认回到二维剖面
|
||||||
|
renderSectionCurrent();
|
||||||
|
};
|
||||||
|
|
||||||
QObject::connect(tree, &QTreeWidget::itemClicked, tree,
|
QObject::connect(tree, &QTreeWidget::itemClicked, tree,
|
||||||
[renderDataset](QTreeWidgetItem* it, int) { renderDataset(it); });
|
[renderDataset](QTreeWidgetItem* it, int) { renderDataset(it); });
|
||||||
|
|
||||||
|
// 视图模式:二维 = 剖面 + 俯视;三维 = 剖面 + 斜视。两者都重渲染当前剖面。
|
||||||
|
QObject::connect(act2D, &QAction::triggered, vtkWidget,
|
||||||
|
[cameraMode, renderSectionCurrent]() {
|
||||||
|
*cameraMode = CameraMode::Top2D;
|
||||||
|
renderSectionCurrent();
|
||||||
|
});
|
||||||
|
QObject::connect(act3D, &QAction::triggered, vtkWidget,
|
||||||
|
[cameraMode, renderSectionCurrent]() {
|
||||||
|
*cameraMode = CameraMode::Free3D;
|
||||||
|
renderSectionCurrent();
|
||||||
|
});
|
||||||
|
|
||||||
// 当前体素 vtkImageData(dd_slice 切面 widget 需复用,保活到下次重建)。
|
// 当前体素 vtkImageData(dd_slice 切面 widget 需复用,保活到下次重建)。
|
||||||
auto voxelImage = std::make_shared<vtkSmartPointer<vtkImageData>>();
|
auto voxelImage = std::make_shared<vtkSmartPointer<vtkImageData>>();
|
||||||
|
|
||||||
// dd_voxel:读两条交叉剖面 → IDW 体素 → GPU 体绘制 + 默认 3D 视角 + 可拖切片。
|
// dd_voxel:读两条交叉剖面 → IDW 体素 → GPU 体绘制 + 默认 3D 视角 + 可拖切片。
|
||||||
QObject::connect(actVoxel, &QAction::triggered, vtkWidget,
|
QObject::connect(actVoxel, &QAction::triggered, vtkWidget,
|
||||||
[&repo, scene, rendererPtr, renderWindowPtr, cameraMode, act3D, propLabel,
|
[&repo, scene, rendererPtr, renderWindowPtr, cameraMode, actVoxel, propLabel,
|
||||||
sliceWidget, voxelImage]() {
|
sliceWidget, voxelImage]() {
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
const auto scatters = repo.loadVoxelScatters();
|
const auto scatters = repo.loadVoxelScatters();
|
||||||
|
|
@ -318,9 +335,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
rendererPtr->AddViewProp(result.volume);
|
rendererPtr->AddViewProp(result.volume);
|
||||||
*voxelImage = result.image;
|
*voxelImage = result.image;
|
||||||
|
|
||||||
// 体素默认 3D 视角(同步工具条勾选态)。
|
// 体素 = 体块 + 3D 视角;高亮「三维体素」自身(互斥组会清掉 2D/3D)。
|
||||||
*cameraMode = CameraMode::Free3D;
|
*cameraMode = CameraMode::Free3D;
|
||||||
act3D->setChecked(true);
|
actVoxel->setChecked(true);
|
||||||
geopro::render::applyFree3D(rendererPtr);
|
geopro::render::applyFree3D(rendererPtr);
|
||||||
rendererPtr->ResetCamera();
|
rendererPtr->ResetCamera();
|
||||||
renderWindowPtr->Render(); // 先渲一帧确保 interactor 就绪
|
renderWindowPtr->Render(); // 先渲一帧确保 interactor 就绪
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue