Commit 50cad05c75d947d97239c0ec408666cdd1924890
Committed by
GitHub
1 parent
27f1cd9f
Exists in
master
FIX: Failed to fetch image coordinates from cross move (#257)
* FIX: Failed to fetch image coordinates from cross move - Previous changes to the cross style disrupted the navigation - Enhanced how image coordinates are communicated through pubsub * WIP: Fix scroll and cross focal point difference in coordinate * FIX: Scroll and cross coordinates did not match - Removed debugging prints - Commented and removed unnecessary calls and function - Tested on niftis with 1.0 and 0.488 pixel spacings * Rename UpdateSlices
Showing
5 changed files
with
55 additions
and
78 deletions
Show diff stats
invesalius/data/record_coords.py
... | ... | @@ -43,9 +43,9 @@ class Record(threading.Thread): |
43 | 43 | |
44 | 44 | def __bind_events(self): |
45 | 45 | # Publisher.subscribe(self.UpdateCurrentCoords, 'Co-registered points') |
46 | - Publisher.subscribe(self.UpdateCurrentCoords, 'Update cross position') | |
46 | + Publisher.subscribe(self.UpdateCurrentCoords, 'Set cross focal point') | |
47 | 47 | |
48 | - def UpdateCurrentCoords(self, arg, position): | |
48 | + def UpdateCurrentCoords(self, position): | |
49 | 49 | self.coord = asarray(position) |
50 | 50 | |
51 | 51 | def stop(self): | ... | ... |
invesalius/data/styles.py
... | ... | @@ -473,18 +473,6 @@ class CrossInteractorStyle(DefaultInteractorStyle): |
473 | 473 | self.slice_actor = viewer.slice_data.actor |
474 | 474 | self.slice_data = viewer.slice_data |
475 | 475 | |
476 | - # tracts | |
477 | - # self.seed = [0., 0., 0.] | |
478 | - # slic = sl.Slice() | |
479 | - # self.affine = slic.affine | |
480 | - # self.tracker = slic.tracker | |
481 | - # | |
482 | - # self.affine_vtk = vtk.vtkMatrix4x4() | |
483 | - # for row in range(0, 4): | |
484 | - # for col in range(0, 4): | |
485 | - # self.affine_vtk.SetElement(row, col, self.affine[row, col]) | |
486 | - # --- | |
487 | - | |
488 | 476 | self.picker = vtk.vtkWorldPointPicker() |
489 | 477 | |
490 | 478 | self.AddObserver("MouseMoveEvent", self.OnCrossMove) |
... | ... | @@ -514,48 +502,18 @@ class CrossInteractorStyle(DefaultInteractorStyle): |
514 | 502 | |
515 | 503 | def ChangeCrossPosition(self, iren): |
516 | 504 | mouse_x, mouse_y = iren.GetEventPosition() |
517 | - wx, wy, wz = self.viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker) | |
518 | - px, py = self.viewer.get_slice_pixel_coord_by_world_pos(wx, wy, wz) | |
519 | - coord = self.viewer.calcultate_scroll_position(px, py) | |
520 | - | |
521 | - # Tracts | |
522 | - # pos_world_aux = np.ones([4, 1]) | |
523 | - # pos_world_aux[:3, -1] = bases.flip_x((wx, wy, wz))[:3] | |
524 | - # pos_world = np.linalg.inv(self.affine) @ pos_world_aux | |
525 | - # seed_aux = pos_world.reshape([1, 4])[0, :3] | |
526 | - # self.seed = seed_aux[np.newaxis, :] | |
527 | - # print("Check the seed: ", self.seed) | |
528 | - # | |
529 | - self.viewer.UpdateSlicesNavigation(None, (wx, wy, wz, 0.0, 0.0, 0.0)) | |
530 | - Publisher.sendMessage('Set cross focal point', position=(wx, wy, wz)) | |
505 | + x, y, z = self.viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker) | |
506 | + self.viewer.UpdateSlicesPosition([x, y, z]) | |
507 | + # This "Set cross" message is needed to update the cross in the other slices | |
508 | + Publisher.sendMessage('Set cross focal point', position=[x, y, z, 0., 0., 0.]) | |
531 | 509 | Publisher.sendMessage('Update slice viewer') |
532 | - # self.ScrollSlice(coord) | |
533 | - | |
534 | - # iren.Render() | |
535 | - | |
536 | - def ScrollSlice(self, coord): | |
537 | - if self.orientation == "AXIAL": | |
538 | - Publisher.sendMessage(('Set scroll position', 'SAGITAL'), | |
539 | - index=coord[0]) | |
540 | - Publisher.sendMessage(('Set scroll position', 'CORONAL'), | |
541 | - index=coord[1]) | |
542 | - elif self.orientation == "SAGITAL": | |
543 | - Publisher.sendMessage(('Set scroll position', 'AXIAL'), | |
544 | - index=coord[2]) | |
545 | - Publisher.sendMessage(('Set scroll position', 'CORONAL'), | |
546 | - index=coord[1]) | |
547 | - elif self.orientation == "CORONAL": | |
548 | - Publisher.sendMessage(('Set scroll position', 'AXIAL'), | |
549 | - index=coord[2]) | |
550 | - Publisher.sendMessage(('Set scroll position', 'SAGITAL'), | |
551 | - index=coord[0]) | |
552 | 510 | |
553 | 511 | def OnScrollBar(self, *args, **kwargs): |
554 | 512 | # Update other slice's cross according to the new focal point from |
555 | 513 | # the actual orientation. |
556 | 514 | x, y, z = self.viewer.cross.GetFocalPoint() |
557 | - self.viewer.UpdateSlicesNavigation(None, (x, y, z, 0.0, 0.0, 0.0)) | |
558 | - Publisher.sendMessage('Set cross focal point', position=(x, y, z)) | |
515 | + self.viewer.UpdateSlicesPosition([x, y, z]) | |
516 | + Publisher.sendMessage('Set cross focal point', position=[x, y, z, 0., 0., 0.]) | |
559 | 517 | Publisher.sendMessage('Update slice viewer') |
560 | 518 | |
561 | 519 | ... | ... |
invesalius/data/viewer_slice.py
... | ... | @@ -565,17 +565,31 @@ class Viewer(wx.Panel): |
565 | 565 | if self.slice_data.cursor: |
566 | 566 | self.slice_data.cursor.SetColour(colour_vtk) |
567 | 567 | |
568 | - def UpdateSlicesNavigation(self, arg, position): | |
568 | + def UpdateSlicesPosition(self, position): | |
569 | 569 | # Get point from base change |
570 | - ux, uy, uz = position[:3] | |
571 | - px, py = self.get_slice_pixel_coord_by_world_pos(ux, uy, uz) | |
570 | + px, py = self.get_slice_pixel_coord_by_world_pos(*position) | |
572 | 571 | coord = self.calcultate_scroll_position(px, py) |
572 | + # Debugging coordinates. For a 1.0 spacing axis the coord and position is the same, | |
573 | + # but for a spacing dimension =! 1, the coord and position are different | |
574 | + # print("\nPosition: {}".format(position)) | |
575 | + # print("Scroll position: {}".format(coord)) | |
576 | + # print("Slice actor bounds: {}".format(self.slice_data.actor.GetBounds())) | |
577 | + # print("Scroll from int of position: {}\n".format([round(s) for s in position])) | |
573 | 578 | |
574 | - self.cross.SetFocalPoint((ux, uy, uz)) | |
579 | + # this call did not affect the working code | |
580 | + # self.cross.SetFocalPoint(coord) | |
581 | + | |
582 | + # update the image slices in all three orientations | |
575 | 583 | self.ScrollSlice(coord) |
576 | 584 | |
577 | 585 | def SetCrossFocalPoint(self, position): |
578 | - self.cross.SetFocalPoint(position) | |
586 | + """ | |
587 | + Sets the cross focal point for all slice panels (axial, coronal, sagittal). This function is also called via | |
588 | + pubsub messaging and may receive a list of 6 coordinates. Thus, limiting the number of list elements in the | |
589 | + SetFocalPoint call is required. | |
590 | + :param position: list of 6 coordinates in vtk world coordinate system wx, wy, wz | |
591 | + """ | |
592 | + self.cross.SetFocalPoint(position[:3]) | |
579 | 593 | |
580 | 594 | def ScrollSlice(self, coord): |
581 | 595 | if self.orientation == "AXIAL": |
... | ... | @@ -818,12 +832,12 @@ class Viewer(wx.Panel): |
818 | 832 | Publisher.subscribe(self.ChangeSliceNumber, |
819 | 833 | ('Set scroll position', |
820 | 834 | self.orientation)) |
821 | - Publisher.subscribe(self.__update_cross_position, | |
822 | - 'Update cross position') | |
823 | - Publisher.subscribe(self.__update_cross_position, | |
824 | - 'Update cross position %s' % self.orientation) | |
835 | + # Publisher.subscribe(self.__update_cross_position, | |
836 | + # 'Update cross position') | |
837 | + # Publisher.subscribe(self.__update_cross_position, | |
838 | + # 'Update cross position %s' % self.orientation) | |
825 | 839 | Publisher.subscribe(self.SetCrossFocalPoint, 'Set cross focal point') |
826 | - # Publisher.subscribe(self.UpdateSlicesNavigation, | |
840 | + # Publisher.subscribe(self.UpdateSlicesPosition, | |
827 | 841 | # 'Co-registered points') |
828 | 842 | ### |
829 | 843 | # Publisher.subscribe(self.ChangeBrushColour, |
... | ... | @@ -1141,9 +1155,9 @@ class Viewer(wx.Panel): |
1141 | 1155 | |
1142 | 1156 | renderer.AddActor(cross_actor) |
1143 | 1157 | |
1144 | - def __update_cross_position(self, arg, position): | |
1145 | - # self.cross.SetFocalPoint(position[:3]) | |
1146 | - self.UpdateSlicesNavigation(None, position) | |
1158 | + # def __update_cross_position(self, arg, position): | |
1159 | + # # self.cross.SetFocalPoint(position[:3]) | |
1160 | + # self.UpdateSlicesPosition(None, position) | |
1147 | 1161 | |
1148 | 1162 | def _set_cross_visibility(self, visibility): |
1149 | 1163 | self.cross_actor.SetVisibility(visibility) |
... | ... | @@ -1300,12 +1314,16 @@ class Viewer(wx.Panel): |
1300 | 1314 | if update3D: |
1301 | 1315 | self.UpdateSlice3D(pos) |
1302 | 1316 | |
1317 | + # This Render needs to come before the self.style.OnScrollBar, otherwise the GetFocalPoint will sometimes | |
1318 | + # provide the non-updated coordinate and the cross focal point will lag one pixel behind the actual | |
1319 | + # scroll position | |
1320 | + self.interactor.Render() | |
1321 | + | |
1303 | 1322 | try: |
1304 | 1323 | self.style.OnScrollBar() |
1305 | 1324 | except AttributeError: |
1306 | 1325 | print("Do not have OnScrollBar") |
1307 | 1326 | |
1308 | - self.interactor.Render() | |
1309 | 1327 | if evt: |
1310 | 1328 | if self._flush_buffer: |
1311 | 1329 | self.slice_.apply_slice_buffer_to_mask(self.orientation) | ... | ... |
invesalius/data/viewer_volume.py
... | ... | @@ -270,9 +270,9 @@ class Viewer(wx.Panel): |
270 | 270 | |
271 | 271 | Publisher.subscribe(self.RemoveVolume, 'Remove Volume') |
272 | 272 | |
273 | - Publisher.subscribe(self.UpdateCameraBallPosition, | |
274 | - 'Update cross position') | |
275 | - Publisher.subscribe(self.SetCrossFocalPoint, 'Set cross focal point') | |
273 | + # Publisher.subscribe(self.UpdateCameraBallPosition, | |
274 | + # 'Update cross position') | |
275 | + Publisher.subscribe(self.UpdateCameraBallPosition, 'Set cross focal point') | |
276 | 276 | Publisher.subscribe(self._check_ball_reference, 'Enable style') |
277 | 277 | Publisher.subscribe(self._uncheck_ball_reference, 'Disable style') |
278 | 278 | |
... | ... | @@ -1191,10 +1191,10 @@ class Viewer(wx.Panel): |
1191 | 1191 | |
1192 | 1192 | self.ren.AddActor(self.ball_actor) |
1193 | 1193 | |
1194 | - def SetCrossFocalPoint(self, position): | |
1195 | - self.UpdateCameraBallPosition(None, position) | |
1194 | + # def SetCrossFocalPoint(self, position): | |
1195 | + # self.UpdateCameraBallPosition(None, position) | |
1196 | 1196 | |
1197 | - def UpdateCameraBallPosition(self, arg, position): | |
1197 | + def UpdateCameraBallPosition(self, position): | |
1198 | 1198 | coord_flip = list(position[:3]) |
1199 | 1199 | coord_flip[1] = -coord_flip[1] |
1200 | 1200 | self.ball_actor.SetPosition(coord_flip) | ... | ... |
invesalius/gui/task_navigator.py
... | ... | @@ -446,7 +446,7 @@ class NeuronavigationPanel(wx.Panel): |
446 | 446 | Publisher.subscribe(self.LoadImageFiducials, 'Load image fiducials') |
447 | 447 | Publisher.subscribe(self.UpdateTriggerState, 'Update trigger state') |
448 | 448 | Publisher.subscribe(self.UpdateTrackObjectState, 'Update track object state') |
449 | - Publisher.subscribe(self.UpdateImageCoordinates, 'Update cross position') | |
449 | + Publisher.subscribe(self.UpdateImageCoordinates, 'Set cross focal point') | |
450 | 450 | Publisher.subscribe(self.OnDisconnectTracker, 'Disconnect tracker') |
451 | 451 | Publisher.subscribe(self.UpdateObjectRegistration, 'Update object registration') |
452 | 452 | Publisher.subscribe(self.OnCloseProject, 'Close project data') |
... | ... | @@ -506,7 +506,7 @@ class NeuronavigationPanel(wx.Panel): |
506 | 506 | def EnableACT(self, data): |
507 | 507 | self.enable_act = data |
508 | 508 | |
509 | - def UpdateImageCoordinates(self, arg, position): | |
509 | + def UpdateImageCoordinates(self, position): | |
510 | 510 | # TODO: Change from world coordinates to matrix coordinates. They are better for multi software communication. |
511 | 511 | self.current_coord = position |
512 | 512 | for m in [0, 1, 2]: |
... | ... | @@ -1213,15 +1213,15 @@ class MarkersPanel(wx.Panel): |
1213 | 1213 | |
1214 | 1214 | def __bind_events(self): |
1215 | 1215 | # Publisher.subscribe(self.UpdateCurrentCoord, 'Co-registered points') |
1216 | - Publisher.subscribe(self.UpdateCurrentCoord, 'Update cross position') | |
1216 | + Publisher.subscribe(self.UpdateCurrentCoord, 'Set cross focal point') | |
1217 | 1217 | Publisher.subscribe(self.OnDeleteSingleMarker, 'Delete fiducial marker') |
1218 | 1218 | Publisher.subscribe(self.OnDeleteAllMarkers, 'Delete all markers') |
1219 | 1219 | Publisher.subscribe(self.OnCreateMarker, 'Create marker') |
1220 | 1220 | Publisher.subscribe(self.UpdateNavigationStatus, 'Navigation status') |
1221 | 1221 | Publisher.subscribe(self.UpdateSeedCoordinates, 'Update tracts') |
1222 | 1222 | |
1223 | - def UpdateCurrentCoord(self, arg, position): | |
1224 | - self.current_coord = position[:] | |
1223 | + def UpdateCurrentCoord(self, position): | |
1224 | + self.current_coord = position | |
1225 | 1225 | #self.current_angle = pubsub_evt.data[1][3:] |
1226 | 1226 | |
1227 | 1227 | def UpdateNavigationStatus(self, nav_status, vis_status): |
... | ... | @@ -1747,7 +1747,7 @@ class TractographyPanel(wx.Panel): |
1747 | 1747 | |
1748 | 1748 | def __bind_events(self): |
1749 | 1749 | Publisher.subscribe(self.OnCloseProject, 'Close project data') |
1750 | - Publisher.subscribe(self.OnUpdateTracts, 'Update cross position') | |
1750 | + Publisher.subscribe(self.OnUpdateTracts, 'Set cross focal point') | |
1751 | 1751 | Publisher.subscribe(self.UpdateNavigationStatus, 'Navigation status') |
1752 | 1752 | |
1753 | 1753 | def OnSelectPeelingDepth(self, evt, ctrl): |
... | ... | @@ -1941,7 +1941,7 @@ class TractographyPanel(wx.Panel): |
1941 | 1941 | wx.MessageBox(_("File incompatible, using default configuration."), _("InVesalius 3")) |
1942 | 1942 | Publisher.sendMessage('Update status text in GUI', label="") |
1943 | 1943 | |
1944 | - def OnUpdateTracts(self, arg, position): | |
1944 | + def OnUpdateTracts(self, position): | |
1945 | 1945 | """ |
1946 | 1946 | Minimal working version of tract computation. Updates when cross sends Pubsub message to update. |
1947 | 1947 | Position refers to the coordinates in InVesalius 2D space. To represent the same coordinates in the 3D space, |
... | ... | @@ -2055,7 +2055,8 @@ class UpdateNavigationScene(threading.Thread): |
2055 | 2055 | |
2056 | 2056 | #TODO: If using the view_tracts substitute the raw coord from the offset coordinate, so the user |
2057 | 2057 | # see the red cross in the position of the offset marker |
2058 | - wx.CallAfter(Publisher.sendMessage, 'Update cross position', arg=m_img, position=coord) | |
2058 | + wx.CallAfter(Publisher.sendMessage, 'Set cross focal point', position=coord) | |
2059 | + wx.CallAfter(Publisher.sendMessage, 'Update slice viewer') | |
2059 | 2060 | |
2060 | 2061 | if view_obj: |
2061 | 2062 | wx.CallAfter(Publisher.sendMessage, 'Update object matrix', m_img=m_img, coord=coord) | ... | ... |