Commit 58d46d1874f9124ecada3a4eaab7b86b5064ce41

Authored by Andrey Zhdanov
Committed by GitHub
1 parent 96989be9
Exists in master

Cleanup of the markers code (#358)

Showing 1 changed file with 44 additions and 43 deletions   Show diff stats
invesalius/gui/task_navigator.py
@@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
18 #-------------------------------------------------------------------------- 18 #--------------------------------------------------------------------------
19 19
20 from functools import partial 20 from functools import partial
  21 +import itertools
21 import csv 22 import csv
22 import time 23 import time
23 24
@@ -649,7 +650,7 @@ class NeuronavigationPanel(wx.Panel): @@ -649,7 +650,7 @@ class NeuronavigationPanel(wx.Panel):
649 fiducial_name = const.IMAGE_FIDUCIALS[n]['fiducial_name'] 650 fiducial_name = const.IMAGE_FIDUCIALS[n]['fiducial_name']
650 651
651 # XXX: This is still a bit hard to read, could be cleaned up. 652 # XXX: This is still a bit hard to read, could be cleaned up.
652 - marker_id = list(const.BTNS_IMG_MARKERS[evt.GetId()].values())[0] 653 + label = list(const.BTNS_IMG_MARKERS[evt.GetId()].values())[0]
653 654
654 if self.btns_set_fiducial[n].GetValue(): 655 if self.btns_set_fiducial[n].GetValue():
655 coord = self.numctrls_fiducial[n][0].GetValue(),\ 656 coord = self.numctrls_fiducial[n][0].GetValue(),\
@@ -663,13 +664,13 @@ class NeuronavigationPanel(wx.Panel): @@ -663,13 +664,13 @@ class NeuronavigationPanel(wx.Panel):
663 seed = 3 * [0.] 664 seed = 3 * [0.]
664 665
665 Publisher.sendMessage('Create marker', coord=coord, colour=colour, size=size, 666 Publisher.sendMessage('Create marker', coord=coord, colour=colour, size=size,
666 - marker_id=marker_id, seed=seed) 667 + marker_id=label, seed=seed)
667 else: 668 else:
668 for m in [0, 1, 2]: 669 for m in [0, 1, 2]:
669 self.numctrls_fiducial[n][m].SetValue(float(self.current_coord[m])) 670 self.numctrls_fiducial[n][m].SetValue(float(self.current_coord[m]))
670 671
671 Publisher.sendMessage('Set image fiducial', fiducial_name=fiducial_name, coord=np.nan) 672 Publisher.sendMessage('Set image fiducial', fiducial_name=fiducial_name, coord=np.nan)
672 - Publisher.sendMessage('Delete fiducial marker', marker_id=marker_id) 673 + Publisher.sendMessage('Delete fiducial marker', label=label)
673 674
674 def OnTrackerFiducials(self, n, evt, ctrl): 675 def OnTrackerFiducials(self, n, evt, ctrl):
675 676
@@ -1092,7 +1093,6 @@ class MarkersPanel(wx.Panel): @@ -1092,7 +1093,6 @@ class MarkersPanel(wx.Panel):
1092 self.current_angle = 0, 0, 0 1093 self.current_angle = 0, 0, 0
1093 self.current_seed = 0, 0, 0 1094 self.current_seed = 0, 0, 0
1094 self.list_coord = [] 1095 self.list_coord = []
1095 - self.marker_ind = 0  
1096 self.tgt_flag = self.tgt_index = None 1096 self.tgt_flag = self.tgt_index = None
1097 self.nav_status = False 1097 self.nav_status = False
1098 1098
@@ -1138,7 +1138,7 @@ class MarkersPanel(wx.Panel): @@ -1138,7 +1138,7 @@ class MarkersPanel(wx.Panel):
1138 1138
1139 # Buttons to delete or remove markers 1139 # Buttons to delete or remove markers
1140 btn_delete_single = wx.Button(self, -1, label=_('Remove'), size=wx.Size(65, 23)) 1140 btn_delete_single = wx.Button(self, -1, label=_('Remove'), size=wx.Size(65, 23))
1141 - btn_delete_single.Bind(wx.EVT_BUTTON, self.OnDeleteSingleMarker) 1141 + btn_delete_single.Bind(wx.EVT_BUTTON, self.OnDeleteMultipleMarkers)
1142 1142
1143 btn_delete_all = wx.Button(self, -1, label=_('Delete all'), size=wx.Size(135, 23)) 1143 btn_delete_all = wx.Button(self, -1, label=_('Delete all'), size=wx.Size(135, 23))
1144 btn_delete_all.Bind(wx.EVT_BUTTON, self.OnDeleteAllMarkers) 1144 btn_delete_all.Bind(wx.EVT_BUTTON, self.OnDeleteAllMarkers)
@@ -1177,7 +1177,7 @@ class MarkersPanel(wx.Panel): @@ -1177,7 +1177,7 @@ class MarkersPanel(wx.Panel):
1177 def __bind_events(self): 1177 def __bind_events(self):
1178 # Publisher.subscribe(self.UpdateCurrentCoord, 'Co-registered points') 1178 # Publisher.subscribe(self.UpdateCurrentCoord, 'Co-registered points')
1179 Publisher.subscribe(self.UpdateCurrentCoord, 'Set cross focal point') 1179 Publisher.subscribe(self.UpdateCurrentCoord, 'Set cross focal point')
1180 - Publisher.subscribe(self.OnDeleteSingleMarker, 'Delete fiducial marker') 1180 + Publisher.subscribe(self.OnDeleteMultipleMarkers, 'Delete fiducial marker')
1181 Publisher.subscribe(self.OnDeleteAllMarkers, 'Delete all markers') 1181 Publisher.subscribe(self.OnDeleteAllMarkers, 'Delete all markers')
1182 Publisher.subscribe(self.CreateMarker, 'Create marker') 1182 Publisher.subscribe(self.CreateMarker, 'Create marker')
1183 Publisher.subscribe(self.UpdateNavigationStatus, 'Navigation status') 1183 Publisher.subscribe(self.UpdateNavigationStatus, 'Navigation status')
@@ -1293,7 +1293,6 @@ class MarkersPanel(wx.Panel): @@ -1293,7 +1293,6 @@ class MarkersPanel(wx.Panel):
1293 1293
1294 if result == wx.ID_OK: 1294 if result == wx.ID_OK:
1295 self.list_coord = [] 1295 self.list_coord = []
1296 - self.marker_ind = 0  
1297 Publisher.sendMessage('Remove all markers', indexes=self.lc.GetItemCount()) 1296 Publisher.sendMessage('Remove all markers', indexes=self.lc.GetItemCount())
1298 self.lc.DeleteAllItems() 1297 self.lc.DeleteAllItems()
1299 Publisher.sendMessage('Stop Blink Marker', index='DeleteAll') 1298 Publisher.sendMessage('Stop Blink Marker', index='DeleteAll')
@@ -1304,46 +1303,47 @@ class MarkersPanel(wx.Panel): @@ -1304,46 +1303,47 @@ class MarkersPanel(wx.Panel):
1304 if not hasattr(evt, 'data'): 1303 if not hasattr(evt, 'data'):
1305 wx.MessageBox(_("Target deleted."), _("InVesalius 3")) 1304 wx.MessageBox(_("Target deleted."), _("InVesalius 3"))
1306 1305
1307 - def OnDeleteSingleMarker(self, evt=None, marker_id=None):  
1308 - # OnDeleteSingleMarker is used for both pubsub and button click events 1306 + def OnDeleteMultipleMarkers(self, evt=None, label=None):
  1307 + # OnDeleteMultipleMarkers is used for both pubsub and button click events
1309 # Pubsub is used for fiducial handle and button click for all others 1308 # Pubsub is used for fiducial handle and button click for all others
1310 1309
1311 - if not evt:  
1312 - if self.lc.GetItemCount(): 1310 + if not evt: # called through pubsub
  1311 + index = []
  1312 + allowed_labels = itertools.chain(*(const.BTNS_IMG_MARKERS[i].values() for i in const.BTNS_IMG_MARKERS))
  1313 +
  1314 + if label and (label in allowed_labels):
1313 for id_n in range(self.lc.GetItemCount()): 1315 for id_n in range(self.lc.GetItemCount()):
1314 item = self.lc.GetItem(id_n, 4) 1316 item = self.lc.GetItem(id_n, 4)
1315 - if item.GetText() == marker_id:  
1316 - for i in const.BTNS_IMG_MARKERS:  
1317 - if marker_id in list(const.BTNS_IMG_MARKERS[i].values())[0]:  
1318 - self.lc.Focus(item.GetId())  
1319 - index = [self.lc.GetFocusedItem()]  
1320 - else:  
1321 - if self.lc.GetFirstSelected() != -1:  
1322 - index = self.GetSelectedItems()  
1323 - else:  
1324 - index = None 1317 + if item.GetText() == label:
  1318 + self.lc.Focus(item.GetId())
  1319 + index = [self.lc.GetFocusedItem()]
  1320 +
  1321 + else: # called from button click
  1322 + index = self.__getSelectedItems()
1325 1323
1326 - #TODO: There are bugs when no marker is selected, test and improve 1324 + #TODO: Bug - when deleting multiple markers and target is not the first marker
1327 if index: 1325 if index:
1328 if self.tgt_flag and self.tgt_index == index[0]: 1326 if self.tgt_flag and self.tgt_index == index[0]:
1329 self.tgt_flag = self.tgt_index = None 1327 self.tgt_flag = self.tgt_index = None
1330 Publisher.sendMessage('Disable or enable coil tracker', status=False) 1328 Publisher.sendMessage('Disable or enable coil tracker', status=False)
1331 - wx.MessageBox(_("No data selected."), _("InVesalius 3")) 1329 + wx.MessageBox(_("Target deleted."), _("InVesalius 3"))
1332 1330
1333 - self.DeleteMarker(index) 1331 + self.__deleteMultipleMarkers(index)
1334 else: 1332 else:
1335 - wx.MessageBox(_("Target deleted."), _("InVesalius 3")) 1333 + wx.MessageBox(_("No data selected."), _("InVesalius 3"))
1336 1334
1337 - def DeleteMarker(self, index): 1335 + def __deleteMultipleMarkers(self, index):
  1336 + """ Delete multiple markers indexed by index. index must be sorted in
  1337 + the ascending order.
  1338 + """
1338 for i in reversed(index): 1339 for i in reversed(index):
1339 del self.list_coord[i] 1340 del self.list_coord[i]
1340 self.lc.DeleteItem(i) 1341 self.lc.DeleteItem(i)
1341 for n in range(0, self.lc.GetItemCount()): 1342 for n in range(0, self.lc.GetItemCount()):
1342 self.lc.SetItem(n, 0, str(n+1)) 1343 self.lc.SetItem(n, 0, str(n+1))
1343 - self.marker_ind -= 1  
1344 Publisher.sendMessage('Remove marker', index=index) 1344 Publisher.sendMessage('Remove marker', index=index)
1345 1345
1346 - def OnCreateMarker(self, evt=None, coord=None, marker_id=None, colour=None): 1346 + def OnCreateMarker(self, evt):
1347 self.CreateMarker() 1347 self.CreateMarker()
1348 1348
1349 def OnLoadMarkers(self, evt): 1349 def OnLoadMarkers(self, evt):
@@ -1405,7 +1405,7 @@ class MarkersPanel(wx.Panel): @@ -1405,7 +1405,7 @@ class MarkersPanel(wx.Panel):
1405 marker_id = '*' 1405 marker_id = '*'
1406 1406
1407 self.CreateMarker(coord=coord, colour=colour, size=size, 1407 self.CreateMarker(coord=coord, colour=colour, size=size,
1408 - marker_id=marker_id, target_id=target_id, seed=seed) 1408 + label=marker_id, target_id=target_id, seed=seed)
1409 1409
1410 # if there are multiple TARGETS will set the last one 1410 # if there are multiple TARGETS will set the last one
1411 if target: 1411 if target:
@@ -1460,7 +1460,7 @@ class MarkersPanel(wx.Panel): @@ -1460,7 +1460,7 @@ class MarkersPanel(wx.Panel):
1460 target_id = line[14] 1460 target_id = line[14]
1461 1461
1462 self.CreateMarker(coord=coord, colour=colour, size=size, 1462 self.CreateMarker(coord=coord, colour=colour, size=size,
1463 - marker_id=marker_id, target_id=target_id, seed=seed) 1463 + label=marker_id, target_id=target_id, seed=seed)
1464 1464
1465 # if there are multiple TARGETS will set the last one 1465 # if there are multiple TARGETS will set the last one
1466 if target: 1466 if target:
@@ -1515,7 +1515,7 @@ class MarkersPanel(wx.Panel): @@ -1515,7 +1515,7 @@ class MarkersPanel(wx.Panel):
1515 def OnSelectSize(self, evt, ctrl): 1515 def OnSelectSize(self, evt, ctrl):
1516 self.marker_size = ctrl.GetValue() 1516 self.marker_size = ctrl.GetValue()
1517 1517
1518 - def CreateMarker(self, coord=None, colour=None, size=None, marker_id='*', target_id='*', seed=None): 1518 + def CreateMarker(self, coord=None, colour=None, size=None, label='*', target_id='*', seed=None):
1519 coord = coord or self.current_coord 1519 coord = coord or self.current_coord
1520 colour = colour or self.marker_colour 1520 colour = colour or self.marker_colour
1521 size = size or self.marker_size 1521 size = size or self.marker_size
@@ -1524,16 +1524,14 @@ class MarkersPanel(wx.Panel): @@ -1524,16 +1524,14 @@ class MarkersPanel(wx.Panel):
1524 # TODO: Use matrix coordinates and not world coordinates as current method. 1524 # TODO: Use matrix coordinates and not world coordinates as current method.
1525 # This makes easier for inter-software comprehension. 1525 # This makes easier for inter-software comprehension.
1526 1526
1527 - Publisher.sendMessage('Add marker', ball_id=self.marker_ind, size=size, colour=colour, coord=coord[0:3])  
1528 -  
1529 - self.marker_ind += 1 1527 + Publisher.sendMessage('Add marker', ball_id=len(self.list_coord), size=size, colour=colour, coord=coord[0:3])
1530 1528
1531 # List of lists with coordinates and properties of a marker 1529 # List of lists with coordinates and properties of a marker
1532 line = [] 1530 line = []
1533 line.extend(coord) 1531 line.extend(coord)
1534 line.extend(colour) 1532 line.extend(colour)
1535 line.append(size) 1533 line.append(size)
1536 - line.append(marker_id) 1534 + line.append(label)
1537 line.extend(seed) 1535 line.extend(seed)
1538 line.append(target_id) 1536 line.append(target_id)
1539 1537
@@ -1549,21 +1547,24 @@ class MarkersPanel(wx.Panel): @@ -1549,21 +1547,24 @@ class MarkersPanel(wx.Panel):
1549 self.lc.SetItem(num_items, 1, str(round(coord[0], 2))) 1547 self.lc.SetItem(num_items, 1, str(round(coord[0], 2)))
1550 self.lc.SetItem(num_items, 2, str(round(coord[1], 2))) 1548 self.lc.SetItem(num_items, 2, str(round(coord[1], 2)))
1551 self.lc.SetItem(num_items, 3, str(round(coord[2], 2))) 1549 self.lc.SetItem(num_items, 3, str(round(coord[2], 2)))
1552 - self.lc.SetItem(num_items, 4, str(marker_id)) 1550 + self.lc.SetItem(num_items, 4, str(label))
1553 self.lc.EnsureVisible(num_items) 1551 self.lc.EnsureVisible(num_items)
1554 1552
1555 - def GetSelectedItems(self): 1553 + def __getSelectedItems(self):
1556 """ 1554 """
1557 - Returns a list of the selected items in the list control. 1555 + Returns a (possibly empty) list of the selected items in the list control.
1558 """ 1556 """
1559 selection = [] 1557 selection = []
1560 - index = self.lc.GetFirstSelected()  
1561 - selection.append(index)  
1562 - while len(selection) != self.lc.GetSelectedItemCount():  
1563 - index = self.lc.GetNextSelected(index)  
1564 - selection.append(index) 1558 +
  1559 + next = self.lc.GetFirstSelected()
  1560 +
  1561 + while next != -1:
  1562 + selection.append(next)
  1563 + next = self.lc.GetNextSelected(next)
  1564 +
1565 return selection 1565 return selection
1566 1566
  1567 +
1567 class DbsPanel(wx.Panel): 1568 class DbsPanel(wx.Panel):
1568 def __init__(self, parent): 1569 def __init__(self, parent):
1569 wx.Panel.__init__(self, parent) 1570 wx.Panel.__init__(self, parent)