Commit ce93f68d9e711956b1ff1ba555c866708ca8820e

Authored by tatiana
1 parent 8fa40bf2

ADD: GUI related to multiple raycasting projections

invesalius/constants.py
1 1 import os.path
  2 +import wx
2 3 from project import Project
3 4  
4 5 # Slice orientation
... ... @@ -27,27 +28,36 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION],
27 28 SAGITAL:[SAGITAL_SLICE_CAM_VIEW_UP, SAGITAL_SLICE_CAM_POSITION],
28 29 CORONAL:[CORONAL_SLICE_CAM_VIEW_UP, CORONAL_SLICE_CAM_POSITION]}
29 30  
  31 +# Volume view angle
  32 +VOL_FRONT = wx.NewId()
  33 +VOL_BACK = wx.NewId()
  34 +VOL_RIGHT = wx.NewId()
  35 +VOL_LEFT = wx.NewId()
  36 +VOL_TOP = wx.NewId()
  37 +VOL_BOTTOM = wx.NewId()
  38 +VOL_ISO = wx.NewId()
  39 +
30 40 # Camera according to volume's orientation
31   -AXIAL_VOLUME_CAM_VIEW_UP = {"FRONT":(0,0,1), "BACK":(0,0,1), "RIGHT":(0,0,1),\
32   - "LEFT":(0,0,1), "TOP":(0,1,0), "BOTTOM":(0,-1,0),\
33   - "ISOMETRIC":(0,0,1)}
34   -AXIAL_VOLUME_CAM_POSITION = {"FRONT":(0,-1,0), "BACK":(0,1,0), "RIGHT":(-1,0,0),\
35   - "LEFT":(1,0,0), "TOP":(0,0,1), "BOTTOM":(0,0,-1),\
36   - "ISOMETRIC":(0.5,-1,0.5)}
37   -
38   -SAGITAL_VOLUME_CAM_VIEW_UP = {"FRONT":(0,-1,0), "BACK":(0,-1,0), "RIGHT":(0,-1,1),\
39   - "LEFT":(0,-1,1), "TOP":(1,-1,0), "BOTTOM":(-1,1,0),\
40   - "ISOMETRIC":(0,-1,0)}
41   -SAGITAL_VOLUME_CAM_POSITION = {"FRONT":(-1,0,0), "BACK":(1,0,0), "RIGHT":(0,0,1),\
42   - "LEFT":(0,0,-1), "TOP":(0,-1,0), "BOTTOM":(0,1,0),\
43   - "ISOMETRIC":(-1,-0.5,-0.5)}
44   -
45   -CORONAL_VOLUME_CAM_VIEW_UP = {"FRONT":(0,-1,0), "BACK":(0,-1,0), "RIGHT":(0,-1,0),\
46   - "LEFT":(0,-1,0), "TOP":(0,1,0), "BOTTOM":(0,-1,0),\
47   - "ISOMETRIC":(0,-1,0)}
48   -CORONAL_VOLUME_CAM_POSITION = {"FRONT":(0,0,-1), "BACK":(0,0,1), "RIGHT":(-1,0,0),\
49   - "LEFT":(1,0,0), "TOP":(0,-1,0), "BOTTOM":(0,1,0),\
50   - "ISOMETRIC":(0.5,-0.5,-1)}
  41 +AXIAL_VOLUME_CAM_VIEW_UP = {VOL_FRONT:(0,0,1), VOL_BACK:(0,0,1), VOL_RIGHT:(0,0,1),\
  42 + VOL_LEFT:(0,0,1), VOL_TOP:(0,1,0), VOL_BOTTOM:(0,-1,0),\
  43 + VOL_ISO:(0,0,1)}
  44 +AXIAL_VOLUME_CAM_POSITION = {VOL_FRONT:(0,-1,0), VOL_BACK:(0,1,0), VOL_RIGHT:(-1,0,0),\
  45 + VOL_LEFT:(1,0,0), VOL_TOP:(0,0,1), VOL_BOTTOM:(0,0,-1),\
  46 + VOL_ISO:(0.5,-1,0.5)}
  47 +
  48 +SAGITAL_VOLUME_CAM_VIEW_UP = {VOL_FRONT:(0,-1,0), VOL_BACK:(0,-1,0), VOL_RIGHT:(0,-1,1),\
  49 + VOL_LEFT:(0,-1,1), VOL_TOP:(1,-1,0), VOL_BOTTOM:(-1,1,0),\
  50 + VOL_ISO:(0,-1,0)}
  51 +SAGITAL_VOLUME_CAM_POSITION = {VOL_FRONT:(-1,0,0), VOL_BACK:(1,0,0), VOL_RIGHT:(0,0,1),\
  52 + VOL_LEFT:(0,0,-1), VOL_TOP:(0,-1,0), VOL_BOTTOM:(0,1,0),\
  53 + VOL_ISO:(-1,-0.5,-0.5)}
  54 +
  55 +CORONAL_VOLUME_CAM_VIEW_UP = {VOL_FRONT:(0,-1,0), VOL_BACK:(0,-1,0), VOL_RIGHT:(0,-1,0),\
  56 + VOL_LEFT:(0,-1,0), VOL_TOP:(0,1,0), VOL_BOTTOM:(0,-1,0),\
  57 + VOL_ISO:(0,-1,0)}
  58 +CORONAL_VOLUME_CAM_POSITION = {VOL_FRONT:(0,0,-1), VOL_BACK:(0,0,1), VOL_RIGHT:(-1,0,0),\
  59 + VOL_LEFT:(1,0,0), VOL_TOP:(0,-1,0), VOL_BOTTOM:(0,1,0),\
  60 + VOL_ISO:(0.5,-0.5,-1)}
