Commit 13163add78ab61b1815767cccdf0887a559ab62e

Authored by Thiago Franco de Moraes
Committed by GitHub
1 parent b2b44bbc
Exists in master

Peel creation using mask and image already loaded (#359)

* Created dialog

* some testings

* Using ww and wl to set mesh colors

* Using ww and wl to set mesh colors

* Not cleaning surface before upsample

* ww and wl -> window_width and window_level

* setting affine_vtk as matrix identity

* Some cleaning and setting specular to 0.25 to make peel brighter

* created an method to create brain peel from mask

* created an method to create brain peel from files

* Starting to give support to peel using files

* Improvements in GUI

* Creating peels from files

* Added nifti wildcard

* checking if torus orientation and arrow project exists before setting visibility

* ADD: Title to the T1 and Mask dialogs for creating peel

* ADD: Last directory to load peel files

* Using image from invesalius project

* FIX: applies vtk affine only for peel from file and decouples self affine variable

Co-authored-by: Victor Hugo Souza <victor.souza@aalto.fi>
Co-authored-by: Renan <renan_hiroshi@hotmail.com>
invesalius/data/brainmesh_handler.py
... ... @@ -2,37 +2,95 @@ import vtk
2 2 import pyacvd
3 3 # import os
4 4 import pyvista
5   -# import numpy as np
  5 +import numpy as np
6 6 # import Trekker
7 7  
  8 +import invesalius.data.slice_ as sl
  9 +from invesalius.data.converters import to_vtk
  10 +
8 11  
9 12 class Brain:
10   - def __init__(self, img_path, mask_path, n_peels, affine_vtk):
  13 + def __init__(self, n_peels, window_width, window_level, affine_vtk=None):
11 14 # Create arrays to access the peel data and peel Actors
12 15 self.peel = []
13 16 self.peelActors = []
14   - # Read the image
15   - T1_reader = vtk.vtkNIFTIImageReader()
16   - T1_reader.SetFileName(img_path)
17   - T1_reader.Update()
  17 + self.window_width = window_width
  18 + self.window_level = window_level
  19 + self.numberOfPeels = n_peels
  20 + self.affine_vtk = affine_vtk
  21 +
  22 + def from_mask(self, mask):
  23 + mask= np.array(mask.matrix[1:, 1:, 1:])
  24 + slic = sl.Slice()
  25 + image = slic.matrix
  26 +
  27 + mask = to_vtk(mask, spacing=slic.spacing)
  28 + image = to_vtk(image, spacing=slic.spacing)
  29 +
  30 + flip = vtk.vtkImageFlip()
  31 + flip.SetInputData(image)
  32 + flip.SetFilteredAxis(1)
  33 + flip.FlipAboutOriginOn()
  34 + flip.ReleaseDataFlagOn()
  35 + flip.Update()
  36 + image = flip.GetOutput()
  37 +
  38 + flip = vtk.vtkImageFlip()
  39 + flip.SetInputData(mask)
  40 + flip.SetFilteredAxis(1)
  41 + flip.FlipAboutOriginOn()
  42 + flip.ReleaseDataFlagOn()
  43 + flip.Update()
  44 + mask = flip.GetOutput()
  45 +
18 46 # Image
19   - self.refImage = T1_reader.GetOutput()
  47 + self.refImage = image
  48 +
  49 + self._do_surface_creation(mask)
  50 +
  51 +
  52 + def from_mask_file(self, mask_path):
  53 + slic = sl.Slice()
  54 + image = slic.matrix
  55 + image = to_vtk(image, spacing=slic.spacing)
  56 +
20 57 # Read the mask
21 58 mask_reader = vtk.vtkNIFTIImageReader()
22 59 mask_reader.SetFileName(mask_path)
23 60 mask_reader.Update()
  61 +
  62 + mask = mask_reader.GetOutput()
  63 +
  64 + mask_sFormMatrix = mask_reader.GetSFormMatrix()
  65 +
  66 + # Image
  67 + self.refImage = image
  68 +
  69 + self._do_surface_creation(mask, mask_sFormMatrix)
  70 +
  71 +
  72 + def _do_surface_creation(self, mask, mask_sFormMatrix=None, qFormMatrix=None):
  73 + if mask_sFormMatrix is None:
  74 + mask_sFormMatrix = vtk.vtkMatrix4x4()
  75 +
  76 + if qFormMatrix is None:
  77 + qFormMatrix = vtk.vtkMatrix4x4()
  78 +
  79 + value = np.mean(mask.GetScalarRange())
  80 +
24 81 # Use the mask to create isosurface
25 82 mc = vtk.vtkContourFilter()
26   - mc.SetInputConnection(mask_reader.GetOutputPort())
27   - mc.SetValue(0, 1)
  83 + mc.SetInputData(mask)
  84 + mc.SetValue(0, value)
  85 + mc.ComputeNormalsOn()
28 86 mc.Update()
29 87  
30 88 # Mask isosurface
31 89 refSurface = mc.GetOutput()
  90 +
32 91 # Create a uniformly meshed surface
33 92 tmpPeel = downsample(refSurface)
34 93 # Standard space coordinates
35   - mask_sFormMatrix = mask_reader.GetSFormMatrix()
36 94  
37 95 # Apply coordinate transform to the meshed mask
38 96 mask_ijk2xyz = vtk.vtkTransform()
... ... @@ -48,7 +106,7 @@ class Brain:
48 106 # Configure calculation of normals
49 107 tmpPeel = fixMesh(tmpPeel)
50 108 # Remove duplicate points etc
51   - tmpPeel = cleanMesh(tmpPeel)
  109 + # tmpPeel = cleanMesh(tmpPeel)
52 110 # Generate triangles
53 111 tmpPeel = upsample(tmpPeel)
54 112  
... ... @@ -56,9 +114,6 @@ class Brain:
56 114 tmpPeel = fixMesh(tmpPeel)
57 115 tmpPeel = cleanMesh(tmpPeel)
58 116  
59   - # Scanner coordinates from image
60   - qFormMatrix = T1_reader.GetQFormMatrix()
61   -
62 117 refImageSpace2_xyz_transform = vtk.vtkTransform()
63 118 refImageSpace2_xyz_transform.SetMatrix(qFormMatrix)
64 119  
... ... @@ -83,16 +138,16 @@ class Brain:
83 138 self.peel_centers = vtk.vtkFloatArray()
84 139 self.peel.append(newPeel)
85 140 self.currentPeelActor = vtk.vtkActor()
86   - self.currentPeelActor.SetUserMatrix(affine_vtk)
  141 + if self.affine_vtk:
  142 + self.currentPeelActor.SetUserMatrix(self.affine_vtk)
87 143 self.GetCurrentPeelActor(currentPeel)
88 144 self.peelActors.append(self.currentPeelActor)
89 145 # locator will later find the triangle on the peel surface where the coil's normal intersect
90 146 self.locator = vtk.vtkCellLocator()
91   - self.numberOfPeels = n_peels
92 147 self.PeelDown(currentPeel)
93 148  
94   - def get_actor(self, n, affine_vtk):
95   - return self.GetPeelActor(n, affine_vtk)
  149 + def get_actor(self, n):
  150 + return self.GetPeelActor(n)
96 151  
97 152 def SliceDown(self, currentPeel):
98 153 # Warp using the normals
... ... @@ -159,9 +214,10 @@ class Brain:
159 214  
160 215 self.currentPeelNo += 1
161 216  
162   - def TransformPeelPosition(self, p, affine_vtk):
  217 + def TransformPeelPosition(self, p):
163 218 peel_transform = vtk.vtkTransform()
164   - peel_transform.SetMatrix(affine_vtk)
  219 + if self.affine_vtk:
  220 + peel_transform.SetMatrix(self.affine_vtk)
165 221 refpeelspace = vtk.vtkTransformPolyDataFilter()
166 222 refpeelspace.SetInputData(self.peel[p])
167 223 refpeelspace.SetTransform(peel_transform)
... ... @@ -169,34 +225,26 @@ class Brain:
169 225 currentPeel = refpeelspace.GetOutput()
170 226 return currentPeel
171 227  
172   - def GetPeelActor(self, p, affine_vtk):
173   - colors = vtk.vtkNamedColors()
174   - # Create the color map
175   - colorLookupTable = vtk.vtkLookupTable()
176   - colorLookupTable.SetNumberOfColors(512)
177   - colorLookupTable.SetSaturationRange(0, 0)
178   - colorLookupTable.SetHueRange(0, 0)
179   - colorLookupTable.SetValueRange(0, 1)
180   - # colorLookupTable.SetTableRange(0, 1000)
181   - # colorLookupTable.SetTableRange(0, 250)
182   - colorLookupTable.SetTableRange(0, 200)
183   - # colorLookupTable.SetTableRange(0, 150)
184   - colorLookupTable.Build()
  228 + def GetPeelActor(self, p):
  229 + lut = vtk.vtkWindowLevelLookupTable()
  230 + lut.SetWindow(self.window_width)
  231 + lut.SetLevel(self.window_level)
  232 + lut.Build()
  233 +
  234 + init = self.window_level - self.window_width / 2
  235 + end = self.window_level + self.window_width / 2
185 236  
186 237 # Set mapper auto
187   - mapper = vtk.vtkOpenGLPolyDataMapper()
  238 + mapper = vtk.vtkPolyDataMapper()
188 239 mapper.SetInputData(self.peel[p])
189   - # mapper.SetScalarRange(0, 1000)
190   - # mapper.SetScalarRange(0, 250)
191   - mapper.SetScalarRange(0, 200)
192   - # mapper.SetScalarRange(0, 150)
193   - mapper.SetLookupTable(colorLookupTable)
  240 + mapper.SetScalarRange(init, end)
  241 + mapper.SetLookupTable(lut)
194 242 mapper.InterpolateScalarsBeforeMappingOn()
195 243  
196 244 # Set actor
197 245 self.currentPeelActor.SetMapper(mapper)
198 246  
199   - currentPeel = self.TransformPeelPosition(p, affine_vtk)
  247 + currentPeel = self.TransformPeelPosition(p)
200 248  
201 249 self.locator.SetDataSet(currentPeel)
202 250 self.locator.BuildLocator()
... ... @@ -206,34 +254,26 @@ class Brain:
206 254 return self.currentPeelActor
207 255  
208 256 def GetCurrentPeelActor(self, currentPeel):
209   - colors = vtk.vtkNamedColors()
210   -
211   - # Create the color map
212   - colorLookupTable = vtk.vtkLookupTable()
213   - colorLookupTable.SetNumberOfColors(512)
214   - colorLookupTable.SetSaturationRange(0, 0)
215   - colorLookupTable.SetHueRange(0, 0)
216   - colorLookupTable.SetValueRange(0, 1)
217   - # colorLookupTable.SetTableRange(0, 1000)
218   - # colorLookupTable.SetTableRange(0, 250)
219   - colorLookupTable.SetTableRange(0, 200)
220   - # colorLookupTable.SetTableRange(0, 150)
221   - colorLookupTable.Build()
  257 + lut = vtk.vtkWindowLevelLookupTable()
  258 + lut.SetWindow(self.window_width)
  259 + lut.SetLevel(self.window_level)
  260 + lut.Build()
  261 +
  262 + init = self.window_level - self.window_width / 2
  263 + end = self.window_level + self.window_width / 2
222 264  
223 265 # Set mapper auto
224   - mapper = vtk.vtkOpenGLPolyDataMapper()
  266 + mapper = vtk.vtkPolyDataMapper()
225 267 mapper.SetInputData(currentPeel)
226   - # mapper.SetScalarRange(0, 1000)
227   - # mapper.SetScalarRange(0, 250)
228   - mapper.SetScalarRange(0, 200)
229   - # mapper.SetScalarRange(0, 150)
230   - mapper.SetLookupTable(colorLookupTable)
  268 + mapper.SetScalarRange(init, end)
  269 + mapper.SetLookupTable(lut)
231 270 mapper.InterpolateScalarsBeforeMappingOn()
232 271  
233 272 # Set actor
234 273 self.currentPeelActor.SetMapper(mapper)
235 274 self.currentPeelActor.GetProperty().SetBackfaceCulling(1)
236 275 self.currentPeelActor.GetProperty().SetOpacity(0.5)
  276 + self.currentPeelActor.GetProperty().SetSpecular(0.25)
237 277  
238 278 return self.currentPeelActor
239 279  
... ...
invesalius/gui/dialogs.py
... ... @@ -46,6 +46,7 @@ except ImportError:
46 46 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
47 47 from wx.lib import masked
48 48 from wx.lib.agw import floatspin
  49 +import wx.lib.filebrowsebutton as filebrowse
49 50 from wx.lib.wordwrap import wordwrap
50 51 from invesalius.pubsub import pub as Publisher
51 52 import csv
... ... @@ -4995,3 +4996,134 @@ class SetSpacingDialog(wx.Dialog):
4995 4996  
4996 4997 def OnCancel(self, evt):
4997 4998 self.EndModal(wx.ID_CANCEL)
  4999 +
  5000 +
  5001 +class PeelsCreationDlg(wx.Dialog):
  5002 + FROM_MASK = 1
  5003 + FROM_FILES = 2
  5004 + def __init__(self, parent, *args, **kwds):
  5005 + wx.Dialog.__init__(self, parent, *args, **kwds)
  5006 +
  5007 + self.mask_path = ''
  5008 + self.method = self.FROM_MASK
  5009 +
  5010 + self._init_gui()
  5011 + self._bind_events_wx()
  5012 + self.get_all_masks()
  5013 +
  5014 + def _init_gui(self):
  5015 + self.SetTitle("dialog")
  5016 +
  5017 + from_mask_stbox = self._from_mask_gui()
  5018 + from_files_stbox = self._from_files_gui()
  5019 +
  5020 + main_sizer = wx.BoxSizer(wx.VERTICAL)
  5021 + main_sizer.Add(from_mask_stbox, 0, wx.EXPAND | wx.ALL, 5)
  5022 + main_sizer.Add(from_files_stbox, 0, wx.EXPAND | wx.ALL, 5)
  5023 +
  5024 + btn_sizer = wx.StdDialogButtonSizer()
  5025 + main_sizer.Add(btn_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4)
  5026 +
  5027 + self.btn_ok = wx.Button(self, wx.ID_OK, "")
  5028 + self.btn_ok.SetDefault()
  5029 + btn_sizer.AddButton(self.btn_ok)
  5030 +
  5031 + self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "")
  5032 + btn_sizer.AddButton(self.btn_cancel)
  5033 +
  5034 + btn_sizer.Realize()
  5035 +
  5036 + self.SetSizer(main_sizer)
  5037 + main_sizer.Fit(self)
  5038 +
  5039 + self.SetAffirmativeId(self.btn_ok.GetId())
  5040 + self.SetEscapeId(self.btn_cancel.GetId())
  5041 +
  5042 + self.Layout()
  5043 +
  5044 + def _from_mask_gui(self):
  5045 + mask_box = wx.StaticBox(self, -1, _("From mask"))
  5046 + from_mask_stbox = wx.StaticBoxSizer(mask_box, wx.VERTICAL)
  5047 +
  5048 + self.cb_masks = wx.ComboBox(self, wx.ID_ANY, choices=[])
  5049 + self.from_mask_rb = wx.RadioButton(self, -1, "", style = wx.RB_GROUP)
  5050 +
  5051 + internal_sizer = wx.BoxSizer(wx.HORIZONTAL)
  5052 + internal_sizer.Add(self.from_mask_rb, 0, wx.ALL | wx.EXPAND, 5)
  5053 + internal_sizer.Add(self.cb_masks, 1, wx.ALL | wx.EXPAND, 5)
  5054 +
  5055 + from_mask_stbox.Add(internal_sizer, 0, wx.EXPAND)
  5056 +
  5057 + return from_mask_stbox
  5058 +
  5059 + def _from_files_gui(self):
  5060 + session = ses.Session()
  5061 + last_directory = session.get('paths', 'last_directory_%d' % const.ID_NIFTI_IMPORT, '')
  5062 +
  5063 + files_box = wx.StaticBox(self, -1, _("From files"))
  5064 + from_files_stbox = wx.StaticBoxSizer(files_box, wx.VERTICAL)
  5065 +
  5066 + self.mask_file_browse = filebrowse.FileBrowseButton(self, -1, labelText=_("Mask file"),
  5067 + fileMask=WILDCARD_NIFTI, dialogTitle=_("Choose Mask file"), startDirectory = last_directory,
  5068 + changeCallback=lambda evt: self._set_files_callback(mask_path=evt.GetString()))
  5069 + self.from_files_rb = wx.RadioButton(self, -1, "")
  5070 +
  5071 + ctrl_sizer = wx.BoxSizer(wx.VERTICAL)
  5072 + ctrl_sizer.Add(self.mask_file_browse, 0, wx.ALL | wx.EXPAND, 5)
  5073 +
  5074 + internal_sizer = wx.BoxSizer(wx.HORIZONTAL)
  5075 + internal_sizer.Add(self.from_files_rb, 0, wx.ALL | wx.EXPAND, 5)
  5076 + internal_sizer.Add(ctrl_sizer, 0, wx.ALL | wx.EXPAND, 5)
  5077 +
  5078 + from_files_stbox.Add(internal_sizer, 0, wx.EXPAND)
  5079 +
  5080 + return from_files_stbox
  5081 +
  5082 + def _bind_events_wx(self):
  5083 + self.from_mask_rb.Bind(wx.EVT_RADIOBUTTON, self.on_select_method)
  5084 + self.from_files_rb.Bind(wx.EVT_RADIOBUTTON, self.on_select_method)
  5085 +
  5086 + def get_all_masks(self):
  5087 + import invesalius.project as prj
  5088 + inv_proj = prj.Project()
  5089 + choices = [i.name for i in inv_proj.mask_dict.values()]
  5090 + try:
  5091 + initial_value = choices[0]
  5092 + enable = True
  5093 + except IndexError:
  5094 + initial_value = ""
  5095 + enable = False
  5096 +
  5097 + self.cb_masks.SetItems(choices)
  5098 + self.cb_masks.SetValue(initial_value)
  5099 + self.btn_ok.Enable(enable)
  5100 +
  5101 + def on_select_method(self, evt):
  5102 + radio_selected = evt.GetEventObject()
  5103 + if radio_selected is self.from_mask_rb:
  5104 + self.method = self.FROM_MASK
  5105 + if self.cb_masks.GetItems():
  5106 + self.btn_ok.Enable(True)
  5107 + else:
  5108 + self.btn_ok.Enable(False)
  5109 + else:
  5110 + self.method = self.FROM_FILES
  5111 + if self._check_if_files_exists():
  5112 + self.btn_ok.Enable(True)
  5113 + else:
  5114 + self.btn_ok.Enable(False)
  5115 +
  5116 + def _set_files_callback(self, mask_path=''):
  5117 + if mask_path:
  5118 + self.mask_path = mask_path
  5119 + if self.method == self.FROM_FILES:
  5120 + if self._check_if_files_exists():
  5121 + self.btn_ok.Enable(True)
  5122 + else:
  5123 + self.btn_ok.Enable(False)
  5124 +
  5125 + def _check_if_files_exists(self):
  5126 + if self.mask_path and os.path.exists(self.mask_path):
  5127 + return True
  5128 + else:
  5129 + return False
