Commit 6da76721b2f2ffe54fee27b149f838a8aa9bd185

Authored by Thiago Franco de Moraes
Committed by GitHub
1 parent c79f0659

Created methods to get pixel and voxel position given the x,y screen position (#51)

invesalius/data/slice_.py
@@ -434,7 +434,7 @@ class Slice(object): @@ -434,7 +434,7 @@ class Slice(object):
434 thresh_min, thresh_max = self.current_mask.edition_threshold_range 434 thresh_min, thresh_max = self.current_mask.edition_threshold_range
435 435
436 if hasattr(position, '__iter__'): 436 if hasattr(position, '__iter__'):
437 - py, px = position 437 + px, py = position
438 if orientation == 'AXIAL': 438 if orientation == 'AXIAL':
439 sx = self.spacing[0] 439 sx = self.spacing[0]
440 sy = self.spacing[1] 440 sy = self.spacing[1]
invesalius/data/styles.py
@@ -76,6 +76,7 @@ def get_LUT_value(data, window, level): @@ -76,6 +76,7 @@ def get_LUT_value(data, window, level):
76 data.shape = shape 76 data.shape = shape
77 return data 77 return data
78 78
  79 +
79 class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage): 80 class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage):
80 def __init__(self, viewer): 81 def __init__(self, viewer):
81 self.right_pressed = False 82 self.right_pressed = False
@@ -213,52 +214,18 @@ class CrossInteractorStyle(DefaultInteractorStyle): @@ -213,52 +214,18 @@ class CrossInteractorStyle(DefaultInteractorStyle):
213 214
214 def ChangeCrossPosition(self, iren): 215 def ChangeCrossPosition(self, iren):
215 mouse_x, mouse_y = iren.GetEventPosition() 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.get_coordinate_cursor()  
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.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 self.ScrollSlice(coord) 221 self.ScrollSlice(coord)
229 Publisher.sendMessage('Set ball reference position based on bound', 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 Publisher.sendMessage('Render volume viewer') 225 Publisher.sendMessage('Render volume viewer')
233 226
234 iren.Render() 227 iren.Render()
235 228
236 -  
237 - def calcultate_scroll_position(self, position):  
238 - # Based in the given coord (x, y, z), returns a list with the scroll positions for each  
239 - # orientation, being the first position the sagital, second the coronal  
240 - # and the last, axial.  
241 -  
242 - if self.orientation == 'AXIAL':  
243 - image_width = self.slice_actor.GetInput().GetDimensions()[0]  
244 - axial = self.slice_data.number  
245 - coronal = position / image_width  
246 - sagital = position % image_width  
247 -  
248 - elif self.orientation == 'CORONAL':  
249 - image_width = self.slice_actor.GetInput().GetDimensions()[0]  
250 - axial = position / image_width  
251 - coronal = self.slice_data.number  
252 - sagital = position % image_width  
253 -  
254 - elif self.orientation == 'SAGITAL':  
255 - image_width = self.slice_actor.GetInput().GetDimensions()[1]  
256 - axial = position / image_width  
257 - coronal = position % image_width  
258 - sagital = self.slice_data.number  
259 -  
260 - return sagital, coronal, axial  
261 -  
262 def ScrollSlice(self, coord): 229 def ScrollSlice(self, coord):
263 if self.orientation == "AXIAL": 230 if self.orientation == "AXIAL":
264 Publisher.sendMessage(('Set scroll position', 'SAGITAL'), 231 Publisher.sendMessage(('Set scroll position', 'SAGITAL'),
@@ -276,18 +243,6 @@ class CrossInteractorStyle(DefaultInteractorStyle): @@ -276,18 +243,6 @@ class CrossInteractorStyle(DefaultInteractorStyle):
276 Publisher.sendMessage(('Set scroll position', 'SAGITAL'), 243 Publisher.sendMessage(('Set scroll position', 'SAGITAL'),
277 coord[0]) 244 coord[0])
278 245
279 - def get_coordinate_cursor(self):  
280 - # Find position  
281 - x, y, z = self.picker.GetPickPosition()  
282 - bounds = self.viewer.slice_data.actor.GetBounds()  
283 - if bounds[0] == bounds[1]:  
284 - x = bounds[0]  
285 - elif bounds[2] == bounds[3]:  
286 - y = bounds[2]  
287 - elif bounds[4] == bounds[5]:  
288 - z = bounds[4]  
289 - return x, y, z  
290 -  
291 246
292 class WWWLInteractorStyle(DefaultInteractorStyle): 247 class WWWLInteractorStyle(DefaultInteractorStyle):
293 """ 248 """
@@ -791,21 +746,13 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -791,21 +746,13 @@ class EditorInteractorStyle(DefaultInteractorStyle):
791 #i.cursor.Show(0) 746 #i.cursor.Show(0)
792 slice_data.cursor.Show() 747 slice_data.cursor.Show()
793 748
794 - self.picker.Pick(mouse_x, mouse_y, 0, render)  
795 -  
796 - coord = self.get_coordinate_cursor()  
797 - position = slice_data.actor.GetInput().FindPoint(coord) 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)
798 751
799 - if position != -1:  
800 - coord = slice_data.actor.GetInput().GetPoint(position)  
801 -  
802 - slice_data.cursor.SetPosition(coord)  
803 cursor = slice_data.cursor 752 cursor = slice_data.cursor
804 radius = cursor.radius 753 radius = cursor.radius
805 754
806 - if position < 0:  
807 - position = viewer.calculate_matrix_position(coord)  
808 - 755 + slice_data.cursor.SetPosition((wx, wy, wz))
809 viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(), 756 viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(),
810 position, radius, viewer.orientation) 757 position, radius, viewer.orientation)
811 #viewer._flush_buffer = True 758 #viewer._flush_buffer = True
@@ -842,39 +789,19 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -842,39 +789,19 @@ class EditorInteractorStyle(DefaultInteractorStyle):
842 elif operation == const.BRUSH_DRAW and iren.GetControlKey(): 789 elif operation == const.BRUSH_DRAW and iren.GetControlKey():
843 operation = const.BRUSH_ERASE 790 operation = const.BRUSH_ERASE
844 791
845 - # TODO: Improve!  
846 - #for i in self.slice_data_list:  
847 - #i.cursor.Show(0)  
848 -  
849 - self.picker.Pick(mouse_x, mouse_y, 0, render)  
850 -  
851 - #if (self.pick.GetViewProp()):  
852 - #self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_BLANK))  
853 - #else:  
854 - #self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))  
855 -  
856 - coord = self.get_coordinate_cursor()  
857 - position = viewer.slice_data.actor.GetInput().FindPoint(coord)  
858 -  
859 - # when position == -1 the cursos is not over the image, so is not  
860 - # necessary to set the cursor position to world coordinate center of  
861 - # pixel from slice image.  
862 - if position != -1:  
863 - coord = slice_data.actor.GetInput().GetPoint(position)  
864 - slice_data.cursor.SetPosition(coord)  
865 - #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))
866 794
867 if (self.left_pressed): 795 if (self.left_pressed):
868 cursor = slice_data.cursor 796 cursor = slice_data.cursor
869 - position = slice_data.actor.GetInput().FindPoint(coord)  
870 radius = cursor.radius 797 radius = cursor.radius
871 798
872 - if position < 0:  
873 - position = viewer.calculate_matrix_position(coord) 799 + position = viewer.get_slice_pixel_coord_by_world_pos(wx, wy, wz)
874 800
  801 + slice_data.cursor.SetPosition((wx, wy, wz))
