Commit d97c6212269264e55f5d99e6bdac88a612da7883
1 parent
91b19b16
Exists in
master
and in
67 other branches
Added the option to swap axes
Showing
5 changed files
with
50 additions
and
2 deletions
Show diff stats
invesalius/constants.py
@@ -460,6 +460,11 @@ ID_START = wx.NewId() | @@ -460,6 +460,11 @@ ID_START = wx.NewId() | ||
460 | ID_FLIP_X = wx.NewId() | 460 | ID_FLIP_X = wx.NewId() |
461 | ID_FLIP_Y = wx.NewId() | 461 | ID_FLIP_Y = wx.NewId() |
462 | ID_FLIP_Z = wx.NewId() | 462 | ID_FLIP_Z = wx.NewId() |
463 | + | ||
464 | +ID_SWAP_XY = wx.NewId() | ||
465 | +ID_SWAP_XZ = wx.NewId() | ||
466 | +ID_SWAP_YZ = wx.NewId() | ||
467 | + | ||
463 | #--------------------------------------------------------- | 468 | #--------------------------------------------------------- |
464 | STATE_DEFAULT = 1000 | 469 | STATE_DEFAULT = 1000 |
465 | STATE_WL = 1001 | 470 | STATE_WL = 1001 |
invesalius/data/mask.py
@@ -49,6 +49,7 @@ class Mask(): | @@ -49,6 +49,7 @@ class Mask(): | ||
49 | 49 | ||
50 | def __bind_events(self): | 50 | def __bind_events(self): |
51 | Publisher.subscribe(self.OnFlipVolume, 'Flip volume') | 51 | Publisher.subscribe(self.OnFlipVolume, 'Flip volume') |
52 | + Publisher.subscribe(self.OnSwapVolumeAxes, 'Swap volume axes') | ||
52 | 53 | ||
53 | def SavePlist(self, filename): | 54 | def SavePlist(self, filename): |
54 | mask = {} | 55 | mask = {} |
@@ -98,6 +99,11 @@ class Mask(): | @@ -98,6 +99,11 @@ class Mask(): | ||
98 | submatrix[:] = submatrix[:, :, ::-1] | 99 | submatrix[:] = submatrix[:, :, ::-1] |
99 | self.matrix[0, 0, 1::] = self.matrix[0, 0, :0:-1] | 100 | self.matrix[0, 0, 1::] = self.matrix[0, 0, :0:-1] |
100 | 101 | ||
102 | + def OnSwapVolumeAxes(self, pubsub_evt): | ||
103 | + axis0, axis1 = pubsub_evt.data | ||
104 | + self.matrix = self.matrix.swapaxes(axis0, axis1) | ||
105 | + print type(self.matrix) | ||
106 | + | ||
101 | def _save_mask(self, filename): | 107 | def _save_mask(self, filename): |
102 | shutil.copyfile(self.temp_file, filename) | 108 | shutil.copyfile(self.temp_file, filename) |
103 | 109 |
invesalius/data/slice_.py
@@ -134,6 +134,7 @@ class Slice(object): | @@ -134,6 +134,7 @@ class Slice(object): | ||
134 | Publisher.subscribe(self.UpdateSlice3D,'Update slice 3D') | 134 | Publisher.subscribe(self.UpdateSlice3D,'Update slice 3D') |
135 | 135 | ||
136 | Publisher.subscribe(self.OnFlipVolume, 'Flip volume') | 136 | Publisher.subscribe(self.OnFlipVolume, 'Flip volume') |
137 | + Publisher.subscribe(self.OnSwapVolumeAxes, 'Swap volume axes') | ||
137 | 138 | ||
138 | def GetMaxSliceNumber(self, orientation): | 139 | def GetMaxSliceNumber(self, orientation): |
139 | shape = self.matrix.shape | 140 | shape = self.matrix.shape |
@@ -980,6 +981,21 @@ class Slice(object): | @@ -980,6 +981,21 @@ class Slice(object): | ||
980 | for buffer_ in self.buffer_slices.values(): | 981 | for buffer_ in self.buffer_slices.values(): |
981 | buffer_.discard_buffer() | 982 | buffer_.discard_buffer() |
982 | 983 | ||
984 | + def OnSwapVolumeAxes(self, pubsub_evt): | ||
985 | + axis0, axis1 = pubsub_evt.data | ||
986 | + self.matrix = self.matrix.swapaxes(axis0, axis1) | ||
987 | + if (axis0, axis1) == (2, 1): | ||
988 | + self.spacing = self.spacing[1], self.spacing[0], self.spacing[2] | ||
989 | + elif (axis0, axis1) == (2, 0): | ||
990 | + self.spacing = self.spacing[2], self.spacing[1], self.spacing[0] | ||
991 | + elif (axis0, axis1) == (1, 0): | ||
992 | + self.spacing = self.spacing[0], self.spacing[2], self.spacing[1] | ||
993 | + | ||
994 | + for buffer_ in self.buffer_slices.values(): | ||
995 | + buffer_.discard_buffer() | ||
996 | + | ||
997 | + print type(self.matrix) | ||
998 | + | ||
983 | def OnExportMask(self, pubsub_evt): | 999 | def OnExportMask(self, pubsub_evt): |
984 | #imagedata = self.current_mask.imagedata | 1000 | #imagedata = self.current_mask.imagedata |
985 | imagedata = self.imagedata | 1001 | imagedata = self.imagedata |
invesalius/data/viewer_slice.py
@@ -1002,7 +1002,7 @@ class Viewer(wx.Panel): | @@ -1002,7 +1002,7 @@ class Viewer(wx.Panel): | ||
1002 | Publisher.subscribe(self.RemoveActors, 'Remove actors ' + str(ORIENTATIONS[self.orientation])) | 1002 | Publisher.subscribe(self.RemoveActors, 'Remove actors ' + str(ORIENTATIONS[self.orientation])) |
1003 | 1003 | ||
1004 | Publisher.subscribe(self.ReloadActualSlice, 'Reload actual slice') | 1004 | Publisher.subscribe(self.ReloadActualSlice, 'Reload actual slice') |
1005 | - | 1005 | + Publisher.subscribe(self.OnUpdateScroll, 'Update scroll') |
1006 | 1006 | ||
1007 | def SetDefaultCursor(self, pusub_evt): | 1007 | def SetDefaultCursor(self, pusub_evt): |
1008 | self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) | 1008 | self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) |
@@ -1502,6 +1502,11 @@ class Viewer(wx.Panel): | @@ -1502,6 +1502,11 @@ class Viewer(wx.Panel): | ||
1502 | self.set_slice_number(pos) | 1502 | self.set_slice_number(pos) |
1503 | self.interactor.Render() | 1503 | self.interactor.Render() |
1504 | 1504 | ||
1505 | + def OnUpdateScroll(self, pubsub_evt): | ||
1506 | + max_slice_number = sl.Slice().GetNumberOfSlices(self.orientation) | ||
1507 | + self.scroll.SetScrollbar(wx.SB_VERTICAL, 1, max_slice_number, | ||
1508 | + max_slice_number) | ||
1509 | + | ||
1505 | def AddActors(self, pubsub_evt): | 1510 | def AddActors(self, pubsub_evt): |
1506 | "Inserting actors" | 1511 | "Inserting actors" |
1507 | actors, n = pubsub_evt.data | 1512 | actors, n = pubsub_evt.data |
invesalius/gui/frame.py
@@ -344,7 +344,11 @@ class Frame(wx.Frame): | @@ -344,7 +344,11 @@ class Frame(wx.Frame): | ||
344 | const.ID_FLIP_Y: 1, | 344 | const.ID_FLIP_Y: 1, |
345 | const.ID_FLIP_Z: 0}[id] | 345 | const.ID_FLIP_Z: 0}[id] |
346 | self.FlipVolume(axis) | 346 | self.FlipVolume(axis) |
347 | - | 347 | + elif id in (const.ID_SWAP_XY, const.ID_SWAP_XZ, const.ID_SWAP_YZ): |
348 | + axes = {const.ID_SWAP_XY: (2, 1), | ||
349 | + const.ID_SWAP_XZ: (2, 0), | ||
350 | + const.ID_SWAP_YZ: (1, 0)}[id] | ||
351 | + self.SwapAxes(axes) | ||
348 | def OnSize(self, evt): | 352 | def OnSize(self, evt): |
349 | """ | 353 | """ |
350 | Refresh GUI when frame is resized. | 354 | Refresh GUI when frame is resized. |
@@ -418,6 +422,11 @@ class Frame(wx.Frame): | @@ -418,6 +422,11 @@ class Frame(wx.Frame): | ||
418 | Publisher.sendMessage('Flip volume', axis) | 422 | Publisher.sendMessage('Flip volume', axis) |
419 | Publisher.sendMessage('Reload actual slice') | 423 | Publisher.sendMessage('Reload actual slice') |
420 | 424 | ||
425 | + def SwapAxes(self, axes): | ||
426 | + Publisher.sendMessage('Swap volume axes', axes) | ||
427 | + Publisher.sendMessage('Update scroll') | ||
428 | + Publisher.sendMessage('Reload actual slice') | ||
429 | + | ||
421 | # ------------------------------------------------------------------ | 430 | # ------------------------------------------------------------------ |
422 | # ------------------------------------------------------------------ | 431 | # ------------------------------------------------------------------ |
423 | # ------------------------------------------------------------------ | 432 | # ------------------------------------------------------------------ |
@@ -492,9 +501,16 @@ class MenuBar(wx.MenuBar): | @@ -492,9 +501,16 @@ class MenuBar(wx.MenuBar): | ||
492 | app(const.ID_FLIP_Y, _("A <-> P")) | 501 | app(const.ID_FLIP_Y, _("A <-> P")) |
493 | app(const.ID_FLIP_Z, _("T <-> B")) | 502 | app(const.ID_FLIP_Z, _("T <-> B")) |
494 | 503 | ||
504 | + swap_axes_menu = wx.Menu() | ||
505 | + app = swap_axes_menu.Append | ||
506 | + app(const.ID_SWAP_XY, _("R-L <-> A-P")) | ||
507 | + app(const.ID_SWAP_XZ, _("R-L <-> T-B")) | ||
508 | + app(const.ID_SWAP_YZ, _("A-P <-> T-B")) | ||
509 | + | ||
495 | file_edit = wx.Menu() | 510 | file_edit = wx.Menu() |
496 | app = file_edit.Append | 511 | app = file_edit.Append |
497 | file_edit.AppendMenu(wx.NewId(), _('Flip'), flip_menu) | 512 | file_edit.AppendMenu(wx.NewId(), _('Flip'), flip_menu) |
513 | + file_edit.AppendMenu(wx.NewId(), _('Swap axes'), swap_axes_menu) | ||
498 | #app(wx.ID_UNDO, "Undo\tCtrl+Z") | 514 | #app(wx.ID_UNDO, "Undo\tCtrl+Z") |
499 | #app(wx.ID_REDO, "Redo\tCtrl+Y") | 515 | #app(wx.ID_REDO, "Redo\tCtrl+Y") |
500 | #app(const.ID_EDIT_LIST, "Show Undo List...") | 516 | #app(const.ID_EDIT_LIST, "Show Undo List...") |