Commit eb6cd6beada052bc779de1b8132d68e73fe6fb51

Authored by tatiana
1 parent 8e4857dd

ENH: (underdevel) Open inv3 project in GUI - currently there is a problem on loa…

…ding masks' imagedatas
invesalius/control.py
@@ -138,7 +138,11 @@ class Controller(): @@ -138,7 +138,11 @@ class Controller():
138 def LoadProject(self): 138 def LoadProject(self):
139 proj = prj.Project() 139 proj = prj.Project()
140 ps.Publisher().sendMessage('Set project name', proj.name) 140 ps.Publisher().sendMessage('Set project name', proj.name)
141 - ps.Publisher().sendMessage('Load slice to viewer', (proj.imagedata)) 141 + ps.Publisher().sendMessage('Load slice to viewer',
  142 + (proj.imagedata,
  143 + proj.mask_dict))
  144 + ps.Publisher().sendMessage('Load surface dict',
  145 + proj.surface_dict)
142 self.LoadImagedataInfo() # TODO: where do we insert this <<<? 146 self.LoadImagedataInfo() # TODO: where do we insert this <<<?
143 ps.Publisher().sendMessage('Bright and contrast adjustment image',\ 147 ps.Publisher().sendMessage('Bright and contrast adjustment image',\
144 (proj.window, proj.level)) 148 (proj.window, proj.level))
@@ -172,8 +176,10 @@ class Controller(): @@ -172,8 +176,10 @@ class Controller():
172 176
173 proj = prj.Project() 177 proj = prj.Project()
174 proj.name = dicom.patient.name 178 proj.name = dicom.patient.name
  179 + proj.modality = dicom.acquisition.modality
175 proj.SetAcquisitionModality(dicom.acquisition.modality) 180 proj.SetAcquisitionModality(dicom.acquisition.modality)
176 proj.imagedata = imagedata 181 proj.imagedata = imagedata
  182 + #proj.dicom = dicom
177 proj.original_orientation =\ 183 proj.original_orientation =\
178 name_to_const[dicom.image.orientation_label] 184 name_to_const[dicom.image.orientation_label]
179 proj.window = float(dicom.image.window) 185 proj.window = float(dicom.image.window)
@@ -226,7 +232,9 @@ class Controller(): @@ -226,7 +232,9 @@ class Controller():
226 232
227 # Set default value into slices' default mask 233 # Set default value into slices' default mask
228 key= thresh_modes[const.THRESHOLD_PRESETS_INDEX] 234 key= thresh_modes[const.THRESHOLD_PRESETS_INDEX]
229 - (min_thresh, max_thresh) = proj.threshold_modes.get_value(key) 235 + #value = proj.threshold_modes.get_value(key)
  236 + value = proj.threshold_modes[key]
  237 + (min_thresh, max_thresh) = value
230 238
231 def LoadRaycastingPreset(self, pubsub_evt): 239 def LoadRaycastingPreset(self, pubsub_evt):
232 label = pubsub_evt.data 240 label = pubsub_evt.data
@@ -260,4 +268,14 @@ class Controller(): @@ -260,4 +268,14 @@ class Controller():
260 268
261 def OnOpenProject(self, pubsub_evt): 269 def OnOpenProject(self, pubsub_evt):
262 filename = pubsub_evt.data 270 filename = pubsub_evt.data
263 - prj.Project().OpenPlistProject(filename) 271 +
  272 + proj = prj.Project()
  273 + proj.OpenPlistProject(filename)
  274 + proj.SetAcquisitionModality(proj.modality)
  275 +
  276 + const.THRESHOLD_OUTVALUE = proj.threshold_range[0]
  277 + const.THRESHOLD_INVALUE = proj.threshold_range[1]
  278 + const.WINDOW_LEVEL['Default'] = (proj.window, proj.level)
  279 + const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level)
  280 +
  281 + self.LoadProject()