51 61  
52 62 VOLUME_POSITION = {AXIAL: [AXIAL_VOLUME_CAM_VIEW_UP, AXIAL_VOLUME_CAM_POSITION],
53 63 SAGITAL: [SAGITAL_VOLUME_CAM_VIEW_UP, SAGITAL_VOLUME_CAM_POSITION],
... ... @@ -137,4 +147,8 @@ REDUCE_IMAGEDATA_QUALITY = 1
137 147 # if 1, use vtkVolumeRaycastMapper, if 0, use vtkFixedPointVolumeRayCastMapper
138 148 TYPE_RAYCASTING_MAPPER = 0
139 149  
140   -RAYCASTING_PRESETS_DIRECTORY= os.path.join("..", "presets", "raycasting")
  150 +folder=RAYCASTING_PRESETS_DIRECTORY= os.path.join("..", "presets", "raycasting")
  151 +
  152 +RAYCASTING_TYPES = [filename.split(".")[0] for filename in
  153 + os.listdir(folder) if
  154 + os.path.isfile(os.path.join(folder,filename))]
... ...
invesalius/data/viewer_volume.py
... ... @@ -60,7 +60,7 @@ class Viewer(wx.Panel):
60 60 self.__bind_events()
61 61 self.__bind_events_wx()
62 62  
63   - self.first_reposition_actor = 0
  63 + self.view_angle = None
64 64  
65 65 def __bind_events(self):
66 66 ps.Publisher().subscribe(self.LoadActor, 'Load surface actor into viewer')
... ... @@ -69,8 +69,10 @@ class Viewer(wx.Panel):
69 69 'Change volume viewer background colour')
70 70 ps.Publisher().subscribe(self.LoadVolume, 'Load volume into viewer')
71 71 ps.Publisher().subscribe(self.AppendActor,'AppendActor')
72   - ps.Publisher().subscribe(self.SetWidgetInteractor, 'Set Widget Interactor')
73   - ps.Publisher().subscribe(self.RepositionActor, 'Reposition Actor')
  72 + ps.Publisher().subscribe(self.SetWidgetInteractor,
  73 + 'Set Widget Interactor')
  74 + ps.Publisher().subscribe(self.OnSetViewAngle,
  75 + 'Set volume view angle')
74 76  
75 77  
76 78 def __bind_events_wx(self):
... ... @@ -90,9 +92,8 @@ class Viewer(wx.Panel):
90 92 volume, colour = pubsub_evt.data
91 93 self.light = self.ren.GetLights().GetNextItem()
92 94 self.ren.AddVolume(volume)
93   - if not (self.first_reposition_actor):
94   - self.RepositionActor()
95   - self.first_reposition_actor = 1
  95 + if not (self.view_angle):
  96 + self.SetViewAngle(const.VOL_FRONT)
96 97 else:
97 98 ren.ResetCamera()
98 99 ren.ResetCameraClippingRange()
... ... @@ -118,21 +119,20 @@ class Viewer(wx.Panel):
118 119  
119 120 self.iren.Render()
120 121  
121   - def RepositionActor(self, evt_pubsub=None):
  122 + def OnSetViewAngle(self, evt_pubsub):
  123 + view = evt_pubsub.data
  124 + self.SetViewAngle(view)
  125 +
  126 + def SetViewAngle(self, view):
