Fem: Move FemFrameSourceAlgorithm class to its own source files
This commit is contained in:
@@ -40,7 +40,6 @@
|
||||
#include <vtkXMLUnstructuredGridReader.h>
|
||||
#include <vtkXMLMultiBlockDataReader.h>
|
||||
#include <vtkMultiBlockDataSet.h>
|
||||
#include <vtkStreamingDemandDrivenPipeline.h>
|
||||
#include <vtkFloatArray.h>
|
||||
#include <vtkStringArray.h>
|
||||
#include <vtkInformation.h>
|
||||
@@ -61,145 +60,6 @@ using namespace Fem;
|
||||
using namespace App;
|
||||
|
||||
|
||||
vtkStandardNewMacro(FemFrameSourceAlgorithm);
|
||||
|
||||
FemFrameSourceAlgorithm::FemFrameSourceAlgorithm::FemFrameSourceAlgorithm()
|
||||
{
|
||||
// we are a source
|
||||
SetNumberOfInputPorts(0);
|
||||
SetNumberOfOutputPorts(1);
|
||||
}
|
||||
|
||||
|
||||
FemFrameSourceAlgorithm::FemFrameSourceAlgorithm::~FemFrameSourceAlgorithm()
|
||||
{}
|
||||
|
||||
void FemFrameSourceAlgorithm::setDataObject(vtkSmartPointer<vtkDataObject> data)
|
||||
{
|
||||
m_data = data;
|
||||
Modified();
|
||||
Update();
|
||||
}
|
||||
|
||||
bool FemFrameSourceAlgorithm::isValid()
|
||||
{
|
||||
return m_data.GetPointer() != nullptr;
|
||||
}
|
||||
|
||||
std::vector<double> FemFrameSourceAlgorithm::getFrameValues()
|
||||
{
|
||||
|
||||
// check if we have frame data
|
||||
if (!m_data || !m_data->IsA("vtkMultiBlockDataSet")) {
|
||||
return std::vector<double>();
|
||||
}
|
||||
|
||||
// we have multiple frames! let's check the amount and times
|
||||
vtkSmartPointer<vtkMultiBlockDataSet> multiblock = vtkMultiBlockDataSet::SafeDownCast(m_data);
|
||||
|
||||
unsigned long nblocks = multiblock->GetNumberOfBlocks();
|
||||
std::vector<double> tFrames(nblocks);
|
||||
|
||||
for (unsigned long i = 0; i < nblocks; i++) {
|
||||
|
||||
vtkDataObject* block = multiblock->GetBlock(i);
|
||||
// check if the TimeValue field is available
|
||||
if (!block->GetFieldData()->HasArray("TimeValue")) {
|
||||
// a frame with no valid value is a undefined state
|
||||
return std::vector<double>();
|
||||
}
|
||||
|
||||
// store the time value!
|
||||
vtkDataArray* TimeValue = block->GetFieldData()->GetArray("TimeValue");
|
||||
if (!TimeValue->IsA("vtkFloatArray") || TimeValue->GetNumberOfTuples() < 1) {
|
||||
// a frame with no valid value is a undefined state
|
||||
return std::vector<double>();
|
||||
}
|
||||
|
||||
tFrames[i] = vtkFloatArray::SafeDownCast(TimeValue)->GetValue(0);
|
||||
}
|
||||
|
||||
return tFrames;
|
||||
}
|
||||
|
||||
int FemFrameSourceAlgorithm::RequestInformation(vtkInformation* reqInfo,
|
||||
vtkInformationVector** inVector,
|
||||
vtkInformationVector* outVector)
|
||||
{
|
||||
|
||||
// setup default information
|
||||
if (!this->Superclass::RequestInformation(reqInfo, inVector, outVector)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_data) {
|
||||
// for the no data case we would return a empty data set in RequestData.
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<double> frames = getFrameValues();
|
||||
|
||||
if (frames.empty()) {
|
||||
// no frames, default info is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
double tRange[2] = {frames.front(), frames.back()};
|
||||
|
||||
// finally set the time info!
|
||||
vtkInformation* info = outVector->GetInformationObject(0);
|
||||
info->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), tRange, 2);
|
||||
info->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &frames[0], frames.size());
|
||||
info->Set(CAN_HANDLE_PIECE_REQUEST(), 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FemFrameSourceAlgorithm::RequestData(vtkInformation*,
|
||||
vtkInformationVector**,
|
||||
vtkInformationVector* outVector)
|
||||
{
|
||||
vtkInformation* outInfo = outVector->GetInformationObject(0);
|
||||
vtkUnstructuredGrid* output =
|
||||
vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||||
|
||||
if (!output) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_data) {
|
||||
outInfo->Set(vtkDataObject::DATA_OBJECT(), vtkUnstructuredGrid::New());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!m_data->IsA("vtkMultiBlockDataSet")) {
|
||||
// no multi frame data, return directly
|
||||
outInfo->Set(vtkDataObject::DATA_OBJECT(), m_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkMultiBlockDataSet> multiblock = vtkMultiBlockDataSet::SafeDownCast(m_data);
|
||||
// find the block asked for (lazy implementation)
|
||||
unsigned long idx = 0;
|
||||
if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())) {
|
||||
auto time = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
|
||||
auto frames = getFrameValues();
|
||||
|
||||
// we have float values, so be aware of rounding errors. lets subtract the searched time and
|
||||
// then use the smallest value
|
||||
for (auto& frame : frames) {
|
||||
frame = std::abs(frame - time);
|
||||
}
|
||||
|
||||
auto it = std::ranges::min_element(frames);
|
||||
idx = std::distance(frames.begin(), it);
|
||||
}
|
||||
|
||||
auto block = multiblock->GetBlock(idx);
|
||||
output->ShallowCopy(block);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PROPERTY_SOURCE_WITH_EXTENSIONS(Fem::FemPostPipeline, Fem::FemPostObject)
|
||||
|
||||
FemPostPipeline::FemPostPipeline()
|
||||
@@ -215,7 +75,8 @@ FemPostPipeline::FemPostPipeline()
|
||||
"set via pipeline object).");
|
||||
|
||||
// create our source algorithm
|
||||
m_source_algorithm = vtkSmartPointer<FemFrameSourceAlgorithm>::New();
|
||||
m_source_algorithm = vtkSmartPointer<vtkFemFrameSourceAlgorithm>::New();
|
||||
|
||||
m_transform_filter->SetInputConnection(m_source_algorithm->GetOutputPort(0));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user