Commit 0ba6002010b090f85010fc4e92c8cca0a34d4784

Authored by Renan
Committed by Paulo Henrique Junqueira Amorim
1 parent 897e159b
Exists in master

Navigation updates (#187)

* Added Camera tracker

-improved tracker.py by using const.py

* Added tracker file

* Tooltip offset

* Remove set button from navigation tab

* Reduce panel size and cleaning

* More cleaning

* Updates to code standards

* Support to the fourth FTsensor

* Support coil's marker

* Update to Pose board instead single marker

* Minor testing

* Support to NDI polaris

* invesalius sets ROMs path

* dialog to select COM port

* dialog to select COM port for polhemus devices

* Sensors ID

* cleaning wrapper export coordinates

* Polaris support working with Visor2 tools and dynamic coregistration

* dialog to choose roms files

* wrapper texts improvements

* improv coils arrows scale

* dialog to select COM for polhemus

* inv_path upgrade

* Removed camera_tracker
invesalius/constants.py
@@ -650,14 +650,18 @@ MTC = 1 @@ -650,14 +650,18 @@ MTC = 1
650 FASTRAK = 2 650 FASTRAK = 2
651 ISOTRAKII = 3 651 ISOTRAKII = 3
652 PATRIOT = 4 652 PATRIOT = 4
653 -DEBUGTRACK = 5  
654 -DISCTRACK = 6 653 +CAMERA = 5
  654 +POLARIS = 6
  655 +DEBUGTRACK = 7
  656 +DISCTRACK = 8
655 DEFAULT_TRACKER = SELECT 657 DEFAULT_TRACKER = SELECT
656 658
  659 +NDICOMPORT = b'COM1'
  660 +
657 TRACKER = [_("Select tracker:"), _("Claron MicronTracker"), 661 TRACKER = [_("Select tracker:"), _("Claron MicronTracker"),
658 _("Polhemus FASTRAK"), _("Polhemus ISOTRAK II"), 662 _("Polhemus FASTRAK"), _("Polhemus ISOTRAK II"),
659 - _("Polhemus PATRIOT"), _("Debug tracker"),  
660 - _("Disconnect tracker")] 663 + _("Polhemus PATRIOT"), _("Camera tracker"),
  664 + _("NDI Polaris"), _("Debug tracker"), _("Disconnect tracker")]
661 665
662 STATIC_REF = 0 666 STATIC_REF = 0
663 DYNAMIC_REF = 1 667 DYNAMIC_REF = 1
@@ -715,13 +719,13 @@ TIPS_OBJ = [_("Select left object fiducial"), @@ -715,13 +719,13 @@ TIPS_OBJ = [_("Select left object fiducial"),
715 _("Select object center"), 719 _("Select object center"),
716 _("Attach sensor to object")] 720 _("Attach sensor to object")]
717 721
718 -PROBE_NAME = "1Probe"  
719 -REF_NAME = "2Ref"  
720 -OBJ_NAME = "3Coil" 722 +MTC_PROBE_NAME = "1Probe"
  723 +MTC_REF_NAME = "2Ref"
  724 +MTC_OBJ_NAME = "3Coil"
721 725
722 #OBJECT TRACKING 726 #OBJECT TRACKING
723 -ARROW_SCALE = 3  
724 -ARROW_UPPER_LIMIT = 30 727 +ARROW_SCALE = 6
  728 +ARROW_UPPER_LIMIT = 15
725 #COIL_ANGLES_THRESHOLD = 3 * ARROW_SCALE 729 #COIL_ANGLES_THRESHOLD = 3 * ARROW_SCALE
726 COIL_ANGLES_THRESHOLD = 3 730 COIL_ANGLES_THRESHOLD = 3
727 COIL_COORD_THRESHOLD = 3 731 COIL_COORD_THRESHOLD = 3
invesalius/data/coordinates.py
@@ -21,6 +21,7 @@ from math import sin, cos @@ -21,6 +21,7 @@ from math import sin, cos
21 import numpy as np 21 import numpy as np
22 22
23 import invesalius.data.transformations as tr 23 import invesalius.data.transformations as tr
  24 +import invesalius.constants as const
24 25
25 from time import sleep 26 from time import sleep
26 from random import uniform 27 from random import uniform
@@ -40,17 +41,48 @@ def GetCoordinates(trck_init, trck_id, ref_mode): @@ -40,17 +41,48 @@ def GetCoordinates(trck_init, trck_id, ref_mode):
40 41
41 coord = None 42 coord = None
42 if trck_id: 43 if trck_id:
43 - getcoord = {1: ClaronCoord,  
44 - 2: PolhemusCoord,  
45 - 3: PolhemusCoord,  
46 - 4: PolhemusCoord,  
47 - 5: DebugCoord} 44 + getcoord = {const.MTC: ClaronCoord,
  45 + const.FASTRAK: PolhemusCoord,
  46 + const.ISOTRAKII: PolhemusCoord,
  47 + const.PATRIOT: PolhemusCoord,
  48 + const.CAMERA: CameraCoord,
  49 + const.POLARIS: PolarisCoord,
  50 + const.DEBUGTRACK: DebugCoord}
48 coord = getcoord[trck_id](trck_init, trck_id, ref_mode) 51 coord = getcoord[trck_id](trck_init, trck_id, ref_mode)
49 else: 52 else:
50 print("Select Tracker") 53 print("Select Tracker")
51 54
52 return coord 55 return coord
53 56
  57 +def PolarisCoord(trck_init, trck_id, ref_mode):
  58 + trck = trck_init[0]
  59 + trck.Run()
  60 +
  61 + probe = trck.probe.decode(const.FS_ENCODE).split(',')
  62 + angles_probe = np.degrees(tr.euler_from_quaternion(probe[2:6], axes='rzyx'))
  63 + trans_probe = np.array(probe[6:9]).astype(float)
  64 + coord1 = np.hstack((trans_probe, angles_probe))
  65 +
  66 + ref = trck.ref.decode(const.FS_ENCODE).split(',')
  67 + angles_ref = np.degrees(tr.euler_from_quaternion(ref[2:6], axes='rzyx'))
  68 + trans_ref = np.array(ref[6:9]).astype(float)
  69 + coord2 = np.hstack((trans_ref, angles_ref))
  70 +
  71 + obj = trck.obj.decode(const.FS_ENCODE).split(',')
  72 + angles_obj = np.degrees(tr.euler_from_quaternion(obj[2:6], axes='rzyx'))
  73 + trans_obj = np.array(obj[6:9]).astype(float)
  74 + coord3 = np.hstack((trans_obj, angles_obj))
  75 +
  76 + coord = np.vstack([coord1, coord2, coord3])
  77 + Publisher.sendMessage('Sensors ID', probe_id=trck.probeID, ref_id=trck.refID, obj_id=trck.objID)
  78 +
  79 + return coord
  80 +
  81 +def CameraCoord(trck_init, trck_id, ref_mode):
  82 + trck = trck_init[0]
  83 + coord, probeID, refID = trck.Run()
  84 + Publisher.sendMessage('Sensors ID', probe_id=probeID, ref_id=refID)
  85 + return coord
54 86
55 def ClaronCoord(trck_init, trck_id, ref_mode): 87 def ClaronCoord(trck_init, trck_id, ref_mode):
56 trck = trck_init[0] 88 trck = trck_init[0]
@@ -214,7 +246,7 @@ def DebugCoord(trk_init, trck_id, ref_mode): @@ -214,7 +246,7 @@ def DebugCoord(trk_init, trck_id, ref_mode):
214 coord4 = np.array([uniform(1, 200), uniform(1, 200), uniform(1, 200), 246 coord4 = np.array([uniform(1, 200), uniform(1, 200), uniform(1, 200),
215 uniform(-180.0, 180.0), uniform(-180.0, 180.0), uniform(-180.0, 180.0)]) 247 uniform(-180.0, 180.0), uniform(-180.0, 180.0), uniform(-180.0, 180.0)])
216 248
217 - Publisher.sendMessage('Sensors ID', probe_id=int(uniform(0, 5)), ref_id=int(uniform(0, 5))) 249 + Publisher.sendMessage('Sensors ID', probe_id=int(uniform(0, 5)), ref_id=int(uniform(0, 5)), obj_id=int(uniform(0, 5)))
218 250
219 return np.vstack([coord1, coord2, coord3, coord4]) 251 return np.vstack([coord1, coord2, coord3, coord4])
220 252
invesalius/data/surface.py
@@ -313,6 +313,7 @@ class SurfaceManager(): @@ -313,6 +313,7 @@ class SurfaceManager():
313 reader = vtk.vtkSTLReader() 313 reader = vtk.vtkSTLReader()
314 elif filename.lower().endswith('.ply'): 314 elif filename.lower().endswith('.ply'):
315 reader = vtk.vtkPLYReader() 315 reader = vtk.vtkPLYReader()
  316 + scalar = True
316 elif filename.lower().endswith('.obj'): 317 elif filename.lower().endswith('.obj'):
317 reader = vtk.vtkOBJReader() 318 reader = vtk.vtkOBJReader()
318 elif filename.lower().endswith('.vtp'): 319 elif filename.lower().endswith('.vtp'):
invesalius/data/trackers.py
@@ -16,7 +16,8 @@ @@ -16,7 +16,8 @@
16 # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais 16 # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais
17 # detalhes. 17 # detalhes.
18 #-------------------------------------------------------------------------- 18 #--------------------------------------------------------------------------
19 - 19 +import invesalius.constants as const
  20 +import invesalius.gui.dialogs as dlg
20 # TODO: Disconnect tracker when a new one is connected 21 # TODO: Disconnect tracker when a new one is connected
21 # TODO: Test if there are too many prints when connection fails 22 # TODO: Test if there are too many prints when connection fails
22 23
@@ -32,11 +33,13 @@ def TrackerConnection(tracker_id, trck_init, action): @@ -32,11 +33,13 @@ def TrackerConnection(tracker_id, trck_init, action):
32 """ 33 """
33 34
34 if action == 'connect': 35 if action == 'connect':
35 - trck_fcn = {1: ClaronTracker,  
36 - 2: PolhemusTracker, # FASTRAK  
37 - 3: PolhemusTracker, # ISOTRAK  
38 - 4: PolhemusTracker, # PATRIOT  
39 - 5: DebugTracker} 36 + trck_fcn = {const.MTC: ClaronTracker,
  37 + const.FASTRAK: PolhemusTracker, # FASTRAK
  38 + const.ISOTRAKII: PolhemusTracker, # ISOTRAK
  39 + const.PATRIOT: PolhemusTracker, # PATRIOT
  40 + const.CAMERA: CameraTracker, # CAMERA
  41 + const.POLARIS: PolarisTracker, # POLARIS
  42 + const.DEBUGTRACK: DebugTracker}
40 43
41 trck_init = trck_fcn[tracker_id](tracker_id) 44 trck_init = trck_fcn[tracker_id](tracker_id)
42 45
@@ -58,6 +61,48 @@ def DefaultTracker(tracker_id): @@ -58,6 +61,48 @@ def DefaultTracker(tracker_id):
58 # return tracker initialization variable and type of connection 61 # return tracker initialization variable and type of connection
59 return trck_init, 'wrapper' 62 return trck_init, 'wrapper'
60 63
  64 +def PolarisTracker(tracker_id):
  65 + from wx import ID_OK
  66 + trck_init = None
  67 + dlg_port = dlg.SetNDIconfigs()
  68 + if dlg_port.ShowModal() == ID_OK:
  69 + com_port, PROBE_DIR, REF_DIR, OBJ_DIR = dlg_port.GetValue()
  70 + try:
  71 + import pypolaris
  72 + lib_mode = 'wrapper'
  73 + trck_init = pypolaris.pypolaris()
  74 +
  75 + if trck_init.Initialize(com_port, PROBE_DIR, REF_DIR, OBJ_DIR) != 0:
  76 + trck_init = None
  77 + lib_mode = None
  78 + print('Could not connect to default tracker.')
  79 + else:
  80 + print('Connect to polaris tracking device.')
  81 +
  82 + except:
  83 + lib_mode = 'error'
  84 + trck_init = None
  85 + print('Could not connect to default tracker.')
  86 + else:
  87 + lib_mode = None
  88 + print('Could not connect to default tracker.')
  89 +
  90 + # return tracker initialization variable and type of connection
  91 + return trck_init, lib_mode
  92 +
  93 +def CameraTracker(tracker_id):
  94 + trck_init = None
  95 + try:
  96 + import invesalius.data.camera_tracker as cam
  97 + trck_init = cam.camera()
  98 + trck_init.Initialize()
  99 + print('Connect to camera tracking device.')
  100 +
  101 + except:
  102 + print('Could not connect to default tracker.')
  103 +
  104 + # return tracker initialization variable and type of connection
  105 + return trck_init, 'wrapper'
61 106
62 def ClaronTracker(tracker_id): 107 def ClaronTracker(tracker_id):
63 import invesalius.constants as const 108 import invesalius.constants as const
@@ -69,13 +114,13 @@ def ClaronTracker(tracker_id): @@ -69,13 +114,13 @@ def ClaronTracker(tracker_id):
69 114
70 lib_mode = 'wrapper' 115 lib_mode = 'wrapper'
71 trck_init = pyclaron.pyclaron() 116 trck_init = pyclaron.pyclaron()
72 - trck_init.CalibrationDir = inv_paths.CAL_DIR.encode(const.FS_ENCODE)  
73 - trck_init.MarkerDir = inv_paths.MAR_DIR.encode(const.FS_ENCODE) 117 + trck_init.CalibrationDir = inv_paths.MTC_CAL_DIR.encode(const.FS_ENCODE)
  118 + trck_init.MarkerDir = inv_paths.MTC_MAR_DIR.encode(const.FS_ENCODE)
74 trck_init.NumberFramesProcessed = 1 119 trck_init.NumberFramesProcessed = 1
75 trck_init.FramesExtrapolated = 0 120 trck_init.FramesExtrapolated = 0
76 - trck_init.PROBE_NAME = const.PROBE_NAME.encode(const.FS_ENCODE)  
77 - trck_init.REF_NAME = const.REF_NAME.encode(const.FS_ENCODE)  
78 - trck_init.OBJ_NAME = const.OBJ_NAME.encode(const.FS_ENCODE) 121 + trck_init.PROBE_NAME = const.MTC_PROBE_NAME.encode(const.FS_ENCODE)
  122 + trck_init.REF_NAME = const.MTC_REF_NAME.encode(const.FS_ENCODE)
  123 + trck_init.OBJ_NAME = const.MTC_OBJ_NAME.encode(const.FS_ENCODE)
79 trck_init.Initialize() 124 trck_init.Initialize()
80 125
81 if trck_init.GetIdentifyingCamera(): 126 if trck_init.GetIdentifyingCamera():
@@ -146,25 +191,38 @@ def PlhWrapperConnection(tracker_id): @@ -146,25 +191,38 @@ def PlhWrapperConnection(tracker_id):
146 191
147 def PlhSerialConnection(tracker_id): 192 def PlhSerialConnection(tracker_id):
148 import serial 193 import serial
  194 + from wx import ID_OK
  195 + trck_init = None
  196 + dlg_port = dlg.SetCOMport()
  197 + if dlg_port.ShowModal() == ID_OK:
  198 + com_port = dlg_port.GetValue()
  199 + try:
  200 + trck_init = serial.Serial(com_port, baudrate=115200, timeout=0.03)
  201 +
  202 + if tracker_id == 2:
  203 + # Polhemus FASTRAK needs configurations first
  204 + trck_init.write(0x02, str.encode("u"))
  205 + trck_init.write(0x02, str.encode("F"))
  206 + elif tracker_id == 3:
  207 + # Polhemus ISOTRAK needs to set tracking point from
  208 + # center to tip.
  209 + trck_init.write(str.encode("u"))
  210 + trck_init.write(str.encode("F"))
  211 + trck_init.write(str.encode("Y"))
  212 +
  213 + trck_init.write(str.encode("P"))
  214 + data = trck_init.readlines()
  215 + if not data:
  216 + trck_init = None
  217 + print('Could not connect to Polhemus serial without error.')
149 218
150 - trck_init = serial.Serial('COM3', baudrate=115200, timeout=0.03)  
151 -  
152 - if tracker_id == 2:  
153 - # Polhemus FASTRAK needs configurations first  
154 - trck_init.write(0x02, str.encode("u"))  
155 - trck_init.write(0x02, str.encode("F"))  
156 - elif tracker_id == 3:  
157 - # Polhemus ISOTRAK needs to set tracking point from  
158 - # center to tip.  
159 - trck_init.write(str.encode("u"))  
160 - trck_init.write(str.encode("F"))  
161 - trck_init.write(str.encode("Y"))  
162 -  
163 - trck_init.write(str.encode("P"))  
164 - data = trck_init.readlines()  
165 - if not data:  
166 - trck_init = None  
167 - print('Could not connect to Polhemus serial without error.') 219 + except:
  220 + lib_mode = 'error'
  221 + trck_init = None
  222 + print('Could not connect to default tracker.')
  223 + else:
  224 + lib_mode = None
  225 + print('Could not connect to default tracker.')
168 226
169 return trck_init 227 return trck_init
170 228
@@ -211,13 +269,13 @@ def DisconnectTracker(tracker_id, trck_init): @@ -211,13 +269,13 @@ def DisconnectTracker(tracker_id, trck_init):
211 :param trck_init: Initialization variable of tracking device. 269 :param trck_init: Initialization variable of tracking device.
212 """ 270 """
213 271
214 - if tracker_id == 5: 272 + if tracker_id == const.DEBUGTRACK:
215 trck_init = False 273 trck_init = False
216 lib_mode = 'debug' 274 lib_mode = 'debug'
217 print('Debug tracker disconnected.') 275 print('Debug tracker disconnected.')
218 else: 276 else:
219 try: 277 try:
220 - if tracker_id == 3: 278 + if tracker_id == const.ISOTRAKII:
221 trck_init.close() 279 trck_init.close()
222 trck_init = False 280 trck_init = False
223 lib_mode = 'serial' 281 lib_mode = 'serial'
invesalius/data/viewer_volume.py
@@ -172,8 +172,9 @@ class Viewer(wx.Panel): @@ -172,8 +172,9 @@ class Viewer(wx.Panel):
172 self._to_show_ball = 0 172 self._to_show_ball = 0
173 self._ball_ref_visibility = False 173 self._ball_ref_visibility = False
174 174
175 - self.sen1 = False  
176 - self.sen2 = False 175 + self.probe = False
  176 + self.ref = False
  177 + self.obj = False
177 178
178 self.timer = False 179 self.timer = False
179 self.index = False 180 self.index = False
@@ -325,8 +326,8 @@ class Viewer(wx.Panel): @@ -325,8 +326,8 @@ class Viewer(wx.Panel):
325 self.RemoveBallReference() 326 self.RemoveBallReference()
326 self.interactor.Render() 327 self.interactor.Render()
327 328
328 - def OnSensors(self, probe_id, ref_id):  
329 - if not self.sen1: 329 + def OnSensors(self, probe_id, ref_id, obj_id=0):
  330 + if not self.probe:
330 self.CreateSensorID() 331 self.CreateSensorID()
331 332
332 if probe_id: 333 if probe_id:
@@ -337,35 +338,49 @@ class Viewer(wx.Panel): @@ -337,35 +338,49 @@ class Viewer(wx.Panel):
337 colour2 = (0, 1, 0) 338 colour2 = (0, 1, 0)
338 else: 339 else:
339 colour2 = (1, 0, 0) 340 colour2 = (1, 0, 0)
  341 + if obj_id:
  342 + colour3 = (0, 1, 0)
  343 + else:
  344 + colour3 = (1, 0, 0)
340 345
341 - self.sen1.SetColour(colour1)  
342 - self.sen2.SetColour(colour2) 346 + self.probe.SetColour(colour1)
  347 + self.ref.SetColour(colour2)
  348 + self.obj.SetColour(colour3)
343 self.Refresh() 349 self.Refresh()
344 350
345 def CreateSensorID(self): 351 def CreateSensorID(self):
346 - sen1 = vtku.Text()  
347 - sen1.SetSize(const.TEXT_SIZE_LARGE)  
348 - sen1.SetPosition((const.X, const.Y))  
349 - sen1.ShadowOff()  
350 - sen1.SetValue("O")  
351 - self.sen1 = sen1  
352 - self.ren.AddActor(sen1.actor)  
353 -  
354 - sen2 = vtku.Text()  
355 - sen2.SetSize(const.TEXT_SIZE_LARGE)  
356 - sen2.SetPosition((const.X+0.04, const.Y))  
357 - sen2.ShadowOff()  
358 - sen2.SetValue("O")  
359 - self.sen2 = sen2  
360 - self.ren.AddActor(sen2.actor) 352 + probe = vtku.Text()
  353 + probe.SetSize(const.TEXT_SIZE_LARGE)
  354 + probe.SetPosition((const.X, const.Y))
  355 + probe.ShadowOff()
  356 + probe.SetValue("P")
  357 + self.probe = probe
  358 + self.ren.AddActor(probe.actor)
  359 +
  360 + ref = vtku.Text()
  361 + ref.SetSize(const.TEXT_SIZE_LARGE)
  362 + ref.SetPosition((const.X+0.04, const.Y))
  363 + ref.ShadowOff()
  364 + ref.SetValue("R")
  365 + self.ref = ref
  366 + self.ren.AddActor(ref.actor)
  367 +
  368 + obj = vtku.Text()
  369 + obj.SetSize(const.TEXT_SIZE_LARGE)
  370 + obj.SetPosition((const.X+0.08, const.Y))
  371 + obj.ShadowOff()
  372 + obj.SetValue("O")
  373 + self.obj = obj
  374 + self.ren.AddActor(obj.actor)
361 375
362 self.interactor.Render() 376 self.interactor.Render()
363 377
364 def OnRemoveSensorsID(self): 378 def OnRemoveSensorsID(self):
365 - if self.sen1:  
366 - self.ren.RemoveActor(self.sen1.actor)  
367 - self.ren.RemoveActor(self.sen2.actor)  
368 - self.sen1 = self.sen2 = False 379 + if self.probe:
  380 + self.ren.RemoveActor(self.probe.actor)
  381 + self.ren.RemoveActor(self.ref.actor)
  382 + self.ren.RemoveActor(self.obj.actor)
  383 + self.probe = self.ref = self.obj = False
369 self.interactor.Render() 384 self.interactor.Render()
370 385
371 def OnShowSurface(self, index, visibility): 386 def OnShowSurface(self, index, visibility):
@@ -708,7 +723,7 @@ class Viewer(wx.Panel): @@ -708,7 +723,7 @@ class Viewer(wx.Panel):
708 (self.target_coord[0], -self.target_coord[1], self.target_coord[2])) 723 (self.target_coord[0], -self.target_coord[1], self.target_coord[2]))
709 724
710 # self.txt.SetCoilDistanceValue(target_dist) 725 # self.txt.SetCoilDistanceValue(target_dist)
711 - self.textSource.SetText('Dist: ' + str("{:06.2f}".format(target_dist)) + ' mm') 726 + self.tdist.SetValue('Distance: ' + str("{:06.2f}".format(target_dist)) + ' mm')
712 self.ren.ResetCamera() 727 self.ren.ResetCamera()
713 self.SetCameraTarget() 728 self.SetCameraTarget()
714 if target_dist > 100: 729 if target_dist > 100:
@@ -819,9 +834,6 @@ class Viewer(wx.Panel): @@ -819,9 +834,6 @@ class Viewer(wx.Panel):
819 self.ren2.AddActor(ind) 834 self.ren2.AddActor(ind)
820 835
821 836
822 - x, y, z = bases.flip_x(coord[0:3])  
823 - self.tactor.SetPosition(x-20, y-30, z+20)  
824 -  
825 self.Refresh() 837 self.Refresh()
826 838
827 def OnUpdateTargetCoordinates(self, coord): 839 def OnUpdateTargetCoordinates(self, coord):
@@ -841,27 +853,6 @@ class Viewer(wx.Panel): @@ -841,27 +853,6 @@ class Viewer(wx.Panel):
841 self.RemoveTargetAim() 853 self.RemoveTargetAim()
842 self.aim_actor = None 854 self.aim_actor = None
843 855
844 - self.textSource = vtk.vtkVectorText()  
845 - mapper = vtk.vtkPolyDataMapper()  
846 - mapper.SetInputConnection(self.textSource.GetOutputPort())  
847 - tactor = vtk.vtkFollower()  
848 - tactor.SetMapper(mapper)  
849 - tactor.GetProperty().SetColor(1.0, 0.25, 0.0)  
850 - tactor.SetScale(5)  
851 - #tactor.SetPosition(self.target_coord[0]+10, self.target_coord[1]+30, self.target_coord[2]+20)  
852 - self.ren.AddActor(tactor)  
853 - self.tactor = tactor  
854 - tactor.SetCamera(self.ren.GetActiveCamera())  
855 -  
856 -  
857 - # v3, M_plane_inv = self.Plane(self.target_coord[0:3], self.pTarget)  
858 - # mat4x4 = vtk.vtkMatrix4x4()  
859 - # for i in range(4):  
860 - # mat4x4.SetElement(i, 0, M_plane_inv[i][0])  
861 - # mat4x4.SetElement(i, 1, M_plane_inv[i][1])  
862 - # mat4x4.SetElement(i, 2, M_plane_inv[i][2])  
863 - # mat4x4.SetElement(i, 3, M_plane_inv[i][3])  
864 -  
865 a, b, g = np.radians(self.target_coord[3:]) 856 a, b, g = np.radians(self.target_coord[3:])
866 r_ref = tr.euler_matrix(a, b, g, 'sxyz') 857 r_ref = tr.euler_matrix(a, b, g, 'sxyz')
867 t_ref = tr.translation_matrix(self.target_coord[:3]) 858 t_ref = tr.translation_matrix(self.target_coord[:3])
@@ -885,7 +876,6 @@ class Viewer(wx.Panel): @@ -885,7 +876,6 @@ class Viewer(wx.Panel):
885 # Transform the polydata 876 # Transform the polydata
886 transform = vtk.vtkTransform() 877 transform = vtk.vtkTransform()
887 transform.SetMatrix(m_img_vtk) 878 transform.SetMatrix(m_img_vtk)
888 - #transform.SetMatrix(mat4x4)  
889 transformPD = vtk.vtkTransformPolyDataFilter() 879 transformPD = vtk.vtkTransformPolyDataFilter()
890 transformPD.SetTransform(transform) 880 transformPD.SetTransform(transform)
891 transformPD.SetInputConnection(reader.GetOutputPort()) 881 transformPD.SetInputConnection(reader.GetOutputPort())
@@ -934,24 +924,24 @@ class Viewer(wx.Panel): @@ -934,24 +924,24 @@ class Viewer(wx.Panel):
934 def RemoveTargetAim(self): 924 def RemoveTargetAim(self):
935 self.ren.RemoveActor(self.aim_actor) 925 self.ren.RemoveActor(self.aim_actor)
936 self.ren.RemoveActor(self.dummy_coil_actor) 926 self.ren.RemoveActor(self.dummy_coil_actor)
937 - self.ren.RemoveActor(self.tactor)  
938 self.Refresh() 927 self.Refresh()
939 928
940 def CreateTextDistance(self): 929 def CreateTextDistance(self):
941 - txt = vtku.Text()  
942 - txt.SetSize(const.TEXT_SIZE_EXTRA_LARGE)  
943 - txt.SetPosition((0.76, 0.05))  
944 - txt.ShadowOff()  
945 - txt.BoldOn()  
946 - self.txt = txt  
947 - self.ren2.AddActor(txt.actor) 930 + tdist = vtku.Text()
  931 + tdist.SetSize(const.TEXT_SIZE_LARGE)
  932 + tdist.SetPosition((const.X, 1.03-const.Y))
  933 + tdist.ShadowOff()
  934 + tdist.BoldOn()
  935 +
  936 + self.ren.AddActor(tdist.actor)
  937 + self.tdist = tdist
