From dbb5f2493360e22f49f2eb3219f12f96d9784b47 Mon Sep 17 00:00:00 2001 From: AndreaRigoni Date: Thu, 19 Mar 2026 14:18:31 +0000 Subject: [PATCH] fix zoom to selected --- src/Vtk/vtkViewport.cpp | 70 +++++++++++++++++++++++++---------------- src/Vtk/vtkViewport.h | 1 + 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/Vtk/vtkViewport.cpp b/src/Vtk/vtkViewport.cpp index 5e6ab2e..c6a8c2e 100644 --- a/src/Vtk/vtkViewport.cpp +++ b/src/Vtk/vtkViewport.cpp @@ -190,38 +190,50 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren) iren->AddObserver(vtkCommand::LeftButtonPressEvent, clickCallback); // Keyboard events for widget coordinate frame - vtkNew keyCallback; - keyCallback->SetClientData(this); - keyCallback->SetCallback([](vtkObject* caller, unsigned long, void* clientdata, void*){ + m_KeyCallback = vtkSmartPointer::New(); + m_KeyCallback->SetClientData(this); + m_KeyCallback->SetCallback([](vtkObject* caller, unsigned long, void* clientdata, void*){ auto* iren = static_cast(caller); auto* self = static_cast(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); diff --git a/src/Vtk/vtkViewport.h b/src/Vtk/vtkViewport.h index 36d1c18..bb488d4 100644 --- a/src/Vtk/vtkViewport.h +++ b/src/Vtk/vtkViewport.h @@ -91,6 +91,7 @@ protected: vtkSmartPointer m_HandlerWidget; std::vector m_Puppets; vtkSmartPointer m_Picker; + vtkSmartPointer m_KeyCallback; }; } // namespace Vtk