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 | 59 | ps.Publisher().subscribe(self.Progress, "Update dicom load") |
| 60 | 60 | ps.Publisher().subscribe(self.OnLoadImportPanel, "End dicom load") |
| 61 | 61 | ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load') |
| 62 | + ps.Publisher().subscribe(self.OnSaveProject, 'Save Project') | |
| 62 | 63 | |
| 63 | 64 | |
| 64 | 65 | def OnCancelImport(self, pubsub_evt): |
| ... | ... | @@ -118,7 +119,9 @@ class Controller(): |
| 118 | 119 | |
| 119 | 120 | if len(patients_groups): |
| 120 | 121 | group = dcm.SelectLargerDicomGroup(patients_groups) |
| 122 | + print "Group", group.GetHandSortedList() | |
| 121 | 123 | imagedata, dicom = self.OpenDicomGroup(group, gui=False) |
| 124 | + print "imagedata", imagedata | |
| 122 | 125 | self.CreateDicomProject(imagedata, dicom) |
| 123 | 126 | # OPTION 2: ANALYZE? |
| 124 | 127 | else: |
| ... | ... | @@ -194,6 +197,7 @@ class Controller(): |
| 194 | 197 | |
| 195 | 198 | # Create imagedata |
| 196 | 199 | filelist = dicom_group.GetFilenameList() |
| 200 | + print "filelist", filelist | |
| 197 | 201 | zspacing = dicom_group.zspacing |
| 198 | 202 | imagedata = utils.CreateImageData(filelist, zspacing) |
| 199 | 203 | |
| ... | ... | @@ -247,3 +251,7 @@ class Controller(): |
| 247 | 251 | preset = prj.Project().raycasting_preset |
| 248 | 252 | preset_dir = os.path.join(const.USER_RAYCASTING_PRESETS_DIRECTORY, preset_name) |
| 249 | 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 | 19 | |
| 20 | 20 | import random |
| 21 | 21 | import constants as const |
| 22 | +import imagedata_utils as iu | |
| 23 | +import plistlib | |
| 24 | +import vtk | |
| 22 | 25 | |
| 23 | 26 | class Mask(): |
| 24 | 27 | general_index = -1 |
| 25 | 28 | def __init__(self): |
| 26 | 29 | Mask.general_index += 1 |
| 27 | 30 | self.index = Mask.general_index |
| 28 | - self.imagedata = None # vtkImageData | |
| 31 | + self.imagedata = '' # vtkImageData | |
| 29 | 32 | self.colour = random.choice(const.MASK_COLOUR) |
| 30 | 33 | self.opacity = const.MASK_OPACITY |
| 31 | 34 | self.threshold_range = const.THRESHOLD_RANGE |
| ... | ... | @@ -33,3 +36,19 @@ class Mask(): |
| 33 | 36 | self.edition_threshold_range = [const.THRESHOLD_OUTVALUE, const.THRESHOLD_INVALUE] |
| 34 | 37 | self.is_shown = 1 |
| 35 | 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 | 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais |
| 17 | 17 | # detalhes. |
| 18 | 18 | #-------------------------------------------------------------------------- |
| 19 | +import plistlib | |
| 19 | 20 | import vtk |
| 20 | 21 | import wx.lib.pubsub as ps |
| 21 | 22 | |
| ... | ... | @@ -34,13 +35,27 @@ class Surface(): |
| 34 | 35 | def __init__(self): |
| 35 | 36 | Surface.general_index += 1 |
| 36 | 37 | self.index = Surface.general_index |
| 37 | - self.polydata = None | |
| 38 | - self.colour = None | |
| 38 | + self.polydata = '' | |
| 39 | + self.colour = '' | |
| 39 | 40 | self.transparency = const.SURFACE_TRANSPARENCY |
| 40 | 41 | self.volume = 0 |
| 41 | 42 | self.is_shown = 1 |
| 42 | 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 | 59 | # TODO: will be initialized inside control as it is being done? |
| 45 | 60 | class SurfaceManager(): |
| 46 | 61 | """ | ... | ... |
invesalius/gui/frame.py
| ... | ... | @@ -329,7 +329,8 @@ class StatusBar(wx.StatusBar): |
| 329 | 329 | self.SetStatusText(label, 0) |
| 330 | 330 | if (int(value) >= 99): |
| 331 | 331 | self.SetStatusText("",0) |
| 332 | - wx.Yield() | |
| 332 | + if sys.platform != 'linux2': | |
| 333 | + wx.Yield() | |
| 333 | 334 | |
| 334 | 335 | |
| 335 | 336 | def UpdateStatusLabel(self, pubsub_evt): |
| ... | ... | @@ -434,8 +435,11 @@ class ProjectToolBar(wx.ToolBar): |
| 434 | 435 | self.Realize() |
| 435 | 436 | |
| 436 | 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 | 445 | class ObjectToolBar(wx.ToolBar): | ... | ... |
invesalius/presets.py
| ... | ... | @@ -16,6 +16,8 @@ |
| 16 | 16 | # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais |
| 17 | 17 | # detalhes. |
| 18 | 18 | #-------------------------------------------------------------------------- |
| 19 | +import os | |
| 20 | +import plistlib | |
| 19 | 21 | |
| 20 | 22 | import wx.lib.pubsub as ps |
| 21 | 23 | |
| ... | ... | @@ -39,7 +41,7 @@ class Presets(): |
| 39 | 41 | "Fat Tissue (Adult)":(-212,-72), |
| 40 | 42 | "Skin Tissue (Adult)":(-718,-177), |
| 41 | 43 | "Skin Tissue (Child)":(-766,-202), |
| 42 | - "Custom":(None, None) | |
| 44 | + "Custom":('', '') | |
| 43 | 45 | }) |
| 44 | 46 | |
| 45 | 47 | self.thresh_mri = TwoWaysDictionary({ |
| ... | ... | @@ -57,7 +59,7 @@ class Presets(): |
| 57 | 59 | "Fat Tissue (Adult)":(812,952), |
| 58 | 60 | "Skin Tissue (Adult)":(306,847), |
| 59 | 61 | "Skin Tissue (Child)":(258,822), |
| 60 | - "Custom":(None, None) | |
| 62 | + "Custom":('', '') | |
| 61 | 63 | }) |
| 62 | 64 | self.__bind_events() |
| 63 | 65 | |
| ... | ... | @@ -93,3 +95,16 @@ class Presets(): |
| 93 | 95 | |
| 94 | 96 | ps.Publisher().sendMessage('Update threshold limits', (thresh_min, |
| 95 | 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 | 21 | import plistlib |
| 22 | 22 | import wx |
| 23 | 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 | 29 | from utils import Singleton |
| 26 | 30 | from presets import Presets |
| ... | ... | @@ -124,42 +128,56 @@ class Project(object): |
| 124 | 128 | preset = plistlib.readPlist(path) |
| 125 | 129 | ps.Publisher.sendMessage('Set raycasting preset', preset) |
| 126 | 130 | |
| 127 | - def SavePlistProjectOld(self, filename): | |
| 131 | + def SavePlistProject(self, filename): | |
| 128 | 132 | project = {} |
| 129 | 133 | |
| 130 | 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 | 137 | else: |
| 134 | 138 | project[key] = self.__dict__[key] |
| 135 | 139 | |
| 136 | 140 | masks = {} |
| 137 | 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 | 143 | print index |
| 140 | 144 | |
| 141 | 145 | surfaces = {} |
| 142 | 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 | 148 | print index |
| 145 | - | |
| 149 | + | |
| 146 | 150 | project['surface_dict'] = surfaces |
| 147 | 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 | 162 | plistlib.Data) |
| 157 | 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 | 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 | 181 | print project |
| 164 | 182 | plistlib.writePlist(project, filename) |
| 165 | 183 | ... | ... |