Commit 6da76721b2f2ffe54fee27b149f838a8aa9bd185
Committed by
GitHub
1 parent
c79f0659
Exists in
master
and in
19 other branches
Created methods to get pixel and voxel position given the x,y screen position (#51)
Showing
3 changed files
with
126 additions
and
229 deletions
Show diff stats
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,52 +214,18 @@ 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.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 | 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() |
| 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 | 229 | def ScrollSlice(self, coord): |
| 263 | 230 | if self.orientation == "AXIAL": |
| 264 | 231 | Publisher.sendMessage(('Set scroll position', 'SAGITAL'), |
| ... | ... | @@ -276,18 +243,6 @@ class CrossInteractorStyle(DefaultInteractorStyle): |
| 276 | 243 | Publisher.sendMessage(('Set scroll position', 'SAGITAL'), |
| 277 | 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 | 247 | class WWWLInteractorStyle(DefaultInteractorStyle): |
| 293 | 248 | """ |
| ... | ... | @@ -791,21 +746,13 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
| 791 | 746 | #i.cursor.Show(0) |
| 792 | 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 | 752 | cursor = slice_data.cursor |
| 804 | 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 | 756 | viewer.slice_.edit_mask_pixel(operation, cursor.GetPixels(), |
| 810 | 757 | position, radius, viewer.orientation) |
| 811 | 758 | #viewer._flush_buffer = True |
| ... | ... | @@ -842,39 +789,19 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
| 842 | 789 | elif operation == const.BRUSH_DRAW and iren.GetControlKey(): |
| 843 | 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 | 795 | if (self.left_pressed): |
| 868 | 796 | cursor = slice_data.cursor |
| 869 | - position = slice_data.actor.GetInput().FindPoint(coord) | |
| 870 | 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 | 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 | 805 | viewer.OnScrollBar(update3D=False) |
| 879 | 806 | |
| 880 | 807 | else: |
| ... | ... | @@ -924,18 +851,6 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
| 924 | 851 | else: |
| 925 | 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 | 855 | class WatershedProgressWindow(object): |
| 941 | 856 | def __init__(self, process): |
| ... | ... | @@ -1153,28 +1068,15 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
| 1153 | 1068 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
| 1154 | 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 | 1075 | slice_data.cursor.SetPosition(coord) |
| 1170 | 1076 | |
| 1171 | 1077 | cursor = slice_data.cursor |
| 1172 | - position = slice_data.actor.GetInput().FindPoint(coord) | |
| 1173 | 1078 | radius = cursor.radius |
| 1174 | 1079 | |
| 1175 | - if position < 0: | |
| 1176 | - position = viewer.calculate_matrix_position(coord) | |
| 1177 | - | |
| 1178 | 1080 | operation = self.config.operation |
| 1179 | 1081 | |
| 1180 | 1082 | if operation == BRUSH_FOREGROUND: |
| ... | ... | @@ -1213,31 +1115,13 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
| 1213 | 1115 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
| 1214 | 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 | 1119 | slice_data.cursor.SetPosition(coord) |
| 1236 | - #self.__update_cursor_position(slice_data, coord) | |
| 1237 | 1120 | |
| 1238 | 1121 | if (self.left_pressed): |
| 1239 | 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 | 1125 | radius = cursor.radius |
| 1242 | 1126 | |
| 1243 | 1127 | if position < 0: |
| ... | ... | @@ -1344,18 +1228,6 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
| 1344 | 1228 | |
| 1345 | 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 | 1231 | def edit_mask_pixel(self, operation, n, index, position, radius, orientation): |
| 1360 | 1232 | if orientation == 'AXIAL': |
| 1361 | 1233 | mask = self.matrix[n, :, :] |
| ... | ... | @@ -1366,7 +1238,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
| 1366 | 1238 | |
| 1367 | 1239 | spacing = self.viewer.slice_.spacing |
| 1368 | 1240 | if hasattr(position, '__iter__'): |
| 1369 | - py, px = position | |
| 1241 | + px, py = position | |
| 1370 | 1242 | if orientation == 'AXIAL': |
| 1371 | 1243 | sx = spacing[0] |
| 1372 | 1244 | sy = spacing[1] |
| ... | ... | @@ -1804,24 +1676,10 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): |
| 1804 | 1676 | |
| 1805 | 1677 | viewer = self.viewer |
| 1806 | 1678 | iren = viewer.interactor |
| 1807 | - | |
| 1808 | 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 | 1682 | mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] |
| 1824 | - x, y, z = self.calcultate_scroll_position(position) | |
| 1825 | 1683 | if mask[z, y, x] < self.t0 or mask[z, y, x] > self.t1: |
| 1826 | 1684 | return |
| 1827 | 1685 | |
| ... | ... | @@ -1878,43 +1736,6 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): |
| 1878 | 1736 | self.viewer.slice_.current_mask.was_edited = True |
| 1879 | 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 | 1740 | class RemoveMaskPartsInteractorStyle(FloodFillMaskInteractorStyle): |
| 1920 | 1741 | def __init__(self, viewer): |
| ... | ... | @@ -1989,7 +1810,7 @@ class SelectMaskPartsInteractorStyle(DefaultInteractorStyle): |
| 1989 | 1810 | |
| 1990 | 1811 | iren = self.viewer.interactor |
| 1991 | 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 | 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 | 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, | ... | ... |