Commit ce93f68d9e711956b1ff1ba555c866708ca8820e

Authored by tatiana
1 parent 8fa40bf2

ADD: GUI related to multiple raycasting projections

invesalius/constants.py
1 import os.path 1 import os.path
  2 +import wx
2 from project import Project 3 from project import Project
3 4
4 # Slice orientation 5 # Slice orientation
@@ -27,27 +28,36 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION], @@ -27,27 +28,36 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION],
27 SAGITAL:[SAGITAL_SLICE_CAM_VIEW_UP, SAGITAL_SLICE_CAM_POSITION], 28 SAGITAL:[SAGITAL_SLICE_CAM_VIEW_UP, SAGITAL_SLICE_CAM_POSITION],
28 CORONAL:[CORONAL_SLICE_CAM_VIEW_UP, CORONAL_SLICE_CAM_POSITION]} 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 # Camera according to volume's orientation 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 VOLUME_POSITION = {AXIAL: [AXIAL_VOLUME_CAM_VIEW_UP, AXIAL_VOLUME_CAM_POSITION], 62 VOLUME_POSITION = {AXIAL: [AXIAL_VOLUME_CAM_VIEW_UP, AXIAL_VOLUME_CAM_POSITION],
53 SAGITAL: [SAGITAL_VOLUME_CAM_VIEW_UP, SAGITAL_VOLUME_CAM_POSITION], 63 SAGITAL: [SAGITAL_VOLUME_CAM_VIEW_UP, SAGITAL_VOLUME_CAM_POSITION],
@@ -137,4 +147,8 @@ REDUCE_IMAGEDATA_QUALITY = 1 @@ -137,4 +147,8 @@ REDUCE_IMAGEDATA_QUALITY = 1
137 # if 1, use vtkVolumeRaycastMapper, if 0, use vtkFixedPointVolumeRayCastMapper 147 # if 1, use vtkVolumeRaycastMapper, if 0, use vtkFixedPointVolumeRayCastMapper
138 TYPE_RAYCASTING_MAPPER = 0 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,7 +60,7 @@ class Viewer(wx.Panel):
60 self.__bind_events() 60 self.__bind_events()
61 self.__bind_events_wx() 61 self.__bind_events_wx()
62 62
63 - self.first_reposition_actor = 0 63 + self.view_angle = None
64 64
65 def __bind_events(self): 65 def __bind_events(self):
66 ps.Publisher().subscribe(self.LoadActor, 'Load surface actor into viewer') 66 ps.Publisher().subscribe(self.LoadActor, 'Load surface actor into viewer')
@@ -69,8 +69,10 @@ class Viewer(wx.Panel): @@ -69,8 +69,10 @@ class Viewer(wx.Panel):
69 'Change volume viewer background colour') 69 'Change volume viewer background colour')
70 ps.Publisher().subscribe(self.LoadVolume, 'Load volume into viewer') 70 ps.Publisher().subscribe(self.LoadVolume, 'Load volume into viewer')
71 ps.Publisher().subscribe(self.AppendActor,'AppendActor') 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 def __bind_events_wx(self): 78 def __bind_events_wx(self):
@@ -90,9 +92,8 @@ class Viewer(wx.Panel): @@ -90,9 +92,8 @@ class Viewer(wx.Panel):
90 volume, colour = pubsub_evt.data 92 volume, colour = pubsub_evt.data
91 self.light = self.ren.GetLights().GetNextItem() 93 self.light = self.ren.GetLights().GetNextItem()
92 self.ren.AddVolume(volume) 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 else: 97 else:
97 ren.ResetCamera() 98 ren.ResetCamera()
98 ren.ResetCameraClippingRange() 99 ren.ResetCameraClippingRange()
@@ -118,21 +119,20 @@ class Viewer(wx.Panel): @@ -118,21 +119,20 @@ class Viewer(wx.Panel):
118 119
119 self.iren.Render() 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 cam = self.ren.GetActiveCamera() 128 cam = self.ren.GetActiveCamera()
129 cam.SetFocalPoint(0,0,0) 129 cam.SetFocalPoint(0,0,0)
130 130
131 proj = prj.Project() 131 proj = prj.Project()
132 orig_orien = proj.original_orientation 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 cam.SetViewUp(xv,yv,zv) 137 cam.SetViewUp(xv,yv,zv)
138 cam.SetPosition(xp,yp,zp) 138 cam.SetPosition(xp,yp,zp)
@@ -179,4 +179,4 @@ class Viewer(wx.Panel): @@ -179,4 +179,4 @@ class Viewer(wx.Panel):
179 evt_pubsub.data.SetInteractor(self.iren._Iren) 179 evt_pubsub.data.SetInteractor(self.iren._Iren)
180 180
181 def AppendActor(self, evt_pubsub=None): 181 def AppendActor(self, evt_pubsub=None):
182 - self.ren.AddActor(evt_pubsub.data)  
183 \ No newline at end of file 182 \ No newline at end of file
  183 + self.ren.AddActor(evt_pubsub.data)
