Commit dbecc12e2349879b6d0e7056a0dff36771a35e52

Authored by Thiago Franco de Moraes
2 parents 9a71385e 0fb92927

Merge pull request #27 from tfmoraes/editor_improvements

Editor improvements
invesalius/constants.py
@@ -250,11 +250,15 @@ DEFAULT_BRUSH_FORMAT = BRUSH_CIRCLE @@ -250,11 +250,15 @@ DEFAULT_BRUSH_FORMAT = BRUSH_CIRCLE
250 BRUSH_DRAW = 0 250 BRUSH_DRAW = 0
251 BRUSH_ERASE = 1 251 BRUSH_ERASE = 1
252 BRUSH_THRESH = 2 252 BRUSH_THRESH = 2
  253 +BRUSH_THRESH_ERASE = 3
  254 +BRUSH_THRESH_ADD_ONLY = 4
  255 +BRUSH_THRESH_ERASE_ONLY = 5
253 DEFAULT_BRUSH_OP = BRUSH_THRESH 256 DEFAULT_BRUSH_OP = BRUSH_THRESH
254 BRUSH_OP_NAME = [_("Draw"), _("Erase"), _("Threshold")] 257 BRUSH_OP_NAME = [_("Draw"), _("Erase"), _("Threshold")]
255 258
256 BRUSH_COLOUR = (0,0,1.0) 259 BRUSH_COLOUR = (0,0,1.0)
257 BRUSH_SIZE = 30 260 BRUSH_SIZE = 30
  261 +BRUSH_MAX_SIZE = 100
258 262
259 # Surface creation values. Each element's list contains: 263 # Surface creation values. Each element's list contains:
260 # 0: imagedata reformat ratio 264 # 0: imagedata reformat ratio
invesalius/data/cursor_actors.py
@@ -78,6 +78,7 @@ class CursorBase(object): @@ -78,6 +78,7 @@ class CursorBase(object):
78 self.size = 15.0 78 self.size = 15.0
79 self.orientation = "AXIAL" 79 self.orientation = "AXIAL"
80 self.spacing = (1, 1, 1) 80 self.spacing = (1, 1, 1)
  81 + self.position = (0, 0, 0)
81 if vtk.vtkVersion().GetVTKVersion() > '5.8.0': 82 if vtk.vtkVersion().GetVTKVersion() > '5.8.0':
82 self.mapper = vtk.vtkImageSliceMapper() 83 self.mapper = vtk.vtkImageSliceMapper()
83 cursor_property = vtk.vtkImageProperty() 84 cursor_property = vtk.vtkImageProperty()
@@ -108,6 +109,7 @@ class CursorBase(object): @@ -108,6 +109,7 @@ class CursorBase(object):
108 def SetPosition(self, position): 109 def SetPosition(self, position):
109 # Overriding SetPosition method because in rectangles with odd 110 # Overriding SetPosition method because in rectangles with odd
110 # dimensions there is no half position. 111 # dimensions there is no half position.
  112 + self.position = position
111 px, py, pz = position 113 px, py, pz = position
112 sx, sy, sz = self.spacing 114 sx, sy, sz = self.spacing
113 tx = self.actor.GetXRange()[1] - self.actor.GetXRange()[0] 115 tx = self.actor.GetXRange()[1] - self.actor.GetXRange()[0]
invesalius/data/slice_.py
@@ -460,6 +460,13 @@ class Slice(object): @@ -460,6 +460,13 @@ class Slice(object):
460 # (1 * 253 + 1) and out ones gets value 1 (0 * 253 + 1). 460 # (1 * 253 + 1) and out ones gets value 1 (0 * 253 + 1).
461 roi_m[index] = (((roi_i[index] >= thresh_min) 461 roi_m[index] = (((roi_i[index] >= thresh_min)
462 & (roi_i[index] <= thresh_max)) * 253) + 1 462 & (roi_i[index] <= thresh_max)) * 253) + 1
  463 + elif operation == const.BRUSH_THRESH_ERASE:
  464 + roi_m[index] = (((roi_i[index] < thresh_min)
  465 + | (roi_i[index] > thresh_max)) * 253) + 1
  466 + elif operation == const.BRUSH_THRESH_ADD_ONLY:
  467 + roi_m[((index) & (roi_i >= thresh_min) & (roi_i <= thresh_max))] = 254
  468 + elif operation == const.BRUSH_THRESH_ERASE_ONLY:
  469 + roi_m[((index) & ((roi_i < thresh_min) | (roi_i > thresh_max)))] = 1
