The "faces" primitive takes a list of triangles (position, color, and normal for each vertex). This is useful for writing routines in Python to import 3D models made with other 3D modeling tools. You would still need to do lots of calculations of normals and so on, but you would not need to do C coding to import an arbitrary model file.
The faces object is an array primitive (like curve, convex, etc), so you have to use a frame to move it around. It consists of a set of one-sided triangles with user-specified vertices, colors, and normals. The pos, color, and normal attributes look like this:
pos = [ t0v0, t0v1, t0v2, t1v0, t1v1, t1v2, t2v0, t2v1, t2v2, ... ]
where t0v0 is the position of vertex 0 of triangle 0, t0v1 is vertex 1 of triangle 0, etc.
Each face is a one-sided surface. Which side is illuminated is determined by the "winding" order of the face. When you are looking at a face, it is illuminated if the order of the vertices in the pos list goes counter-clockwise. If you need the triangle to be visible from either side, you must create another triangle with the opposite winding order.
If you don't specify normals at the vertices, the face is illuminated only by "ambient" light. In order for the main lighting to affect the appearance, you must specify normals to the surface at the vertices. In the simplest case, a normal at a vertex is perpendicular to the face, and adjoining faces have a hard edge where they join. A soft edge can be produced by averaging the normals to the two faces at their common vertices. The brightness of a face is proportional to the cosine of the angle between the normal and the light.
If you specify different colors at the vertices of one triangular face, VPython interpolates across the face, in which case the face is not all one color. There is a similar interpolation for normals if there are different normals at the vertices, in which case the face is not all one brightness.
The faces object is intended to help with writing model importers and other new primitives in Python, not for direct manipulation by normal programs. It is considerably lower-level than any of the other objects in Visual (although it is not necessarily any faster, at least right now). It is flexible enough to implement smooth or facet shading, per-vertex coloration, two-sided or one-sided lighting, etc, but all of these calculations must be made by the programmer (when setting up pos, color, normal).
For examples of the use of the faces object, see the faces demo programs.