948 938
949 def DisableCoilTracker(self): 939 def DisableCoilTracker(self):
950 try: 940 try:
951 self.ren.SetViewport(0, 0, 1, 1) 941 self.ren.SetViewport(0, 0, 1, 1)
952 self.interactor.GetRenderWindow().RemoveRenderer(self.ren2) 942 self.interactor.GetRenderWindow().RemoveRenderer(self.ren2)
953 self.SetViewAngle(const.VOL_FRONT) 943 self.SetViewAngle(const.VOL_FRONT)
954 - self.ren.RemoveActor(self.txt.actor) 944 + self.ren.RemoveActor(self.tdist.actor)
955 self.CreateTargetAim() 945 self.CreateTargetAim()
956 self.interactor.Render() 946 self.interactor.Render()
957 except: 947 except:
invesalius/gui/dialogs.py
@@ -923,11 +923,13 @@ def NavigationTrackerWarning(trck_id, lib_mode): @@ -923,11 +923,13 @@ def NavigationTrackerWarning(trck_id, lib_mode):
923 """ 923 """
924 Spatial Tracker connection error 924 Spatial Tracker connection error
925 """ 925 """
926 - trck = {1: 'Claron MicronTracker',  
927 - 2: 'Polhemus FASTRAK',  
928 - 3: 'Polhemus ISOTRAK',  
929 - 4: 'Polhemus PATRIOT',  
930 - 5: 'Debug tracker device'} 926 + trck = {const.MTC: 'Claron MicronTracker',
  927 + const.FASTRAK: 'Polhemus FASTRAK',
  928 + const.ISOTRAKII: 'Polhemus ISOTRAK',
  929 + const.PATRIOT: 'Polhemus PATRIOT',
  930 + const.CAMERA: 'CAMERA',
  931 + const.POLARIS: 'NDI Polaris',
  932 + const.DEBUGTRACK: 'Debug tracker device'}
