class GraphKit
class VTKObjectGroup
#The Python vtk module
attr_accessor :vtk_module
# The VTK object which reads the file
attr_accessor :reader
# The output of the Reader
attr_accessor :output
# The VTK mapper (which converts the data to image data)
attr_accessor :mapper
# The VTK actor which is responsible for the data
# within the window
attr_accessor :actor
# The VTK renderer which renders the image data
attr_accessor :renderer
# The VTK object which connects to the renderer
# and should be connected to an image writer to
# write image files.
attr_accessor :large_image_renderer
# The VTK window object into which the data is rendered
# It is what causes the renderer to act.
attr_accessor :renderer_window
# The VTK interactor
attr_accessor :interactor
end
# This module contains methods for rendering GraphKits
# using the Visualization Toolkit (VTK). It uses the
# Python interface to VTK via the RubyPython bridge
# (see rubygems.org/gems/rubypython).
#
# It should work with vtk and vtk-python installed
# on any Linux distro.
#
# If you want to use it on a supercomputer you will
# almost certainly have to build Python and VTK yourself.
#
# The instructions below have been tested on Hector but
# can be easily adapted to work anywhere.
#
# First you need to configure your system to use the GNU
# compilers and with dynamic linking enabled. The instructions
# for configuring your system for installing CodeRunner should
# work well. See the CodeRunner wiki (coderunner.sourceforge.net).
#
# Choose a directory to install everything: myprefix.
#
# Download the source for Python 2.x (2.7 works as of Dec 2012),
# extract it and build it (with shared libraries) as follows.
# $ cd Python-2.7.3
# $ ./configure --prefix= --enable-shared LDFLAGS="-Wl,-rpath
# VTK_WRAP_PYTHON on
# VTK_USE_RENDERING on
# VTK_USE_X off
# VTK_OPENGL_HAS_OSMESA on
#
# The last two settings mean that VTK won't try to pop up windows when
# it is rendering: instead it will write them straight to file.
# OSMESA stands for Off Screen Mesa, where Mesa is the open source
# graphics library.
#
# Press 'c' to update the configuration.
# Now update the following settings:
# PYTHON_EXECUTABLE /bin/python
# PYTHON_INCLUDE_DIR /include/python2.x
# PYTHON_LIBRARY /lib/libpython2.x.so
# VTK_USE_OFFSCREEN on
#
#
# Here is the funky bit: we don't want to use the standard hardware-enabled
# OpenGL libraries because we want to render offscreen. The standard OpenGL
# conflicts with OSMESA and makes SEGFAULTS (yuk). Instead we can have OSMESA
# replace all their functionality by setting
# OPENGL_glu_LIBRARY
# OPENGL_gl_LIBRARY
# to the same value as
# OSMESA_LIBRARY
#
# This will of course not be as fast, but that's OK because we are going
# to parallelise over the supercomputer when we write our rendering scripts!
#
# Press 'c' to configure once more, and 'g' to generate the makefiles.
# Now build
# $ make # This will take about 40 mins.
# $ make install
#
# Finally we need to setup python: add these lines to your .bashrc
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib/vtk-5.10/
# export PYTHONPATH=$PYTHONPATH:/lib/python2.7/site-packages/
# export PATH=/bin:$PATH
module VTK
# This method returns a VTKObjectGroup object, which
# contains references to the VTK/Python objects
# which are necessary to plot the graph.
def vtk_object_group(filename = nil)
# If we are not given a filename, need to write the
# data in VTK format... can change at some point?
temp_write = false
unless filename
temp_write = true
filename = (Time.now.to_i).to_s + rand(1000000).to_s + ".tmp.vtk"
to_vtk_legacy_fast(file_name: filename)
end
require 'rubypython'
RubyPython.start
vtk_og = VTKObjectGroup.new
vtk = vtk_og.vtk_module = RubyPython.import('vtk')
file_name = filename
vtk_og.reader = reader = vtk.vtkUnstructuredGridReader
reader.SetFileName(file_name)
reader.Update
if temp_write
FileUtils.rm(filename)
end
vtk_og.output = output = reader.GetOutput
scalar_range = output.GetScalarRange
vtk_og.mapper = mapper = vtk.vtkDataSetMapper
mapper.SetInput(output)
mapper.SetScalarRange(scalar_range)
look_up_table = vtk.vtkLookupTable
look_up_table.SetNumberOfColors(64)
look_up_table.SetHueRange(0.0, 0.667)
mapper.SetLookupTable(look_up_table)
mapper.SetScalarModeToDefault
#mapper.CreateDefaultLookupTable
mapper.ScalarVisibilityOn
#mapper.SelectColorArray('myvals')
vtk_og.actor = actor = vtk.vtkActor
actor.SetMapper(mapper)
actor.VisibilityOn
vtk_og.renderer = renderer = vtk.vtkRenderer
renderer.AddActor(actor)
#renderer.SetBackground(0,0,0)
vtk_og.renderer_window = renderer_window = vtk.vtkRenderWindow
renderer_window.SetSize(640,480)
renderer_window.AddRenderer(renderer)
render_large = vtk_og.large_image_renderer = vtk.vtkRenderLargeImage
render_large.SetInput(vtk_og.renderer)
render_large.SetMagnification(4)
vtk_og.interactor = interactor = vtk.vtkRenderWindowInteractor
interactor.SetRenderWindow(renderer_window)
interactor.Initialize
#interactor.Start
return vtk_og
end
# Visualise the Graph using the Visualization Toolkit (VTK).
# If output_file is "window", display it in a window;
# otherwise, write to the file, e.g. my_graph.jpg, my_graph.gif
# If input_file is given it sould be a VTK data file. Otherwise
# it will write the data to a temporary VTK legacy data file.
#
# The optional block yields a VTKObjectGroup which contains references
# to all the VTK objects for arbitrary manipulation before
# rendering.
def vtk_render(output_file='window', input_file=nil, &block)
vtk_og = vtk_object_group(filename)
yield(vtk_og) if block
vtk = vtk_og.vtk_module
#filter = vtk.vtkWindowToImageFilter
#vtk_og.renderer_window.SetOffScreenRendering(1)
#gf = vtk.vtkGraphicsFactory
#gf.SetOffScreenOnlyMode(1)
vtk_og.renderer_window.Start
#vtk_og.reader.Update
#vtk_og.renderer.Update
#filter.SetInput(vtk_og.renderer_window)
case File.extname(output_file)
when '.jpeg', '.jpg'
jpeg_writer = vtk.vtkJPEGWriter
#vtk_og.renderer.DeviceRender
#jpeg_writer.SetInput(vtk_og.renderer.GetOutput)
#jpeg_writer.SetInput(render_large.GetOutput)
jpeg_writer.SetInput(vtk_og.large_image_renderer.GetOutput)
#filter.Update
jpeg_writer.SetFileName(output_file)
jpeg_writer.Write
end
vtk_og.renderer_window.Finalize
end
end #module VTK
include VTK
end