2010 October 12 / j|d|a|v|i|s|@|c|a|r|l|e|t|o|n|.|e|d|u

Mesh

An immutable triangular mesh built from vertex attribute arrays and triangles (triples of indices into the vertex attribute arrays). The attribute arrays might store 2D or 3D vertices, normals, texture coordinates, colors, or other material properties. However, Mesh does not have any sense of such semantics. It is simply a data repository. The semantics are declared in the renderer.

__init__(self, triangles, attributes)

Initializes the mesh. When this method is invoked, OpenGL must be ready to receive commands. attributes is a sequence of one or more attribute arrays, all of the same length. Each attribute array is a sequence of float-tuples, with all of the tuples in a given attribute array of the same length. For example, attributes might contain two elements, the first being a sequence of 4035 3-tuples (3D vertices, perhaps) and the second being a sequence of 4035 2-tuples (texture coordinates). triangles is a sequence of 3-tuples of unsigned integers serving as triangles into the attribute arrays.

getNumTriangles(self)

Returns the number of triangles.

getNumVertices(self)

Returns the number of vertices --- that is, the length of every attribute array.

getAttributeSizes(self)

Returns a tuple of integers indicating how many floats are in each attribute. The length of this tuple is the number of attributes. The sum of this tuple is the total number of floats needed to describe the attributes of each vertex.

Utility Functions

collapsedMeshData(triangles, vertices, others=None)

Returns new (triangles, vertices, others) that have been optimized by repeatedly collapsing equal vertices into each other (and adjusting the triangles accordingly). If others is not None, then it must be a list of arrays, each array of length equal to vertices, containing other attribute data (normals, colors, texture coordinates, etc.); whenever two vertices are collapsed in the new vertices, the corresponding entries in each array of others are collapsed in the new others.

equatedVertices(vertices, epsilon)

Returns a new list of vertices, of the same length as the old list, such that all vertices within epsilon of each other, as measured by the l-infinity norm, have been adjusted to be equal. Used to clean up after precision errors. Consider using this function and then collapedVertices.

joinedMeshData(meshDataList)

Given a sequence meshDataList of sequences (triangles, attrib1, attrib2, ...), returns a single sequence [triangles, attrib1, attrib2, ...] that joins them all together, so that a joined mesh can be made.

nontrivialTriangles(triangles, vertices)

Returns a new list of triangles, that is identical to the old list with all trivial triangles removed. A triangle is trivial if two of its vertices are identical.

smoothNormals(triangles, vertices)

Returns a list of unit normals, one per vertex, formed by averaging the true unit normals of all adjacent triangles.

transformedMeshData(vertices, normals, m)

Given 3D triangular mesh data and a 3x3 matrix m (given as a 9-sequence in row-major order), returns a pair (vertices, normals) that describes the original mesh transformed by the matrix. That is, vertices transform by m, and normals transform by the inverse transpose of m (and are then renormalized). The matrix must be invertible.

deformedMeshData(vertices, normals, function, jacobian)

The inputs vertices and normals are 3D vertices and unit normals at those vertices. The input function is a function that takes in a 3-tuple of floats and outputs a 3-tuple of floats; that is, it deforms 3D space. The input jacobian is a function that takes in a 3-tuple of floats and outputs a 9-tuple of floats; it should be the Jacobian matrix of function (in row-major order). Returns a pair (vertices, normals) that describes the original mesh deformed by the function. That is, vertices transform by function, and normals transform by the inverse transpose of the Jacobian (and are then normalized). In the special case where the Jacobian is constant and function is the corresponding linear transformation, deformedMeshData is equivalent to transformedMeshData. The Jacobian must be invertible at all of the vertices.

localDeformer(displacement, center, radius, cutoff, cutoffDerivative)

The inputs displacement and center are 3-sequences of floats, radius is a positive float, cutoff is a cutoff function on the interval [0.0, 1.0], and cutoffDerivative is its derivative. (The Bopagopa utility functions cubicCutoff and cubicCutoffDerivative are examples.) Returns a pair (function, jacobian) suitable for use as the deformer in deformedMeshData. The deformer leaves points more than radius away from the center unmoved. It moves other points based on their distance from the center --- specifically, by cutoff(distance^2 / radius^2) * displacement. Assuming that cutoff(0.0) is 1.0 and cutoff(1.0) is 0.0, the deformer's effect is to move the center by displacement, and to adjust a neighborhood around the center accordingly.

2D Constructor Functions

