Home

If you're new to Python
and VPython: Introduction

A VPython tutorial

Pictures of 3D objects

Choose a 3D object:

Work with 3D objects:

Windows, Events, & Files:

Vector operations

Graphs

factorial/combin

What's new in Visual 5

VPython web site
Visual license
Python web site
Math module (sqrt etc.)
Numpy module (arrays)

 
New Features in Visual 5
material etc

New features

There is a new example program texture_and_lighting.py that displays many of the new features: a swinging light illuminates a translucent ball that rolls on a wood table. Also see the example programs material_test.py, stonehenge.py, and boxlighttest.py.

There are a couple of known incompatibilities with earlier versions of VPython.

Credits

Visual 5 was created by David Scherer and Bruce Sherwood. Jonathan Brandmeyer provided support in Visual 4beta for opacity, local lighting, and textures, and made some important architectural changes, but had to stop work on the project before it was completed.  Further development has led to API changes which are incompatible with the Visual 4beta release, so this release is called version 5 instead of 4.

The late Arthur Siegel implemented dependence on the currently supported numpy library in place of Numeric, which is no longer supported. Hugh Fisher provided a big start on the native-mode Mac version. Michael Temkine fixed some bugs and implemented keyboard handling for Windows.

Previous to Visual 4beta, Jonathan Brandmeyer made several major contributions to Visual 3, including changing the connection between Python and C++ from CXX, which was no longer supported, to the Boost C++ libraries, and implementing auto-configurable installations for Linux.

Transparency/opacity

You can make most objects be transparent by specifying a value from 0-1 inclusive for the attribute "opacity". For example, box(color=color.red, opacity=0.8) is slightly transparent. An opacity value of 0 means totally transparent, and 1 means totally opaque. Currently curve, convex, faces, points, and helix objects do not allow transparency.

You may see incorrect rendering any time there is a translucent object (opacity < 1.0) which is not convex (e.g. ring), or two translucent objects which overlap on the screen and also in their depth extents (distances from the camera to the nearest and farthest planes perpendicular to scene.forward which intersect the object). The objects need not actually overlap in 3D space to have problems. The incorrect rendering will usually have the effect of making the more distant object disappear (fail to show through the nearer object). Accurate rendering of ad hoc scenes with translucency is difficult and expensive, and we did not want to wait for a perfect solution before introducing this useful enhancement.

Materials

You can give a material property such as wood to an object:

box(color=color.orange, material=materials.wood)

Materials currently available include wood, plastic, marble, earth (continents and oceans), rough, diffuse, emissive, and unshaded (that is, display the specified color unaffected by existing lights). The example program material_test.py shows examples of all of these materials.

Materials will work with graphics cards that support Pixel Shader 3.0 ("PS 3.0"). For details, see
http://en.wikipedia.org/wiki/Pixel_shader#Hardware. Some materials may work with graphics cards that support PS 2.0, but other materials may need to be manually disabled; see instructions in the site-settings.py module in the Visual package in your site-packages folder. If the graphics hardware does not support pixel shaders, the material property is ignored. If you think you should be able to use materials but have trouble with their display or performance, we highly recommend upgrading your video card drivers to the latest version.

Lighting

In previous versions of Visual, lights were restricted to being white and very distant from the scene ("at infinity"). Now you can create lights that are local, near other objects, and you can specify colors for lights. The following statement creates a yellow light positioned at (x,y,z):

lamp = local_light(pos=(x,y,z), color=color.yellow)

If you continually update lamp.pos, the light will move. You may wish to place a sphere or box with material=materials.emissive at the same location so that the lamp looks like a glowing lamp.

If you want to disable all of the lights, so that the only light is ambient light (scene.ambient), say scene.lights = [], making an empty list of lights.

A distant red light located in the direction (x,y,z) is created like this:

distant_light(direction=(x,y,z), color=color.red)

Points object

A new points object is similar to a curve, but with disconnected points. As with curve, the pos attribute is an array of points, and color can also be an array. If you say shape="round", the points are round, which is the default; shape="square" makes square points.

New frame options

You can now make a frame visible or invisible, and all objects in the frame will be affected.

There are now functions for converting between coordinates within a frame and "world" coordinates.

New curve append option: retain

If "trail" is a curve, trail.append(pos=(x,y,z), retain = 50) means that only the 50 most recently added points of a curve will be displayed; the earlier ones are deleted. This is a nice option for having a moving object leave a tail behind itself, like a comet.

Fonts in labels

You can now specify a font for a label, including font='sans' or 'serif' or 'monospace' (fixed-width). Python Unicode text is supported.

Specifying a gray

For convenience you can now say color=color.gray(0.7) to mean color=(0.7,0.7,0.7).

Reading and writing files

The new module visual.filedialog provides a simple file dialog display for choosing files.

Render time

If you say scene.show_rendertime = True, in the lower left of the graphics window you will see the cycle time (time between renderings of the scene) and the render time (time taken to render the scene). This can be a useful diagnostic of performance issues.

Design for left-button events if possible

Visual 5 provides the basic mouse event functionality that was present in Visual 3 for handling events from right and middle buttons when userspin or userzoom is disabled, out of concern for supporting old programs. However, it has become evident that there are limitations to this approach which could preclude some kinds of mouse handling that people might want to do in the future. For example, you might want to allow userspin with right drags yet also pick up right clicks. For that reason it is conceivable that future developments in this area might break existing programs, and therefore for maximum forward compatibility it is prudent to use only left-button interactions in new programs.

Known incompatibilities in this new version

Here are known incompatibilities:

There are some unavoidable incompatibilities due to the fact that the currently supported numerical array package numpy differs from its predecessor Numeric. The only way to handle some of these incompatibilies is by using the Python "try/except" structure. For examples, see the example programs gas.py or stars.py.

You can still set scene.lights in the same way as in Visual 3, but you cannot read the information in scene.lights in the same way as before, because in Visual 5 scene.lights is a list of distant_light (and/or local_light) objects, not a list of vector directions. If you read and used information in scene.lights, you may need to use a Python "try/except" structure to make your program run on both Visual 3 and Visual 5. For example, suppose an old program wanted to have two lights, one 70% as bright as the first light in the scene.lights list, and the other a duplicate except coming from the back, to light both front and back of the scene. Here is code to do this:

try:
    L0 = 0.7*norm(scene.lights[0])
    L1 = vector(L0.x, L0.y, -L0.z)
    scene.lights = [L0, L1]
except:
    L0 = scene.lights[0]
    L0.color = 0.7*vector(L0.color)
    scene.lights = [L0]
    d = L0.direction
    L1 = distant_light(direction=(d.x,d.y,-d.z),
         color=L0.color)