463 elif operation == const.BRUSH_DRAW: 470 elif operation == const.BRUSH_DRAW:
464 roi_m[index] = 254 471 roi_m[index] = 254
465 elif operation == const.BRUSH_ERASE: 472 elif operation == const.BRUSH_ERASE:
invesalius/data/styles.py
@@ -540,6 +540,11 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -540,6 +540,11 @@ class EditorInteractorStyle(DefaultInteractorStyle):
540 self.AddObserver("LeftButtonReleaseEvent", self.OnBrushRelease) 540 self.AddObserver("LeftButtonReleaseEvent", self.OnBrushRelease)
541 self.AddObserver("MouseMoveEvent", self.OnBrushMove) 541 self.AddObserver("MouseMoveEvent", self.OnBrushMove)
542 542
  543 + self.RemoveObservers("MouseWheelForwardEvent")
  544 + self.RemoveObservers("MouseWheelBackwardEvent")
  545 + self.AddObserver("MouseWheelForwardEvent",self.EOnScrollForward)
  546 + self.AddObserver("MouseWheelBackwardEvent", self.EOnScrollBackward)
  547 +
543 def OnEnterInteractor(self, obj, evt): 548 def OnEnterInteractor(self, obj, evt):
544 if (self.viewer.slice_.buffer_slices[self.orientation].mask is None): 549 if (self.viewer.slice_.buffer_slices[self.orientation].mask is None):
545 return 550 return
@@ -556,9 +561,26 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -556,9 +561,26 @@ class EditorInteractorStyle(DefaultInteractorStyle):
556 if (self.viewer.slice_.buffer_slices[self.orientation].mask is None): 561 if (self.viewer.slice_.buffer_slices[self.orientation].mask is None):
557 return 562 return
558 563
  564 +
559 viewer = self.viewer 565 viewer = self.viewer
560 iren = viewer.interactor 566 iren = viewer.interactor
561 567
  568 + operation = viewer._brush_cursor_op
  569 + if operation == const.BRUSH_THRESH:
  570 + if iren.GetControlKey():
  571 + if iren.GetShiftKey():
  572 + operation = const.BRUSH_THRESH_ERASE_ONLY
  573 + else:
  574 + operation = const.BRUSH_THRESH_ERASE
  575 + elif iren.GetShiftKey():
  576 + operation = const.BRUSH_THRESH_ADD_ONLY
  577 +
  578 + elif operation == const.BRUSH_ERASE and iren.GetControlKey():
  579 + operation = const.BRUSH_DRAW
  580 +
  581 + elif operation == const.BRUSH_DRAW and iren.GetControlKey():
  582 + operation = const.BRUSH_ERASE
  583 +
