The class pyInterface defines the basic interface between Ygdrasil and Python, and is used by pyNode, pyTransform, and pySelector. Each of these Ygdrasil node classes uses a pyInterface object to handle common messages and the app() function.
pyInterface defines a Python module "ygdrasil", which contains several functions corresponding to basic Ygdrasil functions. It also defines a Python class "ygNode", which provides several member functions corresponding to the C++ ygNode's member functions.
All Ygdrasil/Python scripts are expected to define a class which is derived from ygNode or one of the other Ygdrasil/Python classes (currently ygTransform & ygSelector). An object of this class will be created when the script is loaded, and its app() member function will be called by ygInterface on each frame.
Here is a very simple example scene and Python script. The script keeps a counter that increments each frame; when it reaches 1000, the counter resets and the event "overflow" is generated. The script also includes a function "ping()" that can is called by a WandTrigger.
Scene file:
pyNode nodeA (script(example.py), when(overflow, print(overflow occurred)))
wandTrigger (when(button1, nodeA.ping))
Script file example.py:
class example(ygNode):
def __init__(self):
self.val = 1
def app(self):
self.val += 1
if (self.val > 1000):
self.eventOccurred('overflow')
self.val = 1
def ping(self):
print name(), 'pinged; val =', self.val
These messages are available in all Ygdrasil/Python node classes:
[C++:] PyRun_SimpleFile("foo.py")
[Python:] nodeA = foo()
[Python:] nodeA.ygNodeName = 'nodeA'
And then on each frame, the Python command "nodeA.app()" is run.
The Python class ygNode has the following member functions:
Note that some of the functions (childName, parentName, origin) deal with the names of nodes, where the corresponding C++ ygNode functions use pointers to actual node objects. This is done because there is no guarantee that the other Ygdrasil node being referred to is of a Python-based node class; hence, only the name of the node is used, rather than a Python ygNode object.
pyInterface also defines the module ygdrasil, which consists of a set of functions that provide the actual connection between Python and Ygdrasil. (This is separate from the ygNode class because of some of the ugly details of Python's embedding/extending system.)
Some of these functions correspond to ygWorld functions, and so were not included as Python ygNode functions. Other functions are primarily used behind the scenes in the Python ygNode class; however, these can also be called directly if desired, such as to allow a Python node to get data from some other non-Python Ygdrasil node.
The functions defined in the ygdrasil module are:
Illegal node names are possible:
Note: this bug has been corrected in Ygdrasil 0.1.7 (except for cases
where a scene file explicitly assigns a node an illegal name).
Because pyInterface uses an ygNode's name for the name of the corresponding Python
variable that it creates, the node name needs to be something that will be a
legal variable name. Normally this is not a problem, but in the case where the
node has not been given a name in the scene, it is assigned one by Ygdrasil.
By default, this name is built from the host name (plus process ID); some systems
are configured to return their fully qualified internet name, rather than just
the basic machine name - e.g. hostname returns "mediastudy1.fal.buffalo.edu"
instead of just "mediastudy1". This causes pyInterface to try to create
a variable with dots in its name, which will fail.
Use the environment variable YG_DUMMYNAME_BASE, or explicity name all Python nodes,
to avoid this for the time being.
Note that really this is a flaw in Ygdrasil, not pyInterface - node names with dots
in them could cause problems elsewhere.
Last updated 26 October 2002.
home page