# HG changeset patch # User John Tsiombikas # Date 1326521450 -7200 # Node ID 38489ad82bf427faeeffab2c18be0b3c2468e386 # Parent 8c6d64af9505d787a9dbf57b5fb05befefb20022 foo diff -r 8c6d64af9505 -r 38489ad82bf4 src/dynarr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dynarr.c Sat Jan 14 08:10:50 2012 +0200 @@ -0,0 +1,122 @@ +#include +#include +#include +#include "dynarr.h" + +/* The array descriptor keeps auxilliary information needed to manipulate + * the dynamic array. It's allocated adjacent to the array buffer. + */ +struct arrdesc { + int nelem, szelem; + int max_elem; + int bufsz; /* not including the descriptor */ +}; + +#define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc))) + +void *dynarr_alloc(int elem, int szelem) +{ + struct arrdesc *desc; + + if(!(desc = malloc(elem * szelem + sizeof *desc))) { + return 0; + } + desc->nelem = desc->max_elem = elem; + desc->szelem = szelem; + desc->bufsz = elem * szelem; + return (char*)desc + sizeof *desc; +} + +void dynarr_free(void *da) +{ + if(da) { + free(DESC(da)); + } +} + +void *dynarr_resize(void *da, int elem) +{ + int newsz; + void *tmp; + struct arrdesc *desc; + + if(!da) return 0; + desc = DESC(da); + + newsz = desc->szelem * elem; + + if(!(tmp = realloc(desc, newsz + sizeof *desc))) { + return 0; + } + desc = tmp; + + desc->nelem = desc->max_elem = elem; + desc->bufsz = newsz; + return (char*)desc + sizeof *desc; +} + +int dynarr_empty(void *da) +{ + return DESC(da)->nelem ? 0 : 1; +} + +int dynarr_size(void *da) +{ + return DESC(da)->nelem; +} + + +/* stack semantics */ +void *dynarr_push(void *da, void *item) +{ + struct arrdesc *desc; + int nelem; + + desc = DESC(da); + nelem = desc->nelem; + + if(nelem >= desc->max_elem) { + /* need to resize */ + struct arrdesc *tmp; + int newsz = desc->max_elem ? desc->max_elem * 2 : 1; + + if(!(tmp = dynarr_resize(da, newsz))) { + fprintf(stderr, "failed to resize\n"); + return da; + } + da = tmp; + desc = DESC(da); + desc->nelem = nelem; + } + + memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem); + return da; +} + +void *dynarr_pop(void *da) +{ + struct arrdesc *desc; + int nelem; + + desc = DESC(da); + nelem = desc->nelem; + + if(!nelem) return da; + + if(nelem <= desc->max_elem / 3) { + /* reclaim space */ + struct arrdesc *tmp; + int newsz = desc->max_elem / 2; + + if(!(tmp = dynarr_resize(da, newsz))) { + fprintf(stderr, "failed to resize\n"); + return da; + } + da = tmp; + desc = DESC(da); + desc->nelem = nelem; + } + desc->nelem--; + + return da; +} diff -r 8c6d64af9505 -r 38489ad82bf4 src/dynarr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dynarr.h Sat Jan 14 08:10:50 2012 +0200 @@ -0,0 +1,16 @@ +#ifndef DYNARR_H_ +#define DYNARR_H_ + +void *dynarr_alloc(int elem, int szelem); +void dynarr_free(void *da); +void *dynarr_resize(void *da, int elem); + +int dynarr_empty(void *da); +int dynarr_size(void *da); + +/* stack semantics */ +void *dynarr_push(void *da, void *item); +void *dynarr_pop(void *da); + + +#endif /* DYNARR_H_ */ diff -r 8c6d64af9505 -r 38489ad82bf4 src/mesh.c --- a/src/mesh.c Fri Jan 13 09:34:16 2012 +0200 +++ b/src/mesh.c Sat Jan 14 08:10:50 2012 +0200 @@ -2,23 +2,53 @@ #include #include #include +#include +#include #include "mesh.h" +#include "dynarr.h" -int mattr_init(struct mesh_attrib *ma) + +struct mesh_vertattr { + char *name; + void *data; + int elem_sz; +}; + +struct mesh_polyidx { + int *data; +}; + +struct mesh { + char *name; + int poly_nverts; /* 3, 4, etc */ + + struct mesh_vertattr *attr; + struct mesh_polyidx *polyidx; +}; + + +/* --- vertex attributes --- */ + +int vattr_init(struct mesh_vertattr *ma, int elem_sz) { - memset(ma, 0, sizeof *ma); + ma->name = 0; + ma->elem_sz = elem_sz; + + if(!(ma->data = dynarr_alloc(0, elem_sz))) { + return -1; + } return 0; } -void mattr_destroy(struct mesh_attrib *ma) +void vattr_destroy(struct mesh_vertattr *ma) { if(ma) { free(ma->name); - free(ma->data); + dynarr_free(ma->data); } } -int mattr_set_name(struct mesh_attrib *ma, const char *name) +int vattr_set_name(struct mesh_vertattr *ma, const char *name) { char *tmp; @@ -32,50 +62,71 @@ return 0; } +const char *vattr_get_name(struct mesh_vertattr *ma) +{ + return ma->name ? ma->name : ""; +} + #define INITSZ (16 * ma->elem_size) -int mattr_add_elem(struct mesh_attrib *ma, void *data) +int vattr_add_elem(struct mesh_vertattr *ma, void *elem) { - int nsz = (ma->count + 1) * ma->elem_size; - - if(nsz > ma->datasz) { - void *tmp; - - nsz = ma->datasz ? ma->datasz * 2 : INITSZ; - - if(!(tmp = realloc(ma->data, nsz))) { - return -1; - } - ma->data = tmp; - ma->datasz = nsz; + void *tmp = dynarr_push(ma->data, elem); + if(!tmp) { + return -1; } - - memcpy((char*)ma->data + ma->elem_size * ma->count++, data, ma->elem_size); + ma->data = tmp; return 0; } + +void *vattr_pointer(struct mesh_vertattr *ma) +{ + return ma->data; +} + +int vattr_count(struct mesh_vertattr *ma) +{ + return dynarr_size(ma->data); +} + +int vattr_elem_size(struct mesh_vertattr *ma) +{ + return ma->elem_sz; +} + + + /* -------- mesh -------- */ -int mesh_init(struct mesh *m) +int mesh_init(struct mesh *m, int nverts) { - memset(m, 0, sizeof *m); + m->name = 0; + m->poly_nverts = nverts; + + if(!(m->attr = dynarr_alloc(0, sizeof *m->attr))) { + return -1; + } + + if(!(m->polyidx = dynarr_alloc(0, sizeof *m->polyidx))) { + dynarr_free(m->attr); + return -1; + } return 0; } void mesh_destroy(struct mesh *m) { - int i; + int i, nattr = mesh_attr_count(m); - free(m->name); + for(i=0; iattr + i); + } + dynarr_free(m->attr); - for(i=0; inum_attr; i++) { - mattr_destroy(&m->attr[i]); + for(i=0; ipolyidx[i].data); } - free(m->attr); - - for(i=0; inum_attr; i++) { - free(m->polyidx[i]); - } - free(m->polyidx); + dynarr_free(m->polyidx); } int mesh_set_name(struct mesh *m, const char *name) @@ -92,34 +143,84 @@ return 0; } -int mesh_add_attrib(struct mesh *m, struct mesh_attrib *attr) +const char *mesh_get_name(struct mesh *m) { - void *tmp; - int idx = m->num_attr++; + return m->name ? m->name : ""; +} - if(!(tmp = realloc(m->attr, m->num_attr * sizeof *attr))) { +int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr) +{ + struct mesh_polyidx pidx; + void *tmp = dynarr_push(m->attr, attr); + if(!tmp) { return -1; } m->attr = tmp; - m->attr[idx] = *attr; - if(!(tmp = realloc(m->polyidx, m->num_attr * sizeof *m->polyidx))) { - m->num_attr--; + if(!(pidx.data = dynarr_alloc(0, m->poly_nverts * sizeof *pidx.data))) { + assert(pidx.data); return -1; } - m->polyidx[idx] = 0; + tmp = dynarr_push(m->polyidx, &pidx); + if(!tmp) { + assert(tmp); + return -1; + } + m->polyidx = tmp; return 0; } int mesh_find_attrib(struct mesh *m, const char *name) { - int i; + int i, nattr = mesh_attr_count(m); - for(i=0; inum_attr; i++) { - if(strcmp(m->attr[i].name, name) == 0) { + for(i=0; iattr[i].name && strcmp(m->attr[i].name, name) == 0) { return i; } } return -1; } + +int mesh_attr_count(struct mesh *m) +{ + return dynarr_size(m->attr); +} + +int mesh_poly_count(struct mesh *m) +{ + int i, nattr = mesh_attr_count(m); + + for(i=0; ipolyidx[i].data); + if(count) { + return count; + } + } + return 0; +} + +int mesh_add_polyref(struct mesh *m, int attr_loc, ...) +{ + int i, nattr = mesh_attr_count(m); + int *poly = alloca(m->poly_nverts * sizeof *poly); + va_list ap; + void *tmp; + + if(attr_loc < 0 || attr_loc >= nattr) { + return -1; + } + + va_start(ap, attr_loc); + for(i=0; ipoly_nverts; i++) { + poly[i] = va_arg(ap, int); + } + va_end(ap); + + if(!(tmp = dynarr_push(m->polyidx[attr_loc].data, poly))) { + return -1; + } + m->polyidx[attr_loc].data = tmp; + return 0; +} diff -r 8c6d64af9505 -r 38489ad82bf4 src/mesh.h --- a/src/mesh.h Fri Jan 13 09:34:16 2012 +0200 +++ b/src/mesh.h Sat Jan 14 08:10:50 2012 +0200 @@ -1,42 +1,48 @@ #ifndef MESH_H_ #define MESH_H_ -struct mesh_attrib { - char *name; - int count, elem_size; - void *data; - - int datasz; -}; - -struct mesh { - char *name; - int poly_nverts; /* 3, 4, etc */ - - struct mesh_attrib *attr; - int num_attr; - - int **polyidx; - int num_poly; -}; +struct mesh_vertattr; +struct mesh_polyidx; +struct mesh; #ifdef __cplusplus extern "C" { #endif -int mattr_init(struct mesh_attrib *ma); -void mattr_destroy(struct mesh_attrib *ma); +/* --- vertex attributes --- */ -int mattr_set_name(struct mesh_attrib *ma, const char *name); -int mattr_add_elem(struct mesh_attrib *ma, void *data); +int vattr_init(struct mesh_vertattr *ma, int elem_sz); +void vattr_destroy(struct mesh_vertattr *ma); -int mesh_init(struct mesh *m); +int vattr_set_name(struct mesh_vertattr *ma, const char *name); +const char *vattr_get_name(struct mesh_vertattr *ma); + +int vattr_add_elem(struct mesh_vertattr *ma, void *elem); + +void *vattr_pointer(struct mesh_vertattr *ma); +int vattr_count(struct mesh_vertattr *ma); +int vattr_elem_size(struct mesh_vertattr *ma); + +/* --- mesh --- */ + +int mesh_init(struct mesh *m, int nverts); void mesh_destroy(struct mesh *m); int mesh_set_name(struct mesh *m, const char *name); -int mesh_add_attrib(struct mesh *m, struct mesh_attrib *attr); +const char *mesh_get_name(struct mesh *m); + +int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr); int mesh_find_attrib(struct mesh *m, const char *name); +int mesh_attr_count(struct mesh *m); +int mesh_poly_count(struct mesh *m); + +/* the variable arguments correspond to the N indices of the N-gon + * for this particular vertex attribute (attr_loc, retrieved by + * mesh_find_attrib) + */ +int mesh_add_polyref(struct mesh *m, int attr_loc, ...); + #ifdef __cplusplus } #endif