Commit 29f9d5189f0e55a7d7520a78b5e7458b653b5c51

Authored by Paulo Henrique Junqueira Amorim
1 parent 46b26413

ADD: Plane with slices

invesalius/control.py
@@ -116,7 +116,8 @@ class Controller(): @@ -116,7 +116,8 @@ class Controller():
116 ps.Publisher().sendMessage('Show content panel') 116 ps.Publisher().sendMessage('Show content panel')
117 117
118 ps.Publisher().sendMessage('Update AUI') 118 ps.Publisher().sendMessage('Update AUI')
119 - 119 +
  120 + ps.Publisher().sendMessage('Load slice plane')
120 121
121 def LoadImagedataInfo(self): 122 def LoadImagedataInfo(self):
122 proj = prj.Project() 123 proj = prj.Project()
invesalius/data/viewer_volume.py
@@ -72,6 +72,7 @@ class Viewer(wx.Panel): @@ -72,6 +72,7 @@ class Viewer(wx.Panel):
72 self.__bind_events() 72 self.__bind_events()
73 self.__bind_events_wx() 73 self.__bind_events_wx()
74 74
  75 +
75 76
76 def OnMove(self, obj, evt): 77 def OnMove(self, obj, evt):
77 if self.onclick and self.raycasting_volume: 78 if self.onclick and self.raycasting_volume:
@@ -157,8 +158,18 @@ class Viewer(wx.Panel): @@ -157,8 +158,18 @@ class Viewer(wx.Panel):
157 ps.Publisher().subscribe(self.OnDisableBrightContrast, 158 ps.Publisher().subscribe(self.OnDisableBrightContrast,
158 ('Set interaction mode', 159 ('Set interaction mode',
159 const.MODE_SLICE_EDITOR)) 160 const.MODE_SLICE_EDITOR))
160 - 161 +
161 ps.Publisher().subscribe(self.OnExportSurface, 'Export surface to file') 162 ps.Publisher().subscribe(self.OnExportSurface, 'Export surface to file')
  163 +
  164 + ps.Publisher().subscribe(self.LoadSlicePlane, 'Load slice plane')
  165 +
  166 + ps.Publisher().subscribe(self.ResetCamClippingRange, 'Reset cam clipping range')
  167 +
  168 +
  169 + def ResetCamClippingRange(self, pubsub_evt):
  170 + self.ren.ResetCamera()
  171 + self.ren.ResetCameraClippingRange()
  172 +
162 173
163 def OnExportSurface(self, pubsub_evt): 174 def OnExportSurface(self, pubsub_evt):
164 filename, filetype = pubsub_evt.data 175 filename, filetype = pubsub_evt.data
@@ -243,11 +254,8 @@ class Viewer(wx.Panel): @@ -243,11 +254,8 @@ class Viewer(wx.Panel):
243 254
244 self.UpdateRender() 255 self.UpdateRender()
245 256
246 - def LoadPlane(self):  
247 - self.plane = SlicePlane()  
248 - self.plane.EnableX()  
249 - self.plane.EnableY()  
250 - self.plane.EnableZ() 257 + def LoadSlicePlane(self, pubsub_evt):
  258 + self.slice_plane = SlicePlane()
251 259
252 def ChangeBackgroundColour(self, pubsub_evt): 260 def ChangeBackgroundColour(self, pubsub_evt):
253 colour = pubsub_evt.data 261 colour = pubsub_evt.data
@@ -308,12 +316,7 @@ class Viewer(wx.Panel): @@ -308,12 +316,7 @@ class Viewer(wx.Panel):
308 class SlicePlane: 316 class SlicePlane:
309 317
310 def __init__(self): 318 def __init__(self):
311 -  
312 self.Create() 319 self.Create()
313 - self.__bind_events()  
314 -  
315 - def __bind_events(self):  
316 - self.plane_x.AddObserver("InteractionEvent", self.Update)  
317 320
318 def Create(self): 321 def Create(self):
319 322
@@ -352,35 +355,55 @@ class SlicePlane: @@ -352,35 +355,55 @@ class SlicePlane:
352 prop1.SetColor(1, 0, 0) 355 prop1.SetColor(1, 0, 0)
353 cursor_property = plane_z.GetCursorProperty() 356 cursor_property = plane_z.GetCursorProperty()
354 cursor_property.SetOpacity(0) 357 cursor_property.SetOpacity(0)
355 - 358 +
356 ps.Publisher().sendMessage('Set Widget Interactor', plane_x) 359 ps.Publisher().sendMessage('Set Widget Interactor', plane_x)
357 ps.Publisher().sendMessage('Set Widget Interactor', plane_y) 360 ps.Publisher().sendMessage('Set Widget Interactor', plane_y)
358 ps.Publisher().sendMessage('Set Widget Interactor', plane_z) 361 ps.Publisher().sendMessage('Set Widget Interactor', plane_z)
359 362
360 - def EnableX(self, evt_pubsub=None):  
361 - self.plane_x.On()  
362 - self.Update()  
363 -  
364 - def EnableY(self, evt_pubsub=None):  
365 - self.plane_y.On()  
366 - self.Update()  
367 -  
368 - def EnableZ(self, evt_pubsub=None):  
369 - self.plane_z.On()  
370 - self.Update() 363 + ps.Publisher().subscribe(self.Enable, 'Enable plane')
  364 + ps.Publisher().subscribe(self.Disable, 'Disable plane')