invesalius/data/imagedata_utils.py
@@ -169,9 +169,15 @@ def Import(filename): @@ -169,9 +169,15 @@ def Import(filename):
169 reader = vtk.vtkXMLImageDataReader() 169 reader = vtk.vtkXMLImageDataReader()
170 reader.SetFileName(filename) 170 reader.SetFileName(filename)
171 # TODO: Check if the code bellow is necessary 171 # TODO: Check if the code bellow is necessary
172 - #reader.WholeSlicesOn() 172 + reader.WholeSlicesOn()
173 reader.Update() 173 reader.Update()
174 - return reader.GetOutput() 174 +
  175 + cast = vtk.vtkImageCast()
  176 + cast.SetInput(reader.GetOutput())
  177 + cast.SetOutputScalarType(11)
  178 + cast.Update()
  179 +
  180 + return cast.GetOutput()
175 181
176 def View(imagedata): 182 def View(imagedata):
177 viewer = vtk.vtkImageViewer() 183 viewer = vtk.vtkImageViewer()
invesalius/data/slice_.py
@@ -325,12 +325,19 @@ class Slice(object): @@ -325,12 +325,19 @@ class Slice(object):
325 325
326 326
327 327
328 - def SetInput(self, imagedata): 328 + def SetInput(self, imagedata, mask_dict):
329 self.imagedata = imagedata 329 self.imagedata = imagedata
330 self.extent = imagedata.GetExtent() 330 self.extent = imagedata.GetExtent()
331 331
332 imagedata_bg = self.__create_background(imagedata) 332 imagedata_bg = self.__create_background(imagedata)
333 - imagedata_mask = self.__create_mask(imagedata) 333 +
  334 + if not mask_dict:
  335 + imagedata_mask = self.__build_mask(imagedata, create=True)
  336 + else:
  337 + self.__load_masks(mask_dict)
  338 + imagedata_mask = self.current_mask.imagedata
  339 +
  340 +
334 341
335 mask_opacity = self.current_mask.opacity 342 mask_opacity = self.current_mask.opacity
336 343
@@ -343,7 +350,17 @@ class Slice(object): @@ -343,7 +350,17 @@ class Slice(object):
343 else: 350 else:
344 blend_filter.SetOpacity(1, 0) 351 blend_filter.SetOpacity(1, 0)
345 blend_filter.SetInput(0, imagedata_bg) 352 blend_filter.SetInput(0, imagedata_bg)
  353 +
  354 + #cast = vtk.vtkImageCast()
  355 + ##cast.SetInput(imagedata_mask)
  356 + #cast.SetOutputScalarType(3)
  357 + #cast.Update()
  358 + print 1
  359 + #blend_filter.SetInput(1, cast.GetOutput())
346 blend_filter.SetInput(1, imagedata_mask) 360 blend_filter.SetInput(1, imagedata_mask)
  361 + print "******", imagedata_mask.GetScalarType() #11
  362 + print "******", imagedata_bg.GetScalarType() #11
  363 + print 2
347 blend_filter.SetBlendModeToNormal() 364 blend_filter.SetBlendModeToNormal()
348 blend_filter.GetOutput().ReleaseDataFlagOn() 365 blend_filter.GetOutput().ReleaseDataFlagOn()
349 self.blend_filter = blend_filter 366 self.blend_filter = blend_filter
@@ -508,10 +525,31 @@ class Slice(object): @@ -508,10 +525,31 @@ class Slice(object):
508 ps.Publisher().sendMessage('Update slice viewer') 525 ps.Publisher().sendMessage('Update slice viewer')
509 526
510 527
  528 + def __load_masks(self, mask_dict):
  529 + keys = mask_dict.keys()
  530 + keys.sort()
  531 + for key in keys:
  532 + mask = mask_dict[key]
  533 +
  534 + # update gui related to mask
  535 + ps.Publisher().sendMessage('Add mask',
  536 + (mask.index,
  537 + mask.name,
  538 + mask.threshold_range,
  539 + mask.colour))
  540 +
  541 + self.current_mask = mask
  542 + self.__build_mask(mask.imagedata, False)
  543 +
  544 + ps.Publisher().sendMessage('Change mask selected', mask.index)
  545 + ps.Publisher().sendMessage('Update slice viewer')
  546 +
  547 +
