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 250 BRUSH_DRAW = 0
251 251 BRUSH_ERASE = 1
252 252 BRUSH_THRESH = 2
  253 +BRUSH_THRESH_ERASE = 3
  254 +BRUSH_THRESH_ADD_ONLY = 4
  255 +BRUSH_THRESH_ERASE_ONLY = 5
253 256 DEFAULT_BRUSH_OP = BRUSH_THRESH
254 257 BRUSH_OP_NAME = [_("Draw"), _("Erase"), _("Threshold")]
255 258  
256 259 BRUSH_COLOUR = (0,0,1.0)
257 260 BRUSH_SIZE = 30
  261 +BRUSH_MAX_SIZE = 100
258 262  
259 263 # Surface creation values. Each element's list contains:
260 264 # 0: imagedata reformat ratio
... ...
invesalius/data/cursor_actors.py
... ... @@ -78,6 +78,7 @@ class CursorBase(object):
78 78 self.size = 15.0
79 79 self.orientation = "AXIAL"
80 80 self.spacing = (1, 1, 1)
  81 + self.position = (0, 0, 0)
81 82 if vtk.vtkVersion().GetVTKVersion() > '5.8.0':
82 83 self.mapper = vtk.vtkImageSliceMapper()
83 84 cursor_property = vtk.vtkImageProperty()
... ... @@ -108,6 +109,7 @@ class CursorBase(object):
108 109 def SetPosition(self, position):
109 110 # Overriding SetPosition method because in rectangles with odd
110 111 # dimensions there is no half position.
  112 + self.position = position
111 113 px, py, pz = position
112 114 sx, sy, sz = self.spacing
113 115 tx = self.actor.GetXRange()[1] - self.actor.GetXRange()[0]
... ...
invesalius/data/slice_.py
... ... @@ -460,6 +460,13 @@ class Slice(object):
460 460 # (1 * 253 + 1) and out ones gets value 1 (0 * 253 + 1).
461 461 roi_m[index] = (((roi_i[index] >= thresh_min)
462 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 470 elif operation == const.BRUSH_DRAW:
464 471 roi_m[index] = 254
465 472 elif operation == const.BRUSH_ERASE:
... ...
invesalius/data/styles.py
... ... @@ -540,6 +540,11 @@ class EditorInteractorStyle(DefaultInteractorStyle):
540 540 self.AddObserver("LeftButtonReleaseEvent", self.OnBrushRelease)
541 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 548 def OnEnterInteractor(self, obj, evt):
544 549 if (self.viewer.slice_.buffer_slices[self.orientation].mask is None):
545 550 return
... ... @@ -556,9 +561,26 @@ class EditorInteractorStyle(DefaultInteractorStyle):
556 561 if (self.viewer.slice_.buffer_slices[self.orientation].mask is None):
557 562 return
558 563  
  564 +
559 565 viewer = self.viewer
560 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 584 viewer._set_editor_cursor_visibility(1)
563 585  
564 586 mouse_x, mouse_y = iren.GetEventPosition()
... ... @@ -585,7 +607,7 @@ class EditorInteractorStyle(DefaultInteractorStyle):
585 607 if position < 0:
586 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 611 position, radius, viewer.orientation)
590 612 viewer._flush_buffer = True
591 613  
... ... @@ -605,6 +627,22 @@ class EditorInteractorStyle(DefaultInteractorStyle):
605 627 render = iren.FindPokedRenderer(mouse_x, mouse_y)
606 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 646 # TODO: Improve!
609 647 #for i in self.slice_data_list:
610 648 #i.cursor.Show(0)
... ... @@ -635,7 +673,7 @@ class EditorInteractorStyle(DefaultInteractorStyle):
635 673 if position < 0:
636 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 677 position, radius, self.orientation)
640 678 # TODO: To create a new function to reload images to viewer.
641 679 viewer.OnScrollBar(update3D=False)
... ... @@ -650,6 +688,39 @@ class EditorInteractorStyle(DefaultInteractorStyle):
650 688 self.viewer.slice_.apply_slice_buffer_to_mask(self.orientation)
651 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 724 def get_coordinate_cursor(self):
654 725 # Find position
655 726 x, y, z = self.picker.GetPickPosition()
... ...