... ...
invesalius/gui/task_navigator.py
... ... @@ -31,7 +31,8 @@ try:
31 31 import Trekker
32 32 has_trekker = True
33 33 except ImportError:
34   - has_trekker = False
  34 + has_trekker = True
  35 +
35 36 try:
36 37 import invesalius.data.elfin as elfin
37 38 import invesalius.data.elfin_processing as elfin_process
... ... @@ -40,6 +41,7 @@ except ImportError:
40 41 has_robot = False
41 42  
42 43 import wx
  44 +import vtk
43 45  
44 46 try:
45 47 import wx.lib.agw.foldpanelbar as fpb
... ... @@ -72,6 +74,7 @@ from invesalius.navigation.icp import ICP
72 74 from invesalius.navigation.navigation import Navigation
73 75 from invesalius.navigation.tracker import Tracker
74 76 from invesalius.navigation.robot import Robot
  77 +from invesalius.data.converters import to_vtk
75 78  
76 79 from invesalius.net.neuronavigation_api import NeuronavigationApi
77 80  
... ... @@ -1939,7 +1942,7 @@ class TractographyPanel(wx.Panel):
1939 1942 def OnSelectPeelingDepth(self, evt, ctrl):
1940 1943 self.peel_depth = ctrl.GetValue()
1941 1944 if self.checkpeeling.GetValue():
1942   - actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk)
  1945 + actor = self.brain_peel.get_actor(self.peel_depth)
