Fem: Move FemFrameSourceAlgorithm class to its own source files

This commit is contained in:
marioalexis
2025-09-14 00:14:52 -03:00
parent 3ffb861d11
commit 3e1741dfea
6 changed files with 265 additions and 173 deletions

View File

@@ -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));
}