1 #ifndef CISOBJSERIALIZE_H_ 2 #define CISOBJSERIALIZE_H_ 53 void free_obj(
obj_t *p) {
56 for (i = 0; i < p->
nvert; i++) {
66 for (i = 0; i < p->
nvert; i++) {
75 if (p->
faces != NULL) {
76 for (i = 0; i < p->
nface; i++) {
77 if (p->
faces[i] != NULL) {
86 for (i = 0; i < p->
ntexc; i++) {
96 for (i = 0; i < p->
nnorm; i++) {
106 for (i = 0; i < p->
nface; i++) {
116 for (i = 0; i < p->
nface; i++) {
143 int alloc_obj(
obj_t *p,
int nvert,
int nface,
144 int ntexc,
int nnorm,
int do_color) {
152 float **new_vert = (
float**)malloc(p->
nvert*
sizeof(
float*));
153 if (new_vert == NULL) {
154 cislog_error(
"alloc_obj: Failed to allocate vertices.");
159 for (i = 0; i < p->
nvert; i++) {
160 float *ivert = (
float*)malloc(3*
sizeof(
float));
162 cislog_error(
"alloc_obj: Failed to allocate vertex %d.", i);
168 cislog_debug(
"alloc_obj: Allocated %d vertices.", nvert);
171 int **new_vert = (
int**)malloc(p->
nvert*
sizeof(
int*));
172 if (new_vert == NULL) {
173 cislog_error(
"alloc_obj: Failed to allocate vertex_colors.");
178 for (i = 0; i < p->
nvert; i++) {
179 int *ivert = (
int*)malloc(3*
sizeof(
int));
181 cislog_error(
"alloc_obj: Failed to allocate vertex color %d.", i);
187 cislog_debug(
"alloc_obj: Allocated %d vertex colors.", nvert);
190 float **new_texc = (
float**)malloc(p->
ntexc*
sizeof(
float*));
191 if (new_texc == NULL) {
192 cislog_error(
"alloc_obj: Failed to allocate texcoords.");
197 for (i = 0; i < p->
ntexc; i++) {
198 float *itexc = (
float*)malloc(2*
sizeof(
float));
200 cislog_error(
"alloc_obj: Failed to allocate texcoord %d.", i);
206 cislog_debug(
"alloc_obj: Allocated %d texcoords.", ntexc);
208 float **new_norm = (
float**)malloc(p->
nnorm*
sizeof(
float*));
209 if (new_norm == NULL) {
210 cislog_error(
"alloc_obj: Failed to allocate normals.");
215 for (i = 0; i < p->
nnorm; i++) {
216 float *inorm = (
float*)malloc(3*
sizeof(
float));
218 cislog_error(
"alloc_obj: Failed to allocate normal %d.", i);
224 cislog_debug(
"alloc_obj: Allocated %d normals.", nnorm);
226 int **new_face = (
int**)malloc(p->
nface*
sizeof(
int*));
227 if (new_face == NULL) {
228 cislog_error(
"alloc_obj: Failed to allocate faces.");
233 for (i = 0; i < p->
nface; i++) {
234 int *iface = (
int*)malloc(3*
sizeof(
int));
236 cislog_error(
"alloc_obj: Failed to allocate face %d.", i);
242 cislog_debug(
"alloc_obj: Allocated %d faces.", nface);
244 int **new_ftexc = (
int**)malloc(p->
nface*
sizeof(
int*));
245 if (new_ftexc == NULL) {
246 cislog_error(
"alloc_obj: Failed to allocate face texcoords.");
251 for (i = 0; i < p->
nface; i++) {
252 int *iftexc = (
int*)malloc(3*
sizeof(
int));
253 if (iftexc == NULL) {
254 cislog_error(
"alloc_obj: Failed to allocate texcoords for face %d.", i);
260 cislog_debug(
"alloc_obj: Allocated %d face texcoords.", nface);
262 int **new_fnorm = (
int**)malloc(p->
nface*
sizeof(
int*));
263 if (new_fnorm == NULL) {
264 cislog_error(
"alloc_obj: Failed to allocate face normals.");
269 for (i = 0; i < p->
nface; i++) {
270 int *ifnorm = (
int*)malloc(3*
sizeof(
int));
271 if (ifnorm == NULL) {
272 cislog_error(
"alloc_obj: Failed to allocate normals for face %d.", i);
278 cislog_debug(
"alloc_obj: Allocated %d face normals.", nface);
280 cislog_debug(
"alloc_obj: Allocated for %d vertices and %d faces.",
296 int serialize_obj(
const seri_t s,
char *buf,
const size_t buf_size,
297 int *args_used, va_list ap) {
307 char header_format[500] =
"# Author cis_auto\n" 308 "# Generated by cis_interface\n";
310 sprintf(header_format + strlen(header_format),
"usemtl %s\n", p.
material);
312 ilen = strlen(header_format);
313 if (ilen >= (buf_size - msg_len)) {
314 cislog_error(
"serialize_obj: Buffer (size = %d) is not large " 315 "enough to contain the header (size = %d).", buf_size, ilen);
316 return msg_len + ilen;
318 strcat(buf, header_format);
319 msg_len = msg_len + ilen;
322 for (i = 0; i < p.
nvert; i++) {
324 ilen = snprintf(buf + msg_len, buf_size - msg_len,
"v %f %f %f %d %d %d\n",
328 ilen = snprintf(buf + msg_len, buf_size - msg_len,
"v %f %f %f\n",
332 cislog_error(
"serialize_obj: Error formatting vertex %d.", i);
334 }
else if (ilen >= (buf_size - msg_len)) {
335 cislog_error(
"serialize_obj: Buffer (size = %d) is not large " 336 "enough to contain vertex %d (size = %d).",
337 buf_size, i, ilen + msg_len);
338 return msg_len + ilen;
340 msg_len = msg_len + ilen;
343 for (i = 0; i < p.
ntexc; i++) {
344 ilen = snprintf(buf + msg_len, buf_size - msg_len,
"vt %f %f\n",
347 cislog_error(
"serialize_obj: Error formatting texcoord %d.", i);
349 }
else if (ilen >= (buf_size - msg_len)) {
350 cislog_error(
"serialize_obj: Buffer (size = %d) is not large " 351 "enough to contain texcoord %d (size = %d).",
352 buf_size, i, ilen + msg_len);
353 return msg_len + ilen;
355 msg_len = msg_len + ilen;
358 for (i = 0; i < p.
nnorm; i++) {
359 ilen = snprintf(buf + msg_len, buf_size - msg_len,
"vn %f %f %f\n",
362 cislog_error(
"serialize_obj: Error formatting normal %d.", i);
364 }
else if (ilen >= (buf_size - msg_len)) {
365 cislog_error(
"serialize_obj: Buffer (size = %d) is not large " 366 "enough to contain normal %d (size = %d).",
367 buf_size, i, ilen + msg_len);
368 return msg_len + ilen;
370 msg_len = msg_len + ilen;
373 for (i = 0; i < p.
nface; i++) {
376 for (j = 0; j < 3; j++) {
377 sprintf(ival,
" %d", p.
faces[i][j] + 1);
390 ilen = snprintf(buf + msg_len, buf_size - msg_len,
"%s\n", iline);
392 cislog_error(
"serialize_obj: Error formatting line face %d.", i);
394 }
else if (ilen > (buf_size - msg_len)) {
395 cislog_error(
"serialize_obj: Buffer (size = %d) is not large " 396 "enough to contain line for face %d (size = %d).",
397 buf_size, i, ilen + msg_len);
398 return msg_len + ilen;
400 msg_len = msg_len + ilen;
415 int deserialize_obj(
const seri_t s,
const char *buf,
const size_t buf_siz,
423 int nvert = 0, nface = 0, ntexc = 0, nnorm = 0, nmatl = 0;
428 int n_re_face = 3*3 + 1;
432 char re_vert[100] =
"v ([^ \n]+) ([^ \n]+) ([^ \n]+) ([^ \n]+) ([^ \n]+) ([^ \n]+)";
433 char re_face[100] =
"f ([^ \n/]*)/([^ \n/]*)/([^ \n/]*) " 434 "([^ \n/]*)/([^ \n/]*)/([^ \n/]*) " 435 "([^ \n/]*)/([^ \n/]*)/([^ \n/]*)";
436 char re_texc[100] =
"vt ([^ \n]+) ([^ \n]+)";
437 char re_norm[100] =
"vn ([^ \n]+) ([^ \n]+) ([^ \n]+)";
438 char re_matl[100] =
"usemtl ([^\n]+)";
439 nvert = count_matches(re_vert, buf);
443 strcpy(re_vert,
"v ([^ \n]+) ([^ \n]+) ([^ \n]+)");
445 nvert = count_matches(re_vert, buf);
447 nface = count_matches(re_face, buf);
448 ntexc = count_matches(re_texc, buf);
449 nnorm = count_matches(re_norm, buf);
450 nmatl = count_matches(re_matl, buf);
451 cislog_debug(
"deserialize_obj: expecting %d verts, %d faces, %d texcoords, %d normals",
452 nvert, nface, ntexc, nnorm);
455 int ret = alloc_obj(p, nvert, nface, ntexc, nnorm, do_colors);
457 cislog_error(
"deserialize_obj: Error allocating obj structure.");
462 int cvert = 0, cface = 0, ctexc = 0, cnorm = 0, cmatl = 0;
465 size_t iline_siz = 0;
466 size_t sind_line, eind_line;
470 while (cur_pos < buf_siz) {
471 cislog_debug(
"deserialize_obj: Starting position %d/%d",
473 int n_sub_matches = find_match(
"([^\n]*)\n", buf + cur_pos,
474 &sind_line, &eind_line);
475 if (n_sub_matches == 0) {
476 cislog_debug(
"deserialize_obj: End of file.");
478 eind_line = buf_siz - cur_pos;
480 iline_siz = eind_line - sind_line;
481 memcpy(iline, buf + cur_pos, iline_siz);
482 iline[iline_siz] =
'\0';
483 cislog_debug(
"deserialize_obj: iline = %s", iline);
485 if (find_matches(
"#[^\n]*", iline, &sind, &eind) == 1) {
487 cislog_debug(
"deserialize_obj: Comment");
488 }
else if (find_matches(re_matl, iline, &sind, &eind) == n_re_matl) {
490 cislog_debug(
"deserialize_obj: Material");
491 int matl_size = eind[1] - sind[1];
492 memcpy(p->
material, iline+sind[1], matl_size);
495 }
else if (find_matches(re_vert, iline, &sind, &eind) == n_re_vert) {
497 cislog_debug(
"deserialize_obj: Vertex");
498 for (j = 0; j < 3; j++) {
499 p->
vertices[cvert][j] = atof(iline + sind[j+1]);
502 for (j = 0; j < 3; j++) {
507 }
else if (find_matches(re_norm, iline, &sind, &eind) == n_re_norm) {
509 cislog_debug(
"deserialize_obj: Normals");
510 for (j = 0; j < 3; j++) {
511 p->
normals[cnorm][j] = atof(iline + sind[j+1]);
514 }
else if (find_matches(re_texc, iline, &sind, &eind) == n_re_texc) {
516 cislog_debug(
"deserialize_obj: Texcoords");
517 for (j = 0; j < 2; j++) {
518 p->
texcoords[ctexc][j] = atof(iline + sind[j+1]);
521 }
else if (find_matches(re_face, iline, &sind, &eind) == n_re_face) {
523 int n_sub_matches = find_matches(re_face, iline, &sind, &eind);
524 cislog_debug(
"deserialize_obj: Face");
525 for (j = 0; j < 3; j++) {
526 p->
faces[cface][j] = atoi(iline + sind[3*j+1]) - 1;
527 if ((eind[3*j+2] - sind[3*j+2]) == 0)
531 if ((eind[3*j+3] - sind[3*j+3]) == 0)
534 p->
face_normals[cface][j] = atoi(iline + sind[3*j+3]) - 1;
537 }
else if (find_matches(
"\n+", iline, &sind, &eind) == 1) {
539 cislog_debug(
"deserialize_obj: Empty line");
541 cislog_error(
"deserialize_obj: Could not match line: %s", iline);
546 cur_pos = cur_pos + eind_line;
547 cislog_debug(
"deserialize_obj: Advancing to position %d/%d",
552 if (cvert != nvert) {
553 cislog_error(
"deserialize_obj: Found %d verts, expected %d.", cvert, nvert);
556 if (cface != nface) {
557 cislog_error(
"deserialize_obj: Found %d faces, expected %d.", cface, nface);
560 if (ctexc != ntexc) {
561 cislog_error(
"deserialize_obj: Found %d texcs, expected %d.", ctexc, ntexc);
564 if (cnorm != nnorm) {
565 cislog_error(
"deserialize_obj: Found %d norms, expected %d.", cnorm, nnorm);
568 if (cmatl != nmatl) {
569 cislog_error(
"deserialize_obj: Found %d materials, expected %d.", cmatl, nmatl);
574 if (sind != NULL) free(sind);
575 if (eind != NULL) free(eind);
int ** face_normals
Indices of normals for each face.
Definition: ObjSerialize.h:23
int ** face_texcoords
Indices of texcoords for each face.
Definition: ObjSerialize.h:22
Serializer structure.
Definition: SerializeBase.h:19
Obj structure.
Definition: ObjSerialize.h:11
int nvert
Number of vertices.
Definition: ObjSerialize.h:12
char material[100]
Material that should be used for faces.
Definition: ObjSerialize.h:17
int ntexc
Number of texture coordinates.
Definition: ObjSerialize.h:18
int ** vertex_colors
RGB colors of each vertex.
Definition: ObjSerialize.h:16
int nface
Number faces.
Definition: ObjSerialize.h:13
int ** faces
Indices of the vertices composing each face.
Definition: ObjSerialize.h:15
float ** normals
X, Y, Z direction of normals.
Definition: ObjSerialize.h:21
float ** texcoords
Texture coordinates.
Definition: ObjSerialize.h:20
float ** vertices
X, Y, Z positions of vertices.
Definition: ObjSerialize.h:14
int nnorm
Number of normals.
Definition: ObjSerialize.h:19