Commit 33e51c02aee52b1f5566c96dd51f93a73571ccb2
1 parent
b7a728d9
Exists in
master
and in
5 other branches
ADD: Added stereo mode support
Showing
6 changed files
with
87 additions
and
1 deletions
Show diff stats
.gitattributes
@@ -18,6 +18,8 @@ docs/devel/sendmessages.txt -text | @@ -18,6 +18,8 @@ docs/devel/sendmessages.txt -text | ||
18 | docs/devel/subscribes.txt -text | 18 | docs/devel/subscribes.txt -text |
19 | docs/user_guide_invesalius3a.odt -text | 19 | docs/user_guide_invesalius3a.odt -text |
20 | docs/user_guide_invesalius3a.pdf -text | 20 | docs/user_guide_invesalius3a.pdf -text |
21 | +icons/3D_glasses.png -text | ||
22 | +icons/3D_glasses_original.png -text | ||
21 | icons/Floppy.png -text | 23 | icons/Floppy.png -text |
22 | icons/annotation.png -text | 24 | icons/annotation.png -text |
23 | icons/brush_circle.jpg -text | 25 | icons/brush_circle.jpg -text |
3.7 KB
14.9 KB
invesalius/constants.py
@@ -38,6 +38,17 @@ DEFAULT_MEASURE_RADIUS = 1 | @@ -38,6 +38,17 @@ DEFAULT_MEASURE_RADIUS = 1 | ||
38 | DEFAULT_MEASURE_TYPE = MEASURE_LINEAR | 38 | DEFAULT_MEASURE_TYPE = MEASURE_LINEAR |
39 | 39 | ||
40 | 40 | ||
41 | +STEREO_OFF = _("Off") | ||
42 | +STEREO_RED_BLUE = _("RedBlue") | ||
43 | +STEREO_CRISTAL = _("CristalEyes") | ||
44 | +STEREO_INTERLACED = _("Interlaced") | ||
45 | +STEREO_LEFT = _("Left") | ||
46 | +STEREO_RIGHT = _("Right") | ||
47 | +STEREO_DRESDEN = _("Dresden") | ||
48 | +STEREO_CHECKBOARD = _("Checkboard") | ||
49 | +STEREO_ANAGLYPH = _("Anaglyph") | ||
50 | + | ||
51 | + | ||
41 | # VTK text | 52 | # VTK text |
42 | TEXT_SIZE_SMALL = 11 | 53 | TEXT_SIZE_SMALL = 11 |
43 | TEXT_SIZE = 12 | 54 | TEXT_SIZE = 12 |
invesalius/data/viewer_volume.py
@@ -171,6 +171,36 @@ class Viewer(wx.Panel): | @@ -171,6 +171,36 @@ class Viewer(wx.Panel): | ||
171 | 'Set ball reference position') | 171 | 'Set ball reference position') |
172 | ps.Publisher().subscribe(self.SetBallReferencePositionBasedOnBound, | 172 | ps.Publisher().subscribe(self.SetBallReferencePositionBasedOnBound, |
173 | 'Set ball reference position based on bound') | 173 | 'Set ball reference position based on bound') |
174 | + ps.Publisher().subscribe(self.SetStereoMode, 'Set stereo mode') | ||
175 | + | ||
176 | + def SetStereoMode(self, pubsub_evt): | ||
177 | + mode = pubsub_evt.data | ||
178 | + ren_win = self.interactor.GetRenderWindow() | ||
179 | + | ||
180 | + if mode == const.STEREO_OFF: | ||
181 | + ren_win.StereoRenderOff() | ||
182 | + else: | ||
183 | + ren_win.StereoRenderOn() | ||
184 | + | ||
185 | + if mode == const.STEREO_RED_BLUE: | ||
186 | + ren_win.SetStereoTypeToRedBlue() | ||
187 | + elif mode == const.STEREO_CRISTAL: | ||
188 | + ren_win.SetStereoTypeToCrystalEyes() | ||
189 | + elif mode == const.STEREO_INTERLACED: | ||
190 | + ren_win.SetStereoTypeToInterlaced() | ||
191 | + elif mode == const.STEREO_LEFT: | ||
192 | + ren_win.SetStereoTypeToLeft() | ||
193 | + elif mode == const.STEREO_RIGHT: | ||
194 | + ren_win.SetStereoTypeToRight() | ||
195 | + elif mode == const.STEREO_DRESDEN: | ||
196 | + ren_win.SetStereoTypeToDresden() | ||
197 | + elif mode == const.STEREO_CHECKBOARD: | ||
198 | + ren_win.SetStereoTypeToCheckerboard() | ||
199 | + elif mode == const.STEREO_ANAGLYPH: | ||
200 | + ren_win.SetStereoTypeToAnaglyph() | ||
201 | + | ||
202 | + self.interactor.Render() | ||
203 | + | ||
174 | 204 | ||
175 | def CreateBallReference(self): | 205 | def CreateBallReference(self): |
176 | self.ball_reference = vtk.vtkSphereSource() | 206 | self.ball_reference = vtk.vtkSphereSource() |
invesalius/gui/default_viewers.py
@@ -303,7 +303,7 @@ import wx.lib.pubsub as ps | @@ -303,7 +303,7 @@ import wx.lib.pubsub as ps | ||
303 | import constants as const | 303 | import constants as const |
304 | import widgets.colourselect as csel | 304 | import widgets.colourselect as csel |
305 | 305 | ||
306 | -[BUTTON_RAYCASTING, BUTTON_VIEW, BUTTON_SLICE_PLANE] = [wx.NewId() for num in xrange(3)] | 306 | +[BUTTON_RAYCASTING, BUTTON_VIEW, BUTTON_SLICE_PLANE, BUTTON_3D_STEREO] = [wx.NewId() for num in xrange(4)] |
307 | RAYCASTING_TOOLS = wx.NewId() | 307 | RAYCASTING_TOOLS = wx.NewId() |
308 | 308 | ||
309 | ID_TO_NAME = {} | 309 | ID_TO_NAME = {} |
@@ -311,6 +311,9 @@ ID_TO_TOOL = {} | @@ -311,6 +311,9 @@ ID_TO_TOOL = {} | ||
311 | ID_TO_TOOL_ITEM = {} | 311 | ID_TO_TOOL_ITEM = {} |
312 | TOOL_STATE = {} | 312 | TOOL_STATE = {} |
313 | ID_TO_ITEMSLICEMENU = {} | 313 | ID_TO_ITEMSLICEMENU = {} |
314 | +ID_TO_ITEM_3DSTEREO = {} | ||
315 | +ID_TO_STEREO_NAME = {} | ||
316 | + | ||
314 | 317 | ||
315 | class VolumeViewerCover(wx.Panel): | 318 | class VolumeViewerCover(wx.Panel): |
316 | def __init__(self, parent): | 319 | def __init__(self, parent): |
@@ -337,15 +340,24 @@ class VolumeToolPanel(wx.Panel): | @@ -337,15 +340,24 @@ class VolumeToolPanel(wx.Panel): | ||
337 | wx.BITMAP_TYPE_PNG) | 340 | wx.BITMAP_TYPE_PNG) |
338 | 341 | ||
339 | 342 | ||
343 | + BMP_3D_STEREO = wx.Bitmap("../icons/3D_glasses.png", | ||
344 | + wx.BITMAP_TYPE_PNG) | ||
345 | + | ||
346 | + | ||
340 | button_raycasting = pbtn.PlateButton(self, BUTTON_RAYCASTING,"", | 347 | button_raycasting = pbtn.PlateButton(self, BUTTON_RAYCASTING,"", |
341 | BMP_RAYCASTING, style=pbtn.PB_STYLE_SQUARE, | 348 | BMP_RAYCASTING, style=pbtn.PB_STYLE_SQUARE, |
342 | size=(24,24)) | 349 | size=(24,24)) |
343 | 350 | ||
351 | + button_stereo = pbtn.PlateButton(self, BUTTON_3D_STEREO,"", | ||
352 | + BMP_3D_STEREO, style=pbtn.PB_STYLE_SQUARE, | ||
353 | + size=(24,24)) | ||
354 | + | ||
344 | button_slice_plane = self.button_slice_plane = pbtn.PlateButton(self, BUTTON_SLICE_PLANE,"", | 355 | button_slice_plane = self.button_slice_plane = pbtn.PlateButton(self, BUTTON_SLICE_PLANE,"", |
345 | BMP_SLICE_PLANE, style=pbtn.PB_STYLE_SQUARE, | 356 | BMP_SLICE_PLANE, style=pbtn.PB_STYLE_SQUARE, |
346 | size=(24,24)) | 357 | size=(24,24)) |
347 | 358 | ||
348 | self.button_raycasting = button_raycasting | 359 | self.button_raycasting = button_raycasting |
360 | + self.button_stereo = button_stereo | ||
349 | 361 | ||
350 | # VOLUME VIEW ANGLE BUTTON | 362 | # VOLUME VIEW ANGLE BUTTON |
351 | BMP_FRONT = wx.Bitmap(ID_TO_BMP[const.VOL_FRONT][1], | 363 | BMP_FRONT = wx.Bitmap(ID_TO_BMP[const.VOL_FRONT][1], |
@@ -373,6 +385,8 @@ class VolumeToolPanel(wx.Panel): | @@ -373,6 +385,8 @@ class VolumeToolPanel(wx.Panel): | ||
373 | sizer.Add(button_raycasting, 0, wx.TOP|wx.BOTTOM, 1) | 385 | sizer.Add(button_raycasting, 0, wx.TOP|wx.BOTTOM, 1) |
374 | sizer.Add(button_view, 0, wx.TOP|wx.BOTTOM, 1) | 386 | sizer.Add(button_view, 0, wx.TOP|wx.BOTTOM, 1) |
375 | sizer.Add(button_slice_plane, 0, wx.TOP|wx.BOTTOM, 1) | 387 | sizer.Add(button_slice_plane, 0, wx.TOP|wx.BOTTOM, 1) |
388 | + sizer.Add(button_stereo, 0, wx.TOP|wx.BOTTOM, 1) | ||
389 | + | ||
376 | 390 | ||
377 | sizer.Fit(self) | 391 | sizer.Fit(self) |
378 | 392 | ||
@@ -401,11 +415,15 @@ class VolumeToolPanel(wx.Panel): | @@ -401,11 +415,15 @@ class VolumeToolPanel(wx.Panel): | ||
401 | self.button_raycasting.Bind(wx.EVT_LEFT_DOWN, self.OnButtonRaycasting) | 415 | self.button_raycasting.Bind(wx.EVT_LEFT_DOWN, self.OnButtonRaycasting) |
402 | self.button_view.Bind(wx.EVT_LEFT_DOWN, self.OnButtonView) | 416 | self.button_view.Bind(wx.EVT_LEFT_DOWN, self.OnButtonView) |
403 | self.button_colour.Bind(csel.EVT_COLOURSELECT, self.OnSelectColour) | 417 | self.button_colour.Bind(csel.EVT_COLOURSELECT, self.OnSelectColour) |
418 | + self.button_stereo.Bind(wx.EVT_LEFT_DOWN, self.OnButtonStereo) | ||
404 | 419 | ||
405 | def OnButtonRaycasting(self, evt): | 420 | def OnButtonRaycasting(self, evt): |
406 | # MENU RELATED TO RAYCASTING TYPES | 421 | # MENU RELATED TO RAYCASTING TYPES |
407 | self.button_raycasting.PopupMenu(self.menu_raycasting) | 422 | self.button_raycasting.PopupMenu(self.menu_raycasting) |
408 | 423 | ||
424 | + def OnButtonStereo(self, evt): | ||
425 | + self.button_stereo.PopupMenu(self.stereo_menu) | ||
426 | + | ||
409 | def OnButtonView(self, evt): | 427 | def OnButtonView(self, evt): |
410 | self.button_view.PopupMenu(self.menu_view) | 428 | self.button_view.PopupMenu(self.menu_view) |
411 | 429 | ||
@@ -481,6 +499,25 @@ class VolumeToolPanel(wx.Panel): | @@ -481,6 +499,25 @@ class VolumeToolPanel(wx.Panel): | ||
481 | 499 | ||
482 | slice_plane_menu.Bind(wx.EVT_MENU, self.OnMenuPlaneSlice) | 500 | slice_plane_menu.Bind(wx.EVT_MENU, self.OnMenuPlaneSlice) |
483 | 501 | ||
502 | + | ||
503 | + #3D Stereo Buttons | ||
504 | + self.stereo_menu = stereo_menu = wx.Menu() | ||
505 | + itens = [const.STEREO_OFF, const.STEREO_RED_BLUE,const.STEREO_ANAGLYPH, const.STEREO_CRISTAL, | ||
506 | + const.STEREO_INTERLACED, const.STEREO_LEFT, const.STEREO_RIGHT, const.STEREO_DRESDEN, | ||
507 | + const.STEREO_CHECKBOARD] | ||
508 | + | ||
509 | + for value in itens: | ||
510 | + new_id = wx.NewId() | ||
511 | + | ||
512 | + item = wx.MenuItem(stereo_menu, new_id, value, | ||
513 | + kind = wx.ITEM_RADIO) | ||
514 | + | ||
515 | + ID_TO_ITEM_3DSTEREO[new_id] = item | ||
516 | + ID_TO_STEREO_NAME[new_id] = value | ||
517 | + stereo_menu.AppendItem(item) | ||
518 | + | ||
519 | + stereo_menu.Bind(wx.EVT_MENU, self.OnMenuStereo) | ||
520 | + | ||
484 | self.Fit() | 521 | self.Fit() |
485 | self.Update() | 522 | self.Update() |
486 | 523 | ||
@@ -508,6 +545,12 @@ class VolumeToolPanel(wx.Panel): | @@ -508,6 +545,12 @@ class VolumeToolPanel(wx.Panel): | ||
508 | else: | 545 | else: |
509 | ps.Publisher().sendMessage('Enable plane', label) | 546 | ps.Publisher().sendMessage('Enable plane', label) |
510 | 547 | ||
548 | + def OnMenuStereo(self, evt): | ||
549 | + id = evt.GetId() | ||
550 | + mode = ID_TO_STEREO_NAME[id] | ||
551 | + ps.Publisher().sendMessage('Set stereo mode', mode) | ||
552 | + | ||
553 | + | ||
511 | def Uncheck(self, pubsub_evt): | 554 | def Uncheck(self, pubsub_evt): |
512 | for item in self.slice_plane_menu.GetMenuItems(): | 555 | for item in self.slice_plane_menu.GetMenuItems(): |
513 | if (item.IsChecked()): | 556 | if (item.IsChecked()): |