Add vtkPolygonalMeshPointNormals filter
vtkTriangleMeshPointNormals is a filter that computes point normals for a triangle mesh to enable high-performance rendering. It is a fast-path version of the vtkPolyDataNormals filter in order to be able to compute normals for triangle meshes deforming rapidly.
The algorithm works by determining normals for each triangle and adding these vectors to the triangle points. The resulting vectors at each point are then normalized.
This commit also adds the test TestTriangleMeshPointNormals and its baseline image in Filters/Core/Testing/Cxx.
- Normals are computed only for triangular polygons: the filter can not handle meshes with other types of cells (Verts, Lines, Strips) or Polys with the wrong number of components (not equal to 3).
- Unlike the vtkPolyDataNormals filter, this filter does not apply any splitting nor checks for cell orientation consistency in order to speed up the computation.
- Normals are not calculated the exact same way as the vtkPolyDataNormals filter since the triangle normals are not normalized before being added to the point normals: those cell normals are therefore weighted by the triangle area. This is not more nor less correct than normalizing them before adding them, but it is much faster.
If you do not need to do high-performance rendering, you should use vtkPolyDataNormals if your mesh is not only triangular, if you need to split vertices at sharp edges, or if you need to check that the cell orientations are consistent to flip inverted normals.
If you still need high-performance rendering but your input polydata is not a triangular mesh and/or does not have consistent cell orientations (causing inverted normals), you can still use this filter by using vtkTriangleFilter and/or vtkCleanPolyData respectively beforehand. If your mesh is deforming rapidly, you should be deforming the output mesh of those two filters instead in order to only run them once.
Use case & testing
This filter was implemented for a real-time simulation application where a mesh vertices are deforming at every frame. With 110k points, the framerates were the following:
- 100 fps with no normals computation
- 5 fps with vtkPolyDataNormals & default options
- 15 fps with vtkPolyDataNormals with SplittingOff & ConsistencyOff
- 80 fps with vtkPolygonalMeshPointNormals.
This is an improvement of 5 to 16 times faster for that use case.
High-performance rendering : Notes
For high-performance rendering of deformable meshes, two other improvements can be made to boost the performance:
- Skip frustrum culling
- Skip auto shift & scale of VBO:
Those two changes allow to skip calling
GetBounds(), which requires
to recompute the bounds at each frame.
This brings the framerate from 80 fps to 200 fps.
Co-authored with @ken-martin