Commit 7f23d9efe7e270c59e4da6d728dcf39bcba5dff8
1 parent
b4ead449
Exists in
master
and in
68 other branches
ADD: Brush add, remove and threshold operations are working
Showing
3 changed files
with
83 additions
and
47 deletions
Show diff stats
invesalius/data/slice_.py
| ... | ... | @@ -21,8 +21,8 @@ class Slice(object): |
| 21 | 21 | |
| 22 | 22 | def __bind_events(self): |
| 23 | 23 | ps.Publisher().subscribe(self.SetThresholdRange, 'Set threshold values') |
| 24 | - #ps.Publisher().subscribe(self.SetEditionThresholdRange, | |
| 25 | - # 'Set edition threshold values') | |
| 24 | + ps.Publisher().subscribe(self.SetEditionThresholdRange, | |
| 25 | + 'Set edition threshold values') | |
| 26 | 26 | ps.Publisher().subscribe(self.OnChangeCurrentMaskColour, |
| 27 | 27 | 'Change mask colour') |
| 28 | 28 | ps.Publisher().subscribe(self.AddMask, 'Create new mask') |
| ... | ... | @@ -34,12 +34,21 @@ class Slice(object): |
| 34 | 34 | ps.Publisher().subscribe(self.ShowMask, 'Show mask') |
| 35 | 35 | ps.Publisher().subscribe(self.ChangeMaskName, 'Change mask name') |
| 36 | 36 | ps.Publisher().subscribe(self.EraseMaskPixel, 'Erase mask pixel') |
| 37 | - | |
| 37 | + ps.Publisher().subscribe(self.EditMaskPixel, 'Edit mask pixel') | |
| 38 | + ps.Publisher().subscribe(self.AddMaskPixel, 'Add mask pixel') | |
| 38 | 39 | |
| 39 | 40 | def EraseMaskPixel(self, pubsub_evt): |
| 40 | 41 | position = pubsub_evt.data |
| 41 | 42 | self.ErasePixel(position) |
| 42 | 43 | |
| 44 | + def EditMaskPixel(self, pubsub_evt): | |
| 45 | + position = pubsub_evt.data | |
| 46 | + self.EditPixelBasedOnThreshold(position) | |
| 47 | + | |
| 48 | + def AddMaskPixel(self, pubsub_evt): | |
| 49 | + position = pubsub_evt.data | |
| 50 | + self.DrawPixel(position) | |
| 51 | + | |
| 43 | 52 | def ChangeMaskName(self, pubsub_evt): |
| 44 | 53 | index, name = pubsub_evt.data |
| 45 | 54 | |
| ... | ... | @@ -362,43 +371,41 @@ class Slice(object): |
| 362 | 371 | self.current_mask.threshold_range)) |
| 363 | 372 | ps.Publisher().sendMessage('Update slice viewer') |
| 364 | 373 | |
| 365 | - #def SetEditionThresholdRange(self, evt): | |
| 366 | - # thresh_min, thresh_max = evt.data | |
| 367 | - # self.current_mask.edition_threshold_range = thresh_min, thresh_max | |
| 374 | + def SetEditionThresholdRange(self, evt_pubsub): | |
| 375 | + if self.current_mask: | |
| 376 | + thresh_min, thresh_max = evt_pubsub.data | |
| 377 | + self.current_mask.edition_threshold_range = thresh_min, thresh_max | |
| 368 | 378 | |
| 369 | 379 | def ErasePixel(self, position): |
| 370 | 380 | """ |
| 371 | 381 | Delete pixel, based on x, y and z position coordinates. |
| 372 | 382 | """ |
| 373 | 383 | x, y, z = position |
| 374 | - imagedata = self.current_mask.imagedata | |
| 375 | 384 | colour = self.imagedata.GetScalarRange()[0]# - 1 # Important to effect erase |
| 385 | + imagedata = self.current_mask.imagedata | |
| 376 | 386 | imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour) |
| 377 | 387 | imagedata.Update() |
| 378 | 388 | |
| 379 | - def DrawPixel(self, x, y, z, colour=None): | |
| 389 | + def DrawPixel(self, position, colour=None): | |
| 380 | 390 | """ |
| 381 | 391 | Draw pixel, based on x, y and z position coordinates. |
| 382 | 392 | """ |
| 383 | - imagedata = self.current_mask.imagedata | |
| 384 | - if colour is None: | |
| 393 | + x, y, z = position | |
| 394 | + if not colour: | |
| 385 | 395 | colour = self.imagedata.GetScalarRange()[1] |
| 396 | + imagedata = self.current_mask.imagedata | |
| 386 | 397 | imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour) |
| 398 | + imagedata.Update() | |
| 387 | 399 | |
| 388 | - def EditPixelBasedOnThreshold(self, x, y, z): | |
| 400 | + def EditPixelBasedOnThreshold(self, position): | |
| 389 | 401 | """ |
| 390 | 402 | Erase or draw pixel based on edition threshold range. |
| 391 | 403 | """ |
| 392 | - | |
| 393 | - pixel_colour = imagedata.GetScalarComponentAsDouble(x, y, z, 0) | |
| 404 | + x, y, z = position | |
| 405 | + colour = self.imagedata.GetScalarComponentAsDouble(x, y, z, 0) | |
| 394 | 406 | thresh_min, thresh_max = self.current_mask.edition_threshold_range |
| 395 | 407 | |
| 396 | - if (pixel_colour >= thresh_min) and (pixel_colour <= thresh_max): | |
| 397 | - self.DrawPixel(x, y, z, pixel_colour) | |
| 398 | - # TODO: See if the code bellow is really necessary | |
| 399 | - #if (pixel_colour <= 0): | |
| 400 | - # self.DrawPixel(x, y, z, 1) | |
| 401 | - #else: | |
| 402 | - # self.DrawPixel(x, y, z, pixel_colour) | |
| 408 | + if (colour >= thresh_min) and (colour <= thresh_max): | |
| 409 | + self.DrawPixel(position, colour) | |
| 403 | 410 | else: |
| 404 | - self.ErasePixel(x, y, z) | |
| 411 | + self.ErasePixel(position) | ... | ... |
invesalius/data/viewer_slice.py
| ... | ... | @@ -45,6 +45,9 @@ class Viewer(wx.Panel): |
| 45 | 45 | self.orientation = orientation |
| 46 | 46 | self.slice_number = 0 |
| 47 | 47 | |
| 48 | + self._brush_cursor_op = 'Draw' | |
| 49 | + self.brush_cursor_size = 30 | |
| 50 | + | |
| 48 | 51 | # VTK pipeline and actors |
| 49 | 52 | self.__config_interactor() |
| 50 | 53 | self.pick = vtk.vtkCellPicker() |
| ... | ... | @@ -184,11 +187,19 @@ class Viewer(wx.Panel): |
| 184 | 187 | self.cursor.SetPosition(coord) |
| 185 | 188 | self.cursor.SetEditionPosition(self.GetCoordinateCursorEdition()) |
| 186 | 189 | self.ren.Render() |
| 190 | + | |
| 191 | + if self._brush_cursor_op == 'Erase': | |
| 192 | + evt_msg = 'Erase mask pixel' | |
| 193 | + elif self._brush_cursor_op == 'Draw': | |
| 194 | + evt_msg = 'Add mask pixel' | |
| 195 | + elif self._brush_cursor_op == 'Threshold': | |
| 196 | + evt_msg = 'Edit mask pixel' | |
| 197 | + | |
| 187 | 198 | if self.mouse_pressed: |
| 188 | 199 | print "Edit pixel region based on origin:", coord |
| 189 | 200 | pixels = self.cursor.GetPixels() |
| 190 | 201 | for coord in pixels: |
| 191 | - ps.Publisher().sendMessage('Erase mask pixel', coord) | |
| 202 | + ps.Publisher().sendMessage(evt_msg, coord) | |
| 192 | 203 | self.interactor.Render() |
| 193 | 204 | |
| 194 | 205 | def OnCrossMove(self, obj, evt_vtk): |
| ... | ... | @@ -300,6 +311,12 @@ class Viewer(wx.Panel): |
| 300 | 311 | ps.Publisher().subscribe(self.ChangeBrushSize,'Set edition brush size') |
| 301 | 312 | ps.Publisher().subscribe(self.ChangeBrushColour, 'Add mask') |
| 302 | 313 | ps.Publisher().subscribe(self.ChangeBrushActor, 'Set brush format') |
| 314 | + ps.Publisher().subscribe(self.ChangeBrushOperation, 'Set edition operation') | |
| 315 | + | |
| 316 | + | |
| 317 | + def ChangeBrushOperation(self, pubsub_evt): | |
| 318 | + print pubsub_evt.data | |
| 319 | + self._brush_cursor_op = pubsub_evt.data | |
| 303 | 320 | |
| 304 | 321 | def __bind_events_wx(self): |
| 305 | 322 | self.scroll.Bind(wx.EVT_SCROLL, self.OnScrollBar) |
| ... | ... | @@ -409,7 +426,7 @@ class Viewer(wx.Panel): |
| 409 | 426 | def SetColour(self, pubsub_evt): |
| 410 | 427 | colour_wx = pubsub_evt.data |
| 411 | 428 | colour_vtk = [colour/float(255) for colour in colour_wx] |
| 412 | - self._brush_cursor_colour = vtk_colour | |
| 429 | + self._brush_cursor_colour = colour_vtk | |
| 413 | 430 | self.cursor.SetColour(colour_vtk) |
| 414 | 431 | self.interactor.Render() |
| 415 | 432 | ... | ... |
invesalius/gui/task_slice.py
| ... | ... | @@ -303,7 +303,8 @@ class MaskProperties(wx.Panel): |
| 303 | 303 | index, name = pubsub_evt.data |
| 304 | 304 | self.combo_mask_name.SetString(index, name) |
| 305 | 305 | self.combo_mask_name.Refresh() |
| 306 | - | |
| 306 | + | |
| 307 | + | |
| 307 | 308 | def SetThresholdValues(self, pubsub_evt): |
| 308 | 309 | thresh_min, thresh_max = pubsub_evt.data |
| 309 | 310 | self.bind_evt_gradient = False |
| ... | ... | @@ -421,6 +422,7 @@ class EditionTools(wx.Panel): |
| 421 | 422 | gradient_thresh = grad.GradientSlider(self, -1, 0, 5000, 0, 5000, |
| 422 | 423 | (0, 0, 255, 100)) |
| 423 | 424 | self.gradient_thresh = gradient_thresh |
| 425 | + self.bind_evt_gradient = True | |
| 424 | 426 | |
| 425 | 427 | # Add lines into main sizer |
| 426 | 428 | sizer = wx.BoxSizer(wx.VERTICAL) |
| ... | ... | @@ -439,38 +441,48 @@ class EditionTools(wx.Panel): |
| 439 | 441 | |
| 440 | 442 | |
| 441 | 443 | def __bind_events_wx(self): |
| 442 | - pass | |
| 443 | - #self.Bind(grad.EVT_THRESHOLD_CHANGE, self.OnGradientChanged, | |
| 444 | - # self.gradient_thresh) | |
| 444 | + self.Bind(grad.EVT_THRESHOLD_CHANGE, self.OnGradientChanged, | |
| 445 | + self.gradient_thresh) | |
| 445 | 446 | |
| 446 | 447 | def __bind_events(self): |
| 447 | - #ps.Publisher().subscribe(self.SetThresholdBounds, | |
| 448 | - # 'Update threshold limits') | |
| 448 | + ps.Publisher().subscribe(self.SetThresholdBounds, | |
| 449 | + 'Update threshold limits') | |
| 449 | 450 | #ps.Publisher().subscribe(self.SetThresholdValues, |
| 450 | 451 | # 'Set threshold values in gradient') |
| 451 | 452 | ps.Publisher().subscribe(self.ChangeMaskColour, 'Change mask colour') |
| 453 | + ps.Publisher().subscribe(self.SetGradientColour, 'Add mask') | |
| 452 | 454 | |
| 453 | 455 | def ChangeMaskColour(self, pubsub_evt): |
| 454 | 456 | colour = pubsub_evt.data |
| 455 | 457 | self.gradient_thresh.SetColour(colour) |
| 456 | - | |
| 457 | - #def SetThresholdValues(self, pubsub_evt): | |
| 458 | - # thresh_min = pubsub_evt.data[0][0] | |
| 459 | - # thresh_max = pubsub_evt.data[0][1] | |
| 460 | - # self.gradient_thresh.SetMinValue(thresh_min) | |
| 461 | - # self.gradient_thresh.SetMaxValue(thresh_max) | |
| 462 | - | |
| 463 | - #def SetThresholdBounds(self, pubsub_evt): | |
| 464 | - # thresh_min = pubsub_evt.data[0] | |
| 465 | - # thresh_max = pubsub_evt.data[1] | |
| 466 | - # self.gradient_thresh.SetMinRange(thresh_min) | |
| 467 | - # self.gradient_thresh.SetMaxRange(thresh_max) | |
| 468 | - | |
| 469 | - #def OnGradientChanged(self, evt): | |
| 470 | - # thresh_min = self.gradient_thresh.GetMinValue() | |
| 471 | - # thresh_max = self.gradient_thresh.GetMaxValue() | |
| 472 | - # #ps.Publisher().sendMessage('Set edition threshold values', | |
| 473 | - # # (thresh_min, thresh_max)) | |
| 458 | + | |
| 459 | + def SetGradientColour(self, pubsub_evt): | |
| 460 | + vtk_colour = pubsub_evt.data[3] | |
| 461 | + wx_colour = [c*255 for c in vtk_colour] | |
| 462 | + self.gradient_thresh.SetColour(wx_colour) | |
| 463 | + | |
| 464 | + def SetThresholdValues(self, pubsub_evt): | |
| 465 | + thresh_min, thresh_max = pubsub_evt.data | |
| 466 | + self.bind_evt_gradient = False | |
| 467 | + self.gradient_thresh.SetMinValue(thresh_min) | |
| 468 | + self.gradient_thresh.SetMaxValue(thresh_max) | |
| 469 | + self.bind_evt_gradient = True | |
| 470 | + | |
| 471 | + def SetThresholdBounds(self, pubsub_evt): | |
| 472 | + thresh_min = pubsub_evt.data[0] | |
| 473 | + thresh_max = pubsub_evt.data[1] | |
| 474 | + print thresh_min, thresh_max | |
| 475 | + self.gradient_thresh.SetMinRange(thresh_min) | |
| 476 | + self.gradient_thresh.SetMaxRange(thresh_max) | |
| 477 | + self.gradient_thresh.SetMinValue(thresh_min) | |
| 478 | + self.gradient_thresh.SetMaxValue(thresh_max) | |
| 479 | + | |
| 480 | + def OnGradientChanged(self, evt): | |
| 481 | + thresh_min = self.gradient_thresh.GetMinValue() | |
| 482 | + thresh_max = self.gradient_thresh.GetMaxValue() | |
| 483 | + if self.bind_evt_gradient: | |
| 484 | + ps.Publisher().sendMessage('Set edition threshold values', | |
| 485 | + (thresh_min, thresh_max)) | |
| 474 | 486 | |
| 475 | 487 | def OnMenu(self, evt): |
| 476 | 488 | """Button's menu event""" | ... | ... |