BUGRPT: VTK 3.1 & Python callbacks

Randall Hopper aa8vb at yahoo.com
Mon May 15 14:07:22 EDT 2000


     Here's a trivial translation of the VTK expCos2.tcl example to Python.
It appears that VTK 3.1 doesn't check for error when returning from a
Python callback (e.g. bessel in the example), so if there is an error (bad
variable name, divide by zero, etc.), the user won't have any way of
knowing except that the network doesn't work.

     FWIW, I wanted to make sure that Programmable Source object callbacks
were implemented and working well in the Python wrappers before using one
in my tool.  Translating the example was an easy way to do that.  Except
for the missing error propagation just described, they seem to work well.

Thanks,

Randall
-------------- next part --------------
#!/usr/bin/env python
#
# This example demonstrates how to use a programmable source and how to use
# the special vtkDataSetToDataSet::GetOutput() methods (i.e., see
# vtkWarpScalar)
#

import os, math
from libVTKCommonPython import *
from libVTKGraphicsPython import *
from colors import *

# create pipeline - use a programmable source to compute Bessel function and
# generate a plane of quadrilateral polygons,
#
besselSource = vtkProgrammableSource()
besselSource.SetExecuteMethod( lambda source=besselSource: bessel(source) )

# VTK 3.1 doesn't detect and print errors occuring in a Python callback.
#   This is easy to do by checking whether the return value of the function
#   was NULL.  As a result, if a Python callback such as bessel() has a bug
#   in it and throws an exception (e.g. NameError, AttributeError, etc.),
#   the user won't have any way of knowing except that the network won't
#   work.
#
# For example, delete the "math." from the math.sin() invocation below.
#   This will generate a NameError.  No error message will be printed
#   when bessel() returns; the pipeline will just fail somewhere downstream.
#

# Generate plane with Bessel function scalar values.
# It's interesting to compare this with vtkPlaneSource.
def bessel( source ):

  ( XRes, XOrigin, XWidth ) = ( 25, -5.0, 10.0 )
  ( YRes, YOrigin, YWidth ) = ( 40, -5.0, 10.0 )

  newPts   = vtkPoints()
  newPolys = vtkCellArray()
  derivs   = vtkScalars()

  # Compute points and scalars
  id = 0
  for j in range( YRes+1 ):
    x1 = YOrigin + float(j) / YRes * YWidth
    for i in range( XRes+1 ):
      x0 = XOrigin + float(i) / XRes * XWidth

      r     = math.sqrt( x0*x0 + x1*x1 )
      x2    = math.exp( -r ) * math.cos( 10.0 * r )
      deriv = -math.exp( -r ) * ( math.cos( 10.0*r ) +
                                  10.0 * math.sin( 10.0*r ) )

      newPts.InsertPoint( id, x0, x1, x2 )
      derivs.InsertScalar( id, deriv )
      id = id + 1
  
  # Generate polygon connectivity
  for j in range( YRes ):
    for i in range( XRes ):
      newPolys.InsertNextCell( 4 )
      id = i + j * (XRes+1)
      newPolys.InsertCellPoint( id )
      newPolys.InsertCellPoint( id + 1 )
      newPolys.InsertCellPoint( id + XRes + 2 )
      newPolys.InsertCellPoint( id + XRes + 1 )

  source.GetPolyDataOutput().SetPoints( newPts   )
  source.GetPolyDataOutput().SetPolys ( newPolys )
  source.GetPolyDataOutput().GetPointData().SetScalars( derivs )
  
  newPts.Delete()           #reference counting - it's ok
  newPolys.Delete()
  derivs.Delete()
  
# warp plane
warp = vtkWarpScalar()
warp.SetInput( besselSource.GetPolyDataOutput() )
warp.XYPlaneOn()
warp.SetScaleFactor( 0.5 )

# mapper and actor
mapper = vtkPolyDataMapper()
mapper.SetInput( warp.GetPolyDataOutput() )

# NOTE:  The queried scalar range will be 0..1 because we haven't updated the
#   source yet (i.e. besselSource.Update()).  The full range is actually
#   around (-7.1,4.0), but (0,1) produces more colorful results.
mapper.SetScalarRange( besselSource.GetPolyDataOutput().GetScalarRange() )
carpet = vtkActor()
carpet.SetMapper( mapper )

# assign our actor to the renderer

# Create graphics stuff
# Create the RenderWindow, Renderer and both Actors
#
ren1 = vtkRenderer()
renWin = vtkRenderWindow()
renWin.AddRenderer( ren1 )
iren = vtkRenderWindowInteractor()
iren.SetRenderWindow( renWin )

ren1.AddActor( carpet )
renWin.SetSize( 500, 500 )

# render the image
#
ren1.GetActiveCamera().Zoom( 1.5 )
renWin.Render()
#renWin.SetFileName( "expCos2.tcl.ppm" )
#renWin.SaveImageAsPPM()

# enable user interface interactor
iren.Initialize()

iren.Start()


More information about the vtkusers mailing list