Commit 581b710833a23ab8692c6155b2986a70bec50b26
1 parent
7c53970b
Exists in
master
and in
6 other branches
ENH: Surface overwrite while on mask task (fix #117)
Showing
6 changed files
with
96 additions
and
33 deletions
Show diff stats
invesalius/data/slice_.py
@@ -131,9 +131,9 @@ class Slice(object): | @@ -131,9 +131,9 @@ class Slice(object): | ||
131 | #--------------------------------------------------------------------------- | 131 | #--------------------------------------------------------------------------- |
132 | # BEGIN PUBSUB_EVT METHODS | 132 | # BEGIN PUBSUB_EVT METHODS |
133 | #--------------------------------------------------------------------------- | 133 | #--------------------------------------------------------------------------- |
134 | - def __get_mask_data_for_surface_creation(self, pubsub_evt): | ||
135 | - mask_index = pubsub_evt.data | ||
136 | - CreateSurfaceFromIndex | 134 | + #def __get_mask_data_for_surface_creation(self, pubsub_evt): |
135 | + # mask_index = pubsub_evt.data | ||
136 | + # CreateSurfaceFromIndex | ||
137 | 137 | ||
138 | def __add_mask(self, pubsub_evt): | 138 | def __add_mask(self, pubsub_evt): |
139 | mask_name = pubsub_evt.data | 139 | mask_name = pubsub_evt.data |
@@ -363,14 +363,9 @@ class Slice(object): | @@ -363,14 +363,9 @@ class Slice(object): | ||
363 | ps.Publisher().sendMessage('Update slice viewer') | 363 | ps.Publisher().sendMessage('Update slice viewer') |
364 | #--------------------------------------------------------------------------- | 364 | #--------------------------------------------------------------------------- |
365 | 365 | ||
366 | - | ||
367 | - | ||
368 | - | ||
369 | - | ||
370 | - | ||
371 | def CreateSurfaceFromIndex(self, pubsub_evt): | 366 | def CreateSurfaceFromIndex(self, pubsub_evt): |
372 | - mask_index = pubsub_evt.data | ||
373 | - | 367 | + mask_index, overwrite_surface = pubsub_evt.data |
368 | + | ||
374 | 369 | ||
375 | proj = Project() | 370 | proj = Project() |
376 | mask = proj.mask_dict[mask_index] | 371 | mask = proj.mask_dict[mask_index] |
@@ -384,7 +379,8 @@ class Slice(object): | @@ -384,7 +379,8 @@ class Slice(object): | ||
384 | edited_points = mask.edited_points | 379 | edited_points = mask.edited_points |
385 | 380 | ||
386 | ps.Publisher().sendMessage('Create surface', | 381 | ps.Publisher().sendMessage('Create surface', |
387 | - (imagedata,colour,threshold, edited_points)) | 382 | + (imagedata,colour,threshold, |
383 | + edited_points, overwrite_surface)) | ||
388 | 384 | ||
389 | def GetOutput(self): | 385 | def GetOutput(self): |
390 | return self.cross.GetOutput() | 386 | return self.cross.GetOutput() |
invesalius/data/surface.py
@@ -39,15 +39,18 @@ class Surface(): | @@ -39,15 +39,18 @@ class Surface(): | ||
39 | Represent both vtkPolyData and associated properties. | 39 | Represent both vtkPolyData and associated properties. |
40 | """ | 40 | """ |
41 | general_index = -1 | 41 | general_index = -1 |
42 | - def __init__(self): | 42 | + def __init__(self, index=None): |
43 | Surface.general_index += 1 | 43 | Surface.general_index += 1 |
44 | - self.index = Surface.general_index | 44 | + if index is None: |
45 | + self.index = Surface.general_index | ||
46 | + else: | ||
47 | + self.index = index | ||
45 | self.polydata = '' | 48 | self.polydata = '' |
46 | self.colour = '' | 49 | self.colour = '' |
47 | self.transparency = const.SURFACE_TRANSPARENCY | 50 | self.transparency = const.SURFACE_TRANSPARENCY |
48 | self.volume = 0 | 51 | self.volume = 0 |
49 | self.is_shown = 1 | 52 | self.is_shown = 1 |
50 | - self.name = const.SURFACE_NAME_PATTERN %(Surface.general_index+1) | 53 | + self.name = const.SURFACE_NAME_PATTERN %(self.index+1) |
51 | 54 | ||
52 | def SavePlist(self, filename): | 55 | def SavePlist(self, filename): |
53 | surface = {} | 56 | surface = {} |
@@ -95,6 +98,7 @@ class SurfaceManager(): | @@ -95,6 +98,7 @@ class SurfaceManager(): | ||
95 | """ | 98 | """ |
96 | def __init__(self): | 99 | def __init__(self): |
97 | self.actors_dict = {} | 100 | self.actors_dict = {} |
101 | + self.last_surface_index = 0 | ||
98 | self.__bind_events() | 102 | self.__bind_events() |
99 | 103 | ||
100 | def __bind_events(self): | 104 | def __bind_events(self): |
@@ -168,7 +172,11 @@ class SurfaceManager(): | @@ -168,7 +172,11 @@ class SurfaceManager(): | ||
168 | """ | 172 | """ |
169 | Create surface actor, save into project and send it to viewer. | 173 | Create surface actor, save into project and send it to viewer. |
170 | """ | 174 | """ |
171 | - imagedata, colour, [min_value, max_value], edited_points = pubsub_evt.data | 175 | + imagedata, colour, [min_value, max_value], \ |
176 | + edited_points, overwrite = pubsub_evt.data | ||
177 | + | ||
178 | + | ||
179 | + print "---------------- OVERWRITE:",overwrite | ||
172 | quality=_('Optimal *') | 180 | quality=_('Optimal *') |
173 | mode = 'CONTOUR' # 'GRAYSCALE' | 181 | mode = 'CONTOUR' # 'GRAYSCALE' |
174 | ps.Publisher().sendMessage('Begin busy cursor') | 182 | ps.Publisher().sendMessage('Begin busy cursor') |
@@ -253,7 +261,10 @@ class SurfaceManager(): | @@ -253,7 +261,10 @@ class SurfaceManager(): | ||
253 | actor.SetMapper(mapper) | 261 | actor.SetMapper(mapper) |
254 | 262 | ||
255 | # Create Surface instance | 263 | # Create Surface instance |
256 | - surface = Surface() | 264 | + if overwrite: |
265 | + surface = Surface(index = self.last_surface_index) | ||
266 | + else: | ||
267 | + surface = Surface() | ||
257 | surface.colour = colour | 268 | surface.colour = colour |
258 | surface.polydata = polydata | 269 | surface.polydata = polydata |
259 | 270 | ||
@@ -281,29 +292,38 @@ class SurfaceManager(): | @@ -281,29 +292,38 @@ class SurfaceManager(): | ||
281 | 292 | ||
282 | # Append surface into Project.surface_dict | 293 | # Append surface into Project.surface_dict |
283 | proj = prj.Project() | 294 | proj = prj.Project() |
284 | - index = proj.AddSurface(surface) | ||
285 | - surface.index = index | 295 | + if overwrite: |
296 | + proj.ChangeSurface(surface) | ||
297 | + else: | ||
298 | + index = proj.AddSurface(surface) | ||
299 | + surface.index = index | ||
286 | 300 | ||
287 | 301 | ||
288 | session = ses.Session() | 302 | session = ses.Session() |
289 | session.ChangeProject() | 303 | session.ChangeProject() |
290 | 304 | ||
291 | 305 | ||
292 | - # Save actor for future management tasks | ||
293 | - self.actors_dict[surface.index] = actor | ||
294 | - | ||
295 | - # Send actor by pubsub to viewer's render | ||
296 | - ps.Publisher().sendMessage('Load surface actor into viewer', (actor)) | ||
297 | - | ||
298 | - ps.Publisher().sendMessage('Update status text in GUI', | ||
299 | - "Surface created.") | ||
300 | - | ||
301 | # The following lines have to be here, otherwise all volumes disappear | 306 | # The following lines have to be here, otherwise all volumes disappear |
302 | measured_polydata = vtk.vtkMassProperties() | 307 | measured_polydata = vtk.vtkMassProperties() |
303 | measured_polydata.SetInput(polydata) | 308 | measured_polydata.SetInput(polydata) |
304 | volume = measured_polydata.GetVolume() | 309 | volume = measured_polydata.GetVolume() |
305 | surface.volume = volume | 310 | surface.volume = volume |
311 | + self.last_surface_index = surface.index | ||
312 | + | ||
313 | + ps.Publisher().sendMessage('Load surface actor into viewer', actor) | ||
306 | 314 | ||
315 | + # Send actor by pubsub to viewer's render | ||
316 | + if overwrite: | ||
317 | + old_actor = self.actors_dict[self.last_surface_index] | ||
318 | + ps.Publisher().sendMessage('Remove surface actor from viewer', old_actor) | ||
319 | + | ||
320 | + # Save actor for future management tasks | ||
321 | + self.actors_dict[surface.index] = actor | ||
322 | + | ||
323 | + | ||
324 | + ps.Publisher().sendMessage('Update status text in GUI', | ||
325 | + _("Ready")) | ||
326 | + | ||
307 | ps.Publisher().sendMessage('Update surface info in GUI', | 327 | ps.Publisher().sendMessage('Update surface info in GUI', |
308 | (surface.index, surface.name, | 328 | (surface.index, surface.name, |
309 | surface.colour, surface.volume, | 329 | surface.colour, surface.volume, |
invesalius/data/viewer_volume.py
@@ -83,6 +83,8 @@ class Viewer(wx.Panel): | @@ -83,6 +83,8 @@ class Viewer(wx.Panel): | ||
83 | def __bind_events(self): | 83 | def __bind_events(self): |
84 | ps.Publisher().subscribe(self.LoadActor, | 84 | ps.Publisher().subscribe(self.LoadActor, |
85 | 'Load surface actor into viewer') | 85 | 'Load surface actor into viewer') |
86 | + ps.Publisher().subscribe(self.RemoveActor, | ||
87 | + 'Remove surface actor from viewer') | ||
86 | ps.Publisher().subscribe(self.UpdateRender, | 88 | ps.Publisher().subscribe(self.UpdateRender, |
87 | 'Render volume viewer') | 89 | 'Render volume viewer') |
88 | ps.Publisher().subscribe(self.ChangeBackgroundColour, | 90 | ps.Publisher().subscribe(self.ChangeBackgroundColour, |
@@ -351,6 +353,15 @@ class Viewer(wx.Panel): | @@ -351,6 +353,15 @@ class Viewer(wx.Panel): | ||
351 | #self.ShowOrientationCube() | 353 | #self.ShowOrientationCube() |
352 | self.interactor.Render() | 354 | self.interactor.Render() |
353 | 355 | ||
356 | + def RemoveActor(self, pubsub_evt): | ||
357 | + print "RemoveActor" | ||
358 | + actor = pubsub_evt.data | ||
359 | + | ||
360 | + ren = self.ren | ||
361 | + ren.RemoveActor(actor) | ||
362 | + | ||
363 | + self.interactor.Render() | ||
364 | + | ||
354 | def LoadSlicePlane(self, pubsub_evt): | 365 | def LoadSlicePlane(self, pubsub_evt): |
355 | self.slice_plane = SlicePlane() | 366 | self.slice_plane = SlicePlane() |
356 | 367 |
invesalius/gui/data_notebook.py
@@ -273,6 +273,8 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -273,6 +273,8 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
273 | ps.Publisher().sendMessage('Show surface', (index, flag)) | 273 | ps.Publisher().sendMessage('Show surface', (index, flag)) |
274 | 274 | ||
275 | def AddSurface(self, pubsub_evt): | 275 | def AddSurface(self, pubsub_evt): |
276 | + | ||
277 | + | ||
276 | index = pubsub_evt.data[0] | 278 | index = pubsub_evt.data[0] |
277 | name = pubsub_evt.data[1] | 279 | name = pubsub_evt.data[1] |
278 | colour = pubsub_evt.data[2] | 280 | colour = pubsub_evt.data[2] |
@@ -281,9 +283,19 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -281,9 +283,19 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
281 | 283 | ||
282 | image = self.CreateColourBitmap(colour) | 284 | image = self.CreateColourBitmap(colour) |
283 | image_index = self.imagelist.Add(image) | 285 | image_index = self.imagelist.Add(image) |
286 | + | ||
287 | + | ||
288 | + | ||
289 | + index_list = self.surface_list_index.keys() | ||
284 | self.surface_list_index[index] = image_index | 290 | self.surface_list_index[index] = image_index |
291 | + | ||
292 | + if (index in index_list) and index_list: | ||
293 | + self.UpdateItemInfo(index, name, volume, transparency, colour) | ||
294 | + else: | ||
295 | + self.InsertNewItem(index, name, volume, transparency, colour) | ||
296 | + | ||
285 | 297 | ||
286 | - self.InsertNewItem(index, name, volume, transparency, colour) | 298 | + |
287 | 299 | ||
288 | def InsertNewItem(self, index=0, label="Surface 1", volume="0 mm3", | 300 | def InsertNewItem(self, index=0, label="Surface 1", volume="0 mm3", |
289 | transparency="0%%", colour=None): | 301 | transparency="0%%", colour=None): |
@@ -293,6 +305,15 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -293,6 +305,15 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
293 | self.SetStringItem(index, 2, volume) | 305 | self.SetStringItem(index, 2, volume) |
294 | self.SetStringItem(index, 3, transparency) | 306 | self.SetStringItem(index, 3, transparency) |
295 | self.SetItemImage(index, 1) | 307 | self.SetItemImage(index, 1) |
308 | + | ||
309 | + def UpdateItemInfo(self, index=0, label="Surface 1", volume="0 mm3", | ||
310 | + transparency="0%%", colour=None): | ||
311 | + self.SetStringItem(index, 1, label, | ||
312 | + imageId = self.surface_list_index[index]) | ||
313 | + self.SetStringItem(index, 2, volume) | ||
314 | + self.SetStringItem(index, 3, transparency) | ||
315 | + self.SetItemImage(index, 1) | ||
316 | + | ||
296 | 317 | ||
297 | def CreateColourBitmap(self, colour): | 318 | def CreateColourBitmap(self, colour): |
298 | """ | 319 | """ |
invesalius/gui/task_slice.py
@@ -106,17 +106,25 @@ class InnerTaskPanel(wx.Panel): | @@ -106,17 +106,25 @@ class InnerTaskPanel(wx.Panel): | ||
106 | self.fold_panel = fold_panel | 106 | self.fold_panel = fold_panel |
107 | 107 | ||
108 | # Button to fold to select region task | 108 | # Button to fold to select region task |
109 | - button_next = wx.Button(self, -1, _("Create 3D surface")) | 109 | + button_next = wx.Button(self, -1, _("Save surface")) |
110 | + check_box = wx.CheckBox(self, -1, _("Overwrite last surface")) | ||
111 | + self.check_box = check_box | ||
110 | if sys.platform != 'win32': | 112 | if sys.platform != 'win32': |
111 | button_next.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) | 113 | button_next.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) |
114 | + check_box.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) | ||
112 | button_next.Bind(wx.EVT_BUTTON, self.OnButtonNextTask) | 115 | button_next.Bind(wx.EVT_BUTTON, self.OnButtonNextTask) |
113 | 116 | ||
117 | + line_sizer = wx.BoxSizer(wx.HORIZONTAL) | ||
118 | + line_sizer.Add(check_box, 1, wx.ALIGN_LEFT|wx.RIGHT|wx.LEFT|wx.BOTTOM, 5) | ||
119 | + line_sizer.Add(button_next, 0, | ||
120 | + wx.ALIGN_RIGHT|wx.RIGHT|wx.LEFT|wx.BOTTOM, 5) | ||
121 | + line_sizer.Fit(self) | ||
122 | + | ||
114 | # Add line sizers into main sizer | 123 | # Add line sizers into main sizer |
115 | main_sizer = wx.BoxSizer(wx.VERTICAL) | 124 | main_sizer = wx.BoxSizer(wx.VERTICAL) |
116 | main_sizer.Add(line_new, 0,wx.GROW|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5) | 125 | main_sizer.Add(line_new, 0,wx.GROW|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5) |
117 | - main_sizer.Add(fold_panel, 1, wx.GROW|wx.EXPAND|wx.ALL, 5) | ||
118 | - main_sizer.Add(button_next, 0, | ||
119 | - wx.ALIGN_RIGHT|wx.RIGHT|wx.LEFT|wx.BOTTOM, 5) | 126 | + main_sizer.Add(fold_panel, 6, wx.GROW|wx.EXPAND|wx.ALL, 5) |
127 | + main_sizer.AddSizer(line_sizer, 1, wx.GROW|wx.EXPAND) | ||
120 | main_sizer.Fit(self) | 128 | main_sizer.Fit(self) |
121 | 129 | ||
122 | self.SetSizer(main_sizer) | 130 | self.SetSizer(main_sizer) |
@@ -130,9 +138,12 @@ class InnerTaskPanel(wx.Panel): | @@ -130,9 +138,12 @@ class InnerTaskPanel(wx.Panel): | ||
130 | if id == BTN_NEW: | 138 | if id == BTN_NEW: |
131 | self.OnLinkNewMask() | 139 | self.OnLinkNewMask() |
132 | 140 | ||
141 | + | ||
133 | def OnButtonNextTask(self, evt): | 142 | def OnButtonNextTask(self, evt): |
143 | + overwrite = self.check_box.IsChecked() | ||
134 | ps.Publisher().sendMessage('Create surface from index', | 144 | ps.Publisher().sendMessage('Create surface from index', |
135 | - self.GetMaskSelected()) | 145 | + (self.GetMaskSelected(), |
146 | + overwrite)) | ||
136 | 147 | ||
137 | def OnLinkNewMask(self, evt=None): | 148 | def OnLinkNewMask(self, evt=None): |
138 | dlg = wx.TextEntryDialog(self, _('Name of new mask:'), | 149 | dlg = wx.TextEntryDialog(self, _('Name of new mask:'), |
invesalius/project.py
@@ -130,6 +130,10 @@ class Project(object): | @@ -130,6 +130,10 @@ class Project(object): | ||
130 | self.surface_dict[index] = surface | 130 | self.surface_dict[index] = surface |
131 | return index | 131 | return index |
132 | 132 | ||
133 | + def ChangeSurface(self, surface): | ||
134 | + index = surface.index | ||
135 | + self.surface_dict[index] = surface | ||
136 | + | ||
133 | def RemoveSurface(self, index): | 137 | def RemoveSurface(self, index): |
134 | new_dict = {} | 138 | new_dict = {} |
135 | for i in self.surface_dict: | 139 | for i in self.surface_dict: |