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,8 +93,9 @@ class Slice(object):
93 self._type_projection = const.PROJECTION_NORMAL 93 self._type_projection = const.PROJECTION_NORMAL
94 self.n_border = const.PROJECTION_BORDER_SIZE 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 self.rotations = (0, 0, 0) 97 self.rotations = (0, 0, 0)
  98 + self.center = [0, 0, 0]
98 99
99 self.number_of_colours = 256 100 self.number_of_colours = 256
100 self.saturation_range = (0, 0) 101 self.saturation_range = (0, 0)
@@ -125,6 +126,16 @@ class Slice(object): @@ -125,6 +126,16 @@ class Slice(object):
125 i, e = value.min(), value.max() 126 i, e = value.min(), value.max()
126 r = int(e) - int(i) 127 r = int(e) - int(i)
127 self.histogram = np.histogram(self._matrix, r, (i, e))[0] 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 def __bind_events(self): 140 def __bind_events(self):
130 # General slice control 141 # General slice control
@@ -568,16 +579,16 @@ class Slice(object): @@ -568,16 +579,16 @@ class Slice(object):
568 number_slices = 1 579 number_slices = 1
569 580
570 if np.any(self.rotations): 581 if np.any(self.rotations):
571 - dz, dy, dx = self.matrix.shape 582 + cx, cy, cz = self.center
572 rx, ry, rz = self.rotations 583 rx, ry, rz = self.rotations
573 sx, sy, sz = self.spacing 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 Rx = transformations.rotation_matrix(rx, (0, 0, 1)) 586 Rx = transformations.rotation_matrix(rx, (0, 0, 1))
576 Ry = transformations.rotation_matrix(ry, (0, 1, 0)) 587 Ry = transformations.rotation_matrix(ry, (0, 1, 0))
577 Rz = transformations.rotation_matrix(rz, (1, 0, 0)) 588 Rz = transformations.rotation_matrix(rz, (1, 0, 0))
578 # R = transformations.euler_matrix(rz, ry, rx, 'rzyx') 589 # R = transformations.euler_matrix(rz, ry, rx, 'rzyx')
579 R = transformations.concatenate_matrices(Rx, Ry, Rz) 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 M = transformations.concatenate_matrices(T1, R.T, T0) 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,7 +1417,12 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1417 self.line1 = None 1417 self.line1 = None
1418 self.line2 = None 1418 self.line2 = None
1419 1419
  1420 + self.actors = []
  1421 +
  1422 + self.picker = vtk.vtkWorldPointPicker()
  1423 +
1420 self.AddObserver("KeyPressEvent", self.OnKeyPress) 1424 self.AddObserver("KeyPressEvent", self.OnKeyPress)
  1425 + self.AddObserver("MouseMoveEvent", self.OnMouseMove)
1421 self.viewer.slice_data.renderer.AddObserver("StartEvent", self.OnUpdate) 1426 self.viewer.slice_data.renderer.AddObserver("StartEvent", self.OnUpdate)
1422 1427
1423 def SetUp(self): 1428 def SetUp(self):
@@ -1425,6 +1430,10 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): @@ -1425,6 +1430,10 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1425 self.draw_lines() 1430 self.draw_lines()
1426 Publisher.sendMessage('Reload actual slice') 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 def OnKeyPress(self, evt, obj): 1437 def OnKeyPress(self, evt, obj):
1429 key = self.viewer.interactor.GetKeyCode() 1438 key = self.viewer.interactor.GetKeyCode()
1430 if key == '+': 1439 if key == '+':
@@ -1452,10 +1461,46 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): @@ -1452,10 +1461,46 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1452 self.viewer.slice_.current_mask.clear_history() 1461 self.viewer.slice_.current_mask.clear_history()
1453 Publisher.sendMessage('Reload actual slice') 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 def OnUpdate(self, obj, evt): 1500 def OnUpdate(self, obj, evt):
1456 w, h = self.viewer.slice_data.renderer.GetSize() 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 coord = vtk.vtkCoordinate() 1504 coord = vtk.vtkCoordinate()
1460 coord.SetValue(center) 1505 coord.SetValue(center)
1461 x, y = coord.GetComputedDisplayValue(self.viewer.slice_data.renderer) 1506 x, y = coord.GetComputedDisplayValue(self.viewer.slice_data.renderer)
@@ -1488,6 +1533,8 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): @@ -1488,6 +1533,8 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle):
1488 1533
1489 self.viewer.slice_data.renderer.AddActor(actor) 1534 self.viewer.slice_data.renderer.AddActor(actor)
1490 1535
  1536 + self.actors.append(actor)
  1537 +
1491 return line 1538 return line
1492 1539
1493 def draw_lines(self): 1540 def draw_lines(self):