[vtkusers] Update position of multiple render windows

Citizen Snips amb2189 at rit.edu
Mon Jul 7 12:16:07 EDT 2014


(I'm copy/pasting this from my StackOverflow post since it's pretty
well-developed so far. Forgive me if that's an offense)

I'm running into a bit of a problem when trying to run multiple render
windows in a Python VTK application I'm writing. The application is an
attempt to render a 3D model in two separate views for a stereo application
(i.e. Left render and right render), but I'm having an issue with updating
the cameras of each window simultaneously. I currently have two nearly
identical pipelines set up, each with its own vtkCamera, vtkRenderWindow,
vtkRenderer, and vtkRenderWindowInteractor, the only difference being that
the right camera is positionally shifted 30 units along the X axis.

Each of the render window interactors is being updated via the
vtkRenderWindowInteractor.AddObserver() method that calls a simple function
to reset the cameras to their original positions and orientations. The
biggest issue is that this only seems to occur on one window at a time,
specifically the window in focus at the time. It's as if the interactor's
timer just shuts off once the interactor loses focus. In addition, when I
hold down the mouse (And thus move the camera around), the rendered image
begins to 'drift', resetting to a less and less correct position even though
I have hardcoded the coordinates into the function.

Obviously I'm very new to VTK, and much of what goes on is fairly confusing
as so much is hidden in the backend, so it would be amazing to acquire some
assistance on the matter. My code is below. Thanks guys!

from vtk import*
from parse import *
import os
import time, signal, threading

def ParseSIG(signum, stack):
        print signum
        return

class vtkGyroCallback():
        def __init__(self):
                pass
        def execute(self, obj, event):
                #Modified segment to accept input for leftCam position
                gyro = (raw_input())
                xyz = parse("{} {} {}", gyro)
                #This still prints every 100ms, but camera doesn't update!
                print xyz

                #These arguments are updated and the call is made.
                self.leftCam.SetPosition(float(xyz[0]), float(xyz[1]),
float(xyz[2]))
                self.leftCam.SetFocalPoint(0,0,0)
                self.leftCam.SetViewUp(0,1,0)
                self.leftCam.OrthogonalizeViewUp()

                self.rightCam.SetPosition(10, 40, 100)
                self.rightCam.SetFocalPoint(0,0,0)
                self.rightCam.SetViewUp(0,1,0)
                self.rightCam.OrthogonalizeViewUp()

                #Just a guess
                obj.Update()
                return

def main():

        # create two cameras
        cameraR = vtkCamera()
        cameraR.SetPosition(0,0,200)
        cameraR.SetFocalPoint(0,0,0)

        cameraL = vtkCamera()
        cameraL.SetPosition(40,0,200)
        cameraL.SetFocalPoint(0,0,0)



        # create a rendering window and renderer
        renR = vtkRenderer()
        renR.SetActiveCamera(cameraR)

        renL = vtkRenderer()
        renL.SetActiveCamera(cameraL)

        # create source
        reader = vtkPolyDataReader()
        path =
"/home/compilezone/Documents/3DSlicer/SlicerScenes/LegoModel-6_25/Model_5_blood.vtk"
        reader.SetFileName(path)
        reader.Update()

        # create render window

        renWinR = vtkRenderWindow()
        renWinR.AddRenderer(renR)
        renWinR.SetWindowName("Right")

        renWinL = vtkRenderWindow()
        renWinL.AddRenderer(renL)
        renWinL.SetWindowName("Left")

        # create a render window interactor
        irenR = vtkRenderWindowInteractor()
        irenR.SetRenderWindow(renWinR)

        irenL = vtkRenderWindowInteractor()
        irenL.SetRenderWindow(renWinL)

        # mapper
        mapper = vtkPolyDataMapper()
        mapper.SetInput(reader.GetOutput())

        # actor
        actor = vtkActor()
        actor.SetMapper(mapper)

        # assign actor to the renderer
        renR.AddActor(actor)
        renL.AddActor(actor)

        # enable user interface interactor
        renWinR.Render()
        renWinL.Render()
        irenR.Initialize()
        irenL.Initialize()

        #Create callback object for camera manipulation
        cb = vtkGyroCallback()
        cb.rightCam = cameraR
        cb.leftCam = cameraL
        renWinR.AddObserver('InteractionEvent', cb.execute)
        renWinL.AddObserver('InteractionEvent', cb.execute)
        irenR.AddObserver('TimerEvent', cb.execute)
        irenL.AddObserver('TimerEvent', cb.execute)
        timerIDR = irenR.CreateRepeatingTimer(100)
        timerIDL = irenL.CreateRepeatingTimer(100)

        irenR.Start()
        irenL.Start()

if __name__ == '__main__':
    main()

EDIT 1: I modified the code to accept user input for the
self.leftCam.SetPosition() call within the vtkGyroCallback.execute() method
(Thus replacing the hardcoded "10, 40, 100" parameters with three input
variables) then piped the output of a script that simply displayed three
random values into my main program. What this should have accomplished was
having a render window that would constantly change position. Instead,
nothing happens until I click on the screen, at which point the expected
functionality begins. The whole time, timer events are still firing and
inputs are still being accepted, yet the cameras refuse to update until a
mouse event occurs within the scope of their window. What is the deal?

EDIT 2 I've dug around some more and found that within the
vtkObject::InvokeEvent() method that is called within every interaction
event there is a focus loop that overrides all observers that do not pertain
to the object in focus. I'm going to investigate if there is a way to remove
focus so that it will instead bypass this focus loop and go to the unfocused
loop that handles non focused objects. 



--
View this message in context: http://vtk.1045678.n5.nabble.com/Update-position-of-multiple-render-windows-tp5727775.html
Sent from the VTK - Users mailing list archive at Nabble.com.


More information about the vtkusers mailing list