Implementing make-mesh
[mixamesh.git] / README
blobf9d499f1869323dcdb2545966d5f521374ec031b
2 Mixamesh
3 ========
5 Mixamesh aims to be a Common Lisp equivalent of Open Mesh, which
6 treats the mesh as a flexible data type containing varying numbers of
7 arrays of vertices, and tagged vertex attributes indexed by a
8 collection of faces. Common Lisp macro expansion being somewhat more
9 concise and less syntax laden than C++ Template expansion, the
10 interface is somewhat simpler, too.
12 There is a single macro form that expands to the class defintion of a mesh
13 and the functions that operate on it.
15 For example:
17 (def-mesh-type textured-mesh mesh (texcoord uvs-of vector2d))
19 Would define a class called textured mesh derived from mesh mesh is a
20 base class which is defined in mixamesh which is assumed to be the
21 base of all meshes. It would have an accessor called uvs-of, wich
22 would give us access to an array of vector2ds called texcoords contained
23 within an instance of the mesh class.
25 The base class, mesh exists so that generic functions that operate on
26 all meshes can be defined. It is assumed to contain vertices organised
27 into faces, and both vertex and face normals are assumed to be
28 present. Beyond that, no assumptions about mesh attributes are made.
30 Every mesh defined by def-mesh-type comes with several helpers. An
31 instance of the mesh class defined by def-mesh-type itself is a
32 funcallable class, which is roughly anlougus to a C++ functor - an
33 object instance to which function call syntax and semantics can
34 be applied. This is not standard Common Lisp, but is common to
35 nearly all extant Common Lisp implementations and the Closer-Mop
36 library provides a wrapper round any functional differences.
38 When called as a function the mesh instance invokes the mesh-builder
39 generic functions which has specialisation methods defined for every
40 mesh defined via def-mesh-type, due to the fact that def-mesh-type
41 expands them at run time. The function will take a keyword as it's
42 first argument, denoting an operation, and a tuple in array form.
44 The keyword is of the form :add-{attribute-name} or
45 :set-{atrribute-name} eg.  add-vertex, add-colour, set-uv. The add-{*}
46 form assumes that we wish to add an attribute of that type to the
47 exising array of attributes in that mesh.
49 The :set-{*} form assumes that the function invocation is to modify an
50 existing attribute to the mesh. The index of the attributet to modify
51 is not passed in with the function, but stored in the mesh instance
52 itself along with the array. The accessor to it is named
53 current-{attribute-name}-index-of: eg (current-colour-index-of mesh). 
55 This is not supplied as a parameter so that when the
56 :add-{attribute-name} operation is used, it may update this to be the
57 index of the last element in the array of that attribute. This helps
58 when maintaining a one to one mapping between vertices and attributes
59 in that it enables us to be sure vertex and attribute arrays are the
60 same size.
62 It's possible that this is actually an excessively complex interface
63 and something simpler might be engineered via the genralized
64 assignement mechanism of Common Lisp whereby place forms are treated
65 as assigment targets by creating a set of defsetf expanders for each
66 attribute. The author did not explore this avenue.
69 Mixamesh is still less flexible than Open Mesh in that it expects
70 meshes to be indexed by triangluar faces and does not make this
71 optional. It also does not allow indexing by polyonal faces or the use
72 of halfedge data for mesh based algorithms that need more topological
73 information. However there is no real reason that it could not be
74 expanded to do so, given that Lisps macro-expsansion capabilities are
75 a superset of C++'s template expansion capabilities that Open Mesh is
76 based upon.
78 Mixamesh deals only with creating a flexible mesh
79 representation. Actual rendering of the mesh is left to the client of
80 the package. It is envisaged that rendering is handled by a generic
81 function, specialised per mesh type. A more flexible renderer would
82 specialise by attribute type and compose into a renderer for a given
83 mesh type.