Commit 6dbca98b38feba54921fe2a15d1f25498b63e6bc
1 parent
6ca69379
Exists in
master
and in
5 other branches
FIX: Fixed problem change plane slices in volume view
Showing
3 changed files
with
87 additions
and
140 deletions
Show diff stats
invesalius/data/slice_.py
@@ -114,6 +114,7 @@ class Slice(object): | @@ -114,6 +114,7 @@ class Slice(object): | ||
114 | 'Change colour table from background image') | 114 | 'Change colour table from background image') |
115 | 115 | ||
116 | ps.Publisher().subscribe(self.InputImageWidget, 'Input Image in the widget') | 116 | ps.Publisher().subscribe(self.InputImageWidget, 'Input Image in the widget') |
117 | + | ||
117 | ps.Publisher().subscribe(self.OnExportMask,'Export mask to file') | 118 | ps.Publisher().subscribe(self.OnExportMask,'Export mask to file') |
118 | 119 | ||
119 | ps.Publisher().subscribe(self.OnCloseProject, 'Close project data') | 120 | ps.Publisher().subscribe(self.OnCloseProject, 'Close project data') |
@@ -123,7 +124,8 @@ class Slice(object): | @@ -123,7 +124,8 @@ class Slice(object): | ||
123 | 124 | ||
124 | ps.Publisher().subscribe(self.OnRemoveMasks, 'Remove masks') | 125 | ps.Publisher().subscribe(self.OnRemoveMasks, 'Remove masks') |
125 | ps.Publisher().subscribe(self.OnDuplicateMasks, 'Duplicate masks') | 126 | ps.Publisher().subscribe(self.OnDuplicateMasks, 'Duplicate masks') |
126 | - | 127 | + ps.Publisher().subscribe(self.UpdateSlice3D,'Update slice 3D') |
128 | + | ||
127 | def GetMaxSliceNumber(self, orientation): | 129 | def GetMaxSliceNumber(self, orientation): |
128 | shape = self.matrix.shape | 130 | shape = self.matrix.shape |
129 | 131 | ||
@@ -661,17 +663,41 @@ class Slice(object): | @@ -661,17 +663,41 @@ class Slice(object): | ||
661 | 663 | ||
662 | 664 | ||
663 | def InputImageWidget(self, pubsub_evt): | 665 | def InputImageWidget(self, pubsub_evt): |
664 | - #widget = pubsub_evt.data | ||
665 | - | ||
666 | - #flip = vtk.vtkImageFlip() | ||
667 | - #flip.SetInput(self.window_level.GetOutput()) | ||
668 | - #flip.SetFilteredAxis(1) | ||
669 | - #flip.FlipAboutOriginOn() | ||
670 | - #flip.Update() | ||
671 | - | ||
672 | - #widget.SetInput(flip.GetOutput()) | ||
673 | - pass | 666 | + widget, orientation = pubsub_evt.data |
674 | 667 | ||
668 | + original_orientation = Project().original_orientation | ||
669 | + | ||
670 | + img = self.buffer_slices[orientation].vtk_image | ||
671 | + | ||
672 | + cast = vtk.vtkImageCast() | ||
673 | + cast.SetInput(img) | ||
674 | + cast.SetOutputScalarTypeToDouble() | ||
675 | + cast.ClampOverflowOn() | ||
676 | + cast.Update() | ||
677 | + | ||
678 | + flip = vtk.vtkImageFlip() | ||
679 | + flip.SetInput(cast.GetOutput()) | ||
680 | + flip.SetFilteredAxis(1) | ||
681 | + flip.FlipAboutOriginOn() | ||
682 | + flip.Update() | ||
683 | + widget.SetInput(flip.GetOutput()) | ||
684 | + | ||
685 | + def UpdateSlice3D(self, pubsub_evt): | ||
686 | + widget, orientation = pubsub_evt.data | ||
687 | + img = self.buffer_slices[orientation].vtk_image | ||
688 | + | ||
689 | + cast = vtk.vtkImageCast() | ||
690 | + cast.SetInput(img) | ||
691 | + cast.SetOutputScalarTypeToDouble() | ||
692 | + cast.ClampOverflowOn() | ||
693 | + cast.Update() | ||
694 | + | ||
695 | + flip = vtk.vtkImageFlip() | ||
696 | + flip.SetInput(cast.GetOutput()) | ||
697 | + flip.SetFilteredAxis(1) | ||
698 | + flip.FlipAboutOriginOn() | ||
699 | + flip.Update() | ||
700 | + widget.SetInput(flip.GetOutput()) | ||
675 | 701 | ||
676 | def CreateMask(self, imagedata=None, name=None, colour=None, | 702 | def CreateMask(self, imagedata=None, name=None, colour=None, |
677 | opacity=None, threshold_range=None, | 703 | opacity=None, threshold_range=None, |
invesalius/data/viewer_slice.py
@@ -821,6 +821,7 @@ class Viewer(wx.Panel): | @@ -821,6 +821,7 @@ class Viewer(wx.Panel): | ||
821 | ps.Publisher().subscribe(self.RemoveActors, ('Remove actors', ORIENTATIONS[self.orientation])) | 821 | ps.Publisher().subscribe(self.RemoveActors, ('Remove actors', ORIENTATIONS[self.orientation])) |
822 | 822 | ||
823 | ps.Publisher().subscribe(self.ReloadActualSlice, 'Reload actual slice') | 823 | ps.Publisher().subscribe(self.ReloadActualSlice, 'Reload actual slice') |
824 | + | ||
824 | 825 | ||
825 | def SetDefaultCursor(self, pusub_evt): | 826 | def SetDefaultCursor(self, pusub_evt): |
826 | self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) | 827 | self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) |
@@ -1149,22 +1150,22 @@ class Viewer(wx.Panel): | @@ -1149,22 +1150,22 @@ class Viewer(wx.Panel): | ||
1149 | def UpdateSlice3D(self, pos): | 1150 | def UpdateSlice3D(self, pos): |
1150 | original_orientation = project.Project().original_orientation | 1151 | original_orientation = project.Project().original_orientation |
1151 | pos = self.scroll.GetThumbPosition() | 1152 | pos = self.scroll.GetThumbPosition() |
1152 | - if (self.orientation == "CORONAL") and \ | ||
1153 | - (original_orientation == const.AXIAL): | ||
1154 | - pos = abs(self.scroll.GetRange() - pos) | ||
1155 | - elif(self.orientation == "AXIAL") and \ | ||
1156 | - (original_orientation == const.CORONAL): | ||
1157 | - pos = abs(self.scroll.GetRange() - pos) | ||
1158 | - elif(self.orientation == "AXIAL") and \ | ||
1159 | - (original_orientation == const.SAGITAL): | ||
1160 | - pos = abs(self.scroll.GetRange() - pos) | 1153 | + #if (self.orientation == "CORONAL") and \ |
1154 | + # (original_orientation == const.AXIAL): | ||
1155 | + # pos = abs(self.scroll.GetRange() - pos) | ||
1156 | + #elif(self.orientation == "AXIAL") and \ | ||
1157 | + # (original_orientation == const.CORONAL): | ||
1158 | + # pos = abs(self.scroll.GetRange() - pos) | ||
1159 | + #elif(self.orientation == "AXIAL") and \ | ||
1160 | + # (original_orientation == const.SAGITAL): | ||
1161 | + # pos = abs(self.scroll.GetRange() - pos) | ||
1161 | ps.Publisher().sendMessage('Change slice from slice plane',\ | 1162 | ps.Publisher().sendMessage('Change slice from slice plane',\ |
1162 | (self.orientation, pos)) | 1163 | (self.orientation, pos)) |
1163 | 1164 | ||
1164 | def OnScrollBar(self, evt=None): | 1165 | def OnScrollBar(self, evt=None): |
1165 | - pos = self.scroll.GetThumbPosition() | 1166 | + pos = self.scroll.GetThumbPosition() |
1166 | self.set_slice_number(pos) | 1167 | self.set_slice_number(pos) |
1167 | - | 1168 | + self.UpdateSlice3D(pos) |
1168 | if self.state == const.SLICE_STATE_CROSS: | 1169 | if self.state == const.SLICE_STATE_CROSS: |
1169 | # Update other slice's cross according to the new focal point from | 1170 | # Update other slice's cross according to the new focal point from |
1170 | # the actual orientation. | 1171 | # the actual orientation. |
@@ -1172,12 +1173,13 @@ class Viewer(wx.Panel): | @@ -1172,12 +1173,13 @@ class Viewer(wx.Panel): | ||
1172 | ps.Publisher().sendMessage('Update cross position', focal_point) | 1173 | ps.Publisher().sendMessage('Update cross position', focal_point) |
1173 | ps.Publisher().sendMessage('Update slice viewer') | 1174 | ps.Publisher().sendMessage('Update slice viewer') |
1174 | else: | 1175 | else: |
1175 | - self.interactor.Render() | 1176 | + self.interactor.Render() |
1176 | if evt: | 1177 | if evt: |
1177 | evt.Skip() | 1178 | evt.Skip() |
1178 | 1179 | ||
1179 | def OnScrollBarRelease(self, evt): | 1180 | def OnScrollBarRelease(self, evt): |
1180 | - #self.UpdateSlice3D(self.pos) | 1181 | + pos = self.scroll.GetThumbPosition() |
1182 | + #self.UpdateSlice3D(pos) | ||
1181 | evt.Skip() | 1183 | evt.Skip() |
1182 | 1184 | ||
1183 | def OnKeyDown(self, evt=None, obj=None): | 1185 | def OnKeyDown(self, evt=None, obj=None): |
invesalius/data/viewer_volume.py
@@ -801,120 +801,69 @@ class SlicePlane: | @@ -801,120 +801,69 @@ class SlicePlane: | ||
801 | self.original_orientation = project.original_orientation | 801 | self.original_orientation = project.original_orientation |
802 | self.Create() | 802 | self.Create() |
803 | self.__bind_evt() | 803 | self.__bind_evt() |
804 | - self.__bind_vtk_evt() | ||
805 | 804 | ||
806 | def __bind_evt(self): | 805 | def __bind_evt(self): |
807 | ps.Publisher().subscribe(self.Enable, 'Enable plane') | 806 | ps.Publisher().subscribe(self.Enable, 'Enable plane') |
808 | ps.Publisher().subscribe(self.Disable, 'Disable plane') | 807 | ps.Publisher().subscribe(self.Disable, 'Disable plane') |
809 | ps.Publisher().subscribe(self.ChangeSlice, 'Change slice from slice plane') | 808 | ps.Publisher().subscribe(self.ChangeSlice, 'Change slice from slice plane') |
810 | 809 | ||
811 | - def __bind_vtk_evt(self): | ||
812 | - self.plane_x.AddObserver("InteractionEvent", self.PlaneEvent) | ||
813 | - self.plane_y.AddObserver("InteractionEvent", self.PlaneEvent) | ||
814 | - self.plane_z.AddObserver("InteractionEvent", self.PlaneEvent) | ||
815 | - | ||
816 | - def PlaneEvent(self, obj, evt): | ||
817 | - number = obj.GetSliceIndex() | ||
818 | - plane_axis = obj.GetPlaneOrientation() | ||
819 | - if (self.original_orientation == const.AXIAL): | ||
820 | - if (plane_axis == 0): | ||
821 | - orientation = "SAGITAL" | ||
822 | - elif(plane_axis == 1): | ||
823 | - orientation = "CORONAL" | ||
824 | - dimen = obj.GetInput().GetDimensions() | ||
825 | - number = abs(dimen[0] - (number + 1)) | ||
826 | - else: | ||
827 | - orientation = "AXIAL" | ||
828 | - | ||
829 | - elif(self.original_orientation == const.SAGITAL): | ||
830 | - if (plane_axis == 0): | ||
831 | - orientation = "CORONAL" | ||
832 | - elif(plane_axis == 1): | ||
833 | - orientation = "AXIAL" | ||
834 | - dimen = obj.GetInput().GetDimensions() | ||
835 | - number = abs(dimen[0] - (number + 1)) | ||
836 | - else: | ||
837 | - orientation = "SAGITAL" | ||
838 | - else: | ||
839 | - if (plane_axis == 0): | ||
840 | - orientation = "SAGITAL" | ||
841 | - elif(plane_axis == 1): | ||
842 | - orientation = "AXIAL" | ||
843 | - dimen = obj.GetInput().GetDimensions() | ||
844 | - number = abs(dimen[0] - (number + 1)) | ||
845 | - else: | ||
846 | - orientation = "CORONAL" | ||
847 | - | ||
848 | - if (obj.GetSlicePosition() != 0.0): | ||
849 | - ps.Publisher().sendMessage(('Set scroll position', \ | ||
850 | - orientation), number) | ||
851 | - | ||
852 | def Create(self): | 810 | def Create(self): |
853 | plane_x = self.plane_x = vtk.vtkImagePlaneWidget() | 811 | plane_x = self.plane_x = vtk.vtkImagePlaneWidget() |
854 | - plane_x.DisplayTextOff() | ||
855 | - ps.Publisher().sendMessage('Input Image in the widget', plane_x) | 812 | + plane_x.InteractionOff() |
813 | + ps.Publisher().sendMessage('Input Image in the widget', | ||
814 | + (plane_x, 'SAGITAL')) | ||
856 | plane_x.SetPlaneOrientationToXAxes() | 815 | plane_x.SetPlaneOrientationToXAxes() |
857 | plane_x.TextureVisibilityOn() | 816 | plane_x.TextureVisibilityOn() |
858 | - plane_x.SetLeftButtonAction(1) | 817 | + plane_x.SetLeftButtonAction(0) |
859 | plane_x.SetRightButtonAction(0) | 818 | plane_x.SetRightButtonAction(0) |
860 | - prop1 = plane_x.GetPlaneProperty() | ||
861 | - prop1.SetColor(0, 0, 1) | 819 | + plane_x.SetMiddleButtonAction(0) |
862 | cursor_property = plane_x.GetCursorProperty() | 820 | cursor_property = plane_x.GetCursorProperty() |
863 | cursor_property.SetOpacity(0) | 821 | cursor_property.SetOpacity(0) |
864 | 822 | ||
865 | plane_y = self.plane_y = vtk.vtkImagePlaneWidget() | 823 | plane_y = self.plane_y = vtk.vtkImagePlaneWidget() |
866 | plane_y.DisplayTextOff() | 824 | plane_y.DisplayTextOff() |
867 | - ps.Publisher().sendMessage('Input Image in the widget', plane_y) | 825 | + ps.Publisher().sendMessage('Input Image in the widget', |
826 | + (plane_y, 'CORONAL')) | ||
868 | plane_y.SetPlaneOrientationToYAxes() | 827 | plane_y.SetPlaneOrientationToYAxes() |
869 | plane_y.TextureVisibilityOn() | 828 | plane_y.TextureVisibilityOn() |
870 | - plane_y.SetLeftButtonAction(1) | 829 | + plane_y.SetLeftButtonAction(0) |
871 | plane_y.SetRightButtonAction(0) | 830 | plane_y.SetRightButtonAction(0) |
831 | + plane_y.SetMiddleButtonAction(0) | ||
872 | prop1 = plane_y.GetPlaneProperty() | 832 | prop1 = plane_y.GetPlaneProperty() |
873 | - prop1.SetColor(0, 1, 0) | ||
874 | cursor_property = plane_y.GetCursorProperty() | 833 | cursor_property = plane_y.GetCursorProperty() |
875 | cursor_property.SetOpacity(0) | 834 | cursor_property.SetOpacity(0) |
876 | 835 | ||
877 | plane_z = self.plane_z = vtk.vtkImagePlaneWidget() | 836 | plane_z = self.plane_z = vtk.vtkImagePlaneWidget() |
878 | - plane_z.DisplayTextOff() | ||
879 | - ps.Publisher().sendMessage('Input Image in the widget', plane_z) | 837 | + plane_z.InteractionOff() |
838 | + ps.Publisher().sendMessage('Input Image in the widget', | ||
839 | + (plane_z, 'AXIAL')) | ||
880 | plane_z.SetPlaneOrientationToZAxes() | 840 | plane_z.SetPlaneOrientationToZAxes() |
881 | plane_z.TextureVisibilityOn() | 841 | plane_z.TextureVisibilityOn() |
882 | - plane_z.SetLeftButtonAction(1) | 842 | + plane_z.SetLeftButtonAction(0) |
883 | plane_z.SetRightButtonAction(0) | 843 | plane_z.SetRightButtonAction(0) |
884 | - prop1 = plane_z.GetPlaneProperty() | ||
885 | - prop1.SetColor(1, 0, 0) | 844 | + plane_z.SetMiddleButtonAction(0) |
845 | + | ||
886 | cursor_property = plane_z.GetCursorProperty() | 846 | cursor_property = plane_z.GetCursorProperty() |
887 | cursor_property.SetOpacity(0) | 847 | cursor_property.SetOpacity(0) |
888 | 848 | ||
889 | - if(self.original_orientation == const.AXIAL): | ||
890 | - prop3 = plane_z.GetPlaneProperty() | ||
891 | - prop3.SetColor(1, 0, 0) | ||
892 | - | ||
893 | - prop1 = plane_x.GetPlaneProperty() | ||
894 | - prop1.SetColor(0, 0, 1) | ||
895 | - | ||
896 | - prop2 = plane_y.GetPlaneProperty() | ||
897 | - prop2.SetColor(0, 1, 0) | ||
898 | - | ||
899 | - elif(self.original_orientation == const.SAGITAL): | ||
900 | - prop3 = plane_y.GetPlaneProperty() | ||
901 | - prop3.SetColor(1, 0, 0) | ||
902 | 849 | ||
903 | - prop1 = plane_z.GetPlaneProperty() | ||
904 | - prop1.SetColor(0, 0, 1) | ||
905 | - | ||
906 | - prop2 = plane_x.GetPlaneProperty() | ||
907 | - prop2.SetColor(0, 1, 0) | ||
908 | - | ||
909 | - else: | ||
910 | - prop3 = plane_y.GetPlaneProperty() | ||
911 | - prop3.SetColor(1, 0, 0) | 850 | + prop3 = plane_z.GetPlaneProperty() |
851 | + prop3.SetColor(1, 0, 0) | ||
852 | + | ||
853 | + selected_prop3 = plane_z.GetSelectedPlaneProperty() | ||
854 | + selected_prop3.SetColor(1,0,0) | ||
855 | + | ||
856 | + prop1 = plane_x.GetPlaneProperty() | ||
857 | + prop1.SetColor(0, 0, 1) | ||
912 | 858 | ||
913 | - prop1 = plane_x.GetPlaneProperty() | ||
914 | - prop1.SetColor(0, 0, 1) | 859 | + selected_prop1 = plane_x.GetSelectedPlaneProperty() |
860 | + selected_prop1.SetColor(0, 0, 1) | ||
861 | + | ||
862 | + prop2 = plane_y.GetPlaneProperty() | ||
863 | + prop2.SetColor(0, 1, 0) | ||
915 | 864 | ||
916 | - prop2 = plane_z.GetPlaneProperty() | ||
917 | - prop2.SetColor(0, 1, 0) | 865 | + selected_prop2 = plane_y.GetSelectedPlaneProperty() |
866 | + selected_prop2.SetColor(0, 1, 0) | ||
918 | 867 | ||
919 | ps.Publisher().sendMessage('Set Widget Interactor', plane_x) | 868 | ps.Publisher().sendMessage('Set Widget Interactor', plane_x) |
920 | ps.Publisher().sendMessage('Set Widget Interactor', plane_y) | 869 | ps.Publisher().sendMessage('Set Widget Interactor', plane_y) |
@@ -999,42 +948,12 @@ class SlicePlane: | @@ -999,42 +948,12 @@ class SlicePlane: | ||
999 | def ChangeSlice(self, pubsub_evt = None): | 948 | def ChangeSlice(self, pubsub_evt = None): |
1000 | orientation, number = pubsub_evt.data | 949 | orientation, number = pubsub_evt.data |
1001 | 950 | ||
1002 | - if (self.original_orientation == const.AXIAL): | ||
1003 | - if (orientation == "CORONAL"): | ||
1004 | - self.SetSliceNumber(number, "Y") | ||
1005 | - elif(orientation == "SAGITAL"): | ||
1006 | - self.SetSliceNumber(number, "X") | ||
1007 | - else: | ||
1008 | - self.SetSliceNumber(number, "Z") | ||
1009 | - | ||
1010 | - elif(self.original_orientation == const.SAGITAL): | ||
1011 | - if (orientation == "CORONAL"): | ||
1012 | - self.SetSliceNumber(number, "X") | ||
1013 | - elif(orientation == "SAGITAL"): | ||
1014 | - self.SetSliceNumber(number, "Z") | ||
1015 | - else: | ||
1016 | - self.SetSliceNumber(number, "Y") | ||
1017 | - | ||
1018 | - else: | ||
1019 | - if (orientation == "CORONAL"): | ||
1020 | - self.SetSliceNumber(number, "Z") | ||
1021 | - elif(orientation == "SAGITAL"): | ||
1022 | - self.SetSliceNumber(number, "X") | ||
1023 | - else: | ||
1024 | - self.SetSliceNumber(number, "Y") | ||
1025 | - | ||
1026 | - self.Render() | ||
1027 | - | ||
1028 | - def SetSliceNumber(self, number, axis): | ||
1029 | - if (axis == "X"): | ||
1030 | - self.plane_x.SetPlaneOrientationToXAxes() | ||
1031 | - self.plane_x.SetSliceIndex(number) | ||
1032 | - elif(axis == "Y"): | ||
1033 | - self.plane_y.SetPlaneOrientationToYAxes() | ||
1034 | - self.plane_y.SetSliceIndex(number) | 951 | + if (orientation == "CORONAL"): |
952 | + ps.Publisher().sendMessage('Update slice 3D', (self.plane_y,orientation)) | ||
953 | + elif(orientation == "SAGITAL"): | ||
954 | + ps.Publisher().sendMessage('Update slice 3D', (self.plane_x,orientation)) | ||
1035 | else: | 955 | else: |
1036 | - self.plane_z.SetPlaneOrientationToZAxes() | ||
1037 | - self.plane_z.SetSliceIndex(number) | 956 | + ps.Publisher().sendMessage('Update slice 3D', (self.plane_z,orientation)) |
1038 | 957 | ||
1039 | def DeletePlanes(self): | 958 | def DeletePlanes(self): |
1040 | del self.plane_x | 959 | del self.plane_x |