Commit b41e19ac4df328740079278582f835388df4d154
1 parent
95cc3f3a
Exists in
rotvol
Showing angles in a dialog
Showing
4 changed files
with
75 additions
and
16 deletions
Show diff stats
invesalius/constants.py
@@ -479,6 +479,8 @@ ID_SWAP_YZ = wx.NewId() | @@ -479,6 +479,8 @@ ID_SWAP_YZ = wx.NewId() | ||
479 | ID_BOOLEAN_MASK = wx.NewId() | 479 | ID_BOOLEAN_MASK = wx.NewId() |
480 | ID_CLEAN_MASK = wx.NewId() | 480 | ID_CLEAN_MASK = wx.NewId() |
481 | 481 | ||
482 | +ID_REORIENT_IMG = wx.NewId() | ||
483 | + | ||
482 | #--------------------------------------------------------- | 484 | #--------------------------------------------------------- |
483 | STATE_DEFAULT = 1000 | 485 | STATE_DEFAULT = 1000 |
484 | STATE_WL = 1001 | 486 | STATE_WL = 1001 |
invesalius/data/styles.py
@@ -1426,7 +1426,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): | @@ -1426,7 +1426,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): | ||
1426 | 1426 | ||
1427 | self.picker = vtk.vtkWorldPointPicker() | 1427 | self.picker = vtk.vtkWorldPointPicker() |
1428 | 1428 | ||
1429 | - self.AddObserver("KeyPressEvent", self.OnKeyPress) | 1429 | + # self.AddObserver("KeyPressEvent", self.OnKeyPress) |
1430 | self.AddObserver("LeftButtonPressEvent",self.OnLeftClick) | 1430 | self.AddObserver("LeftButtonPressEvent",self.OnLeftClick) |
1431 | self.AddObserver("LeftButtonReleaseEvent", self.OnLeftRelease) | 1431 | self.AddObserver("LeftButtonReleaseEvent", self.OnLeftRelease) |
1432 | self.AddObserver("MouseMoveEvent", self.OnMouseMove) | 1432 | self.AddObserver("MouseMoveEvent", self.OnMouseMove) |
@@ -1546,6 +1546,9 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): | @@ -1546,6 +1546,9 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): | ||
1546 | def OnDblClick(self, evt): | 1546 | def OnDblClick(self, evt): |
1547 | self.viewer.slice_.rotations = [0, 0, 0] | 1547 | self.viewer.slice_.rotations = [0, 0, 0] |
1548 | self.viewer.slice_.q_orientation = np.array((1, 0, 0, 0)) | 1548 | self.viewer.slice_.q_orientation = np.array((1, 0, 0, 0)) |
1549 | + | ||
1550 | + Publisher.sendMessage('Update reorient angles', (0, 0, 0)) | ||
1551 | + | ||
1549 | self._discard_buffers() | 1552 | self._discard_buffers() |
1550 | self.viewer.slice_.current_mask.clear_history() | 1553 | self.viewer.slice_.current_mask.clear_history() |
1551 | Publisher.sendMessage('Reload actual slice') | 1554 | Publisher.sendMessage('Reload actual slice') |
@@ -1566,6 +1569,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): | @@ -1566,6 +1569,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): | ||
1566 | elif self.viewer.orientation == 'SAGITAL': | 1569 | elif self.viewer.orientation == 'SAGITAL': |
1567 | self.viewer.slice_.center = (icx, y, z) | 1570 | self.viewer.slice_.center = (icx, y, z) |
1568 | 1571 | ||
1572 | + | ||
1569 | self._discard_buffers() | 1573 | self._discard_buffers() |
1570 | self.viewer.slice_.current_mask.clear_history() | 1574 | self.viewer.slice_.current_mask.clear_history() |
1571 | Publisher.sendMessage('Reload actual slice') | 1575 | Publisher.sendMessage('Reload actual slice') |
@@ -1608,6 +1612,9 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): | @@ -1608,6 +1612,9 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): | ||
1608 | # angle = np.arctan2(p0[0] , p0[1]) - np.arctan2(p1[0], p1[1]) | 1612 | # angle = np.arctan2(p0[0] , p0[1]) - np.arctan2(p1[0], p1[1]) |
1609 | self.viewer.slice_.rotations[0] = angle | 1613 | self.viewer.slice_.rotations[0] = angle |
1610 | 1614 | ||
1615 | + az, ay, ax = transformations.euler_from_quaternion(self.viewer.slice_.q_orientation) | ||
1616 | + Publisher.sendMessage('Update reorient angles', (ax, ay, az)) | ||
1617 | + | ||
1611 | self._discard_buffers() | 1618 | self._discard_buffers() |
1612 | self.viewer.slice_.current_mask.clear_history() | 1619 | self.viewer.slice_.current_mask.clear_history() |
1613 | Publisher.sendMessage('Reload actual slice %s' % self.viewer.orientation) | 1620 | Publisher.sendMessage('Reload actual slice %s' % self.viewer.orientation) |
invesalius/gui/dialogs.py
@@ -1566,3 +1566,51 @@ class MaskBooleanDialog(wx.Dialog): | @@ -1566,3 +1566,51 @@ class MaskBooleanDialog(wx.Dialog): | ||
1566 | 1566 | ||
1567 | self.Close() | 1567 | self.Close() |
1568 | self.Destroy() | 1568 | self.Destroy() |
1569 | + | ||
1570 | + | ||
1571 | +class ReorientImageDialog(wx.Dialog): | ||
1572 | + def __init__(self): | ||
1573 | + pre = wx.PreDialog() | ||
1574 | + pre.Create(wx.GetApp().GetTopWindow(), -1, _(u'Image reorientation'), style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT) | ||
1575 | + self.PostCreate(pre) | ||
1576 | + | ||
1577 | + self._init_gui() | ||
1578 | + self._bind_events() | ||
1579 | + | ||
1580 | + def _init_gui(self): | ||
1581 | + self.anglex = wx.TextCtrl(self, -1, "0.0") | ||
1582 | + self.angley = wx.TextCtrl(self, -1, "0.0") | ||
1583 | + self.anglez = wx.TextCtrl(self, -1, "0.0") | ||
1584 | + | ||
1585 | + btnapply = wx.Button(self, -1, _("Apply")) | ||
1586 | + | ||
1587 | + sizer = wx.BoxSizer(wx.HORIZONTAL) | ||
1588 | + | ||
1589 | + sizer.Add(wx.StaticText(self, -1, _("Angle X")), 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) | ||
1590 | + sizer.Add(self.anglex, 0, wx.EXPAND | wx.ALL, 5) | ||
1591 | + sizer.AddSpacer(5) | ||
1592 | + | ||
1593 | + sizer.Add(wx.StaticText(self, -1, _("Angle Y")), 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) | ||
1594 | + sizer.Add(self.angley, 0, wx.EXPAND | wx.ALL, 5) | ||
1595 | + sizer.AddSpacer(5) | ||
1596 | + | ||
1597 | + sizer.Add(wx.StaticText(self, -1, _("Angle Z")), 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) | ||
1598 | + sizer.Add(self.anglez, 0, wx.EXPAND | wx.ALL, 5) | ||
1599 | + sizer.AddSpacer(5) | ||
1600 | + | ||
1601 | + sizer.Add(btnapply, 0, wx.EXPAND | wx.ALL, 5) | ||
1602 | + sizer.AddSpacer(5) | ||
1603 | + | ||
1604 | + self.SetSizer(sizer) | ||
1605 | + self.Fit() | ||
1606 | + | ||
1607 | + def _bind_events(self): | ||
1608 | + Publisher.subscribe(self._update_angles, 'Update reorient angles') | ||
1609 | + | ||
1610 | + def _update_angles(self, pubsub_evt): | ||
1611 | + anglex, angley, anglez = pubsub_evt.data | ||
1612 | + self.anglex.SetValue("%.2f" % np.rad2deg(anglex)) | ||
1613 | + self.angley.SetValue("%.2f" % np.rad2deg(angley)) | ||
1614 | + self.anglez.SetValue("%.2f" % np.rad2deg(anglez)) | ||
1615 | + | ||
1616 | + print anglex, angley, anglez |
invesalius/gui/frame.py
@@ -411,6 +411,9 @@ class Frame(wx.Frame): | @@ -411,6 +411,9 @@ class Frame(wx.Frame): | ||
411 | elif id == const.ID_CLEAN_MASK: | 411 | elif id == const.ID_CLEAN_MASK: |
412 | self.OnCleanMask() | 412 | self.OnCleanMask() |
413 | 413 | ||
414 | + elif id == const.ID_REORIENT_IMG: | ||
415 | + self.OnReorientImg() | ||
416 | + | ||
414 | def OnSize(self, evt): | 417 | def OnSize(self, evt): |
415 | """ | 418 | """ |
416 | Refresh GUI when frame is resized. | 419 | Refresh GUI when frame is resized. |
@@ -520,6 +523,11 @@ class Frame(wx.Frame): | @@ -520,6 +523,11 @@ class Frame(wx.Frame): | ||
520 | Publisher.sendMessage('Clean current mask') | 523 | Publisher.sendMessage('Clean current mask') |
521 | Publisher.sendMessage('Reload actual slice') | 524 | Publisher.sendMessage('Reload actual slice') |
522 | 525 | ||
526 | + def OnReorientImg(self): | ||
527 | + Publisher.sendMessage('Enable style', const.SLICE_STATE_REORIENT) | ||
528 | + rdlg = dlg.ReorientImageDialog() | ||
529 | + rdlg.Show() | ||
530 | + | ||
523 | # ------------------------------------------------------------------ | 531 | # ------------------------------------------------------------------ |
524 | # ------------------------------------------------------------------ | 532 | # ------------------------------------------------------------------ |
525 | # ------------------------------------------------------------------ | 533 | # ------------------------------------------------------------------ |
@@ -538,7 +546,8 @@ class MenuBar(wx.MenuBar): | @@ -538,7 +546,8 @@ class MenuBar(wx.MenuBar): | ||
538 | # not. Eg. save should only be available if a project is open | 546 | # not. Eg. save should only be available if a project is open |
539 | self.enable_items = [const.ID_PROJECT_SAVE, | 547 | self.enable_items = [const.ID_PROJECT_SAVE, |
540 | const.ID_PROJECT_SAVE_AS, | 548 | const.ID_PROJECT_SAVE_AS, |
541 | - const.ID_PROJECT_CLOSE] | 549 | + const.ID_PROJECT_CLOSE, |
550 | + const.ID_REORIENT_IMG] | ||
542 | self.__init_items() | 551 | self.__init_items() |
543 | self.__bind_events() | 552 | self.__bind_events() |
544 | 553 | ||
@@ -650,6 +659,12 @@ class MenuBar(wx.MenuBar): | @@ -650,6 +659,12 @@ class MenuBar(wx.MenuBar): | ||
650 | 659 | ||
651 | tools_menu.AppendMenu(-1, _(u"Mask"), mask_menu) | 660 | tools_menu.AppendMenu(-1, _(u"Mask"), mask_menu) |
652 | 661 | ||
662 | + # Image menu | ||
663 | + image_menu = wx.Menu() | ||
664 | + reorient_menu = image_menu.Append(const.ID_REORIENT_IMG, _(u'Reorient image\tCtrl+Shift+R')) | ||
665 | + reorient_menu.Enable(False) | ||
666 | + tools_menu.AppendMenu(-1, _(u'Image'), image_menu) | ||
667 | + | ||
653 | 668 | ||
654 | # VIEW | 669 | # VIEW |
655 | #view_tool_menu = wx.Menu() | 670 | #view_tool_menu = wx.Menu() |
@@ -1278,8 +1293,7 @@ class SliceToolBar(AuiToolBar): | @@ -1278,8 +1293,7 @@ class SliceToolBar(AuiToolBar): | ||
1278 | 1293 | ||
1279 | self.parent = parent | 1294 | self.parent = parent |
1280 | self.enable_items = [const.SLICE_STATE_SCROLL, | 1295 | self.enable_items = [const.SLICE_STATE_SCROLL, |
1281 | - const.SLICE_STATE_CROSS, | ||
1282 | - const.SLICE_STATE_REORIENT] | 1296 | + const.SLICE_STATE_CROSS,] |
1283 | self.__init_items() | 1297 | self.__init_items() |
1284 | self.__bind_events() | 1298 | self.__bind_events() |
1285 | self.__bind_events_wx() | 1299 | self.__bind_events_wx() |
@@ -1298,9 +1312,6 @@ class SliceToolBar(AuiToolBar): | @@ -1298,9 +1312,6 @@ class SliceToolBar(AuiToolBar): | ||
1298 | 1312 | ||
1299 | path = os.path.join(d,"cross_original.png") | 1313 | path = os.path.join(d,"cross_original.png") |
1300 | BMP_CROSS = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) | 1314 | BMP_CROSS = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) |
1301 | - | ||
1302 | - path = os.path.join(d, "tool_rotate_original.png") | ||
1303 | - BMP_REORIENT = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) | ||
1304 | else: | 1315 | else: |
1305 | path = os.path.join(d, "slice.png") | 1316 | path = os.path.join(d, "slice.png") |
1306 | BMP_SLICE = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) | 1317 | BMP_SLICE = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) |
@@ -1308,9 +1319,6 @@ class SliceToolBar(AuiToolBar): | @@ -1308,9 +1319,6 @@ class SliceToolBar(AuiToolBar): | ||
1308 | path = os.path.join(d,"cross.png") | 1319 | path = os.path.join(d,"cross.png") |
1309 | BMP_CROSS = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) | 1320 | BMP_CROSS = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) |
1310 | 1321 | ||
1311 | - path = os.path.join(d, "tool_rotate.png") | ||
1312 | - BMP_REORIENT = wx.Bitmap(path, wx.BITMAP_TYPE_PNG) | ||
1313 | - | ||
1314 | self.sst = self.AddToggleTool(const.SLICE_STATE_SCROLL, | 1322 | self.sst = self.AddToggleTool(const.SLICE_STATE_SCROLL, |
1315 | BMP_SLICE,#, kind=wx.ITEM_CHECK) | 1323 | BMP_SLICE,#, kind=wx.ITEM_CHECK) |
1316 | wx.NullBitmap, | 1324 | wx.NullBitmap, |
@@ -1323,12 +1331,6 @@ class SliceToolBar(AuiToolBar): | @@ -1323,12 +1331,6 @@ class SliceToolBar(AuiToolBar): | ||
1323 | toggle=True, | 1331 | toggle=True, |
1324 | short_help_string=_("Slices' cross intersection")) | 1332 | short_help_string=_("Slices' cross intersection")) |
1325 | 1333 | ||
1326 | - self.srt = self.AddToggleTool(const.SLICE_STATE_REORIENT, | ||
1327 | - BMP_REORIENT,#, kind=wx.ITEM_CHECK) | ||
1328 | - wx.NullBitmap, | ||
1329 | - toggle=True, | ||
1330 | - short_help_string=_("Reorient slices")) | ||
1331 | - | ||
1332 | def __bind_events(self): | 1334 | def __bind_events(self): |
1333 | """ | 1335 | """ |
1334 | Bind events related to pubsub. | 1336 | Bind events related to pubsub. |