invesalius/data/volume.py
@@ -64,9 +64,6 @@ SHADING = { @@ -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 class Volume(): 68 class Volume():
72 69
@@ -101,9 +98,9 @@ class Volume(): @@ -101,9 +98,9 @@ class Volume():
101 if not label: 98 if not label:
102 label = "Skin On Blue" 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 self.config = label 104 self.config = label
108 #print path 105 #print path
109 106
invesalius/gui/default_viewers.py
@@ -163,6 +163,32 @@ class Panel(wx.Panel): @@ -163,6 +163,32 @@ class Panel(wx.Panel):
163 163
164 aui_manager.Update() 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 class VolumeViewerCover(wx.Panel): 192 class VolumeViewerCover(wx.Panel):
167 def __init__(self, parent): 193 def __init__(self, parent):
168 wx.Panel.__init__(self, parent) 194 wx.Panel.__init__(self, parent)
@@ -173,100 +199,90 @@ class VolumeViewerCover(wx.Panel): @@ -173,100 +199,90 @@ class VolumeViewerCover(wx.Panel):
173 self.SetSizer(sizer) 199 self.SetSizer(sizer)
174 sizer.Fit(self) 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 class VolumeToolPanel(wx.Panel): 202 class VolumeToolPanel(wx.Panel):
182 def __init__(self, parent): 203 def __init__(self, parent):
183 wx.Panel.__init__(self, parent, size = (8,100)) 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 self.button_raycasting = button_raycasting 227 self.button_raycasting = button_raycasting
194 228
  229 + # VOLUME VIEW ANGLE BUTTON
195 menu = wx.Menu() 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 button_colour.Bind(csel.EVT_COLOURSELECT, self.OnSelectColour) 250 button_colour.Bind(csel.EVT_COLOURSELECT, self.OnSelectColour)
243 self.button_colour = button_colour 251 self.button_colour = button_colour
244 252
  253 + # SIZER TO ORGANIZE ALL
245 sizer = wx.BoxSizer(wx.VERTICAL) 254 sizer = wx.BoxSizer(wx.VERTICAL)
246 sizer.Add(button_colour, 0, wx.ALL, 1) 255 sizer.Add(button_colour, 0, wx.ALL, 1)
247 sizer.Add(button_raycasting, 0, wx.ALL, 1) 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 self.SetSizer(sizer) 258 self.SetSizer(sizer)
250 sizer.Fit(self) 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 def OnSelectColour(self, evt): 273 def OnSelectColour(self, evt):
264 colour = c = [i/255.0 for i in evt.GetValue()] 274 colour = c = [i/255.0 for i in evt.GetValue()]
265 ps.Publisher().sendMessage('Change volume viewer background colour', colour) 275 ps.Publisher().sendMessage('Change volume viewer background colour', colour)
266 276
267 def OnToggleRaycasting(self, evt): 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 ps.Publisher().sendMessage('Hide raycasting volume') 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))