Commit 9092a27045f7f97833ac607e4bcdd9ad121759c8

Authored by Olli-Pekka Kahilakoski
1 parent c3593caa
Exists in master

MOD: Change logic for when to use coil without handle to mark the target

- Previously, coil without handle was used to mark the target only if
  object calibration had not been done yet. After object calibration
  was done, the variable polydata stored the coil mesh that was selected
  by the user when doing the calibration, and hence that coil mesh
  (typically containing the handle) was used to mark the target.

- Change the logic to follow these rules:

  * When the default coil is selected in object calibration, use the
    default coil with a handle to mark the coil location, and default
	coil without a handle to mark the target.

  * When object calibration is not yet done, use default coil without
    a handle to mark the target.

  * When a custom coil is selected in object calibration, use the custom
    coil to mark both the coil location and the target, regardless of if
    the mesh contains handle or not. This is done because otherwise the user
    would need to select two custom meshes, one that is used to mark the coil
    location and another for the target.
invesalius/data/viewer_volume.py
... ... @@ -192,6 +192,7 @@ class Viewer(wx.Panel):
192 192 self.dummy_coil_actor = None
193 193 self.target_mode = False
194 194 self.polydata = None
  195 + self.use_default_object = True
195 196 self.anglethreshold = const.COIL_ANGLES_THRESHOLD
196 197 self.distthreshold = const.COIL_COORD_THRESHOLD
197 198 self.angle_arrow_projection_threshold = const.COIL_ANGLE_ARROW_PROJECTION_THRESHOLD
... ... @@ -1017,10 +1018,10 @@ class Viewer(wx.Panel):
1017 1018 self.aim_actor = aim_actor
1018 1019 self.ren.AddActor(aim_actor)
1019 1020  
1020   - if self.polydata:
1021   - obj_polydata = self.polydata
1022   - else:
  1021 + if self.use_default_object:
1023 1022 obj_polydata = self.CreateObjectPolyData(os.path.join(inv_paths.OBJ_DIR, "magstim_fig8_coil_no_handle.stl"))
  1023 + else:
  1024 + obj_polydata = self.polydata
1024 1025  
1025 1026 transform = vtk.vtkTransform()
1026 1027 transform.RotateZ(90)
... ... @@ -1597,10 +1598,11 @@ class Viewer(wx.Panel):
1597 1598 self.GetCellIntersection(p1, norm, coil_norm, coil_dir)
1598 1599 self.Refresh()
1599 1600  
1600   - def UpdateTrackObjectState(self, evt=None, flag=None, obj_name=None, polydata=None):
  1601 + def UpdateTrackObjectState(self, evt=None, flag=None, obj_name=None, polydata=None, use_default_object=True):
1601 1602 if flag:
1602 1603 self.obj_name = obj_name
1603 1604 self.polydata = polydata
  1605 + self.use_default_object = use_default_object
1604 1606 if not self.obj_actor:
1605 1607 self.AddObjectActor(self.obj_name)
1606 1608 else:
... ...
invesalius/gui/dialogs.py
... ... @@ -3267,6 +3267,7 @@ class ObjectCalibrationDialog(wx.Dialog):
3267 3267 self.obj_ref_id = 2
3268 3268 self.obj_name = None
3269 3269 self.polydata = None
  3270 + self.use_default_object = False
3270 3271  
3271 3272 self.obj_fiducials = np.full([5, 3], np.nan)
3272 3273 self.obj_orients = np.full([5, 3], np.nan)
... ... @@ -3379,8 +3380,9 @@ class ObjectCalibrationDialog(wx.Dialog):
3379 3380 return 0
3380 3381  
3381 3382 def LoadObject(self):
3382   - default = self.ObjectImportDialog()
3383   - if not default:
  3383 + self.use_default_object = self.ObjectImportDialog()
  3384 +
  3385 + if not self.use_default_object:
