From 9de6858764937e33dd2090be46587d1b9659d8b2 Mon Sep 17 00:00:00 2001 From: sotodela <60348665+sotodela@users.noreply.github.com> Date: Tue, 10 Aug 2021 04:51:34 +0300 Subject: [PATCH] Coil projection on peel (#308) --- invesalius/constants.py | 1 + invesalius/data/brainmesh_handler.py | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------ invesalius/data/viewer_volume.py | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- invesalius/gui/task_navigator.py | 33 ++++++++++++++++++++++++--------- 4 files changed, 269 insertions(+), 47 deletions(-) diff --git a/invesalius/constants.py b/invesalius/constants.py index fd6afb3..895a8c0 100644 --- a/invesalius/constants.py +++ b/invesalius/constants.py @@ -781,6 +781,7 @@ ARROW_UPPER_LIMIT = 15 COIL_ANGLES_THRESHOLD = 3 COIL_COORD_THRESHOLD = 3 TIMESTAMP = 2.0 +COIL_ANGLE_ARROW_PROJECTION_THRESHOLD = 10 CAM_MODE = True diff --git a/invesalius/data/brainmesh_handler.py b/invesalius/data/brainmesh_handler.py index 127963e..172b3c3 100644 --- a/invesalius/data/brainmesh_handler.py +++ b/invesalius/data/brainmesh_handler.py @@ -8,34 +8,33 @@ import pyvista class Brain: def __init__(self, img_path, mask_path, n_peels, affine_vtk): + # Create arrays to access the peel data and peel Actors self.peel = [] self.peelActors = [] - + # Read the image T1_reader = vtk.vtkNIFTIImageReader() T1_reader.SetFileName(img_path) T1_reader.Update() - - # self.refImage = vtk.vtkImageData() + # Image self.refImage = T1_reader.GetOutput() - + # Read the mask mask_reader = vtk.vtkNIFTIImageReader() mask_reader.SetFileName(mask_path) mask_reader.Update() - + # Use the mask to create isosurface mc = vtk.vtkContourFilter() mc.SetInputConnection(mask_reader.GetOutputPort()) mc.SetValue(0, 1) mc.Update() - refSurface = vtk.vtkPolyData() + # Mask isosurface refSurface = mc.GetOutput() - - tmpPeel = vtk.vtkPolyData() + # Create a uniformly meshed surface tmpPeel = downsample(refSurface) - - mask_sFormMatrix = vtk.vtkMatrix4x4() + # Standard space coordinates mask_sFormMatrix = mask_reader.GetSFormMatrix() + # Apply coordinate transform to the meshed mask mask_ijk2xyz = vtk.vtkTransform() mask_ijk2xyz.SetMatrix(mask_sFormMatrix) @@ -44,17 +43,21 @@ class Brain: mask_ijk2xyz_filter.SetTransform(mask_ijk2xyz) mask_ijk2xyz_filter.Update() + # Smooth the mesh tmpPeel = smooth(mask_ijk2xyz_filter.GetOutput()) + # Configure calculation of normals tmpPeel = fixMesh(tmpPeel) + # Remove duplicate points etc tmpPeel = cleanMesh(tmpPeel) + # Generate triangles tmpPeel = upsample(tmpPeel) + tmpPeel = smooth(tmpPeel) tmpPeel = fixMesh(tmpPeel) tmpPeel = cleanMesh(tmpPeel) - # sFormMatrix = vtk.vtkMatrix4x4() + # Scanner coordinates from image qFormMatrix = T1_reader.GetQFormMatrix() - # sFormMatrix = T1_reader.GetSFormMatrix() refImageSpace2_xyz_transform = vtk.vtkTransform() refImageSpace2_xyz_transform.SetMatrix(qFormMatrix) @@ -69,29 +72,32 @@ class Brain: self.xyz2_refImageSpace = vtk.vtkTransformPolyDataFilter() self.xyz2_refImageSpace.SetTransform(xyz2_refImageSpace_transform) - # self.currentPeel = vtk.vtkPolyData() - self.currentPeel = tmpPeel + currentPeel = tmpPeel self.currentPeelNo = 0 - self.mapImageOnCurrentPeel() + currentPeel= self.MapImageOnCurrentPeel(currentPeel) newPeel = vtk.vtkPolyData() - newPeel.DeepCopy(self.currentPeel) + newPeel.DeepCopy(currentPeel) + newPeel.DeepCopy(currentPeel) + self.peel_normals = vtk.vtkFloatArray() + self.peel_centers = vtk.vtkFloatArray() self.peel.append(newPeel) self.currentPeelActor = vtk.vtkActor() self.currentPeelActor.SetUserMatrix(affine_vtk) - self.getCurrentPeelActor() + self.GetCurrentPeelActor(currentPeel) self.peelActors.append(self.currentPeelActor) - + # locator will later find the triangle on the peel surface where the coil's normal intersect + self.locator = vtk.vtkCellLocator() self.numberOfPeels = n_peels - self.peelDown() + self.PeelDown(currentPeel) - def get_actor(self, n): - return self.getPeelActor(n) + def get_actor(self, n, affine_vtk): + return self.GetPeelActor(n, affine_vtk) - def sliceDown(self): + def SliceDown(self, currentPeel): # Warp using the normals warp = vtk.vtkWarpVector() - warp.SetInputData(fixMesh(downsample(self.currentPeel))) # fixMesh here updates normals needed for warping + warp.SetInputData(fixMesh(downsample(currentPeel))) # fixMesh here updates normals needed for warping warp.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject().FIELD_ASSOCIATION_POINTS, vtk.vtkDataSetAttributes().NORMALS) warp.SetScaleFactor(-1) @@ -103,8 +109,8 @@ class Brain: out = fixMesh(out) out = cleanMesh(out) - self.currentPeel = out - + currentPeel = out + return currentPeel # def sliceUp(self): # # Warp using the normals # warp = vtk.vtkWarpVector() @@ -122,8 +128,8 @@ class Brain: # # currentPeel = out - def mapImageOnCurrentPeel(self): - self.xyz2_refImageSpace.SetInputData(self.currentPeel) + def MapImageOnCurrentPeel(self, currentPeel): + self.xyz2_refImageSpace.SetInputData(currentPeel) self.xyz2_refImageSpace.Update() probe = vtk.vtkProbeFilter() @@ -134,25 +140,36 @@ class Brain: self.refImageSpace2_xyz.SetInputData(probe.GetOutput()) self.refImageSpace2_xyz.Update() - self.currentPeel = self.refImageSpace2_xyz.GetOutput() + currentPeel = self.refImageSpace2_xyz.GetOutput() + return currentPeel - def peelDown(self): + def PeelDown(self, currentPeel): for i in range(0, self.numberOfPeels): - self.sliceDown() - self.mapImageOnCurrentPeel() + currentPeel = self.SliceDown(currentPeel) + currentPeel = self.MapImageOnCurrentPeel(currentPeel) newPeel = vtk.vtkPolyData() - newPeel.DeepCopy(self.currentPeel) + newPeel.DeepCopy(currentPeel) self.peel.append(newPeel) - # getCurrentPeelActor() + # GetCurrentPeelActor() # newPeelActor = vtk.vtkActor() # newPeelActor = currentPeelActor # peelActors.push_back(newPeelActor) self.currentPeelNo += 1 - def getPeelActor(self, p): + def TransformPeelPosition(self, p, affine_vtk): + peel_transform = vtk.vtkTransform() + peel_transform.SetMatrix(affine_vtk) + refpeelspace = vtk.vtkTransformPolyDataFilter() + refpeelspace.SetInputData(self.peel[p]) + refpeelspace.SetTransform(peel_transform) + refpeelspace.Update() + currentPeel = refpeelspace.GetOutput() + return currentPeel + + def GetPeelActor(self, p, affine_vtk): colors = vtk.vtkNamedColors() # Create the color map colorLookupTable = vtk.vtkLookupTable() @@ -179,9 +196,16 @@ class Brain: # Set actor self.currentPeelActor.SetMapper(mapper) + currentPeel = self.TransformPeelPosition(p, affine_vtk) + + self.locator.SetDataSet(currentPeel) + self.locator.BuildLocator() + self.GetCenters(currentPeel) + self.GetNormals(currentPeel) + return self.currentPeelActor - def getCurrentPeelActor(self): + def GetCurrentPeelActor(self, currentPeel): colors = vtk.vtkNamedColors() # Create the color map @@ -198,7 +222,7 @@ class Brain: # Set mapper auto mapper = vtk.vtkOpenGLPolyDataMapper() - mapper.SetInputData(self.currentPeel) + mapper.SetInputData(currentPeel) # mapper.SetScalarRange(0, 1000) # mapper.SetScalarRange(0, 250) mapper.SetScalarRange(0, 200) @@ -213,6 +237,26 @@ class Brain: return self.currentPeelActor + def GetCenters(self, currentPeel): + # Compute centers of triangles + centerComputer = vtk.vtkCellCenters() # This computes centers of the triangles on the peel + centerComputer.SetInputData(currentPeel) + centerComputer.Update() + # This stores the centers for easy access + peel_centers = centerComputer.GetOutput() + self.peel_centers = peel_centers + + def GetNormals(self, currentPeel): + # Compute normals of triangles + normalComputer = vtk.vtkPolyDataNormals() # This computes normals of the triangles on the peel + normalComputer.SetInputData(currentPeel) + normalComputer.ComputePointNormalsOff() + normalComputer.ComputeCellNormalsOn() + normalComputer.Update() + # This converts to the normals to an array for easy access + peel_normals = normalComputer.GetOutput().GetCellData().GetNormals() + self.peel_normals = peel_normals + def cleanMesh(inp): cleaned = vtk.vtkCleanPolyData() diff --git a/invesalius/data/viewer_volume.py b/invesalius/data/viewer_volume.py index 3d69755..a987368 100644 --- a/invesalius/data/viewer_volume.py +++ b/invesalius/data/viewer_volume.py @@ -173,6 +173,8 @@ class Viewer(wx.Panel): self.y_actor = None self.z_actor = None self.mark_actor = None + self.obj_projection_arrow_actor = None + self.object_orientation_disk_actor = None self._mode_cross = False self._to_show_ball = 0 @@ -192,6 +194,7 @@ class Viewer(wx.Panel): self.polydata = None self.anglethreshold = const.COIL_ANGLES_THRESHOLD self.distthreshold = const.COIL_COORD_THRESHOLD + self.angle_arrow_projection_threshold = const.COIL_ANGLE_ARROW_PROJECTION_THRESHOLD self.actor_tracts = None self.actor_peel = None @@ -293,6 +296,7 @@ class Viewer(wx.Panel): # Related to object tracking during neuronavigation Publisher.subscribe(self.OnNavigationStatus, 'Navigation status') Publisher.subscribe(self.UpdateObjectOrientation, 'Update object matrix') + Publisher.subscribe(self.UpdateObjectArrowOrientation, 'Update object arrow matrix') Publisher.subscribe(self.UpdateTrackObjectState, 'Update track object state') Publisher.subscribe(self.UpdateShowObjectState, 'Update show object state') @@ -310,6 +314,8 @@ class Viewer(wx.Panel): Publisher.subscribe(self.UpdateMarkerOffsetState, 'Update marker offset state') Publisher.subscribe(self.UpdateMarkerOffsetPosition, 'Update marker offset') Publisher.subscribe(self.AddPeeledSurface, 'Update peel') + Publisher.subscribe(self.GetPeelCenters, 'Get peel centers and normals') + Publisher.subscribe(self.Initlocator_viewer, 'Get init locator') Publisher.subscribe(self.load_mask_preview, 'Load mask preview') Publisher.subscribe(self.remove_mask_preview, 'Remove mask preview') @@ -1320,11 +1326,18 @@ class Viewer(wx.Panel): self.y_actor = self.add_line([0., 0., 0.], [0., 1., 0.], color=[.0, 1.0, .0]) self.z_actor = self.add_line([0., 0., 0.], [0., 0., 1.], color=[1.0, .0, .0]) + self.obj_projection_arrow_actor = self.Add_ObjectArrow([0., 0., 0.], [0., 0., 0.], vtk_colors.GetColor3d('Red'), + 15) + self.object_orientation_disk_actor = self.Add_Object_Orientation_Disk([0., 0., 0.], [0., 0., 0.], + vtk_colors.GetColor3d('Red')) + #self.obj_projection_arrow_actor.SetVisibility(False) + #self.object_orientation_disk_actor.SetVisibility(False) self.ren.AddActor(self.obj_actor) self.ren.AddActor(self.x_actor) self.ren.AddActor(self.y_actor) self.ren.AddActor(self.z_actor) - + #self.ren.AddActor(self.obj_projection_arrow_actor) + #self.ren.AddActor(self.object_orientation_disk_actor) # self.obj_axes = vtk.vtkAxesActor() # self.obj_axes.SetShaftTypeToCylinder() # self.obj_axes.SetXAxisLabelText("x") @@ -1334,6 +1347,63 @@ class Viewer(wx.Panel): # self.ren.AddActor(self.obj_axes) + def Add_Object_Orientation_Disk(self, position, orientation, color=[0.0, 0.0, 1.0]): + # Create a disk to show target + disk = vtk.vtkDiskSource() + disk.SetInnerRadius(5) + disk.SetOuterRadius(15) + disk.SetRadialResolution(100) + disk.SetCircumferentialResolution(100) + disk.Update() + + disk_mapper = vtk.vtkPolyDataMapper() + disk_mapper.SetInputData(disk.GetOutput()) + disk_actor = vtk.vtkActor() + disk_actor.SetMapper(disk_mapper) + disk_actor.GetProperty().SetColor(color) + disk_actor.GetProperty().SetOpacity(1) + disk_actor.SetPosition(position) + disk_actor.SetOrientation(orientation) + + return disk_actor + + def Add_ObjectArrow(self, direction, orientation, color=[0.0, 0.0, 1.0], size=2): + vtk_colors = vtk.vtkNamedColors() + + arrow = vtk.vtkArrowSource() + + mapper = vtk.vtkPolyDataMapper() + mapper.SetInputConnection(arrow.GetOutputPort()) + + actor = vtk.vtkActor() + actor.SetMapper(mapper) + actor.GetProperty().SetColor(color) + actor.GetProperty().SetLineWidth(5) + actor.AddPosition(0, 0, 0) + actor.SetScale(size) + actor.SetPosition(direction) + actor.SetOrientation(orientation) + + return actor + + def ObjectArrowLocation(self, m_img, coord): + # m_img[:3, 0] is from posterior to anterior direction of the coil + # m_img[:3, 1] is from left to right direction of the coil + # m_img[:3, 2] is from bottom to up direction of the coil + vec_length = 70 + m_img_flip = m_img.copy() + m_img_flip[1, -1] = -m_img_flip[1, -1] + p1 = m_img_flip[:-1, -1] # coil center + coil_dir = m_img_flip[:-1, 0] + coil_face = m_img_flip[:-1, 1] + + coil_norm = np.cross(coil_dir, coil_face) + p2_norm = p1 - vec_length * coil_norm # point normal to the coil away from the center by vec_length + coil_dir = np.array([coord[3], coord[4], coord[5]]) + + return coil_dir, p2_norm, coil_norm, p1 + + def add_line(self, p1, p2, color=[0.0, 0.0, 1.0]): line = vtk.vtkLineSource() line.SetPoint1(p1) @@ -1357,6 +1427,80 @@ class Viewer(wx.Panel): self.actor_peel = actor self.Refresh() + def GetPeelCenters(self, centers, normals): + self.peel_centers = centers + self.peel_normals = normals + + self.Refresh() + + def Initlocator_viewer(self, locator): + self.locator = locator + self.Refresh() + + def GetCellIntersection(self, p1, p2, coil_norm, coil_dir): + + vtk_colors = vtk.vtkNamedColors() + # This find store the triangles that intersect the coil's normal + intersectingCellIds = vtk.vtkIdList() + + #for debugging + self.x_actor = self.add_line(p1,p2,vtk_colors.GetColor3d('Blue')) + #self.ren.AddActor(self.x_actor) # remove comment for testing + + self.locator.FindCellsAlongLine(p1, p2, .001, intersectingCellIds) + + closestDist = 50 + + #if find intersection , calculate angle and add actors + if intersectingCellIds.GetNumberOfIds() != 0: + for i in range(intersectingCellIds.GetNumberOfIds()): + cellId = intersectingCellIds.GetId(i) + point = np.array(self.peel_centers.GetPoint(cellId)) + distance = np.linalg.norm(point - p1) + + #print('distance:', distance, point - p1) + self.ren.RemoveActor(self.y_actor) + + if distance < closestDist: + closestDist = distance + closestPoint = point + pointnormal = np.array(self.peel_normals.GetTuple(cellId)) + angle = np.rad2deg(np.arccos(np.dot(pointnormal, coil_norm))) + #print('the angle:', angle) + + #for debbuging + self.y_actor = self.add_line(closestPoint, closestPoint + 75 * pointnormal, + vtk_colors.GetColor3d('Yellow')) + + #self.ren.AddActor(self.y_actor)# remove comment for testing + + + self.ren.AddActor(self.obj_projection_arrow_actor) + self.ren.AddActor(self.object_orientation_disk_actor) + + self.obj_projection_arrow_actor.SetPosition(closestPoint) + self.obj_projection_arrow_actor.SetOrientation(coil_dir) + + self.object_orientation_disk_actor.SetPosition(closestPoint) + self.object_orientation_disk_actor.SetOrientation(coil_dir) + + # change color of arrow and disk according to angle + if angle < self.angle_arrow_projection_threshold: + self.object_orientation_disk_actor.GetProperty().SetColor(vtk_colors.GetColor3d('Green')) + self.obj_projection_arrow_actor.GetProperty().SetColor(vtk_colors.GetColor3d('Green')) + else: + self.object_orientation_disk_actor.GetProperty().SetColor(vtk_colors.GetColor3d('indian_red')) + self.obj_projection_arrow_actor.GetProperty().SetColor(vtk_colors.GetColor3d('indian_red')) + else: + self.ren.RemoveActor(self.y_actor) + + else: + self.ren.RemoveActor(self.obj_projection_arrow_actor) + self.ren.RemoveActor(self.object_orientation_disk_actor) + self.ren.RemoveActor(self.x_actor) + #self.ren.RemoveActor(self.y_actor) + self.Refresh() + def OnNavigationStatus(self, nav_status, vis_status): self.nav_status = nav_status self.tracts_status = vis_status[1] @@ -1368,7 +1512,8 @@ class Viewer(wx.Panel): self.x_actor.SetVisibility(self.obj_state) self.y_actor.SetVisibility(self.obj_state) self.z_actor.SetVisibility(self.obj_state) - + #self.object_orientation_disk_actor.SetVisibility(self.obj_state) + #self.obj_projection_arrow_actor.SetVisibility(self.obj_state) self.Refresh() def UpdateSeedOffset(self, data): @@ -1419,6 +1564,19 @@ class Viewer(wx.Panel): self.Refresh() + + def UpdateObjectArrowOrientation(self, m_img, coord, flag): + + [coil_dir, norm, coil_norm, p1 ]= self.ObjectArrowLocation(m_img,coord) + + if flag: + self.ren.RemoveActor(self.x_actor) + #self.ren.RemoveActor(self.y_actor) + self.ren.RemoveActor(self.obj_projection_arrow_actor) + self.ren.RemoveActor(self.object_orientation_disk_actor) + self.GetCellIntersection(p1, norm, coil_norm, coil_dir) + self.Refresh() + def UpdateTrackObjectState(self, evt=None, flag=None, obj_name=None, polydata=None): if flag: self.obj_name = obj_name @@ -1432,11 +1590,15 @@ class Viewer(wx.Panel): self.ren.RemoveActor(self.y_actor) self.ren.RemoveActor(self.z_actor) self.ren.RemoveActor(self.mark_actor) + self.ren.RemoveActor(self.obj_projection_arrow_actor) + self.ren.RemoveActor(self.object_orientation_disk_actor) self.obj_actor = None self.x_actor = None self.y_actor = None self.z_actor = None self.mark_actor = None + self.obj_projection_arrow_actor = None + self.object_orientation_disk_actor=None self.Refresh() def UpdateShowObjectState(self, state): diff --git a/invesalius/gui/task_navigator.py b/invesalius/gui/task_navigator.py index 81281b6..b1d75b6 100644 --- a/invesalius/gui/task_navigator.py +++ b/invesalius/gui/task_navigator.py @@ -326,6 +326,7 @@ class Navigation(): self.trekker = None self.n_threads = None self.view_tracts = False + self.peel_loaded = False self.enable_act = False self.act_data = None self.n_tracts = const.N_TRACTS @@ -363,7 +364,7 @@ class Navigation(): if self.event.is_set(): self.event.clear() - vis_components = [self.trigger_state, self.view_tracts] + vis_components = [self.trigger_state, self.view_tracts, self.peel_loaded] vis_queues = [self.coord_queue, self.trigger_queue, self.tracts_queue, self.icp_queue] Publisher.sendMessage("Navigation status", nav_status=True, vis_status=vis_components) @@ -458,7 +459,7 @@ class Navigation(): self.tracts_queue.clear() self.tracts_queue.join() - vis_components = [self.trigger_state, self.view_tracts] + vis_components = [self.trigger_state, self.view_tracts, self.peel_loaded] Publisher.sendMessage("Navigation status", nav_status=False, vis_status=vis_components) @@ -870,6 +871,7 @@ class NeuronavigationPanel(wx.Panel): Publisher.subscribe(self.UpdateSleep, 'Update sleep') Publisher.subscribe(self.UpdateNumberThreads, 'Update number of threads') Publisher.subscribe(self.UpdateTractsVisualization, 'Update tracts visualization') + Publisher.subscribe(self.UpdatePeelVisualization, 'Update peel visualization') Publisher.subscribe(self.EnableACT, 'Enable ACT') Publisher.subscribe(self.UpdateACTData, 'Update ACT data') Publisher.subscribe(self.UpdateNavigationStatus, 'Navigation status') @@ -918,6 +920,10 @@ class NeuronavigationPanel(wx.Panel): self.ResetICP() self.tracker.UpdateUI(self.select_tracker_elem, self.numctrls_coord[3:6], self.txtctrl_fre) + + def UpdatePeelVisualization(self, data): + self.navigation.peel_loaded = data + def UpdateNavigationStatus(self, nav_status, vis_status): self.nav_status = nav_status if nav_status and self.icp.m_icp is not None: @@ -1044,6 +1050,7 @@ class NeuronavigationPanel(wx.Panel): self.navigation.UpdateFiducialRegistrationError(self.tracker) fre, fre_ok = self.navigation.GetFiducialRegistrationError(self.icp) + self.txtctrl_fre.SetValue(str(round(fre, 2))) if fre_ok: self.txtctrl_fre.SetBackgroundColour('GREEN') @@ -1862,7 +1869,7 @@ class TractographyPanel(wx.Panel): self.tracts_run = None self.trekker_cfg = const.TREKKER_CONFIG self.nav_status = False - + self.peel_loaded = False self.SetAutoLayout(1) self.__bind_events() @@ -2040,9 +2047,12 @@ class TractographyPanel(wx.Panel): def OnSelectPeelingDepth(self, evt, ctrl): self.peel_depth = ctrl.GetValue() if self.checkpeeling.GetValue(): - actor = self.brain_peel.get_actor(self.peel_depth) + actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk) Publisher.sendMessage('Update peel', flag=True, actor=actor) - + Publisher.sendMessage('Get peel centers and normals', centers=self.brain_peel.peel_centers, + normals=self.brain_peel.peel_normals) + Publisher.sendMessage('Get init locator', locator=self.brain_peel.locator) + self.peel_loaded = True def OnSelectNumTracts(self, evt, ctrl): self.n_tracts = ctrl.GetValue() # self.tract.n_tracts = ctrl.GetValue() @@ -2070,7 +2080,7 @@ class TractographyPanel(wx.Panel): def OnShowPeeling(self, evt, ctrl): # self.view_peeling = ctrl.GetValue() if ctrl.GetValue(): - actor = self.brain_peel.get_actor(self.peel_depth) + actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk) else: actor = None Publisher.sendMessage('Update peel', flag=ctrl.GetValue(), actor=actor) @@ -2114,13 +2124,18 @@ class TractographyPanel(wx.Panel): try: self.brain_peel = brain.Brain(img_path, mask_path, self.n_peels, self.affine_vtk) - self.brain_actor = self.brain_peel.get_actor(self.peel_depth) + self.brain_actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk) self.brain_actor.GetProperty().SetOpacity(self.brain_opacity) Publisher.sendMessage('Update peel', flag=True, actor=self.brain_actor) + Publisher.sendMessage('Get peel centers and normals', centers=self.brain_peel.peel_centers, + normals=self.brain_peel.peel_normals) + Publisher.sendMessage('Get init locator', locator=self.brain_peel.locator) self.checkpeeling.Enable(1) self.checkpeeling.SetValue(True) self.spin_opacity.Enable(1) Publisher.sendMessage('Update status text in GUI', label=_("Brain model loaded")) + self.peel_loaded = True + Publisher.sendMessage('Update peel visualization', data= self.peel_loaded) except: wx.MessageBox(_("Unable to load brain mask."), _("InVesalius 3")) @@ -2308,7 +2323,7 @@ class UpdateNavigationScene(threading.Thread): """ threading.Thread.__init__(self, name='UpdateScene') - self.trigger_state, self.view_tracts = vis_components + self.trigger_state, self.view_tracts, self.peel_loaded = vis_components self.coord_queue, self.trigger_queue, self.tracts_queue, self.icp_queue = vis_queues self.sle = sle self.event = event @@ -2347,7 +2362,7 @@ class UpdateNavigationScene(threading.Thread): if view_obj: wx.CallAfter(Publisher.sendMessage, 'Update object matrix', m_img=m_img, coord=coord) - + wx.CallAfter(Publisher.sendMessage, 'Update object arrow matrix',m_img=m_img, coord=coord, flag= self.peel_loaded) self.coord_queue.task_done() # print('UpdateScene: done {}'.format(count)) # count += 1 -- libgit2 0.21.2