Commit 22434229e7193fec2b24e511f44f8cfb0e0d035c
1 parent
b09b522f
Exists in
master
and in
68 other branches
ADD: Cross reference between slices
Showing
3 changed files
with
62 additions
and
22 deletions
Show diff stats
invesalius/constants.py
@@ -200,6 +200,7 @@ MODE_WW_WL = 4#:"Bright and contrast adjustment"} | @@ -200,6 +200,7 @@ MODE_WW_WL = 4#:"Bright and contrast adjustment"} | ||
200 | #### | 200 | #### |
201 | MODE_SLICE_SCROLL = -1 | 201 | MODE_SLICE_SCROLL = -1 |
202 | MODE_SLICE_EDITOR = -2 | 202 | MODE_SLICE_EDITOR = -2 |
203 | +MODE_SLICE_CROSS = -3 | ||
203 | 204 | ||
204 | ############ | 205 | ############ |
205 | 206 |
invesalius/data/viewer_slice.py
@@ -44,7 +44,7 @@ class Viewer(wx.Panel): | @@ -44,7 +44,7 @@ class Viewer(wx.Panel): | ||
44 | self.SetBackgroundColour(colour) | 44 | self.SetBackgroundColour(colour) |
45 | 45 | ||
46 | # Interactor additional style | 46 | # Interactor additional style |
47 | - self.modes = [] #['DEFAULT'] | 47 | + self.modes = []#['DEFAULT'] |
48 | self.mouse_pressed = 0 | 48 | self.mouse_pressed = 0 |
49 | 49 | ||
50 | # All renderers and image actors in this viewer | 50 | # All renderers and image actors in this viewer |
@@ -105,7 +105,7 @@ class Viewer(wx.Panel): | @@ -105,7 +105,7 @@ class Viewer(wx.Panel): | ||
105 | def SetLayout(self, layout): | 105 | def SetLayout(self, layout): |
106 | self.layout = layout | 106 | self.layout = layout |
107 | slice_ = sl.Slice() | 107 | slice_ = sl.Slice() |
108 | - self.load_renderers(slice_.GetOutput()) | 108 | + self.LoadRenderers(slice_.GetOutput()) |
109 | self.__configure_renderers() | 109 | self.__configure_renderers() |
110 | self.__configure_scroll() | 110 | self.__configure_scroll() |
111 | 111 | ||
@@ -132,10 +132,10 @@ class Viewer(wx.Panel): | @@ -132,10 +132,10 @@ class Viewer(wx.Panel): | ||
132 | self.modes.append(mode) | 132 | self.modes.append(mode) |
133 | 133 | ||
134 | # All modes and bindings | 134 | # All modes and bindings |
135 | - action = {'DEFAULT': { | 135 | + action = {'CROSS': { |
136 | "MouseMoveEvent": self.OnCrossMove, | 136 | "MouseMoveEvent": self.OnCrossMove, |
137 | - "LeftButtonPressEvent": self.OnMouseClick, | ||
138 | - "LeftButtonReleaseEvent": self.OnMouseRelease | 137 | + "LeftButtonPressEvent": self.OnCrossMouseClick, |
138 | + "LeftButtonReleaseEvent": self.OnCrossMouseRelease | ||
139 | }, | 139 | }, |
140 | 'EDITOR': { | 140 | 'EDITOR': { |
141 | "MouseMoveEvent": self.OnBrushMove, | 141 | "MouseMoveEvent": self.OnBrushMove, |
@@ -229,6 +229,11 @@ class Viewer(wx.Panel): | @@ -229,6 +229,11 @@ class Viewer(wx.Panel): | ||
229 | self.mouse_pressed = 0 | 229 | self.mouse_pressed = 0 |
230 | self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS)) | 230 | self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS)) |
231 | 231 | ||
232 | + def __set_mode_cross(self, pubsub_evt): | ||
233 | + self.append_mode('CROSS') | ||
234 | + self.mouse_pressed = 0 | ||
235 | + self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_NONE)) | ||
236 | + | ||
232 | def OnWindowLevelMove(self, evt, obj): | 237 | def OnWindowLevelMove(self, evt, obj): |
233 | if self.mouse_pressed: | 238 | if self.mouse_pressed: |
234 | position = self.interactor.GetLastEventPosition() | 239 | position = self.interactor.GetLastEventPosition() |
@@ -523,7 +528,6 @@ class Viewer(wx.Panel): | @@ -523,7 +528,6 @@ class Viewer(wx.Panel): | ||
523 | elif self._brush_cursor_op == const.BRUSH_THRESH: | 528 | elif self._brush_cursor_op == const.BRUSH_THRESH: |
524 | evt_msg = 'Edit mask pixel' | 529 | evt_msg = 'Edit mask pixel' |
525 | 530 | ||
526 | - self.__update_cross_position(*coord) | ||
527 | 531 | ||
528 | if self.mouse_pressed: | 532 | if self.mouse_pressed: |
529 | pixels = itertools.ifilter(self.test_operation_position, | 533 | pixels = itertools.ifilter(self.test_operation_position, |
@@ -533,17 +537,38 @@ class Viewer(wx.Panel): | @@ -533,17 +537,38 @@ class Viewer(wx.Panel): | ||
533 | self.interactor.Render() | 537 | self.interactor.Render() |
534 | 538 | ||
535 | def OnCrossMove(self, obj, evt_vtk): | 539 | def OnCrossMove(self, obj, evt_vtk): |
536 | - coord = self.get_coordinate() | ||
537 | # Update position in other slices | 540 | # Update position in other slices |
538 | if self.mouse_pressed: | 541 | if self.mouse_pressed: |
539 | - ps.Publisher().sendMessage('Update cursor position in slice', | ||
540 | - coord) | 542 | + mouse_x, mouse_y = self.interactor.GetEventPosition() |
543 | + renderer = self.slice_data_list[0].renderer | ||
544 | + self.pick.Pick(mouse_x, mouse_y, 0, renderer) | ||
545 | + coord_cross = self.get_coordinate_cursor() | ||
546 | + coord = self.get_coordinate() | ||
547 | + ps.Publisher().sendMessage('Update cross position', coord_cross) | ||
541 | ps.Publisher().sendMessage(('Set scroll position', 'SAGITAL'), | 548 | ps.Publisher().sendMessage(('Set scroll position', 'SAGITAL'), |
542 | - coord[0]) | 549 | + coord[0]) |
543 | ps.Publisher().sendMessage(('Set scroll position', 'CORONAL'), | 550 | ps.Publisher().sendMessage(('Set scroll position', 'CORONAL'), |
544 | - coord[1]) | 551 | + coord[1]) |
545 | ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), | 552 | ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), |
546 | - coord[2]) | 553 | + coord[2]) |
554 | + | ||
555 | + def OnCrossMouseClick(self, obj, evt_vtk): | ||
556 | + mouse_x, mouse_y = self.interactor.GetEventPosition() | ||
557 | + renderer = self.slice_data_list[0].renderer | ||
558 | + self.pick.Pick(mouse_x, mouse_y, 0, renderer) | ||
559 | + coord_cross = self.get_coordinate_cursor() | ||
560 | + coord = self.get_coordinate() | ||
561 | + ps.Publisher().sendMessage('Update cross position', coord_cross) | ||
562 | + ps.Publisher().sendMessage(('Set scroll position', 'SAGITAL'), | ||
563 | + coord[0]) | ||
564 | + ps.Publisher().sendMessage(('Set scroll position', 'CORONAL'), | ||
565 | + coord[1]) | ||
566 | + ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), | ||
567 | + coord[2]) | ||
568 | + self.mouse_pressed = 1 | ||
569 | + | ||
570 | + def OnCrossMouseRelease(self, obj, evt_vtk): | ||
571 | + self.mouse_pressed = 0 | ||
547 | 572 | ||
548 | def get_slice_data(self, render): | 573 | def get_slice_data(self, render): |
549 | for slice_data in self.slice_data_list: | 574 | for slice_data in self.slice_data_list: |
@@ -637,6 +662,8 @@ class Viewer(wx.Panel): | @@ -637,6 +662,8 @@ class Viewer(wx.Panel): | ||
637 | ps.Publisher().subscribe(self.ChangeSliceNumber, | 662 | ps.Publisher().subscribe(self.ChangeSliceNumber, |
638 | ('Set scroll position', | 663 | ('Set scroll position', |
639 | self.orientation)) | 664 | self.orientation)) |
665 | + ps.Publisher().subscribe(self.__update_cross_position, | ||
666 | + 'Update cross position') | ||
640 | ### | 667 | ### |
641 | ps.Publisher().subscribe(self.ChangeBrushSize, | 668 | ps.Publisher().subscribe(self.ChangeBrushSize, |
642 | 'Set edition brush size') | 669 | 'Set edition brush size') |
@@ -669,6 +696,9 @@ class Viewer(wx.Panel): | @@ -669,6 +696,9 @@ class Viewer(wx.Panel): | ||
669 | ps.Publisher().subscribe(self.__set_mode_window_level, | 696 | ps.Publisher().subscribe(self.__set_mode_window_level, |
670 | ('Set interaction mode', | 697 | ('Set interaction mode', |
671 | const.MODE_WW_WL)) | 698 | const.MODE_WW_WL)) |
699 | + ps.Publisher().subscribe(self.__set_mode_cross, | ||
700 | + ('Set interaction mode', | ||
701 | + const.MODE_SLICE_CROSS)) | ||
672 | #### | 702 | #### |
673 | ps.Publisher().subscribe(self.UpdateText,\ | 703 | ps.Publisher().subscribe(self.UpdateText,\ |
674 | 'Update window and level text') | 704 | 'Update window and level text') |
@@ -692,7 +722,7 @@ class Viewer(wx.Panel): | @@ -692,7 +722,7 @@ class Viewer(wx.Panel): | ||
692 | imagedata = pubsub_evt.data | 722 | imagedata = pubsub_evt.data |
693 | self.SetInput(imagedata) | 723 | self.SetInput(imagedata) |
694 | 724 | ||
695 | - def load_renderers(self, image): | 725 | + def LoadRenderers(self, image): |
696 | number_renderers = self.layout[0] * self.layout[1] | 726 | number_renderers = self.layout[0] * self.layout[1] |
697 | diff = number_renderers - len(self.slice_data_list) | 727 | diff = number_renderers - len(self.slice_data_list) |
698 | if diff > 0: | 728 | if diff > 0: |
@@ -744,7 +774,7 @@ class Viewer(wx.Panel): | @@ -744,7 +774,7 @@ class Viewer(wx.Panel): | ||
744 | 774 | ||
745 | #actor = vtk.vtkImageActor() | 775 | #actor = vtk.vtkImageActor() |
746 | #actor.SetInput(slice_.GetOutput()) | 776 | #actor.SetInput(slice_.GetOutput()) |
747 | - self.load_renderers(slice_.GetOutput()) | 777 | + self.LoadRenderers(slice_.GetOutput()) |
748 | self.__configure_renderers() | 778 | self.__configure_renderers() |
749 | ren = self.slice_data_list[0].renderer | 779 | ren = self.slice_data_list[0].renderer |
750 | actor = self.slice_data_list[0].actor | 780 | actor = self.slice_data_list[0].actor |
@@ -830,10 +860,12 @@ class Viewer(wx.Panel): | @@ -830,10 +860,12 @@ class Viewer(wx.Panel): | ||
830 | cross_actor.SetProperty(property) | 860 | cross_actor.SetProperty(property) |
831 | # Only the slices are pickable | 861 | # Only the slices are pickable |
832 | cross_actor.PickableOff() | 862 | cross_actor.PickableOff() |
863 | + self.cross_actor = cross_actor | ||
833 | 864 | ||
834 | renderer.AddActor(cross_actor) | 865 | renderer.AddActor(cross_actor) |
835 | 866 | ||
836 | - def __update_cross_position(self, x, y, z): | 867 | + def __update_cross_position(self, pubsub_evt): |
868 | + x, y, z = pubsub_evt.data | ||
837 | #xi, yi, zi = self.vline.GetPoint1() | 869 | #xi, yi, zi = self.vline.GetPoint1() |
838 | #xf, yf, zf = self.vline.GetPoint2() | 870 | #xf, yf, zf = self.vline.GetPoint2() |
839 | #self.vline.SetPoint1(x, yi, z) | 871 | #self.vline.SetPoint1(x, yi, z) |
@@ -863,7 +895,7 @@ class Viewer(wx.Panel): | @@ -863,7 +895,7 @@ class Viewer(wx.Panel): | ||
863 | else: | 895 | else: |
864 | coordinates = {"SAGITAL": yz, "CORONAL": xz, "AXIAL": xy} | 896 | coordinates = {"SAGITAL": yz, "CORONAL": xz, "AXIAL": xy} |
865 | 897 | ||
866 | - self.cross.SetFocalPoint(coordinates[self.orientation]) | 898 | + self.cross.SetFocalPoint(x, y, z) |
867 | 899 | ||
868 | 900 | ||
869 | #print slice_number | 901 | #print slice_number |
@@ -1012,10 +1044,10 @@ class Viewer(wx.Panel): | @@ -1012,10 +1044,10 @@ class Viewer(wx.Panel): | ||
1012 | "CORONAL": {1: slice_data.number}, | 1044 | "CORONAL": {1: slice_data.number}, |
1013 | "AXIAL": {2: slice_data.number}} | 1045 | "AXIAL": {2: slice_data.number}} |
1014 | 1046 | ||
1015 | - if 'DEFAULT' in self.modes: | ||
1016 | - ps.Publisher().sendMessage( | ||
1017 | - 'Update cursor single position in slice', | ||
1018 | - position[self.orientation]) | 1047 | + #if 'DEFAULT' in self.modes: |
1048 | + # ps.Publisher().sendMessage( | ||
1049 | + # 'Update cursor single position in slice', | ||
1050 | + # position[self.orientation]) | ||
1019 | 1051 | ||
1020 | def ChangeSliceNumber(self, pubsub_evt): | 1052 | def ChangeSliceNumber(self, pubsub_evt): |
1021 | index = pubsub_evt.data | 1053 | index = pubsub_evt.data |
invesalius/gui/frame.py
@@ -43,8 +43,9 @@ MODE_BY_ID = {ID_ZOOM: const.MODE_ZOOM, | @@ -43,8 +43,9 @@ MODE_BY_ID = {ID_ZOOM: const.MODE_ZOOM, | ||
43 | ID_CONTRAST: const.MODE_WW_WL} | 43 | ID_CONTRAST: const.MODE_WW_WL} |
44 | 44 | ||
45 | # Slice toolbar | 45 | # Slice toolbar |
46 | -SLICE_TOOLS = [ID_SLICE_SCROLL] = [wx.NewId() for number in range(1)] | ||
47 | -SLICE_MODE_BY_ID = {ID_SLICE_SCROLL: const.MODE_SLICE_SCROLL} | 46 | +SLICE_TOOLS = [ID_SLICE_SCROLL, ID_CROSS] = [wx.NewId() for number in range(2)] |
47 | +SLICE_MODE_BY_ID = {ID_SLICE_SCROLL: const.MODE_SLICE_SCROLL, | ||
48 | + ID_CROSS: const.MODE_SLICE_CROSS} | ||
48 | 49 | ||
49 | class Frame(wx.Frame): | 50 | class Frame(wx.Frame): |
50 | def __init__(self, prnt): | 51 | def __init__(self, prnt): |
@@ -508,9 +509,15 @@ class SliceToolBar(wx.ToolBar): | @@ -508,9 +509,15 @@ class SliceToolBar(wx.ToolBar): | ||
508 | BMP_SLICE = wx.Bitmap("../icons/slice.png", | 509 | BMP_SLICE = wx.Bitmap("../icons/slice.png", |
509 | wx.BITMAP_TYPE_PNG) | 510 | wx.BITMAP_TYPE_PNG) |
510 | 511 | ||
512 | + BMP_CROSS = wx.Bitmap("../icons/cross.png", | ||
513 | + wx.BITMAP_TYPE_PNG) | ||
514 | + | ||
511 | self.AddLabelTool(ID_SLICE_SCROLL, "Scroll slice", | 515 | self.AddLabelTool(ID_SLICE_SCROLL, "Scroll slice", |
512 | BMP_SLICE, kind = wx.ITEM_CHECK) | 516 | BMP_SLICE, kind = wx.ITEM_CHECK) |
513 | 517 | ||
518 | + self.AddLabelTool(ID_CROSS, "Cross", | ||
519 | + BMP_CROSS, kind = wx.ITEM_CHECK) | ||
520 | + | ||
514 | self.Realize() | 521 | self.Realize() |
515 | 522 | ||
516 | def __bind_events_wx(self): | 523 | def __bind_events_wx(self): |