#include "nmPebiResultSnapshotRenderAdapter.h" #include #include #include #include #include #include #include #include #if !defined(_MSC_VER) #include #endif namespace { bool isFiniteValue(double dValue) { #if defined(_MSC_VER) return _finite(dValue) != 0; #else return std::isfinite(dValue); #endif } bool isValidCopiedScalars(vtkDoubleArray* pScalars, vtkIdType nExpectedCellCount, const QString& sExpectedArrayName) { if(pScalars == NULL || pScalars->GetName() == NULL || QString::fromLatin1(pScalars->GetName()) != sExpectedArrayName || pScalars->GetNumberOfComponents() != 1 || pScalars->GetNumberOfTuples() != nExpectedCellCount) { return false; } for(vtkIdType nCellId = 0; nCellId < nExpectedCellCount; ++nCellId) { if(!isFiniteValue(pScalars->GetValue(nCellId))) { return false; } } return true; } } nmPebiResultSnapshotRenderAdapter::nmPebiResultSnapshotRenderAdapter() : m_pRenderGrid(vtkSmartPointer::New()), m_pActiveBuffer(vtkSmartPointer::New()), m_pStandbyBuffer(vtkSmartPointer::New()), m_pProducer(vtkSmartPointer::New()), m_eBindingMode(SharedPropertyArray), m_nCurrentFrameIndex(-1) { } nmPebiResultSnapshotRenderAdapter::~nmPebiResultSnapshotRenderAdapter() { clear(); } bool nmPebiResultSnapshotRenderAdapter::initialize( const QSharedPointer& pSnapshot, PropertyBindingMode eBindingMode) { clear(); if(pSnapshot.isNull() || !pSnapshot->isComplete() || (eBindingMode != SharedPropertyArray && eBindingMode != CopiedPropertyArray)) { return false; } m_pSnapshot = pSnapshot; m_eBindingMode = eBindingMode; if(!m_pSnapshot->copyResultGridStructure(m_pRenderGrid)) { clear(); return false; } // TrivialProducer 只负责把适配器网格接入管道,不会主动修改输出对象。 m_pProducer->SetOutput(m_pRenderGrid); m_pProducer->Modified(); return true; } bool nmPebiResultSnapshotRenderAdapter::initialize( const QSharedPointer& pSnapshot, PressureBindingMode eBindingMode) { if(eBindingMode != SharedPressureFrame && eBindingMode != CopiedPressureFrame) { return false; } return initialize(pSnapshot, eBindingMode == CopiedPressureFrame ? CopiedPropertyArray : SharedPropertyArray); } void nmPebiResultSnapshotRenderAdapter::clear() { // 先断开管道和 CellData,及时释放对旧快照压力数组的临时 VTK 引用。 if(m_pProducer != NULL) { m_pProducer->SetOutput(NULL); m_pProducer->Modified(); } if(m_pRenderGrid != NULL) { m_pRenderGrid->GetCellData()->Initialize(); m_pRenderGrid->Initialize(); } if(m_pActiveBuffer != NULL) { m_pActiveBuffer->Initialize(); } if(m_pStandbyBuffer != NULL) { m_pStandbyBuffer->Initialize(); } m_pSnapshot.clear(); m_eBindingMode = SharedPropertyArray; m_sCurrentPropertyId.clear(); m_nCurrentFrameIndex = -1; } bool nmPebiResultSnapshotRenderAdapter::setPropertyFrame( const QString& sPropertyId, int nFrameIndex) { if(m_pSnapshot.isNull() || m_pRenderGrid == NULL || nFrameIndex < 0 || !m_pSnapshot->hasProperty(sPropertyId) || nFrameIndex >= m_pSnapshot->getPropertyFrameCount(sPropertyId)) { return false; } bool bBound = false; if(m_eBindingMode == SharedPropertyArray) { bBound = m_pSnapshot->bindPropertyFrame( sPropertyId, nFrameIndex, m_pRenderGrid); } else { // 活动缓冲在整个准备阶段保持不变;只有备用缓冲完整有效后才切换。 bBound = m_pSnapshot->copyPropertyFrame( sPropertyId, nFrameIndex, m_pStandbyBuffer) && isValidCopiedScalars( m_pStandbyBuffer, m_pSnapshot->getResultCellCount(), sPropertyId == QString::fromLatin1("pressure") ? QString::fromLatin1("p") : sPropertyId); if(bBound) { vtkDataArray* pPreviousScalars = m_pRenderGrid->GetCellData()->GetScalars(); m_pRenderGrid->GetCellData()->SetScalars(m_pStandbyBuffer); if(m_pRenderGrid->GetCellData()->GetScalars() != m_pStandbyBuffer.GetPointer()) { m_pRenderGrid->GetCellData()->SetScalars(pPreviousScalars); bBound = false; } else { qSwap(m_pActiveBuffer, m_pStandbyBuffer); m_pRenderGrid->Modified(); } } } if(!bBound) { return false; } m_sCurrentPropertyId = sPropertyId; m_nCurrentFrameIndex = nFrameIndex; m_pProducer->Modified(); return true; } bool nmPebiResultSnapshotRenderAdapter::setPressureFrame(int nFrameIndex) { return setPropertyFrame(QString::fromLatin1("pressure"), nFrameIndex); } vtkAlgorithmOutput* nmPebiResultSnapshotRenderAdapter::getOutputPort() const { return m_pSnapshot.isNull() || m_pProducer == NULL ? NULL : m_pProducer->GetOutputPort(); } int nmPebiResultSnapshotRenderAdapter::getCurrentFrameIndex() const { return m_nCurrentFrameIndex; } QString nmPebiResultSnapshotRenderAdapter::getCurrentPropertyId() const { return m_sCurrentPropertyId; } QString nmPebiResultSnapshotRenderAdapter::getCurrentScalarArrayName() const { if(m_sCurrentPropertyId.isEmpty()) { return QString(); } return m_sCurrentPropertyId == QString::fromLatin1("pressure") ? QString::fromLatin1("p") : m_sCurrentPropertyId; } vtkIdType nmPebiResultSnapshotRenderAdapter::getCellCount() const { return m_pRenderGrid == NULL ? 0 : m_pRenderGrid->GetNumberOfCells(); } bool nmPebiResultSnapshotRenderAdapter::isUsingSharedPressure() const { return isUsingSharedProperties(); } bool nmPebiResultSnapshotRenderAdapter::isUsingSharedProperties() const { return !m_pSnapshot.isNull() && m_eBindingMode == SharedPropertyArray; }