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) | ... | ... |