Commit 628fec8e95cb9e1f9320a888f492df59c4aa0298
1 parent
3915e1bb
Exists in
master
and in
68 other branches
FIX: The scrolls in viewer_slice sync between all orientations are correct. Related to ticket #147
Showing
1 changed file
with
55 additions
and
51 deletions
Show diff stats
invesalius/data/viewer_slice.py
| ... | ... | @@ -18,7 +18,6 @@ |
| 18 | 18 | #-------------------------------------------------------------------------- |
| 19 | 19 | |
| 20 | 20 | import itertools |
| 21 | -import os.path | |
| 22 | 21 | |
| 23 | 22 | import numpy |
| 24 | 23 | |
| ... | ... | @@ -84,7 +83,6 @@ class Viewer(wx.Panel): |
| 84 | 83 | |
| 85 | 84 | |
| 86 | 85 | def __init_gui(self): |
| 87 | - | |
| 88 | 86 | interactor = wxVTKRenderWindowInteractor(self, -1, size=self.GetSize()) |
| 89 | 87 | |
| 90 | 88 | scroll = wx.ScrollBar(self, -1, style=wx.SB_VERTICAL) |
| ... | ... | @@ -99,14 +97,12 @@ class Viewer(wx.Panel): |
| 99 | 97 | self.SetSizer(background_sizer) |
| 100 | 98 | background_sizer.Fit(self) |
| 101 | 99 | |
| 102 | - | |
| 103 | 100 | self.Layout() |
| 104 | 101 | self.Update() |
| 105 | 102 | self.SetAutoLayout(1) |
| 106 | 103 | |
| 107 | 104 | self.interactor = interactor |
| 108 | 105 | |
| 109 | - | |
| 110 | 106 | def OnContextMenu(self, evt): |
| 111 | 107 | self.right_pressed = 0 |
| 112 | 108 | if (self.last_position_mouse_move ==\ |
| ... | ... | @@ -306,9 +302,6 @@ class Viewer(wx.Panel): |
| 306 | 302 | def OnReleaseLeftButton(self, evt, obj): |
| 307 | 303 | self.left_pressed = 0 |
| 308 | 304 | ps.Publisher().sendMessage('Update slice viewer') |
| 309 | - | |
| 310 | - | |
| 311 | - | |
| 312 | 305 | |
| 313 | 306 | def OnWindowLevelMove(self, evt, obj): |
| 314 | 307 | if (self.left_pressed): |
| ... | ... | @@ -321,10 +314,8 @@ class Viewer(wx.Panel): |
| 321 | 314 | ps.Publisher().sendMessage('Bright and contrast adjustment image', |
| 322 | 315 | (self.acum_achange_window, self.acum_achange_level)) |
| 323 | 316 | |
| 324 | - | |
| 325 | - self.SetWLText(self.acum_achange_level, | |
| 326 | - self.acum_achange_window) | |
| 327 | - | |
| 317 | + #self.SetWLText(self.acum_achange_level, | |
| 318 | + # self.acum_achange_window) | |
| 328 | 319 | |
| 329 | 320 | const.WINDOW_LEVEL['Manual'] = (self.acum_achange_window,\ |
| 330 | 321 | self.acum_achange_level) |
| ... | ... | @@ -332,9 +323,8 @@ class Viewer(wx.Panel): |
| 332 | 323 | ps.Publisher().sendMessage('Update window level value',(self.acum_achange_window, |
| 333 | 324 | self.acum_achange_level)) |
| 334 | 325 | #Necessary update the slice plane in the volume case exists |
| 326 | + ps.Publisher().sendMessage('Update slice viewer') | |
| 335 | 327 | ps.Publisher().sendMessage('Render volume viewer') |
| 336 | - | |
| 337 | - self.interactor.Render() | |
| 338 | 328 | |
| 339 | 329 | |
| 340 | 330 | def OnWindowLevelClick(self, evt, obj): |
| ... | ... | @@ -419,7 +409,7 @@ class Viewer(wx.Panel): |
| 419 | 409 | value = STR_WL%(window_width, window_level) |
| 420 | 410 | if (self.wl_text): |
| 421 | 411 | self.wl_text.SetValue(value) |
| 422 | - self.interactor.Render() | |
| 412 | + #self.interactor.Render() | |
| 423 | 413 | |
| 424 | 414 | def EnableText(self): |
| 425 | 415 | if not (self.wl_text): |
| ... | ... | @@ -673,28 +663,45 @@ class Viewer(wx.Panel): |
| 673 | 663 | |
| 674 | 664 | self.interactor.Render() |
| 675 | 665 | |
| 676 | - | |
| 666 | + def OnCrossMouseClick(self, evt, obj): | |
| 667 | + self.ChangeCrossPosition() | |
| 677 | 668 | |
| 678 | 669 | def OnCrossMove(self, evt, obj): |
| 679 | - # Update position in other slices | |
| 670 | + # The user moved the mouse with left button pressed | |
| 680 | 671 | if (self.left_pressed): |
| 681 | - mouse_x, mouse_y = self.interactor.GetEventPosition() | |
| 682 | - renderer = self.slice_data_list[0].renderer | |
| 683 | - self.pick.Pick(mouse_x, mouse_y, self.slice_data_list[0].number, renderer) | |
| 684 | - coord_cross = self.get_coordinate_cursor() | |
| 685 | - coord = self.get_coordinate() | |
| 686 | - ps.Publisher().sendMessage('Update cross position', | |
| 687 | - (self.orientation, coord_cross)) | |
| 672 | + self.ChangeCrossPosition() | |
| 673 | + | |
| 674 | + def ChangeCrossPosition(self): | |
| 675 | + mouse_x, mouse_y = self.interactor.GetEventPosition() | |
| 676 | + # Get in what slice data the click occurred | |
| 677 | + renderer = self.slice_data_list[0].renderer | |
| 678 | + # pick to get click position in the 3d world | |
| 679 | + self.pick.Pick(mouse_x, mouse_y, self.slice_data_list[0].number, renderer) | |
| 680 | + coord_cross = self.get_coordinate_cursor() | |
| 681 | + coord = self.CalcultateScrollPosition(coord_cross) | |
| 682 | + ps.Publisher().sendMessage('Update cross position', | |
| 683 | + (self.orientation, coord_cross)) | |
| 684 | + self.ScrollSlice(coord) | |
| 685 | + self.interactor.Render() | |
| 686 | + | |
| 687 | + def ScrollSlice(self, coord): | |
| 688 | + if self.orientation == "AXIAL": | |
| 688 | 689 | ps.Publisher().sendMessage(('Set scroll position', 'SAGITAL'), |
| 689 | 690 | coord[0]) |
| 690 | 691 | ps.Publisher().sendMessage(('Set scroll position', 'CORONAL'), |
| 691 | 692 | coord[1]) |
| 693 | + elif self.orientation == "SAGITAL": | |
| 694 | + ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), | |
| 695 | + coord[2]) | |
| 696 | + ps.Publisher().sendMessage(('Set scroll position', 'CORONAL'), | |
| 697 | + coord[1]) | |
| 698 | + elif self.orientation == "CORONAL": | |
| 692 | 699 | ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), |
| 693 | 700 | coord[2]) |
| 701 | + ps.Publisher().sendMessage(('Set scroll position', 'SAGITAL'), | |
| 702 | + coord[0]) | |
| 694 | 703 | |
| 695 | 704 | def OnZoomMoveRight(self, evt, obj): |
| 696 | - | |
| 697 | - | |
| 698 | 705 | if (self.right_pressed): |
| 699 | 706 | evt.Dolly() |
| 700 | 707 | evt.OnRightButtonDown() |
| ... | ... | @@ -702,31 +709,16 @@ class Viewer(wx.Panel): |
| 702 | 709 | def OnZoomRightClick(self, evt, obj): |
| 703 | 710 | evt.StartDolly() |
| 704 | 711 | |
| 705 | - | |
| 706 | - def OnCrossMouseClick(self, evt, obj): | |
| 707 | - mouse_x, mouse_y = self.interactor.GetEventPosition() | |
| 708 | - renderer = self.slice_data_list[0].renderer | |
| 709 | - self.pick.Pick(mouse_x, mouse_y, self.slice_data_list[0].number, renderer) | |
| 710 | - coord_cross = self.get_coordinate_cursor() | |
| 711 | - coord = self.get_coordinate() | |
| 712 | - ps.Publisher().sendMessage('Update cross position', | |
| 713 | - (self.orientation, coord_cross)) | |
| 714 | - ps.Publisher().sendMessage(('Set scroll position', 'SAGITAL'), | |
| 715 | - coord[0]) | |
| 716 | - ps.Publisher().sendMessage(('Set scroll position', 'CORONAL'), | |
| 717 | - coord[1]) | |
| 718 | - ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), | |
| 719 | - coord[2]) | |
| 720 | - | |
| 721 | - | |
| 722 | 712 | def get_slice_data(self, render): |
| 723 | 713 | for slice_data in self.slice_data_list: |
| 724 | 714 | if slice_data.renderer is render: |
| 725 | 715 | return slice_data |
| 726 | 716 | |
| 727 | - def get_coordinate(self): | |
| 728 | - # Find position | |
| 729 | - x, y, z = self.pick.GetPickPosition() | |
| 717 | + def CalcultateScrollPosition(self, coord): | |
| 718 | + # Based in the given coord (x, y, z), returns a list with the scroll positions for each | |
| 719 | + # orientation, being the first position the sagital, second the coronal | |
| 720 | + # and the last, axial. | |
| 721 | + x, y, z = coord | |
| 730 | 722 | |
| 731 | 723 | # First we fix the position origin, based on vtkActor bounds |
| 732 | 724 | bounds = self.actor.GetBounds() |
| ... | ... | @@ -737,15 +729,20 @@ class Viewer(wx.Panel): |
| 737 | 729 | |
| 738 | 730 | # Then we fix the porpotion, based on vtkImageData spacing |
| 739 | 731 | spacing_x, spacing_y, spacing_z = self.imagedata.GetSpacing() |
| 732 | + | |
| 740 | 733 | x = x/spacing_x |
| 741 | 734 | y = y/spacing_y |
| 742 | 735 | z = z/spacing_z |
| 743 | 736 | |
| 737 | + proj = project.Project() | |
| 738 | + orig_orien = proj.original_orientation | |
| 744 | 739 | # Based on the current orientation, we define 3D position |
| 745 | - coordinates = {"SAGITAL": [self.slice_number, y, z], | |
| 746 | - "CORONAL": [x, self.slice_number, z], | |
| 747 | - "AXIAL": [x, y, self.slice_number]} | |
| 748 | - coord = [int(coord) for coord in coordinates[self.orientation]] | |
| 740 | + # Sagita, coronal, axial | |
| 741 | + coordinates = {const.AXIAL: [x, y, z], | |
| 742 | + const.SAGITAL: [z, x, y], | |
| 743 | + const.CORONAL: [x, z, y]} | |
| 744 | + | |
| 745 | + coord = [int(i) for i in coordinates[orig_orien]] | |
| 749 | 746 | |
| 750 | 747 | # According to vtkImageData extent, we limit min and max value |
| 751 | 748 | # If this is not done, a VTK Error occurs when mouse is pressed outside |
| ... | ... | @@ -763,6 +760,13 @@ class Viewer(wx.Panel): |
| 763 | 760 | def get_coordinate_cursor(self): |
| 764 | 761 | # Find position |
| 765 | 762 | x, y, z = self.pick.GetPickPosition() |
| 763 | + bounds = self.actor.GetBounds() | |
| 764 | + if bounds[0] == bounds[1]: | |
| 765 | + x = bounds[0] | |
| 766 | + elif bounds[2] == bounds[3]: | |
| 767 | + y = bounds[2] | |
| 768 | + elif bounds[4] == bounds[5]: | |
| 769 | + z = bounds[4] | |
| 766 | 770 | return x, y, z |
| 767 | 771 | |
| 768 | 772 | def get_coordinate_cursor_edition(self, slice_data): |
| ... | ... | @@ -1128,8 +1132,8 @@ class Viewer(wx.Panel): |
| 1128 | 1132 | #xz = [x, y - abs(y * 0.001), z] |
| 1129 | 1133 | #xy = [x, y, z + abs(z * 0.001)] |
| 1130 | 1134 | |
| 1131 | - #proj = project.Project() | |
| 1132 | - #orig_orien = proj.original_orientation | |
| 1135 | + proj = project.Project() | |
| 1136 | + orig_orien = proj.original_orientation | |
| 1133 | 1137 | #pos = [x, y, z] |
| 1134 | 1138 | |
| 1135 | 1139 | #if (orig_orien == const.SAGITAL): | ... | ... |