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@1
|
97
|
nuclear@1
|
98
|
nuclear@0
|
99 /* -------- mesh -------- */
|
nuclear@0
|
100
|
nuclear@1
|
101 int mesh_init(struct mesh *m, int nverts)
|
nuclear@0
|
102 {
|
nuclear@1
|
103 m->name = 0;
|
nuclear@1
|
104 m->poly_nverts = nverts;
|
nuclear@1
|
105
|
nuclear@1
|
106 if(!(m->attr = dynarr_alloc(0, sizeof *m->attr))) {
|
nuclear@1
|
107 return -1;
|
nuclear@1
|
108 }
|
nuclear@1
|
109
|
nuclear@1
|
110 if(!(m->polyidx = dynarr_alloc(0, sizeof *m->polyidx))) {
|
nuclear@1
|
111 dynarr_free(m->attr);
|
nuclear@1
|
112 return -1;
|
nuclear@1
|
113 }
|
nuclear@0
|
114 return 0;
|
nuclear@0
|
115 }
|
nuclear@0
|
116
|
nuclear@0
|
117 void mesh_destroy(struct mesh *m)
|
nuclear@0
|
118 {
|
nuclear@1
|
119 int i, nattr = mesh_attr_count(m);
|
nuclear@0
|
120
|
nuclear@1
|
121 for(i=0; i<nattr; i++) {
|
nuclear@1
|
122 vattr_destroy(m->attr + i);
|
nuclear@1
|
123 }
|
nuclear@1
|
124 dynarr_free(m->attr);
|
nuclear@0
|
125
|
nuclear@1
|
126 for(i=0; i<nattr; i++) {
|
nuclear@1
|
127 dynarr_free(m->polyidx[i].data);
|
nuclear@0
|
128 }
|
nuclear@1
|
129 dynarr_free(m->polyidx);
|
nuclear@0
|
130 }
|
nuclear@0
|
131
|
nuclear@0
|
132 int mesh_set_name(struct mesh *m, const char *name)
|
nuclear@0
|
133 {
|
nuclear@0
|
134 char *tmp;
|
nuclear@0
|
135
|
nuclear@0
|
136 if(!(tmp = malloc(strlen(name) + 1))) {
|
nuclear@0
|
137 return -1;
|
nuclear@0
|
138 }
|
nuclear@0
|
139 strcpy(tmp, name);
|
nuclear@0
|
140
|
nuclear@0
|
141 free(m->name);
|
nuclear@0
|
142 m->name = tmp;
|
nuclear@0
|
143 return 0;
|
nuclear@0
|
144 }
|
nuclear@0
|
145
|
nuclear@1
|
146 const char *mesh_get_name(struct mesh *m)
|
nuclear@0
|
147 {
|
nuclear@1
|
148 return m->name ? m->name : "<unnamed mesh>";
|
nuclear@1
|
149 }
|
nuclear@0
|
150
|
nuclear@1
|
151 int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr)
|
nuclear@1
|
152 {
|
nuclear@1
|
153 struct mesh_polyidx pidx;
|
nuclear@1
|
154 void *tmp = dynarr_push(m->attr, attr);
|
nuclear@1
|
155 if(!tmp) {
|
nuclear@0
|
156 return -1;
|
nuclear@0
|
157 }
|
nuclear@0
|
158 m->attr = tmp;
|
nuclear@0
|
159
|
nuclear@1
|
160 if(!(pidx.data = dynarr_alloc(0, m->poly_nverts * sizeof *pidx.data))) {
|
nuclear@1
|
161 assert(pidx.data);
|
nuclear@0
|
162 return -1;
|
nuclear@0
|
163 }
|
nuclear@0
|
164
|
nuclear@1
|
165 tmp = dynarr_push(m->polyidx, &pidx);
|
nuclear@1
|
166 if(!tmp) {
|
nuclear@1
|
167 assert(tmp);
|
nuclear@1
|
168 return -1;
|
nuclear@1
|
169 }
|
nuclear@1
|
170 m->polyidx = tmp;
|
nuclear@0
|
171 return 0;
|
nuclear@0
|
172 }
|
nuclear@0
|
173
|
nuclear@0
|
174 int mesh_find_attrib(struct mesh *m, const char *name)
|
nuclear@0
|
175 {
|
nuclear@1
|
176 int i, nattr = mesh_attr_count(m);
|
nuclear@0
|
177
|
nuclear@1
|
178 for(i=0; i<nattr; i++) {
|
nuclear@1
|
179 if(m->attr[i].name && strcmp(m->attr[i].name, name) == 0) {
|
nuclear@0
|
180 return i;
|
nuclear@0
|
181 }
|
nuclear@0
|
182 }
|
nuclear@0
|
183 return -1;
|
nuclear@0
|
184 }
|
nuclear@1
|
185
|
nuclear@1
|
186 int mesh_attr_count(struct mesh *m)
|
nuclear@1
|
187 {
|
nuclear@1
|
188 return dynarr_size(m->attr);
|
nuclear@1
|
189 }
|
nuclear@1
|
190
|
nuclear@1
|
191 int mesh_poly_count(struct mesh *m)
|
nuclear@1
|
192 {
|
nuclear@1
|
193 int i, nattr = mesh_attr_count(m);
|
nuclear@1
|
194
|
nuclear@1
|
195 for(i=0; i<nattr; i++) {
|
nuclear@1
|
196 int count = dynarr_empty(m->polyidx[i].data);
|
nuclear@1
|
197 if(count) {
|
nuclear@1
|
198 return count;
|
nuclear@1
|
199 }
|
nuclear@1
|
200 }
|
nuclear@1
|
201 return 0;
|
nuclear@1
|
202 }
|
nuclear@1
|
203
|
nuclear@1
|
204 int mesh_add_polyref(struct mesh *m, int attr_loc, ...)
|
nuclear@1
|
205 {
|
nuclear@1
|
206 int i, nattr = mesh_attr_count(m);
|
nuclear@1
|
207 int *poly = alloca(m->poly_nverts * sizeof *poly);
|
nuclear@1
|
208 va_list ap;
|
nuclear@1
|
209 void *tmp;
|
nuclear@1
|
210
|
nuclear@1
|
211 if(attr_loc < 0 || attr_loc >= nattr) {
|
nuclear@1
|
212 return -1;
|
nuclear@1
|
213 }
|
nuclear@1
|
214
|
nuclear@1
|
215 va_start(ap, attr_loc);
|
nuclear@1
|
216 for(i=0; i<m->poly_nverts; i++) {
|
nuclear@1
|
217 poly[i] = va_arg(ap, int);
|
nuclear@1
|
218 }
|
nuclear@1
|
219 va_end(ap);
|
nuclear@1
|
220
|
nuclear@1
|
221 if(!(tmp = dynarr_push(m->polyidx[attr_loc].data, poly))) {
|
nuclear@1
|
222 return -1;
|
nuclear@1
|
223 }
|
nuclear@1
|
224 m->polyidx[attr_loc].data = tmp;
|
nuclear@1
|
225 return 0;
|
nuclear@1
|
226 }
|