Add option to compute surface normals in Surface representations?

If you have surface data without normals, you can use the Generate Surface Normals filter to generate normals and get smoother shading.

If you have volumetric data and you are displaying the outer boundary of the volume with the Surface representation, that data typically doesn’t have surface normals, so you need to first run Extract Surface followed by Generate Surface Normals.

Both of these scenarios require setting up filters in the pipeline, and if you have many data objects loaded, adding one or two more filters for each one for display purposes can be cumbersome.

Would it make sense to have a Surface representation option to compute and use surface normals (default off)? This representation is already extracting the surface, so it would optionally add the equivalent of the Generate Surface Normals filter when the option is on.

Any objections to adding such an option?

2 Likes

Would you just compute the normals or also do triangle splitting and orientation fixes, which is what what the default options of Generate Surface Normals do?

Very interesting feature! Having an option in the representation to automatically compute normal if they are missing seems to me to be the best solution.

Next question will be, where should we add this capability? and I thought the best place was in the vtkGeometryFilter as it’s use by most representations to convert dataset into polydata.

wdyt?

Would you just compute the normals or also do triangle splitting and orientation fixes, which is what what the default options of Generate Surface Normals do?

I wonder if it’s not better to compute normal directly with this filter

1 Like

I definitely agree, normals should be computed by the surface reprensentation (and its internal filters) by default and optionnaly could be turned off.

It should not rely on a secondary filter but be computed on the fly for performance reasons.

This capability should be added in vtkGeometryRepresentation and be connected to the output of vtkPVGeometryFilter.

1 Like

The important thing would be to have it default to “Off”. I am thinking of the non-orientable parameteric surfaces. In those cases, the normals are generated from the derivatives of the parametric equations.

1 Like

I think this is a good idea. Ask me if it needs funding.

1 Like

I really like the idea, but I do meet simulation people that want flat (cell-normal, not point-normal) surface rendering so they can see the discretization of their domain. One option to consider is adding a new representation instead of making it an option to the “Surface” rep (i.e., “Smooth Surface”, “Surface”, “Surface with Edges”).

I think this feature could be interesting for VTK too, that’s why I don’t consider to do it in the vtkGeometryRepresentation initially, wdyt?

That’s a valid design, but I think I prefer that we make it a property instead (along with other properties such as feature angle, edge splitting, etc) in the Surface representation. Default OFF.

VTK filters should primarily do one thing and do it well. Adding options like this results in a combinatoric explosion of testing of the filter. Composition should be prefered, and that points to computing normals in the vtkGeometryRepresentation.

1 Like

Note that the vtkPVGeometryFilter already has a GenerateCellNormals option that works for polygon cells.

Indeed, vtkGeometryRepresentation is ParaView only and VTK itself won’t benefit from this feature. I would expect that the normal computation would be computed through a VTK filter. It would ease reuse and avoid code duplication (maintenance nightmare).

Of course, I get Mathieu’s point about performance reason. The current code of vtkPolyDataNormals is definitely not trivial and reimplementing it in the representation is maybe not worth the expected performance gain. Could we get any insight?

I wanted to note that in one VTK application a customer provided a mesh that causes vtkPolyDataNormals to hang - I turned off these options to prevent the hang:

  m_normals->AutoOrientNormalsOff();
  m_normals->ConsistencyOff();
  m_normals->SplittingOff();

I imagine the code path taken without those options is much simpler.

I have personally worked on the performance of vtkGeometryFilter (used in vtkPVGeometryFilter) and vtkPolyDataNormals.

@Francois_Mazen
Also, i was not aware that vtkPVGeometryFilter can optionally compute cell normals. Personally i think this option should be deprecated, since we are planning to introduce normals computation somehow in the representation level.

A vtkDataRepresentatio, such as vtkGeometryRepresentation, is basically a geometry filter and a mapper or just a mapper for most cases. So if we want both VTK and ParaView to benefit from this work, vtkPolyDataMapper (parent class of vtkCompositePolyDataMapper used in vtkPVGeometryFIlter) should call vtkPolyDataNormals. If we want only ParaView to benefit from this work then vtkGeometryRepresentation should call vtkPolyDataNormals. We can decide which one is more useful.

@aron.helser
Personally, I would like to split vtkPolyDataNormals in two filters in the future, One that fixes, orientation, consistency, and splitting that we could name vtkFixPolyData (or something else), and one that does the actual normal for points or cells computation named vtkPolyDataNormals which can optionally use vtkFixPolyData using the orientation, consistency, and splitting flags. I would like to do that to simplify vtkPolyDataNormals which right now seems too complicate while it should not.

I was not aware of such an issue but if the code is hanging please post an issue on VTK with a dataset, and assuming there is funding, i can explore it.

Filed an issue. The customer is satisfied with disabling Splitting and Consistency, so this would have to be addressed under general VTK or ParaView bugs. It does hang ParaView with the Generate Surface Normals filter. (The data has some consistency issue definitely - duplicate/shared edges or points)

VTK has the vtkPolyDataNormals filter already. Applications that want to use it can use it, just like ParaView would use it in vtkGeometryRepresentation with this approach.

There is no need to reimplement it, just use vtkPolyDataNormals on the output of vtkPVGeometryFilter as Spiros suggested. I’m not sure how one would compute point normals “on the fly” during geometry extraction - you need to accumulate the average normal at points, and doing that with multithreading is complex. Perhaps there is a way, but that would make the surface extraction code much more complex which makes the likelihood of getting any performance benefit lower in my opinion.