commit 0825c12682eba2f6cedf645e974603f68db9624d
parent d21f6161fd4396a3c68df6ebca084f9dbba52b5f
Author: William Casarin <jb55@jb55.com>
Date: Tue, 23 Oct 2018 19:32:57 -0700
ply: initial ply parser
Diffstat:
A | src/ply.c | | | 123 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/ply.h | | | 8 | ++++++++ |
2 files changed, 131 insertions(+), 0 deletions(-)
diff --git a/src/ply.c b/src/ply.c
@@ -0,0 +1,123 @@
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "file.h"
+#include "common.h"
+
+/* void parse_vertex( */
+
+
+enum ply_state {
+ PLY_MAGIC,
+ PLY_HEADER,
+ PLY_VERTICES,
+ PLY_INDICES
+};
+
+static void skip_line(const char **cursor) {
+ while (*((*cursor)++) != '\n')
+ ;
+}
+
+static int consume_string(const char **cursor, const char *str) {
+ int len = strlen(str);
+
+ if (memcmp(*cursor, str, len) == 0)
+ *cursor += len;
+ else
+ return 0;
+
+ return 1;
+}
+
+static int parse_element(const char **cursor, int *nverts) {
+ int ok;
+ ok = consume_string(cursor, "element vertex ");
+ if (!ok)
+ return 0;
+
+ *nverts = atoi(*cursor);
+
+ consume_string(cursor, "\n");
+ return *nverts != 0;
+}
+
+
+static int parse_vertex(const char **cursor, float *v, float *n, u8 *c) {
+ int matched =
+ sscanf(*cursor, "%f %f %f %f %f %f %hhu %hhu %hhu",
+ &v[0], &v[1], &v[2],
+ &n[0], &n[1], &n[2],
+ &c[0], &c[1], &c[2]);
+ skip_line(cursor);
+
+ return matched == 9;
+}
+
+
+static int parse_header(const char **cursor, int *nverts) {
+ int res = parse_element(cursor, nverts);
+ if (res)
+ return 1;
+
+ skip_line(cursor);
+ return 0;
+}
+
+static int parse_magic(const char **cursor) {
+ return consume_string(cursor, "ply\n");
+}
+
+int parse_ply(const char *filename) {
+ size_t len;
+ int nverts = 0;
+ int success = 0;
+ int done = 0;
+ int res = 0;
+ enum ply_state state = PLY_MAGIC;
+ const char *data = file_contents(filename, &len);
+ const char *p = data;
+
+ float vert[3], norm[3];
+ u8 color[3];
+
+ while(!done) {
+ switch (state) {
+ case PLY_MAGIC:
+ res = parse_magic(&p);
+ if (!res) {
+ printf("failed to parse ply magic header\n");
+ break;
+ }
+ state = PLY_HEADER;
+ break;
+ case PLY_HEADER:
+ res = parse_header(&p, &nverts);
+ if (res)
+ printf("got nverts %d\n", nverts);
+ if (consume_string(&p, "end_header\n"))
+ state = PLY_VERTICES;
+ break;
+ case PLY_VERTICES:
+ res = parse_vertex(&p, vert, norm, color);
+ if (!res) {
+ done = 1;
+ break;
+ }
+ printf("got vert %f %f %f %f %f %f %hhu %hhu %hhu\n",
+ vert[0], vert[1], vert[2],
+ norm[0], norm[1], norm[2],
+ color[0], color[1], color[2]);
+ break;
+ case PLY_INDICES:
+ done = 1;
+ break;
+ }
+ }
+
+ free((void*)data);
+
+ return success;
+}
diff --git a/src/ply.h b/src/ply.h
@@ -0,0 +1,8 @@
+
+
+#ifndef PLYPARSER_H
+#define PLYPARSER_H
+
+int parse_ply(const char *filename);
+
+#endif /* PLYPARSER_H */