875 viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(), 802 viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(),
876 - position, radius, self.orientation)  
877 - # TODO: To create a new function to reload images to viewer. 803 + position, radius, viewer.orientation)
  804 +
878 viewer.OnScrollBar(update3D=False) 805 viewer.OnScrollBar(update3D=False)
879 806
880 else: 807 else:
@@ -924,18 +851,6 @@ class EditorInteractorStyle(DefaultInteractorStyle): @@ -924,18 +851,6 @@ class EditorInteractorStyle(DefaultInteractorStyle):
924 else: 851 else:
925 self.OnScrollBackward(obj, evt) 852 self.OnScrollBackward(obj, evt)
926 853
927 - def get_coordinate_cursor(self):  
928 - # Find position  
929 - x, y, z = self.picker.GetPickPosition()  
930 - bounds = self.viewer.slice_data.actor.GetBounds()  
931 - if bounds[0] == bounds[1]:  
932 - x = bounds[0]  
933 - elif bounds[2] == bounds[3]:  
934 - y = bounds[2]  
935 - elif bounds[4] == bounds[5]:  
936 - z = bounds[4]  
937 - return x, y, z  
938 -  
939 854
940 class WatershedProgressWindow(object): 855 class WatershedProgressWindow(object):
941 def __init__(self, process): 856 def __init__(self, process):
@@ -1153,28 +1068,15 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): @@ -1153,28 +1068,15 @@ class WaterShedInteractorStyle(DefaultInteractorStyle):
1153 render = iren.FindPokedRenderer(mouse_x, mouse_y) 1068 render = iren.FindPokedRenderer(mouse_x, mouse_y)
1154 slice_data = viewer.get_slice_data(render) 1069 slice_data = viewer.get_slice_data(render)
1155 1070
1156 - # TODO: Improve!  
1157 - #for i in self.slice_data_list:  
1158 - #i.cursor.Show(0)  
1159 - slice_data.cursor.Show()  
1160 -  
1161 - self.picker.Pick(mouse_x, mouse_y, 0, render)  
1162 -  
1163 - coord = self.get_coordinate_cursor()  
1164 - position = slice_data.actor.GetInput().FindPoint(coord)  
1165 -  
1166 - if position != -1:  
1167 - 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)
1168 1073
  1074 + slice_data.cursor.Show()
