#include "nmPebiResultSnapshotRenderAdapter.h" #include #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_pBindingGrid(vtkSmartPointer::New()), m_pActiveBuffer(vtkSmartPointer::New()), m_pStandbyBuffer(vtkSmartPointer::New()), m_pFilterActiveBuffer(vtkSmartPointer::New()), m_pFilterStandbyBuffer(vtkSmartPointer::New()), m_pProducer(vtkSmartPointer::New()), m_eBindingMode(SharedPropertyArray), m_nCurrentFrameIndex(-1), m_nFilterFrameIndex(-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; } // 事务预取只需要共享点和单元拓扑;不重复深拷贝原始单元映射元数据。 m_pBindingGrid->Initialize(); m_pBindingGrid->CopyStructure(m_pRenderGrid); m_pBindingGrid->GetCellData()->Initialize(); m_pBindingGrid->GetFieldData()->Initialize(); if(m_pBindingGrid->GetNumberOfCells() != m_pRenderGrid->GetNumberOfCells()) { 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_pBindingGrid != NULL) { m_pBindingGrid->GetCellData()->Initialize(); m_pBindingGrid->Initialize(); } if(m_pActiveBuffer != NULL) { m_pActiveBuffer->Initialize(); } if(m_pStandbyBuffer != NULL) { m_pStandbyBuffer->Initialize(); } if(m_pFilterActiveBuffer != NULL) { m_pFilterActiveBuffer->Initialize(); } if(m_pFilterStandbyBuffer != NULL) { m_pFilterStandbyBuffer->Initialize(); } m_pSnapshot.clear(); m_eBindingMode = SharedPropertyArray; m_sCurrentPropertyId.clear(); m_nCurrentFrameIndex = -1; m_sFilterPropertyId.clear(); m_nFilterFrameIndex = -1; } bool nmPebiResultSnapshotRenderAdapter::setPropertyFrame( const QString& sPropertyId, int nFrameIndex) { return setPropertyFrames( sPropertyId, nFrameIndex, QString(), -1); } bool nmPebiResultSnapshotRenderAdapter::setPropertyFrames( const QString& sDisplayPropertyId, int nDisplayFrameIndex, const QString& sFilterPropertyId, int nFilterFrameIndex) { const bool bHasFilter = !sFilterPropertyId.isEmpty(); if(m_pSnapshot.isNull() || m_pRenderGrid == NULL || m_pBindingGrid == NULL || nDisplayFrameIndex < 0 || !m_pSnapshot->hasProperty(sDisplayPropertyId) || nDisplayFrameIndex >= m_pSnapshot->getPropertyFrameCount(sDisplayPropertyId) || (bHasFilter && (nFilterFrameIndex < 0 || !m_pSnapshot->hasProperty(sFilterPropertyId) || nFilterFrameIndex >= m_pSnapshot->getPropertyFrameCount(sFilterPropertyId))) || (bHasFilter && sDisplayPropertyId == sFilterPropertyId && nDisplayFrameIndex != nFilterFrameIndex)) { return false; } if(sDisplayPropertyId == m_sCurrentPropertyId && nDisplayFrameIndex == m_nCurrentFrameIndex && sFilterPropertyId == m_sFilterPropertyId && (!bHasFilter || nFilterFrameIndex == m_nFilterFrameIndex)) { return true; } const QString sDisplayArrayName = sDisplayPropertyId == QString::fromLatin1("pressure") ? QString::fromLatin1("p") : sDisplayPropertyId; const QString sFilterArrayName = sFilterPropertyId == QString::fromLatin1("pressure") ? QString::fromLatin1("p") : sFilterPropertyId; vtkSmartPointer pDisplayCandidate; vtkSmartPointer pFilterCandidate; const vtkIdType nCellCount = m_pSnapshot->getResultCellCount(); if(m_eBindingMode == SharedPropertyArray) { m_pBindingGrid->GetCellData()->Initialize(); if(!m_pSnapshot->bindPropertyFrame( sDisplayPropertyId, nDisplayFrameIndex, m_pBindingGrid)) { return false; } pDisplayCandidate = vtkDoubleArray::SafeDownCast( m_pBindingGrid->GetCellData()->GetScalars()); if(!isValidCopiedScalars( pDisplayCandidate, nCellCount, sDisplayArrayName)) { m_pBindingGrid->GetCellData()->Initialize(); return false; } if(bHasFilter && sFilterPropertyId != sDisplayPropertyId) { m_pBindingGrid->GetCellData()->Initialize(); if(!m_pSnapshot->bindPropertyFrame( sFilterPropertyId, nFilterFrameIndex, m_pBindingGrid)) { return false; } pFilterCandidate = vtkDoubleArray::SafeDownCast( m_pBindingGrid->GetCellData()->GetScalars()); if(!isValidCopiedScalars( pFilterCandidate, nCellCount, sFilterArrayName)) { m_pBindingGrid->GetCellData()->Initialize(); return false; } } m_pBindingGrid->GetCellData()->Initialize(); } else { if(!m_pSnapshot->copyPropertyFrame( sDisplayPropertyId, nDisplayFrameIndex, m_pStandbyBuffer) || !isValidCopiedScalars( m_pStandbyBuffer, nCellCount, sDisplayArrayName)) { return false; } pDisplayCandidate = m_pStandbyBuffer; if(bHasFilter && sFilterPropertyId != sDisplayPropertyId) { if(!m_pSnapshot->copyPropertyFrame( sFilterPropertyId, nFilterFrameIndex, m_pFilterStandbyBuffer) || !isValidCopiedScalars( m_pFilterStandbyBuffer, nCellCount, sFilterArrayName)) { return false; } pFilterCandidate = m_pFilterStandbyBuffer; } } if(bHasFilter && sFilterPropertyId == sDisplayPropertyId) { pFilterCandidate = pDisplayCandidate; } vtkCellData* pCellData = m_pRenderGrid->GetCellData(); vtkSmartPointer pPreviousDisplay = pCellData->GetScalars(); vtkSmartPointer pPreviousFilter; const QString sPreviousDisplayName = getCurrentScalarArrayName(); const QString sPreviousFilterName = getFilterScalarArrayName(); if(!sPreviousFilterName.isEmpty() && sPreviousFilterName != sPreviousDisplayName) { pPreviousFilter = pCellData->GetArray( sPreviousFilterName.toLatin1().constData()); } if(!sPreviousDisplayName.isEmpty()) { pCellData->RemoveArray(sPreviousDisplayName.toLatin1().constData()); } if(!sPreviousFilterName.isEmpty() && sPreviousFilterName != sPreviousDisplayName) { pCellData->RemoveArray(sPreviousFilterName.toLatin1().constData()); } pCellData->SetScalars(pDisplayCandidate); if(bHasFilter && sFilterArrayName != sDisplayArrayName) { pCellData->AddArray(pFilterCandidate); } const bool bCommitted = pCellData->GetScalars() == pDisplayCandidate.GetPointer() && (!bHasFilter || sFilterArrayName == sDisplayArrayName || pCellData->GetArray(sFilterArrayName.toLatin1().constData()) == pFilterCandidate.GetPointer()); if(!bCommitted) { pCellData->RemoveArray(sDisplayArrayName.toLatin1().constData()); if(!sFilterArrayName.isEmpty() && sFilterArrayName != sDisplayArrayName) { pCellData->RemoveArray(sFilterArrayName.toLatin1().constData()); } if(pPreviousDisplay != NULL) { pCellData->SetScalars(pPreviousDisplay); } if(pPreviousFilter != NULL) { pCellData->AddArray(pPreviousFilter); } return false; } if(m_eBindingMode == CopiedPropertyArray) { qSwap(m_pActiveBuffer, m_pStandbyBuffer); if(bHasFilter && sFilterPropertyId != sDisplayPropertyId) { qSwap(m_pFilterActiveBuffer, m_pFilterStandbyBuffer); } } m_sCurrentPropertyId = sDisplayPropertyId; m_nCurrentFrameIndex = nDisplayFrameIndex; m_sFilterPropertyId = sFilterPropertyId; m_nFilterFrameIndex = bHasFilter ? nFilterFrameIndex : -1; m_pRenderGrid->Modified(); 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; } QString nmPebiResultSnapshotRenderAdapter::getFilterScalarArrayName() const { if(m_sFilterPropertyId.isEmpty()) { return QString(); } return m_sFilterPropertyId == QString::fromLatin1("pressure") ? QString::fromLatin1("p") : m_sFilterPropertyId; } QString nmPebiResultSnapshotRenderAdapter::getFilterPropertyId() const { return m_sFilterPropertyId; } int nmPebiResultSnapshotRenderAdapter::getFilterFrameIndex() const { return m_nFilterFrameIndex; } 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; }