diff --git a/src/app/main.cpp b/src/app/main.cpp index 52ccc2d..4b872d2 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -543,7 +543,6 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re auto* btnSliceFrontBack = new QPushButton(QStringLiteral("前后")); auto* btnSliceLeftRight = new QPushButton(QStringLiteral("左右")); auto* btnSliceOblique = new QPushButton(QStringLiteral("任意")); - auto* btnSliceFace = new QPushButton(QStringLiteral("正视")); // 正视选中切片(E54) auto* btnSliceFlip = new QPushButton(QStringLiteral("翻转")); auto* btnSliceClose = new QPushButton(QStringLiteral("关闭")); sliceLayout->addWidget(sliceLabel); @@ -551,7 +550,6 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re sliceLayout->addWidget(btnSliceFrontBack); sliceLayout->addWidget(btnSliceLeftRight); sliceLayout->addWidget(btnSliceOblique); - sliceLayout->addWidget(btnSliceFace); sliceLayout->addWidget(btnSliceFlip); sliceLayout->addWidget(btnSliceClose); sliceBar->setVisible(false); // 默认二维,不显示 @@ -559,14 +557,13 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re // 切片按钮可用性:仅三维 + 有体素时创建/翻转可用;关闭仅在有切片时可用。 auto updateSliceButtons = [interactionMgr, btnSliceUpDown, btnSliceFrontBack, btnSliceLeftRight, - btnSliceOblique, btnSliceFace, btnSliceFlip, btnSliceClose, sceneView]() { + btnSliceOblique, btnSliceFlip, btnSliceClose, sceneView]() { const bool canSlice = sceneView->hasVolume() && interactionMgr->hasVolume(); btnSliceUpDown->setEnabled(canSlice); btnSliceFrontBack->setEnabled(canSlice); btnSliceLeftRight->setEnabled(canSlice); btnSliceOblique->setEnabled(canSlice); btnSliceFlip->setEnabled(canSlice); - btnSliceFace->setEnabled(interactionMgr->hasSlices()); // 正视需有(选中)切片 btnSliceClose->setEnabled(interactionMgr->hasSlices()); }; updateSliceButtons(); @@ -584,8 +581,6 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re [addSlice]() { addSlice(SliceAxis::LeftRight); }); QObject::connect(btnSliceOblique, &QPushButton::clicked, vtkWidget, [addSlice]() { addSlice(SliceAxis::Oblique); }); - QObject::connect(btnSliceFace, &QPushButton::clicked, vtkWidget, - [interactionMgr]() { interactionMgr->faceSelected(); }); QObject::connect(btnSliceFlip, &QPushButton::clicked, vtkWidget, [interactionMgr]() { interactionMgr->flipView(); }); QObject::connect(btnSliceClose, &QPushButton::clicked, vtkWidget, diff --git a/src/render/interact/InteractionManager.cpp b/src/render/interact/InteractionManager.cpp index e67fca1..e05a4a4 100644 --- a/src/render/interact/InteractionManager.cpp +++ b/src/render/interact/InteractionManager.cpp @@ -1,6 +1,7 @@ #include "interact/InteractionManager.hpp" #include +#include #include #include @@ -87,14 +88,27 @@ void InteractionManager::addSlice(SliceAxis axis) { } void InteractionManager::selectByTool(const SliceTool* tool) { - for (std::size_t i = 0; i < slices_.size(); ++i) { - if (slices_[i].get() == tool) { - selected_ = static_cast(i); - updateSelectionVisual(); - safeRender(); - return; - } + int idx = -1; + for (std::size_t i = 0; i < slices_.size(); ++i) + if (slices_[i].get() == tool) { idx = static_cast(i); break; } + if (idx < 0) return; + selected_ = idx; + updateSelectionVisual(); + + // 双击切片正视(D40):同一切片在 350ms 内两次交互 → 视为双击 → 正视。 + const double now = std::chrono::duration( + std::chrono::steady_clock::now().time_since_epoch()) + .count(); + const bool dbl = (tool == lastInteractTool_) && lastInteractMs_ >= 0.0 && + (now - lastInteractMs_) < 350.0; + lastInteractMs_ = now; + lastInteractTool_ = tool; + if (dbl) { + lastInteractMs_ = -1.0; // 重置避免三连判 + faceSlice(idx); + return; } + safeRender(); } void InteractionManager::closeSelected() { diff --git a/src/render/interact/InteractionManager.hpp b/src/render/interact/InteractionManager.hpp index 974196c..486eaa8 100644 --- a/src/render/interact/InteractionManager.hpp +++ b/src/render/interact/InteractionManager.hpp @@ -98,6 +98,11 @@ private: // 析构进行中:closeAll() 跳过 renderWindow_->Render()(Qt 拆台时窗口可能已半析构, // 析构期再 Render 易崩,评审 M3)。 bool destroying_ = false; + + // 双击切片正视(D40)检测:同一切片在阈值内两次交互(StartInteractionEvent)视为双击 → 正视。 + // 因 widget 开启交互后独占切面事件,双击靠监听 widget 交互判定,而非 InteractorStyle。 + double lastInteractMs_ = -1.0; + const SliceTool* lastInteractTool_ = nullptr; }; } // namespace geopro::render::interact diff --git a/src/render/interact/SliceTool.cpp b/src/render/interact/SliceTool.cpp index 39a6d94..19b92ce 100644 --- a/src/render/interact/SliceTool.cpp +++ b/src/render/interact/SliceTool.cpp @@ -78,6 +78,11 @@ SliceTool::SliceTool(vtkImageData* image, vtkRenderWindowInteractor* interactor, } } + // 照原型配置(f57291a):左键拖动=移动切面(默认左键是窗位调整,无用);中键=取值光标。 + // 切面边缘(margins)拖动可旋转切面 → 任意切片"可任意调整角度"(F25)。 + widget_->SetLeftButtonAction(vtkImagePlaneWidget::VTK_SLICE_MOTION_ACTION); + widget_->SetMiddleButtonAction(vtkImagePlaneWidget::VTK_CURSOR_ACTION); + widget_->On(); // 保持 widget 交互开启:任意切片可拖动调整角度/位置(F25 '可任意调整')。 // 监听其交互开始事件 → 触碰本切片即回调 onInteract(上层据此设为选中)。