1169 slice_data.cursor.SetPosition(coord) 1075 slice_data.cursor.SetPosition(coord)
1170 1076
1171 cursor = slice_data.cursor 1077 cursor = slice_data.cursor
1172 - position = slice_data.actor.GetInput().FindPoint(coord)  
1173 radius = cursor.radius 1078 radius = cursor.radius
1174 1079
1175 - if position < 0:  
1176 - position = viewer.calculate_matrix_position(coord)  
1177 -  
1178 operation = self.config.operation 1080 operation = self.config.operation
1179 1081
1180 if operation == BRUSH_FOREGROUND: 1082 if operation == BRUSH_FOREGROUND:
@@ -1213,31 +1115,13 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): @@ -1213,31 +1115,13 @@ class WaterShedInteractorStyle(DefaultInteractorStyle):
1213 render = iren.FindPokedRenderer(mouse_x, mouse_y) 1115 render = iren.FindPokedRenderer(mouse_x, mouse_y)
1214 slice_data = viewer.get_slice_data(render) 1116 slice_data = viewer.get_slice_data(render)
1215 1117
1216 - # TODO: Improve!  
1217 - #for i in self.slice_data_list:  
1218 - #i.cursor.Show(0)  
1219 -  
1220 - self.picker.Pick(mouse_x, mouse_y, 0, render)  
1221 -  
1222 - #if (self.pick.GetViewProp()):  
1223 - #self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_BLANK))  
1224 - #else:  
1225 - #self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))  
1226 -  
1227 - coord = self.get_coordinate_cursor()  
1228 - position = viewer.slice_data.actor.GetInput().FindPoint(coord)  
1229 -  
1230 - # when position == -1 the cursos is not over the image, so is not  
1231 - # necessary to set the cursor position to world coordinate center of  
1232 - # pixel from slice image.  
1233 - if position != -1:  
1234 - coord = slice_data.actor.GetInput().GetPoint(position) 1118 + coord = self.viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker)
1235 slice_data.cursor.SetPosition(coord) 1119 slice_data.cursor.SetPosition(coord)
1236 - #self.__update_cursor_position(slice_data, coord)  
1237 1120
1238 if (self.left_pressed): 1121 if (self.left_pressed):
1239 cursor = slice_data.cursor 1122 cursor = slice_data.cursor
1240 - position = slice_data.actor.GetInput().FindPoint(coord) 1123 + position = self.viewer.get_slice_pixel_coord_by_world_pos(*coord)
  1124 + print ">>>", position
