How to properly clean a polydata with duplicated points

Dear all,

I’m a super-casual C++/VTK user and this is my first post here, so excuse my possible naivety, especially in coding (my daily job involves Fortran).

I have troubles in understanding what is the proper way to clean a polydata that has duplicated points (thus, potentially, zero area faces). With polydata I just refer to surfaces made of polygons (no lines, no vertices, no strips). And, to be more specific, I’m actually interested in surfaces made of triangles only.

This is what I have at the moment.

I used a cube source as starting point. Let’s name it as state 1. It has quadrilateral faces (6) and duplicated points (24). In order to reach the desired end result (8 vertices, 12 faces, no duplicate point) I tried different steps.

In the first step I applied a vtkTriangleFilter, because, as I said, I’m interested in triangles only. Of course, I didn’t expect this step to solve the duplicated points issue. Let’s call state 2 the output of this step.

Then, in the second step, I applied the vtkCleanPolyData filter, let’s name the output of this filter as state 3. Unfortunately, state 3 is rendered (not sure if this is the correct term or even if it is the origin of the problem) as if there is some issue with the normals of the faces (see image below).

Self-convinced by the possible issue with the normals, I kind of blindly applied a vtkPolyDataNormals filter, with ConsistencyOn and SplittingOff, let’s name its output as state 4. But the final result was still rendered wrongly (yet, differently from state 3, see the image below).

Then I realized that I could cure those rendering problems in states 3 and 4 by invoking SetInterpolationToFlat from the relative actors. It also made sense, I should not expect Gouraud to do the same as flat in that circumstance.

So far so good. But, then I realized that I could actually achieve what I wanted, with the expected rendering (not sure, at this point, what is the correct way of displaying what I want), in the two following ways (I’m adding states to them for the consistency of the comparison):

a) Writing the polydata to STL and reading it back (state 5)

b) Manually building the polydata (state 6)

All without any call to SetInterpolationToFlat.

I could eventually rely on manually building all my polydata related to simple sources, but I’m left wondering what would be the correct approach to clean a polydata without having the rendering artifacts I am experiencing? Is SetInterpolationToFlat called somewhere in the alternative ways a and b above?

The different states I mentioned above are shown in the picture below:

While the code I used to test this (and from which the picture is taken) is attached here:
CleanPolyData.tar.gz (3.5 KB)

Thanks for any possible help

If you get point normals from the cube source they will be oriented in the direction of the quad that they are associated with. When you then merge the coincident points as in (3), there are three different normals, and my guess is that just the first one gets chosen. When you calculate point normals as in (4) you probably end up with the average over all connecting triangles. Note that your manually created cube (6) has no normals at all.

What you could do to preserve the normals in a meaningful way to pass the cube source output to vtkPointDataToCellData, without passing point data, before merging the points.

Dear Andreas,

thank you very much for your answer, that elucidated me on several levels.

First of all, I made some tests, and it turns out that the polydata read from the STL doesn’t have normals neither. Which, I guess, makes sense, considering that it is constructed very similarly to how I do with my state 6.

Discovering that polydata might end up without normals, and trying to decipher how to use the vtkPointDatatoCellData filter, I wondered if there is a way to strip off the point normals and just use the cell ones.

I tried calling the normals filter BEFORE the clean filter, with ComputePointNormalsOff and ComputeCellNormalsOn, and this seems to achieve just that, clearing the point normals and computing the cells one. What comes later than only sees those cell normals, which are those I actually want to use in the rendering phase and everything seems to work.

Yet, I’m left with the doubt if this is the correct use and scenario for what I want to achieve.

I think calculating cell normals (and stripping off point normals) using vtkPolyDataNormals is a better solution than computing the cell normals from the point normals using vtkPointDataToCellData. I don’t think whether you apply it before or after vtkCleanPolyData makes a difference.

Yes indeed! Of course, having a null understanding of the matter, this specific combination (PointsOff,CellsOn) was not among those I tried in the past, but somehow I convinced myself of the contrary, which led me to the false assertion.

The fact that it works after the clean as well also makes me feel more confident in the final result.

Thank you again Andreas for your help