Commit 1a85e2a409c9278c6fabae045fbf33a6bc25900f
1 parent
354f97e8
Exists in
interactor_style
Created a new interactor style to handle the Spin camera
Showing
2 changed files
with
56 additions
and
24 deletions
Show diff stats
invesalius/data/styles.py
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | #-------------------------------------------------------------------------- | 18 | #-------------------------------------------------------------------------- |
| 19 | 19 | ||
| 20 | import vtk | 20 | import vtk |
| 21 | +import wx | ||
| 21 | 22 | ||
| 22 | from wx.lib.pubsub import pub as Publisher | 23 | from wx.lib.pubsub import pub as Publisher |
| 23 | 24 | ||
| @@ -289,12 +290,45 @@ class PanMoveInteractorStyle(ZoomInteractorStyle): | @@ -289,12 +290,45 @@ class PanMoveInteractorStyle(ZoomInteractorStyle): | ||
| 289 | self.AddObserver("MouseMoveEvent", self.OnPanMove) | 290 | self.AddObserver("MouseMoveEvent", self.OnPanMove) |
| 290 | 291 | ||
| 291 | def OnPanMove(self, obj, evt): | 292 | def OnPanMove(self, obj, evt): |
| 292 | - print "PAN" | ||
| 293 | if self.left_pressed: | 293 | if self.left_pressed: |
| 294 | obj.Pan() | 294 | obj.Pan() |
| 295 | obj.OnRightButtonDown() | 295 | obj.OnRightButtonDown() |
| 296 | 296 | ||
| 297 | 297 | ||
| 298 | +class SpinInteractorStyle(ZoomInteractorStyle): | ||
| 299 | + """ | ||
| 300 | + Interactor style responsible for spin the camera. | ||
| 301 | + """ | ||
| 302 | + def __init__(self, viewer): | ||
| 303 | + ZoomInteractorStyle.__init__(self) | ||
| 304 | + | ||
| 305 | + self.viewer = viewer | ||
| 306 | + | ||
| 307 | + self.AddObserver("MouseMoveEvent", self.OnSpinMove) | ||
| 308 | + self.viewer.interactor.Bind(wx.EVT_LEFT_DCLICK, self.OnUnspinPan) | ||
| 309 | + | ||
| 310 | + def OnSpinMove(self, obj, evt): | ||
| 311 | + iren = obj.GetInteractor() | ||
| 312 | + mouse_x, mouse_y = iren.GetLastEventPosition() | ||
| 313 | + ren = iren.FindPokedRenderer(mouse_x, mouse_y) | ||
| 314 | + cam = ren.GetActiveCamera() | ||
| 315 | + if (self.left_pressed): | ||
| 316 | + self.viewer.UpdateTextDirection(cam) | ||
| 317 | + self.spined_image = True | ||
| 318 | + obj.Spin() | ||
| 319 | + obj.OnRightButtonDown() | ||
| 320 | + | ||
| 321 | + def OnUnspinPan(self, evt): | ||
| 322 | + orig_orien = 1 | ||
| 323 | + iren = self.viewer.interactor | ||
| 324 | + mouse_x, mouse_y = iren.GetLastEventPosition() | ||
| 325 | + ren = iren.FindPokedRenderer(mouse_x, mouse_y) | ||
| 326 | + cam = ren.GetActiveCamera() | ||
| 327 | + cam.SetViewUp(const.SLICE_POSITION[orig_orien][0][self.viewer.orientation]) | ||
| 328 | + self.viewer.ResetTextDirection(cam) | ||
| 329 | + iren.Render() | ||
| 330 | + | ||
| 331 | + | ||
| 298 | class ViewerStyle: | 332 | class ViewerStyle: |
| 299 | def __init__(self): | 333 | def __init__(self): |
| 300 | self.interactor = None | 334 | self.interactor = None |
invesalius/data/viewer_slice.py
| @@ -224,6 +224,13 @@ class Viewer(wx.Panel): | @@ -224,6 +224,13 @@ class Viewer(wx.Panel): | ||
| 224 | self.interactor.SetInteractorStyle(style) | 224 | self.interactor.SetInteractorStyle(style) |
| 225 | self.interactor.Render() | 225 | self.interactor.Render() |
| 226 | 226 | ||
| 227 | + elif state == const.STATE_SPIN: | ||
| 228 | + style = styles.SpinInteractorStyle(self) | ||
| 229 | + | ||
| 230 | + self.style = style | ||
| 231 | + self.interactor.SetInteractorStyle(style) | ||
| 232 | + self.interactor.Render() | ||
| 233 | + | ||
| 227 | else: | 234 | else: |
| 228 | self.state = state | 235 | self.state = state |
| 229 | action = { | 236 | action = { |
| @@ -235,12 +242,6 @@ class Viewer(wx.Panel): | @@ -235,12 +242,6 @@ class Viewer(wx.Panel): | ||
| 235 | "EnterEvent": self.OnEnterInteractor, | 242 | "EnterEvent": self.OnEnterInteractor, |
| 236 | "LeaveEvent": self.OnLeaveInteractor | 243 | "LeaveEvent": self.OnLeaveInteractor |
| 237 | }, | 244 | }, |
| 238 | - const.STATE_SPIN: | ||
| 239 | - { | ||
| 240 | - "MouseMoveEvent": self.OnSpinMove, | ||
| 241 | - "LeftButtonPressEvent": self.OnSpinClick, | ||
| 242 | - "LeftButtonReleaseEvent": self.OnVtkRightRelease | ||
| 243 | - }, | ||
| 244 | const.STATE_ZOOM: | 245 | const.STATE_ZOOM: |
| 245 | { | 246 | { |
| 246 | "MouseMoveEvent": self.OnZoomMoveLeft, | 247 | "MouseMoveEvent": self.OnZoomMoveLeft, |
| @@ -308,8 +309,8 @@ class Viewer(wx.Panel): | @@ -308,8 +309,8 @@ class Viewer(wx.Panel): | ||
| 308 | 309 | ||
| 309 | if ((state == const.STATE_ZOOM) or (state == const.STATE_ZOOM_SL)): | 310 | if ((state == const.STATE_ZOOM) or (state == const.STATE_ZOOM_SL)): |
| 310 | self.interactor.Bind(wx.EVT_LEFT_DCLICK, self.OnUnZoom) | 311 | self.interactor.Bind(wx.EVT_LEFT_DCLICK, self.OnUnZoom) |
| 311 | - else: | ||
| 312 | - self.interactor.Bind(wx.EVT_LEFT_DCLICK, self.OnUnSpinPan) | 312 | + #else: |
| 313 | + #self.interactor.Bind(wx.EVT_LEFT_DCLICK, self.OnUnspinPan) | ||
| 313 | 314 | ||
| 314 | # Measures are using vtkPropPicker because they need to get which actor | 315 | # Measures are using vtkPropPicker because they need to get which actor |
| 315 | # was picked. | 316 | # was picked. |
| @@ -427,7 +428,7 @@ class Viewer(wx.Panel): | @@ -427,7 +428,7 @@ class Viewer(wx.Panel): | ||
| 427 | #self.Reposition(slice_data) | 428 | #self.Reposition(slice_data) |
| 428 | self.interactor.Render() | 429 | self.interactor.Render() |
| 429 | 430 | ||
| 430 | - def OnUnSpinPan(self, evt): | 431 | + def UnspinPan(self): |
| 431 | orientation = self.orientation | 432 | orientation = self.orientation |
| 432 | proj = project.Project() | 433 | proj = project.Project() |
| 433 | orig_orien = 1 | 434 | orig_orien = 1 |
| @@ -452,20 +453,6 @@ class Viewer(wx.Panel): | @@ -452,20 +453,6 @@ class Viewer(wx.Panel): | ||
| 452 | self.interactor.Render() | 453 | self.interactor.Render() |
| 453 | self.paned_image = False | 454 | self.paned_image = False |
| 454 | 455 | ||
| 455 | - def OnSpinMove(self, evt, obj): | ||
| 456 | - mouse_x, mouse_y = self.interactor.GetLastEventPosition() | ||
| 457 | - ren = self.interactor.FindPokedRenderer(mouse_x, mouse_y) | ||
| 458 | - cam = ren.GetActiveCamera() | ||
| 459 | - if (self.left_pressed): | ||
| 460 | - self.UpdateTextDirection(cam) | ||
| 461 | - self.spined_image = True | ||
| 462 | - evt.Spin() | ||
| 463 | - evt.OnRightButtonDown() | ||
| 464 | - | ||
| 465 | - | ||
| 466 | - def OnSpinClick(self, evt, obj): | ||
| 467 | - evt.StartSpin() | ||
| 468 | - | ||
| 469 | def OnEnterInteractor(self, evt, obj): | 456 | def OnEnterInteractor(self, evt, obj): |
| 470 | if (self.slice_.buffer_slices[self.orientation].mask is None): | 457 | if (self.slice_.buffer_slices[self.orientation].mask is None): |
| 471 | return | 458 | return |
| @@ -547,6 +534,17 @@ class Viewer(wx.Panel): | @@ -547,6 +534,17 @@ class Viewer(wx.Panel): | ||
| 547 | self.right_text.SetValue(directions[3]) | 534 | self.right_text.SetValue(directions[3]) |
| 548 | self.interactor.Render() | 535 | self.interactor.Render() |
| 549 | 536 | ||
| 537 | + def ResetTextDirection(self, cam): | ||
| 538 | + # Values are on ccw order, starting from the top: | ||
| 539 | + if self.orientation == 'AXIAL': | ||
| 540 | + values = [_("A"), _("R"), _("P"), _("L")] | ||
| 541 | + elif self.orientation == 'CORONAL': | ||
| 542 | + values = [_("T"), _("R"), _("B"), _("L")] | ||
| 543 | + else: # 'SAGITAL': | ||
| 544 | + values = [_("T"), _("P"), _("B"), _("A")] | ||
| 545 | + | ||
| 546 | + self.RenderTextDirection(values) | ||
| 547 | + self.interactor.Render() | ||
| 550 | 548 | ||
| 551 | def UpdateTextDirection(self, cam): | 549 | def UpdateTextDirection(self, cam): |
| 552 | croll = cam.GetRoll() | 550 | croll = cam.GetRoll() |