You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmRender/nmVTKInteractionManager.cpp

146 lines
4.2 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "nmVTKInteractionManager.h"
#include "nmVTKPivotCameraInteractorStyle.h"
#include <QCoreApplication>
#include <QThread>
#include <vtkInteractorStyle.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
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<nmVTKPivotCameraInteractorStyle>::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;
}