This module provides functions for working with indexed triangular meshes. You can:
A mesh with no vertices or faces.
Create a mesh from an array of vertices and list of face indices. For
example, to construct a square where a is the lower left corner, b is the
lower right corner, c is the upper right corner and d is the upper left
corner:
vertices =
Array.fromList [ a, b, c, d ]
faceIndices =
[ ( 0, 1, 2 ), ( 0, 2, 3 ) ]
square =
TriangularMesh.indexed vertices faceIndicesInvalid face indices (triples where any one of the three indices is out of bounds) will be dropped.
Create a mesh from a list of triangular faces, where each face is given as a tuple of three vertices. Note that this will not perform any kind of vertex deduplication, so if any vertices are shared between different triangles then they will occur more than once in the resulting mesh's vertex array.
mesh =
TriangleMesh.triangles [ ( a, b, c ), ( a, c, d ) ]
TriangleMesh.vertices mesh
--> Array.fromList [ a, b, c, a, c, d ]
Array.faceIndices mesh
--> [ ( 0, 1, 2 ), ( 3, 4, 5 ) ]Create a fan-shaped mesh from the first given vertex to all vertices in the given list. If the given list is empty or has only one element, then an empty mesh is returned. Otherwise, the first face will be from the first given vertex to the first and second list vertices, the second face will be from the first given vertex to the second and third list vertices, etc.
mesh =
TriangleMesh.fan a [ b, c, d, e ]
TriangleMesh.vertices mesh
--> Array.fromList [ a, b, c, d, e ]
TriangleMesh.faceIndices mesh
--> [ ( 0, 1, 2 ), ( 0, 2, 3 ), ( 0, 3, 4 ) ]
TriangleMesh.faceVertices mesh
--> [ ( a, b, c ), ( a, c, d ), ( a, d, e ) ]Create a strip-shaped mesh between two lists of vertices. The two lists should be the same length; if one list is longer, the extra vertices will be dropped. To get triangles with counterclockwise winding order, the second list should be to the left of the first; for example, for two left-to-right vertex lists, the second should be above the first.
mesh =
TriangleMesh.strip [ a, b, c ] [ d, e, f ]
TriangleMesh.faceVertices mesh
--> [ ( a, b, e )
--> , ( a, e, d )
--> , ( b, c, f )
--> , ( b, f, e )
--> ]Combine a list of meshes into a single mesh. This concatenates the vertex arrays of each mesh and adjusts face indices to refer to the combined vertex array.
square =
TriangularMesh.with
{ vertices = Array.fromList [ a, b, c, d ]
, faceIndices = [ ( 0, 1, 2 ), ( 0, 2, 3 ) ]
}
triangle =
TriangularMesh.with
{ vertices = Array.fromList [ e, f, g ]
, faceIndices = [ ( 0, 1, 2 ) ]
}
TriangularMesh.combine [ square, triangle ]
--> TriangularMesh.with
--> { vertices =
--> Array.fromList [ a, b, c, d, e, f, g ]
--> , faceIndices =
--> [ ( 0, 1, 2 )
--> , ( 0, 2, 3 )
--> , ( 4, 5, 6 )
--> ]
--> }
TriangularMesh.combine [ triangle, square ]
--> TriangularMesh.with
--> { vertices =
--> Array.fromList [ e, f, g, a, b, c, d ]
--> , faceIndices =
--> [ ( 0, 1, 2 )
--> , ( 3, 4, 5 )
--> , ( 3, 5, 6 )
--> ]
--> }Get the vertices of a mesh.
TriangularMesh.vertices square
--> Array.fromList [ a, b, c, d ]Get a particular vertex of a mesh by index. If the index is out of range,
returns Nothing.
TriangularMesh.vertex 1 square
--> Just b
TriangularMesh.vertex 4 square
--> NothingGet the faces of a mesh as triples of vertex indices.
TriangularMesh.faceIndices square
--> [ ( 0, 1, 2 ), ( 0, 2, 3 ) ]Get the faces of a mesh as triples of vertices.
TriangularMesh.faceVertices square
--> [ ( a, b, c ), ( a, c, d ) ]Get all of the edges of a mesh as pairs of vertex indices. Each edge will only be returned once, with the lower-index vertex listed first, and will be returned in sorted order.
TriangularMesh.edgeIndices square
--> [ ( 0, 1 )
--> , ( 0, 2 )
--> , ( 0, 3 )
--> , ( 1, 2 )
--> , ( 2, 3 )
--> ]Get all of the edges of a mesh as pairs of vertices. Each edge will only be returned once, with the lower-index vertex listed first, and will be returned in sorted order.
TriangularMesh.edgeVertices square
--> [ ( a, b )
--> , ( a, c )
--> , ( a, d )
--> , ( b, c )
--> , ( c, d )
--> ]Transform a mesh by applying the given function to each of its vertices. For
example, if you had a 2D mesh where each vertex was an ( x, y ) tuple and you
wanted to convert it to a 3D mesh on the XY plane, you might use
mesh2d : TriangularMesh ( Float, Float )
mesh2d =
...
to3d : ( Float, Float ) -> ( Float, Float, Float )
to3d ( x, y ) =
( x, y, 0 )
mesh3d : TriangularMesh ( Float, Float, Float )
mesh3d =
TriangularMesh.mapVertices to3d mesh2d
A
TriangularMeshis a simple form of face-vertex mesh defined by an array of vertices and a list of face indices. Each set of face indices consists of a tuple of three integer vertex indices.The vertices themselves can be any type you want. For a 2D mesh, you might have each vertex be simply a point:
For a 3D mesh, each vertex might be a (point, normal) tuple:
In more complex cases, each vertex might be a record: