Commit 3f79dd82d0bbdf493074ba34557dd45ec40d1c16

Authored by Thiago Franco de Moraes
1 parent b41e19ac
Exists in rotvol

Almost done

invesalius/control.py
... ... @@ -84,6 +84,8 @@ class Controller():
84 84  
85 85 Publisher.subscribe(self.ShowBooleanOpDialog, 'Show boolean dialog')
86 86  
  87 + Publisher.subscribe(self.ApplyReorientation, 'Apply reorientation')
  88 +
87 89  
88 90 def OnCancelImport(self, pubsub_evt):
89 91 #self.cancel_import = True
... ... @@ -631,3 +633,6 @@ class Controller():
631 633 def ShowBooleanOpDialog(self, pubsub_evt):
632 634 dlg = dialogs.MaskBooleanDialog(prj.Project().mask_dict)
633 635 dlg.Show()
  636 +
  637 + def ApplyReorientation(self, pubsub_evt):
  638 + self.Slice.apply_reorientation()
... ...
invesalius/data/slice_.py
... ... @@ -94,7 +94,6 @@ class Slice(object):
94 94 self.n_border = const.PROJECTION_BORDER_SIZE
95 95  
96 96 self._spacing = (1.0, 1.0, 1.0)
97   - self.rotations = [0, 0, 0]
98 97 self.center = [0, 0, 0]
99 98  
100 99 self.q_orientation = np.array((1, 0, 0, 0))
... ... @@ -580,10 +579,8 @@ class Slice(object):
580 579 if self._type_projection == const.PROJECTION_NORMAL:
581 580 number_slices = 1
582 581  
583   - if np.any(self.rotations):
  582 + if np.any(self.q_orientation[1::]):
584 583 cx, cy, cz = self.center
585   - rx, ry, rz = self.rotations
586   - sx, sy, sz = self.spacing
587 584 T0 = transformations.translation_matrix((-cz, -cy, -cx))
588 585 # Rx = transformations.rotation_matrix(rx, (0, 0, 1))
589 586 # Ry = transformations.rotation_matrix(ry, (0, 1, 0))
... ... @@ -597,7 +594,7 @@ class Slice(object):
597 594  
598 595 if orientation == 'AXIAL':
599 596 tmp_array = np.array(self.matrix[slice_number:slice_number + number_slices])
600   - if np.any(self.rotations):
  597 + if np.any(self.q_orientation[1::]):
601 598 transforms.apply_view_matrix_transform(self.matrix, self.spacing, M, slice_number, orientation, 2, self.matrix.min(), tmp_array)
602 599 if self._type_projection == const.PROJECTION_NORMAL:
603 600 n_image = tmp_array.squeeze()
... ... @@ -644,7 +641,7 @@ class Slice(object):
644 641  
645 642 elif orientation == 'CORONAL':
646 643 tmp_array = np.array(self.matrix[:, slice_number: slice_number + number_slices, :])
647   - if np.any(self.rotations):
  644 + if np.any(self.q_orientation[1::]):
648 645 transforms.apply_view_matrix_transform(self.matrix, self.spacing, M, slice_number, orientation, 1, self.matrix.min(), tmp_array)
649 646  
650 647 if self._type_projection == const.PROJECTION_NORMAL:
... ... @@ -694,7 +691,7 @@ class Slice(object):
694 691 n_image = np.array(self.matrix[:, slice_number, :])
695 692 elif orientation == 'SAGITAL':
696 693 tmp_array = np.array(self.matrix[:, :, slice_number: slice_number + number_slices])
697   - if np.any(self.rotations):
  694 + if np.any(self.q_orientation[1::]):
698 695 transforms.apply_view_matrix_transform(self.matrix, self.spacing, M, slice_number, orientation, 1, self.matrix.min(), tmp_array)
699 696  
700 697 if self._type_projection == const.PROJECTION_NORMAL:
... ... @@ -1365,6 +1362,30 @@ class Slice(object):
1365 1362 self.buffer_slices[o].discard_vtk_mask()
1366 1363 Publisher.sendMessage('Reload actual slice')
1367 1364  
  1365 + def apply_reorientation(self):
  1366 + temp_file = tempfile.mktemp()
  1367 + mcopy = np.memmap(temp_file, shape=self.matrix.shape, dtype=self.matrix.dtype, mode='w+')
  1368 + mcopy[:] = self.matrix
  1369 +
  1370 + cx, cy, cz = self.center
  1371 + T0 = transformations.translation_matrix((-cz, -cy, -cx))
  1372 + R = transformations.quaternion_matrix(self.q_orientation)
  1373 + T1 = transformations.translation_matrix((cz, cy, cx))
  1374 + M = transformations.concatenate_matrices(T1, R.T, T0)
  1375 +
  1376 + transforms.apply_view_matrix_transform(mcopy, self.spacing, M, 0, 'AXIAL', 2, mcopy.min(), self.matrix)
  1377 +
  1378 + del mcopy
  1379 + os.remove(temp_file)
  1380 +
  1381 + self.q_orientation = np.array((1, 0, 0, 0))
  1382 + self.center = [(s * d/2.0) for (d, s) in zip(self.matrix.shape[::-1], self.spacing)]
  1383 +
  1384 + self.__clean_current_mask(None)
  1385 + self.current_mask.matrix[:] = 0
  1386 +
  1387 + Publisher.sendMessage('Reload actual slice')
  1388 +
