Commit 9092a27045f7f97833ac607e4bcdd9ad121759c8
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.
Showing
3 changed files
with
27 additions
and
11 deletions
Show diff stats
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 | ... | ... |