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.
141 lines
3.3 KiB
C++
141 lines
3.3 KiB
C++
#include "nmVTKRenderLayer.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QThread>
|
|
|
|
#include <vtkProp.h>
|
|
#include <vtkRenderer.h>
|
|
|
|
namespace {
|
|
|
|
// VTK 对象没有跨线程保护,所有图层状态必须在 GUI 线程修改。
|
|
bool isLayerGuiThread()
|
|
{
|
|
QCoreApplication* pApplication = QCoreApplication::instance();
|
|
return pApplication == NULL ||
|
|
pApplication->thread() == QThread::currentThread();
|
|
}
|
|
|
|
}
|
|
|
|
nmVTKRenderLayer::nmVTKRenderLayer(const QString& sLayerId)
|
|
: m_sLayerId(sLayerId),
|
|
m_bVisible(true),
|
|
m_pRenderProp(NULL),
|
|
m_pRenderer(NULL),
|
|
m_pOwningScene(NULL)
|
|
{
|
|
Q_ASSERT(isLayerGuiThread());
|
|
// 稳定 ID 只用于 Scene 查找,不承担可翻译的界面文案。
|
|
}
|
|
|
|
nmVTKRenderLayer::~nmVTKRenderLayer()
|
|
{
|
|
Q_ASSERT(isLayerGuiThread());
|
|
Q_ASSERT(m_pOwningScene == NULL);
|
|
// 主 Prop 由基类智能指针继续持有,因此此时 detach 不依赖派生类成员。
|
|
detach();
|
|
m_pRenderProp = NULL;
|
|
m_pOwningScene = NULL;
|
|
}
|
|
|
|
QString nmVTKRenderLayer::getLayerId() const
|
|
{
|
|
return m_sLayerId;
|
|
}
|
|
|
|
bool nmVTKRenderLayer::attach(vtkRenderer* pRenderer)
|
|
{
|
|
Q_ASSERT(isLayerGuiThread());
|
|
if(!isLayerGuiThread() || pRenderer == NULL || m_pRenderProp == NULL) {
|
|
return false;
|
|
}
|
|
if(m_pRenderer == pRenderer) {
|
|
// 幂等挂载不重复增加 Renderer 对 Prop 的引用。
|
|
return true;
|
|
}
|
|
|
|
// 一个图层同一时刻只能挂载到一个 Renderer。
|
|
detach();
|
|
m_pRenderProp->SetVisibility(m_bVisible ? 1 : 0);
|
|
pRenderer->AddViewProp(m_pRenderProp);
|
|
m_pRenderer = pRenderer;
|
|
return true;
|
|
}
|
|
|
|
void nmVTKRenderLayer::detach()
|
|
{
|
|
Q_ASSERT(isLayerGuiThread());
|
|
if(m_pRenderer != NULL && m_pRenderProp != NULL) {
|
|
m_pRenderer->RemoveViewProp(m_pRenderProp);
|
|
}
|
|
m_pRenderer = NULL;
|
|
}
|
|
|
|
void nmVTKRenderLayer::setVisible(bool bVisible)
|
|
{
|
|
Q_ASSERT(isLayerGuiThread());
|
|
if(!isLayerGuiThread()) {
|
|
return;
|
|
}
|
|
m_bVisible = bVisible;
|
|
if(m_pRenderProp != NULL) {
|
|
m_pRenderProp->SetVisibility(bVisible ? 1 : 0);
|
|
}
|
|
}
|
|
|
|
bool nmVTKRenderLayer::isVisible() const
|
|
{
|
|
return m_bVisible;
|
|
}
|
|
|
|
bool nmVTKRenderLayer::isAttached() const
|
|
{
|
|
return m_pRenderer != NULL;
|
|
}
|
|
|
|
bool nmVTKRenderLayer::setRenderProp(vtkProp* pProp)
|
|
{
|
|
Q_ASSERT(isLayerGuiThread());
|
|
if(!isLayerGuiThread() || isAttached() || pProp == NULL) {
|
|
return false;
|
|
}
|
|
// vtkSmartPointer 接管一个 VTK 引用,派生类可继续持有同一对象。
|
|
m_pRenderProp = pProp;
|
|
m_pRenderProp->SetVisibility(m_bVisible ? 1 : 0);
|
|
return true;
|
|
}
|
|
|
|
vtkProp* nmVTKRenderLayer::getRenderProp() const
|
|
{
|
|
return m_pRenderProp;
|
|
}
|
|
|
|
vtkRenderer* nmVTKRenderLayer::getAttachedRenderer() const
|
|
{
|
|
return m_pRenderer;
|
|
}
|
|
|
|
bool nmVTKRenderLayer::claimSceneOwnership(nmVTKScene* pScene)
|
|
{
|
|
Q_ASSERT(isLayerGuiThread());
|
|
if(!isLayerGuiThread() || pScene == NULL || m_pOwningScene != NULL) {
|
|
return false;
|
|
}
|
|
|
|
// 所有权与 Renderer 挂载状态分开记录,公开 detach 不会释放 Scene 所有权。
|
|
m_pOwningScene = pScene;
|
|
return true;
|
|
}
|
|
|
|
bool nmVTKRenderLayer::releaseSceneOwnership(nmVTKScene* pScene)
|
|
{
|
|
Q_ASSERT(isLayerGuiThread());
|
|
if(!isLayerGuiThread() || pScene == NULL || m_pOwningScene != pScene) {
|
|
return false;
|
|
}
|
|
|
|
m_pOwningScene = NULL;
|
|
return true;
|
|
}
|