The easiest way to extend MayaVi is to create a directory that
contains three sub-directories called Sources/
, Modules/
and a Filters/
directory inside
where user defined sources, modules and filters can be stored. You
don't need to create an __init__.py
file in these
directories. This directory should then be added to the MayaVi
"search path" which may be set by using the
menu. The search path
is a ':'-separated string and is specified like the PYTHONPATH. '~',
'~user' and '$VAR' are all expanded. Note that after changing the
search path you'll have to restart MayaVi.
These user defined modules and filters will be made available inside the
sub-menu of the , and menus respectively. These sources, modules and filters can be used from the command line or from a Python interpreter session by using 'User.SourceName' (sources cannot be specified from the command line but may be specified in a Python script), 'User.ModuleName' or 'User.FilterName'. When creating user defined sources or modules or filters make sure that the name of the module is the same as the name of the class that defines the particular object.It is likely that the first thing you will do to test out this functionality is to copy a standard source, module or filter into your directory, rename it and test with it. Beware of some of the following points before you do that.
Make certain that the name of the class that defines the
source/module/filter is identical with the name of the module that
contains it. So if you have a module called
MySuperModule.py
the class that defines the module
must be called MySuperModule
.
The same applies to the sources and filters as well.
The standard Modules/filters and sources are a little special and will typically contain code that looks like this.
import Base.Objects, Common # ... class SomeModule(Base.Objects.Module): # ...
This must be changed to the following.
from mayavi import Common from mayavi.Base import Objects # ... class SomeModule(Objects.Module): # ...
Essentially, the Python module defining your object should be "import-able" from the Python interpreter even without MayaVi running.
This section lists a set of things that developers should know before
extending MayaVi by implementing new Module
s,
Source
s and Filter
s.
The print_err
function takes a string and prints
it out on a GUI message box.
The get_relative_file_name(base_f_name,
f_name)
function returns a file name for the given
f_name
relative to the
base_f_name
. This is useful when one
stores file names in the configuration.
The get_abs_file_name(base_f_name,
rel_f_name)
function returns an absolute file name
given a base file name and another file name relative to the base
name. This is useful to load a stored file name.
The debug
function prints a string on the debug
window and on sys.stdout
. This is used to print
debug messages in all the MayaVi code.
The config
variable is an instance of class that
contains the configuration preferences of the user. This is used to
initialize default colors etc.
The state
variable is instance of the
AppState
class. The
state.busy()
state.idle()
members are used to
change the state of the MayaVi application.
As with any code the best way to learn how the classes and functions are organized and work is to look through the source. What follows are a few hints that might be useful when you develop code for MayaVi.
Before writing a new component please look at the the
Module
, Filter
and
Source
classes defined in
Base/Objects.py
. Also look at their parent
classes. A lot of useful functionality is provided there and reading
this may prevent unnecessary code replication.
The Module and Filter menus are created dynamically from the files in
the Modules
and Filters
directories. All the files there
except the __init__.py
will
be recognized as modules or filters respectively. So do not put any
files there that are neither modules nor filters.
Make sure the name of the new Module/Filter or Source subclass and the
name of the file that defines the Module subclass are the same. For
instance the Axes
module is defined in a file
called Axes.py
.
As far as possible try to follow my style of coding. The naming
convention that I have followed is to name all VTK like methods in the
usual VTK way (like GetOutput). All other methods are named like so
get_vtk_object. This has been done to differentiate between the two.
All class names have the first letter of each word capitalized for
example as in VtkDataReader
and
ExtractVectorComponents
.
Please try to document your classes and functions.
While writing any component please try to make the particular component "import safe" by not doing either of the first two and using the last way of importing modules. Doing this makes it possible to reload modules on the fly.
# Don't do this: from SomeThing import * # or the following: from SomeThing import SomeClass # Use this instead. import SomeThing
While developing a component it is possible to test the component by running MayaVi and then retest it by reloading the modules from the
.
The Common.py
module provides a few useful
classes and functions. Some of them are as follows:
Every component has to be able to save its state to an ASCII file and
be able to reload its state from the saved file. The
save_config
and load_config
functions should implement this. This should be tested properly.
Happy hacking!