122 127  
123   - if (evt_pubsub):
124   - position = evt_pubsub.data
125   - else:
126   - position = "FRONT"
127   -
128 128 cam = self.ren.GetActiveCamera()
129 129 cam.SetFocalPoint(0,0,0)
130 130  
131 131 proj = prj.Project()
132 132 orig_orien = proj.original_orientation
133 133  
134   - xv,yv,zv = const.VOLUME_POSITION[orig_orien][0][position]
135   - xp,yp,zp = const.VOLUME_POSITION[orig_orien][1][position]
  134 + xv,yv,zv = const.VOLUME_POSITION[orig_orien][0][view]
  135 + xp,yp,zp = const.VOLUME_POSITION[orig_orien][1][view]
136 136  
137 137 cam.SetViewUp(xv,yv,zv)
138 138 cam.SetPosition(xp,yp,zp)
... ... @@ -179,4 +179,4 @@ class Viewer(wx.Panel):
179 179 evt_pubsub.data.SetInteractor(self.iren._Iren)
180 180  
181 181 def AppendActor(self, evt_pubsub=None):
182   - self.ren.AddActor(evt_pubsub.data)
183 182 \ No newline at end of file
  183 + self.ren.AddActor(evt_pubsub.data)
... ...
invesalius/data/volume.py
... ... @@ -64,9 +64,6 @@ SHADING = {
64 64 }
65 65 }
66 66  
67   -PRESETS = ["Airways", "Airways II", "Bone + Skin", "Bone + Skin II", "Dark Bone",
68   -"Gold Bone", "Skin On Blue", "Skin On Blue II", "Soft + Skin", "Soft + Skin II",
69   -"Soft + Skin III", "Yellow Bone"]
70 67  
71 68 class Volume():
72 69  
... ... @@ -101,9 +98,9 @@ class Volume():
101 98 if not label:
102 99 label = "Skin On Blue"
103 100  
104   - path = os.path.join("..", "presets", "raycasting",
105   - label+".plist")
106   - label = plistlib.readPlist(path)
  101 + path = os.path.join("..", "presets", "raycasting",
  102 + label+".plist")
  103 + label = plistlib.readPlist(path)
107 104 self.config = label
108 105 #print path
109 106  
... ...
invesalius/gui/default_viewers.py
... ... @@ -163,6 +163,32 @@ class Panel(wx.Panel):
163 163  
164 164 aui_manager.Update()
165 165  
  166 +
  167 +
  168 +
  169 +
  170 +
  171 +
  172 +import wx.lib.platebtn as pbtn
  173 +import wx.lib.buttons as btn
  174 +import wx.lib.pubsub as ps
  175 +import wx.lib.colourselect as csel
  176 +import constants as const
  177 +
  178 +[BUTTON_RAYCASTING, BUTTON_VIEW] = [wx.NewId() for num in xrange(2)]
  179 +
  180 +
  181 +ID_TO_BMP = {const.VOL_FRONT: ["Front", "../icons/view_front.png"],
  182 + const.VOL_BACK: ["Back", "../icons/view_back.png"],
  183 + const.VOL_TOP: ["Top", "../icons/view_top.png"],
  184 + const.VOL_BOTTOM: ["Bottom", "../icons/view_bottom.png"],
  185 + const.VOL_RIGHT: ["Right", "../icons/view_right.png"],
  186 + const.VOL_LEFT: ["Left", "../icons/view_left.png"],
  187 + const.VOL_ISO:["Isometric","../icons/view_isometric.png"]
  188 + }
  189 +
  190 +ID_TO_NAME = {}
  191 +
166 192 class VolumeViewerCover(wx.Panel):
167 193 def __init__(self, parent):
168 194 wx.Panel.__init__(self, parent)
... ... @@ -173,100 +199,90 @@ class VolumeViewerCover(wx.Panel):
173 199 self.SetSizer(sizer)
174 200 sizer.Fit(self)
175 201  
176   -import wx.lib.platebtn as pbtn
177   -import wx.lib.buttons as btn
178   -import wx.lib.pubsub as ps
179   -import wx.lib.colourselect as csel
180   -
181 202 class VolumeToolPanel(wx.Panel):
182 203 def __init__(self, parent):
183 204 wx.Panel.__init__(self, parent, size = (8,100))
184 205  
185   - BMP_RAYCASTING = wx.Bitmap("../icons/volume_raycasting.png", wx.BITMAP_TYPE_PNG)
186   - BMP_RAYCASTING.SetWidth(22)
187   - BMP_RAYCASTING.SetHeight(22)
  206 + # VOLUME RAYCASTING BUTTON
  207 + BMP_RAYCASTING = wx.Bitmap("../icons/volume_raycasting.png",
  208 + wx.BITMAP_TYPE_PNG)
