Commit 47e6e1c3b050796669e062561d42c0d38b850963
1 parent
33e51c02
Exists in
master
and in
67 other branches
Merging cross branch improvements to master
Showing
1 changed file
with
69 additions
and
238 deletions
Show diff stats
invesalius/data/viewer_slice.py
@@ -29,7 +29,6 @@ from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor | @@ -29,7 +29,6 @@ from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor | ||
29 | import wx | 29 | import wx |
30 | import wx.lib.pubsub as ps | 30 | import wx.lib.pubsub as ps |
31 | 31 | ||
32 | - | ||
33 | import constants as const | 32 | import constants as const |
34 | import cursor_actors as ca | 33 | import cursor_actors as ca |
35 | import data.slice_ as sl | 34 | import data.slice_ as sl |
@@ -62,6 +61,7 @@ class Viewer(wx.Panel): | @@ -62,6 +61,7 @@ class Viewer(wx.Panel): | ||
62 | self.left_pressed = 0 | 61 | self.left_pressed = 0 |
63 | self.right_pressed = 0 | 62 | self.right_pressed = 0 |
64 | self.last_position_mouse_move = () | 63 | self.last_position_mouse_move = () |
64 | + self.state = const.STATE_DEFAULT | ||
65 | 65 | ||
66 | # All renderers and image actors in this viewer | 66 | # All renderers and image actors in this viewer |
67 | self.slice_data_list = [] | 67 | self.slice_data_list = [] |
@@ -90,13 +90,12 @@ class Viewer(wx.Panel): | @@ -90,13 +90,12 @@ class Viewer(wx.Panel): | ||
90 | self.on_text = False | 90 | self.on_text = False |
91 | # VTK pipeline and actors | 91 | # VTK pipeline and actors |
92 | self.__config_interactor() | 92 | self.__config_interactor() |
93 | - self.pick = vtk.vtkWorldPointPicker() | ||
94 | self.cross_actor = vtk.vtkActor() | 93 | self.cross_actor = vtk.vtkActor() |
95 | 94 | ||
96 | - | ||
97 | self.__bind_events() | 95 | self.__bind_events() |
98 | self.__bind_events_wx() | 96 | self.__bind_events_wx() |
99 | - | 97 | + |
98 | + self._warped = False | ||
100 | 99 | ||
101 | def __init_gui(self): | 100 | def __init_gui(self): |
102 | interactor = wxVTKRenderWindowInteractor(self, -1, size=self.GetSize()) | 101 | interactor = wxVTKRenderWindowInteractor(self, -1, size=self.GetSize()) |
@@ -117,15 +116,16 @@ class Viewer(wx.Panel): | @@ -117,15 +116,16 @@ class Viewer(wx.Panel): | ||
117 | self.SetAutoLayout(1) | 116 | self.SetAutoLayout(1) |
118 | 117 | ||
119 | self.interactor = interactor | 118 | self.interactor = interactor |
119 | + self.pick = vtk.vtkWorldPointPicker() | ||
120 | + | ||
121 | + self.interactor.SetPicker(self.pick) | ||
120 | 122 | ||
121 | def OnContextMenu(self, evt): | 123 | def OnContextMenu(self, evt): |
122 | self.right_pressed = 0 | 124 | self.right_pressed = 0 |
123 | if (self.last_position_mouse_move ==\ | 125 | if (self.last_position_mouse_move ==\ |
124 | self.interactor.GetLastEventPosition()): | 126 | self.interactor.GetLastEventPosition()): |
125 | self.PopupMenu(self.menu) | 127 | self.PopupMenu(self.menu) |
126 | - | ||
127 | evt.Skip() | 128 | evt.Skip() |
128 | - | ||
129 | 129 | ||
130 | def SetPopupMenu(self, menu): | 130 | def SetPopupMenu(self, menu): |
131 | self.menu = menu | 131 | self.menu = menu |
@@ -158,7 +158,6 @@ class Viewer(wx.Panel): | @@ -158,7 +158,6 @@ class Viewer(wx.Panel): | ||
158 | self.interactor.Render() | 158 | self.interactor.Render() |
159 | self.on_text = True | 159 | self.on_text = True |
160 | 160 | ||
161 | - | ||
162 | def __set_layout(self, pubsub_evt): | 161 | def __set_layout(self, pubsub_evt): |
163 | layout = pubsub_evt.data | 162 | layout = pubsub_evt.data |
164 | self.SetLayout(layout) | 163 | self.SetLayout(layout) |
@@ -173,8 +172,8 @@ class Viewer(wx.Panel): | @@ -173,8 +172,8 @@ class Viewer(wx.Panel): | ||
173 | self.state = state | 172 | self.state = state |
174 | action = {const.SLICE_STATE_CROSS: | 173 | action = {const.SLICE_STATE_CROSS: |
175 | { | 174 | { |
176 | - "MouseMoveEvent": self.OnCrossMove, | ||
177 | - "LeftButtonPressEvent": self.OnCrossMouseClick, | 175 | + "MouseMoveEvent": self.OnCrossMove, |
176 | + "LeftButtonPressEvent": self.OnCrossMouseClick, | ||
178 | }, | 177 | }, |
179 | const.SLICE_STATE_EDITOR: | 178 | const.SLICE_STATE_EDITOR: |
180 | { | 179 | { |
@@ -238,9 +237,7 @@ class Viewer(wx.Panel): | @@ -238,9 +237,7 @@ class Viewer(wx.Panel): | ||
238 | self.on_wl = False | 237 | self.on_wl = False |
239 | self.wl_text.Hide() | 238 | self.wl_text.Hide() |
240 | 239 | ||
241 | - | ||
242 | self.__set_editor_cursor_visibility(0) | 240 | self.__set_editor_cursor_visibility(0) |
243 | - | ||
244 | 241 | ||
245 | # Bind method according to current mode | 242 | # Bind method according to current mode |
246 | if(state == const.STATE_ZOOM_SL): | 243 | if(state == const.STATE_ZOOM_SL): |
@@ -347,7 +344,6 @@ class Viewer(wx.Panel): | @@ -347,7 +344,6 @@ class Viewer(wx.Panel): | ||
347 | ps.Publisher().sendMessage('Update slice viewer') | 344 | ps.Publisher().sendMessage('Update slice viewer') |
348 | ps.Publisher().sendMessage('Render volume viewer') | 345 | ps.Publisher().sendMessage('Render volume viewer') |
349 | 346 | ||
350 | - | ||
351 | def OnWindowLevelClick(self, evt, obj): | 347 | def OnWindowLevelClick(self, evt, obj): |
352 | self.last_x, self.last_y = self.interactor.GetLastEventPosition() | 348 | self.last_x, self.last_y = self.interactor.GetLastEventPosition() |
353 | 349 | ||
@@ -375,7 +371,6 @@ class Viewer(wx.Panel): | @@ -375,7 +371,6 @@ class Viewer(wx.Panel): | ||
375 | 371 | ||
376 | self.scroll.SetThumbPosition(self.acum_achange_slice) | 372 | self.scroll.SetThumbPosition(self.acum_achange_slice) |
377 | self.OnScrollBar() | 373 | self.OnScrollBar() |
378 | - | ||
379 | 374 | ||
380 | def OnChangeSliceClick(self, evt, obj): | 375 | def OnChangeSliceClick(self, evt, obj): |
381 | position = list(self.interactor.GetLastEventPosition()) | 376 | position = list(self.interactor.GetLastEventPosition()) |
@@ -398,7 +393,6 @@ class Viewer(wx.Panel): | @@ -398,7 +393,6 @@ class Viewer(wx.Panel): | ||
398 | def OnVtkRightRelease(self, evt, obj): | 393 | def OnVtkRightRelease(self, evt, obj): |
399 | evt.OnRightButtonUp() | 394 | evt.OnRightButtonUp() |
400 | 395 | ||
401 | - | ||
402 | def OnUnZoom(self, evt, obj = None): | 396 | def OnUnZoom(self, evt, obj = None): |
403 | mouse_x, mouse_y = self.interactor.GetLastEventPosition() | 397 | mouse_x, mouse_y = self.interactor.GetLastEventPosition() |
404 | ren = self.interactor.FindPokedRenderer(mouse_x, mouse_y) | 398 | ren = self.interactor.FindPokedRenderer(mouse_x, mouse_y) |
@@ -496,74 +490,9 @@ class Viewer(wx.Panel): | @@ -496,74 +490,9 @@ class Viewer(wx.Panel): | ||
496 | ren = slice_data.renderer | 490 | ren = slice_data.renderer |
497 | size = ren.GetSize() | 491 | size = ren.GetSize() |
498 | 492 | ||
499 | - | ||
500 | ren.ResetCamera() | 493 | ren.ResetCamera() |
501 | ren.GetActiveCamera().Zoom(1.0) | 494 | ren.GetActiveCamera().Zoom(1.0) |
502 | self.interactor.Render() | 495 | self.interactor.Render() |
503 | - #self.interactor.GetRenderWindow().Render() | ||
504 | - | ||
505 | - | ||
506 | - #if (size[0] <= size[1] + 60): | ||
507 | - # Code bellow doesn't work for Promed 0013 | ||
508 | - """ | ||
509 | - if 0: | ||
510 | - | ||
511 | - bound = slice_data.actor.GetBounds() | ||
512 | - | ||
513 | - width = abs((bound[3] - bound[2]) * -1) | ||
514 | - height = abs((bound[1] - bound[0]) * -1) | ||
515 | - | ||
516 | - origin = ren.GetOrigin() | ||
517 | - cam = ren.GetActiveCamera() | ||
518 | - | ||
519 | - min = [] | ||
520 | - min.append(bound[0]) | ||
521 | - min.append(bound[2]) | ||
522 | - | ||
523 | - rbcenter = [] | ||
524 | - rbcenter.append(min[0] + 0.5 * width) | ||
525 | - rbcenter.append(min[1] + 0.5 * height) | ||
526 | - rbcenter.append(0) | ||
527 | - | ||
528 | - self.ren.SetDisplayPoint(rbcenter) | ||
529 | - self.ren.DisplayToView() | ||
530 | - self.ren.ViewToWorld() | ||
531 | - | ||
532 | - worldRBCenter = self.ren.GetWorldPoint() | ||
533 | - worldRBCenter = list(worldRBCenter) | ||
534 | - | ||
535 | - invw = 1.0/worldRBCenter[3] | ||
536 | - | ||
537 | - worldRBCenter[0] *= invw | ||
538 | - worldRBCenter[1] *= invw | ||
539 | - worldRBCenter[2] *= invw | ||
540 | - | ||
541 | - winCenter = [] | ||
542 | - winCenter.append(origin[0] + 0.5 * size[0]) | ||
543 | - winCenter.append(origin[1] + 0.5 * size[1]) | ||
544 | - winCenter.append(0) | ||
545 | - | ||
546 | - ren.SetDisplayPoint(winCenter) | ||
547 | - ren.DisplayToView() | ||
548 | - ren.ViewToWorld() | ||
549 | - | ||
550 | - worldWinCenter = list(ren.GetWorldPoint()) | ||
551 | - invw = 1.0/worldWinCenter[3] | ||
552 | - worldWinCenter[0] *= invw | ||
553 | - worldWinCenter[1] *= invw | ||
554 | - worldWinCenter[2] *= invw | ||
555 | - | ||
556 | - translation = [] | ||
557 | - translation.append(worldRBCenter[0] - worldWinCenter[0]) | ||
558 | - translation.append(worldRBCenter[1] - worldWinCenter[1]) | ||
559 | - translation.append(worldRBCenter[2] - worldWinCenter[2]) | ||
560 | - | ||
561 | - if (width > height): | ||
562 | - cam.Zoom(size[0] / width) | ||
563 | - else: | ||
564 | - cam.Zoom(size[1] / height) | ||
565 | - """ | ||
566 | - | ||
567 | 496 | ||
568 | def ChangeBrushSize(self, pubsub_evt): | 497 | def ChangeBrushSize(self, pubsub_evt): |
569 | size = pubsub_evt.data | 498 | size = pubsub_evt.data |
@@ -607,7 +536,6 @@ class Viewer(wx.Panel): | @@ -607,7 +536,6 @@ class Viewer(wx.Panel): | ||
607 | slice_data.SetCursor(cursor) | 536 | slice_data.SetCursor(cursor) |
608 | self.interactor.Render() | 537 | self.interactor.Render() |
609 | 538 | ||
610 | - | ||
611 | def OnBrushClick(self, evt, obj): | 539 | def OnBrushClick(self, evt, obj): |
612 | self.__set_editor_cursor_visibility(1) | 540 | self.__set_editor_cursor_visibility(1) |
613 | 541 | ||
@@ -641,7 +569,6 @@ class Viewer(wx.Panel): | @@ -641,7 +569,6 @@ class Viewer(wx.Panel): | ||
641 | # TODO: To create a new function to reload images to viewer. | 569 | # TODO: To create a new function to reload images to viewer. |
642 | self.OnScrollBar() | 570 | self.OnScrollBar() |
643 | 571 | ||
644 | - | ||
645 | def OnBrushMove(self, evt, obj): | 572 | def OnBrushMove(self, evt, obj): |
646 | self.__set_editor_cursor_visibility(1) | 573 | self.__set_editor_cursor_visibility(1) |
647 | 574 | ||
@@ -692,34 +619,40 @@ class Viewer(wx.Panel): | @@ -692,34 +619,40 @@ class Viewer(wx.Panel): | ||
692 | 619 | ||
693 | def OnCrossMove(self, evt, obj): | 620 | def OnCrossMove(self, evt, obj): |
694 | # The user moved the mouse with left button pressed | 621 | # The user moved the mouse with left button pressed |
695 | - if (self.left_pressed): | 622 | + if self.left_pressed: |
696 | self.ChangeCrossPosition() | 623 | self.ChangeCrossPosition() |
697 | 624 | ||
698 | def ChangeCrossPosition(self): | 625 | def ChangeCrossPosition(self): |
699 | mouse_x, mouse_y = self.interactor.GetEventPosition() | 626 | mouse_x, mouse_y = self.interactor.GetEventPosition() |
627 | + renderer = self.slice_data.renderer | ||
628 | + self.pick.Pick(mouse_x, mouse_y, 0, renderer) | ||
629 | + | ||
700 | # Get in what slice data the click occurred | 630 | # Get in what slice data the click occurred |
701 | - renderer = self.slice_data_list[0].renderer | ||
702 | # pick to get click position in the 3d world | 631 | # pick to get click position in the 3d world |
703 | - self.pick.Pick(mouse_x, mouse_y, self.slice_data_list[0].number, renderer) | ||
704 | coord_cross = self.get_coordinate_cursor() | 632 | coord_cross = self.get_coordinate_cursor() |
705 | - coord = self.CalcultateScrollPosition(coord_cross) | ||
706 | - ps.Publisher().sendMessage('Update cross position', | ||
707 | - (self.orientation, coord_cross)) | ||
708 | - ps.Publisher().sendMessage('Set ball reference position based on bound', coord_cross) | 633 | + position = self.slice_data.actor.GetInput().FindPoint(coord_cross) |
634 | + # Forcing focal point to be setted in the center of the pixel. | ||
635 | + coord_cross = self.slice_data.actor.GetInput().GetPoint(position) | ||
636 | + | ||
637 | + coord = self.calcultate_scroll_position(position) | ||
638 | + self.ScrollSlice(coord) | ||
639 | + | ||
640 | + ps.Publisher().sendMessage('Update cross position', coord_cross) | ||
641 | + ps.Publisher().sendMessage('Set ball reference position based on bound', | ||
642 | + coord_cross) | ||
709 | ps.Publisher().sendMessage('Set camera in volume', coord_cross) | 643 | ps.Publisher().sendMessage('Set camera in volume', coord_cross) |
710 | ps.Publisher().sendMessage('Render volume viewer') | 644 | ps.Publisher().sendMessage('Render volume viewer') |
711 | 645 | ||
712 | - print "Scroll to", coord | ||
713 | - self.ScrollSlice(coord) | ||
714 | self.interactor.Render() | 646 | self.interactor.Render() |
715 | 647 | ||
716 | def Navigation(self, pubsub_evt): | 648 | def Navigation(self, pubsub_evt): |
717 | # Get point from base change | 649 | # Get point from base change |
718 | x, y, z = pubsub_evt.data | 650 | x, y, z = pubsub_evt.data |
719 | coord_cross = x, y, z | 651 | coord_cross = x, y, z |
720 | - coord = self.CalcultateScrollPosition(coord_cross) | ||
721 | - ps.Publisher().sendMessage('Update cross position', | ||
722 | - (self.orientation, coord_cross)) | 652 | + position = self.slice_data.actor.GetInput().FindPoint(x, y, z) |
653 | + coord_cross = self.slice_data.actor.GetInput().GetPoint(position) | ||
654 | + coord = self.calcultate_scroll_position(position) | ||
655 | + ps.Publisher().sendMessage('Update cross position', coord_cross) | ||
723 | 656 | ||
724 | self.ScrollSlice(coord) | 657 | self.ScrollSlice(coord) |
725 | self.interactor.Render() | 658 | self.interactor.Render() |
@@ -756,43 +689,28 @@ class Viewer(wx.Panel): | @@ -756,43 +689,28 @@ class Viewer(wx.Panel): | ||
756 | # WARN: Return the only slice_data used in this slice_viewer. | 689 | # WARN: Return the only slice_data used in this slice_viewer. |
757 | return self.slice_data | 690 | return self.slice_data |
758 | 691 | ||
759 | - def CalcultateScrollPosition(self, coord): | 692 | + def calcultate_scroll_position(self, position): |
760 | # Based in the given coord (x, y, z), returns a list with the scroll positions for each | 693 | # Based in the given coord (x, y, z), returns a list with the scroll positions for each |
761 | # orientation, being the first position the sagital, second the coronal | 694 | # orientation, being the first position the sagital, second the coronal |
762 | # and the last, axial. | 695 | # and the last, axial. |
763 | - x, y, z = coord | 696 | + image_width = self.slice_.buffer_slices[self.orientation].image.shape[1] |
764 | 697 | ||
765 | - proj = project.Project() | ||
766 | - orig_orien = proj.original_orientation | ||
767 | - | ||
768 | - # First we fix the position origin, based on vtkActor bounds | ||
769 | - bounds = self.actor.GetBounds() | ||
770 | - bound_xi, bound_xf, bound_yi, bound_yf, bound_zi, bound_zf = bounds | ||
771 | - x = float(x - bound_xi) | ||
772 | - y = float(y - bound_yi) | ||
773 | - z = float(z - bound_zi) | ||
774 | - | ||
775 | - # Then we fix the porpotion, based on vtkImageData spacing | ||
776 | - spacing_x, spacing_y, spacing_z = self.imagedata.GetSpacing() | ||
777 | - | ||
778 | - x = x/spacing_x | ||
779 | - y = y/spacing_y | ||
780 | - z = z/spacing_z | ||
781 | - | ||
782 | - x, y, z = self._assert_coord_into_image([x, y, z]) | 698 | + if self.orientation == 'AXIAL': |
699 | + axial = self.slice_data.number | ||
700 | + coronal = position / image_width | ||
701 | + sagital = position % image_width | ||
783 | 702 | ||
784 | - # Based on the current orientation, we define 3D position | ||
785 | - # Sagita, coronal, axial | ||
786 | - coordinates = {const.AXIAL: [x, y, z], | ||
787 | - const.SAGITAL: [z, x, y], | ||
788 | - const.CORONAL: [x, z, y]} | 703 | + elif self.orientation == 'CORONAL': |
704 | + axial = position / image_width | ||
705 | + coronal = self.slice_data.number | ||
706 | + sagital = position % image_width | ||
789 | 707 | ||
790 | - coord = [int(i) for i in coordinates[orig_orien]] | 708 | + elif self.orientation == 'SAGITAL': |
709 | + axial = position / image_width | ||
710 | + coronal = position % image_width | ||
711 | + sagital = self.slice_data.number | ||
791 | 712 | ||
792 | - # According to vtkImageData extent, we limit min and max value | ||
793 | - # If this is not done, a VTK Error occurs when mouse is pressed outside | ||
794 | - # vtkImageData extent | ||
795 | - return coord | 713 | + return sagital, coronal, axial |
796 | 714 | ||
797 | def calculate_matrix_position(self, coord): | 715 | def calculate_matrix_position(self, coord): |
798 | x, y, z = coord | 716 | x, y, z = coord |
@@ -965,7 +883,6 @@ class Viewer(wx.Panel): | @@ -965,7 +883,6 @@ class Viewer(wx.Panel): | ||
965 | def OnHideText(self, pubsub_evt): | 883 | def OnHideText(self, pubsub_evt): |
966 | self.HideTextActors() | 884 | self.HideTextActors() |
967 | 885 | ||
968 | - | ||
969 | def OnCloseProject(self, pubsub_evt): | 886 | def OnCloseProject(self, pubsub_evt): |
970 | self.CloseProject() | 887 | self.CloseProject() |
971 | 888 | ||
@@ -982,15 +899,12 @@ class Viewer(wx.Panel): | @@ -982,15 +899,12 @@ class Viewer(wx.Panel): | ||
982 | self.wl_text = None | 899 | self.wl_text = None |
983 | self.pick = vtk.vtkWorldPointPicker() | 900 | self.pick = vtk.vtkWorldPointPicker() |
984 | 901 | ||
985 | - | ||
986 | def OnSetInteractorStyle(self, pubsub_evt): | 902 | def OnSetInteractorStyle(self, pubsub_evt): |
987 | state = pubsub_evt.data | 903 | state = pubsub_evt.data |
988 | self.SetInteractorStyle(state) | 904 | self.SetInteractorStyle(state) |
989 | 905 | ||
990 | if (state != const.SLICE_STATE_EDITOR): | 906 | if (state != const.SLICE_STATE_EDITOR): |
991 | ps.Publisher().sendMessage('Set interactor default cursor') | 907 | ps.Publisher().sendMessage('Set interactor default cursor') |
992 | - | ||
993 | - | ||
994 | 908 | ||
995 | def ChangeBrushOperation(self, pubsub_evt): | 909 | def ChangeBrushOperation(self, pubsub_evt): |
996 | self._brush_cursor_op = pubsub_evt.data | 910 | self._brush_cursor_op = pubsub_evt.data |
@@ -1006,7 +920,6 @@ class Viewer(wx.Panel): | @@ -1006,7 +920,6 @@ class Viewer(wx.Panel): | ||
1006 | def LoadImagedata(self, pubsub_evt): | 920 | def LoadImagedata(self, pubsub_evt): |
1007 | imagedata, mask_dict = pubsub_evt.data | 921 | imagedata, mask_dict = pubsub_evt.data |
1008 | self.SetInput(imagedata, mask_dict) | 922 | self.SetInput(imagedata, mask_dict) |
1009 | - | ||
1010 | 923 | ||
1011 | def LoadRenderers(self, imagedata): | 924 | def LoadRenderers(self, imagedata): |
1012 | number_renderers = self.layout[0] * self.layout[1] | 925 | number_renderers = self.layout[0] * self.layout[1] |
@@ -1061,7 +974,6 @@ class Viewer(wx.Panel): | @@ -1061,7 +974,6 @@ class Viewer(wx.Panel): | ||
1061 | slice_data.SetBorderStyle(style) | 974 | slice_data.SetBorderStyle(style) |
1062 | n += 1 | 975 | n += 1 |
1063 | 976 | ||
1064 | - | ||
1065 | def __create_cursor(self): | 977 | def __create_cursor(self): |
1066 | cursor = ca.CursorCircle() | 978 | cursor = ca.CursorCircle() |
1067 | cursor.SetOrientation(self.orientation) | 979 | cursor.SetOrientation(self.orientation) |
@@ -1083,6 +995,7 @@ class Viewer(wx.Panel): | @@ -1083,6 +995,7 @@ class Viewer(wx.Panel): | ||
1083 | self.slice_data.actor.SetInput(imagedata) | 995 | self.slice_data.actor.SetInput(imagedata) |
1084 | self.slice_data.SetCursor(self.__create_cursor()) | 996 | self.slice_data.SetCursor(self.__create_cursor()) |
1085 | self.cam = self.slice_data.renderer.GetActiveCamera() | 997 | self.cam = self.slice_data.renderer.GetActiveCamera() |
998 | + self.__build_cross_lines(imagedata) | ||
1086 | self.set_slice_number(0) | 999 | self.set_slice_number(0) |
1087 | self.__update_camera() | 1000 | self.__update_camera() |
1088 | self.slice_data.renderer.ResetCamera() | 1001 | self.slice_data.renderer.ResetCamera() |
@@ -1117,46 +1030,27 @@ class Viewer(wx.Panel): | @@ -1117,46 +1030,27 @@ class Viewer(wx.Panel): | ||
1117 | ## Insert cursor | 1030 | ## Insert cursor |
1118 | self.SetInteractorStyle(const.STATE_DEFAULT) | 1031 | self.SetInteractorStyle(const.STATE_DEFAULT) |
1119 | 1032 | ||
1120 | - #self.__build_cross_lines() | 1033 | + def __build_cross_lines(self, imagedata): |
1034 | + renderer = self.slice_data.renderer | ||
1121 | 1035 | ||
1122 | - def __build_cross_lines(self): | ||
1123 | - actor = self.slice_data_list[0].actor | ||
1124 | - renderer = self.slice_data_list[0].renderer | ||
1125 | - xi, xf, yi, yf, zi, zf = actor.GetBounds() | ||
1126 | - | ||
1127 | - #vline = vtk.vtkLineSource() | ||
1128 | - #vline.SetPoint1(xi, yi, zi) | ||
1129 | - #vline.SetPoint2(xi, yf, zi) | ||
1130 | - #self.vline = vline | ||
1131 | - | ||
1132 | - #hline = vtk.vtkLineSource() | ||
1133 | - #hline.SetPoint1(xi, yi, zi) | ||
1134 | - #hline.SetPoint2(xf, yi, zi) | ||
1135 | - #self.hline = hline | ||
1136 | - | ||
1137 | - #cross = vtk.vtkAppendPolyData() | ||
1138 | - #cross.AddInput(vline.GetOutput()) | ||
1139 | - #cross.AddInput(hline.GetOutput()) | ||
1140 | cross = vtk.vtkCursor3D() | 1036 | cross = vtk.vtkCursor3D() |
1141 | cross.AllOff() | 1037 | cross.AllOff() |
1142 | cross.AxesOn() | 1038 | cross.AxesOn() |
1143 | - #cross.WrapOn() | ||
1144 | - #cross.OutlineOff() | ||
1145 | - #cross.ZShadowsOff() | ||
1146 | - #cross.YShadowsOff() | ||
1147 | - #cross.XShadowsOff() | ||
1148 | - cross.SetModelBounds(self.imagedata.GetBounds()) | ||
1149 | self.cross = cross | 1039 | self.cross = cross |
1150 | 1040 | ||
1041 | + c = vtk.vtkCoordinate() | ||
1042 | + c.SetCoordinateSystemToWorld() | ||
1043 | + | ||
1151 | cross_mapper = vtk.vtkPolyDataMapper() | 1044 | cross_mapper = vtk.vtkPolyDataMapper() |
1152 | cross_mapper.SetInput(cross.GetOutput()) | 1045 | cross_mapper.SetInput(cross.GetOutput()) |
1046 | + #cross_mapper.SetTransformCoordinate(c) | ||
1153 | 1047 | ||
1154 | - property = vtk.vtkProperty() | ||
1155 | - property.SetColor(1, 0, 0) | 1048 | + p = vtk.vtkProperty() |
1049 | + p.SetColor(1, 0, 0) | ||
1156 | 1050 | ||
1157 | cross_actor = vtk.vtkActor() | 1051 | cross_actor = vtk.vtkActor() |
1158 | cross_actor.SetMapper(cross_mapper) | 1052 | cross_actor.SetMapper(cross_mapper) |
1159 | - cross_actor.SetProperty(property) | 1053 | + cross_actor.SetProperty(p) |
1160 | cross_actor.VisibilityOff() | 1054 | cross_actor.VisibilityOff() |
1161 | # Only the slices are pickable | 1055 | # Only the slices are pickable |
1162 | cross_actor.PickableOff() | 1056 | cross_actor.PickableOff() |
@@ -1165,78 +1059,9 @@ class Viewer(wx.Panel): | @@ -1165,78 +1059,9 @@ class Viewer(wx.Panel): | ||
1165 | renderer.AddActor(cross_actor) | 1059 | renderer.AddActor(cross_actor) |
1166 | 1060 | ||
1167 | def __update_cross_position(self, pubsub_evt): | 1061 | def __update_cross_position(self, pubsub_evt): |
1168 | - x, y, z = pubsub_evt.data[1] | ||
1169 | - orientation = pubsub_evt.data[0] | ||
1170 | - #xi, yi, zi = self.vline.GetPoint1() | ||
1171 | - #xf, yf, zf = self.vline.GetPoint2() | ||
1172 | - #self.vline.SetPoint1(x, yi, z) | ||
1173 | - #self.vline.SetPoint2(x, yf, z) | ||
1174 | - #self.vline.Update() | ||
1175 | - | ||
1176 | - #xi, yi, zi = self.hline.GetPoint1() | ||
1177 | - #xf, yf, zf = self.hline.GetPoint2() | ||
1178 | - #self.hline.SetPoint1(xi, y, z) | ||
1179 | - #self.hline.SetPoint2(xf, y, z) | ||
1180 | - #self.hline.Update() | ||
1181 | - slice_data = self.slice_data_list[0] | ||
1182 | - slice_number = slice_data.number | ||
1183 | - actor_bound = slice_data.actor.GetBounds() | ||
1184 | - extent = slice_data.actor.GetDisplayExtent() | ||
1185 | - cam = slice_data.renderer.GetActiveCamera() | ||
1186 | - | ||
1187 | - vCamera = numpy.array(cam.GetPosition()) - numpy.array(cam.GetFocalPoint()) | ||
1188 | - n_vCamera = vCamera / numpy.linalg.norm(vCamera) | ||
1189 | - | ||
1190 | - pos = [j + 0.01 * i for i,j in zip(n_vCamera, (x, y, z))] | ||
1191 | - | ||
1192 | - #yz = [x + abs(x * 0.001), y, z] | ||
1193 | - #xz = [x, y - abs(y * 0.001), z] | ||
1194 | - #xy = [x, y, z + abs(z * 0.001)] | ||
1195 | - | ||
1196 | - proj = project.Project() | ||
1197 | - orig_orien = proj.original_orientation | ||
1198 | - #pos = [x, y, z] | ||
1199 | - | ||
1200 | - #if (orig_orien == const.SAGITAL): | ||
1201 | - # coordinates = {"SAGITAL": xy, "CORONAL": yz, "AXIAL": xz} | ||
1202 | - #elif(orig_orien == const.CORONAL): | ||
1203 | - # #coordinates = {"SAGITAL": yz, "CORONAL": xy, "AXIAL": xz} | ||
1204 | - # if orientation == "AXIAL": | ||
1205 | - # pos[2] += abs(pos[2] * 0.001) | ||
1206 | - # elif orientation == "SAGITAL": | ||
1207 | - # pos[0] += abs(pos[0] * 0.001) | ||
1208 | - # elif orientation == "CORONAL": | ||
1209 | - # pos[1] -= abs(pos[1] * 0.001) | ||
1210 | - #else: | ||
1211 | - # #coordinates = {"SAGITAL": yz, "CORONAL": xz, "AXIAL": xy} | ||
1212 | - # print "AXIAL" | ||
1213 | - # if orientation == "AXIAL": | ||
1214 | - # pos[2] += abs(pos[2] * 0.001) | ||
1215 | - # elif orientation == "SAGITAL": | ||
1216 | - # pos[0] += abs(pos[0] * 0.001) | ||
1217 | - # elif orientation == "CORONAL": | ||
1218 | - # pos[1] -= abs(pos[1] * 0.001) | ||
1219 | - | ||
1220 | - | ||
1221 | - #pos = [x, y, z] | ||
1222 | - #if orientation == "AXIAL": | ||
1223 | - # pos[2] += abs(pos[2] * 0.001) | ||
1224 | - #elif orientation == "SAGITAL": | ||
1225 | - # pos[0] += abs(pos[0] * 0.001) | ||
1226 | - #elif orientation == "CORONAL": | ||
1227 | - # pos[1] -= abs(pos[1] * 0.001) | ||
1228 | - #print ">POS", pos | ||
1229 | 1062 | + pos = pubsub_evt.data | |
1230 | self.cross.SetFocalPoint(pos) | 1063 | self.cross.SetFocalPoint(pos) |
1231 | 1064 | ||
1232 | |||
1233 | - #print slice_number | ||
1234 | - #print x, y, z | ||
1235 | - #print "Focal", self.cross.GetFocalPoint() | ||
1236 | - #print "bounds", self.cross.GetModelBounds() | ||
1237 | - #print "actor bounds", slice_data.actor.GetBounds() | ||
1238 | |||
1239 | - | ||
1240 | def __set_cross_visibility(self, visibility): | 1065 | def __set_cross_visibility(self, visibility): |
1241 | self.cross_actor.SetVisibility(visibility) | 1066 | self.cross_actor.SetVisibility(visibility) |
1242 | 1067 | ||
@@ -1275,6 +1100,7 @@ class Viewer(wx.Panel): | @@ -1275,6 +1100,7 @@ class Viewer(wx.Panel): | ||
1275 | renderer = vtk.vtkRenderer() | 1100 | renderer = vtk.vtkRenderer() |
1276 | self.interactor.GetRenderWindow().AddRenderer(renderer) | 1101 | self.interactor.GetRenderWindow().AddRenderer(renderer) |
1277 | actor = vtk.vtkImageActor() | 1102 | actor = vtk.vtkImageActor() |
1103 | + actor.InterpolateOff() | ||
1278 | slice_data = sd.SliceData() | 1104 | slice_data = sd.SliceData() |
1279 | slice_data.SetOrientation(self.orientation) | 1105 | slice_data.SetOrientation(self.orientation) |
1280 | slice_data.renderer = renderer | 1106 | slice_data.renderer = renderer |
@@ -1294,11 +1120,9 @@ class Viewer(wx.Panel): | @@ -1294,11 +1120,9 @@ class Viewer(wx.Panel): | ||
1294 | self.cam.SetViewUp(const.SLICE_POSITION[orig_orien][0][self.orientation]) | 1120 | self.cam.SetViewUp(const.SLICE_POSITION[orig_orien][0][self.orientation]) |
1295 | self.cam.SetPosition(const.SLICE_POSITION[orig_orien][1][self.orientation]) | 1121 | self.cam.SetPosition(const.SLICE_POSITION[orig_orien][1][self.orientation]) |
1296 | self.cam.ComputeViewPlaneNormal() | 1122 | self.cam.ComputeViewPlaneNormal() |
1297 | - self.cam.OrthogonalizeViewUp() | 1123 | + #self.cam.OrthogonalizeViewUp() |
1298 | self.cam.ParallelProjectionOn() | 1124 | self.cam.ParallelProjectionOn() |
1299 | 1125 | ||
1300 | - #slice_data.renderer.Render() | ||
1301 | - | ||
1302 | def __update_display_extent(self, image): | 1126 | def __update_display_extent(self, image): |
1303 | self.slice_data.actor.SetDisplayExtent(image.GetExtent()) | 1127 | self.slice_data.actor.SetDisplayExtent(image.GetExtent()) |
1304 | self.slice_data.renderer.ResetCameraClippingRange() | 1128 | self.slice_data.renderer.ResetCameraClippingRange() |
@@ -1340,7 +1164,15 @@ class Viewer(wx.Panel): | @@ -1340,7 +1164,15 @@ class Viewer(wx.Panel): | ||
1340 | def OnScrollBar(self, evt=None): | 1164 | def OnScrollBar(self, evt=None): |
1341 | pos = self.scroll.GetThumbPosition() | 1165 | pos = self.scroll.GetThumbPosition() |
1342 | self.set_slice_number(pos) | 1166 | self.set_slice_number(pos) |
1343 | - self.interactor.Render() | 1167 | + |
1168 | + if self.state == const.SLICE_STATE_CROSS: | ||
1169 | + # Update other slice's cross according to the new focal point from | ||
1170 | + # the actual orientation. | ||
1171 | + focal_point = self.cross.GetFocalPoint() | ||
1172 | + ps.Publisher().sendMessage('Update cross position', focal_point) | ||
1173 | + ps.Publisher().sendMessage('Update slice viewer') | ||
1174 | + else: | ||
1175 | + self.interactor.Render() | ||
1344 | if evt: | 1176 | if evt: |
1345 | evt.Skip() | 1177 | evt.Skip() |
1346 | 1178 | ||
@@ -1376,8 +1208,6 @@ class Viewer(wx.Panel): | @@ -1376,8 +1208,6 @@ class Viewer(wx.Panel): | ||
1376 | pos = pos - 1 | 1208 | pos = pos - 1 |
1377 | self.scroll.SetThumbPosition(pos) | 1209 | self.scroll.SetThumbPosition(pos) |
1378 | self.OnScrollBar() | 1210 | self.OnScrollBar() |
1379 | - | ||
1380 | - | ||
1381 | 1211 | ||
1382 | def OnScrollBackward(self, evt=None, obj=None): | 1212 | def OnScrollBackward(self, evt=None, obj=None): |
1383 | pos = self.scroll.GetThumbPosition() | 1213 | pos = self.scroll.GetThumbPosition() |
@@ -1388,8 +1218,6 @@ class Viewer(wx.Panel): | @@ -1388,8 +1218,6 @@ class Viewer(wx.Panel): | ||
1388 | self.scroll.SetThumbPosition(pos) | 1218 | self.scroll.SetThumbPosition(pos) |
1389 | self.OnScrollBar() | 1219 | self.OnScrollBar() |
1390 | 1220 | ||
1391 | - | ||
1392 | - | ||
1393 | def OnSize(self, evt): | 1221 | def OnSize(self, evt): |
1394 | w, h = evt.GetSize() | 1222 | w, h = evt.GetSize() |
1395 | w = float(w) | 1223 | w = float(w) |
@@ -1408,12 +1236,14 @@ class Viewer(wx.Panel): | @@ -1408,12 +1236,14 @@ class Viewer(wx.Panel): | ||
1408 | 1236 | ||
1409 | self.slice_data.SetNumber(index) | 1237 | self.slice_data.SetNumber(index) |
1410 | self.__update_display_extent(image) | 1238 | self.__update_display_extent(image) |
1411 | - #self.interactor.Render() | 1239 | + self.cross.SetModelBounds(self.slice_data.actor.GetBounds()) |
1412 | 1240 | ||
1413 | def ChangeSliceNumber(self, pubsub_evt): | 1241 | def ChangeSliceNumber(self, pubsub_evt): |
1414 | index = pubsub_evt.data | 1242 | index = pubsub_evt.data |
1415 | - self.set_slice_number(index) | 1243 | + #self.set_slice_number(index) |
1416 | self.scroll.SetThumbPosition(index) | 1244 | self.scroll.SetThumbPosition(index) |
1245 | + pos = self.scroll.GetThumbPosition() | ||
1246 | + self.set_slice_number(pos) | ||
1417 | self.interactor.Render() | 1247 | self.interactor.Render() |
1418 | 1248 | ||
1419 | def test_operation_position(self, coord): | 1249 | def test_operation_position(self, coord): |
@@ -1470,7 +1300,8 @@ class Viewer(wx.Panel): | @@ -1470,7 +1300,8 @@ class Viewer(wx.Panel): | ||
1470 | self.interactor.Render() | 1300 | self.interactor.Render() |
1471 | 1301 | ||
1472 | def ReloadActualSlice(self, pubsub_evt): | 1302 | def ReloadActualSlice(self, pubsub_evt): |
1473 | - self.OnScrollBar() | 1303 | + pos = self.scroll.GetThumbPosition() |
1304 | + self.set_slice_number(pos) | ||
1474 | 1305 | ||
1475 | def AddActors(self, pubsub_evt): | 1306 | def AddActors(self, pubsub_evt): |
1476 | "Inserting actors" | 1307 | "Inserting actors" |