Hope this script is useful for someone…
It’s done to be executed on Slicer but you can easily adapt it to pure vtk.
guide_dec = getNode('guide-dec')
idFilter = vtk.vtkIdFilter()
idFilter.SetInputData(guide_dec.GetMesh());
idFilter.SetPointIds(True)
idFilter.SetCellIds(False)
idFilter.SetPointIdsArrayName("PointIds")
idFilter.SetCellIdsArrayName("CellIds")
idFilter.Update()
nonManifoldEdgesFilter = vtk.vtkFeatureEdges()
nonManifoldEdgesFilter.SetInputData(idFilter.GetOutput())
nonManifoldEdgesFilter.BoundaryEdgesOff()
nonManifoldEdgesFilter.FeatureEdgesOff()
nonManifoldEdgesFilter.ManifoldEdgesOff()
nonManifoldEdgesFilter.NonManifoldEdgesOn()
nonManifoldEdgesFilter.Update()
nonManifoldPointids = nonManifoldEdgesFilter.GetOutput().GetPointData().GetArray("PointIds")
nonManifoldPointids.GetNumberOfValues()
edgesFilter = vtk.vtkFeatureEdges()
edgesFilter.SetInputData(idFilter.GetOutput())
edgesFilter.BoundaryEdgesOff()
edgesFilter.FeatureEdgesOff()
edgesFilter.ManifoldEdgesOn()
edgesFilter.NonManifoldEdgesOn()
edgesFilter.Update()
allPointids = edgesFilter.GetOutput().GetPointData().GetArray("PointIds")
ids = vtk.vtkIdTypeArray()
ids.SetNumberOfComponents(1)
for i in range(nonManifoldPointids.GetNumberOfValues()):
nonManifoldPointIDFound = True
for j in range(allPointids.GetNumberOfValues()):
if int(nonManifoldPointids.GetTuple1(i)) == int(allPointids.GetTuple1(i)):
nonManifoldPointIDFound = False
break
ids.InsertNextValue(int(nonManifoldPointids.GetTuple1(i)))
selectionNode = vtk.vtkSelectionNode()
selectionNode.SetFieldType(vtk.vtkSelectionNode.POINT)
selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES)
selectionNode.SetSelectionList(ids);
selectionNode.GetProperties().Set(vtk.vtkSelectionNode.CONTAINING_CELLS(), 1)
selectionNode.GetProperties().Set(vtk.vtkSelectionNode.INVERSE(), 1)
selection = vtk.vtkSelection()
selection.AddNode(selectionNode);
extractSelection = vtk.vtkExtractSelection()
extractSelection.SetInputConnection(0, guide_dec.GetPolyDataConnection())
extractSelection.SetInputData(1, selection)
extractSelection.Update()
geometryFilter = vtk.vtkGeometryFilter()
geometryFilter.SetInputData(extractSelection.GetOutput())
geometryFilter.Update()
# test if the removal of non manifold edges did work
featureEdges2 = vtk.vtkFeatureEdges()
featureEdges2.SetInputData(geometryFilter.GetOutput())
featureEdges2.BoundaryEdgesOff()
featureEdges2.FeatureEdgesOff()
featureEdges2.ManifoldEdgesOff()
featureEdges2.NonManifoldEdgesOn()
featureEdges2.Update()
featureEdges2.GetOutput().GetNumberOfPoints()
# save the model without non-manifold edges
guide_dec.SetAndObserveMesh(geometryFilter.GetOutput())