MeVisLab Scripting Reference
|
MeVisLab contains Python wrappers for the whole Open Inventor toolkit. This allows to:
The wrappers are inside of the Inventor Python package and are organized as follows:
For a description of the defined classes and the interface of these classes, please see the C++ Open Inventor Reference. Most of the interface will be replicated in the Python wrappers.
The Inventor.base module contains all the linear algebra classes and some base classes like SoType and SoBase. This is different to the C++ Inventor, where these classes are in the root directory and the the misc directory.
The following shows an example of doing a plane/line intersection:
Linear algebra is available in single and double precision, denoted by a "f" postfix for float and a "d" postfix for double. Some single precision classes do not have a "f" postfix, e.g. SbPlane, SbRotation, SbMatrix, while the double precision versions always have a "d" postfix.
The MLABField classes accept both single and double precision on setValue(), but always return double precision versions, since they use double precision internally.
Each linear algebra class has a conversion method to convert to the other precision, e.g. SbVec3f.toVec3d(), SbVec3d.toVec3f(), SbMatrix.toMatrixd(), SbMatrixd.toMatrix(), ...
The Inventor.base module contains all basic Inventor nodes and can be used to construct scene graphs in Python. The fields of Inventor nodes and engines can be accessed by their name. Use getValue()/setValue() to read/write a field's value. A scene graph can be stored in a MLABSoNodeField, so you can create a macro module that internally builds a scene graph and outputs the scene via an MLABSoNodeField.
The Inventor.actions module contains all Inventor actions. You can use it to e.g. get the bounding box of a scene or to search for a node in the scene.
The Inventor.fields defines all core Inventor fields. Fields are exposed as properties of the nodes/engines they are contained in. Field values can be set/get via setValue()/setValues() and getValue()/getValues(). Fields with multiple values (e.g. SoMFFloat, SoMFVec3f, ...) support NumPy arrays in their setValues() methods and return a read-only NumPy array in getValues(). To efficiently set values, you can either create a NumPy array and set it via setValues() (this causes an extra copy), or you can use the setNum() and startEditing()/finishEditing() methods to directly work on the field data using a NumPy array that contains a direct pointer to the field data.
The MLABField offers the MLABField::inventorField() method to access the underlying SoField of an MLABField that wraps an Inventor field. This allows to e.g. use the SoMFVec3f API to set multiple vector values on an MLABField that wraps a SoMFVec3f, without the need to use setStringValue().
The Inventor.sensors module contains all Inventor sensors. You can use it to listen to fields and nodes, or to create a timer.
NOTE: Inventor sensors are triggered via a delayed queue, so you will not get an immediate notification if a field changes, you will get it later on when the Inventor queue is processed. This can be circumvented by calling setPriority(0) on the sensor, but note that this might lead to the sensor being triggered more often.
The Inventor wrappers offer to derive from a SoNode (or any derived class) from within Python. It is possible to implement the GLRender method and to use PyOpenGL (currently not included with MeVisLab) to do the actual rendering. Using the Inventor.elements and the SoState of an action, it is possible to read/write to all available Inventor elements in the state.
Here is a simple example of how to override event handling in such a class:
Various places in Open Inventor take static C callback functions. Most places have been overloaded with methods that take a Python callable instead. Please note that these callables are not reference counted by the callback setter function, so you need to keep a reference of the function around in Python. Normal member functions will be ref-counted anyways, so this is mainly a problem when you want to use local functions or lambdas as callback functions, in which case you need to store them in a Python variable that lives longer than the C++ object on which you are setting the callback.