vtkGeometryFIlter does not support vtkMultiBockDataSet containing mixed polydata/unstructured grid content


I’m working with vtkMultiBlockDataSets that contain both ctkPolyData and vtkUnstructuredGrid blocks.

I find that neither vtkGeometryFilter nor vtkDataSetSurfaceFIlter support such a dataset. These filters work just fine if the vtkMultiBlockDataSet includes only polys or only ugrids - but they just donlt work at all with mixed datasets

So to extract the external faces of my data I have to write my own filter, iterate over the multi blcok data set and execute geomety filter oon the individauel datasets and reconstruct the multiblock dataset.

Is this a know limitation? Is there a better way to do this?


vtkGeometryFilter and vtkDataSetFilter are not supposed to take vtkMultiBlockDataSet inputs. How are you using it? In plain C++?

What you should use with a multi block is vtkCompositeDataGeometryFilter. It iterates on the input blocks and calls vtkDataSetSurfaceFilter on them.

@Yohann_Bearzi - Thanks for the reply. I’m using Python. The documentation for the geometfy filter classes says they take ANY vtk dataset however I just relaised that vtkMultiblockDataSet doesnlt actually inherit from vtkDataSet - so that make sense.

The problem with using vtkCompositeDataGeometryFilter is that it gives me back a single vtkPolydata which isn’t what I need. I need to keep the structure of the vtkMultiBlockDataSet.

My understanding of VTK was that non-composite aware filters should just iterate over the composite data structures - but that seems not to be the case.

For now, I’m just going to keep doing what Ido now - implement my own fillter that iterates over the blocks and returns a filtered vrkMultiBlockDataSet. The Python implementaion of vtkPythonAlgorithm make writing this filter really easy AND keeps my pipeline intact.


vtkCompositeDataGeometryFilter should do exactly what you intend to do. You don’t need to write your own filter.

I’m pretty sure it generates a SINGLE vtkPolyData - not a vtkMultiBlockDtatSet of vtkPolyDatas.
But I’ll check. It’s a while since I did this and I may be wrong…

From the documentation

vtkCompositeDataGeometryFilter applies vtkGeometryFilter to all leaves in vtkCompositeDataSet. Place this filter at the end of a pipeline before a polydata consumer such as a polydata mapper to extract geometry from all blocks and append them to one polydata object.

Oh yes you’re correct. My bad. Yes, you need to create a custom filter. Shouldn’t be too hard.

My understanding of VTK was that non-composite aware filters should just iterate over the composite data structures - but that seems not to be the case.

I would’ve expected vtkGeometryFilter to work as you expected it too. Can you file a bug report?

@andreasbuykx - Yes - I will file a bug report.

OK - Turns out this is fake news…
I created an issue and was building a test case to demonstrate the problelm when I realised that what I was stating was wrong.

Basically I was doing this,

geometry_filter = vtk.vtkGeometryFilter()
geometry_filter_output = geometry_filter.GetOutput()
print('type(geometry_filter_output) : ',type(geometry_filter_output))

And finding the output type to be None, and seemingly confirming the problem.
But when I change the output line to,

geometry_filter_output = geometry_filter.GetOutputDataObject(0)

I do in fact get a vtkMultiBlockDataSet returned from the different geometry filters.

I don’t really understand why I have to use GetOutputDataObject(0) when the input is a vtkMultiBlockDataSet but GetOuput() works just fine when the input is a vtkPolyData or vtkUnstructuredGrid?

vtkGeometryFilter::GetOutput() is a convenience method from the base class vtkPolyDataAlgorithm that returns the output cast to vtkPolyData, because (except when processing composite data) any vtkPolyDataAlgorithm returns vtkPolyData. This explains why it returns None on a vtkMultiBlockDataSetInput, and I would expect that it returns None for a vtkUnstructuredGrid too.

When processing composite data with a non-composite aware filter the executive creates a duplicate of the input data object which is not a vtkPolyData. Therefore you have to use vtkGeometryFilter::GetOutputDataObject which just returns the data object at the specified output port.