feat(vtk): D39 以选中三维体/切片为中心旋转视图(不跳)
正确做法: 点击只选中(不动相机)→切换点选不跳; 在'按下开始拖动'那刻才把焦点设到 选中切片中心(焦点+位置同步补偿 delta→视向/距离不变、画面不跳), 之后默认 TrackballCamera 即绕该中心旋转。PickInteractorStyle 加 getRotateCenter 回调, InteractionManager 提供 选中切片中心; 无选中则绕默认焦点。ctest 221/221
This commit is contained in:
parent
2e5cc4e6db
commit
8d94247dd9
|
|
@ -41,6 +41,12 @@ void InteractionManager::installStyle() {
|
||||||
style_->onPick = [this](const Vec3& w) { onPicked(w); };
|
style_->onPick = [this](const Vec3& w) { onPicked(w); };
|
||||||
style_->onDoubleClick = [this](const Vec3& w) { onDoubleClicked(w); };
|
style_->onDoubleClick = [this](const Vec3& w) { onDoubleClicked(w); };
|
||||||
style_->onWheelStep = [this](int dir) { return onWheel(dir); };
|
style_->onWheelStep = [this](int dir) { return onWheel(dir); };
|
||||||
|
// D39: 提供旋转中心 = 选中切片中心(有选中→true)。style 在按下拖动时据此绕选中切片旋转。
|
||||||
|
style_->getRotateCenter = [this](Vec3& c) {
|
||||||
|
if (selected_ < 0 || selected_ >= static_cast<int>(slices_.size())) return false;
|
||||||
|
c = slices_[static_cast<std::size_t>(selected_)]->center();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
interactor_->SetInteractorStyle(style_);
|
interactor_->SetInteractorStyle(style_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,6 +56,7 @@ void InteractionManager::uninstallStyle() {
|
||||||
style_->onPick = nullptr;
|
style_->onPick = nullptr;
|
||||||
style_->onDoubleClick = nullptr;
|
style_->onDoubleClick = nullptr;
|
||||||
style_->onWheelStep = nullptr;
|
style_->onWheelStep = nullptr;
|
||||||
|
style_->getRotateCenter = nullptr;
|
||||||
}
|
}
|
||||||
// 从 interactor 上彻底摘除自定义 style,避免 interactor 仍持空回调 style(评审 H2)。
|
// 从 interactor 上彻底摘除自定义 style,避免 interactor 仍持空回调 style(评审 H2)。
|
||||||
if (interactor_) interactor_->SetInteractorStyle(nullptr);
|
if (interactor_) interactor_->SetInteractorStyle(nullptr);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
#include <vtkCamera.h>
|
||||||
#include <vtkCellPicker.h>
|
#include <vtkCellPicker.h>
|
||||||
#include <vtkNew.h>
|
#include <vtkNew.h>
|
||||||
#include <vtkObjectFactory.h>
|
#include <vtkObjectFactory.h>
|
||||||
|
|
@ -70,9 +71,29 @@ void PickInteractorStyle::OnLeftButtonDown() {
|
||||||
return; // 不进入拖动旋转
|
return; // 不进入拖动旋转
|
||||||
}
|
}
|
||||||
if (hit) {
|
if (hit) {
|
||||||
// 单击命中 → 选中 + 设旋转中心为命中点(拖动绕其旋转)。
|
// 单击命中 → 选中所在切片(onPick 内仅选中, 不动相机)。
|
||||||
if (onPick) onPick(world);
|
if (onPick) onPick(world);
|
||||||
}
|
}
|
||||||
|
// D39: 有选中三维体/切片时,按下开始拖动前把焦点设到其中心——焦点与位置同步平移同一 delta,
|
||||||
|
// 视向/距离不变(画面不跳),之后默认 TrackballCamera 即绕该中心旋转。无选中则绕默认焦点。
|
||||||
|
// 只在"按下"时设(不是选中时),故切换点选切片不会跳。
|
||||||
|
if (getRotateCenter && iren) {
|
||||||
|
Vec3 c;
|
||||||
|
if (getRotateCenter(c)) {
|
||||||
|
const int* p2 = iren->GetEventPosition();
|
||||||
|
if (auto* ren = iren->FindPokedRenderer(p2[0], p2[1])) {
|
||||||
|
if (auto* cam = ren->GetActiveCamera()) {
|
||||||
|
double f[3], pp[3];
|
||||||
|
cam->GetFocalPoint(f);
|
||||||
|
cam->GetPosition(pp);
|
||||||
|
cam->SetFocalPoint(c[0], c[1], c[2]);
|
||||||
|
cam->SetPosition(pp[0] + (c[0] - f[0]), pp[1] + (c[1] - f[1]),
|
||||||
|
pp[2] + (c[2] - f[2]));
|
||||||
|
ren->ResetCameraClippingRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// 始终保留 TrackballCamera 默认拖动(旋转/平移)。
|
// 始终保留 TrackballCamera 默认拖动(旋转/平移)。
|
||||||
Superclass::OnLeftButtonDown();
|
Superclass::OnLeftButtonDown();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ public:
|
||||||
// 滚轮步进:dir=+1 前/-1 后。返回 true 表示已被消费(有选中切片推进),
|
// 滚轮步进:dir=+1 前/-1 后。返回 true 表示已被消费(有选中切片推进),
|
||||||
// false 则执行默认相机缩放。
|
// false 则执行默认相机缩放。
|
||||||
std::function<bool(int dir)> onWheelStep;
|
std::function<bool(int dir)> onWheelStep;
|
||||||
|
// 取当前旋转中心(D39):有选中三维体/切片→填其中心、返回 true;否则 false(绕默认焦点)。
|
||||||
|
// 在"按下开始拖动"时调用一次,把焦点设到该中心(位置同步补偿,画面不变)→ 之后绕它旋转、不跳。
|
||||||
|
std::function<bool(Vec3& center)> getRotateCenter;
|
||||||
|
|
||||||
void OnLeftButtonDown() override;
|
void OnLeftButtonDown() override;
|
||||||
void OnMouseWheelForward() override;
|
void OnMouseWheelForward() override;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue