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/nmData/nmPebiResultSnapshotRenderA...

412 lines
12 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 "nmPebiResultSnapshotRenderAdapter.h"
#include <vtkAlgorithmOutput.h>
#include <vtkCellData.h>
#include <vtkDataArray.h>
#include <vtkDoubleArray.h>
#include <vtkFieldData.h>
#include <vtkTrivialProducer.h>
#include <vtkUnstructuredGrid.h>
#include <QtGlobal>
#include <math.h>
#if !defined(_MSC_VER)
#include <cmath>
#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<vtkUnstructuredGrid>::New()),
m_pBindingGrid(vtkSmartPointer<vtkUnstructuredGrid>::New()),
m_pActiveBuffer(vtkSmartPointer<vtkDoubleArray>::New()),
m_pStandbyBuffer(vtkSmartPointer<vtkDoubleArray>::New()),
m_pFilterActiveBuffer(vtkSmartPointer<vtkDoubleArray>::New()),
m_pFilterStandbyBuffer(vtkSmartPointer<vtkDoubleArray>::New()),
m_pProducer(vtkSmartPointer<vtkTrivialProducer>::New()),
m_eBindingMode(SharedPropertyArray),
m_nCurrentFrameIndex(-1),
m_nFilterFrameIndex(-1)
{
}
nmPebiResultSnapshotRenderAdapter::~nmPebiResultSnapshotRenderAdapter()
{
clear();
}
bool nmPebiResultSnapshotRenderAdapter::initialize(
const QSharedPointer<const nmPebiResultSnapshot>& 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<const nmPebiResultSnapshot>& 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<vtkDoubleArray> pDisplayCandidate;
vtkSmartPointer<vtkDoubleArray> 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<vtkDataArray> pPreviousDisplay = pCellData->GetScalars();
vtkSmartPointer<vtkDataArray> 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;
}