diff --git a/invesalius/constants.py b/invesalius/constants.py index 4f726f9..cd750fb 100644 --- a/invesalius/constants.py +++ b/invesalius/constants.py @@ -479,6 +479,8 @@ ID_SWAP_YZ = wx.NewId() ID_BOOLEAN_MASK = wx.NewId() ID_CLEAN_MASK = wx.NewId() +ID_REORIENT_IMG = wx.NewId() + #--------------------------------------------------------- STATE_DEFAULT = 1000 STATE_WL = 1001 diff --git a/invesalius/data/styles.py b/invesalius/data/styles.py index c1674bd..bc9ee55 100644 --- a/invesalius/data/styles.py +++ b/invesalius/data/styles.py @@ -1426,7 +1426,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): self.picker = vtk.vtkWorldPointPicker() - self.AddObserver("KeyPressEvent", self.OnKeyPress) + # self.AddObserver("KeyPressEvent", self.OnKeyPress) self.AddObserver("LeftButtonPressEvent",self.OnLeftClick) self.AddObserver("LeftButtonReleaseEvent", self.OnLeftRelease) self.AddObserver("MouseMoveEvent", self.OnMouseMove) @@ -1546,6 +1546,9 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): def OnDblClick(self, evt): self.viewer.slice_.rotations = [0, 0, 0] self.viewer.slice_.q_orientation = np.array((1, 0, 0, 0)) + + Publisher.sendMessage('Update reorient angles', (0, 0, 0)) + self._discard_buffers() self.viewer.slice_.current_mask.clear_history() Publisher.sendMessage('Reload actual slice') @@ -1566,6 +1569,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): elif self.viewer.orientation == 'SAGITAL': self.viewer.slice_.center = (icx, y, z) + self._discard_buffers() self.viewer.slice_.current_mask.clear_history() Publisher.sendMessage('Reload actual slice') @@ -1608,6 +1612,9 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): # angle = np.arctan2(p0[0] , p0[1]) - np.arctan2(p1[0], p1[1]) self.viewer.slice_.rotations[0] = angle + az, ay, ax = transformations.euler_from_quaternion(self.viewer.slice_.q_orientation) + Publisher.sendMessage('Update reorient angles', (ax, ay, az)) + self._discard_buffers() self.viewer.slice_.current_mask.clear_history() Publisher.sendMessage('Reload actual slice %s' % self.viewer.orientation) diff --git a/invesalius/gui/dialogs.py b/invesalius/gui/dialogs.py index 43e4e89..eb4bf2f 100644 --- a/invesalius/gui/dialogs.py +++ b/invesalius/gui/dialogs.py @@ -1566,3 +1566,51 @@ class MaskBooleanDialog(wx.Dialog): self.Close() self.Destroy() + + +class ReorientImageDialog(wx.Dialog): + def __init__(self): + pre = wx.PreDialog() + pre.Create(wx.GetApp().GetTopWindow(), -1, _(u'Image reorientation'), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT) + self.PostCreate(pre) + + self._init_gui() + self._bind_events() + + def _init_gui(self): + self.anglex = wx.TextCtrl(self, -1, "0.0") + self.angley = wx.TextCtrl(self, -1, "0.0") + self.anglez = wx.TextCtrl(self, -1, "0.0") + + btnapply = wx.Button(self, -1, _("Apply")) + + sizer = wx.BoxSizer(wx.HORIZONTAL) + + sizer.Add(wx.StaticText(self, -1, _("Angle X")), 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) + sizer.Add(self.anglex, 0, wx.EXPAND | wx.ALL, 5) + sizer.AddSpacer(5) + + sizer.Add(wx.StaticText(self, -1, _("Angle Y")), 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) + sizer.Add(self.angley, 0, wx.EXPAND | wx.ALL, 5) + sizer.AddSpacer(5) + + sizer.Add(wx.StaticText(self, -1, _("Angle Z")), 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) + sizer.Add(self.anglez, 0, wx.EXPAND | wx.ALL, 5) + sizer.AddSpacer(5) + + sizer.Add(btnapply, 0, wx.EXPAND | wx.ALL, 5) + sizer.AddSpacer(5) + + self.SetSizer(sizer) + self.Fit() + + def _bind_events(self): + Publisher.subscribe(self._update_angles, 'Update reorient angles') + + def _update_angles(self, pubsub_evt): + anglex, angley, anglez = pubsub_evt.data + self.anglex.SetValue("%.2f" % np.rad2deg(anglex)) + self.angley.SetValue("%.2f" % np.rad2deg(angley)) + self.anglez.SetValue("%.2f" % np.rad2deg(anglez)) + + print anglex, angley, anglez diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index 8b67b49..6fe9755 100644 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -411,6 +411,9 @@ class Frame(wx.Frame): elif id == const.ID_CLEAN_MASK: self.OnCleanMask() + elif id == const.ID_REORIENT_IMG: + self.OnReorientImg() + def OnSize(self, evt): """ Refresh GUI when frame is resized. @@ -520,6 +523,11 @@ class Frame(wx.Frame): Publisher.sendMessage('Clean current mask') Publisher.sendMessage('Reload actual slice') + def OnReorientImg(self): + Publisher.sendMessage('Enable style', const.SLICE_STATE_REORIENT) + rdlg = dlg.ReorientImageDialog() + rdlg.Show() + # ------------------------------------------------------------------ # ------------------------------------------------------------------ # ------------------------------------------------------------------ @@ -538,7 +546,8 @@ class MenuBar(wx.MenuBar): # not. Eg. save should only be available if a project is open self.enable_items = [const.ID_PROJECT_SAVE, const.ID_PROJECT_SAVE_AS, - const.ID_PROJECT_CLOSE] + const.ID_PROJECT_CLOSE, + const.ID_REORIENT_IMG] self.__init_items() self.__bind_events() @@ -650,6 +659,12 @@ class MenuBar(wx.MenuBar): tools_menu.AppendMenu(-1, _(u"Mask"), mask_menu) + # Image menu + image_menu = wx.Menu() + reorient_menu = image_menu.Append(const.ID_REORIENT_IMG, _(u'Reorient image\tCtrl+Shift+R')) + reorient_menu.Enable(False) + tools_menu.AppendMenu(-1, _(u'Image'), image_menu) + # VIEW #view_tool_menu = wx.Menu() @@ -1278,8 +1293,7 @@ class SliceToolBar(AuiToolBar): self.parent = parent self.enable_items = [const.SLICE_STATE_SCROLL, - const.SLICE_STATE_CROSS, - const.SLICE_STATE_REORIENT] + const.SLICE_STATE_CROSS,] self.__init_items() self.__bind_events() self.__bind_events_wx() @@ -1298,9 +1312,6 @@ class SliceToolBar(AuiToolBar): path = os.path.join(d,"cross_original.png") BMP_CROSS = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) - - path = os.path.join(d, "tool_rotate_original.png") - BMP_REORIENT = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) else: path = os.path.join(d, "slice.png") BMP_SLICE = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) @@ -1308,9 +1319,6 @@ class SliceToolBar(AuiToolBar): path = os.path.join(d,"cross.png") BMP_CROSS = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) - path = os.path.join(d, "tool_rotate.png") - BMP_REORIENT = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) - self.sst = self.AddToggleTool(const.SLICE_STATE_SCROLL, BMP_SLICE,#, kind=wx.ITEM_CHECK) wx.NullBitmap, @@ -1323,12 +1331,6 @@ class SliceToolBar(AuiToolBar): toggle=True, short_help_string=_("Slices' cross intersection")) - self.srt = self.AddToggleTool(const.SLICE_STATE_REORIENT, - BMP_REORIENT,#, kind=wx.ITEM_CHECK) - wx.NullBitmap, - toggle=True, - short_help_string=_("Reorient slices")) - def __bind_events(self): """ Bind events related to pubsub. -- libgit2 0.21.2