fix zoom to selected

This commit is contained in:
AndreaRigoni
2026-03-19 14:18:31 +00:00
parent 1e6e3ae4f4
commit dbb5f24933
2 changed files with 44 additions and 27 deletions

View File

@@ -190,38 +190,50 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
iren->AddObserver(vtkCommand::LeftButtonPressEvent, clickCallback);
// Keyboard events for widget coordinate frame
vtkNew<vtkCallbackCommand> keyCallback;
keyCallback->SetClientData(this);
keyCallback->SetCallback([](vtkObject* caller, unsigned long, void* clientdata, void*){
m_KeyCallback = vtkSmartPointer<vtkCallbackCommand>::New();
m_KeyCallback->SetClientData(this);
m_KeyCallback->SetCallback([](vtkObject* caller, unsigned long, void* clientdata, void*){
auto* iren = static_cast<vtkRenderWindowInteractor*>(caller);
auto* self = static_cast<Viewport*>(clientdata);
if (!self->m_HandlerWidget || !self->m_HandlerWidget->GetEnabled()) return;
std::string key = iren->GetKeySym();
if (key == "l") {
self->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::LOCAL);
std::cout << "Widget Frame: LOCAL" << std::endl;
bool handled = false;
if (self->m_HandlerWidget && self->m_HandlerWidget->GetEnabled()) {
if (key == "l") {
self->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::LOCAL);
std::cout << "Widget Frame: LOCAL" << std::endl;
handled = true;
}
else if (key == "g") {
self->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::GLOBAL);
std::cout << "Widget Frame: GLOBAL" << std::endl;
handled = true;
}
else if (key == "c") {
self->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::CENTER);
std::cout << "Widget Frame: CENTER" << std::endl;
handled = true;
}
else if (key == "k") {
self->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::CENTER_LOCAL);
std::cout << "Widget Frame: CENTER_LOCAL" << std::endl;
handled = true;
}
}
else if (key == "g") {
self->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::GLOBAL);
std::cout << "Widget Frame: GLOBAL" << std::endl;
if (key == "f") {
self->ZoomSelected();
handled = true;
}
else if (key == "c") {
self->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::CENTER);
std::cout << "Widget Frame: CENTER" << std::endl;
if (handled) {
self->m_KeyCallback->SetAbortFlag(1);
iren->Render();
}
else if (key == "k") {
self->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::CENTER_LOCAL);
std::cout << "Widget Frame: CENTER_LOCAL" << std::endl;
}
else if (key == "s") {
self->ZoomSelected();
}
iren->Render();
});
iren->AddObserver(vtkCommand::KeyPressEvent, keyCallback);
iren->AddObserver(vtkCommand::KeyPressEvent, m_KeyCallback, 1.0);
iren->AddObserver(vtkCommand::CharEvent, m_KeyCallback, 1.0);
}
void Viewport::Reset()
@@ -262,14 +274,18 @@ void Viewport::ZoomSelected()
if (bounds[0] > bounds[1]) return; // Invalid bounds
// Expand bounds by 1.5 from center
// Expand bounds by a factor from center (e.g. 2.0 to have some margin)
double center[3] = {(bounds[0] + bounds[1]) / 2.0, (bounds[2] + bounds[3]) / 2.0, (bounds[4] + bounds[5]) / 2.0};
double h_ext[3] = {(bounds[1] - bounds[0]) / 2.0, (bounds[3] - bounds[2]) / 2.0, (bounds[5] - bounds[4]) / 2.0};
// Ensure a minimum size to avoid camera issues with flat/point objects
double max_h = std::max({h_ext[0], h_ext[1], h_ext[2], 0.1});
double newBounds[6];
for (int i=0; i<3; ++i) {
newBounds[2*i] = center[i] - 1.5 * h_ext[i];
newBounds[2*i+1] = center[i] + 1.5 * h_ext[i];
double current_h = std::max(h_ext[i], max_h * 0.1);
newBounds[2*i] = center[i] - 2.5 * current_h;
newBounds[2*i+1] = center[i] + 2.5 * current_h;
}
m_Renderer->ResetCamera(newBounds);

View File

@@ -91,6 +91,7 @@ protected:
vtkSmartPointer<vtkHandlerWidget> m_HandlerWidget;
std::vector<Puppet*> m_Puppets;
vtkSmartPointer<vtkCellPicker> m_Picker;
vtkSmartPointer<vtkCallbackCommand> m_KeyCallback;
};
} // namespace Vtk