Commit 4a31cb1d4a09e6ab52c280e4ce057e36def674bc
1 parent
36143132
Exists in
master
and in
68 other branches
ADD: A method to create the invesalius plist project
Showing
6 changed files
with
102 additions
and
23 deletions
Show diff stats
invesalius/control.py
| @@ -59,6 +59,7 @@ class Controller(): | @@ -59,6 +59,7 @@ class Controller(): | ||
| 59 | ps.Publisher().subscribe(self.Progress, "Update dicom load") | 59 | ps.Publisher().subscribe(self.Progress, "Update dicom load") |
| 60 | ps.Publisher().subscribe(self.OnLoadImportPanel, "End dicom load") | 60 | ps.Publisher().subscribe(self.OnLoadImportPanel, "End dicom load") |
| 61 | ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load') | 61 | ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load') |
| 62 | + ps.Publisher().subscribe(self.OnSaveProject, 'Save Project') | ||
| 62 | 63 | ||
| 63 | 64 | ||
| 64 | def OnCancelImport(self, pubsub_evt): | 65 | def OnCancelImport(self, pubsub_evt): |
| @@ -118,7 +119,9 @@ class Controller(): | @@ -118,7 +119,9 @@ class Controller(): | ||
| 118 | 119 | ||
| 119 | if len(patients_groups): | 120 | if len(patients_groups): |
| 120 | group = dcm.SelectLargerDicomGroup(patients_groups) | 121 | group = dcm.SelectLargerDicomGroup(patients_groups) |
| 122 | + print "Group", group.GetHandSortedList() | ||
| 121 | imagedata, dicom = self.OpenDicomGroup(group, gui=False) | 123 | imagedata, dicom = self.OpenDicomGroup(group, gui=False) |
| 124 | + print "imagedata", imagedata | ||
| 122 | self.CreateDicomProject(imagedata, dicom) | 125 | self.CreateDicomProject(imagedata, dicom) |
| 123 | # OPTION 2: ANALYZE? | 126 | # OPTION 2: ANALYZE? |
| 124 | else: | 127 | else: |
| @@ -194,6 +197,7 @@ class Controller(): | @@ -194,6 +197,7 @@ class Controller(): | ||
| 194 | 197 | ||
| 195 | # Create imagedata | 198 | # Create imagedata |
| 196 | filelist = dicom_group.GetFilenameList() | 199 | filelist = dicom_group.GetFilenameList() |
| 200 | + print "filelist", filelist | ||
| 197 | zspacing = dicom_group.zspacing | 201 | zspacing = dicom_group.zspacing |
| 198 | imagedata = utils.CreateImageData(filelist, zspacing) | 202 | imagedata = utils.CreateImageData(filelist, zspacing) |
| 199 | 203 | ||
| @@ -247,3 +251,7 @@ class Controller(): | @@ -247,3 +251,7 @@ class Controller(): | ||
| 247 | preset = prj.Project().raycasting_preset | 251 | preset = prj.Project().raycasting_preset |
| 248 | preset_dir = os.path.join(const.USER_RAYCASTING_PRESETS_DIRECTORY, preset_name) | 252 | preset_dir = os.path.join(const.USER_RAYCASTING_PRESETS_DIRECTORY, preset_name) |
| 249 | plistlib.writePlist(preset, preset_dir) | 253 | plistlib.writePlist(preset, preset_dir) |
| 254 | + | ||
| 255 | + def OnSaveProject(self, pubsub_evt): | ||
| 256 | + filename = prj.Project().name | ||
| 257 | + prj.Project().SavePlistProject(filename) |
invesalius/data/mask.py
| @@ -19,13 +19,16 @@ | @@ -19,13 +19,16 @@ | ||
| 19 | 19 | ||
| 20 | import random | 20 | import random |
| 21 | import constants as const | 21 | import constants as const |
| 22 | +import imagedata_utils as iu | ||
| 23 | +import plistlib | ||
| 24 | +import vtk | ||
| 22 | 25 | ||
| 23 | class Mask(): | 26 | class Mask(): |
| 24 | general_index = -1 | 27 | general_index = -1 |
| 25 | def __init__(self): | 28 | def __init__(self): |
| 26 | Mask.general_index += 1 | 29 | Mask.general_index += 1 |
| 27 | self.index = Mask.general_index | 30 | self.index = Mask.general_index |
| 28 | - self.imagedata = None # vtkImageData | 31 | + self.imagedata = '' # vtkImageData |
| 29 | self.colour = random.choice(const.MASK_COLOUR) | 32 | self.colour = random.choice(const.MASK_COLOUR) |
| 30 | self.opacity = const.MASK_OPACITY | 33 | self.opacity = const.MASK_OPACITY |
| 31 | self.threshold_range = const.THRESHOLD_RANGE | 34 | self.threshold_range = const.THRESHOLD_RANGE |
| @@ -33,3 +36,19 @@ class Mask(): | @@ -33,3 +36,19 @@ class Mask(): | ||
| 33 | self.edition_threshold_range = [const.THRESHOLD_OUTVALUE, const.THRESHOLD_INVALUE] | 36 | self.edition_threshold_range = [const.THRESHOLD_OUTVALUE, const.THRESHOLD_INVALUE] |
| 34 | self.is_shown = 1 | 37 | self.is_shown = 1 |
| 35 | self.edited_points = {} | 38 | self.edited_points = {} |
| 39 | + | ||
| 40 | + def SavePlist(self, filename): | ||
| 41 | + mask = {} | ||
| 42 | + filename = '%s$%s$%d' % (filename, 'mask', self.index) | ||
| 43 | + d = self.__dict__ | ||
| 44 | + for key in d: | ||
| 45 | + if isinstance(d[key], vtk.vtkImageData): | ||
| 46 | + img_name = '%s_%s.vti' % (filename, key) | ||
| 47 | + iu.Export(d[key], img_name, bin=True) | ||
| 48 | + mask[key] = {'$imagedata': img_name} | ||
| 49 | + else: | ||
| 50 | + mask[key] = d[key] | ||
| 51 | + | ||
| 52 | + print mask | ||
| 53 | + plistlib.writePlist(mask, filename + '.plist') | ||
| 54 | + return filename |
invesalius/data/surface.py
| @@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
| 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais |
| 17 | # detalhes. | 17 | # detalhes. |
| 18 | #-------------------------------------------------------------------------- | 18 | #-------------------------------------------------------------------------- |
| 19 | +import plistlib | ||
| 19 | import vtk | 20 | import vtk |
| 20 | import wx.lib.pubsub as ps | 21 | import wx.lib.pubsub as ps |
| 21 | 22 | ||
| @@ -34,13 +35,27 @@ class Surface(): | @@ -34,13 +35,27 @@ class Surface(): | ||
| 34 | def __init__(self): | 35 | def __init__(self): |
| 35 | Surface.general_index += 1 | 36 | Surface.general_index += 1 |
| 36 | self.index = Surface.general_index | 37 | self.index = Surface.general_index |
| 37 | - self.polydata = None | ||
| 38 | - self.colour = None | 38 | + self.polydata = '' |
| 39 | + self.colour = '' | ||
| 39 | self.transparency = const.SURFACE_TRANSPARENCY | 40 | self.transparency = const.SURFACE_TRANSPARENCY |
| 40 | self.volume = 0 | 41 | self.volume = 0 |
| 41 | self.is_shown = 1 | 42 | self.is_shown = 1 |
| 42 | self.name = const.SURFACE_NAME_PATTERN %(Surface.general_index+1) | 43 | self.name = const.SURFACE_NAME_PATTERN %(Surface.general_index+1) |
| 43 | 44 | ||
| 45 | + def SavePlist(self, filename): | ||
| 46 | + surface = {} | ||
| 47 | + filename = '%s$%s$%d' % (filename, 'surface', self.index) | ||
| 48 | + d = self.__dict__ | ||
| 49 | + for key in d: | ||
| 50 | + if isinstance(d[key], vtk.vtkPolyData): | ||
| 51 | + img_name = '%s_%s.vtp' % (filename, key) | ||
| 52 | + pu.Export(d[key], img_name, bin=True) | ||
| 53 | + surface[key] = {'$polydata': img_name} | ||
| 54 | + else: | ||
| 55 | + surface[key] = d[key] | ||
| 56 | + plistlib.writePlist(surface, filename + '.plist') | ||
| 57 | + return filename | ||
| 58 | + | ||
| 44 | # TODO: will be initialized inside control as it is being done? | 59 | # TODO: will be initialized inside control as it is being done? |
| 45 | class SurfaceManager(): | 60 | class SurfaceManager(): |
| 46 | """ | 61 | """ |
invesalius/gui/frame.py
| @@ -329,7 +329,8 @@ class StatusBar(wx.StatusBar): | @@ -329,7 +329,8 @@ class StatusBar(wx.StatusBar): | ||
| 329 | self.SetStatusText(label, 0) | 329 | self.SetStatusText(label, 0) |
| 330 | if (int(value) >= 99): | 330 | if (int(value) >= 99): |
| 331 | self.SetStatusText("",0) | 331 | self.SetStatusText("",0) |
| 332 | - wx.Yield() | 332 | + if sys.platform != 'linux2': |
| 333 | + wx.Yield() | ||
| 333 | 334 | ||
| 334 | 335 | ||
| 335 | def UpdateStatusLabel(self, pubsub_evt): | 336 | def UpdateStatusLabel(self, pubsub_evt): |
| @@ -434,8 +435,11 @@ class ProjectToolBar(wx.ToolBar): | @@ -434,8 +435,11 @@ class ProjectToolBar(wx.ToolBar): | ||
| 434 | self.Realize() | 435 | self.Realize() |
| 435 | 436 | ||
| 436 | def __bind_events(self): | 437 | def __bind_events(self): |
| 437 | - pass | 438 | + self.Bind(wx.EVT_TOOL, self.OnToolSave, id=const.ID_FILE_SAVE) |
| 438 | 439 | ||
| 440 | + def OnToolSave(self, evt): | ||
| 441 | + print "Saving ..." | ||
| 442 | + ps.Publisher().sendMessage('Save Project') | ||
| 439 | # ------------------------------------------------------------------ | 443 | # ------------------------------------------------------------------ |
| 440 | 444 | ||
| 441 | class ObjectToolBar(wx.ToolBar): | 445 | class ObjectToolBar(wx.ToolBar): |
invesalius/presets.py
| @@ -16,6 +16,8 @@ | @@ -16,6 +16,8 @@ | ||
| 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais |
| 17 | # detalhes. | 17 | # detalhes. |
| 18 | #-------------------------------------------------------------------------- | 18 | #-------------------------------------------------------------------------- |
| 19 | +import os | ||
| 20 | +import plistlib | ||
| 19 | 21 | ||
| 20 | import wx.lib.pubsub as ps | 22 | import wx.lib.pubsub as ps |
| 21 | 23 | ||
| @@ -39,7 +41,7 @@ class Presets(): | @@ -39,7 +41,7 @@ class Presets(): | ||
| 39 | "Fat Tissue (Adult)":(-212,-72), | 41 | "Fat Tissue (Adult)":(-212,-72), |
| 40 | "Skin Tissue (Adult)":(-718,-177), | 42 | "Skin Tissue (Adult)":(-718,-177), |
| 41 | "Skin Tissue (Child)":(-766,-202), | 43 | "Skin Tissue (Child)":(-766,-202), |
| 42 | - "Custom":(None, None) | 44 | + "Custom":('', '') |
| 43 | }) | 45 | }) |
| 44 | 46 | ||
| 45 | self.thresh_mri = TwoWaysDictionary({ | 47 | self.thresh_mri = TwoWaysDictionary({ |
| @@ -57,7 +59,7 @@ class Presets(): | @@ -57,7 +59,7 @@ class Presets(): | ||
| 57 | "Fat Tissue (Adult)":(812,952), | 59 | "Fat Tissue (Adult)":(812,952), |
| 58 | "Skin Tissue (Adult)":(306,847), | 60 | "Skin Tissue (Adult)":(306,847), |
| 59 | "Skin Tissue (Child)":(258,822), | 61 | "Skin Tissue (Child)":(258,822), |
| 60 | - "Custom":(None, None) | 62 | + "Custom":('', '') |
| 61 | }) | 63 | }) |
| 62 | self.__bind_events() | 64 | self.__bind_events() |
| 63 | 65 | ||
| @@ -93,3 +95,16 @@ class Presets(): | @@ -93,3 +95,16 @@ class Presets(): | ||
| 93 | 95 | ||
| 94 | ps.Publisher().sendMessage('Update threshold limits', (thresh_min, | 96 | ps.Publisher().sendMessage('Update threshold limits', (thresh_min, |
| 95 | thresh_max)) | 97 | thresh_max)) |
| 98 | + | ||
| 99 | + def SavePlist(self, filename): | ||
| 100 | + filename = "%s$%s" % (filename, 'presets.plist') | ||
| 101 | + preset = {} | ||
| 102 | + preset['thresh_mri'] = self.thresh_mri.copy() | ||
| 103 | + preset['thresh_ct'] = self.thresh_ct.copy() | ||
| 104 | + plistlib.writePlist(preset, filename) | ||
| 105 | + return filename | ||
| 106 | + | ||
| 107 | + def OpenPlist(self, filename): | ||
| 108 | + preset = plistlib.readPlist(filename) | ||
| 109 | + self.thresh_mri = TwoWaysDictionary(preset['thresh_mri']) | ||
| 110 | + self.thresh_ct = TwoWaysDictionary(preset['thresh_ct']) |
invesalius/project.py
| @@ -21,6 +21,10 @@ import os | @@ -21,6 +21,10 @@ import os | ||
| 21 | import plistlib | 21 | import plistlib |
| 22 | import wx | 22 | import wx |
| 23 | import wx.lib.pubsub as ps | 23 | import wx.lib.pubsub as ps |
| 24 | +import vtk | ||
| 25 | + | ||
| 26 | +import data.imagedata_utils as iu | ||
| 27 | +import data.polydata_utils as pu | ||
| 24 | 28 | ||
| 25 | from utils import Singleton | 29 | from utils import Singleton |
| 26 | from presets import Presets | 30 | from presets import Presets |
| @@ -124,42 +128,56 @@ class Project(object): | @@ -124,42 +128,56 @@ class Project(object): | ||
| 124 | preset = plistlib.readPlist(path) | 128 | preset = plistlib.readPlist(path) |
| 125 | ps.Publisher.sendMessage('Set raycasting preset', preset) | 129 | ps.Publisher.sendMessage('Set raycasting preset', preset) |
| 126 | 130 | ||
| 127 | - def SavePlistProjectOld(self, filename): | 131 | + def SavePlistProject(self, filename): |
| 128 | project = {} | 132 | project = {} |
| 129 | 133 | ||
| 130 | for key in self.__dict__: | 134 | for key in self.__dict__: |
| 131 | - if getattr(self.__dict__[key], 'SavePlist'): | ||
| 132 | - project[key] = {'path': self.__dict__[key].SavePlist('.')} | 135 | + if getattr(self.__dict__[key], 'SavePlist', None): |
| 136 | + project[key] = {'path': self.__dict__[key].SavePlist(filename)} | ||
| 133 | else: | 137 | else: |
| 134 | project[key] = self.__dict__[key] | 138 | project[key] = self.__dict__[key] |
| 135 | 139 | ||
| 136 | masks = {} | 140 | masks = {} |
| 137 | for index in self.mask_dict: | 141 | for index in self.mask_dict: |
| 138 | - masks[str(index)] = "self.mask_dict[index]" | 142 | + masks[str(index)] = self.mask_dict[index].SavePlist(filename) |
| 139 | print index | 143 | print index |
| 140 | 144 | ||
| 141 | surfaces = {} | 145 | surfaces = {} |
| 142 | for index in self.surface_dict: | 146 | for index in self.surface_dict: |
| 143 | - surfaces[str(index)] = "self.surface_dict[index]" | 147 | + surfaces[str(index)] = self.surface_dict[index].SavePlist(filename) |
| 144 | print index | 148 | print index |
| 145 | - | 149 | + |
| 146 | project['surface_dict'] = surfaces | 150 | project['surface_dict'] = surfaces |
| 147 | project['mask_dict'] = masks | 151 | project['mask_dict'] = masks |
| 148 | - project['imagedata'] = 'imagedata' | 152 | + img_file = '%s_%s.vti' % (filename, 'imagedata') |
| 153 | + iu.Export(self.imagedata, img_file, bin=True) | ||
| 154 | + project['imagedata'] = img_file | ||
| 149 | 155 | ||
| 150 | - plistlib.writePlist(project, filename) | 156 | + plistlib.writePlist(project, filename + '.plist') |
| 151 | 157 | ||
| 152 | - def SavePlistProject(self, filename, object=None): | ||
| 153 | - if object is None: | ||
| 154 | - object = self | ||
| 155 | - supported_types = (str, int, float, bool, tuple, list, dict, | 158 | + def SavePlistProjectOld(self, filename, dict_object=None): |
| 159 | + if dict_object is None: | ||
| 160 | + dict_object = self.__dict__ | ||
| 161 | + supported_types = (str, int, float, bool, tuple, list, | ||
| 156 | plistlib.Data) | 162 | plistlib.Data) |
| 157 | project = {} | 163 | project = {} |
| 158 | - for key in object.__dict__: | ||
| 159 | - prop = object.__dict__[key] | 164 | + for key in dict_object: |
| 165 | + prop = dict_object[key] | ||
| 160 | if isinstance(prop, supported_types): | 166 | if isinstance(prop, supported_types): |
| 161 | - project[key] = prop | ||
| 162 | - print key | 167 | + project[str(key)] = prop |
| 168 | + elif isinstance(prop, dict): | ||
| 169 | + project[str(key)] = self.SavePlistProject('%s$%s' % (filename, | ||
| 170 | + key), prop) | ||
| 171 | + elif isinstance(prop, vtk.vtkImageData): | ||
| 172 | + img_name = '%s_%s' % (key, filename) | ||
| 173 | + img_file = iu.Export(prop, img_name, bin=True) | ||
| 174 | + project[str(key)] = {'imagedatafile': img_file} | ||
| 175 | + elif isinstance(prop, vtk.vtkPolyData): | ||
| 176 | + pd_name = '%s_%s' % (key, filename) | ||
| 177 | + pd_file = pu.Export(prop, pd_name, bin=True) | ||
| 178 | + project[str(key)] = {'polydatafile': pd_file} | ||
| 179 | + else: | ||
| 180 | + project[str(key)] = {'plistfile': self.SavePlistProject("%s$%s" % (filename, key), prop.__dict__)} | ||
| 163 | print project | 181 | print project |
| 164 | plistlib.writePlist(project, filename) | 182 | plistlib.writePlist(project, filename) |
| 165 | 183 |