1241 radius = cursor.radius 1125 radius = cursor.radius
1242 1126
1243 if position < 0: 1127 if position < 0:
@@ -1344,18 +1228,6 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): @@ -1344,18 +1228,6 @@ class WaterShedInteractorStyle(DefaultInteractorStyle):
1344 1228
1345 Publisher.sendMessage('Reload actual slice') 1229 Publisher.sendMessage('Reload actual slice')
1346 1230
1347 - def get_coordinate_cursor(self):  
1348 - # Find position  
1349 - x, y, z = self.picker.GetPickPosition()  
1350 - bounds = self.viewer.slice_data.actor.GetBounds()  
1351 - if bounds[0] == bounds[1]:  
1352 - x = bounds[0]  
1353 - elif bounds[2] == bounds[3]:  
1354 - y = bounds[2]  
1355 - elif bounds[4] == bounds[5]:  
1356 - z = bounds[4]  
1357 - return x, y, z  
1358 -  
1359 def edit_mask_pixel(self, operation, n, index, position, radius, orientation): 1231 def edit_mask_pixel(self, operation, n, index, position, radius, orientation):
1360 if orientation == 'AXIAL': 1232 if orientation == 'AXIAL':
1361 mask = self.matrix[n, :, :] 1233 mask = self.matrix[n, :, :]
@@ -1366,7 +1238,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): @@ -1366,7 +1238,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle):
1366 1238
1367 spacing = self.viewer.slice_.spacing 1239 spacing = self.viewer.slice_.spacing
1368 if hasattr(position, '__iter__'): 1240 if hasattr(position, '__iter__'):
1369 - py, px = position 1241 + px, py = position
1370 if orientation == 'AXIAL': 1242 if orientation == 'AXIAL':
1371 sx = spacing[0] 1243 sx = spacing[0]
1372 sy = spacing[1] 1244 sy = spacing[1]
@@ -1804,24 +1676,10 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): @@ -1804,24 +1676,10 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle):
1804 1676
1805 viewer = self.viewer 1677 viewer = self.viewer
1806 iren = viewer.interactor 1678 iren = viewer.interactor
1807 -  
1808 mouse_x, mouse_y = iren.GetEventPosition() 1679 mouse_x, mouse_y = iren.GetEventPosition()
1809 - render = iren.FindPokedRenderer(mouse_x, mouse_y)  
1810 - slice_data = viewer.get_slice_data(render)  
1811 -  
1812 - self.picker.Pick(mouse_x, mouse_y, 0, render)  
1813 -  
1814 - coord = self.get_coordinate_cursor()  
1815 - position = slice_data.actor.GetInput().FindPoint(coord)  
1816 -  
1817 - if position != -1:  
1818 - coord = slice_data.actor.GetInput().GetPoint(position)  
1819 -  
1820 - if position < 0:  
1821 - position = viewer.calculate_matrix_position(coord) 1680 + x, y, z = self.viewer.get_voxel_coord_by_screen_pos(mouse_x, mouse_y, self.picker)
1822 1681
1823 mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] 1682 mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:]
1824 - x, y, z = self.calcultate_scroll_position(position)  
1825 if mask[z, y, x] < self.t0 or mask[z, y, x] > self.t1: 1683 if mask[z, y, x] < self.t0 or mask[z, y, x] > self.t1:
1826 return 1684 return
1827 1685
@@ -1878,43 +1736,6 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): @@ -1878,43 +1736,6 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle):
1878 self.viewer.slice_.current_mask.was_edited = True 1736 self.viewer.slice_.current_mask.was_edited = True
1879 Publisher.sendMessage('Reload actual slice') 1737 Publisher.sendMessage('Reload actual slice')
1880 1738
1881 - def get_coordinate_cursor(self):  
1882 - # Find position  
1883 - x, y, z = self.picker.GetPickPosition()  
1884 - bounds = self.viewer.slice_data.actor.GetBounds()  
1885 - if bounds[0] == bounds[1]:  
1886 - x = bounds[0]  
1887 - elif bounds[2] == bounds[3]:  
1888 - y = bounds[2]  
1889 - elif bounds[4] == bounds[5]:  
1890 - z = bounds[4]  
1891 - return x, y, z  
1892 -  
1893 - def calcultate_scroll_position(self, position):  
1894 - # Based in the given coord (x, y, z), returns a list with the scroll positions for each  
1895 - # orientation, being the first position the sagital, second the coronal  
1896 - # and the last, axial.  
1897 -  
1898 - if self.orientation == 'AXIAL':  
1899 - image_width = self.slice_actor.GetInput().GetDimensions()[0]  
1900 - axial = self.slice_data.number  
1901 - coronal = position / image_width  
1902 - sagital = position % image_width  
1903 -  
1904 - elif self.orientation == 'CORONAL':  
1905 - image_width = self.slice_actor.GetInput().GetDimensions()[0]  
1906 - axial = position / image_width  
1907 - coronal = self.slice_data.number  
1908 - sagital = position % image_width  
1909 -  
1910 - elif self.orientation == 'SAGITAL':  
1911 - image_width = self.slice_actor.GetInput().GetDimensions()[1]  
1912 - axial = position / image_width  
1913 - coronal = position % image_width  
1914 - sagital = self.slice_data.number  
1915 -  
1916 - return sagital, coronal, axial  
1917 -  
1918 1739
1919 class RemoveMaskPartsInteractorStyle(FloodFillMaskInteractorStyle): 1740 class RemoveMaskPartsInteractorStyle(FloodFillMaskInteractorStyle):
1920 def __init__(self, viewer): 1741 def __init__(self, viewer):
@@ -1989,7 +1810,7 @@ class SelectMaskPartsInteractorStyle(DefaultInteractorStyle): @@ -1989,7 +1810,7 @@ class SelectMaskPartsInteractorStyle(DefaultInteractorStyle):
1989 1810
1990 iren = self.viewer.interactor 1811 iren = self.viewer.interactor
1991 mouse_x, mouse_y = iren.GetEventPosition() 1812 mouse_x, mouse_y = iren.GetEventPosition()
1992 - 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)
1993 1814
1994 mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] 1815 mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:]
1995 1816
invesalius/data/viewer_slice.py
@@ -940,25 +940,23 @@ class Viewer(wx.Panel): @@ -940,25 +940,23 @@ class Viewer(wx.Panel):
940 # WARN: Return the only slice_data used in this slice_viewer. 940 # WARN: Return the only slice_data used in this slice_viewer.
941 return self.slice_data 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 # orientation, being the first position the sagital, second the coronal 945 # orientation, being the first position the sagital, second the coronal
946 # and the last, axial. 946 # and the last, axial.
947 - image_width = self.slice_.buffer_slices[self.orientation].image.shape[1]  
948 -  
949 if self.orientation == 'AXIAL': 947 if self.orientation == 'AXIAL':
950 axial = self.slice_data.number 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 elif self.orientation == 'CORONAL': 952 elif self.orientation == 'CORONAL':
955 - axial = position / image_width 953 + axial = y
956 coronal = self.slice_data.number 954 coronal = self.slice_data.number
957 - sagital = position % image_width 955 + sagital = x
958 956
959 elif self.orientation == 'SAGITAL': 957 elif self.orientation == 'SAGITAL':
960 - axial = position / image_width  
961 - coronal = position % image_width 958 + axial = y
  959 + coronal = x
