Commit 3043ba903884aea3fe13f9e3fcd885fa5fd76690

Authored by tatiana
1 parent 7aabaaed

ENC: Masks relation with GUI (both data_notebook and tab)

invesalius/data/mask.py
... ... @@ -12,4 +12,5 @@ class Mask():
12 12 self.threshold_range = const.THRESHOLD_RANGE
13 13 self.name = const.MASK_NAME_PATTERN %(Mask.general_index+1)
14 14 self.edition_threshold_range = const.THRESHOLD_RANGE
  15 + self.is_shown = 1
15 16  
16 17 \ No newline at end of file
... ...
invesalius/data/slice_.py
... ... @@ -17,6 +17,7 @@ class Slice(object):
17 17 def __init__(self):
18 18 self.imagedata = None
19 19 self.__bind_events()
  20 + self.current_mask = None
20 21  
21 22 def __bind_events(self):
22 23 ps.Publisher().subscribe(self.SetThresholdRange, 'Set threshold values')
... ... @@ -30,9 +31,33 @@ class Slice(object):
30 31 'Create surface from index')
31 32 ps.Publisher().subscribe(self.UpdateCursorPosition,
32 33 'Update cursor position in slice')
  34 + ps.Publisher().subscribe(self.ShowMask, 'Show mask')
  35 +
  36 +
  37 + def ShowMask(self, pubsub_evt):
  38 +
  39 + # This is necessary because wx events are calling this before it was created
  40 + if self.current_mask:
  41 + mask_index, value = pubsub_evt.data
  42 +
  43 + proj = Project()
  44 + proj.mask_dict[mask_index].is_shown = value
  45 +
  46 +
  47 + if (mask_index == self.current_mask.index):
  48 + if value:
  49 + self.blend_filter.SetOpacity(1, self.current_mask.opacity)
  50 + else:
  51 +
  52 + self.blend_filter.SetOpacity(1, 0)
  53 + self.blend_filter.Update()
  54 + ps.Publisher().sendMessage('Update slice viewer')
  55 +
  56 +
33 57  
34 58 def CreateSurfaceFromIndex(self, pubsub_evt):
35 59 mask_index = pubsub_evt.data
  60 +
36 61  
37 62 proj = Project()
38 63 mask = proj.mask_dict[mask_index]
... ... @@ -65,24 +90,29 @@ class Slice(object):
65 90 self.current_mask = future_mask
66 91  
67 92 colour = future_mask.colour
68   - self.ChangeCurrentMaskColour(colour)
  93 + self.ChangeCurrentMaskColour(colour, update=False)
69 94  
70 95 imagedata = future_mask.imagedata
71 96 self.img_colours_mask.SetInput(imagedata)
72 97  
  98 + if self.current_mask.is_shown:
  99 + self.blend_filter.SetOpacity(1, self.current_mask.opacity)
  100 + else:
  101 +
  102 + self.blend_filter.SetOpacity(1, 0)
  103 + self.blend_filter.Update()
  104 +
73 105 ps.Publisher().sendMessage('Set mask threshold in notebook',
74 106 (self.current_mask.index,
75 107 self.current_mask.threshold_range))
76 108 ps.Publisher().sendMessage('Set threshold values in gradient',
77 109 self.current_mask.threshold_range)
  110 + ps.Publisher().sendMessage('Select mask name in combo', mask_index)
78 111 ps.Publisher().sendMessage('Update slice viewer')
79 112  
80   - def ChangeCurrentMaskColour(self, colour):
81   - try:
82   - self.current_mask
83   - except AttributeError:
84   - pass
85   - else:
  113 + def ChangeCurrentMaskColour(self, colour, update=True):
  114 + # This is necessary because wx events are calling this before it was created
  115 + if self.current_mask:
86 116 (r,g,b) = colour
87 117 scalar_range = int(self.imagedata.GetScalarRange()[1])
88 118 self.current_mask.colour = colour
... ... @@ -94,11 +124,12 @@ class Slice(object):
94 124 ps.Publisher().sendMessage('Change mask colour in notebook',
95 125 (self.current_mask.index, (r,g,b)))
96 126 ps.Publisher().sendMessage('Set GUI items colour', colour_wx)
97   - ps.Publisher().sendMessage('Update slice viewer')
  127 + if update:
  128 + ps.Publisher().sendMessage('Update slice viewer')
