Commit 65bab099998acaa3f81070ebdf95fbc293756604

Authored by Thiago Franco de Moraes
1 parent da24d361
Exists in import_mesh

Importing mesh file to invesalius

invesalius/data/surface.py
... ... @@ -150,6 +150,8 @@ class SurfaceManager():
150 150 Publisher.subscribe(self.OnRemove,"Remove surfaces")
151 151 Publisher.subscribe(self.UpdateSurfaceInterpolation, 'Update Surface Interpolation')
152 152  
  153 + Publisher.subscribe(self.OnImportSurfaceFile, 'Import surface file')
  154 +
153 155 def OnDuplicate(self, pubsub_evt):
154 156 selected_items = pubsub_evt.data
155 157 proj = prj.Project()
... ... @@ -241,6 +243,31 @@ class SurfaceManager():
241 243 new_index = self.CreateSurfaceFromPolydata(new_polydata)
242 244 Publisher.sendMessage('Show single surface', (new_index, True))
243 245  
  246 + def OnImportSurfaceFile(self, pubsub_evt):
  247 + """
  248 + Creates a new surface from a surface file (STL, PLY or VTP)
  249 + """
  250 + filename = pubsub_evt.data
  251 + self.CreateSurfaceFromFile(filename)
  252 +
  253 + def CreateSurfaceFromFile(self, filename):
  254 + if filename.lower().endswith('.stl'):
  255 + reader = vtk.vtkSTLReader()
  256 + elif filename.lower().endswith('.ply'):
  257 + reader = vtk.vtkPLYReader()
  258 + elif filename.lower().endswith('.vtp'):
  259 + reader = vtk.vtkXMLPolyDataReader()
  260 + else:
  261 + return
  262 +
  263 + reader.SetFileName(filename)
  264 + reader.Update()
  265 + polydata = reader.GetOutput()
  266 +
  267 + name = os.path.splitext(os.path.split(filename)[-1])[0]
  268 +
  269 + self.CreateSurfaceFromPolydata(polydata, name=name)
  270 +
244 271 def CreateSurfaceFromPolydata(self, polydata, overwrite=False,
245 272 name=None, colour=None,
246 273 transparency=None, volume=None, area=None):
... ...
invesalius/gui/data_notebook.py
... ... @@ -40,7 +40,7 @@ import invesalius.gui.widgets.listctrl as listmix
40 40 import invesalius.utils as ul
41 41  
42 42  
43   -BTN_NEW, BTN_REMOVE, BTN_DUPLICATE = [wx.NewId() for i in xrange(3)]
  43 +BTN_NEW, BTN_REMOVE, BTN_DUPLICATE, BTN_OPEN = [wx.NewId() for i in xrange(4)]
