Commit b2b98a16e815eb15416382c43600d68f94a75676

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

Dragging the center of rotation

invesalius/data/slice_.py
... ... @@ -93,8 +93,9 @@ class Slice(object):
93 93 self._type_projection = const.PROJECTION_NORMAL
94 94 self.n_border = const.PROJECTION_BORDER_SIZE
95 95  
96   - self.spacing = (1.0, 1.0, 1.0)
  96 + self._spacing = (1.0, 1.0, 1.0)
97 97 self.rotations = (0, 0, 0)
  98 + self.center = [0, 0, 0]
98 99  
99 100 self.number_of_colours = 256
100 101 self.saturation_range = (0, 0)
... ... @@ -125,6 +126,16 @@ class Slice(object):
125 126 i, e = value.min(), value.max()
126 127 r = int(e) - int(i)
127 128 self.histogram = np.histogram(self._matrix, r, (i, e))[0]
  129 + self.center = [(s * d/2.0) for (d, s) in zip(self.matrix.shape[::-1], self.spacing)]
  130 +
  131 + @property
  132 + def spacing(self):
  133 + return self._spacing
  134 +
  135 + @spacing.setter
  136 + def spacing(self, value):
  137 + self._spacing = value
  138 + self.center = [(s * d/2.0) for (d, s) in zip(self.matrix.shape[::-1], self.spacing)]
128 139  
129 140 def __bind_events(self):
130 141 # General slice control
... ... @@ -568,16 +579,16 @@ class Slice(object):
568 579 number_slices = 1
569 580  
570 581 if np.any(self.rotations):
571   - dz, dy, dx = self.matrix.shape
  582 + cx, cy, cz = self.center
572 583 rx, ry, rz = self.rotations
573 584 sx, sy, sz = self.spacing
574   - T0 = transformations.translation_matrix((-dz/2.0 * sz, -dy/2.0 * sy, -dx/2.0 * sx))
  585 + T0 = transformations.translation_matrix((-cz, -cy, -cx))
575 586 Rx = transformations.rotation_matrix(rx, (0, 0, 1))
576 587 Ry = transformations.rotation_matrix(ry, (0, 1, 0))
577 588 Rz = transformations.rotation_matrix(rz, (1, 0, 0))
578 589 # R = transformations.euler_matrix(rz, ry, rx, 'rzyx')
579 590 R = transformations.concatenate_matrices(Rx, Ry, Rz)
580   - T1 = transformations.translation_matrix((dz/2.0 * sz, dy/2.0 * sy, dx/2.0 * sx))
  591 + T1 = transformations.translation_matrix((cz, cy, cx))
581 592 M = transformations.concatenate_matrices(T1, R.T, T0)
582 593  
583 594  
... ...
invesalius/data/styles.py
... ... @@ -1417,7 +1417,12 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1417 1417 self.line1 = None
1418 1418 self.line2 = None
1419 1419  
  1420 + self.actors = []
  1421 +
  1422 + self.picker = vtk.vtkWorldPointPicker()
  1423 +
1420 1424 self.AddObserver("KeyPressEvent", self.OnKeyPress)
  1425 + self.AddObserver("MouseMoveEvent", self.OnMouseMove)
1421 1426 self.viewer.slice_data.renderer.AddObserver("StartEvent", self.OnUpdate)
1422 1427  
1423 1428 def SetUp(self):
... ... @@ -1425,6 +1430,10 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1425 1430 self.draw_lines()
1426 1431 Publisher.sendMessage('Reload actual slice')
1427 1432  
  1433 + def CleanUp(self):
  1434 + for actor in self.actors:
  1435 + self.viewer.slice_data.renderer.RemoveActor(actor)
  1436 +
1428 1437 def OnKeyPress(self, evt, obj):
1429 1438 key = self.viewer.interactor.GetKeyCode()
1430 1439 if key == '+':
... ... @@ -1452,10 +1461,46 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1452 1461 self.viewer.slice_.current_mask.clear_history()
1453 1462 Publisher.sendMessage('Reload actual slice')
1454 1463  
  1464 + def OnMouseMove(self, obj, evt):
  1465 + """
  1466 + This event is responsible to reorient image, set mouse cursors
  1467 + """
  1468 + # Getting mouse position
  1469 + iren = self.viewer.interactor
  1470 + mx, my = iren.GetEventPosition()
  1471 +
  1472 + # Getting center value
  1473 + center = self.viewer.slice_.center
  1474 + coord = vtk.vtkCoordinate()
  1475 + coord.SetValue(center)
  1476 + cx, cy = coord.GetComputedDisplayValue(self.viewer.slice_data.renderer)
  1477 +
  1478 + dist_center = ((mx - cx)**2 + (my - cy)**2)**0.5
  1479 +
  1480 + if dist_center <= 15:
  1481 + cursor = wx.StockCursor(wx.CURSOR_SIZENESW)
  1482 +
  1483 + if self.left_pressed:
  1484 + self.picker.Pick(mx, my, 0, self.viewer.slice_data.renderer)
  1485 + x, y, z = self.picker.GetPickPosition()
  1486 + icx, icy, icz = self.viewer.slice_.center
  1487 +
  1488 + if self.viewer.orientation == 'AXIAL':
  1489 + self.viewer.slice_.center = (x, y, icz)
  1490 + elif self.viewer.orientation == 'CORONAL':
  1491 + self.viewer.slice_.center = (x, icy, z)
  1492 + elif self.viewer.orientation == 'SAGITAL':
  1493 + self.viewer.slice_.center = (icx, y, z)
  1494 + Publisher.sendMessage('Update slice viewer')
  1495 + else:
  1496 + cursor = wx.StockCursor(wx.CURSOR_DEFAULT)
  1497 +
  1498 + self.viewer.interactor.SetCursor(cursor)
  1499 +
1455 1500 def OnUpdate(self, obj, evt):
1456 1501 w, h = self.viewer.slice_data.renderer.GetSize()
1457 1502  
1458   - center = self.viewer.slice_data.actor.GetCenter()
  1503 + center = self.viewer.slice_.center
1459 1504 coord = vtk.vtkCoordinate()
1460 1505 coord.SetValue(center)
1461 1506 x, y = coord.GetComputedDisplayValue(self.viewer.slice_data.renderer)
... ... @@ -1488,6 +1533,8 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1488 1533  
1489 1534 self.viewer.slice_data.renderer.AddActor(actor)
1490 1535  
  1536 + self.actors.append(actor)
  1537 +
1491 1538 return line
1492 1539  
1493 1540 def draw_lines(self):
... ...