Exception in vtkPolyDataNormals when using vtkThreadedCompositeDataPipeline
We are experiencing a crash in a very simple test application to test the behaviour of vtkThreadedCompositeDataPipeline. The same application works fine when using vtkCompositeDataPipeline. Repeatedly executing the code below may result in different exception locations. Changing the number of loops may also change the location. May be a race condition.
VTK was compiled with Visual Studio 2019 (v142) using VTK_SMP_IMPLEMENTATION_TYPE=OpenMP.
We were under the impression that vtkThreadedCompositeDataPipeline is supposed to work with every filter that is not composite data aware out of the box.
#include <vtkMultiBlockDataSet.h>
#include <vtkSphereSource.h>
#include <vtkTransformFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkTransform.h>
#include <vtkCompositeDataPipeline.h>
#include <vtkThreadedCompositeDataPipeline.h>
int main()
{
vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetPhiResolution(10);
sphereSource->SetThetaResolution(10);
sphereSource->ReleaseDataFlagOff();
sphereSource->Update();
vtkSmartPointer<vtkPolyData> sphere = sphereSource->GetOutput();
vtkSmartPointer<vtkMultiBlockDataSet> multiblock = vtkSmartPointer<vtkMultiBlockDataSet>::New();
multiblock->SetNumberOfBlocks(10);
for (int i = 0; i < 10; ++i)
{
vtkSmartPointer<vtkPolyData> sphere2 = vtkSmartPointer<vtkPolyData>::New();
sphere2->DeepCopy(sphere);
multiblock->SetBlock(i, sphere2);
}
int cells = sphere->GetNumberOfCells();
std::cout << "Cells: " << cells << std::endl;
vtkSmartPointer<vtkThreadedCompositeDataPipeline> compositeExec = vtkSmartPointer<vtkThreadedCompositeDataPipeline>::New();
vtkAlgorithm::SetDefaultExecutivePrototype(compositeExec);
vtkSmartPointer<vtkPolyDataNormals> normalsFilter = vtkSmartPointer<vtkPolyDataNormals>::New();
normalsFilter->SetInputData(multiblock);
std::cout << "Start." << std::endl;
normalsFilter->Update();
vtkSmartPointer<vtkDataObject> obj = normalsFilter->GetOutputDataObject(0);
assert(obj->GetDataObjectType() == VTK_MULTIBLOCK_DATA_SET);
vtkSmartPointer<vtkMultiBlockDataSet> outputMultiblock = vtkMultiBlockDataSet::SafeDownCast(obj);
assert(outputMultiblock != nullptr);
assert(outputMultiblock->GetNumberOfBlocks() == multiblock->GetNumberOfBlocks());
vtkAlgorithm::SetDefaultExecutivePrototype(nullptr);
std::cout << "Done." << std::endl;
std::getchar();
}