I am migrating my code from VTK 8.2.0 to VTK 9.4.0 and I have noticed (after spending some time debugging) that vtkClipPolyData behaves differently.
The context is the following:
I call vtkClipPolyData to clip with a plane an input PolyData (that is generated from vtkImageMarchingCubes). Clearly the input PolyData it’s not a manifold.
After calling vtkClipPolyData, I compute the bounds of the clipped polydata.
In VTK 8.2.0, the bounds fit the extend of the clipped PolyData.
In VTK 9.4.0, the bounds fit the extend of the input PolyData.
Visually (even with ParaView) both clipped polygonal data look similar.
Then by inspecting their respective vtk files, I have noticed that in the VTK 9.4.0 file some points that have been clipped and are still there. The solution I found is to call an extra vtkCleanPolyData to get rid of these points.
What is the right behavior for vtkClipPolyData ? VTK 8.2.0 or VTK 9.4.0
Looking at the documentation, there is a warning “the resulting output may consist of different cell types than the input data.” So probably VTK 9.4.0 has the right behavior.
Is there a better & straight solution that calling vtkCleanPolyData in VTK 9.4.0 ?
Adding vtkCleanPolyData seems like the best solution, since it’s the go-to method for removing unused points in a dataset.
In my opinion, the VTK 8.2 behavior seems more correct. If a point has been clipped, it should not be present in the output. I have been looking at the code to try to find out what has changed between 8.2 and 9.4, there aren’t many VTK classes that are involved: just vtkClipPolyData, vtkMergePoints, and vtkTriangle.
If I find something wrong with the code, I’ll let you know. Otherwise, just use vtkCleanPolyData.
I’ve investigated this, and the situation is more complex than I had expected. Key points:
The behavior of vtkClipPolyData has not changed since VTK 8.2
The behavior of GetBounds() has changed (it changed in VTK 9.1)
Use GenerateClippedOutputOff() to avoid the extra, unwanted points
Even in VTK 8.2, vtkClipPolyData will produce these unwanted points if GenerateClippedOutput is On. It does this because it uses the same vtkPoints object for both the ClippedOutput, and the main Output. In other words, both outputs contain all of the points for both the “clipped” and the “kept” parts of the dataset.
The thing that changed in VTK 9.1 is that vtkPolyData::GetBounds() computes the bounds based on the points rather than the cells. So GetBounds() used to ignore any points that didn’t belong a cell, but now, GetBounds() uses all the points, even points that aren’t used by any cells. See this link for an explanation.
Proposed solution:
Instead of using GenerateClippedOutputOn(), use two separate vtkClipPolyData filters and call InsideOutOn() on one of them. This will be less efficient than using just one vtkClipPolyData, but it will probably be more efficient than vtkCleanPolyData.
Now, I understand how GenerateClippedOutputOn() works. Indeed, in my code I use GenerateClippedOutputOn().
I will follow your proposed solution: two vtkClipPolyData (with GenerateClippedOutputOff()) since I find more intuitive to get an output PolyData with all clipped points removed.
Moreover, it’s compatible with VTK 8.2