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++

#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;
}