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 | 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") | ... | ... |