Commit a7c8e435747c14b78f0dcac6af9a02e69fcc1a3d

Authored by Renan
Committed by Thiago Franco de Moraes
1 parent 5b5760de

Navigation improvement (#79)

* Added indicator to MTC sensors

* Show sensors ID in viewer volume

* fix

* PLH stylus button

* Dialog to confirm all markers delete

* Fix remove sensors ID

* Disable sensors ID when navigation mode is disabled
invesalius/data/coordinates.py
@@ -22,7 +22,7 @@ import numpy as np @@ -22,7 +22,7 @@ import numpy as np
22 22
23 from time import sleep 23 from time import sleep
24 from random import uniform 24 from random import uniform
25 - 25 +from wx.lib.pubsub import pub as Publisher
26 26
27 def GetCoordinates(trck_init, trck_id, ref_mode): 27 def GetCoordinates(trck_init, trck_id, ref_mode):
28 28
@@ -55,6 +55,7 @@ def ClaronCoord(trck_init, trck_id, ref_mode): @@ -55,6 +55,7 @@ def ClaronCoord(trck_init, trck_id, ref_mode):
55 coord = None 55 coord = None
56 k = 0 56 k = 0
57 # TODO: try to replace while and use some Claron internal computation 57 # TODO: try to replace while and use some Claron internal computation
  58 +
58 if ref_mode: 59 if ref_mode:
59 while k < 20: 60 while k < 20:
60 try: 61 try:
@@ -80,6 +81,8 @@ def ClaronCoord(trck_init, trck_id, ref_mode): @@ -80,6 +81,8 @@ def ClaronCoord(trck_init, trck_id, ref_mode):
80 k += 1 81 k += 1
81 print "wait, collecting coordinates ..." 82 print "wait, collecting coordinates ..."
82 83
  84 + Publisher.sendMessage('Sensors ID', [trck.probeID, trck.refID])
  85 +
83 return coord 86 return coord
84 87
85 88
@@ -123,6 +126,9 @@ def PolhemusWrapperCoord(trck, trck_id, ref_mode): @@ -123,6 +126,9 @@ def PolhemusWrapperCoord(trck, trck_id, ref_mode):
123 float(trck.PositionTooltipZ1) * scale[2], float(trck.AngleX1), float(trck.AngleY1), 126 float(trck.PositionTooltipZ1) * scale[2], float(trck.AngleX1), float(trck.AngleY1),
124 float(trck.AngleZ1)]) 127 float(trck.AngleZ1)])
125 128
  129 + if trck.StylusButton:
  130 + Publisher.sendMessage('PLH Stylus Button On')
  131 +
126 return coord 132 return coord
127 133
128 134
@@ -221,6 +227,8 @@ def DebugCoord(trk_init, trck_id, ref_mode): @@ -221,6 +227,8 @@ def DebugCoord(trk_init, trck_id, ref_mode):
221 coord = np.array([uniform(1, 200), uniform(1, 200), uniform(1, 200), 227 coord = np.array([uniform(1, 200), uniform(1, 200), uniform(1, 200),
222 uniform(1, 200), uniform(1, 200), uniform(1, 200)]) 228 uniform(1, 200), uniform(1, 200), uniform(1, 200)])
223 229
  230 + Publisher.sendMessage('Sensors ID', [int(uniform(0, 5)), int(uniform(0, 5))])
  231 +
224 return coord 232 return coord
225 233
226 234
invesalius/data/trackers.py
@@ -200,6 +200,7 @@ def DisconnectTracker(tracker_id): @@ -200,6 +200,7 @@ def DisconnectTracker(tracker_id):
200 """ 200 """
201 from wx.lib.pubsub import pub as Publisher 201 from wx.lib.pubsub import pub as Publisher
202 Publisher.sendMessage('Update status text in GUI', _("Disconnecting tracker ...")) 202 Publisher.sendMessage('Update status text in GUI', _("Disconnecting tracker ..."))
  203 + Publisher.sendMessage('Remove sensors ID')
203 trck_init = None 204 trck_init = None
204 # TODO: create individual functions to disconnect each other device, e.g. Polhemus. 205 # TODO: create individual functions to disconnect each other device, e.g. Polhemus.
205 if tracker_id == 1: 206 if tracker_id == 1:
invesalius/data/trigger.py
@@ -47,12 +47,12 @@ class Trigger(threading.Thread): @@ -47,12 +47,12 @@ class Trigger(threading.Thread):
47 print 'Connection with port COM1 failed.' 47 print 'Connection with port COM1 failed.'
48 48
49 def stop(self): 49 def stop(self):
50 - if self.trigger_init:  
51 - self.trigger_init.close()  
52 self._pause_ = True 50 self._pause_ = True
53 51
54 def run(self): 52 def run(self):
55 while self.nav_id: 53 while self.nav_id:
  54 + self.trigger_init.write('0')
  55 + sleep(0.3)
56 lines = self.trigger_init.readlines() 56 lines = self.trigger_init.readlines()
57 # Following lines can simulate a trigger in 3 sec repetitions 57 # Following lines can simulate a trigger in 3 sec repetitions
58 # sleep(3) 58 # sleep(3)
@@ -61,4 +61,6 @@ class Trigger(threading.Thread): @@ -61,4 +61,6 @@ class Trigger(threading.Thread):
61 wx.CallAfter(Publisher.sendMessage, 'Create marker') 61 wx.CallAfter(Publisher.sendMessage, 'Create marker')
62 sleep(0.175) 62 sleep(0.175)
63 if self._pause_: 63 if self._pause_:
  64 + if self.trigger_init:
  65 + self.trigger_init.close()
64 return 66 return
invesalius/data/viewer_volume.py
@@ -120,6 +120,9 @@ class Viewer(wx.Panel): @@ -120,6 +120,9 @@ class Viewer(wx.Panel):
120 self._to_show_ball = 0 120 self._to_show_ball = 0
121 self._ball_ref_visibility = False 121 self._ball_ref_visibility = False
122 122
  123 + self.sen1 = False
  124 + self.sen2 = False
  125 +
123 def __bind_events(self): 126 def __bind_events(self):
124 Publisher.subscribe(self.LoadActor, 127 Publisher.subscribe(self.LoadActor,
125 'Load surface actor into viewer') 128 'Load surface actor into viewer')
@@ -191,6 +194,9 @@ class Viewer(wx.Panel): @@ -191,6 +194,9 @@ class Viewer(wx.Panel):
191 Publisher.subscribe(self._check_ball_reference, 'Enable style') 194 Publisher.subscribe(self._check_ball_reference, 'Enable style')
192 Publisher.subscribe(self._uncheck_ball_reference, 'Disable style') 195 Publisher.subscribe(self._uncheck_ball_reference, 'Disable style')
193 196
  197 + Publisher.subscribe(self.OnSensors, 'Sensors ID')
  198 + Publisher.subscribe(self.OnRemoveSensorsID, 'Remove sensors ID')
  199 +
