feat/vtk-3d-view #7
|
|
@ -510,7 +510,10 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
QAction* aAnoPoint = anomMenu->addAction(QStringLiteral("点"));
|
QAction* aAnoPoint = anomMenu->addAction(QStringLiteral("点"));
|
||||||
QAction* aAnoLine = anomMenu->addAction(QStringLiteral("线"));
|
QAction* aAnoLine = anomMenu->addAction(QStringLiteral("线"));
|
||||||
QAction* aAnoFace = anomMenu->addAction(QStringLiteral("面"));
|
QAction* aAnoFace = anomMenu->addAction(QStringLiteral("面"));
|
||||||
QAction* aSave = menu.addAction(QStringLiteral("保存"));
|
// 「保存」仅对未保存(临时)切片显示——已保存切片定稿锁定、不可再改/再存(用户要求)。
|
||||||
|
QAction* aSave = interactionMgr->selectedSliceDsId().empty()
|
||||||
|
? menu.addAction(QStringLiteral("保存"))
|
||||||
|
: nullptr;
|
||||||
QMenu* expMenu = menu.addMenu(QStringLiteral("导出"));
|
QMenu* expMenu = menu.addMenu(QStringLiteral("导出"));
|
||||||
QAction* aImg = expMenu->addAction(QStringLiteral("图片"));
|
QAction* aImg = expMenu->addAction(QStringLiteral("图片"));
|
||||||
QAction* aDat = expMenu->addAction(QStringLiteral("dat"));
|
QAction* aDat = expMenu->addAction(QStringLiteral("dat"));
|
||||||
|
|
@ -630,7 +633,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
[]() { /* onCancel:放弃,无需处理 */ });
|
[]() { /* onCancel:放弃,无需处理 */ });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (chosen == aSave) {
|
if (aSave != nullptr && chosen == aSave) {
|
||||||
int axis = 3;
|
int axis = 3;
|
||||||
geopro::render::interact::Vec3 o{}, p1{}, p2{};
|
geopro::render::interact::Vec3 o{}, p1{}, p2{};
|
||||||
if (!interactionMgr->selectedSlicePlane(axis, o, p1, p2)) return;
|
if (!interactionMgr->selectedSlicePlane(axis, o, p1, p2)) return;
|
||||||
|
|
|
||||||
|
|
@ -344,9 +344,7 @@ void CategorySection::showContextMenu(const QPoint& pos) {
|
||||||
sl->addAction(QStringLiteral("左右"), this, [this, id] { emit sliceRequested(SliceAxis::LeftRight, id); });
|
sl->addAction(QStringLiteral("左右"), this, [this, id] { emit sliceRequested(SliceAxis::LeftRight, id); });
|
||||||
sl->addAction(QStringLiteral("任意"), this, [this, id] { emit sliceRequested(SliceAxis::Oblique, id); });
|
sl->addAction(QStringLiteral("任意"), this, [this, id] { emit sliceRequested(SliceAxis::Oblique, id); });
|
||||||
menu.addAction(QStringLiteral("色阶"), this, [this, id] { emit colorScaleRequested(id); });
|
menu.addAction(QStringLiteral("色阶"), this, [this, id] { emit colorScaleRequested(id); });
|
||||||
} else if (ddCode == QStringLiteral("dd_slice")) { // 切片
|
} 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("导出"));
|
QMenu* ex = menu.addMenu(QStringLiteral("导出"));
|
||||||
ex->addAction(QStringLiteral("图片"), this, [this, id] { emit sliceExportImageRequested(id); });
|
ex->addAction(QStringLiteral("图片"), this, [this, id] { emit sliceExportImageRequested(id); });
|
||||||
ex->addAction(QStringLiteral("dat"), this, [this, id] { emit sliceExportDatRequested(id); });
|
ex->addAction(QStringLiteral("dat"), this, [this, id] { emit sliceExportDatRequested(id); });
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@ void InteractionManager::showSavedSlice(const std::string& dsId, int axis, const
|
||||||
tool->setVolumeDsId(volumeDsId);
|
tool->setVolumeDsId(volumeDsId);
|
||||||
SliceTool* tp = tool.get();
|
SliceTool* tp = tool.get();
|
||||||
tool->onInteract = [this, tp]() { selectByTool(tp); };
|
tool->onInteract = [this, tp]() { selectByTool(tp); };
|
||||||
|
tool->setInteractive(false); // 已保存切片定稿锁定:不可移动/旋转(用户要求);仍可拾取选中/右键
|
||||||
slices_.push_back(std::move(tool));
|
slices_.push_back(std::move(tool));
|
||||||
selected_ = static_cast<int>(slices_.size()) - 1;
|
selected_ = static_cast<int>(slices_.size()) - 1;
|
||||||
updateSelectionVisual(); // 程序化显示(syncSlices):不发 onSliceSelectionChanged,避免列表选中被刷
|
updateSelectionVisual(); // 程序化显示(syncSlices):不发 onSliceSelectionChanged,避免列表选中被刷
|
||||||
|
|
@ -289,6 +290,7 @@ std::string InteractionManager::selectedSliceVolumeDsId() const {
|
||||||
void InteractionManager::tagSelectedSlice(const std::string& dsId) {
|
void InteractionManager::tagSelectedSlice(const std::string& dsId) {
|
||||||
if (selected_ < 0 || selected_ >= static_cast<int>(slices_.size())) return;
|
if (selected_ < 0 || selected_ >= static_cast<int>(slices_.size())) return;
|
||||||
slices_[static_cast<std::size_t>(selected_)]->setDsId(dsId);
|
slices_[static_cast<std::size_t>(selected_)]->setDsId(dsId);
|
||||||
|
slices_[static_cast<std::size_t>(selected_)]->setInteractive(false); // 保存即定稿锁定(不可改)
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkImageData* InteractionManager::selectedSliceImage() const {
|
vtkImageData* InteractionManager::selectedSliceImage() const {
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,10 @@ vtkImageData* SliceTool::reslicedOutput() const {
|
||||||
return widget_ ? widget_->GetResliceOutput() : nullptr;
|
return widget_ ? widget_->GetResliceOutput() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SliceTool::setInteractive(bool on) {
|
||||||
|
if (widget_) widget_->SetInteraction(on ? 1 : 0); // 关=锁移动/旋转/光标,纹理仍显示
|
||||||
|
}
|
||||||
|
|
||||||
vtkSmartPointer<vtkImageData> SliceTool::coloredResliceImage() const {
|
vtkSmartPointer<vtkImageData> SliceTool::coloredResliceImage() const {
|
||||||
if (!widget_) return nullptr;
|
if (!widget_) return nullptr;
|
||||||
vtkImageMapToColors* cm = widget_->GetColorMap(); // widget 内部把 reslice 经 LUT 上色 → 纹理
|
vtkImageMapToColors* cm = widget_->GetColorMap(); // widget 内部把 reslice 经 LUT 上色 → 纹理
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,9 @@ public:
|
||||||
// 与屏幕切片纹理同源的着色输出(widget 自己的 ColorMap 输出, RGBA, 逐像素一致, 外区透明)。
|
// 与屏幕切片纹理同源的着色输出(widget 自己的 ColorMap 输出, RGBA, 逐像素一致, 外区透明)。
|
||||||
// 异常截图/导出用它而非另建 LUT,避免与屏幕配色不一致(用户实测差异大)。
|
// 异常截图/导出用它而非另建 LUT,避免与屏幕配色不一致(用户实测差异大)。
|
||||||
vtkSmartPointer<vtkImageData> coloredResliceImage() const;
|
vtkSmartPointer<vtkImageData> coloredResliceImage() const;
|
||||||
|
// 开/关 widget 鼠标交互(移动/旋转/光标)。关=锁定但仍显示(已保存切片定稿不可改);
|
||||||
|
// 拾取选中/右键菜单由 PickInteractorStyle 独立处理,不受此影响。
|
||||||
|
void setInteractive(bool on);
|
||||||
|
|
||||||
// 关闭:Off() 并解除 interactor 绑定(幂等)。
|
// 关闭:Off() 并解除 interactor 绑定(幂等)。
|
||||||
void close();
|
void close();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue