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