931 933
932 if lib_mode == 'choose': 934 if lib_mode == 'choose':
933 msg = _('No tracking device selected') 935 msg = _('No tracking device selected')
@@ -3351,7 +3353,7 @@ class ObjectCalibrationDialog(wx.Dialog): @@ -3351,7 +3353,7 @@ class ObjectCalibrationDialog(wx.Dialog):
3351 choice_ref.SetToolTip(tooltip) 3353 choice_ref.SetToolTip(tooltip)
3352 choice_ref.Bind(wx.EVT_COMBOBOX, self.OnChoiceRefMode) 3354 choice_ref.Bind(wx.EVT_COMBOBOX, self.OnChoiceRefMode)
3353 choice_ref.Enable(0) 3355 choice_ref.Enable(0)
3354 - if self.tracker_id == const.MTC or self.tracker_id == const.FASTRAK or self.tracker_id == const.DEBUGTRACK: 3356 + if not (self.tracker_id == const.PATRIOT or self.tracker_id == const.ISOTRAKII):
3355 choice_ref.Enable(1) 3357 choice_ref.Enable(1)
3356 3358
3357 # ComboBox for sensor selection for FASTRAK 3359 # ComboBox for sensor selection for FASTRAK
@@ -3778,3 +3780,135 @@ class GoToDialogScannerCoord(wx.Dialog): @@ -3778,3 +3780,135 @@ class GoToDialogScannerCoord(wx.Dialog):
3778 def Close(self): 3780 def Close(self):
3779 wx.Dialog.Close(self) 3781 wx.Dialog.Close(self)
3780 self.Destroy() 3782 self.Destroy()
  3783 +
  3784 +class SetNDIconfigs(wx.Dialog):
  3785 + def __init__(self, title=_("Setting NDI polaris configs:")):
  3786 + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP)
  3787 + self._init_gui()
  3788 +
  3789 + def serial_ports(self):
  3790 + """ Lists serial port names
  3791 + """
  3792 + import serial.tools.list_ports
  3793 + if sys.platform.startswith('win'):
  3794 + ports = ([comport.device for comport in serial.tools.list_ports.comports()])
  3795 + else:
  3796 + raise EnvironmentError('Unsupported platform')
  3797 + return ports
  3798 +
  3799 + def _init_gui(self):
  3800 + self.com_ports = wx.ComboBox(self, -1, style=wx.CB_DROPDOWN|wx.CB_READONLY)
  3801 + row_com = wx.BoxSizer(wx.VERTICAL)
  3802 + row_com.Add(wx.StaticText(self, wx.ID_ANY, "Select the COM port"), 0, wx.TOP|wx.RIGHT,5)
  3803 + row_com.Add(self.com_ports, 0, wx.EXPAND)
  3804 +
  3805 + ports = self.serial_ports()
  3806 + self.com_ports.Append(ports)
  3807 +
  3808 + self.dir_probe = wx.FilePickerCtrl(self, path=inv_paths.NDI_MAR_DIR_REF, style=wx.FLP_USE_TEXTCTRL|wx.FLP_SMALL,
  3809 + wildcard="Rom files (*.rom)|*.rom", message="Select probe's rom file")
  3810 + row_probe = wx.BoxSizer(wx.VERTICAL)
  3811 + row_probe.Add(wx.StaticText(self, wx.ID_ANY, "Set probe's rom file"), 0, wx.TOP|wx.RIGHT, 5)
  3812 + row_probe.Add(self.dir_probe, 0, wx.EXPAND|wx.ALIGN_CENTER)
  3813 +
  3814 + self.dir_ref = wx.FilePickerCtrl(self, path=inv_paths.NDI_MAR_DIR_REF, style=wx.FLP_USE_TEXTCTRL|wx.FLP_SMALL,
  3815 + wildcard="Rom files (*.rom)|*.rom", message="Select reference's rom file")
  3816 + row_ref = wx.BoxSizer(wx.VERTICAL)
  3817 + row_ref.Add(wx.StaticText(self, wx.ID_ANY, "Set reference's rom file"), 0, wx.TOP | wx.RIGHT, 5)
  3818 + row_ref.Add(self.dir_ref, 0, wx.EXPAND|wx.ALIGN_CENTER)
  3819 +
  3820 + self.dir_obj = wx.FilePickerCtrl(self, path=inv_paths.NDI_MAR_DIR_OBJ, style=wx.FLP_USE_TEXTCTRL|wx.FLP_SMALL,
  3821 + wildcard="Rom files (*.rom)|*.rom", message="Select object's rom file")
  3822 + #self.dir_probe.Bind(wx.EVT_FILEPICKER_CHANGED, self.Selected)
  3823 + row_obj = wx.BoxSizer(wx.VERTICAL)
  3824 + row_obj.Add(wx.StaticText(self, wx.ID_ANY, "Set object's rom file"), 0, wx.TOP|wx.RIGHT, 5)
  3825 + row_obj.Add(self.dir_obj, 0, wx.EXPAND|wx.ALIGN_CENTER)
  3826 +
  3827 + # self.goto_orientation.SetSelection(cb_init)
  3828 +
  3829 + btn_ok = wx.Button(self, wx.ID_OK)
  3830 + btn_ok.SetHelpText("")
  3831 + btn_ok.SetDefault()
  3832 +
  3833 + btn_cancel = wx.Button(self, wx.ID_CANCEL)
  3834 + btn_cancel.SetHelpText("")
  3835 +
  3836 + btnsizer = wx.StdDialogButtonSizer()
  3837 + btnsizer.AddButton(btn_ok)
  3838 + btnsizer.AddButton(btn_cancel)
  3839 + btnsizer.Realize()
  3840 +
  3841 + main_sizer = wx.BoxSizer(wx.VERTICAL)
  3842 +
  3843 + main_sizer.Add((5, 5))
  3844 + main_sizer.Add(row_com, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
  3845 + main_sizer.Add((5, 5))
  3846 + main_sizer.Add(row_probe, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
  3847 + main_sizer.Add((5, 5))
  3848 + main_sizer.Add(row_ref, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
  3849 + main_sizer.Add((5, 5))
  3850 + main_sizer.Add(row_obj, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
  3851 + main_sizer.Add((15, 15))
  3852 + main_sizer.Add(btnsizer, 0, wx.EXPAND)
  3853 + main_sizer.Add((5, 5))
  3854 +
  3855 + self.SetSizer(main_sizer)
  3856 + main_sizer.Fit(self)
  3857 +
  3858 + self.CenterOnParent()
  3859 +
  3860 + def GetValue(self):
  3861 + return self.com_ports.GetString(self.com_ports.GetSelection()).encode(const.FS_ENCODE), \
  3862 + self.dir_probe.GetPath().encode(const.FS_ENCODE),\
  3863 + self.dir_ref.GetPath().encode(const.FS_ENCODE), \
  3864 + self.dir_obj.GetPath().encode(const.FS_ENCODE)
  3865 +
  3866 +class SetCOMport(wx.Dialog):
  3867 + def __init__(self, title=_("Select COM port")):
  3868 + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP)
  3869 + self._init_gui()
  3870 +
  3871 + def serial_ports(self):
  3872 + """ Lists serial port names
  3873 + """
  3874 + import serial.tools.list_ports
  3875 + if sys.platform.startswith('win'):
  3876 + ports = ([comport.device for comport in serial.tools.list_ports.comports()])
  3877 + else:
  3878 + raise EnvironmentError('Unsupported platform')
  3879 + return ports
  3880 +
  3881 + def _init_gui(self):
  3882 + self.com_ports = wx.ComboBox(self, -1, style=wx.CB_DROPDOWN|wx.CB_READONLY)
  3883 + ports = self.serial_ports()
  3884 + self.com_ports.Append(ports)
  3885 +
  3886 + # self.goto_orientation.SetSelection(cb_init)
  3887 +
  3888 + btn_ok = wx.Button(self, wx.ID_OK)
  3889 + btn_ok.SetHelpText("")
  3890 + btn_ok.SetDefault()
  3891 +
  3892 + btn_cancel = wx.Button(self, wx.ID_CANCEL)
  3893 + btn_cancel.SetHelpText("")
  3894 +
  3895 + btnsizer = wx.StdDialogButtonSizer()
  3896 + btnsizer.AddButton(btn_ok)
  3897 + btnsizer.AddButton(btn_cancel)
  3898 + btnsizer.Realize()
  3899 +
  3900 + main_sizer = wx.BoxSizer(wx.VERTICAL)
  3901 +
  3902 + main_sizer.Add((5, 5))
  3903 + main_sizer.Add(self.com_ports, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5)
  3904 + main_sizer.Add((5, 5))
  3905 + main_sizer.Add(btnsizer, 0, wx.EXPAND)
  3906 + main_sizer.Add((5, 5))
  3907 +
  3908 + self.SetSizer(main_sizer)
  3909 + main_sizer.Fit(self)
  3910 +
  3911 + self.CenterOnParent()
  3912 +
  3913 + def GetValue(self):
  3914 + return self.com_ports.GetString(self.com_ports.GetSelection())
3781 \ No newline at end of file 3915 \ No newline at end of file
invesalius/gui/task_navigator.py
@@ -453,7 +453,7 @@ class NeuronavigationPanel(wx.Panel): @@ -453,7 +453,7 @@ class NeuronavigationPanel(wx.Panel):
453 if hasattr(evt, 'GetSelection'): 453 if hasattr(evt, 'GetSelection'):
454 choice = evt.GetSelection() 454 choice = evt.GetSelection()
455 else: 455 else:
456 - choice = 6 456 + choice = const.DISCTRACK
457 457
458 if self.trk_init: 458 if self.trk_init:
459 trck = self.trk_init[0] 459 trck = self.trk_init[0]
@@ -462,7 +462,7 @@ class NeuronavigationPanel(wx.Panel): @@ -462,7 +462,7 @@ class NeuronavigationPanel(wx.Panel):
462 462
463 # Conditions check if click was on current selection and if any other tracker 463 # Conditions check if click was on current selection and if any other tracker
464 # has been initialized before 464 # has been initialized before
465 - if trck and choice != 6: 465 + if trck and choice != const.DISCTRACK:
466 self.ResetTrackerFiducials() 466 self.ResetTrackerFiducials()
467 Publisher.sendMessage('Update status text in GUI', 467 Publisher.sendMessage('Update status text in GUI',
468 label=_("Disconnecting tracker...")) 468 label=_("Disconnecting tracker..."))
@@ -480,7 +480,7 @@ class NeuronavigationPanel(wx.Panel): @@ -480,7 +480,7 @@ class NeuronavigationPanel(wx.Panel):
480 else: 480 else:
481 ctrl.SetSelection(self.tracker_id) 481 ctrl.SetSelection(self.tracker_id)
482 print("Tracker connected!") 482 print("Tracker connected!")
483 - elif choice == 6: 483 + elif choice == const.DISCTRACK:
484 if trck: 484 if trck:
485 self.ResetTrackerFiducials() 485 self.ResetTrackerFiducials()
486 Publisher.sendMessage('Update status text in GUI', 486 Publisher.sendMessage('Update status text in GUI',
invesalius/inv_paths.py
@@ -49,9 +49,14 @@ else: @@ -49,9 +49,14 @@ else:
49 ) 49 )
50 50
51 # Navigation paths 51 # Navigation paths
52 -CAL_DIR = INV_TOP_DIR.joinpath("navigation", "mtc_files", "CalibrationFiles")  
53 -MAR_DIR = INV_TOP_DIR.joinpath("navigation", "mtc_files", "Markers")  
54 -OBJ_DIR = INV_TOP_DIR.joinpath("navigation", "objects") 52 +OBJ_DIR = str(INV_TOP_DIR.joinpath("navigation", "objects"))
  53 +
  54 +MTC_CAL_DIR = str(INV_TOP_DIR.joinpath("navigation", "mtc_files", "CalibrationFiles"))
  55 +MTC_MAR_DIR = str(INV_TOP_DIR.joinpath("navigation", "mtc_files", "Markers"))
  56 +
  57 +NDI_MAR_DIR_PROBE = str(INV_TOP_DIR.joinpath("navigation", "ndi_files", "Markers", "8700340.rom"))
  58 +NDI_MAR_DIR_REF = str(INV_TOP_DIR.joinpath("navigation", "ndi_files", "Markers", "8700339.rom"))
  59 +NDI_MAR_DIR_OBJ = str(INV_TOP_DIR.joinpath("navigation", "ndi_files", "Markers", "8700338.rom"))
55 60
56 # MAC App 61 # MAC App
57 if not os.path.exists(ICON_DIR): 62 if not os.path.exists(ICON_DIR):
navigation/mtc_files/Markers/3Coil_big 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +
  2 +[Marker]
  3 +FacetsCount=1
  4 +SliderControlledXpointsCount=0
  5 +Name=3Coil_big
  6 +
  7 +[Facet1]
  8 +VectorsCount=2
  9 +
  10 +[Facet1V1]
  11 +EndPos(0,0)=-12.130921665071337
  12 +EndPos(0,1)=4.771099944171531e-005
  13 +EndPos(0,2)=-1.6777868612989378e-016
  14 +EndPos(1,0)=12.131083622124752
  15 +EndPos(1,1)=1.0800131569805988e-004
  16 +EndPos(1,2)=-2.4831245547224282e-015
  17 +
  18 +[Facet1V2]
  19 +EndPos(0,0)=-12.143021882072084
  20 +EndPos(0,1)=-16.190735690907974
  21 +EndPos(0,2)=-1.3422294890391503e-015
  22 +EndPos(1,0)=-12.130921665071337
  23 +EndPos(1,1)=4.771099944171531e-005
  24 +EndPos(1,2)=-1.6777868612989378e-016
  25 +
  26 +[Tooltip2MarkerXf]
  27 +Scale=1.
  28 +S0=0.
  29 +R0,0=1.
  30 +R1,0=0.
  31 +R2,0=0.
  32 +S1=0.
  33 +R0,1=0.
  34 +R1,1=1.
  35 +R2,1=0.
  36 +S2=0.
  37 +R0,2=0.
  38 +R1,2=0.
  39 +R2,2=1.
navigation/ndi_files/Markers/8700338.rom 0 → 100644
No preview for this file type
navigation/ndi_files/Markers/8700339.rom 0 → 100644
No preview for this file type
navigation/ndi_files/Markers/8700340.rom 0 → 100644
No preview for this file type
navigation/ndi_files/Markers/NBSprobe.rom 0 → 100644
No preview for this file type
navigation/ndi_files/Markers/NBSref.rom 0 → 100644
No preview for this file type
navigation/ndi_files/Markers/NT-103.rom 0 → 100644
No preview for this file type
navigation/ndi_files/Markers/NT-112.rom 0 → 100644
No preview for this file type
navigation/ndi_files/Markers/NT-115.rom 0 → 100644
No preview for this file type
navigation/ndi_files/Markers/active-wireless.rom 0 → 100644
No preview for this file type