3384 3386 filename = ShowImportMeshFilesDialog()
3385 3387  
3386 3388 if filename:
... ... @@ -3398,6 +3400,12 @@ class ObjectCalibrationDialog(wx.Dialog):
3398 3400 else:
3399 3401 filename = os.path.join(inv_paths.OBJ_DIR, "magstim_fig8_coil.stl")
3400 3402 reader = vtk.vtkSTLReader()
  3403 +
  3404 + # XXX: If the user cancels the dialog for importing the coil mesh file, the current behavior is to
  3405 + # use the default object after all. A more logical behavior in that case would be to cancel the
  3406 + # whole object calibration, but implementing that would need larger refactoring.
  3407 + #
  3408 + self.use_default_object = True
3401 3409 else:
3402 3410 filename = os.path.join(inv_paths.OBJ_DIR, "magstim_fig8_coil.stl")
3403 3411 reader = vtk.vtkSTLReader()
... ... @@ -3531,7 +3539,7 @@ class ObjectCalibrationDialog(wx.Dialog):
3531 3539 self.obj_ref_id = 0
3532 3540  
3533 3541 def GetValue(self):
3534   - return self.obj_fiducials, self.obj_orients, self.obj_ref_id, self.obj_name, self.polydata
  3542 + return self.obj_fiducials, self.obj_orients, self.obj_ref_id, self.obj_name, self.polydata, self.use_default_object
3535 3543  
3536 3544 class ICPCorregistrationDialog(wx.Dialog):
3537 3545  
... ...
invesalius/gui/task_navigator.py
... ... @@ -287,7 +287,7 @@ class InnerFoldPanel(wx.Panel):
287 287  
288 288 Publisher.sendMessage('Update serial port', serial_port=com_port)
289 289  
290   - def OnShowObject(self, evt=None, flag=None, obj_name=None, polydata=None):
  290 + def OnShowObject(self, evt=None, flag=None, obj_name=None, polydata=None, use_default_object=True):
291 291 if not evt:
292 292 if flag:
293 293 self.checkobj.Enable(True)
... ... @@ -966,7 +966,7 @@ class NeuronavigationPanel(wx.Panel):
966 966 def UpdateObjectRegistration(self, data=None):
967 967 self.navigation.obj_reg = data
968 968  
969   - def UpdateTrackObjectState(self, evt=None, flag=None, obj_name=None, polydata=None):
  969 + def UpdateTrackObjectState(self, evt=None, flag=None, obj_name=None, polydata=None, use_default_object=True):
970 970 self.navigation.track_obj = flag
971 971  
972 972 def UpdateSerialPort(self, serial_port):
... ... @@ -1320,7 +1320,7 @@ class ObjectRegistrationPanel(wx.Panel):
1320 1320 dialog = dlg.ObjectCalibrationDialog(self.nav_prop)
1321 1321 try:
1322 1322 if dialog.ShowModal() == wx.ID_OK:
1323   - self.obj_fiducials, self.obj_orients, self.obj_ref_mode, self.obj_name, polydata = dialog.GetValue()
  1323 + self.obj_fiducials, self.obj_orients, self.obj_ref_mode, self.obj_name, polydata, use_default_object = dialog.GetValue()
1324 1324 if np.isfinite(self.obj_fiducials).all() and np.isfinite(self.obj_orients).all():
1325 1325 self.checktrack.Enable(1)
1326 1326 Publisher.sendMessage('Update object registration',
... ... @@ -1329,7 +1329,13 @@ class ObjectRegistrationPanel(wx.Panel):
1329 1329 label=_("Ready"))
1330 1330 # Enable automatically Track object, Show coil and disable Vol. Camera
1331 1331 self.checktrack.SetValue(True)
1332   - Publisher.sendMessage('Update track object state', flag=True, obj_name=self.obj_name, polydata=polydata)
  1332 + Publisher.sendMessage(
  1333 + 'Update track object state',
  1334 + flag=True,
  1335 + obj_name=self.obj_name,
  1336 + polydata=polydata,
  1337 + use_default_object=use_default_object,
  1338 + )
1333 1339 Publisher.sendMessage('Change camera checkbox', status=False)
1334 1340  
1335 1341 except wx._core.PyAssertionError: # TODO FIX: win64
... ...