Commit 8f68c9cd843276e3385345e6650394d32163ce38
1 parent
30c6a6ab
Exists in
master
and in
26 other branches
Only testing
Showing
3 changed files
with
84 additions
and
4 deletions
Show diff stats
invesalius/data/converters.py
... | ... | @@ -56,3 +56,25 @@ def to_vtk(n_array, spacing, slice_number, orientation): |
56 | 56 | image_copy.DeepCopy(image) |
57 | 57 | |
58 | 58 | return image_copy |
59 | + | |
60 | + | |
61 | +def np_rgba_to_vtk(n_array, spacing=(1.0, 1.0, 1.0)): | |
62 | + dy, dx, dc = n_array.shape | |
63 | + v_image = numpy_support.numpy_to_vtk(n_array.reshape(dy*dx, dc)) | |
64 | + | |
65 | + extent = (0, dx -1, 0, dy -1, 0, 0) | |
66 | + | |
67 | + # Generating the vtkImageData | |
68 | + image = vtk.vtkImageData() | |
69 | + image.SetOrigin(0, 0, 0) | |
70 | + image.SetSpacing(spacing) | |
71 | + image.SetDimensions(dx, dy, 1) | |
72 | + # SetNumberOfScalarComponents and SetScalrType were replaced by | |
73 | + # AllocateScalars | |
74 | + # image.SetNumberOfScalarComponents(1) | |
75 | + # image.SetScalarType(numpy_support.get_vtk_array_type(n_array.dtype)) | |
76 | + image.AllocateScalars(numpy_support.get_vtk_array_type(n_array.dtype), dc) | |
77 | + image.SetExtent(extent) | |
78 | + image.GetPointData().SetScalars(v_image) | |
79 | + | |
80 | + return image | ... | ... |
invesalius/data/slice_data.py
invesalius/data/viewer_slice.py
... | ... | @@ -23,7 +23,7 @@ import collections |
23 | 23 | import itertools |
24 | 24 | import tempfile |
25 | 25 | |
26 | -import numpy | |
26 | +import numpy as np | |
27 | 27 | |
28 | 28 | import vtk |
29 | 29 | from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor |
... | ... | @@ -46,6 +46,8 @@ import project |
46 | 46 | import slice_data as sd |
47 | 47 | import utils |
48 | 48 | |
49 | +from data import converters | |
50 | + | |
49 | 51 | from data import measures |
50 | 52 | |
51 | 53 | ID_TO_TOOL_ITEM = {} |
... | ... | @@ -144,6 +146,50 @@ class ContourMIPConfig(wx.Panel): |
144 | 146 | self.txt_mip_border.Disable() |
145 | 147 | |
146 | 148 | |
149 | +class CanvasRendererCTX: | |
150 | + def __init__(self, viewer): | |
151 | + self.viewer = viewer | |
152 | + self.canvas_renderer = viewer.slice_data.canvas_renderer | |
153 | + self._size = self.canvas_renderer.GetSize() | |
154 | + self._init_canvas() | |
155 | + viewer.slice_data.renderer.AddObserver("EndEvent", self.OnPaint) | |
156 | + | |
157 | + def _init_canvas(self): | |
158 | + w, h = self._size | |
159 | + self._array = np.empty((h, w, 4), dtype=np.uint8) | |
160 | + | |
161 | + self._cv_image = converters.np_rgba_to_vtk(self._array) | |
162 | + | |
163 | + self.mapper = vtk.vtkImageMapper() | |
164 | + self.mapper.SetInputData(self._cv_image) | |
165 | + self.mapper.SetColorWindow(255) | |
166 | + self.mapper.SetColorLevel(128) | |
167 | + | |
168 | + self.actor = vtk.vtkActor2D() | |
169 | + self.actor.SetPosition(0, 0) | |
170 | + self.actor.SetMapper(self.mapper) | |
171 | + self.actor.GetProperty().SetOpacity(0.99) | |
172 | + | |
173 | + self.canvas_renderer.AddActor2D(self.actor) | |
174 | + | |
175 | + def _resize_canvas(self, w, h): | |
176 | + self._array = np.empty((h, w, 4), dtype=np.uint8) | |
177 | + self._cv_image = converters.np_rgba_to_vtk(self._array) | |
178 | + self.mapper.SetInputData(self._cv_image) | |
179 | + self.mapper.Update() | |
180 | + | |
181 | + def OnPaint(self, evt, obj): | |
182 | + size = self.canvas_renderer.GetSize() | |
183 | + w, h = size | |
184 | + if self._size != size: | |
185 | + self._size = size | |
186 | + self._resize_canvas(w, h) | |
187 | + | |
188 | + self._array[:] = 0 | |
189 | + self._array[150:500, 150:500, 0] = 255 | |
190 | + self._array[150:500, 150:500, 3] = 127 | |
191 | + self._cv_image.Modified() | |
192 | + | |
147 | 193 | |
148 | 194 | class Viewer(wx.Panel): |
149 | 195 | |
... | ... | @@ -896,6 +942,8 @@ class Viewer(wx.Panel): |
896 | 942 | self.cam = self.slice_data.renderer.GetActiveCamera() |
897 | 943 | self.__build_cross_lines() |
898 | 944 | |
945 | + canvas = CanvasRendererCTX(self) | |
946 | + | |
899 | 947 | # Set the slice number to the last slice to ensure the camera if far |
900 | 948 | # enough to show all slices. |
901 | 949 | self.set_slice_number(max_slice_number - 1) |
... | ... | @@ -958,13 +1006,20 @@ class Viewer(wx.Panel): |
958 | 1006 | renderer.SetLayer(0) |
959 | 1007 | cam = renderer.GetActiveCamera() |
960 | 1008 | |
1009 | + canvas_renderer = vtk.vtkRenderer() | |
1010 | + canvas_renderer.SetLayer(1) | |
1011 | + canvas_renderer.SetActiveCamera(cam) | |
1012 | + canvas_renderer.SetInteractive(0) | |
1013 | + canvas_renderer.PreserveDepthBufferOn() | |
1014 | + | |
961 | 1015 | overlay_renderer = vtk.vtkRenderer() |
962 | - overlay_renderer.SetLayer(1) | |
1016 | + overlay_renderer.SetLayer(2) | |
963 | 1017 | overlay_renderer.SetActiveCamera(cam) |
964 | 1018 | overlay_renderer.SetInteractive(0) |
965 | - | |
966 | - self.interactor.GetRenderWindow().SetNumberOfLayers(2) | |
1019 | + | |
1020 | + self.interactor.GetRenderWindow().SetNumberOfLayers(3) | |
967 | 1021 | self.interactor.GetRenderWindow().AddRenderer(overlay_renderer) |
1022 | + self.interactor.GetRenderWindow().AddRenderer(canvas_renderer) | |
968 | 1023 | self.interactor.GetRenderWindow().AddRenderer(renderer) |
969 | 1024 | |
970 | 1025 | actor = vtk.vtkImageActor() |
... | ... | @@ -974,12 +1029,14 @@ class Viewer(wx.Panel): |
974 | 1029 | slice_data = sd.SliceData() |
975 | 1030 | slice_data.SetOrientation(self.orientation) |
976 | 1031 | slice_data.renderer = renderer |
1032 | + slice_data.canvas_renderer = canvas_renderer | |
977 | 1033 | slice_data.overlay_renderer = overlay_renderer |
978 | 1034 | slice_data.actor = actor |
979 | 1035 | slice_data.SetBorderStyle(sd.BORDER_ALL) |
980 | 1036 | renderer.AddActor(actor) |
981 | 1037 | renderer.AddActor(slice_data.text.actor) |
982 | 1038 | renderer.AddViewProp(slice_data.box_actor) |
1039 | + | |
983 | 1040 | return slice_data |
984 | 1041 | |
985 | 1042 | def __update_camera(self): | ... | ... |