Create filter that uses vtkImageAppend

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.

@Charles_Gueunet maybe ?

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:

  1. The clean one, when you call UpdateInformation() of the vtkImageAppend filter then retrieve the Keys you need on your own RequestInformation (using GetInformation).
  2. 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!