<commit_before>===========================
Development guide for TVTK
===========================
:Author: <NAME>
:Contact: <EMAIL>
:Copyright: 2004, Enthought, Inc.

.. contents::


Introduction
============

This document provides some details on how TVTK works and how it is
implemented.  Basic documentation on the installation, features and
usage of tvtk is provided in the README.txt file that should be in the
same directory as this file.


How tvtk works
==============

All tvtk classes derive from `TVTKBase`.  This is defined in
`tvtk_base.py`.  `TVTKBase` provides basic functionality common to all
tvtk classes.  Most importantly it provides for the following:

 * Allows one to wrap an existing VTK object or create a new one.
   `TVTKBase.__init__` accepts an optional VTK object, that can be
   used to wrap an existing VTK object.  Read the method docstring for
   more details.

 * Sets up the event handlers that allow us to listen to any changes
   made to the underlying VTK object.

 * Basic support for pickling the object.

 * The `update_traits` automatically updates the traits of the tvtk
   class such that they reflect the state of the underlying VTK
   object.

 * Common code to change the underlying VTK object when the trait is
   changed.

As mentioned above, tvtk classes can either wrap an existing VTK
object or create a new one and manage the new object.


Automatic trait updation
------------------------

One very important feature of tvtk objects is that any VTK related
traits of object are dynamically updated if the underlying VTK object
is changed.  This is achieved by adding an observer to the VTK object
that effectively calls TVTKBase.update_traits when the 'ModifiedEvent'
is invoked.  Here is an example of a VTK observer callback::

    >>> import vtk
    >>> p = vtk.vtkProperty()
    >>> def cb(obj, evt):
    ...     print obj.__class__.__name__, evt
    ...
    >>> p.AddObserver("ModifiedEvent", cb)
    1
    >>> p.SetRepresentationToWireframe()
    vtkOpenGLProperty ModifiedEvent

As can be seen, when the property is modified, the callback is called.
The trouble with this approach is that `p` now holds a reference to
`cb`.  Thus if `cb` were the `update_traits` method of the tvtk class
that manages the VTK object, we run into a non-garbage-collectable
reference cycle issue and a huge memory leak.  To get around this we
use the functionality provided by `messenger.py`.  Effectively,
`TVTKBase.__init__` tells messenger to call `self.update_traits` when
it is called back from the VTK object.  Messenger itself uses
`weakrefs` so the reference cycle problem does not exist.  The VTK
object basically calls `messenger.send` and `messenger` takes care of
the rest.  This allows the tvtk class to be safely used and also
allows for automatic trait updation.

Each tvtk class has an attribute called `_updateable_traits_`.  This
is a tuple of tuples.  Each tuple contains a pair of strings like so::

    >>> p = tvtk.Property()
    >>> p._updateable_traits_[:4]
    (('opacity', 'GetOpacity'),
     ('frontface_culling', 'GetFrontfaceCulling'),
     ('point_size', 'GetPointSize'),
     ('specular_color', 'GetSpecularColor'))

The first string is the name of the trait and the second the name of
the function used to obtain the value of the trait from the VTK
object. `TVTKBase.update_traits` uses this tuple and for each trait it
calls the relevant VTK 'get' function and updates the value of the
trait.

While this whole process seems to be inefficient, it actually works
quite well in practice and does not appear to be slow at all.


Messaging
---------

The messaging functionality is defined in `tvtk/messenger.py`.  Unit
tests are in the 'tests/' directory.  As described in the previous
section, tvtk objects use the messenger functionality to ensure that
the traits are always up to date.  `messenger.py` is well documented
and tested.  So please read the docstrings for more details.  Here is
some basic information from the documentation.

`messenger.py` implements a simple, robust, safe, `Messenger` class
that allows one to register callbacks for a signal/slot (or
event/handler) kind of messaging system.  One can basically register a
callback function/method to be called when an object sends a
particular event.  The Messenger class is Borg.  So it is easy to
instantiate and use.  This module is also reload-safe, so if the
module is reloaded the callback information is not lost.  Method
callbacks do not have a reference counting problem since weak
references are used.  The main functionality is provided by three
functions, `connect`, `disconnect` and `send`.

`connect` basically allows one to connect an object, `obj`, that emits
an event, `event` to a callback function, `callback`.

When an object calls `send`, it passes itself, the event it wishes to
emit along with any optional arguments and keyword arguments to send.
All registered `callback` for the particular event are called with the
the object that called it (`obj`), the event (`event`) and the
optional arguments.

`disconnect` allows one to disconnect either a particular callback, or
all callbacks for a particular event or the entire object.

The messenger class thus provides a simple observer pattern
implementation that makes it easy to do inter-object communication.
For further details please read the code and docstrings.  Also look at
the test suite in `tests/test_messenger.py`.


Pickling
--------

`TVTKBase` provides the basic functionality for pickling.
Essentially, the dictionary (`self.__dict__`) of the tvtk object is
pickled.  The `_vtk_obj` attribute is not pickled since VTK objects
are not picklable.  Other irrelevant attributes are also removed.
`__setstate__` works even on a live object by checking to see if
`self._vtk_obj` exists.  Some of the tvtk classes override these
methods to implement them better.  For example look at the code for
the `Matrix4x4` class.