511 548
512 - def __create_mask(self, imagedata): 549 + def __build_mask(self, imagedata, create=True):
513 # create new mask instance and insert it into project 550 # create new mask instance and insert it into project
514 - self.CreateMask(imagedata=imagedata) 551 + if create:
  552 + self.CreateMask(imagedata=imagedata)
515 current_mask = self.current_mask 553 current_mask = self.current_mask
516 554
517 # properties to be inserted into pipeline 555 # properties to be inserted into pipeline
invesalius/data/surface.py
@@ -100,6 +100,44 @@ class SurfaceManager(): @@ -100,6 +100,44 @@ class SurfaceManager():
100 ps.Publisher().subscribe(self.OnChangeSurfaceName, 'Change surface name') 100 ps.Publisher().subscribe(self.OnChangeSurfaceName, 'Change surface name')
101 ps.Publisher().subscribe(self.OnShowSurface, 'Show surface') 101 ps.Publisher().subscribe(self.OnShowSurface, 'Show surface')
102 ps.Publisher().subscribe(self.OnExportSurface,'Export surface to file') 102 ps.Publisher().subscribe(self.OnExportSurface,'Export surface to file')
  103 + ps.Publisher().subscribe(self.OnLoadSurfaceDict, 'Load surface dict')
  104 +
  105 + def OnLoadSurfaceDict(self, pubsub_evt):
  106 + surface_dict = pubsub_evt.data
  107 +
  108 + for key in surface_dict:
  109 + surface = surface_dict[key]
  110 + # Map polygonal data (vtkPolyData) to graphics primitives.
  111 + mapper = vtk.vtkPolyDataMapper()
  112 + mapper.SetInput(surface.polydata)
  113 + mapper.ScalarVisibilityOff()
  114 +
  115 + # Represent an object (geometry & properties) in the rendered scene
  116 + actor = vtk.vtkActor()
  117 + actor.SetMapper(mapper)
  118 +
  119 + # Set actor colour and transparency
  120 + actor.GetProperty().SetColor(surface.colour)
  121 + actor.GetProperty().SetOpacity(1-surface.transparency)
  122 +
  123 + self.actors_dict[surface.index] = actor
  124 +
  125 +
  126 + # Send actor by pubsub to viewer's render
  127 + ps.Publisher().sendMessage('Load surface actor into viewer', (actor))
  128 +
  129 + ps.Publisher().sendMessage('Update status text in GUI',
  130 + "Surface created.")
  131 +
  132 + # The following lines have to be here, otherwise all volumes disappear
  133 +
  134 + ps.Publisher().sendMessage('Update surface info in GUI',
  135 + (surface.index, surface.name,
  136 + surface.colour, surface.volume,
  137 + surface.transparency))
  138 +
  139 +
  140 +
103 141
104 def AddNewActor(self, pubsub_evt): 142 def AddNewActor(self, pubsub_evt):
105 """ 143 """
invesalius/data/viewer_slice.py
@@ -746,8 +746,8 @@ class Viewer(wx.Panel): @@ -746,8 +746,8 @@ class Viewer(wx.Panel):
746 self.interactor.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu) 746 self.interactor.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
747 747
748 def LoadImagedata(self, pubsub_evt): 748 def LoadImagedata(self, pubsub_evt):
749 - imagedata = pubsub_evt.data  
750 - self.SetInput(imagedata) 749 + imagedata, mask_dict = pubsub_evt.data
  750 + self.SetInput(imagedata, mask_dict)
