Commit 3043ba903884aea3fe13f9e3fcd885fa5fd76690
1 parent
7aabaaed
Exists in
master
and in
6 other branches
ENC: Masks relation with GUI (both data_notebook and tab)
Showing
7 changed files
with
97 additions
and
67 deletions
Show diff stats
invesalius/data/mask.py
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
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