vtkPolyDataNormals appears to behave incorrectly

The sample code I provide here allows you to easily compare SetComputePointNormals(true) and SetComputePointNormals(false), so we can compare the correct behavior with the incorrect behavior, shown in this image:


Here is the code:

#include <vtkActor.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkPolyDataNormals.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkCleanPolyData.h>

int main(int argc, char* argv[])
{
	if(argc != 3) {
		std::cout <<
		"Error: We need the filename in argv[1], and argv[2] should be Y or N for ComputePointNormals"
		<< std::endl;
		return EXIT_FAILURE;
	}

	vtkNew<vtkPolyDataReader> reader;
	reader->SetFileName(argv[1]);
	reader->Update();

	vtkNew<vtkCleanPolyData> cleaner;
	cleaner->SetInputData(reader->GetOutput());
	cleaner->ConvertPolysToLinesOn();
	cleaner->ConvertLinesToPointsOn();

	vtkNew<vtkPolyDataNormals> normals;
	normals->SetInputConnection(cleaner->GetOutputPort());
	normals->ComputeCellNormalsOn();
	normals->SetComputePointNormals(argv[2][0] == 'Y');

	vtkNew<vtkPolyDataMapper> mapper;
	mapper->SetInputConnection(normals->GetOutputPort());

	vtkNew<vtkActor> actor;
	actor->SetMapper(mapper);

	vtkNew<vtkRenderer> renderer;
	renderer->AddActor(actor);
	renderer->SetBackground(0.1, 0.4, 0.1);

	vtkNew<vtkRenderWindow> renderWindow;
	renderWindow->AddRenderer(renderer);
	renderWindow->SetSize(1500, 1000);
	renderWindow->SetWindowName(argv[2]);

	vtkNew<vtkRenderWindowInteractor> interactor;
	interactor->SetRenderWindow(renderWindow);

	interactor->Initialize();
	renderWindow->Render();
	renderWindow->Render();
	interactor->Start();

	return EXIT_SUCCESS;
}

And here is the file containing the polydata:
SourceData.vtk (282.7 KB)

You run the program like this:
programName SourceData.vtk Y
or like this:
programName SourceData.vtk N
The Y/N on the command line controls the boolean going into SetComputePointNormals()

Hi @whereismymoney,

Thanks for posting!

Indeed, that doesn’t look great and it could be related to the normals calculation.

Could you try the same thing without the clean filter please?

Best,
Julien

Hi Julien,
Thank you for your response. Without the cleaner, both the SetComputePointNormals(true) and SetComputePointNormals(false) cases look good.
Best,
Matthias

In our product, we must include the clean filter [with ConvertPolysToLinesOn() and ConvertLinesToPointsOn()] to avoid a crash in vtkPolyDataNormals for other more complicated test cases.

The polydata I provided has a lot of problems. Here is a report prepared by Mathematica