feat/vtk-3d-view #7
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "interact/InteractionManager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
|
||||
|
|
@ -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<int>(i);
|
||||
int idx = -1;
|
||||
for (std::size_t i = 0; i < slices_.size(); ++i)
|
||||
if (slices_[i].get() == tool) { idx = static_cast<int>(i); break; }
|
||||
if (idx < 0) return;
|
||||
selected_ = idx;
|
||||
updateSelectionVisual();
|
||||
safeRender();
|
||||
|
||||
// 双击切片正视(D40):同一切片在 350ms 内两次交互 → 视为双击 → 正视。
|
||||
const double now = std::chrono::duration<double, std::milli>(
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(上层据此设为选中)。
|
||||
|
|
|
|||
Loading…
Reference in New Issue