Commit a25e8aebd96bcc7d9dab8d95cd435cf0e5ba219c

Authored by Thiago Franco de Moraes
2 parents 10945a2a 6da76721

Merge

invesalius/data/slice_.py
... ... @@ -434,7 +434,7 @@ class Slice(object):
434 434 thresh_min, thresh_max = self.current_mask.edition_threshold_range
435 435  
436 436 if hasattr(position, '__iter__'):
437   - py, px = position
  437 + px, py = position
438 438 if orientation == 'AXIAL':
439 439 sx = self.spacing[0]
440 440 sy = self.spacing[1]
... ...
invesalius/data/styles.py
... ... @@ -76,6 +76,7 @@ def get_LUT_value(data, window, level):
76 76 data.shape = shape
77 77 return data
78 78  
  79 +
79 80 class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage):
80 81 def __init__(self, viewer):
81 82 self.right_pressed = False
... ... @@ -213,22 +214,14 @@ class CrossInteractorStyle(DefaultInteractorStyle):
213 214  
214 215 def ChangeCrossPosition(self, iren):
215 216 mouse_x, mouse_y = iren.GetEventPosition()
216   - ren = iren.GetRenderWindow().GetRenderers().GetFirstRenderer()
217   - self.picker.Pick(mouse_x, mouse_y, 0, ren)
218   -
219   - # Get in what slice data the click occurred
220   - # pick to get click position in the 3d world
221   - coord_cross = self.viewer.get_coordinate_cursor(self.picker)
222   - position = self.slice_actor.GetInput().FindPoint(coord_cross)
223   - # Forcing focal point to be setted in the center of the pixel.
224   - coord_cross = self.slice_actor.GetInput().GetPoint(position)
225   -
226   - coord = self.viewer.calcultate_scroll_position(position)
227   - Publisher.sendMessage('Update cross position', coord_cross)
  217 + wx, wy, wz = self.viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker)
  218 + px, py = self.viewer.get_slice_pixel_coord_by_world_pos(wx, wy, wz)
  219 + coord = self.viewer.calcultate_scroll_position(px, py)
  220 + Publisher.sendMessage('Update cross position', (wx, wy, wz))
228 221 self.ScrollSlice(coord)
229 222 Publisher.sendMessage('Set ball reference position based on bound',
230   - coord_cross)
231   - Publisher.sendMessage('Set camera in volume', coord_cross)
  223 + (wx, wy, wz))
  224 + Publisher.sendMessage('Set camera in volume', (wx, wy, wz))
232 225 Publisher.sendMessage('Render volume viewer')
233 226  
234 227 iren.Render()
... ... @@ -753,21 +746,13 @@ class EditorInteractorStyle(DefaultInteractorStyle):
753 746 #i.cursor.Show(0)
754 747 slice_data.cursor.Show()
755 748  
756   - self.picker.Pick(mouse_x, mouse_y, 0, render)
757   -
758   - coord = self.get_coordinate_cursor()
759   - position = slice_data.actor.GetInput().FindPoint(coord)
760   -
761   - if position != -1:
762   - coord = slice_data.actor.GetInput().GetPoint(position)
  749 + wx, wy, wz = viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker)
  750 + position = viewer.get_slice_pixel_coord_by_world_pos(wx, wy, wz)
763 751  
764   - slice_data.cursor.SetPosition(coord)
765 752 cursor = slice_data.cursor
766 753 radius = cursor.radius
767 754  
768   - if position < 0:
769   - position = viewer.calculate_matrix_position(coord)
770   -
  755 + slice_data.cursor.SetPosition((wx, wy, wz))