1943 1946 Publisher.sendMessage('Update peel', flag=True, actor=actor)
1944 1947 Publisher.sendMessage('Get peel centers and normals', centers=self.brain_peel.peel_centers,
1945 1948 normals=self.brain_peel.peel_normals)
... ... @@ -1972,7 +1975,7 @@ class TractographyPanel(wx.Panel):
1972 1975 def OnShowPeeling(self, evt, ctrl):
1973 1976 # self.view_peeling = ctrl.GetValue()
1974 1977 if ctrl.GetValue():
1975   - actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk)
  1978 + actor = self.brain_peel.get_actor(self.peel_depth)
1976 1979 self.peel_loaded = True
1977 1980 Publisher.sendMessage('Update peel visualization', data=self.peel_loaded)
1978 1981 else:
... ... @@ -2002,46 +2005,48 @@ class TractographyPanel(wx.Panel):
2002 2005  
2003 2006 def OnLinkBrain(self, event=None):
2004 2007 Publisher.sendMessage('Begin busy cursor')
2005   - mask_path = dlg.ShowImportOtherFilesDialog(const.ID_NIFTI_IMPORT, _("Import brain mask"))
2006   - img_path = dlg.ShowImportOtherFilesDialog(const.ID_NIFTI_IMPORT, _("Import T1 anatomical image"))
2007   - # data_dir = os.environ.get('OneDrive') + r'\data\dti_navigation\baran\anat_reg_improve_20200609'
2008   - # mask_file = 'Baran_brain_mask.nii'
2009   - # mask_path = os.path.join(data_dir, mask_file)
2010   - # img_file = 'Baran_T1_inFODspace.nii'
2011   - # img_path = os.path.join(data_dir, img_file)
2012   -
2013   - if not self.affine_vtk:
  2008 + inv_proj = prj.Project()
  2009 + peels_dlg = dlg.PeelsCreationDlg(wx.GetApp().GetTopWindow())
  2010 + ret = peels_dlg.ShowModal()
  2011 + method = peels_dlg.method
  2012 + if ret == wx.ID_OK:
2014 2013 slic = sl.Slice()
2015   - prj_data = prj.Project()
2016   - matrix_shape = tuple(prj_data.matrix_shape)
2017   - spacing = tuple(prj_data.spacing)
2018   - img_shift = spacing[1] * (matrix_shape[1] - 1)
2019   - self.affine = slic.affine.copy()
2020   - self.affine[1, -1] -= img_shift
2021   - self.affine_vtk = vtk_utils.numpy_to_vtkMatrix4x4(self.affine)
2022   -
2023   - if mask_path and img_path:
2024   - Publisher.sendMessage('Update status text in GUI', label=_("Busy"))
2025   - try:
2026   - self.brain_peel = brain.Brain(img_path, mask_path, self.n_peels, self.affine_vtk)
2027   - self.brain_actor = self.brain_peel.get_actor(self.peel_depth, self.affine_vtk)
2028   - self.brain_actor.GetProperty().SetOpacity(self.brain_opacity)
2029   -
2030   - self.checkpeeling.Enable(1)
2031   - self.checkpeeling.SetValue(True)
2032   - self.spin_opacity.Enable(1)
2033   - self.peel_loaded = True
2034   -
2035   - Publisher.sendMessage('Update peel', flag=True, actor=self.brain_actor)
2036   - Publisher.sendMessage('Get peel centers and normals', centers=self.brain_peel.peel_centers,
2037   - normals=self.brain_peel.peel_normals)
2038   - Publisher.sendMessage('Get init locator', locator=self.brain_peel.locator)
2039   - Publisher.sendMessage('Update status text in GUI', label=_("Brain model loaded"))
2040   - Publisher.sendMessage('Update peel visualization', data= self.peel_loaded)
2041   - except:
2042   - Publisher.sendMessage('Update status text in GUI', label=_("Brain mask initialization failed."))
2043   - wx.MessageBox(_("Unable to load brain mask."), _("InVesalius 3"))
  2014 + ww = slic.window_width
  2015 + wl = slic.window_level
  2016 + affine_vtk = vtk.vtkMatrix4x4()
  2017 +
  2018 + if method == peels_dlg.FROM_FILES:
  2019 + matrix_shape = tuple(inv_proj.matrix_shape)
  2020 + try:
  2021 + affine = slic.affine.copy()
  2022 + except AttributeError:
  2023 + affine = np.eye(4)
  2024 + affine[1, -1] -= matrix_shape[1]
  2025 + affine_vtk = vtk_utils.numpy_to_vtkMatrix4x4(affine)
  2026 +
  2027 + self.brain_peel = brain.Brain(self.n_peels, ww, wl, affine_vtk)
  2028 + if method == peels_dlg.FROM_MASK:
  2029 + choices = [i for i in inv_proj.mask_dict.values()]
  2030 + mask_index = peels_dlg.cb_masks.GetSelection()
  2031 + mask = choices[mask_index]
  2032 + self.brain_peel.from_mask(mask)
  2033 + else:
  2034 + mask_path = peels_dlg.mask_path
  2035 + self.brain_peel.from_mask_file(mask_path)
  2036 + self.brain_actor = self.brain_peel.get_actor(self.peel_depth)
  2037 + self.brain_actor.GetProperty().SetOpacity(self.brain_opacity)
  2038 + Publisher.sendMessage('Update peel', flag=True, actor=self.brain_actor)
  2039 + Publisher.sendMessage('Get peel centers and normals', centers=self.brain_peel.peel_centers,
  2040 + normals=self.brain_peel.peel_normals)
  2041 + Publisher.sendMessage('Get init locator', locator=self.brain_peel.locator)
  2042 + self.checkpeeling.Enable(1)
  2043 + self.checkpeeling.SetValue(True)
  2044 + self.spin_opacity.Enable(1)
  2045 + Publisher.sendMessage('Update status text in GUI', label=_("Brain model loaded"))
  2046 + self.peel_loaded = True
  2047 + Publisher.sendMessage('Update peel visualization', data= self.peel_loaded)
2044 2048  
  2049 + peels_dlg.Destroy()
2045 2050 Publisher.sendMessage('End busy cursor')
2046 2051  
2047 2052 def OnLinkFOD(self, event=None):
... ...