751 751
752 def LoadRenderers(self, image): 752 def LoadRenderers(self, image):
753 number_renderers = self.layout[0] * self.layout[1] 753 number_renderers = self.layout[0] * self.layout[1]
@@ -788,7 +788,7 @@ class Viewer(wx.Panel): @@ -788,7 +788,7 @@ class Viewer(wx.Panel):
788 self.cursor_ = cursor 788 self.cursor_ = cursor
789 return cursor 789 return cursor
790 790
791 - def SetInput(self, imagedata): 791 + def SetInput(self, imagedata, mask_dict):
792 self.imagedata = imagedata 792 self.imagedata = imagedata
793 793
794 #ren = self.ren 794 #ren = self.ren
@@ -797,7 +797,7 @@ class Viewer(wx.Panel): @@ -797,7 +797,7 @@ class Viewer(wx.Panel):
797 # Slice pipeline, to be inserted into current viewer 797 # Slice pipeline, to be inserted into current viewer
798 slice_ = sl.Slice() 798 slice_ = sl.Slice()
799 if slice_.imagedata is None: 799 if slice_.imagedata is None:
800 - slice_.SetInput(imagedata) 800 + slice_.SetInput(imagedata, mask_dict)
801 801
802 #actor = vtk.vtkImageActor() 802 #actor = vtk.vtkImageActor()
803 #actor.SetInput(slice_.GetOutput()) 803 #actor.SetInput(slice_.GetOutput())
invesalius/gui/task_importer.py
@@ -32,7 +32,7 @@ BTN_OPEN_PROJECT = wx.NewId() @@ -32,7 +32,7 @@ BTN_OPEN_PROJECT = wx.NewId()
32 32
33 WILDCARD_OPEN = "InVesalius 1 project (*.promed)|*.promed|"\ 33 WILDCARD_OPEN = "InVesalius 1 project (*.promed)|*.promed|"\
34 "InVesalius 2 project (*.inv)|*.inv|"\ 34 "InVesalius 2 project (*.inv)|*.inv|"\
35 - "InVesalius 3 project (*.iv3)|*.iv3|"\ 35 + "InVesalius 3 project (*.inv3)|*.inv3|"\
36 "All files (*.*)|*.*" 36 "All files (*.*)|*.*"
37 37
38 class TaskPanel(wx.Panel): 38 class TaskPanel(wx.Panel):
@@ -177,7 +177,10 @@ class InnerTaskPanel(wx.Panel): @@ -177,7 +177,10 @@ class InnerTaskPanel(wx.Panel):
177 defaultDir=path, 177 defaultDir=path,
178 defaultFile="", wildcard=WILDCARD_OPEN, 178 defaultFile="", wildcard=WILDCARD_OPEN,
179 style=wx.OPEN|wx.CHANGE_DIR) 179 style=wx.OPEN|wx.CHANGE_DIR)
180 - dlg.SetFilterIndex(3) 180 + if sys.platform != 'darwin':
  181 + dlg.SetFilterIndex(2)
  182 + else:
  183 + dlg.SetFilterIndex(3)
181 184
182 # Show the dialog and retrieve the user response. If it is the OK response, 185 # Show the dialog and retrieve the user response. If it is the OK response,
183 # process the data. 186 # process the data.
@@ -206,9 +209,9 @@ class InnerTaskPanel(wx.Panel): @@ -206,9 +209,9 @@ class InnerTaskPanel(wx.Panel):
206 self.OnLinkOpenProject() 209 self.OnLinkOpenProject()
207 210
208 def TestLoadProjects(self): 211 def TestLoadProjects(self):
209 - self.LoadProject("test1.iv3")  
210 - self.LoadProject("test2.iv3")  
211 - self.LoadProject("test3.iv3") 212 + self.LoadProject("test1.inv3")
  213 + self.LoadProject("test2.inv3")
  214 + self.LoadProject("test3.inv3")
212 215
213 def LoadProject(self, proj_name="Unnamed"): 216 def LoadProject(self, proj_name="Unnamed"):
214 """ 217 """
invesalius/presets.py
@@ -105,6 +105,16 @@ class Presets(): @@ -105,6 +105,16 @@ class Presets():
105 return filename 105 return filename
106 106
107 def OpenPlist(self, filename): 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']) 108 + p = plistlib.readPlist(filename)
  109 + d1 = p['thresh_mri'].copy()
  110 + d2 = p['thresh_ct'].copy()
  111 +
  112 + self.thresh_mri = TwoWaysDictionary(d1)
  113 + self.thresh_ct = TwoWaysDictionary(d2)
  114 +
  115 +
  116 +
  117 + def Test(self):
  118 + print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  119 + print self.thresh_ct.get_value("Bone")
  120 + print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