Array handling
--------------

TVTK lets the user pass Numeric arrays/Python lists in place of the
`DataArray`, `CellArray`, `Points` etc. classes.  This is done by
finding the call signature of the wrapped VTK method, checking to see
if it has an array and then intelligently generating the appropriate
VTK array data using the signature information.  This generated VTK
data array is then passed to the wrapped function under the covers.
This functionality also works if the method has multiple call
signatures (overloaded VTK method) and one of them involves arrays.
The main functions to do this conversion magic are in the
`array_handler.py` module.  The `wrapper_gen.py` module generates the
appropriate wrapper code depending on the call signature.  So if a
method has no VTK objects in its signature, no wrapping is necessary.
If it only has non-array VTK objects, then array handling is
unnecessary but one must dereference the VTK object from the passed
tvtk wrapper object.  If the call signature involves VTK array
objects, then any Numeric arrays or Python lists are converted to the
correct VTK data array and passed to the wrapped VTK object.

For the efficient conversion to `CellArray` objects, an extension
module is required.  The sources for this extension module are in
`src/array_ext.*`.  The Pyrex_ source file can be used to generate the
`src/array_ext.c` file like so::

  $ cd src
  $ pyrexc array_ext.pyx

The sources ship with the generated source file so that folks without
Pyrex can build it.

`special_gen.py` defines all the additional methods for the
`DataArray` and other classes that allow these objects to support
iteration, `__repr__`, `__getitem__` etc.


.. _Pyrex: http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/


The magical `tvtk` instance
---------------------------

When one does the following::

    >>> from enthought.tvtk.api import tvtk

The imported `tvtk` is really an instance of a class and not a module!
This is so because, the tvtk classes are almost 800 in number and they
wrap around the *entire* VTK API.  VTK itself allows one to import all
the defined classes in one go.  That is, if one does `import vtk`, one
can instantiate all VTK related classes.  This is very useful
functionality.  However, importing 800 wrapper classes in one go is
*extremely* slow.  Thus, `tvtk` provides a convenient solution to get
around the problem.  While `tvtk` is a class instance, it behaves just
like you'd expect of a module.

 * It supports tab-completion on class names.
 * Allows one to access all the tvtk classes.
 * Imports extremely fast.  Any slowness in the import is really<commit_msg>DOC: updating tvtk documentation to refer to Cython (in favor of Pyrex)<commit_after>===========================
Development guide for TVTK
===========================
:Author: <NAME>
:Contact: <EMAIL>
:Copyright: 2004-2011, Enthought, Inc.

.. contents::


Introduction
============

This document provides some details on how TVTK works and how it is
implemented.  Basic documentation on the installation, features and
usage of tvtk is provided in the README.txt file that should be in the
same directory as this file.


How tvtk works
==============

All tvtk classes derive from `TVTKBase`.  This is defined in
`tvtk_base.py`.  `TVTKBase` provides basic functionality common to all
tvtk classes.  Most importantly it provides for the following:

 * Allows one to wrap an existing VTK object or create a new one.
   `TVTKBase.__init__` accepts an optional VTK object, that can be
   used to wrap an existing VTK object.  Read the method docstring for
   more details.

 * Sets up the event handlers that allow us to listen to any changes
   made to the underlying VTK object.

 * Basic support for pickling the object.

 * The `update_traits` automatically updates the traits of the tvtk
   class such that they reflect the state of the underlying VTK
   object.

 * Common code to change the underlying VTK object when the trait is
   changed.

As mentioned above, tvtk classes can either wrap an existing VTK
object or create a new one and manage the new object.


Automatic trait updation
------------------------

One very important feature of tvtk objects is that any VTK related
traits of object are dynamically updated if the underlying VTK object
is changed.  This is achieved by adding an observer to the VTK object
that effectively calls TVTKBase.update_traits when the 'ModifiedEvent'
is invoked.  Here is an example of a VTK observer callback::

    >>> import vtk
    >>> p = vtk.vtkProperty()
    >>> def cb(obj, evt):
    ...     print obj.__class__.__name__, evt
    ...
    >>> p.AddObserver("ModifiedEvent", cb)
    1
    >>> p.SetRepresentationToWireframe()
    vtkOpenGLProperty ModifiedEvent

As can be seen, when the property is modified, the callback is called.
The trouble with this approach is that `p` now holds a reference to
`cb`.  Thus if `cb` were the `update_traits` method of the tvtk class
that manages the VTK object, we run into a non-garbage-collectable
reference cycle issue and a huge memory leak.  To get around this we
use the functionality provided by `messenger.py`.  Effectively,
`TVTKBase.__init__` tells messenger to call `self.update_traits` when
it is called back from the VTK object.  Messenger itself uses
`weakrefs` so the reference cycle problem does not exist.  The VTK
object basically calls `messenger.send` and `messenger` takes care of
the rest.  This allows the tvtk class to be safely used and also
allows for automatic trait updation.

