Mesh internal surface smoothing behavior changed in vtkWindowedSincPolyDataFilter

It seems that the rewrite of vtkWindowedSincPolyDataFilter (that amazingly improved its performance) also changed how internal surfaces are smoothed. Smoothing of internal surfaces are important because when we segment a medical image we usually annotate many adjacent structures that have common surfaces and when we apply smoothing then we want to smooth surface of each structure and not just the outer surface of the entire segmented region.

The old version (VTK8) smoothed the internal surfaces, while the new version (VTK9) does not seem to smooth internal edges at all.

I’ve tried to adjust all parameters (BoundarySmoothingOn/Off, FeatureEdgeSmoothingOn/Off, NonManifoldSmoothingOn/Off, FeatureAngle, EdgeAngle, NormalizeCoordinatesOn/Off) but I could not find any settings that would smooth the internal surfaces.

@will.schroeder Is this difference expected? Could there be any preprocessing or filter parameter combination that would allow smoothing internal surfaces?

Example

Input surface

Smoothed surface using old vtkWindowedSincPolyDataFilter

Boundary between segments are smoothed. There is some bubbling due to the strong smoothing factor (we used somewhat stronger smoothing as usual to make all differences easier to see).

image

Smoothed surface using new vtkWindowedSincPolyDataFilter

Outer surface is smoothed - good. There is no bubbling (outer surface remains smooth) - good (better than the old version). However, internal edges remain sharp and jagged - not good, they are not smoothed at all.

image

How to reproduce

Run the Python script below on this data set, using the old and new version of vtkWindowedSincPolyDataFilter (in the zip file I’ve included both outputs, so the results can be compared without running the script).

# WindowedSyncPolyDataFilter internal edge smoothing test

reader = vtk.vtkXMLPolyDataReader()
reader.SetFileName("c:/tmp/smootherinput.vtp")

smoother = vtk.vtkWindowedSincPolyDataFilter()
smoother.SetInputConnection(reader.GetOutputPort())
smoother.SetNumberOfIterations(100)
smoother.SetPassBand(0.0001)
smoother.NormalizeCoordinatesOn()
smoother.FeatureEdgeSmoothingOff()
smoother.SetFeatureAngle(90.0)
smoother.SetEdgeAngle(15.0)
smoother.BoundarySmoothingOff()
smoother.NonManifoldSmoothingOn()

smoother.Update()
writer = vtk.vtkXMLPolyDataWriter()
writer.SetInputConnection(smoother.GetOutputPort())
writer.SetFileName("c:/tmp/smootheroutput.vtp")
writer.Update()
writer.Write()

Thanks Andras for bringing this to our attention. The filters should produce the same results so this needs to be fixed.

By internal edges, are you using vtkDiscreteMarchingCubes (or equivalent) to produce non-manifold edges (i.e., edges used by more than two triangles/polygons)?

Unfortunately I’ve got some heavy deliverables this month, but as soon as I can I will look into this. I suspect that it may be related to the smoothing network as it relates to non-manifold edges.

Yes, we use vtkDiscreteMarchingCubes, to generate the input mesh from a label volume (see here.

Sounds great, thank you.

@lassoan something like this may also make a good example.

If you’re really busy, I’m happy to do both a Python & C++ example form what you have provided once the internal edge smoothing is fixed…

1 Like

Andrew this would be good. Part of the reason is that I hope to complete Surface Nets 3D in June, which (should be) a superior version of vtkDiscreteMarchingCubes. It would be good to have an example for that as well.

Excellent! Keep me in the loop … please.