Correct usage of SetPixelAspect() or possible workaround

Hi,

I would like to render my scene anisotropically , pixels stretched or compressed, the python vtk code below doesn’t seems to produce the expected behavior, no detectable distortion with any value specified.

import vtk

sphere = vtk.vtkSphereSource()
sphere.SetRadius(5.0)
sphere.SetThetaResolution(48)
sphere.SetPhiResolution(48)

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(sphere.GetOutputPort())

actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(0.2, 0.35, 0.8)

renderer = vtk.vtkRenderer()
renderer.AddActor(actor)
renderer.SetBackground(0.9, 0.9, 0.9)

renderer.SetPixelAspect(1, 0.5)

renWin = vtk.vtkRenderWindow()
renWin.SetSize(600, 600)
renWin.AddRenderer(renderer)

iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

renWin.Render()
iren.Initialize()
iren.Start()

Thank for your advice,

Context: Im developing a workaround for the problem of missing depth in stereo rendering while using GPU raycast volume mappers. I need my viewports to be squashed horizontally because the 3d display will stretch the side by side content to overlay them on the display.

I did a quick check, and I can confirm that calling PixelAspect() here seems to have no effect on the rendering, even though the Aspect is correctly computed during the rendering process.

PixelAspect: (1.0, 0.5)    
Aspect: (1.0, 0.5)    

I also tried with an extremely old version of VTK (5.10) and it behaved exactly the same way.

Oddly, the TiledAspectRatio is 1.0. This is the aspect ratio that the Renderer actually uses to set up the camera:

TiledAspectRatio: 1.0    

The c++ code for GetTiledAspectRatio() shows what is happening. The aspect is being divided by itself, resulting in a value of 1.0:

double vtkRenderer::GetTiledAspectRatio()                                       
{                                                                               
  int usize, vsize;                                                             
  this->GetTiledSize(&usize, &vsize);                                           
                                                                                
  // some renderer subclasses may have more complicated computations for the    
  // aspect ratio. SO take that into account by computing the difference        
  // between our simple aspect ratio and what the actual renderer is            
  // reporting.                                                                 
  double aspect[2];                                                             
  this->ComputeAspect();                                                        
  this->GetAspect(aspect);                                                      
  double aspect2[2];                                                            
  this->vtkViewport::ComputeAspect();                                           
  this->vtkViewport::GetAspect(aspect2);                                        
  double aspectModification = aspect[0] * aspect2[1] / (aspect[1] * aspect2[0]);
                                                                                
  double finalAspect = 1.0;                                                     
  if (vsize && usize)                                                           
  {                                                                             
    finalAspect = aspectModification * usize / vsize;                           
  }                                                                             
  return finalAspect;                                                           
}     

This GetTiledAspectRatio() code was written in 2004 (according to git), and I can’t see any rationale for it being this way unless there used to be vtkRenderer subclasses that would query the aspect ratio directly from the video hardware. Even then, I’m not sure I understand the logic.

Thanks for your insights, interesting. It is looks like an easy and possibly safe fix.

In the meantime, is there any workaround that worth trying to achieve anisotropic rendering?