Commit 581b710833a23ab8692c6155b2986a70bec50b26

Authored by tatiana
1 parent 7c53970b

ENH: Surface overwrite while on mask task (fix #117)

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: