How to copy zbuffer after window interaction

I am trying to figure out how to obtain the zbuffer for a view after I have interacted with it. I am just starting with VTK. Here is the code that I have so far,

# Create a render window, and interactor
renderWindow = vtkRenderWindow()
renderWindow.SetSize(800, 600)

# Create renderer + add to renderwindow
renderer = vtkRenderer()
renderWindow.AddRenderer(renderer)

def key_press(obj,key):
    if obj.GetKeySym() == "u":
       # get depth buffer
       z_buffer_data = vtkFloatArray()
       rmax, cmax = renderWindow.GetActualSize()

       # 0,0 starts at lower left
       renderWindow.GetZbufferData(0, 0, cmax-1, rmax-1, z_buffer_data)

       # convert to numpy
       z_buffer_data_numpy = numpy_support.vtk_to_numpy(z_buffer_data)
       z_buffer_data_numpy = np.reshape(z_buffer_data_numpy, (-1, cmax))

    return z_buffer_data_numpy
        
# Create interactor
renderWindowInteractor = vtkRenderWindowInteractor()
renderWindowInteractor.SetInteractorStyle(vtkInteractorStyleTerrain())
renderWindowInteractor.SetRenderWindow(renderWindow)
renderWindowInteractor.AddObserver("KeyPressEvent", key_press)

How can I get ‘z_buffer_data_numpy’ and proceed with other calculations?

Hi,

Well, off the top of my head, you can either set a gobal variable or subclass vtk.vtkInteractorStyleTrackballCamera: How to get the key code in a vtk KeyPressEvent using python - Stack Overflow for a better designed way to get in-event data.

regards,

Paulo

Thanks Paulo,

Unfortunately this example (and others I have found) only show how you can print the key being pressed. I want to be able to dump the zbuffer into a numpy array but I do not know how to pass the actual array (I am able to print it and that looks fine). I just would like for the values to be returned.

M.

No, look at the example again, you can design the subclass to add any additional members you like. You can use them to fetch any information you need after the event is processed.

The only way that I managed to get the z-buffer was by defining the variable within the keypressed function to be global (I think you had mentioned this as a possibility earlier). But could not find other clues otherwise.

Global variables are not regarded as a good practice from the design standpoint. Use it sparingly and document it plenty. Again, I guess you know how to code classes in Python, so, you I can tell you a global variable is not the only way.

Yes. In fact I have never used global variables. But, right now, I cannot say that I see how to return the zbuffer without recourse to using it??? I altered the code you pointed towards but that is modifying the interactor style class which is then ‘associated’ with a renderWindowInteractor. So I am lost as to how to access this through the interactor style class. I just starting to get accustomed to VTK…

M.

Hi,

Sorry if I sound nitpicking, but we don’t say the custom class is associated with but extends (the current OOP jargon) vtkInteractorStyleTrackballCamera. To extend a class is to create a new class that has everything vtkInteractorStyleTrackballCamera has plus new features you want to add:

class MyInteractorStyle(vtk.vtkInteractorStyleTrackballCamera):

    def __init__(self,parent=None):
        self.parent = iren
        self.AddObserver("KeyPressEvent",self.keyPressEvent)
        self.pressed_key = '\0'  #<--- this is a new member variable.

    def keyPressEvent(self,obj,event):
        key = self.parent.GetKeySym()
        if key == 'l':
            print(key)
        #save the pressed key to the member variable so we can access it later.
        self.pressed_key = key
        return

(...)

iren = vtk.vtkRenderWindowInteractor()

my_interactor = MyInteractorStyle()

iren.SetInteractorStyle( my_interactor )

iren.SetRenderWindow(renWin)
renWin.Render()

iren.Initialize()
iren.Start()

#print the key that was pressed last.
print( "The last key pressed is ", my_interactor.key_pressed ) 

I hope this helps,

Paulo

Thank you Paulo. That worked great!!

1 Like