Commit bc5cd630e6aa6813d60500c7740e63b6a34db836
1 parent
4efd8d3f
Exists in
master
and in
68 other branches
ADD: Raycasting window and level control by cursor
Showing
4 changed files
with
144 additions
and
38 deletions
Show diff stats
invesalius/constants.py
| @@ -2,6 +2,11 @@ import os.path | @@ -2,6 +2,11 @@ import os.path | ||
| 2 | import wx | 2 | import wx |
| 3 | from project import Project | 3 | from project import Project |
| 4 | 4 | ||
| 5 | +# VTK text | ||
| 6 | +TEXT_SIZE = 12 | ||
| 7 | +TEXT_COLOUR = (1,1,1) | ||
| 8 | +TEXT_POSITION = (0.03, 0.97) | ||
| 9 | + | ||
| 5 | # Slice orientation | 10 | # Slice orientation |
| 6 | AXIAL = 0 | 11 | AXIAL = 0 |
| 7 | CORONAL = 1 | 12 | CORONAL = 1 |
invesalius/data/viewer_volume.py
| @@ -23,8 +23,10 @@ import wx | @@ -23,8 +23,10 @@ import wx | ||
| 23 | import vtk | 23 | import vtk |
| 24 | from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor | 24 | from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor |
| 25 | import wx.lib.pubsub as ps | 25 | import wx.lib.pubsub as ps |
| 26 | + | ||
| 26 | import constants as const | 27 | import constants as const |
| 27 | import project as prj | 28 | import project as prj |
| 29 | +import data.vtk_utils as vtku | ||
| 28 | 30 | ||
| 29 | class Viewer(wx.Panel): | 31 | class Viewer(wx.Panel): |
| 30 | def __init__(self, parent): | 32 | def __init__(self, parent): |
| @@ -32,36 +34,57 @@ class Viewer(wx.Panel): | @@ -32,36 +34,57 @@ class Viewer(wx.Panel): | ||
| 32 | self.SetBackgroundColour(wx.Colour(0, 0, 0)) | 34 | self.SetBackgroundColour(wx.Colour(0, 0, 0)) |
| 33 | 35 | ||
| 34 | style = vtk.vtkInteractorStyleTrackballCamera() | 36 | style = vtk.vtkInteractorStyleTrackballCamera() |
| 37 | + self.style = style | ||
| 35 | 38 | ||
| 36 | - iren = wxVTKRenderWindowInteractor(self, -1, size = self.GetSize()) | ||
| 37 | - iren.SetInteractorStyle(style) | 39 | + interactor = wxVTKRenderWindowInteractor(self, -1, size = self.GetSize()) |
| 40 | + interactor.SetInteractorStyle(style) | ||
| 38 | 41 | ||
| 39 | sizer = wx.BoxSizer(wx.VERTICAL) | 42 | sizer = wx.BoxSizer(wx.VERTICAL) |
| 40 | - sizer.Add(iren, 1, wx.EXPAND) | 43 | + sizer.Add(interactor, 1, wx.EXPAND) |
| 41 | self.SetSizer(sizer) | 44 | self.SetSizer(sizer) |
| 42 | self.Layout() | 45 | self.Layout() |
| 43 | 46 | ||
| 44 | - # It would be more correct (API-wise) to call iren.Initialize() and | ||
| 45 | - # iren.Start() here, but Initialize() calls RenderWindow.Render(). | 47 | + # It would be more correct (API-wise) to call interactor.Initialize() and |
| 48 | + # interactor.Start() here, but Initialize() calls RenderWindow.Render(). | ||
| 46 | # That Render() call will get through before we can setup the | 49 | # That Render() call will get through before we can setup the |
| 47 | # RenderWindow() to render via the wxWidgets-created context; this | 50 | # RenderWindow() to render via the wxWidgets-created context; this |
| 48 | # causes flashing on some platforms and downright breaks things on | 51 | # causes flashing on some platforms and downright breaks things on |
| 49 | # other platforms. Instead, we call widget.Enable(). This means | 52 | # other platforms. Instead, we call widget.Enable(). This means |
| 50 | # that the RWI::Initialized ivar is not set, but in THIS SPECIFIC CASE, | 53 | # that the RWI::Initialized ivar is not set, but in THIS SPECIFIC CASE, |
| 51 | # that doesn't matter. | 54 | # that doesn't matter. |
| 52 | - iren.Enable(1) | 55 | + interactor.Enable(1) |
| 53 | 56 | ||
| 54 | ren = vtk.vtkRenderer() | 57 | ren = vtk.vtkRenderer() |
| 55 | - iren.GetRenderWindow().AddRenderer(ren) | 58 | + interactor.GetRenderWindow().AddRenderer(ren) |
| 56 | 59 | ||
| 57 | - self.iren = iren | 60 | + self.interactor = interactor |
| 58 | self.ren = ren | 61 | self.ren = ren |
| 59 | 62 | ||
| 63 | + self.onclick = False | ||
| 64 | + | ||
| 60 | self.__bind_events() | 65 | self.__bind_events() |
| 61 | self.__bind_events_wx() | 66 | self.__bind_events_wx() |
| 62 | 67 | ||
| 63 | self.view_angle = None | 68 | self.view_angle = None |
| 64 | 69 | ||
| 70 | + def OnMove(self, obj, evt): | ||
| 71 | + if self.onclick: | ||
| 72 | + mouse_x, mouse_y = self.interactor.GetEventPosition() | ||
| 73 | + diff_x = mouse_x - self.last_x | ||
| 74 | + diff_y = mouse_y - self.last_y | ||
| 75 | + self.last_x, self.last_y = mouse_x, mouse_y | ||
| 76 | + ps.Publisher().sendMessage('Set raycasting relative window and level', | ||
| 77 | + (diff_x, diff_y)) | ||
| 78 | + self.interactor.Render() | ||
| 79 | + | ||
| 80 | + def OnClick(self, obj, evt): | ||
| 81 | + self.onclick = True | ||
| 82 | + mouse_x, mouse_y = self.interactor.GetEventPosition() | ||
| 83 | + self.last_x, self.last_y = mouse_x, mouse_y | ||
| 84 | + | ||
| 85 | + def OnRelease(self, obj, evt): | ||
| 86 | + self.onclick = False | ||
| 87 | + | ||
| 65 | def __bind_events(self): | 88 | def __bind_events(self): |
| 66 | ps.Publisher().subscribe(self.LoadActor, 'Load surface actor into viewer') | 89 | ps.Publisher().subscribe(self.LoadActor, 'Load surface actor into viewer') |
| 67 | ps.Publisher().subscribe(self.UpdateRender, 'Render volume viewer') | 90 | ps.Publisher().subscribe(self.UpdateRender, 'Render volume viewer') |
| @@ -73,25 +96,52 @@ class Viewer(wx.Panel): | @@ -73,25 +96,52 @@ class Viewer(wx.Panel): | ||
| 73 | 'Set Widget Interactor') | 96 | 'Set Widget Interactor') |
| 74 | ps.Publisher().subscribe(self.OnSetViewAngle, | 97 | ps.Publisher().subscribe(self.OnSetViewAngle, |
| 75 | 'Set volume view angle') | 98 | 'Set volume view angle') |
| 76 | - | 99 | + ps.Publisher().subscribe(self.OnSetWindowLevelText, |
| 100 | + 'Set volume window and level text') | ||
| 101 | + ps.Publisher().subscribe(self.OnEnableBrightContrast, | ||
| 102 | + 'Bright and contrast adjustment') | ||
| 103 | + ps.Publisher().subscribe(self.OnDisableBrightContrast, | ||
| 104 | + 'Set Editor Mode') | ||
| 77 | 105 | ||
| 78 | def __bind_events_wx(self): | 106 | def __bind_events_wx(self): |
| 79 | #self.Bind(wx.EVT_SIZE, self.OnSize) | 107 | #self.Bind(wx.EVT_SIZE, self.OnSize) |
| 80 | pass | 108 | pass |
| 81 | - | 109 | + |
| 110 | + | ||
| 111 | + def OnEnableBrightContrast(self, pubsub_evt): | ||
| 112 | + style = self.style | ||
| 113 | + style.AddObserver("MouseMoveEvent", self.OnMove) | ||
| 114 | + style.AddObserver("LeftButtonPressEvent", self.OnClick) | ||
| 115 | + style.AddObserver("LeftButtonReleaseEvent", self.OnRelease) | ||
| 116 | + | ||
| 117 | + | ||
| 118 | + def OnDisableBrightContrast(self, pubsub_evt): | ||
| 119 | + style = vtk.vtkInteractorStyleTrackballCamera() | ||
| 120 | + self.interactor.SetInteractorStyle(style) | ||
| 121 | + self.style = style | ||
| 122 | + | ||
| 123 | + | ||
| 82 | def OnSize(self, evt): | 124 | def OnSize(self, evt): |
| 83 | - print "viewer_volume :: OnSize" | ||
| 84 | self.UpdateRender() | 125 | self.UpdateRender() |
| 85 | self.Refresh() | 126 | self.Refresh() |
| 86 | - print dir(self.iren) | ||
| 87 | - self.iren.UpdateWindowUI() | ||
| 88 | - self.iren.Update() | 127 | + self.interactor.UpdateWindowUI() |
| 128 | + self.interactor.Update() | ||
| 89 | evt.Skip() | 129 | evt.Skip() |
| 90 | 130 | ||
| 131 | + def OnSetWindowLevelText(self, pubsub_evt): | ||
| 132 | + ww, wl = pubsub_evt.data | ||
| 133 | + self.text.SetValue("WL: %d WW: %d"%(wl, ww)) | ||
| 134 | + | ||
| 91 | def LoadVolume(self, pubsub_evt): | 135 | def LoadVolume(self, pubsub_evt): |
| 92 | - volume, colour = pubsub_evt.data | 136 | + volume = pubsub_evt.data[0] |
| 93 | self.light = self.ren.GetLights().GetNextItem() | 137 | self.light = self.ren.GetLights().GetNextItem() |
| 138 | + | ||
| 139 | + text = vtku.Text() | ||
| 140 | + self.text = text | ||
| 141 | + | ||
| 94 | self.ren.AddVolume(volume) | 142 | self.ren.AddVolume(volume) |
| 143 | + self.ren.AddActor(text.actor) | ||
| 144 | + | ||
| 95 | if not (self.view_angle): | 145 | if not (self.view_angle): |
| 96 | self.SetViewAngle(const.VOL_FRONT) | 146 | self.SetViewAngle(const.VOL_FRONT) |
| 97 | else: | 147 | else: |
| @@ -117,7 +167,7 @@ class Viewer(wx.Panel): | @@ -117,7 +167,7 @@ class Viewer(wx.Panel): | ||
| 117 | ren.ResetCamera() | 167 | ren.ResetCamera() |
| 118 | ren.ResetCameraClippingRange() | 168 | ren.ResetCameraClippingRange() |
| 119 | 169 | ||
| 120 | - self.iren.Render() | 170 | + self.interactor.Render() |
| 121 | 171 | ||
| 122 | def OnSetViewAngle(self, evt_pubsub): | 172 | def OnSetViewAngle(self, evt_pubsub): |
| 123 | view = evt_pubsub.data | 173 | view = evt_pubsub.data |
| @@ -139,21 +189,21 @@ class Viewer(wx.Panel): | @@ -139,21 +189,21 @@ class Viewer(wx.Panel): | ||
| 139 | 189 | ||
| 140 | self.ren.ResetCameraClippingRange() | 190 | self.ren.ResetCameraClippingRange() |
| 141 | self.ren.ResetCamera() | 191 | self.ren.ResetCamera() |
| 142 | - self.iren.Render() | 192 | + self.interactor.Render() |
| 143 | 193 | ||
| 144 | def UpdateRender(self, evt_pubsub=None): | 194 | def UpdateRender(self, evt_pubsub=None): |
| 145 | - self.iren.Render() | 195 | + self.interactor.Render() |
| 146 | 196 | ||
| 147 | def CreatePlanes(self): | 197 | def CreatePlanes(self): |
| 148 | 198 | ||
| 149 | imagedata = self.imagedata | 199 | imagedata = self.imagedata |
| 150 | ren = self.ren | 200 | ren = self.ren |
| 151 | - iren = self.iren | 201 | + interactor = self.interactor |
| 152 | 202 | ||
| 153 | import ivVolumeWidgets as vw | 203 | import ivVolumeWidgets as vw |
| 154 | axial_plane = vw.Plane() | 204 | axial_plane = vw.Plane() |
| 155 | axial_plane.SetRender(ren) | 205 | axial_plane.SetRender(ren) |
| 156 | - axial_plane.SetInteractor(iren) | 206 | + axial_plane.SetInteractor(interactor) |
| 157 | axial_plane.SetOrientation(vw.AXIAL) | 207 | axial_plane.SetOrientation(vw.AXIAL) |
| 158 | axial_plane.SetInput(imagedata) | 208 | axial_plane.SetInput(imagedata) |
| 159 | axial_plane.Show() | 209 | axial_plane.Show() |
| @@ -161,7 +211,7 @@ class Viewer(wx.Panel): | @@ -161,7 +211,7 @@ class Viewer(wx.Panel): | ||
| 161 | 211 | ||
| 162 | coronal_plane = vw.Plane() | 212 | coronal_plane = vw.Plane() |
| 163 | coronal_plane.SetRender(ren) | 213 | coronal_plane.SetRender(ren) |
| 164 | - coronal_plane.SetInteractor(iren) | 214 | + coronal_plane.SetInteractor(interactor) |
| 165 | coronal_plane.SetOrientation(vw.CORONAL) | 215 | coronal_plane.SetOrientation(vw.CORONAL) |
| 166 | coronal_plane.SetInput(imagedata) | 216 | coronal_plane.SetInput(imagedata) |
| 167 | coronal_plane.Show() | 217 | coronal_plane.Show() |
| @@ -169,14 +219,14 @@ class Viewer(wx.Panel): | @@ -169,14 +219,14 @@ class Viewer(wx.Panel): | ||
| 169 | 219 | ||
| 170 | sagital_plane = vw.Plane() | 220 | sagital_plane = vw.Plane() |
| 171 | sagital_plane.SetRender(ren) | 221 | sagital_plane.SetRender(ren) |
| 172 | - sagital_plane.SetInteractor(iren) | 222 | + sagital_plane.SetInteractor(interactor) |
| 173 | sagital_plane.SetOrientation(vw.SAGITAL) | 223 | sagital_plane.SetOrientation(vw.SAGITAL) |
| 174 | sagital_plane.SetInput(imagedata) | 224 | sagital_plane.SetInput(imagedata) |
| 175 | sagital_plane.Show() | 225 | sagital_plane.Show() |
| 176 | sagital_plane.Update() | 226 | sagital_plane.Update() |
| 177 | 227 | ||
| 178 | def SetWidgetInteractor(self, evt_pubsub=None): | 228 | def SetWidgetInteractor(self, evt_pubsub=None): |
| 179 | - evt_pubsub.data.SetInteractor(self.iren._Iren) | 229 | + evt_pubsub.data.SetInteractor(self.interactor._Iren) |
| 180 | 230 | ||
| 181 | def AppendActor(self, evt_pubsub=None): | 231 | def AppendActor(self, evt_pubsub=None): |
| 182 | self.ren.AddActor(evt_pubsub.data) | 232 | self.ren.AddActor(evt_pubsub.data) |
invesalius/data/volume.py
| @@ -72,6 +72,9 @@ class Volume(): | @@ -72,6 +72,9 @@ class Volume(): | ||
| 72 | self.exist = None | 72 | self.exist = None |
| 73 | self.color_transfer = None | 73 | self.color_transfer = None |
| 74 | self.opacity_transfer_func = None | 74 | self.opacity_transfer_func = None |
| 75 | + self.ww = None | ||
| 76 | + self.wl = None | ||
| 77 | + self.n = 0 | ||
| 75 | 78 | ||
| 76 | self.__bind_events() | 79 | self.__bind_events() |
| 77 | 80 | ||
| @@ -83,10 +86,12 @@ class Volume(): | @@ -83,10 +86,12 @@ class Volume(): | ||
| 83 | 'Hide raycasting volume') | 86 | 'Hide raycasting volume') |
| 84 | ps.Publisher().subscribe(self.SetRaycastPreset, | 87 | ps.Publisher().subscribe(self.SetRaycastPreset, |
| 85 | 'Set raycasting preset') | 88 | 'Set raycasting preset') |
| 86 | - ps.Publisher().subscribe(self.SetWWWL, | 89 | + ps.Publisher().subscribe(self.OnSetWindowLevel, |
| 87 | 'Set raycasting wwwl') | 90 | 'Set raycasting wwwl') |
| 88 | ps.Publisher().subscribe(self.Refresh, | 91 | ps.Publisher().subscribe(self.Refresh, |
| 89 | 'Set raycasting refresh') | 92 | 'Set raycasting refresh') |
| 93 | + ps.Publisher().subscribe(self.OnSetRelativeWindowLevel, | ||
| 94 | + 'Set raycasting relative window and level') | ||
| 90 | 95 | ||
| 91 | def OnLoadVolume(self, pubsub_evt): | 96 | def OnLoadVolume(self, pubsub_evt): |
| 92 | label = pubsub_evt.data | 97 | label = pubsub_evt.data |
| @@ -95,7 +100,6 @@ class Volume(): | @@ -95,7 +100,6 @@ class Volume(): | ||
| 95 | 100 | ||
| 96 | def LoadConfig(self): | 101 | def LoadConfig(self): |
| 97 | self.config = Project().raycasting_preset | 102 | self.config = Project().raycasting_preset |
| 98 | - #print path | ||
| 99 | 103 | ||
| 100 | def OnHideVolume(self, pubsub_evt): | 104 | def OnHideVolume(self, pubsub_evt): |
| 101 | self.volume.SetVisibility(0) | 105 | self.volume.SetVisibility(0) |
| @@ -126,11 +130,24 @@ class Volume(): | @@ -126,11 +130,24 @@ class Volume(): | ||
| 126 | self.Create8bColorTable(self.scale) | 130 | self.Create8bColorTable(self.scale) |
| 127 | self.Create8bOpacityTable(self.scale) | 131 | self.Create8bOpacityTable(self.scale) |
| 128 | 132 | ||
| 129 | - def SetWWWL(self, pubsub_evt): | 133 | + def OnSetRelativeWindowLevel(self, pubsub_evt): |
| 134 | + diff_ww, diff_wl = pubsub_evt.data | ||
| 135 | + ww = self.ww + diff_ww | ||
| 136 | + wl = self.wl + diff_wl | ||
| 137 | + ps.Publisher().sendMessage('Set volume window and level text', | ||
| 138 | + (ww, wl)) | ||
| 139 | + self.SetWWWL(ww, wl) | ||
| 140 | + self.ww = ww | ||
| 141 | + self.wl = wl | ||
| 142 | + | ||
| 143 | + def OnSetWindowLevel(self, pubsub_evt): | ||
| 130 | ww, wl, n = pubsub_evt.data | 144 | ww, wl, n = pubsub_evt.data |
| 131 | - print "Setting ww, wl", ww, wl | 145 | + self.SetWWWL(ww,wl,n) |
| 146 | + | ||
| 147 | + def SetWWWL(self, ww, wl): | ||
| 148 | + | ||
| 132 | if self.config['advancedCLUT']: | 149 | if self.config['advancedCLUT']: |
| 133 | - curve = self.config['16bitClutCurves'][n] | 150 | + curve = self.config['16bitClutCurves'][self.n] |
| 134 | 151 | ||
| 135 | p1 = curve[0] | 152 | p1 = curve[0] |
| 136 | p2 = curve[-1] | 153 | p2 = curve[-1] |
| @@ -155,7 +172,7 @@ class Volume(): | @@ -155,7 +172,7 @@ class Volume(): | ||
| 155 | self.config['ww'] = ww | 172 | self.config['ww'] = ww |
| 156 | 173 | ||
| 157 | self.__config_preset() | 174 | self.__config_preset() |
| 158 | - ps.Publisher().sendMessage('Render volume viewer', None) | 175 | + #ps.Publisher().sendMessage('Render volume viewer', None) |
| 159 | 176 | ||
| 160 | def Refresh(self, pubsub_evt): | 177 | def Refresh(self, pubsub_evt): |
| 161 | self.__config_preset() | 178 | self.__config_preset() |
| @@ -167,7 +184,6 @@ class Volume(): | @@ -167,7 +184,6 @@ class Volume(): | ||
| 167 | else: | 184 | else: |
| 168 | color_transfer = vtk.vtkColorTransferFunction() | 185 | color_transfer = vtk.vtkColorTransferFunction() |
| 169 | color_transfer.RemoveAllPoints() | 186 | color_transfer.RemoveAllPoints() |
| 170 | - print self.config | ||
| 171 | curve_table = self.config['16bitClutCurves'] | 187 | curve_table = self.config['16bitClutCurves'] |
| 172 | color_table = self.config['16bitClutColors'] | 188 | color_table = self.config['16bitClutColors'] |
| 173 | colors = [] | 189 | colors = [] |
| @@ -191,12 +207,10 @@ class Volume(): | @@ -191,12 +207,10 @@ class Volume(): | ||
| 191 | color_transfer = vtk.vtkColorTransferFunction() | 207 | color_transfer = vtk.vtkColorTransferFunction() |
| 192 | color_transfer.RemoveAllPoints() | 208 | color_transfer.RemoveAllPoints() |
| 193 | color_preset = self.config['CLUT'] | 209 | color_preset = self.config['CLUT'] |
| 194 | - print ">>>", color_preset | ||
| 195 | if color_preset != "No CLUT": | 210 | if color_preset != "No CLUT": |
| 196 | p = plistlib.readPlist( | 211 | p = plistlib.readPlist( |
| 197 | os.path.join(const.RAYCASTING_PRESETS_DIRECTORY, | 212 | os.path.join(const.RAYCASTING_PRESETS_DIRECTORY, |
| 198 | 'color_list', color_preset + '.plist')) | 213 | 'color_list', color_preset + '.plist')) |
| 199 | - print "nome clut", p | ||
| 200 | r = p['Red'] | 214 | r = p['Red'] |
| 201 | g = p['Green'] | 215 | g = p['Green'] |
| 202 | b = p['Blue'] | 216 | b = p['Blue'] |
| @@ -205,7 +219,6 @@ class Volume(): | @@ -205,7 +219,6 @@ class Volume(): | ||
| 205 | wl = self.TranslateScale(scale, self.config['wl']) | 219 | wl = self.TranslateScale(scale, self.config['wl']) |
| 206 | inc = ww / 254.0 | 220 | inc = ww / 254.0 |
| 207 | for i,rgb in enumerate(colors): | 221 | for i,rgb in enumerate(colors): |
| 208 | - print i,inc, ww, wl - ww/2 + i * inc, rgb | ||
| 209 | color_transfer.AddRGBPoint((wl - ww/2) + (i * inc), *[i/255.0 for i in rgb]) | 222 | color_transfer.AddRGBPoint((wl - ww/2) + (i * inc), *[i/255.0 for i in rgb]) |
| 210 | self.color_transfer = color_transfer | 223 | self.color_transfer = color_transfer |
| 211 | return color_transfer | 224 | return color_transfer |
| @@ -221,6 +234,8 @@ class Volume(): | @@ -221,6 +234,8 @@ class Volume(): | ||
| 221 | 234 | ||
| 222 | ww = self.config['ww'] | 235 | ww = self.config['ww'] |
| 223 | wl = self.config['wl'] | 236 | wl = self.config['wl'] |
| 237 | + self.ww = ww | ||
| 238 | + self.wl = wl | ||
| 224 | 239 | ||
| 225 | l1 = wl - ww/2.0 | 240 | l1 = wl - ww/2.0 |
| 226 | l2 = wl + ww/2.0 | 241 | l2 = wl + ww/2.0 |
| @@ -255,16 +270,12 @@ class Volume(): | @@ -255,16 +270,12 @@ class Volume(): | ||
| 255 | ww = self.config['ww'] | 270 | ww = self.config['ww'] |
| 256 | wl = self.TranslateScale(scale, self.config['wl']) | 271 | wl = self.TranslateScale(scale, self.config['wl']) |
| 257 | 272 | ||
| 258 | - print ww, wl | ||
| 259 | - | ||
| 260 | l1 = wl - ww/2.0 | 273 | l1 = wl - ww/2.0 |
| 261 | l2 = wl + ww/2.0 | 274 | l2 = wl + ww/2.0 |
| 262 | 275 | ||
| 263 | opacity_transfer_func.RemoveAllPoints() | 276 | opacity_transfer_func.RemoveAllPoints() |
| 264 | opacity_transfer_func.AddSegment(0, 0, 2**16-1, 0) | 277 | opacity_transfer_func.AddSegment(0, 0, 2**16-1, 0) |
| 265 | 278 | ||
| 266 | - print "l1, l2", l1, l2 | ||
| 267 | - | ||
| 268 | k1 = 0.0 | 279 | k1 = 0.0 |
| 269 | k2 = 1.0 | 280 | k2 = 1.0 |
| 270 | 281 |
invesalius/data/vtk_utils.py
| 1 | import wx.lib.pubsub as ps | 1 | import wx.lib.pubsub as ps |
| 2 | +import vtk | ||
| 3 | + | ||
| 4 | +import constants as const | ||
| 2 | 5 | ||
| 3 | # If you are frightened by the code bellow, or think it must have been result of | 6 | # If you are frightened by the code bellow, or think it must have been result of |
| 4 | # an identation error, lookup at: | 7 | # an identation error, lookup at: |
| @@ -47,4 +50,41 @@ def ShowProgress(number_of_filters = 1): | @@ -47,4 +50,41 @@ def ShowProgress(number_of_filters = 1): | ||
| 47 | (progress[0], label)) | 50 | (progress[0], label)) |
| 48 | return progress[0] | 51 | return progress[0] |
| 49 | 52 | ||
| 50 | - return UpdateProgress | ||
| 51 | \ No newline at end of file | 53 | \ No newline at end of file |
| 54 | + return UpdateProgress | ||
| 55 | + | ||
| 56 | +class Text(object): | ||
| 57 | + def __init__(self): | ||
| 58 | + | ||
| 59 | + property = vtk.vtkTextProperty() | ||
| 60 | + property.SetFontSize(const.TEXT_SIZE) | ||
| 61 | + property.SetFontFamilyToArial() | ||
| 62 | + property.BoldOff() | ||
| 63 | + property.ItalicOff() | ||
| 64 | + property.ShadowOn() | ||
| 65 | + property.SetJustificationToLeft() | ||
| 66 | + property.SetVerticalJustificationToTop() | ||
| 67 | + property.SetColor(const.TEXT_COLOUR) | ||
| 68 | + self.property = property | ||
| 69 | + | ||
| 70 | + mapper = vtk.vtkTextMapper() | ||
| 71 | + mapper.SetTextProperty(property) | ||
| 72 | + self.mapper = mapper | ||
| 73 | + | ||
| 74 | + x, y = const.TEXT_POSITION | ||
| 75 | + actor = vtk.vtkActor2D() | ||
| 76 | + actor.SetMapper(mapper) | ||
| 77 | + actor.GetPositionCoordinate().SetCoordinateSystemToNormalizedDisplay() | ||
| 78 | + actor.GetPositionCoordinate().SetValue(x,y) | ||
| 79 | + self.actor = actor | ||
| 80 | + | ||
| 81 | + def SetValue(self, value): | ||
| 82 | + self.mapper.SetInput(str(value)) | ||
| 83 | + | ||
| 84 | + def SetPosition(self, position): | ||
| 85 | + self.actor.SetPositionCoordinate().SetValue(position) | ||
| 86 | + | ||
| 87 | + def Show(self, value=1): | ||
| 88 | + if value: | ||
| 89 | + self.actor.VisibilityOn() | ||
| 90 | + else: | ||
| 91 | + self.actor.VisibilityOff() |