194 # Related to marker creation in navigation tools 200 # Related to marker creation in navigation tools
195 Publisher.subscribe(self.AddMarker, 'Add marker') 201 Publisher.subscribe(self.AddMarker, 'Add marker')
196 Publisher.subscribe(self.HideAllMarkers, 'Hide all markers') 202 Publisher.subscribe(self.HideAllMarkers, 'Hide all markers')
@@ -241,6 +247,51 @@ class Viewer(wx.Panel): @@ -241,6 +247,51 @@ class Viewer(wx.Panel):
241 self.RemoveBallReference() 247 self.RemoveBallReference()
242 self.interactor.Render() 248 self.interactor.Render()
243 249
  250 + def OnSensors(self, pubsub_evt):
  251 + probe_id = pubsub_evt.data[0]
  252 + ref_id = pubsub_evt.data[1]
  253 + if not self.sen1:
  254 + self.CreateSensorID()
  255 +
  256 + if probe_id:
  257 + colour1 = (0, 1, 0)
  258 + else:
  259 + colour1 = (1, 0, 0)
  260 + if ref_id:
  261 + colour2 = (0, 1, 0)
  262 + else:
  263 + colour2 = (1, 0, 0)
  264 +
  265 + self.sen1.SetColour(colour1)
  266 + self.sen2.SetColour(colour2)
  267 + self.Refresh()
  268 +
  269 + def CreateSensorID(self):
  270 + sen1 = vtku.Text()
  271 + sen1.SetSize(const.TEXT_SIZE_LARGE)
  272 + sen1.SetPosition((const.X, const.Y))
  273 + sen1.ShadowOff()
  274 + sen1.SetValue("O")
  275 + self.sen1 = sen1
  276 + self.ren.AddActor(sen1.actor)
  277 +
  278 + sen2 = vtku.Text()
  279 + sen2.SetSize(const.TEXT_SIZE_LARGE)
  280 + sen2.SetPosition((const.X+0.04, const.Y))
  281 + sen2.ShadowOff()
  282 + sen2.SetValue("O")
  283 + self.sen2 = sen2
  284 + self.ren.AddActor(sen2.actor)
  285 +
  286 + self.interactor.Render()
  287 +
  288 + def OnRemoveSensorsID(self, pubsub_evt):
  289 + if self.sen1:
  290 + self.ren.RemoveActor(self.sen1.actor)
  291 + self.ren.RemoveActor(self.sen2.actor)
  292 + self.sen1 = self.sen2 = False
  293 + self.interactor.Render()
  294 +
244 def OnShowSurface(self, pubsub_evt): 295 def OnShowSurface(self, pubsub_evt):
245 index, value = pubsub_evt.data 296 index, value = pubsub_evt.data
246 if value: 297 if value:
invesalius/gui/dialogs.py
@@ -793,11 +793,23 @@ def NoMarkerSelected(): @@ -793,11 +793,23 @@ def NoMarkerSelected():
793 dlg = wx.MessageDialog(None, "", msg, 793 dlg = wx.MessageDialog(None, "", msg,
794 wx.ICON_INFORMATION | wx.OK) 794 wx.ICON_INFORMATION | wx.OK)
795 else: 795 else:
796 - dlg = wx.MessageDialog(None,msg, "InVesalius 3 - Neuronavigator", 796 + dlg = wx.MessageDialog(None, msg, "InVesalius 3 - Neuronavigator",
797 wx.ICON_INFORMATION | wx.OK) 797 wx.ICON_INFORMATION | wx.OK)
798 dlg.ShowModal() 798 dlg.ShowModal()
799 dlg.Destroy() 799 dlg.Destroy()
800 800
  801 +def DeleteAllMarkers():
  802 + msg = _("Do you really want to delete all markers?")
  803 + if sys.platform == 'darwin':
  804 + dlg = wx.MessageDialog(None, "", msg,
  805 + wx.OK | wx.CANCEL | wx.ICON_QUESTION)
  806 + else:
  807 + dlg = wx.MessageDialog(None, msg, "InVesalius 3 - Neuronavigator",
  808 + wx.OK | wx.CANCEL | wx.ICON_QUESTION)
  809 + result = dlg.ShowModal()
  810 + dlg.Destroy()
  811 + return result
  812 +
801 813
802 def EnterMarkerID(default): 814 def EnterMarkerID(default):
803 msg = _("Edit marker ID") 815 msg = _("Edit marker ID")
invesalius/gui/frame.py
@@ -486,6 +486,8 @@ class Frame(wx.Frame): @@ -486,6 +486,8 @@ class Frame(wx.Frame):
486 wx.MessageBox(_('Currently the Navigation mode is only working on Windows'), 'Info', wx.OK | wx.ICON_INFORMATION) 486 wx.MessageBox(_('Currently the Navigation mode is only working on Windows'), 'Info', wx.OK | wx.ICON_INFORMATION)
487 self._show_navigator_message = False 487 self._show_navigator_message = False
488 Publisher.sendMessage('Set navigation mode', status) 488 Publisher.sendMessage('Set navigation mode', status)
  489 + if not status:
  490 + Publisher.sendMessage('Remove sensors ID')
