marcomusy
(Marco Musy)
April 19, 2021, 11:26pm
1
With vtk<9 I could interact with 2 independent rendering windows, eg.:
import vtk
cone = vtk.vtkConeSource()
cone.Update()
coneMapper = vtk.vtkPolyDataMapper()
coneMapper.SetInputData(cone.GetOutput())
coneActor = vtk.vtkActor()
coneActor.SetMapper(coneMapper)
cube = vtk.vtkCubeSource()
cube.Update()
cubeMapper = vtk.vtkPolyDataMapper()
cubeMapper.SetInputData(cube.GetOutput())
cubeActor = vtk.vtkActor()
cubeActor.SetMapper(cubeMapper)
##########################
ren1 = vtk.vtkRenderer()
ren1.AddActor(coneActor)
ren1.SetBackground(1,0.7,1)
renWin1 = vtk.vtkRenderWindow()
renWin1.AddRenderer(ren1)
iren1 = vtk.vtkRenderWindowInteractor()
iren1.SetRenderWindow(renWin1)
renWin1.Render()
renWin1.SetWindowName("window1")
# iren1.Start()
##########################
ren2 = vtk.vtkRenderer()
ren2.AddActor(cubeActor)
ren2.SetBackground(1,1,0.7)
renWin2 = vtk.vtkRenderWindow()
renWin2.SetPosition(400,0)
renWin2.AddRenderer(ren2)
iren2 = vtk.vtkRenderWindowInteractor()
iren2.SetRenderWindow(renWin2)
renWin2.Render()
renWin2.SetWindowName("window2")
iren2.Start()
#iren1.Start()
I could rotate both cone and cube.
Now this is no more the case (window1, the one with with the cone, is unresponsive)… why this difference?
is it a bug now, or was it a bug before? (kind of a useful bug though)
amaclean
(Andrew Maclean)
April 21, 2021, 12:41am
2
It is not a bug. You are running two completely separate pipelines and rendering into separate windows with separate interactors.
You need one render window and interactor and then share the camera between the viewports.
For example here is a quick example based on Model
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import vtk
def main():
colors = vtk.vtkNamedColors()
# Set the colors.
colors.SetColor('CubeColor', [250, 128, 114, 255])
colors.SetColor('BkgColor', [230, 230, 230, 255])
# Create the rendering window and two renderers.
ren_1 = vtk.vtkRenderer()
ren_2 = vtk.vtkRenderer()
ren_win = vtk.vtkRenderWindow()
ren_win.AddRenderer(ren_1)
ren_win.AddRenderer(ren_2)
ren_win.SetWindowName('Model')
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
# Create an actor and give it cone geometry.
cone = vtk.vtkConeSource()
cone.SetResolution(8)
cone_mapper = vtk.vtkPolyDataMapper()
cone_mapper.SetInputConnection(cone.GetOutputPort())
cone_actor = vtk.vtkActor()
cone_actor.SetMapper(cone_mapper)
cone_actor.GetProperty().SetColor(colors.GetColor3d('Peacock'))
# Create an actor and give it cube geometry.
cube = vtk.vtkCubeSource()
cube_mapper = vtk.vtkPolyDataMapper()
cube_mapper.SetInputConnection(cube.GetOutputPort())
cube_actor = vtk.vtkActor()
cube_actor.SetMapper(cube_mapper)
cube_actor.GetProperty().SetColor(colors.GetColor3d('CubeColor'))
# Assign our actors to both renderers.
ren_1.AddActor(cone_actor)
ren_2.AddActor(cube_actor)
camera = ren_1.GetActiveCamera()
ren_2.SetActiveCamera(camera)
ren_1.ResetCamera()
# set the size of our window
ren_win.SetSize(600, 300)
ren_win.SetPosition(0, 50)
# Set the viewports and backgrounds of the renderers.
ren_1.SetViewport(0, 0, 0.5, 1)
ren_1.SetBackground(colors.GetColor3d('BkgColor'))
ren_2.SetViewport(0.5, 0, 1, 1)
ren_2.SetBackground(colors.GetColor3d('Linen'))
# Draw the resulting scene.
ren_win.Render()
iren.Start()
if __name__ == '__main__':
main()
marcomusy
(Marco Musy)
April 21, 2021, 1:01am
3
Yes, they are two completely different pipelines, that is why I am surprised that in vtk8.1.2 the iren2
starts iren1
too, so I can in practice interact with both windows (not renderers) at the same time. This doesn’t happen in vtk9 (which actually looks more logical…).
So question is: can one interact with 2 separate windows at the same time?
Joachim_P
(Joachim P.)
April 21, 2021, 3:41am
4
Haven’t try but you might want to try something like that:
iren1.Initialize()
iren2.Initialize()
while True:
iren1.ProcessEvents()
iren2.ProcessEvents()
In this case, both windows should have the chance to process the interaction-render loop.
marcomusy
(Marco Musy)
April 21, 2021, 9:58am
5
sounds interesting… but no… if I add the above lines, without any iren.Start()
, both windows are frozen in vtk9.
Joachim_P
(Joachim P.)
April 21, 2021, 10:33am
6
Really? I tried it and it works great here.
marcomusy
(Marco Musy)
April 21, 2021, 10:46am
7
uhm, unless i’m doing something silly it doesn’t work in my python 3.8.5:
import vtk
cone = vtk.vtkConeSource()
cone.Update()
coneMapper = vtk.vtkPolyDataMapper()
coneMapper.SetInputData(cone.GetOutput())
coneActor = vtk.vtkActor()
coneActor.SetMapper(coneMapper)
cube = vtk.vtkCubeSource()
cube.Update()
cubeMapper = vtk.vtkPolyDataMapper()
cubeMapper.SetInputData(cube.GetOutput())
cubeActor = vtk.vtkActor()
cubeActor.SetMapper(cubeMapper)
##########################
ren1 = vtk.vtkRenderer()
ren1.AddActor(coneActor)
ren1.SetBackground(1,0.7,1)
renWin1 = vtk.vtkRenderWindow()
renWin1.AddRenderer(ren1)
iren1 = vtk.vtkRenderWindowInteractor()
iren1.SetRenderWindow(renWin1)
renWin1.Render()
renWin1.SetWindowName("window1")
##########################
ren2 = vtk.vtkRenderer()
ren2.AddActor(cubeActor)
ren2.SetBackground(1,1,0.7)
renWin2 = vtk.vtkRenderWindow()
renWin2.SetPosition(400,0)
renWin2.AddRenderer(ren2)
iren2 = vtk.vtkRenderWindowInteractor()
iren2.SetRenderWindow(renWin2)
renWin2.Render()
renWin2.SetWindowName("window2")
iren1.Initialize()
iren2.Initialize()
while True:
iren1.ProcessEvents()
iren2.ProcessEvents()
both windows are unresponsive.
Joachim_P
(Joachim P.)
April 21, 2021, 10:55am
8
I tried with a recent master and under Windows. I will check on Linux and let you know.
1 Like
Joachim_P
(Joachim P.)
April 21, 2021, 11:38am
9
OK so calliing Start()
on one instance of a renderwindowinteractor should actually perform the interaction-render loop on all windows of the threads. And yes, on Windows, it works great if I just call iren2->Start()
.
Then, it appears that on Linux, the bug has been fixed 9 months ago on master: https://gitlab.kitware.com/vtk/vtk/-/merge_requests/7095
Please try with a recent VTK build.
2 Likes
amaclean
(Andrew Maclean)
April 26, 2021, 2:54am
10
I have updated MultipleViewports and produced a corresponding Python example. Please take a look.
Joachim_P
(Joachim P.)
April 26, 2021, 3:36am
11
@amaclean This example is a bit different than what was discussed here as it involves only a single render window and a single interactor. Here we have two of them and a single renderer for each.
amaclean
(Andrew Maclean)
April 26, 2021, 8:39am
12
My apologies, here is the correct link: MultipleRenderWindows . Please note that only the test image can be displayed. You need to run the program to see four windows. There is also a Python version.