371 365
372 - def DisableX(self, evt_pubsub=None):  
373 - self.plane_x.Off()  
374 - self.Update() 366 + self.Enable()
  367 + self.Disable()
  368 +
  369 + self.Render()
  370 +
  371 + def Enable(self, evt_pubsub=None):
  372 + if (evt_pubsub):
  373 + label = evt_pubsub.data
  374 +
  375 + if(label == "Axial"):
  376 + self.plane_z.On()
  377 + elif(label == "Coronal"):
  378 + self.plane_x.On()
  379 + elif(label == "Sagital"):
  380 + self.plane_y.On()
  381 +
  382 + else:
  383 + self.plane_z.On()
  384 + self.plane_x.On()
  385 + self.plane_y.On()
  386 + ps.Publisher().sendMessage('Set volume view angle', const.VOL_ISO)
  387 + self.Render()
  388 +
  389 + def Disable(self, evt_pubsub=None):
  390 + if (evt_pubsub):
  391 + label = evt_pubsub.data
  392 +
  393 + if(label == "Axial"):
  394 + self.plane_z.Off()
  395 + elif(label == "Coronal"):
  396 + self.plane_x.Off()
  397 + elif(label == "Sagital"):
  398 + self.plane_y.Off()
  399 + else:
  400 + self.plane_z.Off()
  401 + self.plane_x.Off()
  402 + self.plane_y.Off()
375 403
376 - def DisableY(self, evt_pubsub=None):  
377 - self.plane_y.Off()  
378 - self.Update() 404 + self.Render()
379 405
380 - def DisableZ(self, evt_pubsub=None):  
381 - self.plane_z.Off()  
382 - self.Update()  
383 406
384 - def Update(self, obj, evt):  
385 - ps.Publisher().sendMessage('Render volume viewer', None) 407 + def Render(self):
  408 + ps.Publisher().sendMessage('Render volume viewer')
