#include "nmVTKInteractionManager.h" #include "nmVTKPivotCameraInteractorStyle.h" #include #include #include #include #include namespace { // InteractorStyle 会注册 VTK 观察关系,绑定与解除都限定在 GUI 线程。 bool isInteractionGuiThread() { QCoreApplication* pApplication = QCoreApplication::instance(); return pApplication == nullptr || pApplication->thread() == QThread::currentThread(); } } nmVTKInteractionManager::nmVTKInteractionManager( nmVTKCameraController* pCameraController) : m_pInteractor(nullptr), m_pDefaultStyle( vtkSmartPointer::New()), m_pActiveStyle(nullptr) { Q_ASSERT(isInteractionGuiThread()); m_pDefaultStyle->setCameraController(pCameraController); } nmVTKInteractionManager::~nmVTKInteractionManager() { Q_ASSERT(isInteractionGuiThread()); // Interactor 持有 Style 引用,必须先清除绑定再释放智能指针。 unbindInteractor(); m_pActiveStyle = nullptr; if(m_pDefaultStyle != nullptr) { m_pDefaultStyle->setCameraController(nullptr); } m_pDefaultStyle = nullptr; } bool nmVTKInteractionManager::bindInteractor( vtkRenderWindowInteractor* pInteractor, vtkRenderer* pRenderer) { Q_ASSERT(isInteractionGuiThread()); if(!isInteractionGuiThread() || pInteractor == nullptr || m_pDefaultStyle == nullptr) { return false; } if(m_pInteractor != pInteractor) { // 切换对象前先清除旧 Interactor 持有的 Style 引用。 unbindInteractor(); m_pInteractor = pInteractor; } m_pDefaultStyle->SetDefaultRenderer(pRenderer); m_pDefaultStyle->SetCurrentRenderer(pRenderer); return restoreDefaultInteraction(); } bool nmVTKInteractionManager::installInteractionStyle( vtkInteractorStyle* pStyle) { Q_ASSERT(isInteractionGuiThread()); if(!isInteractionGuiThread() || m_pInteractor == nullptr || pStyle == nullptr) { return false; } // 管理器和 Interactor 各持有一个 VTK 引用,直到恢复或清除当前模式。 m_pActiveStyle = pStyle; m_pInteractor->SetInteractorStyle(m_pActiveStyle); return true; } bool nmVTKInteractionManager::restoreDefaultInteraction() { Q_ASSERT(isInteractionGuiThread()); if(!isInteractionGuiThread() || m_pInteractor == nullptr || m_pDefaultStyle == nullptr) { return false; } // 后续工具临时替换样式后,可通过本入口回到唯一默认交互模式。 return installInteractionStyle(m_pDefaultStyle); } void nmVTKInteractionManager::clearInteractionStyle() { Q_ASSERT(isInteractionGuiThread()); if(!isInteractionGuiThread()) { return; } if(m_pInteractor != nullptr) { m_pInteractor->SetInteractorStyle(nullptr); } m_pActiveStyle = nullptr; } void nmVTKInteractionManager::unbindInteractor() { Q_ASSERT(isInteractionGuiThread()); if(!isInteractionGuiThread()) { return; } // 本管理器定义单一活动模式边界,解绑时不保留任何旧 Style。 clearInteractionStyle(); if(m_pDefaultStyle != nullptr) { // DefaultRenderer 会覆盖 CurrentRenderer,必须先解除前者。 m_pDefaultStyle->SetDefaultRenderer(nullptr); m_pDefaultStyle->SetCurrentRenderer(nullptr); } m_pInteractor = nullptr; } vtkRenderWindowInteractor* nmVTKInteractionManager::getInteractor() const { return m_pInteractor; } vtkInteractorStyleTrackballCamera* nmVTKInteractionManager::getDefaultStyle() const { return m_pDefaultStyle.GetPointer(); } vtkInteractorStyle* nmVTKInteractionManager::getActiveStyle() const { return m_pActiveStyle; } bool nmVTKInteractionManager::isDefaultInteractionActive() const { vtkInteractorStyle* pDefaultStyle = m_pDefaultStyle.GetPointer(); vtkInteractorStyle* pActiveStyle = m_pActiveStyle.GetPointer(); return m_pInteractor != nullptr && pDefaultStyle != nullptr && pActiveStyle == pDefaultStyle && m_pInteractor->GetInteractorStyle() == pDefaultStyle; }