188 209  
189   - FRONT_BMP = wx.Bitmap("../icons/view_front.png", wx.BITMAP_TYPE_PNG)
190   -
191   - button_raycasting=btn.GenBitmapToggleButton(self, 1, BMP_RAYCASTING, size=(24,24))
192   - button_raycasting.Bind(wx.EVT_BUTTON, self.OnToggleRaycasting)
  210 + menu = wx.Menu()
  211 + for name in const.RAYCASTING_TYPES:
  212 + id = wx.NewId()
  213 + item = wx.MenuItem(menu, id, name)
  214 + menu.AppendItem(item)
  215 + ID_TO_NAME[id] = name
  216 + self.menu_raycasting = menu
  217 + menu.Bind(wx.EVT_MENU, self.OnMenuRaycasting)
  218 +
  219 + #button_raycasting=btn.GenBitmapToggleButton(self, 1, BMP_RAYCASTING, size=(24,24))
  220 + self.button_raycasting_toggle = 0
  221 + button_raycasting = pbtn.PlateButton(self, BUTTON_RAYCASTING,"",
  222 + BMP_RAYCASTING, style=pbtn.PB_STYLE_SQUARE,
  223 + size=(24,24))
  224 + self.Bind(wx.EVT_BUTTON, self.OnToggleRaycasting)
  225 + button_raycasting.SetMenu(menu)
  226 +
193 227 self.button_raycasting = button_raycasting
194 228  
  229 + # VOLUME VIEW ANGLE BUTTON
195 230 menu = wx.Menu()
196   -
197   - item = wx.MenuItem(menu, 0, "Front")
198   - item.SetBitmap(FRONT_BMP)
199   -
200   - BACK_BMP = wx.Bitmap("../icons/view_back.png", wx.BITMAP_TYPE_PNG)
201   - item2 = wx.MenuItem(menu, 1, "Back")
202   - item2.SetBitmap(BACK_BMP)
203   -
204   - TOP_BMP = wx.Bitmap("../icons/view_top.png", wx.BITMAP_TYPE_PNG)
205   - item3 = wx.MenuItem(menu, 2, "Top")
206   - item3.SetBitmap(TOP_BMP)
207   -
208   - BOTTOM_BMP = wx.Bitmap("../icons/view_bottom.png", wx.BITMAP_TYPE_PNG)
209   - item4 = wx.MenuItem(menu, 3, "Bottom")
210   - item4.SetBitmap(BOTTOM_BMP)
211   -
212   - RIGHT_BMP = wx.Bitmap("../icons/view_right.png", wx.BITMAP_TYPE_PNG)
213   - item5 = wx.MenuItem(menu, 4, "Right")
214   - item5.SetBitmap(RIGHT_BMP)
215   -
216   - LEFT_BMP = wx.Bitmap("../icons/view_left.png", wx.BITMAP_TYPE_PNG)
217   - item6 = wx.MenuItem(menu, 5, "Left")
218   - item6.SetBitmap(LEFT_BMP)
219   -
220   - ISOMETRIC_BMP = wx.Bitmap("../icons/view_isometric.png", wx.BITMAP_TYPE_PNG)
221   - item7 = wx.MenuItem(menu, 6, "Isometric")
222   - item7.SetBitmap(ISOMETRIC_BMP)
223   -
224   - self.Bind(wx.EVT_MENU, self.OnMenu)
225   -
226   - menu.AppendItem(item)
227   - menu.AppendItem(item2)
228   - menu.AppendItem(item3)
229   - menu.AppendItem(item4)
230   - menu.AppendItem(item5)
231   - menu.AppendItem(item6)
232   - menu.AppendItem(item7)
233   - self.menu = menu
234   -
235   - button_position = pbtn.PlateButton(self, wx.ID_ANY,"", FRONT_BMP,
236   - style=pbtn.PB_STYLE_SQUARE, size=(24,24))
237   -
238   - button_position.SetMenu(menu)
239   - self.button_position = button_position
240   -
241   - button_colour= csel.ColourSelect(self, 111,colour=(0,0,0),size=(24,24))
  231 + for id in ID_TO_BMP:
  232 + bmp = wx.Bitmap(ID_TO_BMP[id][1], wx.BITMAP_TYPE_PNG)
  233 + item = wx.MenuItem(menu, id, ID_TO_BMP[id][0])
  234 + item.SetBitmap(bmp)
  235 + menu.AppendItem(item)
  236 + menu.Bind(wx.EVT_MENU, self.OnMenuView)
  237 + self.menu_view = menu
  238 +
  239 + BMP_FRONT = wx.Bitmap(ID_TO_BMP[const.VOL_FRONT][1],
  240 + wx.BITMAP_TYPE_PNG)
  241 + button_view = pbtn.PlateButton(self, BUTTON_VIEW, "",
  242 + BMP_FRONT, size=(24,24),
  243 + style=pbtn.PB_STYLE_SQUARE)
  244 + button_view.SetMenu(menu)
  245 + self.button_view = button_view
  246 +
  247 + # VOLUME COLOUR BUTTOM
  248 + button_colour= csel.ColourSelect(self, 111,colour=(0,0,0),
  249 + size=(24,24))
