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""" | ... | ... |