Each tvtk class has an attribute called `_updateable_traits_`.  This
is a tuple of tuples.  Each tuple contains a pair of strings like so::

    >>> p = tvtk.Property()
    >>> p._updateable_traits_[:4]
    (('opacity', 'GetOpacity'),
     ('frontface_culling', 'GetFrontfaceCulling'),
     ('point_size', 'GetPointSize'),
     ('specular_color', 'GetSpecularColor'))

The first string is the name of the trait and the second the name of
the function used to obtain the value of the trait from the VTK
object. `TVTKBase.update_traits` uses this tuple and for each trait it
calls the relevant VTK 'get' function and updates the value of the
trait.

While this whole process seems to be inefficient, it actually works
quite well in practice and does not appear to be slow at all.


Messaging
---------

The messaging functionality is defined in `tvtk/messenger.py`.  Unit
tests are in the 'tests/' directory.  As described in the previous
section, tvtk objects use the messenger functionality to ensure that
the traits are always up to date.  `messenger.py` is well documented
and tested.  So please read the docstrings for more details.  Here is
some basic information from the documentation.

`messenger.py` implements a simple, robust, safe, `Messenger` class
that allows one to register callbacks for a signal/slot (or
event/handler) kind of messaging system.  One can basically register a
callback function/method to be called when an object sends a
particular event.  The Messenger class is Borg.  So it is easy to
instantiate and use.  This module is also reload-safe, so if the
module is reloaded the callback information is not lost.  Method
callbacks do not have a reference counting problem since weak
references are used.  The main functionality is provided by three
functions, `connect`, `disconnect` and `send`.

`connect` basically allows one to connect an object, `obj`, that emits
an event, `event` to a callback function, `callback`.

When an object calls `send`, it passes itself, the event it wishes to
emit along with any optional arguments and keyword arguments to send.
All registered `callback` for the particular event are called with the
the object that called it (`obj`), the event (`event`) and the
optional arguments.

`disconnect` allows one to disconnect either a particular callback, or
all callbacks for a particular event or the entire object.

The messenger class thus provides a simple observer pattern
implementation that makes it easy to do inter-object communication.
For further details please read the code and docstrings.  Also look at
the test suite in `tests/test_messenger.py`.


Pickling
--------

`TVTKBase` provides the basic functionality for pickling.
Essentially, the dictionary (`self.__dict__`) of the tvtk object is
pickled.  The `_vtk_obj` attribute is not pickled since VTK objects
are not picklable.  Other irrelevant attributes are also removed.
`__setstate__` works even on a live object by checking to see if
`self._vtk_obj` exists.  Some of the tvtk classes override these
methods to implement them better.  For example look at the code for
the `Matrix4x4` class.


Array handling
--------------

TVTK lets the user pass Numeric arrays/Python lists in place of the
`DataArray`, `CellArray`, `Points` etc. classes.  This is done by
finding the call signature of the wrapped VTK method, checking to see
if it has an array and then intelligently generating the appropriate
VTK array data using the signature information.  This generated VTK
data array is then passed to the wrapped function under the covers.
This functionality also works if the method has multiple call
signatures (overloaded VTK method) and one of them involves arrays.
The main functions to do this conversion magic are in the
`array_handler.py` module.  The `wrapper_gen.py` module generates the
appropriate wrapper code depending on the call signature.  So if a
method has no VTK objects in its signature, no wrapping is necessary.
If it only has non-array VTK objects, then array handling is
unnecessary but one must dereference the VTK object from the passed
tvtk wrapper object.  If the call signature involves VTK array
objects, then any Numeric arrays or Python lists are converted to the
correct VTK data array and passed to the wrapped VTK object.

For the efficient conversion to `CellArray` objects, an extension
module is required.  The sources for this extension module are in
`src/array_ext.*`.  The Cython_ file can be used to generate the
`src/array_ext.c` file like so::

  $ cd src
  $ cython array_ext.pyx

The sources ship with the generated source file so that folks without
Cython can build it.

`special_gen.py` defines all the additional methods for the
`DataArray` and other classes that allow these objects to support
iteration, `__repr__`, `__getitem__` etc.


.. _Cython: http://cython.org/


The magical `tvtk` instance
---------------------------

When one does the following::

    >>> from enthought.tvtk.api import tvtk

The imported `tvtk` is really an instance of a class and not a module!
This is so because, the tvtk classes are almost 800 in number and they
wrap around the *entire* VTK API.  VTK itself allows one to import all
the defined classes in one go.  That is, if one does `import vtk`, one
can instantiate all VTK related classes.  This is very useful
functionality.  However, importing 800 wrapper classes in one go is
*extremely* slow.  Thus, `tvtk` provides a convenient solution to get
around the problem.  While `tvtk` is a class instance, it behaves just
like you'd expect of a module.

 * It supports tab-completion on class names.
 * Allows one to access all the tvtk classes.
 * Imports extremely fast.  Any slowness in the import is really
{'fraction_non_alphanumeric': 0.06952430737062205, 'fraction_numerical': 0.001858628100133589, 'mean_word_length': 4.011059371362049, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1973752', 'n_tokens_mistral': 4612, 'n_tokens_neox': 4402, 'n_words': 2529}