fix(vtk): 恢复原型切片可拖动配置(SLICE_MOTION)+双击正视(去按钮)
据用户指出'原型阶段切片可拖动调整',查 git(f57291a)原型配置:
SetLeftButtonAction(VTK_SLICE_MOTION_ACTION) + SetMiddleButtonAction(VTK_CURSOR_ACTION)
我的 SliceTool 漏了这两行→默认左键是窗位调整(无用)→拖切片面无反应=用户的'不能调'。
- 补回两行: 左键拖动=移动切面; 切面边缘 margins 拖动=旋转角度(F25 任意切片可调)。
- 双击正视(D40)改用 widget StartInteractionEvent 检测(同一切片350ms内两次=双击→正视),
恢复 spec 的双击交互, 去掉上一版擅自加的'正视'按钮(改了需求, 错)。
- 选中=触碰(onInteract); 滚轮/关闭=选中切片; 相机旋转=空白处拖动。ctest 221/221
This commit is contained in:
parent
87c5cc910e
commit
f3a1ba9f99
|
|
@ -543,7 +543,6 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
auto* btnSliceFrontBack = new QPushButton(QStringLiteral("前后"));
|
auto* btnSliceFrontBack = new QPushButton(QStringLiteral("前后"));
|
||||||
auto* btnSliceLeftRight = new QPushButton(QStringLiteral("左右"));
|
auto* btnSliceLeftRight = new QPushButton(QStringLiteral("左右"));
|
||||||
auto* btnSliceOblique = new QPushButton(QStringLiteral("任意"));
|
auto* btnSliceOblique = new QPushButton(QStringLiteral("任意"));
|
||||||
auto* btnSliceFace = new QPushButton(QStringLiteral("正视")); // 正视选中切片(E54)
|
|
||||||
auto* btnSliceFlip = new QPushButton(QStringLiteral("翻转"));
|
auto* btnSliceFlip = new QPushButton(QStringLiteral("翻转"));
|
||||||
auto* btnSliceClose = new QPushButton(QStringLiteral("关闭"));
|
auto* btnSliceClose = new QPushButton(QStringLiteral("关闭"));
|
||||||
sliceLayout->addWidget(sliceLabel);
|
sliceLayout->addWidget(sliceLabel);
|
||||||
|
|
@ -551,7 +550,6 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
sliceLayout->addWidget(btnSliceFrontBack);
|
sliceLayout->addWidget(btnSliceFrontBack);
|
||||||
sliceLayout->addWidget(btnSliceLeftRight);
|
sliceLayout->addWidget(btnSliceLeftRight);
|
||||||
sliceLayout->addWidget(btnSliceOblique);
|
sliceLayout->addWidget(btnSliceOblique);
|
||||||
sliceLayout->addWidget(btnSliceFace);
|
|
||||||
sliceLayout->addWidget(btnSliceFlip);
|
sliceLayout->addWidget(btnSliceFlip);
|
||||||
sliceLayout->addWidget(btnSliceClose);
|
sliceLayout->addWidget(btnSliceClose);
|
||||||
sliceBar->setVisible(false); // 默认二维,不显示
|
sliceBar->setVisible(false); // 默认二维,不显示
|
||||||
|
|
@ -559,14 +557,13 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
|
|
||||||
// 切片按钮可用性:仅三维 + 有体素时创建/翻转可用;关闭仅在有切片时可用。
|
// 切片按钮可用性:仅三维 + 有体素时创建/翻转可用;关闭仅在有切片时可用。
|
||||||
auto updateSliceButtons = [interactionMgr, btnSliceUpDown, btnSliceFrontBack, btnSliceLeftRight,
|
auto updateSliceButtons = [interactionMgr, btnSliceUpDown, btnSliceFrontBack, btnSliceLeftRight,
|
||||||
btnSliceOblique, btnSliceFace, btnSliceFlip, btnSliceClose, sceneView]() {
|
btnSliceOblique, btnSliceFlip, btnSliceClose, sceneView]() {
|
||||||
const bool canSlice = sceneView->hasVolume() && interactionMgr->hasVolume();
|
const bool canSlice = sceneView->hasVolume() && interactionMgr->hasVolume();
|
||||||
btnSliceUpDown->setEnabled(canSlice);
|
btnSliceUpDown->setEnabled(canSlice);
|
||||||
btnSliceFrontBack->setEnabled(canSlice);
|
btnSliceFrontBack->setEnabled(canSlice);
|
||||||
btnSliceLeftRight->setEnabled(canSlice);
|
btnSliceLeftRight->setEnabled(canSlice);
|
||||||
btnSliceOblique->setEnabled(canSlice);
|
btnSliceOblique->setEnabled(canSlice);
|
||||||
btnSliceFlip->setEnabled(canSlice);
|
btnSliceFlip->setEnabled(canSlice);
|
||||||
btnSliceFace->setEnabled(interactionMgr->hasSlices()); // 正视需有(选中)切片
|
|
||||||
btnSliceClose->setEnabled(interactionMgr->hasSlices());
|
btnSliceClose->setEnabled(interactionMgr->hasSlices());
|
||||||
};
|
};
|
||||||
updateSliceButtons();
|
updateSliceButtons();
|
||||||
|
|
@ -584,8 +581,6 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
[addSlice]() { addSlice(SliceAxis::LeftRight); });
|
[addSlice]() { addSlice(SliceAxis::LeftRight); });
|
||||||
QObject::connect(btnSliceOblique, &QPushButton::clicked, vtkWidget,
|
QObject::connect(btnSliceOblique, &QPushButton::clicked, vtkWidget,
|
||||||
[addSlice]() { addSlice(SliceAxis::Oblique); });
|
[addSlice]() { addSlice(SliceAxis::Oblique); });
|
||||||
QObject::connect(btnSliceFace, &QPushButton::clicked, vtkWidget,
|
|
||||||
[interactionMgr]() { interactionMgr->faceSelected(); });
|
|
||||||
QObject::connect(btnSliceFlip, &QPushButton::clicked, vtkWidget,
|
QObject::connect(btnSliceFlip, &QPushButton::clicked, vtkWidget,
|
||||||
[interactionMgr]() { interactionMgr->flipView(); });
|
[interactionMgr]() { interactionMgr->flipView(); });
|
||||||
QObject::connect(btnSliceClose, &QPushButton::clicked, vtkWidget,
|
QObject::connect(btnSliceClose, &QPushButton::clicked, vtkWidget,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "interact/InteractionManager.hpp"
|
#include "interact/InteractionManager.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
|
@ -87,14 +88,27 @@ void InteractionManager::addSlice(SliceAxis axis) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractionManager::selectByTool(const SliceTool* tool) {
|
void InteractionManager::selectByTool(const SliceTool* tool) {
|
||||||
for (std::size_t i = 0; i < slices_.size(); ++i) {
|
int idx = -1;
|
||||||
if (slices_[i].get() == tool) {
|
for (std::size_t i = 0; i < slices_.size(); ++i)
|
||||||
selected_ = static_cast<int>(i);
|
if (slices_[i].get() == tool) { idx = static_cast<int>(i); break; }
|
||||||
updateSelectionVisual();
|
if (idx < 0) return;
|
||||||
safeRender();
|
selected_ = idx;
|
||||||
return;
|
updateSelectionVisual();
|
||||||
}
|
|
||||||
|
// 双击切片正视(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() {
|
void InteractionManager::closeSelected() {
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,11 @@ private:
|
||||||
// 析构进行中:closeAll() 跳过 renderWindow_->Render()(Qt 拆台时窗口可能已半析构,
|
// 析构进行中:closeAll() 跳过 renderWindow_->Render()(Qt 拆台时窗口可能已半析构,
|
||||||
// 析构期再 Render 易崩,评审 M3)。
|
// 析构期再 Render 易崩,评审 M3)。
|
||||||
bool destroying_ = false;
|
bool destroying_ = false;
|
||||||
|
|
||||||
|
// 双击切片正视(D40)检测:同一切片在阈值内两次交互(StartInteractionEvent)视为双击 → 正视。
|
||||||
|
// 因 widget 开启交互后独占切面事件,双击靠监听 widget 交互判定,而非 InteractorStyle。
|
||||||
|
double lastInteractMs_ = -1.0;
|
||||||
|
const SliceTool* lastInteractTool_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace geopro::render::interact
|
} // 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_->On();
|
||||||
// 保持 widget 交互开启:任意切片可拖动调整角度/位置(F25 '可任意调整')。
|
// 保持 widget 交互开启:任意切片可拖动调整角度/位置(F25 '可任意调整')。
|
||||||
// 监听其交互开始事件 → 触碰本切片即回调 onInteract(上层据此设为选中)。
|
// 监听其交互开始事件 → 触碰本切片即回调 onInteract(上层据此设为选中)。
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue