# Load segmentation and export surface mesh as model .ply

**URL:** <https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646>\
**Category:** Support\
**Created:** [April 20, 2018, 12:57pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646 "2018-04-20T12:57:47Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![ladybug](https://avatars.discourse-cdn.com/v4/letter/l/46a35a/32.png) [@ladybug](https://discourse.slicer.org/u/ladybug)\
**Post date:** [April 20, 2018, 12:57pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/1 "2018-04-20T12:57:48Z")

</div>

Hello,  
I’m new to creating modules and my programming skills are rather basic, so I encountered problems in loading segmentation from subdirectories, and in exporting and saving the mesh models.  
The first issue looks like following: I want to load segmentations named ‘\_repair.seg.nrrd’ from multiple subdirectories. What I got so far is:

```auto
  def onExportButtonClicked(self):
    dir_path = qt.QFileDialog.getExistingDirectory(None, 'Open folder', '/home/', qt.QFileDialog.ShowDirsOnly)
    dir_path = dir_path.replace("\\", "/")
    for filename in os.listdir(dir_path):
      self.exportMesh(dir_path, filename)
    print("Finished.")
    
  def exportMesh(self, dir_path, filename):
    whichOP= "preop"
	# Load segmentation (repair .seg.nrrd)
    file_complete = dir_path + "/" + filename + "/" + whichOP + "/CT/" + filename + "_" + whichOP + "_repair.seg.nrrd"
    print("Loading {}".format(file_complete))
    slicer.app.processEvents()
    MasterModelNode = slicer.util.loadNodeFromFile(file_complete, "_repair.seg.nrrd", {}, returnNode=True)
    modelNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLModelHierarchyNode')
    slicer.modules.segmentations.logic().ExportAllSegmentsToModelHierarchy(MasterModelNode, modelNode) 

```

I can’t get further, because I get an error:

```auto
TypeError: ExportAllSegmentsToModelHierarchy argument 1: method requires a VTK object. 

```

I would be really grateful for your help, as I lack knowledge to fix this (probably really trivial) problem. I have a next piece of code that looks as below. However, I don’t even know if it works, because of the previous error I mentioned.

```auto
    # Make sure surface mesh cells are consistently oriented
    surfaceMesh = MasterModelNode.GetClosedSurfaceRepresentation(segmentID)
    normals = vtk.vtkPolyDataNormals()
    normals.AutoOrientNormalsOn()
    normals.ConsistencyOn()
    normals.SetInputData(surfaceMesh)
    normals.Update()
    surfaceMesh = normals.GetOutput()
    # Save as PLY file
    writer = vtk.vtkSTLWriter()
    writer.SetInputData(surfaceMesh)
    #### name should be: name of segmentation .ply
    file_new = dir_path + "/" + filename + "/" + whichOP + "/CT/" + filename + segmentName + ".ply"
    writer.SetFileName(file_new) # set file name
    writer.Update()
    # Clean up
    segmentEditorWidget = None
    slicer.mrmlScene.RemoveNode(file_complete)
    slicer.mrmlScene.RemoveNode(segmentEditorNode)

```

Best regards!

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 21, 2018, 4:20pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/2 "2018-04-21T16:20:09Z")

</div>

> [@ladybug](#):
>
> MasterModelNode = slicer.util.loadNodeFromFile(file\_complete, “\_repair.seg.nrrd”, {}, returnNode=True)

Probably this line is not working as you expect leading to the error message about needing a vtk object. Try printing out the result to debug.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [April 21, 2018, 7:20pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/3 "2018-04-21T19:20:07Z")

</div>

Yes, that line is incorrect. If `returnNode=True` is specified then `slicer.util.loadNodeFromFile` returns `(success, MasterModelNode)` pair and not just `MasterModelNode`.

---

<div class="post-metadata">

**Author:** ![ladybug](https://avatars.discourse-cdn.com/v4/letter/l/46a35a/32.png) [@ladybug](https://discourse.slicer.org/u/ladybug)\
**Post date:** [May 14, 2018, 3:03pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/4 "2018-05-14T15:03:55Z")

</div>

Hello again,  
Thank you so much for your reply. So after debug the code seems to work until it reaches:

slicer.modules.segmentations.logic().ExportAllSegmentsToModelHierarchy(MasterModelNode, modelNode)

Can there be a problem with my file type, namely what I wrote as: “\_repair.seg.nrrd” in

MasterModelNode = slicer.util.loadNodeFromFile(file\_complete, “\_repair.seg.nrrd”, {}, returnNode=True) ?

I tried also “.seg.nrrd” and separately “.seg” or “.nrrd” but it makes no difference at all. It still shows the same error.

Best

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 14, 2018, 8:54pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/5 "2018-05-14T20:54:16Z")

</div>

You can use `slicer.util.loadSegmentation` for loading a segmentation from file.

> <https://github.com/Slicer/Slicer/blob/a99595c98da13f87d16705ea5370edb3521179e2/Base/Python/slicer/util.py#L352-L354>

Note that in recent nightly versions of Slicer, you can export segmentation directly to stl or obj files. See [Save segmentation directly to STL or OBJ files](https://discourse.slicer.org/t/save-segmentation-directly-to-stl-or-obj-files/2428) post for details and [API documentation](http://apidocs.slicer.org/master/classvtkSlicerSegmentationsModuleLogic.html#a9578121589a3b5e20a05aa8dce33c642) for description how it can be used from script.

---

<div class="post-metadata">

**Author:** ![ladybug](https://avatars.discourse-cdn.com/v4/letter/l/46a35a/32.png) [@ladybug](https://discourse.slicer.org/u/ladybug)\
**Post date:** [May 15, 2018, 2:26pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/6 "2018-05-15T14:26:02Z")

</div>

So I used slicer.util.loadSegmentation(filename, returnNode=False) as you suggested but the error remains - ‘method requires a VTK object’.  
Also I need to export the mesh surface as .ply file.  
Is it possible that I miss a line about a node, like getNode(‘Segmentation’)?  
Best!

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 16, 2018, 8:11pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/7 "2018-05-16T20:11:15Z")

</div>

> [@ladybug](#):
>
> So I used slicer.util.loadSegmentation(filename, returnNode=False) as you suggested but the error remains - ‘method requires a VTK object’.

What error, where? What command do you type exactly?

> [@ladybug](#):
>
> Also I need to export the mesh surface as .ply file.

If you need .ply export you cannot use the direct export feature but you need to use VTK writers. You can add a feature request to the [Slicer issue tracker](https://issues.slicer.org) to implement .ply format export.

---

<div class="post-metadata">

**Author:** ![ladybug](https://avatars.discourse-cdn.com/v4/letter/l/46a35a/32.png) [@ladybug](https://discourse.slicer.org/u/ladybug)\
**Post date:** [May 17, 2018, 9:31am UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/8 "2018-05-17T09:31:14Z")

</div>

This is my piece of code until it works:

```
  def onExportButtonClicked(self):
    qt.QFileDialog.ShowDirsOnly)
    filename = qt.QFileDialog.getOpenFileName(self.parent, 'Open file', 'D:\\SlicerTest\\THA\\001\\preop\\CT', "All Files (*.nrrd)")
    print filename
    self.exportMesh(filename)
    print("Finished.")
    
  def exportMesh(self, filename):
    # Load segmentation (repair.seg.nrrd)
    slicer.app.processEvents()
    MasterModelNode = slicer.util.loadSegmentation(filename, returnNode=False)
    modelNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLModelHierarchyNode')
    slicer.modules.segmentations.logic().ExportAllSegmentsToModelHierarchy(MasterModelNode, modelNode)  

```

The error I get in Python Interactor in Slicer is as follows:

 ![error%20slicer](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/3/4/3459359a8eda80f4f1cce12b5133716468c36f31.jpeg)

Best

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [May 17, 2018, 12:12pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/9 "2018-05-17T12:12:18Z")

</div>

In cases like this you need to confirm line-by-line that you are getting the data you expect from the API, for example by adding print statements or executing the calls in the python console.

Here, you have the returnNode=False argument to the loadSegmentation call, but then try to use the MasterModelNode as a node, when it’s a boolean.

HTH,  
Steve

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 17, 2018, 1:46pm UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/10 "2018-05-17T13:46:18Z")

</div>

This code snippet should do what you need:

```
def onExportButtonClicked(self):
  filename = qt.QFileDialog.getOpenFileName(self.parent, 'Open file', 'D:\\SlicerTest\\THA\\001\\preop\\CT', "All Files (*.nrrd)")
  self.exportMesh(filename)

def exportMesh(self, filename):
  [success, segmentationNode] = slicer.util.loadSegmentation(filename, returnNode=True)
  segmentationNode.CreateClosedSurfaceRepresentation()
  segmentation=segmentationNode.GetSegmentation()
  for segmentIndex in range(segmentation.GetNumberOfSegments()):
    segmentID = segmentation.GetNthSegmentID(segmentIndex)
    polydata = segmentationNode.GetClosedSurfaceRepresentation(segmentID)
    writer = vtk.vtkPLYWriter()
    writer.SetInputData(polydata)
    writer.SetFileName(os.path.split(filename)[0]+"/"+segmentationNode.GetName()+"_"+segmentID)
    writer.Update()
```

---

<div class="post-metadata">

**Author:** ![ladybug](https://avatars.discourse-cdn.com/v4/letter/l/46a35a/32.png) [@ladybug](https://discourse.slicer.org/u/ladybug)\
**Post date:** [May 18, 2018, 11:36am UTC](https://discourse.slicer.org/t/load-segmentation-and-export-surface-mesh-as-model-ply/2646/11 "2018-05-18T11:36:08Z")

</div>

Thank you so much for your help @lassoan ! Of course everything works perfectly now.  
Best regards
