Commit 03258f78c496a44699c4f5a4b7186ff100171961
1 parent
fb4bd5e7
Exists in
master
and in
68 other branches
ENH: Show more then a slice by window
Showing
1 changed file
with
48 additions
and
20 deletions
Show diff stats
invesalius/data/viewer_slice.py
@@ -41,6 +41,10 @@ class Viewer(wx.Panel): | @@ -41,6 +41,10 @@ class Viewer(wx.Panel): | ||
41 | self.modes = []#['DEFAULT'] | 41 | self.modes = []#['DEFAULT'] |
42 | self.mouse_pressed = 0 | 42 | self.mouse_pressed = 0 |
43 | 43 | ||
44 | + # All renderers and image actors in this viewer | ||
45 | + self.image_windows = [] | ||
46 | + self.slice_dispostion = (2, 2) | ||
47 | + | ||
44 | self.__init_gui() | 48 | self.__init_gui() |
45 | 49 | ||
46 | self.orientation = orientation | 50 | self.orientation = orientation |
@@ -179,11 +183,13 @@ class Viewer(wx.Panel): | @@ -179,11 +183,13 @@ class Viewer(wx.Panel): | ||
179 | self.mouse_pressed = 1 | 183 | self.mouse_pressed = 1 |
180 | 184 | ||
181 | mouse_x, mouse_y = self.interactor.GetEventPosition() | 185 | mouse_x, mouse_y = self.interactor.GetEventPosition() |
182 | - self.pick.Pick(mouse_x, mouse_y, 0, self.ren) | 186 | + render = self.interactor.FindPokedRenderer(mouse_x, mouse_y) |
187 | + actor = self.get_image_window(render) | ||
188 | + self.pick.Pick(mouse_x, mouse_y, 0, render) | ||
183 | 189 | ||
184 | coord = self.GetCoordinateCursor() | 190 | coord = self.GetCoordinateCursor() |
185 | self.cursor.SetPosition(coord) | 191 | self.cursor.SetPosition(coord) |
186 | - self.cursor.SetEditionPosition(self.GetCoordinateCursorEdition()) | 192 | + self.cursor.SetEditionPosition(self.GetCoordinateCursorEdition(actor)) |
187 | self.__update_cursor_position(coord) | 193 | self.__update_cursor_position(coord) |
188 | self.ren.Render() | 194 | self.ren.Render() |
189 | 195 | ||
@@ -203,10 +209,12 @@ class Viewer(wx.Panel): | @@ -203,10 +209,12 @@ class Viewer(wx.Panel): | ||
203 | 209 | ||
204 | def OnBrushMove(self, obj, evt_vtk): | 210 | def OnBrushMove(self, obj, evt_vtk): |
205 | mouse_x, mouse_y = self.interactor.GetEventPosition() | 211 | mouse_x, mouse_y = self.interactor.GetEventPosition() |
206 | - self.pick.Pick(mouse_x, mouse_y, 0, self.ren) | 212 | + render = self.interactor.FindPokedRenderer(mouse_x, mouse_y) |
213 | + actor = self.get_image_window(render) | ||
214 | + self.pick.Pick(mouse_x, mouse_y, 0, render) | ||
207 | coord = self.GetCoordinateCursor() | 215 | coord = self.GetCoordinateCursor() |
208 | self.cursor.SetPosition(coord) | 216 | self.cursor.SetPosition(coord) |
209 | - self.cursor.SetEditionPosition(self.GetCoordinateCursorEdition()) | 217 | + self.cursor.SetEditionPosition(self.GetCoordinateCursorEdition(actor)) |
210 | self.__update_cursor_position(coord) | 218 | self.__update_cursor_position(coord) |
211 | 219 | ||
212 | if self._brush_cursor_op == const.BRUSH_ERASE: | 220 | if self._brush_cursor_op == const.BRUSH_ERASE: |
@@ -237,6 +245,11 @@ class Viewer(wx.Panel): | @@ -237,6 +245,11 @@ class Viewer(wx.Panel): | ||
237 | ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), | 245 | ps.Publisher().sendMessage(('Set scroll position', 'AXIAL'), |
238 | coord[2]) | 246 | coord[2]) |
239 | 247 | ||
248 | + def get_image_window(self, render): | ||
249 | + for r, a in self.image_windows: | ||
250 | + if r is render: | ||
251 | + return a | ||
252 | + | ||
240 | def GetCoordinate(self): | 253 | def GetCoordinate(self): |
241 | # Find position | 254 | # Find position |
242 | x, y, z = self.pick.GetPickPosition() | 255 | x, y, z = self.pick.GetPickPosition() |
@@ -280,12 +293,12 @@ class Viewer(wx.Panel): | @@ -280,12 +293,12 @@ class Viewer(wx.Panel): | ||
280 | x, y, z = self.pick.GetPickPosition() | 293 | x, y, z = self.pick.GetPickPosition() |
281 | return x, y, z | 294 | return x, y, z |
282 | 295 | ||
283 | - def GetCoordinateCursorEdition(self): | 296 | + def GetCoordinateCursorEdition(self, actor): |
284 | # Find position | 297 | # Find position |
285 | x, y, z = self.pick.GetPickPosition() | 298 | x, y, z = self.pick.GetPickPosition() |
286 | 299 | ||
287 | # First we fix the position origin, based on vtkActor bounds | 300 | # First we fix the position origin, based on vtkActor bounds |
288 | - bounds = self.actor.GetBounds() | 301 | + bounds = actor.GetBounds() |
289 | bound_xi, bound_xf, bound_yi, bound_yf, bound_zi, bound_zf = bounds | 302 | bound_xi, bound_xf, bound_yi, bound_yf, bound_zi, bound_zf = bounds |
290 | x = float(x - bound_xi) | 303 | x = float(x - bound_xi) |
291 | y = float(y - bound_yi) | 304 | y = float(y - bound_yi) |
@@ -338,6 +351,18 @@ class Viewer(wx.Panel): | @@ -338,6 +351,18 @@ class Viewer(wx.Panel): | ||
338 | imagedata = pubsub_evt.data | 351 | imagedata = pubsub_evt.data |
339 | self.SetInput(imagedata) | 352 | self.SetInput(imagedata) |
340 | 353 | ||
354 | + def load_renderers(self, image): | ||
355 | + proportion_x = 1.0 / self.slice_dispostion[0] | ||
356 | + proportion_y = 1.0 / self.slice_dispostion[1] | ||
357 | + for i in xrange(self.slice_dispostion[0]): | ||
358 | + for j in xrange(self.slice_dispostion[1]): | ||
359 | + position = ((i*proportion_x, j * proportion_y, | ||
360 | + (i+1)*proportion_x, (j+1)*proportion_y)) | ||
361 | + ren, actor = self.create_slice_window(image) | ||
362 | + ren.SetViewport(position) | ||
363 | + self.image_windows.append((ren, actor)) | ||
364 | + | ||
365 | + | ||
341 | def SetInput(self, imagedata): | 366 | def SetInput(self, imagedata): |
342 | self.imagedata = imagedata | 367 | self.imagedata = imagedata |
343 | 368 | ||
@@ -352,7 +377,8 @@ class Viewer(wx.Panel): | @@ -352,7 +377,8 @@ class Viewer(wx.Panel): | ||
352 | 377 | ||
353 | #actor = vtk.vtkImageActor() | 378 | #actor = vtk.vtkImageActor() |
354 | #actor.SetInput(slice_.GetOutput()) | 379 | #actor.SetInput(slice_.GetOutput()) |
355 | - ren, actor = self.add_actor(slice_.GetOutput()) | 380 | + self.load_renderers(slice_.GetOutput()) |
381 | + ren, actor = self.image_windows[0] | ||
356 | actor_bound = actor.GetBounds() | 382 | actor_bound = actor.GetBounds() |
357 | self.actor = actor | 383 | self.actor = actor |
358 | self.ren = ren | 384 | self.ren = ren |
@@ -374,7 +400,8 @@ class Viewer(wx.Panel): | @@ -374,7 +400,8 @@ class Viewer(wx.Panel): | ||
374 | 400 | ||
375 | #ren.AddActor(actor) | 401 | #ren.AddActor(actor) |
376 | #ren.AddActor(text_actor) | 402 | #ren.AddActor(text_actor) |
377 | - self.__update_camera() | 403 | + for ren, actor in self.image_windows: |
404 | + self.__update_camera(ren, actor) | ||
378 | 405 | ||
379 | max_slice_number = actor.GetSliceNumberMax() | 406 | max_slice_number = actor.GetSliceNumberMax() |
380 | self.scroll.SetScrollbar(wx.SB_VERTICAL, 1, max_slice_number, | 407 | self.scroll.SetScrollbar(wx.SB_VERTICAL, 1, max_slice_number, |
@@ -408,9 +435,10 @@ class Viewer(wx.Panel): | @@ -408,9 +435,10 @@ class Viewer(wx.Panel): | ||
408 | 435 | ||
409 | def SetOrientation(self, orientation): | 436 | def SetOrientation(self, orientation): |
410 | self.orientation = orientation | 437 | self.orientation = orientation |
411 | - self.__update_camera() | 438 | + for ren, actor in self.image_windows: |
439 | + self.__update_camera(ren, actor) | ||
412 | 440 | ||
413 | - def add_actor(self, image): | 441 | + def create_slice_window(self, image): |
414 | render = vtk.vtkRenderer() | 442 | render = vtk.vtkRenderer() |
415 | self.interactor.GetRenderWindow().AddRenderer(render) | 443 | self.interactor.GetRenderWindow().AddRenderer(render) |
416 | actor = vtk.vtkImageActor() | 444 | actor = vtk.vtkImageActor() |
@@ -418,10 +446,10 @@ class Viewer(wx.Panel): | @@ -418,10 +446,10 @@ class Viewer(wx.Panel): | ||
418 | render.AddActor(actor) | 446 | render.AddActor(actor) |
419 | return render, actor | 447 | return render, actor |
420 | 448 | ||
421 | - def __update_camera(self): | 449 | + def __update_camera(self, ren, actor): |
422 | orientation = self.orientation | 450 | orientation = self.orientation |
423 | 451 | ||
424 | - cam = self.cam | 452 | + cam = ren.GetActiveCamera() |
425 | cam.SetFocalPoint(0, 0, 0) | 453 | cam.SetFocalPoint(0, 0, 0) |
426 | cam.SetPosition(const.CAM_POSITION[self.orientation]) | 454 | cam.SetPosition(const.CAM_POSITION[self.orientation]) |
427 | cam.SetViewUp(const.CAM_VIEW_UP[self.orientation]) | 455 | cam.SetViewUp(const.CAM_VIEW_UP[self.orientation]) |
@@ -429,12 +457,12 @@ class Viewer(wx.Panel): | @@ -429,12 +457,12 @@ class Viewer(wx.Panel): | ||
429 | cam.OrthogonalizeViewUp() | 457 | cam.OrthogonalizeViewUp() |
430 | cam.ParallelProjectionOn() | 458 | cam.ParallelProjectionOn() |
431 | 459 | ||
432 | - self.__update_display_extent() | 460 | + self.__update_display_extent(actor, ren) |
433 | 461 | ||
434 | - self.ren.ResetCamera() | ||
435 | - self.ren.Render() | 462 | + ren.ResetCamera() |
463 | + ren.Render() | ||
436 | 464 | ||
437 | - def __update_display_extent(self): | 465 | + def __update_display_extent(self, actor, render): |
438 | pos = self.slice_number | 466 | pos = self.slice_number |
439 | e = self.imagedata.GetWholeExtent() | 467 | e = self.imagedata.GetWholeExtent() |
440 | 468 | ||
@@ -442,9 +470,9 @@ class Viewer(wx.Panel): | @@ -442,9 +470,9 @@ class Viewer(wx.Panel): | ||
442 | "CORONAL": (e[0], e[1], pos, pos, e[4], e[5]), | 470 | "CORONAL": (e[0], e[1], pos, pos, e[4], e[5]), |
443 | "AXIAL": (e[0], e[1], e[2], e[3], pos, pos)} | 471 | "AXIAL": (e[0], e[1], e[2], e[3], pos, pos)} |
444 | 472 | ||
445 | - self.actor.SetDisplayExtent(new_extent[self.orientation]) | ||
446 | - self.ren.ResetCameraClippingRange() | ||
447 | - self.ren.Render() | 473 | + actor.SetDisplayExtent(new_extent[self.orientation]) |
474 | + render.ResetCameraClippingRange() | ||
475 | + render.Render() | ||
448 | 476 | ||
449 | def UpdateRender(self, evt): | 477 | def UpdateRender(self, evt): |
450 | self.interactor.Render() | 478 | self.interactor.Render() |
@@ -481,7 +509,7 @@ class Viewer(wx.Panel): | @@ -481,7 +509,7 @@ class Viewer(wx.Panel): | ||
481 | def SetSliceNumber(self, index): | 509 | def SetSliceNumber(self, index): |
482 | self.text_actor.SetInput(str(index)) | 510 | self.text_actor.SetInput(str(index)) |
483 | self.slice_number = index | 511 | self.slice_number = index |
484 | - self.__update_display_extent() | 512 | + self.__update_display_extent(self.actor, self.ren) |
485 | 513 | ||
486 | position = {"SAGITAL": {0: self.slice_number}, | 514 | position = {"SAGITAL": {0: self.slice_number}, |
487 | "CORONAL": {1: self.slice_number}, | 515 | "CORONAL": {1: self.slice_number}, |