rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <string.h>
|
nuclear@0
|
4 #include <errno.h>
|
nuclear@1
|
5 #include <stdarg.h>
|
nuclear@1
|
6 #include <assert.h>
|
nuclear@0
|
7 #include "mesh.h"
|
nuclear@1
|
8 #include "dynarr.h"
|
nuclear@0
|
9
|
nuclear@1
|
10
|
nuclear@1
|
11 struct mesh_vertattr {
|
nuclear@1
|
12 char *name;
|
nuclear@1
|
13 void *data;
|
nuclear@1
|
14 int elem_sz;
|
nuclear@1
|
15 };
|
nuclear@1
|
16
|
nuclear@1
|
17 struct mesh_polyidx {
|
nuclear@1
|
18 int *data;
|
nuclear@1
|
19 };
|
nuclear@1
|
20
|
nuclear@1
|
21 struct mesh {
|
nuclear@1
|
22 char *name;
|
nuclear@1
|
23 int poly_nverts; /* 3, 4, etc */
|
nuclear@1
|
24
|
nuclear@1
|
25 struct mesh_vertattr *attr;
|
nuclear@1
|
26 struct mesh_polyidx *polyidx;
|
nuclear@1
|
27 };
|
nuclear@1
|
28
|
nuclear@1
|
29
|
nuclear@1
|
30 /* --- vertex attributes --- */
|
nuclear@1
|
31
|
nuclear@1
|
32 int vattr_init(struct mesh_vertattr *ma, int elem_sz)
|
nuclear@0
|
33 {
|
nuclear@1
|
34 ma->name = 0;
|
nuclear@1
|
35 ma->elem_sz = elem_sz;
|
nuclear@1
|
36
|
nuclear@1
|
37 if(!(ma->data = dynarr_alloc(0, elem_sz))) {
|
nuclear@1
|
38 return -1;
|
nuclear@1
|
39 }
|
nuclear@0
|
40 return 0;
|
nuclear@0
|
41 }
|
nuclear@0
|
42
|
nuclear@1
|
43 void vattr_destroy(struct mesh_vertattr *ma)
|
nuclear@0
|
44 {
|
nuclear@0
|
45 if(ma) {
|
nuclear@0
|
46 free(ma->name);
|
nuclear@1
|
47 dynarr_free(ma->data);
|
nuclear@0
|
48 }
|
nuclear@0
|
49 }
|
nuclear@0
|
50
|
nuclear@1
|
51 int vattr_set_name(struct mesh_vertattr *ma, const char *name)
|
nuclear@0
|
52 {
|
nuclear@0
|
53 char *tmp;
|
nuclear@0
|
54
|
nuclear@0
|
55 if(!(tmp = malloc(strlen(name) + 1))) {
|
nuclear@0
|
56 return -1;
|
nuclear@0
|
57 }
|
nuclear@0
|
58 strcpy(tmp, name);
|
nuclear@0
|
59
|
nuclear@0
|
60 free(ma->name);
|
nuclear@0
|
61 ma->name = tmp;
|
nuclear@0
|
62 return 0;
|
nuclear@0
|
63 }
|
nuclear@0
|
64
|
nuclear@1
|
65 const char *vattr_get_name(struct mesh_vertattr *ma)
|
nuclear@1
|
66 {
|
nuclear@1
|
67 return ma->name ? ma->name : "<unnamed vattr>";
|
nuclear@1
|
68 }
|
nuclear@1
|
69
|
nuclear@0
|
70 #define INITSZ (16 * ma->elem_size)
|
nuclear@1
|
71 int vattr_add_elem(struct mesh_vertattr *ma, void *elem)
|
nuclear@0
|
72 {
|
nuclear@1
|
73 void *tmp = dynarr_push(ma->data, elem);
|
nuclear@1
|
74 if(!tmp) {
|
nuclear@1
|
75 return -1;
|
nuclear@0
|
76 }
|
nuclear@1
|
77 ma->data = tmp;
|
nuclear@0
|
78 return 0;
|
nuclear@0
|
79 }
|
nuclear@0
|
80
|
nuclear@1
|
81
|
nuclear@1
|
82 void *vattr_pointer(struct mesh_vertattr *ma)
|
nuclear@1
|
83 {
|
nuclear@1
|
84 return ma->data;
|
nuclear@1
|
85 }
|
nuclear@1
|
86
|
nuclear@1
|
87 int vattr_count(struct mesh_vertattr *ma)
|
nuclear@1
|
88 {
|
nuclear@1
|
89 return dynarr_size(ma->data);
|
nuclear@1
|
90 }
|
nuclear@1
|
91
|
nuclear@1
|
92 int vattr_elem_size(struct mesh_vertattr *ma)
|
nuclear@1
|
93 {
|
nuclear@1
|
94 return ma->elem_sz;
|
nuclear@1
|
95 }
|
nuclear@1
|
96
|
nuclear@3
|
97 void *vattr_elem(struct mesh_vertattr *ma, int elem)
|
nuclear@3
|
98 {
|
nuclear@3
|
99 int count = dynarr_size(ma->data);
|
nuclear@3
|
100 if(elem >= count) {
|
nuclear@3
|
101 return 0;
|
nuclear@3
|
102 }
|
nuclear@3
|
103 return (char*)ma->data + elem * ma->elem_sz;
|
nuclear@3
|
104 }
|
nuclear@1
|
105
|
nuclear@1
|
106
|
nuclear@0
|
107 /* -------- mesh -------- */
|
nuclear@0
|
108
|
nuclear@1
|
109 int mesh_init(struct mesh *m, int nverts)
|
nuclear@0
|
110 {
|
nuclear@1
|
111 m->name = 0;
|
nuclear@1
|
112 m->poly_nverts = nverts;
|
nuclear@1
|
113
|
nuclear@1
|
114 if(!(m->attr = dynarr_alloc(0, sizeof *m->attr))) {
|
nuclear@1
|
115 return -1;
|
nuclear@1
|
116 }
|
nuclear@1
|
117
|
nuclear@1
|
118 if(!(m->polyidx = dynarr_alloc(0, sizeof *m->polyidx))) {
|
nuclear@1
|
119 dynarr_free(m->attr);
|
nuclear@1
|
120 return -1;
|
nuclear@1
|
121 }
|
nuclear@0
|
122 return 0;
|
nuclear@0
|
123 }
|
nuclear@0
|
124
|
nuclear@0
|
125 void mesh_destroy(struct mesh *m)
|
nuclear@0
|
126 {
|
nuclear@3
|
127 int i, nattr = mesh_num_attribs(m);
|
nuclear@0
|
128
|
nuclear@1
|
129 for(i=0; i<nattr; i++) {
|
nuclear@1
|
130 vattr_destroy(m->attr + i);
|
nuclear@1
|
131 }
|
nuclear@1
|
132 dynarr_free(m->attr);
|
nuclear@0
|
133
|
nuclear@1
|
134 for(i=0; i<nattr; i++) {
|
nuclear@1
|
135 dynarr_free(m->polyidx[i].data);
|
nuclear@0
|
136 }
|
nuclear@1
|
137 dynarr_free(m->polyidx);
|
nuclear@0
|
138 }
|
nuclear@0
|
139
|
nuclear@0
|
140 int mesh_set_name(struct mesh *m, const char *name)
|
nuclear@0
|
141 {
|
nuclear@0
|
142 char *tmp;
|
nuclear@0
|
143
|
nuclear@0
|
144 if(!(tmp = malloc(strlen(name) + 1))) {
|
nuclear@0
|
145 return -1;
|
nuclear@0
|
146 }
|
nuclear@0
|
147 strcpy(tmp, name);
|
nuclear@0
|
148
|
nuclear@0
|
149 free(m->name);
|
nuclear@0
|
150 m->name = tmp;
|
nuclear@0
|
151 return 0;
|
nuclear@0
|
152 }
|
nuclear@0
|
153
|
nuclear@1
|
154 const char *mesh_get_name(struct mesh *m)
|
nuclear@0
|
155 {
|
nuclear@1
|
156 return m->name ? m->name : "<unnamed mesh>";
|
nuclear@1
|
157 }
|
nuclear@0
|
158
|
nuclear@3
|
159 int mesh_poly_type(struct mesh *m)
|
nuclear@3
|
160 {
|
nuclear@3
|
161 return m->poly_nverts;
|
nuclear@3
|
162 }
|
nuclear@3
|
163
|
nuclear@1
|
164 int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr)
|
nuclear@1
|
165 {
|
nuclear@1
|
166 struct mesh_polyidx pidx;
|
nuclear@1
|
167 void *tmp = dynarr_push(m->attr, attr);
|
nuclear@1
|
168 if(!tmp) {
|
nuclear@0
|
169 return -1;
|
nuclear@0
|
170 }
|
nuclear@0
|
171 m->attr = tmp;
|
nuclear@0
|
172
|
nuclear@1
|
173 if(!(pidx.data = dynarr_alloc(0, m->poly_nverts * sizeof *pidx.data))) {
|
nuclear@1
|
174 assert(pidx.data);
|
nuclear@0
|
175 return -1;
|
nuclear@0
|
176 }
|
nuclear@0
|
177
|
nuclear@1
|
178 tmp = dynarr_push(m->polyidx, &pidx);
|
nuclear@1
|
179 if(!tmp) {
|
nuclear@1
|
180 assert(tmp);
|
nuclear@1
|
181 return -1;
|
nuclear@1
|
182 }
|
nuclear@1
|
183 m->polyidx = tmp;
|
nuclear@0
|
184 return 0;
|
nuclear@0
|
185 }
|
nuclear@0
|
186
|
nuclear@3
|
187 int mesh_num_attribs(struct mesh *m)
|
nuclear@3
|
188 {
|
nuclear@3
|
189 return dynarr_size(m->attr);
|
nuclear@3
|
190 }
|
nuclear@3
|
191
|
nuclear@0
|
192 int mesh_find_attrib(struct mesh *m, const char *name)
|
nuclear@0
|
193 {
|
nuclear@3
|
194 int i, nattr = mesh_num_attribs(m);
|
nuclear@0
|
195
|
nuclear@1
|
196 for(i=0; i<nattr; i++) {
|
nuclear@1
|
197 if(m->attr[i].name && strcmp(m->attr[i].name, name) == 0) {
|
nuclear@0
|
198 return i;
|
nuclear@0
|
199 }
|
nuclear@0
|
200 }
|
nuclear@0
|
201 return -1;
|
nuclear@0
|
202 }
|
nuclear@1
|
203
|
nuclear@3
|
204 struct mesh_vertattr *mesh_attrib(struct mesh *m, int loc)
|
nuclear@1
|
205 {
|
nuclear@3
|
206 return loc >= 0 ? m->attr + loc : 0;
|
nuclear@3
|
207 }
|
nuclear@3
|
208
|
nuclear@3
|
209 void *mesh_attrib_data(struct mesh *m, int loc)
|
nuclear@3
|
210 {
|
nuclear@3
|
211 return loc >= 0 ? m->attr[loc].data : 0;
|
nuclear@3
|
212 }
|
nuclear@3
|
213
|
nuclear@3
|
214 int *mesh_poly_data(struct mesh *m, int loc)
|
nuclear@3
|
215 {
|
nuclear@3
|
216 return loc >= 0 ? m->polyidx[loc].data : 0;
|
nuclear@3
|
217 }
|
nuclear@3
|
218
|
nuclear@3
|
219
|
nuclear@3
|
220 int mesh_attrib_count(struct mesh *m, int loc)
|
nuclear@3
|
221 {
|
nuclear@3
|
222 return loc >= 0 ? vattr_count(m->attr + loc) : 0;
|
nuclear@1
|
223 }
|
nuclear@1
|
224
|
nuclear@1
|
225 int mesh_poly_count(struct mesh *m)
|
nuclear@1
|
226 {
|
nuclear@3
|
227 int i, nattr = mesh_num_attribs(m);
|
nuclear@1
|
228
|
nuclear@1
|
229 for(i=0; i<nattr; i++) {
|
nuclear@1
|
230 int count = dynarr_empty(m->polyidx[i].data);
|
nuclear@1
|
231 if(count) {
|
nuclear@1
|
232 return count;
|
nuclear@1
|
233 }
|
nuclear@1
|
234 }
|
nuclear@1
|
235 return 0;
|
nuclear@1
|
236 }
|
nuclear@1
|
237
|
nuclear@3
|
238 void *mesh_attrib_elem(struct mesh *m, int loc, int elem)
|
nuclear@3
|
239 {
|
nuclear@3
|
240 return loc >= 0 ? vattr_elem(m->attr + loc, elem) : 0;
|
nuclear@3
|
241 }
|
nuclear@3
|
242
|
nuclear@3
|
243 int mesh_attrib_elem_size(struct mesh *m, int loc)
|
nuclear@3
|
244 {
|
nuclear@3
|
245 return loc >= 0 ? m->attr[loc].elem_sz : 0;
|
nuclear@3
|
246 }
|
nuclear@3
|
247
|
nuclear@1
|
248 int mesh_add_polyref(struct mesh *m, int attr_loc, ...)
|
nuclear@1
|
249 {
|
nuclear@3
|
250 int i, nattr = mesh_num_attribs(m);
|
nuclear@1
|
251 int *poly = alloca(m->poly_nverts * sizeof *poly);
|
nuclear@1
|
252 va_list ap;
|
nuclear@1
|
253 void *tmp;
|
nuclear@1
|
254
|
nuclear@1
|
255 if(attr_loc < 0 || attr_loc >= nattr) {
|
nuclear@1
|
256 return -1;
|
nuclear@1
|
257 }
|
nuclear@1
|
258
|
nuclear@1
|
259 va_start(ap, attr_loc);
|
nuclear@1
|
260 for(i=0; i<m->poly_nverts; i++) {
|
nuclear@1
|
261 poly[i] = va_arg(ap, int);
|
nuclear@1
|
262 }
|
nuclear@1
|
263 va_end(ap);
|
nuclear@1
|
264
|
nuclear@1
|
265 if(!(tmp = dynarr_push(m->polyidx[attr_loc].data, poly))) {
|
nuclear@1
|
266 return -1;
|
nuclear@1
|
267 }
|
nuclear@1
|
268 m->polyidx[attr_loc].data = tmp;
|
nuclear@1
|
269 return 0;
|
nuclear@1
|
270 }
|