Commit 940329e661e279a0ec11a807fdf817e8fae7153e
1 parent
85c57f6f
Exists in
master
and in
6 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,10 +22,20 @@ import wx | ||
22 | 22 | ||
23 | from project import Project | 23 | from project import Project |
24 | 24 | ||
25 | + | ||
26 | +#--------------- | ||
27 | + | ||
25 | # VTK text | 28 | # VTK text |
26 | TEXT_SIZE = 12 | 29 | TEXT_SIZE = 12 |
30 | +TEXT_SIZE_LARGE = 18 | ||
27 | TEXT_COLOUR = (1,1,1) | 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 | # Slice orientation | 40 | # Slice orientation |
31 | AXIAL = 0 | 41 | AXIAL = 0 |
invesalius/data/slice_data.py
@@ -19,6 +19,7 @@ | @@ -19,6 +19,7 @@ | ||
19 | import vtk | 19 | import vtk |
20 | 20 | ||
21 | import constants as const | 21 | import constants as const |
22 | +import vtk_utils as vu | ||
22 | 23 | ||
23 | class SliceData(object): | 24 | class SliceData(object): |
24 | def __init__(self): | 25 | def __init__(self): |
@@ -31,18 +32,13 @@ class SliceData(object): | @@ -31,18 +32,13 @@ class SliceData(object): | ||
31 | 32 | ||
32 | def __create_text(self): | 33 | def __create_text(self): |
33 | colour = const.ORIENTATION_COLOUR[self.orientation] | 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 | def SetCursor(self, cursor): | 43 | def SetCursor(self, cursor): |
48 | if self.cursor: | 44 | if self.cursor: |
@@ -52,18 +48,17 @@ class SliceData(object): | @@ -52,18 +48,17 @@ class SliceData(object): | ||
52 | 48 | ||
53 | def SetNumber(self, number): | 49 | def SetNumber(self, number): |
54 | self.number = number | 50 | self.number = number |
55 | - self.text_actor.SetInput("%d" % self.number) | 51 | + self.text.SetValue("%d" % self.number) |
56 | 52 | ||
57 | def SetOrientation(self, orientation): | 53 | def SetOrientation(self, orientation): |
58 | self.orientation = orientation | 54 | self.orientation = orientation |
59 | colour = const.ORIENTATION_COLOUR[self.orientation] | 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 | def Hide(self): | 58 | def Hide(self): |
64 | self.renderer.RemoveActor(self.actor) | 59 | self.renderer.RemoveActor(self.actor) |
65 | - self.renderer.RemoveActor(self.text_actor) | 60 | + self.renderer.RemoveActor(self.text.actor) |
66 | 61 | ||
67 | def Show(self): | 62 | def Show(self): |
68 | self.renderer.AddActor(self.actor) | 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,6 +37,7 @@ import project | ||
37 | from slice_data import SliceData | 37 | from slice_data import SliceData |
38 | 38 | ||
39 | ID_TO_TOOL_ITEM = {} | 39 | ID_TO_TOOL_ITEM = {} |
40 | +STR_WL = "WL: %d WW: %d" | ||
40 | 41 | ||
41 | class Viewer(wx.Panel): | 42 | class Viewer(wx.Panel): |
42 | 43 | ||
@@ -66,7 +67,7 @@ class Viewer(wx.Panel): | @@ -66,7 +67,7 @@ class Viewer(wx.Panel): | ||
66 | self._brush_cursor_colour = const.BRUSH_COLOUR | 67 | self._brush_cursor_colour = const.BRUSH_COLOUR |
67 | self._brush_cursor_type = const.DEFAULT_BRUSH_OP | 68 | self._brush_cursor_type = const.DEFAULT_BRUSH_OP |
68 | self.cursor = None | 69 | self.cursor = None |
69 | - self.text = None | 70 | + self.wl_text = None |
70 | # VTK pipeline and actors | 71 | # VTK pipeline and actors |
71 | #self.__config_interactor() | 72 | #self.__config_interactor() |
72 | self.pick = vtk.vtkPropPicker() | 73 | self.pick = vtk.vtkPropPicker() |
@@ -107,6 +108,11 @@ class Viewer(wx.Panel): | @@ -107,6 +108,11 @@ class Viewer(wx.Panel): | ||
107 | 108 | ||
108 | def SetLayout(self, layout): | 109 | def SetLayout(self, layout): |
109 | self.layout = layout | 110 | self.layout = layout |
111 | + if layout == (1,1): | ||
112 | + self.wl_text.Show() | ||
113 | + else: | ||
114 | + self.wl_text.Hide() | ||
115 | + | ||
110 | slice_ = sl.Slice() | 116 | slice_ = sl.Slice() |
111 | self.LoadRenderers(slice_.GetOutput()) | 117 | self.LoadRenderers(slice_.GetOutput()) |
112 | self.__configure_renderers() | 118 | self.__configure_renderers() |
@@ -262,9 +268,10 @@ class Viewer(wx.Panel): | @@ -262,9 +268,10 @@ class Viewer(wx.Panel): | ||
262 | ps.Publisher().sendMessage('Bright and contrast adjustment image', | 268 | ps.Publisher().sendMessage('Bright and contrast adjustment image', |
263 | (self.acum_achange_window, self.acum_achange_level)) | 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 | const.WINDOW_LEVEL['Manual'] = (self.acum_achange_window,\ | 276 | const.WINDOW_LEVEL['Manual'] = (self.acum_achange_window,\ |
270 | self.acum_achange_level) | 277 | self.acum_achange_level) |
@@ -361,19 +368,18 @@ class Viewer(wx.Panel): | @@ -361,19 +368,18 @@ class Viewer(wx.Panel): | ||
361 | slice_data.cursor.Show(0) | 368 | slice_data.cursor.Show(0) |
362 | self.interactor.Render() | 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 | self.interactor.Render() | 375 | self.interactor.Render() |
368 | 376 | ||
369 | def EnableText(self): | 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 | self.ren.AddActor(text.actor) | 380 | self.ren.AddActor(text.actor) |
373 | proj = project.Project() | 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 | def Reposition(self, slice_data): | 385 | def Reposition(self, slice_data): |
@@ -722,9 +728,7 @@ class Viewer(wx.Panel): | @@ -722,9 +728,7 @@ class Viewer(wx.Panel): | ||
722 | ps.Publisher().subscribe(self.__set_mode_cross, | 728 | ps.Publisher().subscribe(self.__set_mode_cross, |
723 | ('Set interaction mode', | 729 | ('Set interaction mode', |
724 | const.MODE_SLICE_CROSS)) | 730 | const.MODE_SLICE_CROSS)) |
725 | - #### | ||
726 | - ps.Publisher().subscribe(self.UpdateText,\ | ||
727 | - 'Update window and level text') | 731 | + |
728 | ps.Publisher().subscribe(self.UpdateWindowLevelValue,\ | 732 | ps.Publisher().subscribe(self.UpdateWindowLevelValue,\ |
729 | 'Update window level value') | 733 | 'Update window level value') |
730 | 734 | ||
@@ -750,12 +754,12 @@ class Viewer(wx.Panel): | @@ -750,12 +754,12 @@ class Viewer(wx.Panel): | ||
750 | imagedata, mask_dict = pubsub_evt.data | 754 | imagedata, mask_dict = pubsub_evt.data |
751 | self.SetInput(imagedata, mask_dict) | 755 | self.SetInput(imagedata, mask_dict) |
752 | 756 | ||
753 | - def LoadRenderers(self, image): | 757 | + def LoadRenderers(self, imagedata): |
754 | number_renderers = self.layout[0] * self.layout[1] | 758 | number_renderers = self.layout[0] * self.layout[1] |
755 | diff = number_renderers - len(self.slice_data_list) | 759 | diff = number_renderers - len(self.slice_data_list) |
756 | if diff > 0: | 760 | if diff > 0: |
757 | for i in xrange(diff): | 761 | for i in xrange(diff): |
758 | - slice_data = self.create_slice_window(image) | 762 | + slice_data = self.create_slice_window(imagedata) |
759 | self.slice_data_list.append(slice_data) | 763 | self.slice_data_list.append(slice_data) |
760 | elif diff < 0: | 764 | elif diff < 0: |
761 | to_remove = self.slice_data_list[number_renderers::] | 765 | to_remove = self.slice_data_list[number_renderers::] |
@@ -771,10 +775,20 @@ class Viewer(wx.Panel): | @@ -771,10 +775,20 @@ class Viewer(wx.Panel): | ||
771 | n = 0 | 775 | n = 0 |
772 | for j in xrange(self.layout[1]-1, -1, -1): | 776 | for j in xrange(self.layout[1]-1, -1, -1): |
773 | for i in xrange(self.layout[0]): | 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 | slice_data = self.slice_data_list[n] | 784 | slice_data = self.slice_data_list[n] |
777 | slice_data.renderer.SetViewport(position) | 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 | slice_data.SetCursor(self.__create_cursor()) | 792 | slice_data.SetCursor(self.__create_cursor()) |
779 | self.__update_camera(slice_data) | 793 | self.__update_camera(slice_data) |
780 | n += 1 | 794 | n += 1 |
@@ -811,22 +825,6 @@ class Viewer(wx.Panel): | @@ -811,22 +825,6 @@ class Viewer(wx.Panel): | ||
811 | self.ren = ren | 825 | self.ren = ren |
812 | self.cam = ren.GetActiveCamera() | 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 | for slice_data in self.slice_data_list: | 828 | for slice_data in self.slice_data_list: |
831 | self.__update_camera(slice_data) | 829 | self.__update_camera(slice_data) |
832 | self.Reposition(slice_data) | 830 | self.Reposition(slice_data) |
@@ -989,11 +987,6 @@ class Viewer(wx.Panel): | @@ -989,11 +987,6 @@ class Viewer(wx.Panel): | ||
989 | slice_number = slice_data.number | 987 | slice_number = slice_data.number |
990 | actor_bound = slice_data.actor.GetBounds() | 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 | yz = [x + abs(x * 0.001), y, z] | 990 | yz = [x + abs(x * 0.001), y, z] |
998 | xz = [x, y - abs(y * 0.001), z] | 991 | xz = [x, y - abs(y * 0.001), z] |
999 | xy = [x, y, z + abs(z * 0.001)] | 992 | xy = [x, y, z + abs(z * 0.001)] |
@@ -1025,7 +1018,7 @@ class Viewer(wx.Panel): | @@ -1025,7 +1018,7 @@ class Viewer(wx.Panel): | ||
1025 | slice_data.renderer = renderer | 1018 | slice_data.renderer = renderer |
1026 | slice_data.actor = actor | 1019 | slice_data.actor = actor |
1027 | renderer.AddActor(actor) | 1020 | renderer.AddActor(actor) |
1028 | - renderer.AddActor(slice_data.text_actor) | 1021 | + renderer.AddActor(slice_data.text.actor) |
1029 | return slice_data | 1022 | return slice_data |
1030 | 1023 | ||
1031 | def __update_camera(self, slice_data): | 1024 | def __update_camera(self, slice_data): |
@@ -1135,7 +1128,6 @@ class Viewer(wx.Panel): | @@ -1135,7 +1128,6 @@ class Viewer(wx.Panel): | ||
1135 | evt.Skip() | 1128 | evt.Skip() |
1136 | 1129 | ||
1137 | def set_slice_number(self, index): | 1130 | def set_slice_number(self, index): |
1138 | - self.text_actor.SetInput(str(index)) | ||
1139 | self.slice_number = index | 1131 | self.slice_number = index |
1140 | for n, slice_data in enumerate(self.slice_data_list): | 1132 | for n, slice_data in enumerate(self.slice_data_list): |
1141 | ren = slice_data.renderer | 1133 | ren = slice_data.renderer |
invesalius/data/vtk_utils.py
@@ -109,6 +109,12 @@ class Text(object): | @@ -109,6 +109,12 @@ class Text(object): | ||
109 | actor.GetPositionCoordinate().SetValue(x,y) | 109 | actor.GetPositionCoordinate().SetValue(x,y) |
110 | self.actor = actor | 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 | def SetValue(self, value): | 118 | def SetValue(self, value): |
113 | self.mapper.SetInput(str(value)) | 119 | self.mapper.SetInput(str(value)) |
114 | 120 | ||
@@ -116,6 +122,9 @@ class Text(object): | @@ -116,6 +122,9 @@ class Text(object): | ||
116 | self.actor.GetPositionCoordinate().SetValue(position[0], | 122 | self.actor.GetPositionCoordinate().SetValue(position[0], |
117 | position[1]) | 123 | position[1]) |
118 | 124 | ||
125 | + def GetPosition(self, position): | ||
126 | + self.actor.GetPositionCoordinate().GetValue() | ||
127 | + | ||
119 | def SetJustificationToRight(self): | 128 | def SetJustificationToRight(self): |
120 | self.property.SetJustificationToRight() | 129 | self.property.SetJustificationToRight() |
121 | 130 |
invesalius/gui/dicom_preview_panel.py
@@ -60,7 +60,7 @@ class SingleImagePreview(wx.Panel): | @@ -60,7 +60,7 @@ class SingleImagePreview(wx.Panel): | ||
60 | actor = vtk.vtkImageActor() | 60 | actor = vtk.vtkImageActor() |
61 | self.actor = actor | 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 | text_image_size = vtku.Text() | 64 | text_image_size = vtku.Text() |
65 | text_image_size.SetPosition(LEFT_UP) | 65 | text_image_size.SetPosition(LEFT_UP) |
66 | text_image_size.SetValue("image size") | 66 | text_image_size.SetValue("image size") |