98 129  
99 130  
100 131 def GetOutput(self):
101   - return self.blend_imagedata.GetOutput()
  132 + return self.cast_filter.GetOutput()
102 133  
103 134 def SetInput(self, imagedata):
104 135 self.imagedata = imagedata
... ... @@ -110,18 +141,18 @@ class Slice(object):
110 141 mask_opacity = self.current_mask.opacity
111 142  
112 143 # blend both imagedatas, so it can be inserted into viewer
113   - blend_imagedata = vtk.vtkImageBlend()
114   - blend_imagedata.SetBlendModeToNormal()
115   - blend_imagedata.SetOpacity(0, 1)
116   - blend_imagedata.SetOpacity(1, mask_opacity)
117   - blend_imagedata.SetInput(0, imagedata_bg)
118   - blend_imagedata.SetInput(1, imagedata_mask)
119   - blend_imagedata.SetBlendModeToNormal()
120   - blend_imagedata.GetOutput().ReleaseDataFlagOn()
121   - #self.blend_imagedata = blend_imagedata
122   -
123   - #blend_imagedata.Update()
124   - #extent = blend_imagedata.GetOutput().GetWholeExtent()
  144 + blend_filter = vtk.vtkImageBlend()
  145 + blend_filter.SetBlendModeToNormal()
  146 + blend_filter.SetOpacity(0, 1)
  147 + if self.current_mask.is_shown:
  148 + blend_filter.SetOpacity(1, mask_opacity)
  149 + else:
  150 + blend_filter.SetOpacity(1, 0)
  151 + blend_filter.SetInput(0, imagedata_bg)
  152 + blend_filter.SetInput(1, imagedata_mask)
  153 + blend_filter.SetBlendModeToNormal()
  154 + blend_filter.GetOutput().ReleaseDataFlagOn()
  155 + self.blend_filter = blend_filter
125 156  
126 157 # global values
127 158 CURSOR_X = -1 # SAGITAL
... ... @@ -133,7 +164,7 @@ class Slice(object):
133 164  
134 165 cross = vtk.vtkImageCursor3D()
135 166 cross.GetOutput().ReleaseDataFlagOn()
136   - cross.SetInput(blend_imagedata.GetOutput())
  167 + cross.SetInput(blend_filter.GetOutput())
137 168 cross.SetCursorPosition(CURSOR_X, CURSOR_Y, CURSOR_Z)
138 169 cross.SetCursorValue(CURSOR_VALUE)
139 170 cross.SetCursorRadius(CURSOR_RADIUS)
... ... @@ -146,7 +177,7 @@ class Slice(object):
146 177 cast.SetOutputScalarTypeToUnsignedChar()
147 178 cast.Update()
148 179  
149   - self.blend_imagedata = cast
  180 + self.cast_filter = cast
150 181  
151 182  
152 183 def UpdateCursorPosition(self, pubsub_evt):
... ... @@ -154,11 +185,9 @@ class Slice(object):
154 185 new_pos = pubsub_evt.data
155 186 self.cross.SetCursorPosition(new_pos)
156 187 self.cross.Modified()
157   - self.blend_imagedata.Update()
158   - ps.Publisher().sendMessage('Update slice viewer', None)
159   -
  188 + self.cast_filter.Update()
  189 + ps.Publisher().sendMessage('Update slice viewer')
160 190  
161   -
162 191 def __create_background(self, imagedata):
163 192  
164 193 thresh_min, thresh_max = imagedata.GetScalarRange()
... ... @@ -208,15 +237,19 @@ class Slice(object):
208 237  
209 238 # when this is not the first instance, user will have defined a name
210 239 if name is not None:
  240 + print "new mask, we will check if it will be shown"
211 241 future_mask.name = name
  242 + if future_mask.is_shown:
  243 + self.blend_filter.SetOpacity(1, future_mask.opacity)
  244 + else:
  245 + self.blend_filter.SetOpacity(1, 0)
  246 + self.blend_filter.Update()