771 756 viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(),
772 757 position, radius, viewer.orientation)
773 758 #viewer._flush_buffer = True
... ... @@ -804,39 +789,19 @@ class EditorInteractorStyle(DefaultInteractorStyle):
804 789 elif operation == const.BRUSH_DRAW and iren.GetControlKey():
805 790 operation = const.BRUSH_ERASE
806 791  
807   - # TODO: Improve!
808   - #for i in self.slice_data_list:
809   - #i.cursor.Show(0)
810   -
811   - self.picker.Pick(mouse_x, mouse_y, 0, render)
812   -
813   - #if (self.pick.GetViewProp()):
814   - #self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_BLANK))
815   - #else:
816   - #self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
817   -
818   - coord = self.get_coordinate_cursor()
819   - position = viewer.slice_data.actor.GetInput().FindPoint(coord)
820   -
821   - # when position == -1 the cursos is not over the image, so is not
822   - # necessary to set the cursor position to world coordinate center of
823   - # pixel from slice image.
824   - if position != -1:
825   - coord = slice_data.actor.GetInput().GetPoint(position)
826   - slice_data.cursor.SetPosition(coord)
827   - #self.__update_cursor_position(slice_data, coord)
  792 + wx, wy, wz = viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker)
  793 + slice_data.cursor.SetPosition((wx, wy, wz))
828 794  
829 795 if (self.left_pressed):
830 796 cursor = slice_data.cursor
831   - position = slice_data.actor.GetInput().FindPoint(coord)
832 797 radius = cursor.radius
833 798  
834   - if position < 0:
835   - position = viewer.calculate_matrix_position(coord)
  799 + position = viewer.get_slice_pixel_coord_by_world_pos(wx, wy, wz)
836 800  
  801 + slice_data.cursor.SetPosition((wx, wy, wz))
837 802 viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(),
838   - position, radius, self.orientation)
839   - # TODO: To create a new function to reload images to viewer.
  803 + position, radius, viewer.orientation)
  804 +
840 805 viewer.OnScrollBar(update3D=False)
841 806  
842 807 else:
... ... @@ -886,18 +851,6 @@ class EditorInteractorStyle(DefaultInteractorStyle):
886 851 else:
887 852 self.OnScrollBackward(obj, evt)
888 853  
889   - def get_coordinate_cursor(self):
890   - # Find position
891   - x, y, z = self.picker.GetPickPosition()
892   - bounds = self.viewer.slice_data.actor.GetBounds()
893   - if bounds[0] == bounds[1]:
894   - x = bounds[0]
895   - elif bounds[2] == bounds[3]:
896   - y = bounds[2]
897   - elif bounds[4] == bounds[5]:
898   - z = bounds[4]
899   - return x, y, z
900   -
901 854  
902 855 class WatershedProgressWindow(object):
903 856 def __init__(self, process):
... ... @@ -1115,28 +1068,15 @@ class WaterShedInteractorStyle(DefaultInteractorStyle):
1115 1068 render = iren.FindPokedRenderer(mouse_x, mouse_y)
1116 1069 slice_data = viewer.get_slice_data(render)
1117 1070  
1118   - # TODO: Improve!
1119   - #for i in self.slice_data_list:
1120   - #i.cursor.Show(0)
1121   - slice_data.cursor.Show()
1122   -
1123   - self.picker.Pick(mouse_x, mouse_y, 0, render)
1124   -
1125   - coord = self.get_coordinate_cursor()
1126   - position = slice_data.actor.GetInput().FindPoint(coord)
1127   -
1128   - if position != -1:
1129   - coord = slice_data.actor.GetInput().GetPoint(position)
  1071 + coord = self.viewer.get_coordinate_cursor(mouse_x, mouse_y, picker=None)
  1072 + position = self.viewer.get_slice_pixel_coord_by_screen_pos(mouse_x, mouse_y, self.picker)
1130 1073  
  1074 + slice_data.cursor.Show()