1368 1389 def __undo_edition(self, pub_evt):
1369 1390 buffer_slices = self.buffer_slices
1370 1391 actual_slices = {"AXIAL": buffer_slices["AXIAL"].index,
... ...
invesalius/data/styles.py
... ... @@ -1426,7 +1426,6 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1426 1426  
1427 1427 self.picker = vtk.vtkWorldPointPicker()
1428 1428  
1429   - # self.AddObserver("KeyPressEvent", self.OnKeyPress)
1430 1429 self.AddObserver("LeftButtonPressEvent",self.OnLeftClick)
1431 1430 self.AddObserver("LeftButtonReleaseEvent", self.OnLeftRelease)
1432 1431 self.AddObserver("MouseMoveEvent", self.OnMouseMove)
... ... @@ -1435,37 +1434,19 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1435 1434 self.viewer.interactor.Bind(wx.EVT_LEFT_DCLICK, self.OnDblClick)
1436 1435  
1437 1436 def SetUp(self):
1438   - self.viewer.slice_.current_mask.is_shown = False
1439 1437 self.draw_lines()
  1438 + Publisher.sendMessage('Show mask', (self.viewer.slice_.current_mask.index, False))
1440 1439 Publisher.sendMessage('Reload actual slice')
1441 1440  
1442 1441 def CleanUp(self):
1443 1442 for actor in self.actors:
1444 1443 self.viewer.slice_data.renderer.RemoveActor(actor)
1445 1444  
1446   - def OnKeyPress(self, evt, obj):
1447   - key = self.viewer.interactor.GetKeyCode()
1448   - if key == '+':
1449   - delta = 1
1450   - elif key == '-':
1451   - delta = -1
1452   - else:
1453   - return
1454   -
1455   - rx, ry, rz = self.viewer.slice_.rotations
1456   - orientation = self.viewer.orientation
1457   - if orientation == 'AXIAL':
1458   - rz += np.deg2rad(delta)
1459   - elif orientation == 'CORONAL':
1460   - ry += np.deg2rad(delta)
1461   - elif orientation == 'SAGITAL':
1462   - rx += np.deg2rad(delta)
1463   -
1464   - self.viewer.slice_.rotations = (rx, ry, rz)
  1445 + self.viewer.slice_.rotations = [0, 0, 0]
  1446 + self.viewer.slice_.q_orientation = np.array((1, 0, 0, 0))
1465 1447 self._discard_buffers()
1466   -
1467   - self.viewer.slice_.current_mask.clear_history()
1468   - Publisher.sendMessage('Reload actual slice')
  1448 + Publisher.sendMessage('Show mask', (self.viewer.slice_.current_mask.index, True))
  1449 + Publisher.sendMessage('Reload actual slice %s' % self.viewer.orientation)
1469 1450  
1470 1451 def OnLeftClick(self, obj, evt):
1471 1452 if self._over_center:
... ... @@ -1480,16 +1461,9 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1480 1461 self.picker.Pick(x, y, 0, self.viewer.slice_data.renderer)
1481 1462 x, y, z = self.picker.GetPickPosition()
1482 1463  
1483   - # if self.viewer.orientation == 'AXIAL':
1484   - # self.p0 = np.array((y-cy, x-cx))
1485   - # elif self.viewer.orientation == 'CORONAL':
1486   - # self.p0 = np.array((z-cz, x-cx))
1487   - # elif self.viewer.orientation == 'SAGITAL':
1488   - # self.p0 = np.array((z-cz, y-cy))
1489 1464 self.p0 = self.get_image_point_coord(x, y, z)
1490 1465 self.to_rot = True
1491 1466  
1492   -
1493 1467 def OnLeftRelease(self, obj, evt):
1494 1468 self.dragging = False
1495 1469  
... ... @@ -1501,7 +1475,6 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1501 1475 """
1502 1476 This event is responsible to reorient image, set mouse cursors
1503 1477 """
1504   -
1505 1478 if self.dragging:
1506 1479 self._move_center_rot()
1507 1480 elif self.to_rot:
... ... @@ -1599,19 +1572,6 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1599 1572  
1600 1573 self.viewer.slice_.q_orientation = transformations.quaternion_multiply(self.viewer.slice_.q_orientation, transformations.quaternion_about_axis(angle, axis))
1601 1574  
1602   - # print axis, angle, self.viewer.slice_.q_orientation
1603   - print axis, angle
1604   -
1605   - if self.viewer.orientation == 'AXIAL':
1606   - # angle = np.arctan2(p0[0] , p0[1]) - np.arctan2(p1[0], p1[1])
1607   - self.viewer.slice_.rotations[2] = angle
1608   - elif self.viewer.orientation == 'CORONAL':
1609   - # angle = np.arctan2(p0[0] , p0[1]) - np.arctan2(p1[0], p1[1])
1610   - self.viewer.slice_.rotations[1] = angle
1611   - elif self.viewer.orientation == 'SAGITAL':
1612   - # angle = np.arctan2(p0[0] , p0[1]) - np.arctan2(p1[0], p1[1])
1613   - self.viewer.slice_.rotations[0] = angle
1614   -
1615 1575 az, ay, ax = transformations.euler_from_quaternion(self.viewer.slice_.q_orientation)
1616 1576 Publisher.sendMessage('Update reorient angles', (ax, ay, az))
1617 1577  
... ... @@ -1677,7 +1637,6 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1677 1637 self.line1 = self._create_line(0, 0.5, 1, 0.5, color1)
1678 1638 self.line2 = self._create_line(0.5, 0, 0.5, 1, color2)
1679 1639  
1680   -
1681 1640 def _discard_buffers(self):
1682 1641 for buffer_ in self.viewer.slice_.buffer_slices.values():
1683 1642 buffer_.discard_vtk_image()
... ...
invesalius/gui/dialogs.py
... ... @@ -1576,13 +1576,14 @@ class ReorientImageDialog(wx.Dialog):
1576 1576  
1577 1577 self._init_gui()
1578 1578 self._bind_events()
  1579 + self._bind_events_wx()
1579 1580  
1580 1581 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")
  1582 + self.anglex = wx.TextCtrl(self, -1, "0.0", style=wx.TE_READONLY)
  1583 + self.angley = wx.TextCtrl(self, -1, "0.0", style=wx.TE_READONLY)
  1584 + self.anglez = wx.TextCtrl(self, -1, "0.0", style=wx.TE_READONLY)
1584 1585  
1585   - btnapply = wx.Button(self, -1, _("Apply"))
  1586 + self.btnapply = wx.Button(self, -1, _("Apply"))
1586 1587  
1587 1588 sizer = wx.BoxSizer(wx.HORIZONTAL)
1588 1589  
... ... @@ -1598,7 +1599,7 @@ class ReorientImageDialog(wx.Dialog):
1598 1599 sizer.Add(self.anglez, 0, wx.EXPAND | wx.ALL, 5)
1599 1600 sizer.AddSpacer(5)
1600 1601  
1601   - sizer.Add(btnapply, 0, wx.EXPAND | wx.ALL, 5)
  1602 + sizer.Add(self.btnapply, 0, wx.EXPAND | wx.ALL, 5)
1602 1603 sizer.AddSpacer(5)
1603 1604  
1604 1605 self.SetSizer(sizer)
... ... @@ -1607,10 +1608,21 @@ class ReorientImageDialog(wx.Dialog):
1607 1608 def _bind_events(self):
1608 1609 Publisher.subscribe(self._update_angles, 'Update reorient angles')
1609 1610  
  1611 + def _bind_events_wx(self):
  1612 + self.btnapply.Bind(wx.EVT_BUTTON, self.apply_reorientation)
  1613 + self.Bind(wx.EVT_CLOSE, self.OnClose)
  1614 +
1610 1615 def _update_angles(self, pubsub_evt):
1611 1616 anglex, angley, anglez = pubsub_evt.data
1612 1617 self.anglex.SetValue("%.2f" % np.rad2deg(anglex))
1613 1618 self.angley.SetValue("%.2f" % np.rad2deg(angley))
1614 1619 self.anglez.SetValue("%.2f" % np.rad2deg(anglez))
1615 1620  
1616   - print anglex, angley, anglez
  1621 + def apply_reorientation(self, evt):
  1622 + Publisher.sendMessage('Apply reorientation')
  1623 + self.Close()
  1624 +
  1625 + def OnClose(self, evt):
  1626 + Publisher.sendMessage('Disable style', const.SLICE_STATE_REORIENT)
  1627 + Publisher.sendMessage('Enable style', const.STATE_DEFAULT)
  1628 + self.Destroy()
... ...