Commit 581b710833a23ab8692c6155b2986a70bec50b26
1 parent
7c53970b
Exists in
master
and in
68 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 | 131 | #--------------------------------------------------------------------------- |
| 132 | 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 | 138 | def __add_mask(self, pubsub_evt): |
| 139 | 139 | mask_name = pubsub_evt.data |
| ... | ... | @@ -363,14 +363,9 @@ class Slice(object): |
| 363 | 363 | ps.Publisher().sendMessage('Update slice viewer') |
| 364 | 364 | #--------------------------------------------------------------------------- |
| 365 | 365 | |
| 366 | - | |
| 367 | - | |
| 368 | - | |
| 369 | - | |
| 370 | - | |
| 371 | 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 | 370 | proj = Project() |
| 376 | 371 | mask = proj.mask_dict[mask_index] |
| ... | ... | @@ -384,7 +379,8 @@ class Slice(object): |
| 384 | 379 | edited_points = mask.edited_points |
| 385 | 380 | |
| 386 | 381 | ps.Publisher().sendMessage('Create surface', |
| 387 | - (imagedata,colour,threshold, edited_points)) | |
| 382 | + (imagedata,colour,threshold, | |
| 383 | + edited_points, overwrite_surface)) | |
| 388 | 384 | |
| 389 | 385 | def GetOutput(self): |
| 390 | 386 | return self.cross.GetOutput() | ... | ... |
invesalius/data/surface.py
| ... | ... | @@ -39,15 +39,18 @@ class Surface(): |
| 39 | 39 | Represent both vtkPolyData and associated properties. |
| 40 | 40 | """ |
| 41 | 41 | general_index = -1 |
| 42 | - def __init__(self): | |
| 42 | + def __init__(self, index=None): | |
| 43 | 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 | 48 | self.polydata = '' |
| 46 | 49 | self.colour = '' |
| 47 | 50 | self.transparency = const.SURFACE_TRANSPARENCY |
| 48 | 51 | self.volume = 0 |
| 49 | 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 | 55 | def SavePlist(self, filename): |
| 53 | 56 | surface = {} |
| ... | ... | @@ -95,6 +98,7 @@ class SurfaceManager(): |
| 95 | 98 | """ |
| 96 | 99 | def __init__(self): |
| 97 | 100 | self.actors_dict = {} |
| 101 | + self.last_surface_index = 0 | |
| 98 | 102 | self.__bind_events() |
| 99 | 103 | |
| 100 | 104 | def __bind_events(self): |
| ... | ... | @@ -168,7 +172,11 @@ class SurfaceManager(): |
| 168 | 172 | """ |
| 169 | 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 | 180 | quality=_('Optimal *') |
| 173 | 181 | mode = 'CONTOUR' # 'GRAYSCALE' |
| 174 | 182 | ps.Publisher().sendMessage('Begin busy cursor') |
| ... | ... | @@ -253,7 +261,10 @@ class SurfaceManager(): |
| 253 | 261 | actor.SetMapper(mapper) |
| 254 | 262 | |
| 255 | 263 | # Create Surface instance |
| 256 | - surface = Surface() | |
| 264 | + if overwrite: | |
| 265 | + surface = Surface(index = self.last_surface_index) | |
| 266 | + else: | |
| 267 | + surface = Surface() | |
| 257 | 268 | surface.colour = colour |
| 258 | 269 | surface.polydata = polydata |
| 259 | 270 | |
| ... | ... | @@ -281,29 +292,38 @@ class SurfaceManager(): |
| 281 | 292 | |
| 282 | 293 | # Append surface into Project.surface_dict |
| 283 | 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 | 302 | session = ses.Session() |
| 289 | 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 | 306 | # The following lines have to be here, otherwise all volumes disappear |
| 302 | 307 | measured_polydata = vtk.vtkMassProperties() |
| 303 | 308 | measured_polydata.SetInput(polydata) |
| 304 | 309 | volume = measured_polydata.GetVolume() |
| 305 | 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 | 327 | ps.Publisher().sendMessage('Update surface info in GUI', |
| 308 | 328 | (surface.index, surface.name, |
| 309 | 329 | surface.colour, surface.volume, | ... | ... |
invesalius/data/viewer_volume.py
| ... | ... | @@ -83,6 +83,8 @@ class Viewer(wx.Panel): |
| 83 | 83 | def __bind_events(self): |
| 84 | 84 | ps.Publisher().subscribe(self.LoadActor, |
| 85 | 85 | 'Load surface actor into viewer') |
| 86 | + ps.Publisher().subscribe(self.RemoveActor, | |
| 87 | + 'Remove surface actor from viewer') | |
| 86 | 88 | ps.Publisher().subscribe(self.UpdateRender, |
| 87 | 89 | 'Render volume viewer') |
| 88 | 90 | ps.Publisher().subscribe(self.ChangeBackgroundColour, |
| ... | ... | @@ -351,6 +353,15 @@ class Viewer(wx.Panel): |
| 351 | 353 | #self.ShowOrientationCube() |
| 352 | 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 | 365 | def LoadSlicePlane(self, pubsub_evt): |
| 355 | 366 | self.slice_plane = SlicePlane() |
| 356 | 367 | ... | ... |
invesalius/gui/data_notebook.py
| ... | ... | @@ -273,6 +273,8 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): |
| 273 | 273 | ps.Publisher().sendMessage('Show surface', (index, flag)) |
| 274 | 274 | |
| 275 | 275 | def AddSurface(self, pubsub_evt): |
| 276 | + | |
| 277 | + | |
| 276 | 278 | index = pubsub_evt.data[0] |
| 277 | 279 | name = pubsub_evt.data[1] |
| 278 | 280 | colour = pubsub_evt.data[2] |
| ... | ... | @@ -281,9 +283,19 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): |
| 281 | 283 | |
| 282 | 284 | image = self.CreateColourBitmap(colour) |
| 283 | 285 | image_index = self.imagelist.Add(image) |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + index_list = self.surface_list_index.keys() | |
| 284 | 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 | 300 | def InsertNewItem(self, index=0, label="Surface 1", volume="0 mm3", |
| 289 | 301 | transparency="0%%", colour=None): |
| ... | ... | @@ -293,6 +305,15 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): |
| 293 | 305 | self.SetStringItem(index, 2, volume) |
| 294 | 306 | self.SetStringItem(index, 3, transparency) |
| 295 | 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 | 318 | def CreateColourBitmap(self, colour): |
| 298 | 319 | """ | ... | ... |
invesalius/gui/task_slice.py
| ... | ... | @@ -106,17 +106,25 @@ class InnerTaskPanel(wx.Panel): |
| 106 | 106 | self.fold_panel = fold_panel |
| 107 | 107 | |
| 108 | 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 | 112 | if sys.platform != 'win32': |
| 111 | 113 | button_next.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) |
| 114 | + check_box.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) | |
| 112 | 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 | 123 | # Add line sizers into main sizer |
| 115 | 124 | main_sizer = wx.BoxSizer(wx.VERTICAL) |
| 116 | 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 | 128 | main_sizer.Fit(self) |
| 121 | 129 | |
| 122 | 130 | self.SetSizer(main_sizer) |
| ... | ... | @@ -130,9 +138,12 @@ class InnerTaskPanel(wx.Panel): |
| 130 | 138 | if id == BTN_NEW: |
| 131 | 139 | self.OnLinkNewMask() |
| 132 | 140 | |
| 141 | + | |
| 133 | 142 | def OnButtonNextTask(self, evt): |
| 143 | + overwrite = self.check_box.IsChecked() | |
| 134 | 144 | ps.Publisher().sendMessage('Create surface from index', |
| 135 | - self.GetMaskSelected()) | |
| 145 | + (self.GetMaskSelected(), | |
| 146 | + overwrite)) | |
| 136 | 147 | |
| 137 | 148 | def OnLinkNewMask(self, evt=None): |
| 138 | 149 | dlg = wx.TextEntryDialog(self, _('Name of new mask:'), | ... | ... |
invesalius/project.py
| ... | ... | @@ -130,6 +130,10 @@ class Project(object): |
| 130 | 130 | self.surface_dict[index] = surface |
| 131 | 131 | return index |
| 132 | 132 | |
| 133 | + def ChangeSurface(self, surface): | |
| 134 | + index = surface.index | |
| 135 | + self.surface_dict[index] = surface | |
| 136 | + | |
| 133 | 137 | def RemoveSurface(self, index): |
| 134 | 138 | new_dict = {} |
| 135 | 139 | for i in self.surface_dict: | ... | ... |