surface: Triangulated surface calculations

Routines for calculating surface triangulations and properties of triangulated surfaces.

Surfaces are represented using numpy arrays of vertices (N by 3 array, xyz coodinates, float32), and a numpy array of triangles which are triples of indices into the vertex list (M by 3 array, vertex indices, int32). For surface lighting, normal vectors at each vertex are used (N by 3 array, unit vectors, float32). The vertex, triangle and normal arrays are sometimes called varray, tarray, narray, and sometimes vertices, triangles, normals.

spheres_surface_area(centers, radii, npoints=1000)

Return the exposed surface area of a set of possibly intersecting set of spheres. An array giving the exposed area for each input sphere is returned. The area is computed by an exact method except for round-off errors. The calculation can fail in rare cases where 4 spheres intersect at a point and area values of -1 are returned for spheres where the calculation fails. TODO: The code also computes the areas using numerical approximation, and the results compared with the maximum and average discrepancy printed for debugging. This code is not needed except for debugging.

box_geometry(llb, urf)

Return vertex, normal vector and triangle arrays for box with corners llb and urf (lower-left-back, upper-right-front)

cone_geometry(radius=1, height=1, nc=20, caps=True, points_up=True)

Return vertex, normal vector and triangle arrays for cone geometry with specified radius and height with point of cone at origin

cylinder_geometry(radius=1, height=1, nz=2, nc=10, caps=True, hexagonal_lattice=False)

Return vertex, normal vector and triangle arrays for cylinder geometry with specified radius and height centered at the origin.

dashed_cylinder_geometry(segments=5, radius=1, height=1, nz=2, nc=10, caps=True)

Return vertex, normal vector and triangle arrays for a sequence of colinear cylinders.


Return vertex, normal vector and triangle arrays for a radius 1 octahedron.


Return vertex, normal vector and triangle arrays for unit sphere geometry. Only produces 20, 80, 320, … (multiples of 4) triangle count.


Return vertex, normal vector and triangle arrays for unit sphere geometry. Alternate techinque that produces any even number of triangles >= 4. Use in place of sphere_geometry() in new code.


Return vertex, normal vector and triangle arrays for a radius 1 tetrahedron.

enclosed_volume(varray, tarray)

Return the enclosed volume of a surface triangulation specified by vertex and triangle arrays. Also returns the number of holes in the surface, defined as the number of boundary curves.

surface_area(varray, tarray)

Return the surface area of a triangulation specified by vertex and triangle arrays.


Return the surface area, enclosed volume and number of holes (i.e. boundary curves) of a surface triangulation specified by vertex and triangle arrays.

ses_surface_geometry(xyz, radii, probe_radius=1.4, grid_spacing=0.5, sas=False)

Calculate a solvent excluded molecular surface using a distance grid contouring method. Vertex, normal and triangle arrays are returned. If sas is true then the solvent accessible surface is returned instead.

connected_triangles(triangles, tindex)

Return sorted array of triangle indices of triangles connected to the specified triangle. Two triangles are connected if they share a vertex. The surface must be oriented and at most two triangles can share an edge. The triangle array is triples of indices of vertices (m by 3, Numpy int32). Implemented in C++.

triangle_vertices(triangles, tindices) → vertex_indices

Return an array of vertex indices used the specified subset of triangles.


Return each connected piece of a surface as a separate triangle array and vertex array. The return value is a tuple of pairs of vertex and triangle index arrays. Vertices connected by any sequence of triangle edges are considered connected. Implemented in C++.

enclosed_volume(vertices, triangles) -> (volume, hole_count)

If surface has hole then returned volume is computed by capping boundary loops with fans centered at geometric center of loops. Returns volume and hole count. Implemented in C++.

surface_area(vertices, triangles) → area

Sum of triangle areas. Implemented in C++.

vertex_areas(vertices, triangles, areas)

Accumulate 1/3 triangle area to each vertex. Third parameter areas is a float array for returning vertex area values. Implemented in C++.

boundary_edges(triangles) → vertex index pairs

Returns N by 2 array of vertex indices for directed edges. Implemented in C++.

boundary_loops(triangles) → tuple of vertex index arrays

Returns tuple of arrays of vertex indices, one array for each loop. Implemented in C++.

calculate_vertex_normals(vertices, triangles)

Calculate vertex normals by adding normals for each triangle that uses a vertex, and then normalizing the sum. Implemented in C++.

invert_vertex_normals(normals, triangles)

Flip normals and reverse triangle vertex order. Implemented in C++.

sharp_edge_patches(vertices, normals, triangles, vertex_to_atom_index_map, atom_positions, atom_radii) -> (vertices, normals, triangles, vertex_to_atom_index_map)

Split triangles to create sharp boundaries equidistant between atoms. Equidistant means an equal number of atom radii away. Implemented in C++.


Map vertex indices to unique vertex indices so vertices at the same point are treated as one. This is used for connected piece calculations. Implemented in C++.

Returns numpy int32 array, length n, mapping vertex index to unique vertex index.

surface_area_of_spheres(centers, radii, areas)

Compute surface area of union of solid sphere. Third argument areas contains areas contributed by each sphere Can fail in degenerate cases giving area -1 for spheres with failed area calculation. Implemented in C++.

estimate_surface_area_of_spheres(centers, radii, sphere_points, point_weights, areas)

Use points on sphere, count how many are inside other spheres to estimate surface area of union of solid spheres. Third argument areas contains areas contributed by each sphere Implemented in C++.

subdivide_triangles(vertices, triangles, normals) -> (vertices triangles, normals)

Divide each triangle into 4 triangles placing new vertices at edge midpoints. Implemented in C++.

subdivide_mesh(vertices, triangles, normals, edge_length) -> (vertices triangles, normals)

Divide triangle into smaller triangles so that edges are shorter than the specified the maximum edge length. Implemented in C++.

tube_geometry(path, tangents, cross_section, cross_section_normals) -> (vertices, normals, triangles)

Calculates tube surface geometry from a center-line path. Arguments path and tangents are n by 3 float arrays, and the cross section arguments are m by 3 arrays. Implemented in C++.

tube_geometry_colors(colors, segment_subdivisions, circle_subdivisions, start_divisions, end_divisions) → N by 4 numpy array of RGBA colors

Computes vertex colors for a tube with geometry determined by tube_geometry() Each segment can have a separate color. Colors argument is N by 4 array. A segment is is the interval between segment_subdivisions+1 path points not including points at ends of the path specified by start/end divisions. Arguments other than colors are integers. Implemented in C++.

tube_triangle_mask(segment_mask, segment_subdivisions, circle_subdivisions, start_divisions, end_divisions) → triangle_mask

Computes triangle mask to show only specified segments of a tube generated with tube_geometry(). Segments are defined in the same way as for the tube_geometry_colors() routine. The input segment mask is a uint8 length N array, and output is a uint8 numpy array with length equal to number of triangles generated by tube_geometry(). Implemented in C++.

largest_blobs_triangle_mask(vertices, triangles, triangle_mask, blob_count=1, rank_metric='size rank')

Return a triangle mask which includes the N largest connected surface components using a specified metric “size rank”, “area rank”, or “volume rank”. Size rank measures maximum extent along x, y and z axes.

gaussian_surface(xyz, weights, resolution, level=None, grid_spacing=None)

Return vertex, normal vector and triangles for a contour surface computed from a density map created as a sum of Gaussians at specified center positions with specified heights, and Gaussian width determined by resolution. If the contour level is None then compute the lowest density value at the center point positions. Return the input level or this computed level as a fourth return value.