489 491
490 def OnSize(self, evt): 492 def OnSize(self, evt):
491 """ 493 """
invesalius/gui/task_navigator.py
@@ -325,6 +325,7 @@ class NeuronavigationPanel(wx.Panel): @@ -325,6 +325,7 @@ class NeuronavigationPanel(wx.Panel):
325 Publisher.subscribe(self.UpdateTriggerState, 'Update trigger state') 325 Publisher.subscribe(self.UpdateTriggerState, 'Update trigger state')
326 Publisher.subscribe(self.UpdateImageCoordinates, 'Set ball reference position') 326 Publisher.subscribe(self.UpdateImageCoordinates, 'Set ball reference position')
327 Publisher.subscribe(self.OnDisconnectTracker, 'Disconnect tracker') 327 Publisher.subscribe(self.OnDisconnectTracker, 'Disconnect tracker')
  328 + Publisher.subscribe(self.OnStylusButton, 'PLH Stylus Button On')
328 329
329 def LoadImageFiducials(self, pubsub_evt): 330 def LoadImageFiducials(self, pubsub_evt):
330 marker_id = pubsub_evt.data[0] 331 marker_id = pubsub_evt.data[0]
@@ -358,6 +359,10 @@ class NeuronavigationPanel(wx.Panel): @@ -358,6 +359,10 @@ class NeuronavigationPanel(wx.Panel):
358 if self.tracker_id: 359 if self.tracker_id:
359 dt.TrackerConnection(self.tracker_id, 'disconnect') 360 dt.TrackerConnection(self.tracker_id, 'disconnect')
360 361
  362 + def OnStylusButton(self, pubsub_evt):
  363 + if self.trigger_state:
  364 + Publisher.sendMessage('Create marker')
  365 +
361 def OnChoiceTracker(self, evt, ctrl): 366 def OnChoiceTracker(self, evt, ctrl):
362 Publisher.sendMessage('Update status text in GUI', _("Configuring tracker ...")) 367 Publisher.sendMessage('Update status text in GUI', _("Configuring tracker ..."))
363 if evt: 368 if evt:
@@ -642,10 +647,12 @@ class MarkersPanel(wx.Panel): @@ -642,10 +647,12 @@ class MarkersPanel(wx.Panel):
642 self.list_coord[list_index][7] = str(id_label) 647 self.list_coord[list_index][7] = str(id_label)
643 648
644 def OnDeleteAllMarkers(self, pubsub_evt): 649 def OnDeleteAllMarkers(self, pubsub_evt):
645 - self.list_coord = []  
646 - self.marker_ind = 0  
647 - Publisher.sendMessage('Remove all markers', self.lc.GetItemCount())  
648 - self.lc.DeleteAllItems() 650 + result = dlg.DeleteAllMarkers()
  651 + if result == wx.ID_OK:
  652 + self.list_coord = []
  653 + self.marker_ind = 0
  654 + Publisher.sendMessage('Remove all markers', self.lc.GetItemCount())
  655 + self.lc.DeleteAllItems()
649 656
650 def OnDeleteSingleMarker(self, evt): 657 def OnDeleteSingleMarker(self, evt):
651 # OnDeleteSingleMarker is used for both pubsub and button click events 658 # OnDeleteSingleMarker is used for both pubsub and button click events
@@ -682,7 +689,7 @@ class MarkersPanel(wx.Panel): @@ -682,7 +689,7 @@ class MarkersPanel(wx.Panel):
682 # OnCreateMarker is used for both pubsub and button click events 689 # OnCreateMarker is used for both pubsub and button click events
683 # Pubsub is used for markers created with fiducial buttons, trigger and create marker button 690 # Pubsub is used for markers created with fiducial buttons, trigger and create marker button
684 if hasattr(evt, 'data'): 691 if hasattr(evt, 'data'):
685 - if evt.data: 692 + if evt.data is not None:
686 self.CreateMarker(evt.data[0], (0.0, 1.0, 0.0), self.marker_size, evt.data[1]) 693 self.CreateMarker(evt.data[0], (0.0, 1.0, 0.0), self.marker_size, evt.data[1])
687 else: 694 else:
688 self.CreateMarker(self.current_coord, self.marker_colour, self.marker_size) 695 self.CreateMarker(self.current_coord, self.marker_colour, self.marker_size)