9

I'm trying to open a vtk window using vtk_show, but my Ipython console crashes every time i do this, apparently this is because Ipython can't display an external window, which is exactly what vtk_show does. I searched on google for a solution, but it's written for python2 (i'm using python 3.6.3). Here's the solution i found:

import vtk
from IPython.display import Image

def vtk_show(renderer, width=400, height=300):
    """
    Takes vtkRenderer instance and returns an IPython Image with the 
    rendering.
    """
    renderWindow = vtk.vtkRenderWindow()
    renderWindow.SetOffScreenRendering(1)
    renderWindow.AddRenderer(renderer)
    renderWindow.SetSize(width, height)
    renderWindow.Render()

    windowToImageFilter = vtk.vtkWindowToImageFilter()
    windowToImageFilter.SetInput(renderWindow)
    windowToImageFilter.Update()

    writer = vtk.vtkPNGWriter()
    writer.SetWriteToMemory(1)
    writer.SetInputConnection(windowToImageFilter.GetOutputPort())
    writer.Write()
    data = str(buffer(writer.GetResult()))

    return Image(data)

I'm getting an error while trying to use the buffer built-in function of python2, but as this function doesn't exist on python3+ i'm stuck.. If anyone could help me with this i would be very appreciated. Thanks in advance!

tomas-silveira
  • 593
  • 3
  • 5
  • 14

2 Answers2

13

At least these two points must be modified on your code to have the same behavior with Python 3:

So the data = ... line should read:

data = bytes(memoryview(writer.GetResult()))
jcgiret
  • 728
  • 7
  • 12
  • 1
    What do you mean by it didn’t work? Could you post the error message? Also, could you you precise that in your initial post? – jcgiret May 04 '18 at 08:57
  • I think it comes from the str call now. Try to change the line ‘data=...’ in ‘data = memoryview(writer.GetResults()).tobytes()’ – jcgiret May 04 '18 at 09:12
  • Hey again and sorry for the very late response! i managed to fix the error i was getting and completely forgot to come here. – tomas-silveira May 07 '18 at 17:40
  • No worries! Note that you can answer your own question! – jcgiret May 07 '18 at 18:34
  • This worked for fixing the example code for [pyzmq](https://pyzmq.readthedocs.io/en/latest/serialization.html) as well. – Mason Jun 25 '19 at 19:43
1

To clarify, I believe this example was an adaptation of a very informative blog example showing how to extract surfaces from medical images using VTK's marching cubes algorithm. The accompanying Jupyter notebook was intended for Python 2.7, and as mentioned for it to be used in Python 3.6+, the data=... portion needs to be changed.

import vtk
from IPython.display import Image

def vtk_show(renderer, width=400, height=300):
    """
    Takes vtkRenderer instance and returns an IPython Image with the 
    rendering.
    """
    renderWindow = vtk.vtkRenderWindow()
    renderWindow.SetOffScreenRendering(1)
    renderWindow.AddRenderer(renderer)
    renderWindow.SetSize(width, height)
    renderWindow.Render()

    windowToImageFilter = vtk.vtkWindowToImageFilter()
    windowToImageFilter.SetInput(renderWindow)
    windowToImageFilter.Update()

    writer = vtk.vtkPNGWriter()
    writer.SetWriteToMemory(1)
    writer.SetInputConnection(windowToImageFilter.GetOutputPort())
    writer.Write()
    data = memoryview(writer.GetResults()).tobytes()

    return Image(data)

Credit for the solution definitely goes to @MafiaSkafia and @jcgiret, but I wanted to post a full and final solution.

amandagb
  • 11
  • 1