Commit a7c8e435747c14b78f0dcac6af9a02e69fcc1a3d
Committed by
Thiago Franco de Moraes
1 parent
5b5760de
Exists in
master
and in
6 other branches
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
Showing
7 changed files
with
92 additions
and
9 deletions
Show diff stats
invesalius/data/coordinates.py
| ... | ... | @@ -22,7 +22,7 @@ import numpy as np |
| 22 | 22 | |
| 23 | 23 | from time import sleep |
| 24 | 24 | from random import uniform |
| 25 | - | |
| 25 | +from wx.lib.pubsub import pub as Publisher | |
| 26 | 26 | |
| 27 | 27 | def GetCoordinates(trck_init, trck_id, ref_mode): |
| 28 | 28 | |
| ... | ... | @@ -55,6 +55,7 @@ def ClaronCoord(trck_init, trck_id, ref_mode): |
| 55 | 55 | coord = None |
| 56 | 56 | k = 0 |
| 57 | 57 | # TODO: try to replace while and use some Claron internal computation |
| 58 | + | |
| 58 | 59 | if ref_mode: |
| 59 | 60 | while k < 20: |
| 60 | 61 | try: |
| ... | ... | @@ -80,6 +81,8 @@ def ClaronCoord(trck_init, trck_id, ref_mode): |
| 80 | 81 | k += 1 |
| 81 | 82 | print "wait, collecting coordinates ..." |
| 82 | 83 | |
| 84 | + Publisher.sendMessage('Sensors ID', [trck.probeID, trck.refID]) | |
| 85 | + | |
| 83 | 86 | return coord |
| 84 | 87 | |
| 85 | 88 | |
| ... | ... | @@ -123,6 +126,9 @@ def PolhemusWrapperCoord(trck, trck_id, ref_mode): |
| 123 | 126 | float(trck.PositionTooltipZ1) * scale[2], float(trck.AngleX1), float(trck.AngleY1), |
| 124 | 127 | float(trck.AngleZ1)]) |
| 125 | 128 | |
| 129 | + if trck.StylusButton: | |
| 130 | + Publisher.sendMessage('PLH Stylus Button On') | |
| 131 | + | |
| 126 | 132 | return coord |
| 127 | 133 | |
| 128 | 134 | |
| ... | ... | @@ -221,6 +227,8 @@ def DebugCoord(trk_init, trck_id, ref_mode): |
| 221 | 227 | coord = np.array([uniform(1, 200), uniform(1, 200), uniform(1, 200), |
| 222 | 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 | 232 | return coord |
| 225 | 233 | |
| 226 | 234 | ... | ... |
invesalius/data/trackers.py
| ... | ... | @@ -200,6 +200,7 @@ def DisconnectTracker(tracker_id): |
| 200 | 200 | """ |
| 201 | 201 | from wx.lib.pubsub import pub as Publisher |
| 202 | 202 | Publisher.sendMessage('Update status text in GUI', _("Disconnecting tracker ...")) |
| 203 | + Publisher.sendMessage('Remove sensors ID') | |
| 203 | 204 | trck_init = None |
| 204 | 205 | # TODO: create individual functions to disconnect each other device, e.g. Polhemus. |
| 205 | 206 | if tracker_id == 1: | ... | ... |
invesalius/data/trigger.py
| ... | ... | @@ -47,12 +47,12 @@ class Trigger(threading.Thread): |
| 47 | 47 | print 'Connection with port COM1 failed.' |
| 48 | 48 | |
| 49 | 49 | def stop(self): |
| 50 | - if self.trigger_init: | |
| 51 | - self.trigger_init.close() | |
| 52 | 50 | self._pause_ = True |
| 53 | 51 | |
| 54 | 52 | def run(self): |
| 55 | 53 | while self.nav_id: |
| 54 | + self.trigger_init.write('0') | |
| 55 | + sleep(0.3) | |
| 56 | 56 | lines = self.trigger_init.readlines() |
| 57 | 57 | # Following lines can simulate a trigger in 3 sec repetitions |
| 58 | 58 | # sleep(3) |
| ... | ... | @@ -61,4 +61,6 @@ class Trigger(threading.Thread): |
| 61 | 61 | wx.CallAfter(Publisher.sendMessage, 'Create marker') |
| 62 | 62 | sleep(0.175) |
| 63 | 63 | if self._pause_: |
| 64 | + if self.trigger_init: | |
| 65 | + self.trigger_init.close() | |
| 64 | 66 | return | ... | ... |
invesalius/data/viewer_volume.py
| ... | ... | @@ -120,6 +120,9 @@ class Viewer(wx.Panel): |
| 120 | 120 | self._to_show_ball = 0 |
| 121 | 121 | self._ball_ref_visibility = False |
| 122 | 122 | |
| 123 | + self.sen1 = False | |
| 124 | + self.sen2 = False | |
| 125 | + | |
| 123 | 126 | def __bind_events(self): |
| 124 | 127 | Publisher.subscribe(self.LoadActor, |
| 125 | 128 | 'Load surface actor into viewer') |
| ... | ... | @@ -191,6 +194,9 @@ class Viewer(wx.Panel): |
| 191 | 194 | Publisher.subscribe(self._check_ball_reference, 'Enable style') |
| 192 | 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 | 200 | # Related to marker creation in navigation tools |
| 195 | 201 | Publisher.subscribe(self.AddMarker, 'Add marker') |
| 196 | 202 | Publisher.subscribe(self.HideAllMarkers, 'Hide all markers') |
| ... | ... | @@ -241,6 +247,51 @@ class Viewer(wx.Panel): |
| 241 | 247 | self.RemoveBallReference() |
| 242 | 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 | 295 | def OnShowSurface(self, pubsub_evt): |
| 245 | 296 | index, value = pubsub_evt.data |
| 246 | 297 | if value: | ... | ... |
invesalius/gui/dialogs.py
| ... | ... | @@ -793,11 +793,23 @@ def NoMarkerSelected(): |
| 793 | 793 | dlg = wx.MessageDialog(None, "", msg, |
| 794 | 794 | wx.ICON_INFORMATION | wx.OK) |
| 795 | 795 | else: |
| 796 | - dlg = wx.MessageDialog(None,msg, "InVesalius 3 - Neuronavigator", | |
| 796 | + dlg = wx.MessageDialog(None, msg, "InVesalius 3 - Neuronavigator", | |
| 797 | 797 | wx.ICON_INFORMATION | wx.OK) |
| 798 | 798 | dlg.ShowModal() |
| 799 | 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 | 814 | def EnterMarkerID(default): |
| 803 | 815 | msg = _("Edit marker ID") | ... | ... |
invesalius/gui/frame.py
| ... | ... | @@ -486,6 +486,8 @@ class Frame(wx.Frame): |
| 486 | 486 | wx.MessageBox(_('Currently the Navigation mode is only working on Windows'), 'Info', wx.OK | wx.ICON_INFORMATION) |
| 487 | 487 | self._show_navigator_message = False |
| 488 | 488 | Publisher.sendMessage('Set navigation mode', status) |
| 489 | + if not status: | |
| 490 | + Publisher.sendMessage('Remove sensors ID') | |
| 489 | 491 | |
| 490 | 492 | def OnSize(self, evt): |
| 491 | 493 | """ | ... | ... |
invesalius/gui/task_navigator.py
| ... | ... | @@ -325,6 +325,7 @@ class NeuronavigationPanel(wx.Panel): |
| 325 | 325 | Publisher.subscribe(self.UpdateTriggerState, 'Update trigger state') |
| 326 | 326 | Publisher.subscribe(self.UpdateImageCoordinates, 'Set ball reference position') |
| 327 | 327 | Publisher.subscribe(self.OnDisconnectTracker, 'Disconnect tracker') |
| 328 | + Publisher.subscribe(self.OnStylusButton, 'PLH Stylus Button On') | |
| 328 | 329 | |
| 329 | 330 | def LoadImageFiducials(self, pubsub_evt): |
| 330 | 331 | marker_id = pubsub_evt.data[0] |
| ... | ... | @@ -358,6 +359,10 @@ class NeuronavigationPanel(wx.Panel): |
| 358 | 359 | if self.tracker_id: |
| 359 | 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 | 366 | def OnChoiceTracker(self, evt, ctrl): |
| 362 | 367 | Publisher.sendMessage('Update status text in GUI', _("Configuring tracker ...")) |
| 363 | 368 | if evt: |
| ... | ... | @@ -642,10 +647,12 @@ class MarkersPanel(wx.Panel): |
| 642 | 647 | self.list_coord[list_index][7] = str(id_label) |
| 643 | 648 | |
| 644 | 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 | 657 | def OnDeleteSingleMarker(self, evt): |
| 651 | 658 | # OnDeleteSingleMarker is used for both pubsub and button click events |
| ... | ... | @@ -682,7 +689,7 @@ class MarkersPanel(wx.Panel): |
| 682 | 689 | # OnCreateMarker is used for both pubsub and button click events |
| 683 | 690 | # Pubsub is used for markers created with fiducial buttons, trigger and create marker button |
| 684 | 691 | if hasattr(evt, 'data'): |
| 685 | - if evt.data: | |
| 692 | + if evt.data is not None: | |
| 686 | 693 | self.CreateMarker(evt.data[0], (0.0, 1.0, 0.0), self.marker_size, evt.data[1]) |
| 687 | 694 | else: |
| 688 | 695 | self.CreateMarker(self.current_coord, self.marker_colour, self.marker_size) | ... | ... |