Automatize model generation from segmentation

Hi again,

meanwhile I discoverd similar topics, e.g.

and an example how to export the Model to disk:

https://github.com/SlicerMorph/Scripts#2-run-an-image-processing-pipeline-on-a-folder-of-volumes

One question remains on how is the order in setting up the segmentEditorWidget.
Not sure if the code is “fine” like it is applied, because after all files in the folder
are processed the “KEEP_LARGEST_ISLAND” filter is still “active” → the mouse pointer has this typical “icon”…

# Load CurrentSegmentation
    CurrentSegmentation = os.path.join(ProjectFolder, FilesInFolder[sampleIndex])
    slicer.util.loadSegmentation(CurrentSegmentation)
    segmentationNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLSegmentationNode")
    
    sampleID = segmentationNode.GetName()
    
    # storage of the segment volume 
    volumeSegment[sampleIndex][0] = sampleID 
    
    # masterVolume for segmentation
    masterVolumeNode = segmentationNode.GetNodeReference(segmentationNode.GetReferenceImageGeometryReferenceRole())
    
    # Create segment editor to get access to effects
    segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
    
    # To show segment editor widget (useful for debugging):
    # segmentEditorWidget.show()
    segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
    segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
    slicer.mrmlScene.AddNode(segmentEditorNode)
    segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
    
    # actual segmentation
    segmentEditorWidget.setSegmentationNode(segmentationNode)
    segmentEditorWidget.setSourceVolumeNode(masterVolumeNode)
    
    # Visible segments will be processed
    inputSegmentIDs = vtk.vtkStringArray()
    segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(inputSegmentIDs)
    
    segmentationNode.GetDisplayNode().SetSegmentVisibility(inputSegmentIDs.GetValue(2), False)
    
    # apply filter: Keep_Largest_Island / get rid of "particles"
    for index in range(inputSegmentIDs.GetNumberOfValues()-1):
        segmentID = inputSegmentIDs.GetValue(index)
        segmentEditorWidget.setCurrentSegmentID(segmentID)
        
        # Remove islands in inverted segment (these are the holes inside the segment)
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("Operation", "KEEP_LARGEST_ISLAND")
        effect.self().onApply()

    # prepare: Export segment -> to model
    shNode = slicer.mrmlScene.GetSubjectHierarchyNode()
    exportFolderItemId = shNode.CreateFolderItem(shNode.GetSceneItemID(), sampleID)
    slicer.modules.segmentations.logic().ExportAllSegmentsToModels(segmentationNode, exportFolderItemId)
itemList=[]
    shNode.GetItemChildren(exportFolderItemId,itemList)
    if itemList is []:
      print("Error: no model node exported for ", volumeNode.GetName())
      continue
    
    # export skull = Segment_1
    modelNode = shNode.GetItemDataNode(itemList[0])
    # Decimate the model 80%
    slicer.modules.SurfaceToolboxWidget.logic.decimate(modelNode, modelNode, 0.8)
    slicer.util.saveNode(modelNode, plyFilePathSkull)

  # Delete temporary segment editor
    slicer.mrmlScene.RemoveNode(segmentEditorNode)
    del segmentEditorWidget

  slicer.mrmlScene.Clear(0)  # EMPTY scene

Maybe one could comment on the lines above.

THANKS!

Best,
Markus