962 sagital = self.slice_data.number 960 sagital = self.slice_data.number
963 961
964 return sagital, coronal, axial 962 return sagital, coronal, axial
@@ -975,13 +973,28 @@ class Viewer(wx.Panel): @@ -975,13 +973,28 @@ class Viewer(wx.Panel):
975 elif self.orientation == 'SAGITAL': 973 elif self.orientation == 'SAGITAL':
976 mx = round((y - yi)/self.slice_.spacing[1], 0) 974 mx = round((y - yi)/self.slice_.spacing[1], 0)
977 my = round((z - zi)/self.slice_.spacing[2], 0) 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 if picker is None: 991 if picker is None:
983 picker = self.pick 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 x, y, z = picker.GetPickPosition() 998 x, y, z = picker.GetPickPosition()
986 bounds = self.slice_data.actor.GetBounds() 999 bounds = self.slice_data.actor.GetBounds()
987 if bounds[0] == bounds[1]: 1000 if bounds[0] == bounds[1]:
@@ -1029,10 +1042,10 @@ class Viewer(wx.Panel): @@ -1029,10 +1042,10 @@ class Viewer(wx.Panel):
1029 1042
1030 return x, y, z 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 Parameters: 1050 Parameters:
1038 mx (int): x position. 1051 mx (int): x position.
@@ -1046,23 +1059,86 @@ class Viewer(wx.Panel): @@ -1046,23 +1059,86 @@ class Viewer(wx.Panel):
1046 if picker is None: 1059 if picker is None:
1047 picker = self.pick 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 slice_data = self.slice_data 1132 slice_data = self.slice_data
1050 renderer = slice_data.renderer 1133 renderer = slice_data.renderer
1051 1134
1052 - picker.Pick(mx, my, 0, renderer)  
1053 -  
1054 coord = self.get_coordinate_cursor(picker) 1135 coord = self.get_coordinate_cursor(picker)
1055 position = slice_data.actor.GetInput().FindPoint(coord) 1136 position = slice_data.actor.GetInput().FindPoint(coord)
1056 1137
1057 if position != -1: 1138 if position != -1:
1058 coord = slice_data.actor.GetInput().GetPoint(position) 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 def __bind_events(self): 1143 def __bind_events(self):
1068 Publisher.subscribe(self.LoadImagedata, 1144 Publisher.subscribe(self.LoadImagedata,