diskMeshData(radius, numSides=16, numAnnuli=1)

Returns (indices, vertices, texCoords) for a 2D triangular mesh of a disk of the given radius. Uses numSides subdivisions around and numAnnuli subdivisions out. The center of the disk is at the origin.

sectorMeshData(radius, start, end, numSides=8, numAnnuli=1)

Returns (indices, vertices) for a 2D triangular mesh of a sector of a disk of the given radius, running between the angles start and end (in radians, counterclockwise from the positive x-axis). Uses numSides subdivisions around and numAnnuli subdivisions out. The center of the sector (that is, the center of the corresponding disk) is at the origin.

annulusMeshData(inner, outer, numSides=16, numAnnuli=1)

Returns (indices, vertices, texCoords) for a 2D triangular mesh of an annulus of the given radii. Uses numSides subdivisions around and numAnnuli subdivisions out. The center of the annulus is at the origin.

rectangleMeshData(width, height, numWide=1, numHigh=1)

Returns (indices, vertices, texCoords) for a 2D triangular mesh of a rectangle, of the given width and length. Uses numWide by numHigh subdivisions. The bottom left corner of the rectangle is at the origin.

roundedRectangleMeshData(width, height, radius, numWide=1, numHigh=1, numSides=4, numAnnuli=1)

Returns (indices, vertices, texCoords) for a 2D triangular mesh of a rectangle with rounded corners, of given overall width and height and given radius of rounded corners. For the core rectangle uses numWide by numHigh subdivisions; for each quarter disk uses numSides subdivisions around and numAnnuli subdivisions out. The bottom left corner (of the bounding non-rounded rectangle) is at the origin.

convexPolygonMeshData(vertices)

Returns (indices, vertices, texCoords) for a 2D triangular mesh of a polygon with the given vertices in counterclockwise order. If the polygon is not convex then strange visual artifacts may arise. The positions of the vertices are all relative to the origin.

3D Constructor Functions

elevationMeshData(width, height, elevations)

Returns a pair (triangles, vertices, texCoords, normals) that can be used to build a 3D triangular mesh of a surface based on elevations. The surface's shadow is width x height. elevations is a 2D array of floats indicating the elevation of the surface above the z = 0 plane at even spacings.

boxMeshData(width, height, depth, numWide=1, numHigh=1, numDeep=1)

Returns a tuple (triangles, vertices, texCoords, normals) that can be used to build a 3D triangular mesh of a box. The edges of the box come with redundant vertices because the normals change abruptly, and to facilitate texture mapping. The box extends from the origin into the first octant of space.

surfaceOfRevolutionMeshData(zs, rs, numSides=16, numAnnuli=1)

Returns a tuple (triangle, vertices, texCoords, normals) that can be used to build a mesh for a surface of revolution. The surface is formed by revolving a piecewise-linear curve about the z-axis. The arguments zs and rs are sequences of floats of equal length at least 2. The vertices of the curve have z-values given by zs, and nonnegative radii (out from the z-axis) given by rs. The first z should be less than the last z, to guarantee correct orientation. If the first radius is not 0.0, then that end of the solid is capped with a disk; the same goes for the last radius. You can depend on the vertices occuring in a particular order: by meridian, from the zs[0] end of the meridian to the zs[-1] end of the meridian.

sphereMeshData(radius, numSides=16, numLayers=8)

Returns a tuple (triangles, vertices, texCoords, normals) that can be used to build a sphere mesh of the given radius (centered at the origin).

cylinderMeshData(height, radius, numSides=16, numLayers=1, numAnnuli=1)

Returns a tuple (triangles, vertices, texCoords, normals) that can be used to build a 3D triangular mesh of a cylinder. The cylinder extends from the origin along the positive z-axis.

capsuleMeshData(height, radius, numSides=16, numLayers=8, numAnnuli=4)

Returns a tuple (triangles, vertices, texCoords, normals) that can be used to build a 3D triangular mesh of a capsule (a cylinder capped with hemispheres). Specifically, height is the height of the cylindrical part of the capsule; the radius is the radius of the cylindrical part and of the hemispherical caps. The total height of the capsule is therefore height + 2.0 * radius. The cylindrical part of the capsule extends from the origin along the positive z-axis.

coneMeshData(height, radius, numSides=16, numLayers=1, numAnnuli=1)

Returns a tuple (triangles, vertices, texCoords, normals) that can be used to build a 3D triangular mesh of a cone. The cone extends from the origin along the positive z-axis, and points up.