212 247  
213 248 # insert new mask into project and retrieve its index
214 249 proj = Project()
215 250 proj.AddMask(future_mask.index, future_mask)
216 251  
217 252  
218   - imagedata1 = proj.mask_dict[0].imagedata
219   -
220 253 # update gui related to mask
221 254 ps.Publisher().sendMessage('Add mask',
222 255 (future_mask.index,
... ... @@ -227,7 +260,6 @@ class Slice(object):
227 260 self.current_mask = future_mask
228 261  
229 262  
230   -
231 263 def __create_mask(self, imagedata):
232 264 # create new mask instance and insert it into project
233 265 self.CreateMask(imagedata=imagedata)
... ...
invesalius/data/surface.py
... ... @@ -35,7 +35,6 @@ class SurfaceManager():
35 35  
36 36 """
37 37 def __init__(self):
38   - print "surface manager was created"
39 38 self.actors_dict = {}
40 39 self.__bind_events()
41 40  
... ...
invesalius/data/viewer_slice.py
... ... @@ -173,8 +173,7 @@ class Viewer(wx.Panel):
173 173 coord[index] = extent_max[index]
174 174 elif coord[index] < extent_min[index]:
175 175 coord[index] = extent_min[index]
176   -
177   - print "New coordinate: ", coord
  176 + #print "New coordinate: ", coord
178 177  
179 178 return coord
180 179  
... ...
invesalius/gui/data_notebook.py
... ... @@ -93,17 +93,17 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
93 93 def __init_image_list(self):
94 94 self.imagelist = wx.ImageList(16, 16)
95 95  
96   - image = wx.Image("../icons/object_visible.jpg")
  96 + image = wx.Image("../icons/object_invisible.jpg")
97 97 bitmap = wx.BitmapFromImage(image.Scale(16, 16))
98 98 bitmap.SetWidth(16)
99 99 bitmap.SetHeight(16)
100   - img_check = self.imagelist.Add(bitmap)
101   -
102   - image = wx.Image("../icons/object_invisible.jpg")
  100 + img_null = self.imagelist.Add(bitmap)
  101 +
  102 + image = wx.Image("../icons/object_visible.jpg")
103 103 bitmap = wx.BitmapFromImage(image.Scale(16, 16))
104 104 bitmap.SetWidth(16)
105 105 bitmap.SetHeight(16)
106   - img_null = self.imagelist.Add(bitmap)
  106 + img_check = self.imagelist.Add(bitmap)
107 107  
108 108 self.SetImageList(self.imagelist, wx.IMAGE_LIST_SMALL)
109 109  
... ... @@ -113,35 +113,37 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
113 113 print "Editing label", evt.GetLabel()
114 114 #print evt.GetImage()
115 115 #print evt.GetId()
116   - #print evt.GetIndex()
117   - print "--------"
118   - print evt.m_oldItemIndex
119   - print evt.m_itemIndex
120   - index = evt.GetIndex()
  116 + print evt.GetIndex()
  117 + #print "--------"
  118 + #print evt.m_oldItemIndex
  119 + #print evt.m_itemIndex
  120 + #index = evt.GetIndex()
121 121 #print dir(evt)
122 122  
123   - print "Get item data:", self.GetItemData(index)
124   - print "Get item position:", self.GetItemPosition(index)
125   - print "Get next item:", self.GetNextItem(index)
  123 + #print "Get item data:", self.GetItemData(index)
  124 + #print "Get item position:", self.GetItemPosition(index)
  125 + #print "Get next item:", self.GetNextItem(index)
126 126 evt.Skip()
127 127  
128 128 def OnItemActivated(self, evt):
129 129 print "OnItemActivated"
130 130 self.ToggleItem(evt.m_itemIndex)
131 131  
  132 +
132 133 def OnCheckItem(self, index, flag):
133   - # TODO: use pubsub to communicate to models
  134 +
134 135 if flag:
135   - print "checked, ", index
136   - else:
137   - print "unchecked, ", index
  136 + for key in self.mask_list_index.keys():
  137 + if key != index:
  138 + self.SetItemImage(key, 0)
  139 + ps.Publisher().sendMessage('Change mask selected',index)
  140 + ps.Publisher().sendMessage('Show mask', (index, flag))
138 141  
139 142 def CreateColourBitmap(self, colour):
140 143 """
141 144 Create a wx Image with a mask colour.
142 145 colour: colour in rgb format(0 - 1)
143 146 """
144   - print "Colour", colour
145 147 image = self.image_gray
146 148 new_image = Image.new("RGB", image.size)
147 149 for x in xrange(image.size[0]):
... ... @@ -157,24 +159,19 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
157 159  
158 160 def InsertNewItem(self, index=0, label="Mask 1", threshold="(1000, 4500)",
159 161 colour=None):
160   - print "InsertNewItem"
161 162 self.InsertStringItem(index, "")
162 163 self.SetStringItem(index, 1, label,
163 164 imageId=self.mask_list_index[index])
164 165 self.SetStringItem(index, 2, threshold)
165   -
166   - print "Get item data:", self.GetItemData(index)
167   - print "Get item position:", self.GetItemPosition(index)
168   - print "Get next item:", self.GetNextItem(index)
169   - # FindItem
170   - # FindItemData
171   - # FindItemAtPos
  166 + self.SetItemImage(index, 1)
  167 + for key in self.mask_list_index.keys():
  168 + if key != index:
  169 + self.SetItemImage(key, 0)
172 170  
173 171 def AddMask(self, pubsub_evt):
174 172 index, mask_name, threshold_range, colour = pubsub_evt.data
175 173 image = self.CreateColourBitmap(colour)
176 174 image_index = self.imagelist.Add(image)
177   - print "image_index: ", image_index
178 175 self.mask_list_index[index] = image_index
179 176 self.InsertNewItem(index, mask_name, str(threshold_range))
180 177  
... ... @@ -292,11 +289,7 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
292 289 self.ToggleItem(evt.m_itemIndex)
293 290  
294 291 def OnCheckItem(self, index, flag):
295   - # TODO: use pubsub to communicate to models
296   - if flag:
297   - print "checked, ", index
298   - else:
299   - print "unchecked, ", index
  292 + ps.Publisher().sendMessage('Show surface', (index, not flag))
300 293  
301 294  
302 295  
... ... @@ -417,7 +410,6 @@ class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
417 410 self.imagelist = wx.ImageList(16, 16)
418 411  
419 412 image = wx.Image("../icons/object_visible.jpg")
420   - #image = wx.Image("../img/object_visible-v2.jpg")
421 413 bitmap = wx.BitmapFromImage(image.Scale(16, 16))
422 414 bitmap.SetWidth(16)
423 415 bitmap.SetHeight(16)
... ... @@ -439,6 +431,7 @@ class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
439 431  
440 432 def OnItemActivated(self, evt):
441 433 self.ToggleItem(evt.m_itemIndex)
  434 + print m_itemIndex
442 435  
443 436 def OnCheckItem(self, index, flag):
444 437 # TODO: use pubsub to communicate to models
... ...
invesalius/gui/task_slice.py
... ... @@ -285,12 +285,18 @@ class MaskProperties(wx.Panel):
285 285 ps.Publisher().subscribe(self.SetItemsColour, 'Set GUI items colour')
286 286 ps.Publisher().subscribe(self.SetThresholdValues,
287 287 'Set threshold values in gradient')
  288 + ps.Publisher().subscribe(self.SelectMaskName, 'Select mask name in combo')
288 289  
289 290 def __bind_events_wx(self):
290 291 self.combo_thresh.Bind(wx.EVT_COMBOBOX, self.OnComboThresh)
291 292 self.Bind(grad.EVT_THRESHOLD_CHANGE, self.OnSlideChanged,
292 293 self.gradient)
293 294  
  295 + def SelectMaskName(self, pubsub_evt):
  296 + index = pubsub_evt.data
  297 + self.combo_mask_name.SetSelection(index)
  298 + print dir(self.combo_mask_name)
  299 +
294 300 def SetThresholdValues(self, pubsub_evt):
295 301 thresh_min, thresh_max = pubsub_evt.data
296 302 self.bind_evt_gradient = False
... ... @@ -308,6 +314,7 @@ class MaskProperties(wx.Panel):
308 314 mask_thresh = evt_pubsub.data[2]
309 315 mask_colour = [int(c*255) for c in evt_pubsub.data[3]]
310 316 index = self.combo_mask_name.Append(mask_name)
  317 + self.combo_mask_name.SetSelection(index)
311 318 self.button_colour.SetColour(mask_colour)
312 319 self.gradient.SetColour(mask_colour)
313 320 self.combo_mask_name.SetSelection(index)
... ...
invesalius/invesalius.py
... ... @@ -33,7 +33,6 @@ class InVesalius(wx.App):
33 33 self.main = Frame(None)
34 34 self.control = Controller(self.main)
35 35 self.SetAppName("InVesalius 3.0")
36   - self.SetTopWindow(self.main)
37 36 return True
38 37  
39 38 def ShowFrame(self):
... ...