44 44  
45 45 TYPE = {const.LINEAR: _(u"Linear"),
46 46 const.ANGULAR: _(u"Angular"),
... ... @@ -594,6 +594,9 @@ class SurfaceButtonControlPanel(wx.Panel):
594 594 BMP_DUPLICATE = wx.Bitmap(os.path.join(const.ICON_DIR, "data_duplicate.png"),
595 595 wx.BITMAP_TYPE_PNG)
596 596  
  597 + BMP_OPEN = wx.Bitmap(os.path.join(const.ICON_DIR, "data_duplicate.png"),
  598 + wx.BITMAP_TYPE_PNG)
  599 +
597 600 # Plate buttons based on previous bitmaps
598 601 button_style = pbtn.PB_STYLE_SQUARE | pbtn.PB_STYLE_DEFAULT
599 602 button_new = pbtn.PlateButton(self, BTN_NEW, "",
... ... @@ -608,12 +611,17 @@ class SurfaceButtonControlPanel(wx.Panel):
608 611 BMP_DUPLICATE,
609 612 style=button_style,
610 613 size = wx.Size(24, 20))
  614 + button_open = pbtn.PlateButton(self, BTN_OPEN, "",
  615 + BMP_OPEN,
  616 + style=button_style,
  617 + size = wx.Size(24, 20))
611 618  
612 619 # Add all controls to gui
613 620 sizer = wx.BoxSizer(wx.HORIZONTAL)
614 621 sizer.Add(button_new, 0, wx.GROW|wx.EXPAND|wx.LEFT)
615 622 sizer.Add(button_remove, 0, wx.GROW|wx.EXPAND)
616 623 sizer.Add(button_duplicate, 0, wx.GROW|wx.EXPAND)
  624 + sizer.Add(button_open, 0, wx.GROW|wx.EXPAND)
617 625 self.SetSizer(sizer)
618 626 self.Fit()
619 627  
... ... @@ -628,6 +636,8 @@ class SurfaceButtonControlPanel(wx.Panel):
628 636 self.OnRemove()
629 637 elif id == BTN_DUPLICATE:
630 638 self.OnDuplicate()
  639 + elif id == BTN_OPEN:
  640 + self.OnOpenMesh()
631 641  
632 642 def OnNew(self):
633 643 sl = slice_.Slice()
... ... @@ -659,6 +669,11 @@ class SurfaceButtonControlPanel(wx.Panel):
659 669 else:
660 670 dlg.SurfaceSelectionRequiredForDuplication()
661 671  
  672 + def OnOpenMesh(self):
  673 + filename = dlg.ShowImportMeshFilesDialog()
  674 + if filename:
  675 + Publisher.sendMessage('Import surface file', filename)
  676 +
662 677  
663 678 class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
664 679  
... ...
invesalius/gui/dialogs.py
... ... @@ -223,6 +223,11 @@ WILDCARD_NIFTI = "NIfTI 1 (*.nii)|*.nii|" \
223 223 WILDCARD_PARREC = "PAR/REC (*.par)|*.par|" \
224 224 "All files (*.*)|*.*"
225 225  
  226 +WILDCARD_MESH_FILES = "STL (*.stl)|*.stl|" \
  227 + "PLY (*.ply)|*.ply|" \
  228 + "VTP (*.vtp)|*.vtp|" \
  229 + "All files (*.*)|*.*"
  230 +
226 231  
227 232 def ShowOpenProjectDialog():
228 233 # Default system path
... ... @@ -376,6 +381,40 @@ def ShowImportOtherFilesDialog(id_type):
376 381 return filename
377 382  
378 383  
  384 +def ShowImportMeshFilesDialog():
  385 + # Default system path
  386 + current_dir = os.path.abspath(".")
  387 + dlg = wx.FileDialog(None, message=_("Import surface file"),
  388 + defaultDir="",
  389 + defaultFile="", wildcard=WILDCARD_MESH_FILES,
  390 + style=wx.FD_OPEN | wx.FD_CHANGE_DIR)
  391 +
  392 + # stl filter is default
  393 + dlg.SetFilterIndex(0)
  394 +
  395 + # Show the dialog and retrieve the user response. If it is the OK response,
  396 + # process the data.
  397 + filename = None
  398 + try:
  399 + if dlg.ShowModal() == wx.ID_OK:
  400 + # GetPath returns in unicode, if a path has non-ascii characters a
  401 + # UnicodeEncodeError is raised. To avoid this, path is encoded in utf-8
  402 + if sys.platform == "win32":
  403 + filename = dlg.GetPath()
  404 + else:
  405 + filename = dlg.GetPath().encode('utf-8')
  406 +
  407 + except(wx._core.PyAssertionError): # TODO: error win64
  408 + if (dlg.GetPath()):
  409 + filename = dlg.GetPath()
  410 +
  411 + # Destroy the dialog. Don't do this until you are done with it!
  412 + # BAD things can happen otherwise!
  413 + dlg.Destroy()
  414 + os.chdir(current_dir)
  415 + return filename
  416 +
  417 +
379 418 def ShowSaveAsProjectDialog(default_filename=None):
380 419 current_dir = os.path.abspath(".")
381 420 dlg = wx.FileDialog(None,
... ...