Hi all,
I am using Paraview 5.11.0.
I am currently trying to use the vtkImageAppend class in a filter. My problem is that the new dataset is not saved in the pipeline.
Here is a simplified version of my RequestData function:
int ttkperiodiqueGhostsGeneration::RequestData(vtkInformation *ttkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector) {
vtkDataSet *input = vtkDataSet::GetData(inputVector[0]);
vtkImageData* image = vtkImageData::SafeDownCast(input);
vtkDataSet *output = vtkDataSet::GetData(outputVector);
vtkSmartPointer<vtkImageAppend> imageAppend = vtkSmartPointer<vtkImageAppend>::New();
vtkNew<vtkImageData> input2;
input2->DeepCopy(image);
imageAppend->SetInputData(image);
imageAppend->AddInputData(input2);
imageAppend->SetAppendAxis(0);
imageAppend->Update();
output->ShallowCopy(imageAppend->GetOutput());
return 0;
}
In this snippet, I try to append the same ImageData twice. However, when executing with Paraview, if I look at the results in the spreadsheet view, I can clearly see that the data does not grow, and there are as many points after my filter as before, when the number of points should double.
I feel like I am missing a step, but I can’t seem to figure out what.
Is there some additional things to do to ensure the data is indeed created and passed down the pipeline?
Thanks for any help
Hi all,
I have managed to eventually to append the data and show it in Paraview. What was missing was a new RequestInformation method like this:
int ttkperiodiqueGhostsGeneration::RequestInformation(
vtkInformation *ttkNotUsed(request),
vtkInformationVector **inputVectors,
vtkInformationVector *outputVector) {
vtkImageData* image = vtkImageData::GetData(inputVectors[0]);
vtkImageData *output = vtkImageData::GetData(outputVector);
int newExtent[6];
int* extent = image->GetExtent();
newExtent[0] = extent[0];
newExtent[1] = extent[1]+(extent[1]-extent[0]);
newExtent[2] = extent[2];
newExtent[3] = extent[3];
newExtent[4] = extent[4];
newExtent[5] = extent[5];
vtkInformation *outInfo = outputVector->GetInformationObject(0);
outInfo->Set(vtkStreamingDemandDrivenPipeline::UNRESTRICTED_UPDATE_EXTENT(), 1);
outInfo->Set(
vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), newExtent, 6);
return 1;
}
However, I still have an error message from Paraview:
( 14.760s) [paraview ]vtkStreamingDemandDrive:867 ERR| vtkPVPostFilterExecutive (0x55890232eee0): The update extent specified in the information for output port 0 on algorithm vtkPVPostFilter (0x55890232be90) is -10 30 -10 10 -10 10, which is outside the whole extent -10 10 -10 10 -10 10.
I am doing something wrong?
Is there a way to move the code inside RequestInformation
to RequestData
?
Thanks for any help.
I think you would need to be able to use the vtkImageAppend::RequestInformation
on your own RequestInformation
.
The easiest way to do so would be to set the vtkImageAppend
filter as an internal field in your class so you can call its RequestInformation
directly inside your own. You would also need to provide the AppendAxis
directly in your constructor as it needs to be set before the pipeline call these methods.
Hi,
Thanks for the reply. I will try this and get back to you if I have any problems.
Hi,
Unfortunately, as the RequestInformation
method in vtkImageAppend
is protected, I can’t call it from my own filter.
Furthermore, my end goal is to use several vtkImageAppend
filters, for which some of the data is not available before the execution of the filter, and some computation is also necessary to know how many vtkAppendImage
filters are necessary and what their append axis are.
Is there a way to solve the problem showed by the error message from my filter’s RequestData
?
Thanks for any help.
Unfortunately, as the RequestInformation
method in vtkImageAppend
is protected, I can’t call it from my own filter.
I do not like when a filter does this… You have two ways to overcome this small issue:
- The clean one, when you call
UpdateInformation()
of the vtkImageAppend
filter then retrieve the Keys you need on your own RequestInformation
(using GetInformation
).
- The easy one, when you create a dumb intermediate class, that inherits from
vtkImageAppend
and override the Request*
methods in its public
area.
Furthermore, my end goal is to use several vtkImageAppend
filters, for which some of the data is not available before the execution of the filter, and some computation is also necessary to know how many vtkAppendImage
filters are necessary and what their append axis are.
From my understanding, as long as you are directly outputting vtkImageData
you need to have a correct WHOLE_EXTENT
at the end of the RequestInformation
. As this is also true for the filters used in the input, I am not sure to get which information you would miss during this step to compute a valid one, as all your input ImageData should have their extent available.
Is there a way to solve the problem showed by the error message from my filter’s RequestData
?
The workaround I would see would be to output a vtkPartitionnedDataSet
(or another composite) instead of an image data if you cannot fulfill the Whole extent constraint. This approach has some drawbacks of course as the input is now inside a composite.
Thank you for the reply.
I eventually created my own function for merging vtkImageData objects that corresponded to my needs better.
The error message mentioned earlier was due to my implementation missing the RequestUpdateExtent
function, similarly to what is described here.
Everything seems to work well now.
Thanks for all the help!