diff --git a/src/app/main.cpp b/src/app/main.cpp index 8e8d197..d28aa83 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -853,7 +853,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re pushChecked(); // 体/其它 → 控制器(增删图元,可能触发 onVolumeChanged→syncSlices) syncSlices(); // 切片勾选变化即时调和(父体已在场时立即显隐) }); - QObject::connect(ca, &geopro::app::Column3DAnalysis::sliceRequested, vtkWidget, + QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::sliceRequested, vtkWidget, [interactionMgr](geopro::render::interact::SliceAxis axis) { interactionMgr->addSlice(axis); }); @@ -884,7 +884,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re [](const std::string&) {}); }); // 列表切片「保存」=把当前(可能被拖动过的)位姿覆盖更新到该 dd_slice;须该切片正在渲染才有位姿可取。 - QObject::connect(ca, &geopro::app::Column3DAnalysis::sliceSaveRequested, &window, + QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::sliceSaveRequested, &window, [&window, interactionMgr, scene3dRepo, sceneView](const QString& dsId) { if (!interactionMgr->selectSavedSlice(dsId.toStdString())) { QMessageBox::information(&window, QStringLiteral("保存"), @@ -904,7 +904,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re [](const std::string&) {}); }); // 列表切片「保存为」=以该切片当前(存储)位姿另存为新 dd_slice(不依赖渲染)。 - QObject::connect(ca, &geopro::app::Column3DAnalysis::sliceSaveAsRequested, &window, + QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::sliceSaveAsRequested, &window, [&window, scene3dRepo, refreshAnalysis](const QString& dsId) { geopro::data::I3dSceneRepository::SliceSpec spec; if (!scene3dRepo->sliceSpec(dsId.toStdString(), spec)) return; @@ -919,7 +919,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re [](const std::string&) {}); }); // 列表切片「导出▸图片」:定位到渲染中的该切片 → 导出其上色 2D 图。 - QObject::connect(ca, &geopro::app::Column3DAnalysis::sliceExportImageRequested, &window, + QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::sliceExportImageRequested, &window, [&window, interactionMgr](const QString& dsId) { if (!interactionMgr->selectSavedSlice(dsId.toStdString())) { QMessageBox::information(&window, QStringLiteral("导出"), @@ -937,7 +937,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re QStringLiteral("导出失败。")); }); // 列表切片「导出▸dat」:定位到渲染中的该切片 → 导出其重采样标量网格。 - QObject::connect(ca, &geopro::app::Column3DAnalysis::sliceExportDatRequested, &window, + QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::sliceExportDatRequested, &window, [&window, interactionMgr](const QString& dsId) { if (!interactionMgr->selectSavedSlice(dsId.toStdString())) { QMessageBox::information(&window, QStringLiteral("导出"), @@ -956,7 +956,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re }); // 色阶(三维体/切片):复刻原版「色阶配置」对话框,确定后体素 + 其切片随新色阶重渲染。 // 仅对当前已渲染的三维体生效(切片色阶继承体色阶,经 InteractionManager 重建)。 - QObject::connect(ca, &geopro::app::Column3DAnalysis::colorScaleRequested, &window, + QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::colorScaleRequested, &window, [&window, &colorTplRepo, &nav, sceneCtrl, sceneView](const QString& qid) { const std::string dsId = qid.toStdString(); if (sceneView->currentVolumeDsId() != dsId || !sceneView->hasVolume()) { @@ -998,7 +998,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re QObject::connect(ca, &geopro::app::Column3DAnalysis::anomalyDisplayFilterChanged, vtkWidget, [refreshAnomalies](int) { refreshAnomalies(); }); // 单条显隐 → 切该异常 actor 可见性。 - QObject::connect(ca, &geopro::app::Column3DAnalysis::anomalyVisibilityChanged, vtkWidget, + QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::anomalyVisibilityChanged, vtkWidget, [sceneView, renderWindowPtr](const QString& id, bool vis) { sceneView->setAnomalyVisible(id.toStdString(), vis); renderWindowPtr->Render(); diff --git a/src/app/panels/columns/CategoryAnalysisTab.cpp b/src/app/panels/columns/CategoryAnalysisTab.cpp index 4c42df4..aae0e37 100644 --- a/src/app/panels/columns/CategoryAnalysisTab.cpp +++ b/src/app/panels/columns/CategoryAnalysisTab.cpp @@ -39,6 +39,16 @@ CategoryAnalysisTab::CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* d connect(sec, &CategorySection::detailRequested, this, &CategoryAnalysisTab::detailRequested); connect(sec, &CategorySection::deleteDatasetRequested, this, &CategoryAnalysisTab::deleteDatasetRequested); + connect(sec, &CategorySection::sliceRequested, this, &CategoryAnalysisTab::sliceRequested); + connect(sec, &CategorySection::colorScaleRequested, this, &CategoryAnalysisTab::colorScaleRequested); + connect(sec, &CategorySection::sliceSaveRequested, this, &CategoryAnalysisTab::sliceSaveRequested); + connect(sec, &CategorySection::sliceSaveAsRequested, this, &CategoryAnalysisTab::sliceSaveAsRequested); + connect(sec, &CategorySection::sliceExportImageRequested, this, + &CategoryAnalysisTab::sliceExportImageRequested); + connect(sec, &CategorySection::sliceExportDatRequested, this, + &CategoryAnalysisTab::sliceExportDatRequested); + connect(sec, &CategorySection::anomalyVisibilityChanged, this, + &CategoryAnalysisTab::anomalyVisibilityChanged); col->addWidget(sec); } col->addStretch(1); diff --git a/src/app/panels/columns/CategoryAnalysisTab.hpp b/src/app/panels/columns/CategoryAnalysisTab.hpp index 73fd6f5..42c8335 100644 --- a/src/app/panels/columns/CategoryAnalysisTab.hpp +++ b/src/app/panels/columns/CategoryAnalysisTab.hpp @@ -5,6 +5,7 @@ #include #include #include "DatasetCategory.hpp" // CategoryBuckets +#include "interact/SlicePlaneMath.hpp" // geopro::render::interact::SliceAxis #include "repo/RepoTypes.hpp" namespace geopro::data { @@ -31,6 +32,14 @@ signals: void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds); void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除切片/异常 + // ── 三维体段操作转发(迁自旧 Column3DAnalysis,全接)── + void sliceRequested(geopro::render::interact::SliceAxis axis); + void colorScaleRequested(const QString& dsId); + void sliceSaveRequested(const QString& dsId); + void sliceSaveAsRequested(const QString& dsId); + void sliceExportImageRequested(const QString& dsId); + void sliceExportDatRequested(const QString& dsId); + void anomalyVisibilityChanged(const QString& dsId, bool vis); private: void recomputeCheckedUnion(); diff --git a/src/app/panels/columns/CategorySection.cpp b/src/app/panels/columns/CategorySection.cpp index 06b9dcb..6f8bd0e 100644 --- a/src/app/panels/columns/CategorySection.cpp +++ b/src/app/panels/columns/CategorySection.cpp @@ -195,6 +195,7 @@ QStringList CategorySection::checkedDsIds() const { void CategorySection::emitChecked() { emit checkedDatasetsChanged(checkedDsIds()); } void CategorySection::showContextMenu(const QPoint& pos) { + using geopro::render::interact::SliceAxis; QTreeWidgetItem* it = list_->itemAt(pos); if (!it) return; const QString id = it->data(0, kDsIdRole).toString(); @@ -204,10 +205,27 @@ void CategorySection::showContextMenu(const QPoint& pos) { QMenu menu(this); menu.addAction(QStringLiteral("详情"), this, [this, id, ddCode, name] { emit detailRequested(id, ddCode, name); }); - // 切片 / 异常可删除(三维体段无 deleteVolume 端点)。 - if (ddCode == QStringLiteral("dd_slice") || ddCode == QStringLiteral("dd_anomaly")) { - menu.addAction(QStringLiteral("删除"), this, - [this, id, ddCode] { emit deleteDatasetRequested(id, ddCode); }); + if (ddCode == QStringLiteral("dd_voxel")) { // 三维体 + QMenu* sl = menu.addMenu(QStringLiteral("生成切片")); + sl->addAction(QStringLiteral("上下"), this, [this] { emit sliceRequested(SliceAxis::UpDown); }); + sl->addAction(QStringLiteral("前后"), this, [this] { emit sliceRequested(SliceAxis::FrontBack); }); + sl->addAction(QStringLiteral("左右"), this, [this] { emit sliceRequested(SliceAxis::LeftRight); }); + sl->addAction(QStringLiteral("任意"), this, [this] { emit sliceRequested(SliceAxis::Oblique); }); + menu.addAction(QStringLiteral("色阶…"), this, [this, id] { emit colorScaleRequested(id); }); + } else if (ddCode == QStringLiteral("dd_slice")) { // 切片 + menu.addAction(QStringLiteral("保存位姿"), this, [this, id] { emit sliceSaveRequested(id); }); + menu.addAction(QStringLiteral("另存为…"), this, [this, id] { emit sliceSaveAsRequested(id); }); + QMenu* ex = menu.addMenu(QStringLiteral("导出")); + ex->addAction(QStringLiteral("图片"), this, [this, id] { emit sliceExportImageRequested(id); }); + ex->addAction(QStringLiteral("dat"), this, [this, id] { emit sliceExportDatRequested(id); }); + menu.addAction(QStringLiteral("色阶…"), this, [this, id] { emit colorScaleRequested(id); }); + menu.addSeparator(); + menu.addAction(QStringLiteral("删除"), this, [this, id, ddCode] { emit deleteDatasetRequested(id, ddCode); }); + } else if (ddCode == QStringLiteral("dd_anomaly")) { // 异常 + menu.addAction(QStringLiteral("显示"), this, [this, id] { emit anomalyVisibilityChanged(id, true); }); + menu.addAction(QStringLiteral("隐藏"), this, [this, id] { emit anomalyVisibilityChanged(id, false); }); + menu.addSeparator(); + menu.addAction(QStringLiteral("删除"), this, [this, id, ddCode] { emit deleteDatasetRequested(id, ddCode); }); } menu.exec(list_->viewport()->mapToGlobal(pos)); } diff --git a/src/app/panels/columns/CategorySection.hpp b/src/app/panels/columns/CategorySection.hpp index f671f58..af8c195 100644 --- a/src/app/panels/columns/CategorySection.hpp +++ b/src/app/panels/columns/CategorySection.hpp @@ -2,6 +2,7 @@ #include #include #include +#include "interact/SlicePlaneMath.hpp" // geopro::render::interact::SliceAxis #include "repo/CategoryConfig.hpp" #include "repo/RepoTypes.hpp" @@ -38,6 +39,14 @@ signals: void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds); // 段头「+新增三维体」 void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 双击/右键=详情 void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除(切片/异常) + // ── 三维体段右键操作(迁自旧 Column3DAnalysis,全接)── + void sliceRequested(geopro::render::interact::SliceAxis axis); // 体→生成切片(轴) + void colorScaleRequested(const QString& dsId); // 体/切片→色阶 + void sliceSaveRequested(const QString& dsId); // 切片→保存位姿 + void sliceSaveAsRequested(const QString& dsId); // 切片→另存 + void sliceExportImageRequested(const QString& dsId); // 切片→导出图片 + void sliceExportDatRequested(const QString& dsId); // 切片→导出 dat + void anomalyVisibilityChanged(const QString& dsId, bool vis); // 异常→显示/隐藏 private: void showContextMenu(const QPoint& pos); // 段体树右键菜单(详情 + 删除)