242 250 button_colour.Bind(csel.EVT_COLOURSELECT, self.OnSelectColour)
243 251 self.button_colour = button_colour
244 252  
  253 + # SIZER TO ORGANIZE ALL
245 254 sizer = wx.BoxSizer(wx.VERTICAL)
246 255 sizer.Add(button_colour, 0, wx.ALL, 1)
247 256 sizer.Add(button_raycasting, 0, wx.ALL, 1)
248   - sizer.Add(button_position, 0, wx.ALL, 1)
  257 + sizer.Add(button_view, 0, wx.ALL, 1)
249 258 self.SetSizer(sizer)
250 259 sizer.Fit(self)
251 260  
252   - self.orientations = {0:("FRONT", FRONT_BMP), 1:("BACK", BACK_BMP),\
253   - 2:("TOP",TOP_BMP), 3:("BOTTOM",BOTTOM_BMP),\
254   - 4:("RIGHT",RIGHT_BMP), 5:("LEFT", LEFT_BMP),\
255   - 6:("ISOMETRIC",ISOMETRIC_BMP)}
256   -
257   - def OnMenu(self, evt):
  261 + def OnMenuRaycasting(self, evt):
  262 + """Events from button menus."""
  263 + ps.Publisher().sendMessage('Set raycasting preset',
  264 + ID_TO_NAME[evt.GetId()])
  265 + ps.Publisher().sendMessage('Render volume viewer')
258 266  
259   - self.button_position.SetBitmapSelected(self.orientations[evt.GetId()][1])
260   - ps.Publisher().sendMessage('Reposition Actor',\
261   - self.orientations[evt.GetId()][0])
  267 + def OnMenuView(self, evt):
  268 + """Events from button menus."""
  269 + self.button_view.SetBitmapSelected(ID_TO_BMP[evt.GetId()][1])
  270 + ps.Publisher().sendMessage('Set volume view angle',
  271 + ID_TO_BMP[evt.GetId()][0])
262 272  
263 273 def OnSelectColour(self, evt):
264 274 colour = c = [i/255.0 for i in evt.GetValue()]
265 275 ps.Publisher().sendMessage('Change volume viewer background colour', colour)
266 276  
267 277 def OnToggleRaycasting(self, evt):
268   - if self.button_raycasting.GetToggle():
269   - #ps.Publisher().sendMessage('Create volume raycasting')
270   - ps.Publisher().sendMessage('Show raycasting volume')
271   - else:
  278 + print "oi"
  279 + if self.button_raycasting_toggle:
272 280 ps.Publisher().sendMessage('Hide raycasting volume')
  281 + self.button_raycasting.SetBackgroundColour(self.GetParent().GetBackgroundColour())
  282 + #self.button_raycasting.SetBitmapSelected(ID_TO_BMP2[0])
  283 + self.button_raycasting_toggle = 0
  284 + else:
  285 + ps.Publisher().sendMessage('Show raycasting volume')
  286 + self.button_raycasting_toggle = 1
  287 + #self.button_raycasting.SetBitmapSelected(ID_TO_BMP2[1])
  288 + self.button_raycasting.SetBackgroundColour((255,255,255))
... ...