386 409
387 \ No newline at end of file 410 \ No newline at end of file
invesalius/gui/default_viewers.py
@@ -248,7 +248,7 @@ import wx.lib.pubsub as ps @@ -248,7 +248,7 @@ import wx.lib.pubsub as ps
248 import wx.lib.colourselect as csel 248 import wx.lib.colourselect as csel
249 import constants as const 249 import constants as const
250 250
251 -[BUTTON_RAYCASTING, BUTTON_VIEW] = [wx.NewId() for num in xrange(2)] 251 +[BUTTON_RAYCASTING, BUTTON_VIEW, BUTTON_SLICE_PLANE] = [wx.NewId() for num in xrange(3)]
252 RAYCASTING_TOOLS = wx.NewId() 252 RAYCASTING_TOOLS = wx.NewId()
253 253
254 ID_TO_BMP = {const.VOL_FRONT: ["Front", "../icons/view_front.png"], 254 ID_TO_BMP = {const.VOL_FRONT: ["Front", "../icons/view_front.png"],
@@ -264,6 +264,7 @@ ID_TO_NAME = {} @@ -264,6 +264,7 @@ ID_TO_NAME = {}
264 ID_TO_TOOL = {} 264 ID_TO_TOOL = {}
265 ID_TO_TOOL_ITEM = {} 265 ID_TO_TOOL_ITEM = {}
266 TOOL_STATE = {} 266 TOOL_STATE = {}
  267 +ID_TO_ITEMSLICEMENU = {}
267 268
268 class VolumeViewerCover(wx.Panel): 269 class VolumeViewerCover(wx.Panel):
269 def __init__(self, parent): 270 def __init__(self, parent):
@@ -286,10 +287,19 @@ class VolumeToolPanel(wx.Panel): @@ -286,10 +287,19 @@ class VolumeToolPanel(wx.Panel):
286 BMP_RAYCASTING = wx.Bitmap("../icons/volume_raycasting.png", 287 BMP_RAYCASTING = wx.Bitmap("../icons/volume_raycasting.png",
287 wx.BITMAP_TYPE_PNG) 288 wx.BITMAP_TYPE_PNG)
288 289
  290 + BMP_SLICE_PLANE = wx.Bitmap("../icons/slice_plane.png",
  291 + wx.BITMAP_TYPE_PNG)
  292 +
289 293
290 button_raycasting = pbtn.PlateButton(self, BUTTON_RAYCASTING,"", 294 button_raycasting = pbtn.PlateButton(self, BUTTON_RAYCASTING,"",
291 BMP_RAYCASTING, style=pbtn.PB_STYLE_SQUARE, 295 BMP_RAYCASTING, style=pbtn.PB_STYLE_SQUARE,
292 size=(24,24)) 296 size=(24,24))
  297 +
  298 + button_slice_plane = self.button_slice_plane = pbtn.PlateButton(self, BUTTON_SLICE_PLANE,"",
  299 + BMP_SLICE_PLANE, style=pbtn.PB_STYLE_SQUARE,
  300 + size=(24,24))
  301 + button_slice_plane.Bind(wx.EVT_LEFT_DOWN, self.OnButtonSlicePlane)
  302 +
293 self.button_raycasting = button_raycasting 303 self.button_raycasting = button_raycasting
294 self.button_raycasting.Bind(wx.EVT_LEFT_DOWN, self.OnButtonRaycasting) 304 self.button_raycasting.Bind(wx.EVT_LEFT_DOWN, self.OnButtonRaycasting)
295 305
@@ -321,6 +331,7 @@ class VolumeToolPanel(wx.Panel): @@ -321,6 +331,7 @@ class VolumeToolPanel(wx.Panel):
321 sizer.Add(button_colour, 0, wx.ALL, sp) 331 sizer.Add(button_colour, 0, wx.ALL, sp)
322 sizer.Add(button_raycasting, 0, wx.TOP|wx.BOTTOM, 1) 332 sizer.Add(button_raycasting, 0, wx.TOP|wx.BOTTOM, 1)
323 sizer.Add(button_view, 0, wx.TOP|wx.BOTTOM, 1) 333 sizer.Add(button_view, 0, wx.TOP|wx.BOTTOM, 1)
  334 + sizer.Add(button_slice_plane, 0, wx.TOP|wx.BOTTOM, 1)
324 335
325 sizer.Fit(self) 336 sizer.Fit(self)
326 337
@@ -343,6 +354,9 @@ class VolumeToolPanel(wx.Panel): @@ -343,6 +354,9 @@ class VolumeToolPanel(wx.Panel):
343 354
344 def OnButtonView(self, evt): 355 def OnButtonView(self, evt):
345 self.button_view.PopupMenu(self.menu_view) 356 self.button_view.PopupMenu(self.menu_view)
  357 +
  358 + def OnButtonSlicePlane(self, evt):
  359 + self.button_slice_plane.PopupMenu(self.slice_plane_menu)
346 360
347 def __init_menus(self, pubsub_evt=None): 361 def __init_menus(self, pubsub_evt=None):
348 # MENU RELATED TO RAYCASTING TYPES 362 # MENU RELATED TO RAYCASTING TYPES
@@ -386,10 +400,37 @@ class VolumeToolPanel(wx.Panel): @@ -386,10 +400,37 @@ class VolumeToolPanel(wx.Panel):
386 menu.AppendItem(item) 400 menu.AppendItem(item)
387 menu.Bind(wx.EVT_MENU, self.OnMenuView) 401 menu.Bind(wx.EVT_MENU, self.OnMenuView)
388 self.menu_view = menu 402 self.menu_view = menu
389 - 403 +
  404 + #SLICE PLANES BUTTON
  405 + self.slice_plane_menu = slice_plane_menu = wx.Menu()
  406 + itens = ["Axial", "Coronal", "Sagital"]
  407 +
  408 + for value in itens:
  409 + new_id = wx.NewId()
  410 +
  411 + item = wx.MenuItem(slice_plane_menu, new_id, value,
  412 + kind = wx.ITEM_CHECK)
  413 + ID_TO_ITEMSLICEMENU[new_id] = item
  414 + slice_plane_menu.AppendItem(item)
  415 +
  416 + slice_plane_menu.Bind(wx.EVT_MENU, self.OnMenuPlaneSlice)
  417 +
390 self.Fit() 418 self.Fit()
391 self.Update() 419 self.Update()
  420 +
  421 + def OnMenuPlaneSlice(self, evt):
  422 +
  423 + id = evt.GetId()
  424 + item = ID_TO_ITEMSLICEMENU[id]
  425 + checked = item.IsChecked()
  426 + label = item.GetLabel()
  427 +
  428 + if not (checked):
  429 + ps.Publisher().sendMessage('Disable plane', label)
  430 + else:
  431 + ps.Publisher().sendMessage('Enable plane', label)
392 432
  433 +
393 def ChangeButtonColour(self, pubsub_evt): 434 def ChangeButtonColour(self, pubsub_evt):
394 colour = [i*255 for i in pubsub_evt.data] 435 colour = [i*255 for i in pubsub_evt.data]
395 self.button_colour.SetColour(colour) 436 self.button_colour.SetColour(colour)