diff --git a/invesalius/constants.py b/invesalius/constants.py index b6f8d06..7e866ff 100644 --- a/invesalius/constants.py +++ b/invesalius/constants.py @@ -698,25 +698,57 @@ TR2 = wx.NewId() TR3 = wx.NewId() SET = wx.NewId() -BTNS_IMG = {IR1: {0: _('LEI')}, - IR2: {1: _('REI')}, - IR3: {2: _('NAI')}} - -BTNS_IMG_MKS = {IR1: {0: 'LEI'}, - IR2: {1: 'REI'}, - IR3: {2: 'NAI'}} - -TIPS_IMG = [_("Select left ear in image"), - _("Select right ear in image"), - _("Select nasion in image")] - -BTNS_TRK = {TR1: {3: _('LET')}, - TR2: {4: _('RET')}, - TR3: {5: _('NAT')}} - -TIPS_TRK = [_("Select left ear with spatial tracker"), - _("Select right ear with spatial tracker"), - _("Select nasion with spatial tracker")] +IMAGE_FIDUCIALS = [ + { + 'button_id': IR1, + 'label': 'LEI', + 'fiducial_name': 'LE', + 'fiducial_index': 0, + 'tip': _("Select left ear in image"), + }, + { + 'button_id': IR2, + 'label': 'REI', + 'fiducial_name': 'RE', + 'fiducial_index': 1, + 'tip': _("Select right ear in image"), + }, + { + 'button_id': IR3, + 'label': 'NAI', + 'fiducial_name': 'NA', + 'fiducial_index': 2, + 'tip': _("Select nasion in image"), + }, +] + +TRACKER_FIDUCIALS = [ + { + 'button_id': TR1, + 'label': 'LET', + 'fiducial_name': 'LE', + 'fiducial_index': 3, + 'tip': _("Select left ear with spatial tracker"), + }, + { + 'button_id': TR2, + 'label': 'RET', + 'fiducial_name': 'RE', + 'fiducial_index': 4, + 'tip': _("Select right ear with spatial tracker"), + }, + { + 'button_id': TR3, + 'label': 'NAT', + 'fiducial_name': 'NA', + 'fiducial_index': 5, + 'tip': _("Select nasion with spatial tracker"), + }, +] + +BTNS_IMG_MARKERS = {IR1: {0: 'LEI'}, + IR2: {1: 'REI'}, + IR3: {2: 'NAI'}} OBJL = wx.NewId() OBJR = wx.NewId() diff --git a/invesalius/gui/task_navigator.py b/invesalius/gui/task_navigator.py index a4c928b..029608c 100644 --- a/invesalius/gui/task_navigator.py +++ b/invesalius/gui/task_navigator.py @@ -369,26 +369,24 @@ class NeuronavigationPanel(wx.Panel): choice_ref.Bind(wx.EVT_COMBOBOX, partial(self.OnChoiceRefMode, ctrl=choice_trck)) # Toggle buttons for image fiducials - btns_img = const.BTNS_IMG - tips_img = const.TIPS_IMG + for n, fiducial in enumerate(const.IMAGE_FIDUCIALS): + button_id = fiducial['button_id'] + label = fiducial['label'] + tip = fiducial['tip'] - for k in btns_img: - n = list(btns_img[k].keys())[0] - lab = list(btns_img[k].values())[0] - self.btns_coord[n] = wx.ToggleButton(self, k, label=lab, size=wx.Size(45, 23)) - self.btns_coord[n].SetToolTip(wx.ToolTip(tips_img[n])) - self.btns_coord[n].Bind(wx.EVT_TOGGLEBUTTON, self.OnImageFiducials) + self.btns_coord[n] = wx.ToggleButton(self, button_id, label=label, size=wx.Size(45, 23)) + self.btns_coord[n].SetToolTip(wx.ToolTip(tip)) + self.btns_coord[n].Bind(wx.EVT_TOGGLEBUTTON, partial(self.OnImageFiducials, n)) # Push buttons for tracker fiducials - btns_trk = const.BTNS_TRK - tips_trk = const.TIPS_TRK + for n, fiducial in enumerate(const.TRACKER_FIDUCIALS): + button_id = fiducial['button_id'] + label = fiducial['label'] + tip = fiducial['tip'] - for k in btns_trk: - n = list(btns_trk[k].keys())[0] - lab = list(btns_trk[k].values())[0] - self.btns_coord[n] = wx.Button(self, k, label=lab, size=wx.Size(45, 23)) - self.btns_coord[n].SetToolTip(wx.ToolTip(tips_trk[n-3])) - self.btns_coord[n].Bind(wx.EVT_BUTTON, self.OnTrackerFiducials) + self.btns_coord[n + 3] = wx.Button(self, button_id, label=label, size=wx.Size(45, 23)) + self.btns_coord[n + 3].SetToolTip(wx.ToolTip(tip)) + self.btns_coord[n + 3].Bind(wx.EVT_BUTTON, partial(self.OnTrackerFiducials, n)) # TODO: Find a better allignment between FRE, text and navigate button txt_fre = wx.StaticText(self, -1, _('FRE:')) @@ -462,6 +460,8 @@ class NeuronavigationPanel(wx.Panel): def __bind_events(self): Publisher.subscribe(self.LoadImageFiducials, 'Load image fiducials') + Publisher.subscribe(self.SetImageFiducial, 'Set image fiducial') + Publisher.subscribe(self.SetTrackerFiducial, 'Set tracker fiducial') Publisher.subscribe(self.UpdateTriggerState, 'Update trigger state') Publisher.subscribe(self.UpdateTrackObjectState, 'Update track object state') Publisher.subscribe(self.UpdateImageCoordinates, 'Set cross focal point') @@ -481,15 +481,114 @@ class NeuronavigationPanel(wx.Panel): Publisher.subscribe(self.UpdateTarget, 'Update target') def LoadImageFiducials(self, marker_id, coord): - for n in const.BTNS_IMG_MKS: - btn_id = list(const.BTNS_IMG_MKS[n].keys())[0] - fid_id = list(const.BTNS_IMG_MKS[n].values())[0] - if marker_id == fid_id and not self.btns_coord[btn_id].GetValue(): + for n in const.BTNS_IMG_MARKERS: + btn_id = list(const.BTNS_IMG_MARKERS[n].keys())[0] + fiducial_name = list(const.BTNS_IMG_MARKERS[n].values())[0] + if marker_id == fiducial_name and not self.btns_coord[btn_id].GetValue(): self.btns_coord[btn_id].SetValue(True) - self.fiducials[btn_id, :] = coord[0:3] + Publisher.sendMessage('Set image fiducial', fiducial_name=fiducial_name, coord=coord[0:3]) for m in [0, 1, 2]: self.numctrls_coord[btn_id][m].SetValue(coord[m]) + def FiducialNameToIndex(self, fiducials, fiducial_name): + fiducial = [fiducial for fiducial in fiducials if fiducial['fiducial_name'] == fiducial_name][0] + return fiducial['fiducial_index'] + + def SetImageFiducial(self, fiducial_name, coord): + fiducial_index = self.FiducialNameToIndex(const.IMAGE_FIDUCIALS, fiducial_name) + self.fiducials[fiducial_index, :] = coord + + print("Set image fiducial {} to coordinates {}".format(fiducial_name, coord)) + + def SetTrackerFiducial(self, fiducial_name): + fiducial_index = self.FiducialNameToIndex(const.TRACKER_FIDUCIALS, fiducial_name) + coord = None + + if not(self.trk_init and self.tracker_id): + dlg.ShowNavigationTrackerWarning(0, 'choose') + return + + # if self.tracker_id == const.DEBUGTRACK: + # if btn_id == 3: + # coord1 = np.array([-120., 0., 0., 0., 0., 0.]) + # elif btn_id == 4: + # coord1 = np.array([120., 0., 0., 0., 0., 0.]) + # elif btn_id == 5: + # coord1 = np.array([0., 120., 0., 0., 0., 0.]) + # coord2 = np.zeros([3, 6]) + # coord_raw = np.vstack([coord1, coord2]) + # else: + coord_raw = dco.GetCoordinates(self.trk_init, self.tracker_id, self.ref_mode_id) + + if self.ref_mode_id: + coord = dco.dynamic_reference_m(coord_raw[0, :], coord_raw[1, :]) + else: + coord = coord_raw[0, :] + coord[2] = -coord[2] + + # Update tracker fiducial with tracker coordinates + self.fiducials[fiducial_index, :] = coord[0:3] + + if fiducial_index == 3: + self.fiducials_raw[0, :] = coord_raw[0, :] + self.fiducials_raw[1, :] = coord_raw[1, :] + elif fiducial_index == 4: + self.fiducials_raw[2, :] = coord_raw[0, :] + self.fiducials_raw[3, :] = coord_raw[1, :] + else: + self.fiducials_raw[4, :] = coord_raw[0, :] + self.fiducials_raw[5, :] = coord_raw[1, :] + + # Update tracker location in the UI. + for n in [0, 1, 2]: + self.numctrls_coord[fiducial_index][n].SetValue(float(coord[n])) + + print("Set tracker fiducial {} to coordinates {}.".format(fiducial_name, coord[0:3])) + + def UpdateNavigationStatus(self, nav_status, vis_status): + self.nav_status = nav_status + if nav_status and (self.m_icp is not None): + self.checkicp.Enable(True) + else: + self.checkicp.Enable(False) + #self.checkicp.SetValue(False) + + def UpdateFRE(self, fre): + # TODO: Exhibit FRE in a warning dialog and only starts navigation after user clicks ok + self.txtctrl_fre.SetValue(str(round(fre, 2))) + if fre <= 3: + self.txtctrl_fre.SetBackgroundColour('GREEN') + else: + self.txtctrl_fre.SetBackgroundColour('RED') + + def UpdateTrekkerObject(self, data): + # self.trk_inp = data + self.trekker = data + + def UpdateNumTracts(self, data): + self.n_tracts = data + + def UpdateSeedOffset(self, data): + self.seed_offset = data + + def UpdateSeedRadius(self, data): + self.seed_radius = data + + def UpdateSleep(self, data): + self.sleep_nav = data + + def UpdateNumberThreads(self, data): + self.n_threads = data + + def UpdateTractsVisualization(self, data): + self.view_tracts = data + + def UpdateACTData(self, data): + self.act_data = data + + def UpdateTarget(self, coord): + self.target = coord + def UpdateNavigationStatus(self, nav_status, vis_status): self.nav_status = nav_status if nav_status and (self.m_icp is not None): @@ -645,65 +744,29 @@ class NeuronavigationPanel(wx.Panel): nav_prop=(self.tracker_id, self.trk_init, self.ref_mode_id)) print("Reference mode changed!") - def OnImageFiducials(self, evt): - btn_id = list(const.BTNS_IMG_MKS[evt.GetId()].keys())[0] - marker_id = list(const.BTNS_IMG_MKS[evt.GetId()].values())[0] + def OnImageFiducials(self, n, evt): + fiducial_name = const.IMAGE_FIDUCIALS[n]['fiducial_name'] - if self.btns_coord[btn_id].GetValue(): - coord = self.numctrls_coord[btn_id][0].GetValue(),\ - self.numctrls_coord[btn_id][1].GetValue(),\ - self.numctrls_coord[btn_id][2].GetValue(), 0, 0, 0 + # XXX: This is still a bit hard to read, could be cleaned up. + marker_id = list(const.BTNS_IMG_MARKERS[evt.GetId()].values())[0] - self.fiducials[btn_id, :] = coord[0:3] + if self.btns_coord[n].GetValue(): + coord = self.numctrls_coord[n][0].GetValue(),\ + self.numctrls_coord[n][1].GetValue(),\ + self.numctrls_coord[n][2].GetValue(), 0, 0, 0 + + Publisher.sendMessage('Set image fiducial', fiducial_name=fiducial_name, coord=coord[0:3]) Publisher.sendMessage('Create marker', coord=coord, marker_id=marker_id) else: - for n in [0, 1, 2]: - self.numctrls_coord[btn_id][n].SetValue(float(self.current_coord[n])) + for m in [0, 1, 2]: + self.numctrls_coord[n][m].SetValue(float(self.current_coord[m])) - self.fiducials[btn_id, :] = np.nan + Publisher.sendMessage('Set image fiducial', fiducial_name=fiducial_name, coord=np.nan) Publisher.sendMessage('Delete fiducial marker', marker_id=marker_id) - def OnTrackerFiducials(self, evt): - btn_id = list(const.BTNS_TRK[evt.GetId()].keys())[0] - coord = None - - if self.trk_init and self.tracker_id: - # if self.tracker_id == const.DEBUGTRACK: - # if btn_id == 3: - # coord1 = np.array([-120., 0., 0., 0., 0., 0.]) - # elif btn_id == 4: - # coord1 = np.array([120., 0., 0., 0., 0., 0.]) - # elif btn_id == 5: - # coord1 = np.array([0., 120., 0., 0., 0., 0.]) - # coord2 = np.zeros([3, 6]) - # coord_raw = np.vstack([coord1, coord2]) - # else: - coord_raw = dco.GetCoordinates(self.trk_init, self.tracker_id, self.ref_mode_id) - - if self.ref_mode_id: - coord = dco.dynamic_reference_m(coord_raw[0, :], coord_raw[1, :]) - else: - coord = coord_raw[0, :] - coord[2] = -coord[2] - - else: - dlg.ShowNavigationTrackerWarning(0, 'choose') - - # Update number controls with tracker coordinates - if coord is not None: - self.fiducials[btn_id, :] = coord[0:3] - if btn_id == 3: - self.fiducials_raw[0, :] = coord_raw[0, :] - self.fiducials_raw[1, :] = coord_raw[1, :] - elif btn_id == 4: - self.fiducials_raw[2, :] = coord_raw[0, :] - self.fiducials_raw[3, :] = coord_raw[1, :] - else: - self.fiducials_raw[4, :] = coord_raw[0, :] - self.fiducials_raw[5, :] = coord_raw[1, :] - - for n in [0, 1, 2]: - self.numctrls_coord[btn_id][n].SetValue(float(coord[n])) + def OnTrackerFiducials(self, n, evt): + fiducial_name = const.TRACKER_FIDUCIALS[n]['fiducial_name'] + Publisher.sendMessage('Set tracker fiducial', fiducial_name=fiducial_name) def OnICP(self): dialog = dlg.ICPCorregistrationDialog(nav_prop=(self.tracker_id, self.trk_init, self.ref_mode_id)) @@ -1437,8 +1500,8 @@ class MarkersPanel(wx.Panel): for id_n in range(self.lc.GetItemCount()): item = self.lc.GetItem(id_n, 4) if item.GetText() == marker_id: - for i in const.BTNS_IMG_MKS: - if marker_id in list(const.BTNS_IMG_MKS[i].values())[0]: + for i in const.BTNS_IMG_MARKERS: + if marker_id in list(const.BTNS_IMG_MARKERS[i].values())[0]: self.lc.Focus(item.GetId()) index = [self.lc.GetFocusedItem()] else: @@ -1519,8 +1582,8 @@ class MarkersPanel(wx.Panel): # size = float(line[9]) if len(line) >= 11: - for i in const.BTNS_IMG_MKS: - if line[10] in list(const.BTNS_IMG_MKS[i].values())[0]: + for i in const.BTNS_IMG_MARKERS: + if line[10] in list(const.BTNS_IMG_MARKERS[i].values())[0]: Publisher.sendMessage('Load image fiducials', marker_id=line[10], coord=coord) elif line[10] == 'TARGET': target = count_line @@ -1537,8 +1600,8 @@ class MarkersPanel(wx.Panel): size = float(line[6]) if len(line) == 8: - for i in const.BTNS_IMG_MKS: - if line[7] in list(const.BTNS_IMG_MKS[i].values())[0]: + for i in const.BTNS_IMG_MARKERS: + if line[7] in list(const.BTNS_IMG_MARKERS[i].values())[0]: Publisher.sendMessage('Load image fiducials', marker_id=line[7], coord=coord) else: line.append("") -- libgit2 0.21.2