Commit 940329e661e279a0ec11a807fdf817e8fae7153e
1 parent
85c57f6f
Exists in
master
and in
68 other branches
ENH: Text actors on slice_viewer
Showing
5 changed files
with
66 additions
and
60 deletions
Show diff stats
invesalius/constants.py
| ... | ... | @@ -22,10 +22,20 @@ import wx |
| 22 | 22 | |
| 23 | 23 | from project import Project |
| 24 | 24 | |
| 25 | + | |
| 26 | +#--------------- | |
| 27 | + | |
| 25 | 28 | # VTK text |
| 26 | 29 | TEXT_SIZE = 12 |
| 30 | +TEXT_SIZE_LARGE = 18 | |
| 27 | 31 | TEXT_COLOUR = (1,1,1) |
| 28 | -TEXT_POSITION = (0.03, 0.97) | |
| 32 | +(X,Y) = (0.03, 0.97) | |
| 33 | +TEXT_POS_LEFT_UP = (X, Y) | |
| 34 | +TEXT_POS_LEFT_DOWN = (X, 1-Y) | |
| 35 | +TEXT_POS_LEFT_DOWN_SLC = (X, 1-0.93) | |
| 36 | +TEXT_POS_RIGHT_UP = (1-X, Y) | |
| 37 | +TEXT_POS_RIGHT_DOWN = (1-X, 1-Y) | |
| 38 | +TEXT_POSITION = TEXT_POS_LEFT_UP | |
| 29 | 39 | |
| 30 | 40 | # Slice orientation |
| 31 | 41 | AXIAL = 0 | ... | ... |
invesalius/data/slice_data.py
| ... | ... | @@ -19,6 +19,7 @@ |
| 19 | 19 | import vtk |
| 20 | 20 | |
| 21 | 21 | import constants as const |
| 22 | +import vtk_utils as vu | |
| 22 | 23 | |
| 23 | 24 | class SliceData(object): |
| 24 | 25 | def __init__(self): |
| ... | ... | @@ -31,18 +32,13 @@ class SliceData(object): |
| 31 | 32 | |
| 32 | 33 | def __create_text(self): |
| 33 | 34 | colour = const.ORIENTATION_COLOUR[self.orientation] |
| 34 | - text_property = vtk.vtkTextProperty() | |
| 35 | - text_property.SetColor(colour) | |
| 36 | - text_property.SetFontSize(16) | |
| 37 | - text_property.SetFontFamilyToTimes() | |
| 38 | - text_property.BoldOn() | |
| 39 | - self.text_property = text_property | |
| 40 | 35 | |
| 41 | - text_actor = vtk.vtkTextActor() | |
| 42 | - text_actor.SetInput("%d" % self.number) | |
| 43 | - text_actor.GetTextProperty().ShallowCopy(text_property) | |
| 44 | - text_actor.SetPosition(10, 10) | |
| 45 | - self.text_actor = text_actor | |
| 36 | + text = vu.Text() | |
| 37 | + text.SetColour(colour) | |
| 38 | + text.SetPosition(const.TEXT_POS_LEFT_DOWN_SLC) | |
| 39 | + text.SetSize(const.TEXT_SIZE_LARGE) | |
| 40 | + text.SetValue("%d" % self.number) | |
| 41 | + self.text = text | |
| 46 | 42 | |
| 47 | 43 | def SetCursor(self, cursor): |
| 48 | 44 | if self.cursor: |
| ... | ... | @@ -52,18 +48,17 @@ class SliceData(object): |
| 52 | 48 | |
| 53 | 49 | def SetNumber(self, number): |
| 54 | 50 | self.number = number |
| 55 | - self.text_actor.SetInput("%d" % self.number) | |
| 51 | + self.text.SetValue("%d" % self.number) | |
| 56 | 52 | |
| 57 | 53 | def SetOrientation(self, orientation): |
| 58 | 54 | self.orientation = orientation |
| 59 | 55 | colour = const.ORIENTATION_COLOUR[self.orientation] |
| 60 | - self.text_property.SetColor(colour) | |
| 61 | - self.text_actor.GetTextProperty().ShallowCopy(self.text_property) | |
| 56 | + self.text.SetColour(colour) | |
| 62 | 57 | |
| 63 | 58 | def Hide(self): |
| 64 | 59 | self.renderer.RemoveActor(self.actor) |
| 65 | - self.renderer.RemoveActor(self.text_actor) | |
| 60 | + self.renderer.RemoveActor(self.text.actor) | |
| 66 | 61 | |
| 67 | 62 | def Show(self): |
| 68 | 63 | self.renderer.AddActor(self.actor) |
| 69 | - self.renderer.AddActor(self.text_actor) | |
| 64 | + self.renderer.AddActor(self.text.actor) | ... | ... |
invesalius/data/viewer_slice.py
| ... | ... | @@ -37,6 +37,7 @@ import project |
| 37 | 37 | from slice_data import SliceData |
| 38 | 38 | |
| 39 | 39 | ID_TO_TOOL_ITEM = {} |
| 40 | +STR_WL = "WL: %d WW: %d" | |
| 40 | 41 | |
| 41 | 42 | class Viewer(wx.Panel): |
| 42 | 43 | |
| ... | ... | @@ -66,7 +67,7 @@ class Viewer(wx.Panel): |
| 66 | 67 | self._brush_cursor_colour = const.BRUSH_COLOUR |
| 67 | 68 | self._brush_cursor_type = const.DEFAULT_BRUSH_OP |
| 68 | 69 | self.cursor = None |
| 69 | - self.text = None | |
| 70 | + self.wl_text = None | |
| 70 | 71 | # VTK pipeline and actors |
| 71 | 72 | #self.__config_interactor() |
| 72 | 73 | self.pick = vtk.vtkPropPicker() |
| ... | ... | @@ -107,6 +108,11 @@ class Viewer(wx.Panel): |
| 107 | 108 | |
| 108 | 109 | def SetLayout(self, layout): |
| 109 | 110 | self.layout = layout |
| 111 | + if layout == (1,1): | |
| 112 | + self.wl_text.Show() | |
| 113 | + else: | |
| 114 | + self.wl_text.Hide() | |
| 115 | + | |
| 110 | 116 | slice_ = sl.Slice() |
| 111 | 117 | self.LoadRenderers(slice_.GetOutput()) |
| 112 | 118 | self.__configure_renderers() |
| ... | ... | @@ -262,9 +268,10 @@ class Viewer(wx.Panel): |
| 262 | 268 | ps.Publisher().sendMessage('Bright and contrast adjustment image', |
| 263 | 269 | (self.acum_achange_window, self.acum_achange_level)) |
| 264 | 270 | |
| 265 | - ps.Publisher().sendMessage('Update window and level text',\ | |
| 266 | - "WL: %d WW: %d"%(self.acum_achange_level,\ | |
| 267 | - self.acum_achange_window)) | |
| 271 | + | |
| 272 | + self.SetWLText(self.acum_achange_level, | |
| 273 | + self.acum_achange_window) | |
| 274 | + | |
| 268 | 275 | |
| 269 | 276 | const.WINDOW_LEVEL['Manual'] = (self.acum_achange_window,\ |
| 270 | 277 | self.acum_achange_level) |
| ... | ... | @@ -361,19 +368,18 @@ class Viewer(wx.Panel): |
| 361 | 368 | slice_data.cursor.Show(0) |
| 362 | 369 | self.interactor.Render() |
| 363 | 370 | |
| 364 | - def UpdateText(self, pubsub_evt): | |
| 365 | - if (self.text): | |
| 366 | - self.text.SetValue(pubsub_evt.data) | |
| 371 | + def SetWLText(self, window_width, window_level): | |
| 372 | + value = STR_WL%(window_width, window_level) | |
| 373 | + if (self.wl_text): | |
| 374 | + self.wl_text.SetValue(value) | |
| 367 | 375 | self.interactor.Render() |
| 368 | 376 | |
| 369 | 377 | def EnableText(self): |
| 370 | - if not (self.text): | |
| 371 | - text = self.text = vtku.Text() | |
| 378 | + if not (self.wl_text): | |
| 379 | + text = self.wl_text = vtku.Text() | |
| 372 | 380 | self.ren.AddActor(text.actor) |
| 373 | 381 | proj = project.Project() |
| 374 | - | |
| 375 | - ps.Publisher().sendMessage('Update window and level text',\ | |
| 376 | - "WL: %d WW: %d"%(proj.level, proj.window)) | |
| 382 | + self.SetWLText(proj.level, proj.window) | |
| 377 | 383 | |
| 378 | 384 | |
| 379 | 385 | def Reposition(self, slice_data): |
| ... | ... | @@ -722,9 +728,7 @@ class Viewer(wx.Panel): |
| 722 | 728 | ps.Publisher().subscribe(self.__set_mode_cross, |
| 723 | 729 | ('Set interaction mode', |
| 724 | 730 | const.MODE_SLICE_CROSS)) |
| 725 | - #### | |
| 726 | - ps.Publisher().subscribe(self.UpdateText,\ | |
| 727 | - 'Update window and level text') | |
| 731 | + | |
| 728 | 732 | ps.Publisher().subscribe(self.UpdateWindowLevelValue,\ |
| 729 | 733 | 'Update window level value') |
| 730 | 734 | |
| ... | ... | @@ -750,12 +754,12 @@ class Viewer(wx.Panel): |
| 750 | 754 | imagedata, mask_dict = pubsub_evt.data |
| 751 | 755 | self.SetInput(imagedata, mask_dict) |
| 752 | 756 | |
| 753 | - def LoadRenderers(self, image): | |
| 757 | + def LoadRenderers(self, imagedata): | |
| 754 | 758 | number_renderers = self.layout[0] * self.layout[1] |
| 755 | 759 | diff = number_renderers - len(self.slice_data_list) |
| 756 | 760 | if diff > 0: |
| 757 | 761 | for i in xrange(diff): |
| 758 | - slice_data = self.create_slice_window(image) | |
| 762 | + slice_data = self.create_slice_window(imagedata) | |
| 759 | 763 | self.slice_data_list.append(slice_data) |
| 760 | 764 | elif diff < 0: |
| 761 | 765 | to_remove = self.slice_data_list[number_renderers::] |
| ... | ... | @@ -771,10 +775,20 @@ class Viewer(wx.Panel): |
| 771 | 775 | n = 0 |
| 772 | 776 | for j in xrange(self.layout[1]-1, -1, -1): |
| 773 | 777 | for i in xrange(self.layout[0]): |
| 774 | - position = ((i*proportion_x, j * proportion_y, | |
| 775 | - (i+1)*proportion_x, (j+1)*proportion_y)) | |
| 778 | + slice_xi = i*proportion_x | |
| 779 | + slice_xf = (i+1)*proportion_x | |
| 780 | + slice_yi = j*proportion_y | |
| 781 | + slice_yf = (j+1)*proportion_y | |
| 782 | + | |
| 783 | + position = (slice_xi, slice_yi, slice_xf, slice_yf) | |
| 776 | 784 | slice_data = self.slice_data_list[n] |
| 777 | 785 | slice_data.renderer.SetViewport(position) |
| 786 | + x = slice_xi + (0.03*proportion_x) | |
| 787 | + ratio = 0 | |
| 788 | + if self.layout[1] > 1: | |
| 789 | + ratio = 0.04 | |
| 790 | + y = slice_yi +(0.09*proportion_y)+ratio | |
| 791 | + slice_data.text.SetPosition((x,y)) | |
| 778 | 792 | slice_data.SetCursor(self.__create_cursor()) |
| 779 | 793 | self.__update_camera(slice_data) |
| 780 | 794 | n += 1 |
| ... | ... | @@ -811,22 +825,6 @@ class Viewer(wx.Panel): |
| 811 | 825 | self.ren = ren |
| 812 | 826 | self.cam = ren.GetActiveCamera() |
| 813 | 827 | |
| 814 | - colour = const.ORIENTATION_COLOUR[self.orientation] | |
| 815 | - | |
| 816 | - text_property = vtk.vtkTextProperty() | |
| 817 | - text_property.SetFontSize(16) | |
| 818 | - text_property.SetFontFamilyToTimes() | |
| 819 | - text_property.BoldOn() | |
| 820 | - text_property.SetColor(colour) | |
| 821 | - | |
| 822 | - text_actor = vtk.vtkTextActor() | |
| 823 | - text_actor.SetInput("%d" % self.slice_number) | |
| 824 | - text_actor.GetTextProperty().ShallowCopy(text_property) | |
| 825 | - text_actor.SetPosition(1,1) | |
| 826 | - self.text_actor = text_actor | |
| 827 | - | |
| 828 | - #ren.AddActor(actor) | |
| 829 | - #ren.AddActor(text_actor) | |
| 830 | 828 | for slice_data in self.slice_data_list: |
| 831 | 829 | self.__update_camera(slice_data) |
| 832 | 830 | self.Reposition(slice_data) |
| ... | ... | @@ -989,11 +987,6 @@ class Viewer(wx.Panel): |
| 989 | 987 | slice_number = slice_data.number |
| 990 | 988 | actor_bound = slice_data.actor.GetBounds() |
| 991 | 989 | |
| 992 | ||
| 993 | - #print self.orientation | |
| 994 | - #print x, y, z | |
| 995 | - #print actor_bound | |
| 996 | - | |
| 997 | 990 | yz = [x + abs(x * 0.001), y, z] |
| 998 | 991 | xz = [x, y - abs(y * 0.001), z] |
| 999 | 992 | xy = [x, y, z + abs(z * 0.001)] |
| ... | ... | @@ -1025,7 +1018,7 @@ class Viewer(wx.Panel): |
| 1025 | 1018 | slice_data.renderer = renderer |
| 1026 | 1019 | slice_data.actor = actor |
| 1027 | 1020 | renderer.AddActor(actor) |
| 1028 | - renderer.AddActor(slice_data.text_actor) | |
| 1021 | + renderer.AddActor(slice_data.text.actor) | |
| 1029 | 1022 | return slice_data |
| 1030 | 1023 | |
| 1031 | 1024 | def __update_camera(self, slice_data): |
| ... | ... | @@ -1135,7 +1128,6 @@ class Viewer(wx.Panel): |
| 1135 | 1128 | evt.Skip() |
| 1136 | 1129 | |
| 1137 | 1130 | def set_slice_number(self, index): |
| 1138 | - self.text_actor.SetInput(str(index)) | |
| 1139 | 1131 | self.slice_number = index |
| 1140 | 1132 | for n, slice_data in enumerate(self.slice_data_list): |
| 1141 | 1133 | ren = slice_data.renderer | ... | ... |
invesalius/data/vtk_utils.py
| ... | ... | @@ -109,6 +109,12 @@ class Text(object): |
| 109 | 109 | actor.GetPositionCoordinate().SetValue(x,y) |
| 110 | 110 | self.actor = actor |
| 111 | 111 | |
| 112 | + def SetColour(self, colour): | |
| 113 | + self.property.SetColor(colour) | |
| 114 | + | |
| 115 | + def SetSize(self, size): | |
| 116 | + self.property.SetFontSize(size) | |
| 117 | + | |
| 112 | 118 | def SetValue(self, value): |
| 113 | 119 | self.mapper.SetInput(str(value)) |
| 114 | 120 | |
| ... | ... | @@ -116,6 +122,9 @@ class Text(object): |
| 116 | 122 | self.actor.GetPositionCoordinate().SetValue(position[0], |
| 117 | 123 | position[1]) |
| 118 | 124 | |
| 125 | + def GetPosition(self, position): | |
| 126 | + self.actor.GetPositionCoordinate().GetValue() | |
| 127 | + | |
| 119 | 128 | def SetJustificationToRight(self): |
| 120 | 129 | self.property.SetJustificationToRight() |
| 121 | 130 | ... | ... |
invesalius/gui/dicom_preview_panel.py
| ... | ... | @@ -60,7 +60,7 @@ class SingleImagePreview(wx.Panel): |
| 60 | 60 | actor = vtk.vtkImageActor() |
| 61 | 61 | self.actor = actor |
| 62 | 62 | |
| 63 | - LEFT_UP = (X, Y) = const.TEXT_POSITION | |
| 63 | + LEFT_UP = (X, Y) = const.TEXT_POS_LEFT_UP | |
| 64 | 64 | text_image_size = vtku.Text() |
| 65 | 65 | text_image_size.SetPosition(LEFT_UP) |
| 66 | 66 | text_image_size.SetValue("image size") | ... | ... |