562 viewer._set_editor_cursor_visibility(1) 584 viewer._set_editor_cursor_visibility(1)
563 585
564 mouse_x, mouse_y = iren.GetEventPosition() 586 mouse_x, mouse_y = iren.GetEventPosition()
@@ -585,7 +607,7 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -585,7 +607,7 @@ class EditorInteractorStyle(DefaultInteractorStyle):
585 if position < 0: 607 if position < 0:
586 position = viewer.calculate_matrix_position(coord) 608 position = viewer.calculate_matrix_position(coord)
587 609
588 - viewer.slice_.edit_mask_pixel(viewer._brush_cursor_op, cursor.GetPixels(), 610 + viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(),
589 position, radius, viewer.orientation) 611 position, radius, viewer.orientation)
590 viewer._flush_buffer = True 612 viewer._flush_buffer = True
591 613
@@ -605,6 +627,22 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -605,6 +627,22 @@ class EditorInteractorStyle(DefaultInteractorStyle):
605 render = iren.FindPokedRenderer(mouse_x, mouse_y) 627 render = iren.FindPokedRenderer(mouse_x, mouse_y)
606 slice_data = viewer.get_slice_data(render) 628 slice_data = viewer.get_slice_data(render)
607 629
  630 + operation = viewer._brush_cursor_op
  631 + if operation == const.BRUSH_THRESH:
  632 + if iren.GetControlKey():
  633 + if iren.GetShiftKey():
  634 + operation = const.BRUSH_THRESH_ERASE_ONLY
  635 + else:
  636 + operation = const.BRUSH_THRESH_ERASE
  637 + elif iren.GetShiftKey():
  638 + operation = const.BRUSH_THRESH_ADD_ONLY
  639 +
  640 + elif operation == const.BRUSH_ERASE and iren.GetControlKey():
  641 + operation = const.BRUSH_DRAW
  642 +
  643 + elif operation == const.BRUSH_DRAW and iren.GetControlKey():
  644 + operation = const.BRUSH_ERASE
  645 +
608 # TODO: Improve! 646 # TODO: Improve!
609 #for i in self.slice_data_list: 647 #for i in self.slice_data_list:
610 #i.cursor.Show(0) 648 #i.cursor.Show(0)
@@ -635,7 +673,7 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -635,7 +673,7 @@ class EditorInteractorStyle(DefaultInteractorStyle):
635 if position < 0: 673 if position < 0:
636 position = viewer.calculate_matrix_position(coord) 674 position = viewer.calculate_matrix_position(coord)
637 675
638 - viewer.slice_.edit_mask_pixel(viewer._brush_cursor_op, cursor.GetPixels(), 676 + viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(),
639 position, radius, self.orientation) 677 position, radius, self.orientation)
640 # TODO: To create a new function to reload images to viewer. 678 # TODO: To create a new function to reload images to viewer.
641 viewer.OnScrollBar(update3D=False) 679 viewer.OnScrollBar(update3D=False)
@@ -650,6 +688,39 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -650,6 +688,39 @@ class EditorInteractorStyle(DefaultInteractorStyle):
650 self.viewer.slice_.apply_slice_buffer_to_mask(self.orientation) 688 self.viewer.slice_.apply_slice_buffer_to_mask(self.orientation)
651 self.viewer._flush_buffer = False 689 self.viewer._flush_buffer = False
652 690
  691 + def EOnScrollForward(self, evt, obj):
  692 + iren = self.viewer.interactor
  693 + if iren.GetControlKey():
  694 + mouse_x, mouse_y = iren.GetEventPosition()
  695 + render = iren.FindPokedRenderer(mouse_x, mouse_y)
  696 + slice_data = self.viewer.get_slice_data(render)
  697 + cursor = slice_data.cursor
  698 + size = cursor.radius * 2
  699 +
  700 + if size < 100:
  701 + Publisher.sendMessage('Set edition brush size', size + 1)
  702 + cursor.SetPosition(cursor.position)
  703 + self.viewer.interactor.Render()
  704 +
  705 + else:
  706 + self.OnScrollForward(obj, evt)
  707 +
  708 + def EOnScrollBackward(self, evt, obj):
  709 + iren = self.viewer.interactor
  710 + if iren.GetControlKey():
  711 + mouse_x, mouse_y = iren.GetEventPosition()
  712 + render = iren.FindPokedRenderer(mouse_x, mouse_y)
  713 + slice_data = self.viewer.get_slice_data(render)
  714 + cursor = slice_data.cursor
  715 + size = cursor.radius * 2
  716 +
  717 + if size > 0:
  718 + Publisher.sendMessage('Set edition brush size', size - 1)
  719 + cursor.SetPosition(cursor.position)
  720 + self.viewer.interactor.Render()
  721 + else:
  722 + self.OnScrollBackward(obj, evt)
  723 +
653 def get_coordinate_cursor(self): 724 def get_coordinate_cursor(self):
654 # Find position 725 # Find position
655 x, y, z = self.picker.GetPickPosition() 726 x, y, z = self.picker.GetPickPosition()