1131 1075 slice_data.cursor.SetPosition(coord)
1132 1076  
1133 1077 cursor = slice_data.cursor
1134   - position = slice_data.actor.GetInput().FindPoint(coord)
1135 1078 radius = cursor.radius
1136 1079  
1137   - if position < 0:
1138   - position = viewer.calculate_matrix_position(coord)
1139   -
1140 1080 operation = self.config.operation
1141 1081  
1142 1082 if operation == BRUSH_FOREGROUND:
... ... @@ -1175,31 +1115,13 @@ class WaterShedInteractorStyle(DefaultInteractorStyle):
1175 1115 render = iren.FindPokedRenderer(mouse_x, mouse_y)
1176 1116 slice_data = viewer.get_slice_data(render)
1177 1117  
1178   - # TODO: Improve!
1179   - #for i in self.slice_data_list:
1180   - #i.cursor.Show(0)
1181   -
1182   - self.picker.Pick(mouse_x, mouse_y, 0, render)
1183   -
1184   - #if (self.pick.GetViewProp()):
1185   - #self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_BLANK))
1186   - #else:
1187   - #self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
1188   -
1189   - coord = self.get_coordinate_cursor()
1190   - position = viewer.slice_data.actor.GetInput().FindPoint(coord)
1191   -
1192   - # when position == -1 the cursos is not over the image, so is not
1193   - # necessary to set the cursor position to world coordinate center of
1194   - # pixel from slice image.
1195   - if position != -1:
1196   - coord = slice_data.actor.GetInput().GetPoint(position)
  1118 + coord = self.viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker)
1197 1119 slice_data.cursor.SetPosition(coord)
1198   - #self.__update_cursor_position(slice_data, coord)
1199 1120  
1200 1121 if (self.left_pressed):
1201 1122 cursor = slice_data.cursor
1202   - position = slice_data.actor.GetInput().FindPoint(coord)
  1123 + position = self.viewer.get_slice_pixel_coord_by_world_pos(*coord)
  1124 + print ">>>", position
1203 1125 radius = cursor.radius
1204 1126  
1205 1127 if position < 0:
... ... @@ -1306,18 +1228,6 @@ class WaterShedInteractorStyle(DefaultInteractorStyle):
1306 1228  
1307 1229 Publisher.sendMessage('Reload actual slice')
1308 1230  
1309   - def get_coordinate_cursor(self):
1310   - # Find position
1311   - x, y, z = self.picker.GetPickPosition()
1312   - bounds = self.viewer.slice_data.actor.GetBounds()
1313   - if bounds[0] == bounds[1]:
1314   - x = bounds[0]
1315   - elif bounds[2] == bounds[3]:
1316   - y = bounds[2]
1317   - elif bounds[4] == bounds[5]:
1318   - z = bounds[4]
1319   - return x, y, z
1320   -
1321 1231 def edit_mask_pixel(self, operation, n, index, position, radius, orientation):
1322 1232 if orientation == 'AXIAL':
1323 1233 mask = self.matrix[n, :, :]
... ... @@ -1328,7 +1238,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle):
1328 1238  
1329 1239 spacing = self.viewer.slice_.spacing
1330 1240 if hasattr(position, '__iter__'):
1331   - py, px = position
  1241 + px, py = position
1332 1242 if orientation == 'AXIAL':
1333 1243 sx = spacing[0]
1334 1244 sy = spacing[1]
... ... @@ -1767,7 +1677,7 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle):
1767 1677 viewer = self.viewer
1768 1678 iren = viewer.interactor
1769 1679 mouse_x, mouse_y = iren.GetEventPosition()
1770   - x, y, z = self.viewer.get_voxel_clicked(mouse_x, mouse_y, self.picker)
  1680 + x, y, z = self.viewer.get_voxel_coord_by_screen_pos(mouse_x, mouse_y, self.picker)