invesalius/project.py
@@ -55,6 +55,11 @@ class Project(object): @@ -55,6 +55,11 @@ class Project(object):
55 # TODO: Discuss when this will be used. 55 # TODO: Discuss when this will be used.
56 self.imagedata = '' 56 self.imagedata = ''
57 57
  58 + self.name = ''
  59 + #self.dicom = ''
  60 + self.modality = ''
  61 + self.original_orientation = -1
  62 +
58 # Masks are related to vtkImageData 63 # Masks are related to vtkImageData
59 self.mask_dict = {} 64 self.mask_dict = {}
60 # Predefined threshold values 65 # Predefined threshold values
@@ -65,10 +70,12 @@ class Project(object): @@ -65,10 +70,12 @@ class Project(object):
65 self.level = '' 70 self.level = ''
66 71
67 self.presets = Presets() 72 self.presets = Presets()
68 - 73 + self.threshold_modes = self.presets.thresh_ct
  74 + self.threshold_range = ''
  75 +
69 self.original_orientation = '' 76 self.original_orientation = ''
70 # MRI ? CT? 77 # MRI ? CT?
71 - self.threshold_modes = self.presets.thresh_ct 78 +
72 79
73 # TODO: define how we will relate these threshold values to 80 # TODO: define how we will relate these threshold values to
74 # default threshold labels 81 # default threshold labels
@@ -121,13 +128,17 @@ class Project(object): @@ -121,13 +128,17 @@ class Project(object):
121 return self.mask_dict[index] 128 return self.mask_dict[index]
122 129
123 130
124 - def SetAcquisitionModality(self, type_): 131 + def SetAcquisitionModality(self, type_=None):
  132 + if type_ is None:
  133 + type_ = self.modality
  134 +
125 if type_ == "MRI": 135 if type_ == "MRI":
126 self.threshold_modes = self.presets.thresh_mri 136 self.threshold_modes = self.presets.thresh_mri
127 elif type_ == "CT": 137 elif type_ == "CT":
128 self.threshold_modes = self.presets.thresh_ct 138 self.threshold_modes = self.presets.thresh_ct
129 else: 139 else:
130 print "Different Acquisition Modality!!!" 140 print "Different Acquisition Modality!!!"
  141 + self.modality = type_
131 142
132 def SetRaycastPreset(self, label): 143 def SetRaycastPreset(self, label):
133 path = os.path.join(RAYCASTING_PRESETS_DIRECTORY, label + '.plist') 144 path = os.path.join(RAYCASTING_PRESETS_DIRECTORY, label + '.plist')
@@ -187,9 +198,10 @@ class Project(object): @@ -187,9 +198,10 @@ class Project(object):
187 elif key == 'presets': 198 elif key == 'presets':
188 filepath = os.path.split(project[key]["#plist"])[-1] 199 filepath = os.path.split(project[key]["#plist"])[-1]
189 path = os.path.join(dirpath, filepath) 200 path = os.path.join(dirpath, filepath)
190 - preset = Presets()  
191 - preset.OpenPlist(path)  
192 - self.presets = preset 201 + p = Presets()
  202 + p.OpenPlist(path)
  203 + p.Test()
  204 + self.presets = p
193 elif key == 'mask_dict': 205 elif key == 'mask_dict':
194 self.mask_dict = {} 206 self.mask_dict = {}
195 for mask in project[key]: 207 for mask in project[key]:
@@ -210,13 +222,6 @@ class Project(object): @@ -210,13 +222,6 @@ class Project(object):
210 setattr(self, key, project[key]) 222 setattr(self, key, project[key])
211 print "depois", self.__dict__ 223 print "depois", self.__dict__
212 224
213 - #masks = project['masks']  
214 - #for index in masks:  
215 - # self.mask_dict[index] = masks[index]  
216 -  
217 - #surfaces = project['surfaces']  
218 - #for index in surfaces:  
219 - # self.surface_dict[index] = surfaces[index]  
220 225
221 226
222 def Compress(folder, filename): 227 def Compress(folder, filename):