Jython3D : Python and Java3D
This article was originally written in October 2003.
Combining Jython with Java3D seems like such a good idea – finally a high level language with a high level 3D graphics API. At the time of writing I couldn’t find anything of substance on the web about combining the two, so I set out to translate some of the example Java programs that come with Java3D into Jython.
Compare the following code fragments from the Java3D examples, the snippet is from the Java3D demo GearBox, the code is Copyright © 1996-2002 Sun Microsystems:
DirectionalLight light2 = new DirectionalLight(light2Color, light2Direction); light2.setInfluencingBounds(bounds); objScale.addChild(light2); // Create the transform group node and initialize it to the // identity. Enable the TRANSFORM_WRITE capability so that // our behavior code can modify it at runtime. Add it to the // root of the subgraph. TransformGroup objTrans = new TransformGroup(); objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objScale.addChild(objTrans); // Create an Appearance. Appearance look = new Appearance(); Color3f objColor = new Color3f(0.5f, 0.5f, 0.6f); Color3f black = new Color3f(0.0f, 0.0f, 0.0f); Color3f white = new Color3f(1.0f, 1.0f, 1.0f); look.setMaterial(new Material(objColor, black, objColor, white, 100.0f)); // Create a gear, add it to the scene graph. // SpurGear gear = new SpurGear(toothCount, 1.0f, 0.2f, SpurGear gear = new SpurGearThinBody(toothCount, 1.0f, 0.2f, 0.05f, 0.05f, 0.3f, 0.28f, look); objTrans.addChild(gear); // Create a new Behavior object that will rotate the object and // add it into the scene graph. Transform3D yAxis = new Transform3D(); Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 8000, 0, 0, 0, 0, 0); RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, objTrans, yAxis, 0.0f, (float) Math.PI*2.0f); rotator.setSchedulingBounds(bounds); objTrans.addChild(rotator); // Have Java 3D perform optimizations on this scene graph. objRoot.compile();
My equivalent Jython code is below. There are some key differences between the Java implementation and the Jython version. For example, the class SpurGearThinBody has five constructors defined in the Java version, whereas the Python equivalent requires only one, thanks to the availability of default and keyword function arguments. Keyword arguments also add to the readability of the code.
light2 = DirectionalLight(light2Color, light2Direction, influencingBounds=bounds) objScale.addChild(light2) # Create the transform group node and initialize it # to the identity. Enable the TRANSFORM_WRITE capability so that # our behaviour code can modify it at runtime. Add it to the # root of the subgraph. objTrans = TransformGroup(capability=TransformGroup.ALLOW_TRANSFORM_WRITE) objScale.addChild(objTrans) # Create an Appearance look = Appearance() objColor = Color3f(0.5, 0.5, 0.6) black = Color3f(0.0, 0.0, 0.0) white = Color3f(1.0, 1.0, 1.0) look.material = Material(objColor, black, objColor, white, 100.0) # Create a gear, add it to the scene graph gear = SpurGearThinBody(toothCount=toothCount, pitchCircleRadius=1.0, shaftRadius=0.2, addendum=0.05, dedendum=0.05, gearThickness=0.3, toothTipThickness=0.28, look=look) objTrans.addChild(gear) # Create a new Behavior object that will rotate the object and # add it to the scene graph. yAxis = Transform3D() rotationAlpha = Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 8000, 0, 0, 0, 0, 0) rotator = RotationInterpolator(rotationAlpha, objTrans, yAxis, 0.0, math.pi * 2.0, schedulingBounds=bounds) objTrans.addChild(rotator) # Have Java 3D perform optimizations on the scene graph objRoot.compile()
prompt$ jython SimpleUniverse.py
prompt$ jython GearTest.py
prompt$ jython GearBox.py
Note that it is also possible to run the original Java implementations as Applets from within a browser. If you compile the Jython code using jythonc, this should also be possible with the Jython implementations.