1771 1681  
1772 1682 mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:]
1773 1683 if mask[z, y, x] < self.t0 or mask[z, y, x] > self.t1:
... ... @@ -1900,7 +1810,7 @@ class SelectMaskPartsInteractorStyle(DefaultInteractorStyle):
1900 1810  
1901 1811 iren = self.viewer.interactor
1902 1812 mouse_x, mouse_y = iren.GetEventPosition()
1903   - x, y, z = self.viewer.get_voxel_clicked(mouse_x, mouse_y, self.picker)
  1813 + x, y, z = self.viewer.get_voxel_coord_by_screen_pos(mouse_x, mouse_y, self.picker)
1904 1814  
1905 1815 mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:]
1906 1816  
... ...
invesalius/data/viewer_slice.py
... ... @@ -940,25 +940,23 @@ class Viewer(wx.Panel):
940 940 # WARN: Return the only slice_data used in this slice_viewer.
941 941 return self.slice_data
942 942  
943   - def calcultate_scroll_position(self, position):
944   - # Based in the given coord (x, y, z), returns a list with the scroll positions for each
  943 + def calcultate_scroll_position(self, x, y):
  944 + # Based in the given coord (x, y), returns a list with the scroll positions for each
945 945 # orientation, being the first position the sagital, second the coronal
946 946 # and the last, axial.
947   - image_width = self.slice_.buffer_slices[self.orientation].image.shape[1]
948   -
949 947 if self.orientation == 'AXIAL':
950 948 axial = self.slice_data.number
951   - coronal = position / image_width
952   - sagital = position % image_width
  949 + coronal = y
  950 + sagital = x
953 951  
954 952 elif self.orientation == 'CORONAL':
955   - axial = position / image_width
  953 + axial = y
956 954 coronal = self.slice_data.number
957   - sagital = position % image_width
  955 + sagital = x
958 956  
959 957 elif self.orientation == 'SAGITAL':
960   - axial = position / image_width
961   - coronal = position % image_width
  958 + axial = y
  959 + coronal = x
962 960 sagital = self.slice_data.number
963 961  
964 962 return sagital, coronal, axial
... ... @@ -975,13 +973,28 @@ class Viewer(wx.Panel):
975 973 elif self.orientation == 'SAGITAL':
976 974 mx = round((y - yi)/self.slice_.spacing[1], 0)
977 975 my = round((z - zi)/self.slice_.spacing[2], 0)
978   - return my, mx
  976 + return mx, my
979 977  
980   - def get_coordinate_cursor(self, picker=None):
981   - # Find position
  978 + def get_coordinate_cursor(self, mx, my, picker=None):
  979 + """
  980 + Given the mx, my screen position returns the x, y, z position in world
  981 + coordinates.
  982 +
  983 + Parameters
  984 + mx (int): x position.
  985 + my (int): y position
  986 + picker: the picker used to get calculate the voxel coordinate.
  987 +
  988 + Returns:
  989 + world coordinate (x, y, z)
  990 + """
982 991 if picker is None:
983 992 picker = self.pick
984 993  
  994 + slice_data = self.slice_data
  995 + renderer = slice_data.renderer
  996 +
  997 + picker.Pick(mx, my, 0, renderer)
985 998 x, y, z = picker.GetPickPosition()
986 999 bounds = self.slice_data.actor.GetBounds()
987 1000 if bounds[0] == bounds[1]:
... ... @@ -1029,10 +1042,10 @@ class Viewer(wx.Panel):
1029 1042  
1030 1043 return x, y, z
1031 1044  
1032   - def get_voxel_clicked(self, mx, my, picker=None):
  1045 + def get_voxel_coord_by_screen_pos(self, mx, my, picker=None):
1033 1046 """
1034   - Given the (mx, my) mouse clicked position returns the voxel coordinate
1035   - of the voxel at (that mx, my) position.
  1047 + Given the (mx, my) screen position returns the voxel coordinate
  1048 + of the volume at (that mx, my) position.
1036 1049  
1037 1050 Parameters:
1038 1051 mx (int): x position.
... ... @@ -1046,23 +1059,86 @@ class Viewer(wx.Panel):
1046 1059 if picker is None:
1047 1060 picker = self.pick
1048 1061  
  1062 + wx, wy, wz = self.get_coordinate_cursor(mx, my, picker)
  1063 + x, y, z = self.get_voxel_coord_by_world_pos(wx, wy, wz)
  1064 +
  1065 + return (x, y, z)
  1066 +
  1067 + def get_voxel_coord_by_world_pos(self, wx, wy, wz):
  1068 + """
  1069 + Given the (x, my) screen position returns the voxel coordinate
  1070 + of the volume at (that mx, my) position.
  1071 +
  1072 + Parameters:
  1073 + wx (float): x position.
  1074 + wy (float): y position
  1075 + wz (float): z position
  1076 +
  1077 + Returns:
  1078 + voxel_coordinate (x, y, z): voxel coordinate inside the matrix. Can
  1079 + be used to access the voxel value inside the matrix.
  1080 + """
  1081 + px, py = self.get_slice_pixel_coord_by_world_pos(wx, wy, wz)
  1082 + x, y, z = self.calcultate_scroll_position(px, py)
  1083 +
  1084 + return (x, y, z)
  1085 +
  1086 +
  1087 + def get_slice_pixel_coord_by_screen_pos(self, mx, my, picker=None):
  1088 + """
  1089 + Given the (mx, my) screen position returns the pixel coordinate
  1090 + of the slice at (that mx, my) position.
  1091 +
  1092 + Parameters:
  1093 + mx (int): x position.
  1094 + my (int): y position
  1095 + picker: the picker used to get calculate the pixel coordinate.
  1096 +
  1097 + Returns:
  1098 + voxel_coordinate (x, y): voxel coordinate inside the matrix. Can
  1099 + be used to access the voxel value inside the matrix.
  1100 + """
  1101 + if picker is None:
  1102 + picker = self.pick
  1103 +
  1104 + wx, wy, wz = self.get_coordinate_cursor(mx, my, picker)
  1105 + return self.get_slice_pixel_coord_by_world_pos(wx, wy, wz)
  1106 +
  1107 + return px, py
  1108 +
  1109 + def get_slice_pixel_coord_by_world_pos(self, wx, wy, wz):
  1110 + """
  1111 + Given the (wx, wy, wz) world position returns the pixel coordinate
  1112 + of the slice at (that mx, my) position.
  1113 +
  1114 + Parameters:
  1115 + mx (int): x position.
  1116 + my (int): y position
  1117 + picker: the picker used to get calculate the pixel coordinate.
  1118 +
  1119 + Returns:
  1120 + voxel_coordinate (x, y): voxel coordinate inside the matrix. Can
  1121 + be used to access the voxel value inside the matrix.
  1122 + """
  1123 + coord = wx, wy, wz
  1124 + px, py = self.calculate_matrix_position(coord)
  1125 +
  1126 + return px, py
  1127 +
  1128 + def get_coord_inside_volume(self, mx, my, picker=None):
  1129 + if picker is None:
  1130 + picker = self.pick
  1131 +
1049 1132 slice_data = self.slice_data
1050 1133 renderer = slice_data.renderer
1051 1134  
1052   - picker.Pick(mx, my, 0, renderer)
1053   -
1054 1135 coord = self.get_coordinate_cursor(picker)
1055 1136 position = slice_data.actor.GetInput().FindPoint(coord)
1056 1137  
1057 1138 if position != -1:
1058 1139 coord = slice_data.actor.GetInput().GetPoint(position)
1059 1140  
1060   - if position < 0:
1061   - position = viewer.calculate_matrix_position(coord)
1062   -
1063   - x, y, z = self.calcultate_scroll_position(position)
1064   -
1065   - return (x, y, z)
  1141 + return coord
1066 1142  
1067 1143 def __bind_events(self):
1068 1144 Publisher.subscribe(self.LoadImagedata,
... ...