commit 95c780728ce0366819c1ba9f7fab3c9064c84663
parent 0eb797de96c8724ee10d5e5290768b2d8e9108d0
Author: vaplv <vaplv@free.fr>
Date: Sat, 5 Jul 2014 15:29:30 +0200
Add and test the face getter
Diffstat:
| M | src/obj.c | | | 36 | +++++++++++++++++++----------------- |
| M | src/obj.h | | | 16 | ++++++++++++++++ |
| M | src/test_obj.c | | | 272 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
3 files changed, 204 insertions(+), 120 deletions(-)
diff --git a/src/obj.c b/src/obj.c
@@ -13,14 +13,6 @@ struct vertex {
size_t itexcoord;
};
-struct face {
- size_t ivertex; /* Index toward the first vertex */
- size_t nvertices; /* Vertex count */
- size_t igroup; /* Index toward the face group */
- size_t ismooth_group; /* Index toward the face smooth group */
- size_t imtl; /* Index toward the face material */
-};
-
struct named_group {
struct str name;
size_t iface; /* Index toward the first face */
@@ -74,7 +66,7 @@ named_group_copy_and_release(struct named_group* dst, struct named_group* src)
/* Generate the darray_face data structure */
#define DARRAY_NAME face
-#define DARRAY_DATA struct face
+#define DARRAY_DATA struct obj_face
#include <rsys/dynamic_array.h>
/* Generate the darray_named_group data structure */
@@ -243,16 +235,16 @@ error:
static enum obj_result
parse_face(struct obj* obj, char** word_tk)
{
- struct face face;
+ struct obj_face face;
char* word;
enum obj_result res = OBJ_OK;
ASSERT(obj && word_tk);
- face.ivertex = darray_vertex_size_get(&obj->vertices);
- face.nvertices = 0;
- face.igroup = darray_named_group_size_get(&obj->groups) - 1;
- face.ismooth_group = darray_smooth_group_size_get(&obj->smooth_groups) - 1;
- face.imtl = darray_named_group_size_get(&obj->usemtls) - 1;
+ face.vertex_id = darray_vertex_size_get(&obj->vertices);
+ face.vertices_count = 0;
+ face.group_id = darray_named_group_size_get(&obj->groups) - 1;
+ face.smooth_group_id = darray_smooth_group_size_get(&obj->smooth_groups) - 1;
+ face.mtl_id = darray_named_group_size_get(&obj->usemtls) - 1;
while((word = strtok_r(NULL, " ", word_tk))) {
char* id, *id_tk;
struct vertex vert;
@@ -275,7 +267,7 @@ parse_face(struct obj* obj, char** word_tk)
res = OBJ_MEMORY_ERROR;
goto error;
}
- ++face.nvertices;
+ ++face.vertices_count;
}
if(darray_face_push_back(&obj->faces, &face)) {
@@ -286,7 +278,7 @@ parse_face(struct obj* obj, char** word_tk)
exit:
return res;
error:
- FOR_EACH_REVERSE(face.nvertices, face.nvertices, 0)
+ FOR_EACH_REVERSE(face.vertices_count, face.vertices_count, 0)
darray_vertex_pop_back(&obj->vertices);
goto exit;
}
@@ -652,3 +644,13 @@ obj_desc_get(struct obj* obj, struct obj_desc* desc)
return OBJ_OK;
}
+enum obj_result
+obj_face_get(const struct obj* obj, const size_t iface, struct obj_face* face)
+{
+ if(!obj || !face || iface >= darray_face_size_get(&obj->faces))
+ return OBJ_BAD_ARGUMENT;
+ *face = darray_face_cdata_get(&obj->faces)[iface];
+ return OBJ_OK;
+}
+
+
diff --git a/src/obj.h b/src/obj.h
@@ -17,6 +17,8 @@
#define OBJ(Func) obj_##Func
#endif
+#define OBJ_ID_NONE ((size_t)(-1))
+
enum obj_result {
OBJ_BAD_ARGUMENT,
OBJ_IO_ERROR,
@@ -32,6 +34,14 @@ struct obj_desc {
size_t mtllibs_count;
};
+struct obj_face {
+ size_t vertex_id; /* Index of the first face vertex */
+ size_t vertices_count;
+ size_t group_id; /* Index of the face group */
+ size_t smooth_group_id; /* Index of the face smooth group */
+ size_t mtl_id; /* Index of the face material */
+};
+
struct obj;
struct mem_allocator;
@@ -60,6 +70,12 @@ obj_desc_get
(struct obj* obj,
struct obj_desc* desc);
+OBJ_API enum obj_result
+obj_face_get
+ (const struct obj* obj,
+ const size_t face_id,
+ struct obj_face* face);
+
END_DECLS
#endif /* OBJ_H */
diff --git a/src/test_obj.c b/src/test_obj.c
@@ -2,120 +2,39 @@
#include <rsys/mem_allocator.h>
#include <string.h>
-static const char* plane_obj =
- "mtllib master.mtl"
- "\n"
- "v 0.0000 2.0000 0.0000\n"
- "v 0.0000 0.0000 0.0000\n"
- "v 2.0000 0.0000 0.0000\n"
- "v 2.0000 2.0000 0.0000\n"
- "vt 0.0000 1.0000 0.0000\n"
- "vt 0.0000 0.0000 0.0000\n"
- "vt 1.0000 0.0000 0.0000\n"
- "vt 1.0000 1.0000 0.0000\n"
- "# 4 vertices\n"
- "\n"
- "usemtl wood\n"
- "f 1/1 2/2 3/3 4/4\n"
- "# 1 element\n";
-
-
-static const char* squares_obj =
- "v 0.000000 2.000000 0.000000\n"
- "v 0.000000 0.000000 0.000000\n"
- "v 2.000000 0.000000 0.000000\n"
- "v 2.000000 2.000000 0.000000\n"
- "v 4.000000 0.000000 -1.255298\n"
- "v 4.000000 2.000000 -1.255298\n"
- "vn 0.000000 0.000000 1.000000\n"
- "vn 0.000000 0.000000 1.000000\n"
- "vn 0.276597 0.000000 0.960986\n"
- "vn 0.276597 0.000000 0.960986\n"
- "vn 0.531611 0.000000 0.846988\n"
- "vn 0.531611 0.000000 0.846988\n"
- "# 6 vertices\n"
- "\n"
- "# 6 normals\n"
- "\n"
- "g all\n"
- "s 1\n"
- "f 1//1 2//2 3//3 4//4\n"
- "f 4//4 3//3 5//5 6//6\n"
- "# 2 elements\n";
-
-static const char* cube_obj =
- "# Cube with a different material applied to each of its faces\n"
- "mtllib master.mtl\n"
- "v 0.0000 2.0000 2.0000\n"
- "v 0.0000 0.0000 2.0000\n"
- "v 2.0000 0.0000 2.0000\n"
- "v 2.0000 2.0000 2.0000\n"
- "v 0.0000 2.0000 0.0000\n"
- "v 0.0000 0.0000 0.0000\n"
- "v 2.0000 0.0000 0.0000\n"
- "v 2.0000 2.0000 0.0000\n"
- "# 8 vertices\n"
- "g front\n"
- "usemtl red\n"
- "f 1 2 3 4\n"
- "g back\n"
- "usemtl blue\n"
- "f 8 7 6 5\n"
- "g right\n"
- "usemtl green\n"
- "f 4 3 7 8\n"
- "g top\n"
- "usemtl gold\n"
- "f 5 1 4 8\n"
- "g left\n"
- "usemtl orange\n"
- "f 5 6 2 1\n"
- "g bottom\n"
- "usemtl purple\n"
- "f 2 6 7 3\n"
- "# 6 elements\n";
-
-int
-main(int argc, char** argv)
+static void
+test_plane(struct obj* obj)
{
- struct mem_allocator allocator;
+ static const char* plane_obj =
+ "mtllib master.mtl"
+ "\n"
+ "v 0.0000 2.0000 0.0000\n"
+ "v 0.0000 0.0000 0.0000\n"
+ "v 2.0000 0.0000 0.0000\n"
+ "v 2.0000 2.0000 0.0000\n"
+ "vt 0.0000 1.0000 0.0000\n"
+ "vt 0.0000 0.0000 0.0000\n"
+ "vt 1.0000 0.0000 0.0000\n"
+ "vt 1.0000 1.0000 0.0000\n"
+ "# 4 vertices\n"
+ "\n"
+ "usemtl wood\n"
+ "f 1/1 2/2 3/3 4/4\n"
+ "# 1 element\n";
struct obj_desc desc;
- struct obj* obj;
+ struct obj_face face;
FILE* file;
- (void)argc, (void)argv;
+
+ NCHECK(obj, NULL);
file = fopen("test_obj_plane.obj", "w");
NCHECK(file, NULL);
fwrite(plane_obj, sizeof(char), strlen(plane_obj), file);
fclose(file);
- file = fopen("test_obj_squares.obj", "w");
- NCHECK(file, NULL);
- fwrite(squares_obj, sizeof(char), strlen(squares_obj), file);
- fclose(file);
-
- file = fopen("test_obj_cube.obj", "w");
- NCHECK(file, NULL);
- fwrite(cube_obj, sizeof(char), strlen(cube_obj), file);
- fclose(file);
-
- mem_init_proxy_allocator(&allocator, &mem_default_allocator);
-
- CHECK(obj_create(NULL, NULL), OBJ_BAD_ARGUMENT);
- CHECK(obj_create(&allocator, NULL), OBJ_BAD_ARGUMENT);
- CHECK(obj_create(NULL, &obj), OBJ_OK);
-
- CHECK(obj_ref_get(NULL), OBJ_BAD_ARGUMENT);
- CHECK(obj_ref_get(obj), OBJ_OK);
- CHECK(obj_ref_put(NULL), OBJ_BAD_ARGUMENT);
- CHECK(obj_ref_put(obj), OBJ_OK);
- CHECK(obj_ref_put(obj), OBJ_OK);
-
- CHECK(obj_create(&allocator, &obj), OBJ_OK);
-
CHECK(obj_load(NULL, NULL), OBJ_BAD_ARGUMENT);
CHECK(obj_load(obj, NULL), OBJ_BAD_ARGUMENT);
- CHECK(obj_load(NULL, "test_obj_cube.obj"), OBJ_BAD_ARGUMENT);
+ CHECK(obj_load(NULL, "test_obj_plane.obj"), OBJ_BAD_ARGUMENT);
CHECK(obj_load(obj, "none.obj"), OBJ_IO_ERROR);
CHECK(obj_load(obj, "test_obj_plane.obj"), OBJ_OK);
@@ -129,7 +48,58 @@ main(int argc, char** argv)
CHECK(desc.usemtls_count, 1);
CHECK(desc.mtllibs_count, 1);
+ CHECK(obj_face_get(NULL, SIZE_MAX, NULL), OBJ_BAD_ARGUMENT);
+ CHECK(obj_face_get(obj, SIZE_MAX, NULL), OBJ_BAD_ARGUMENT);
+ CHECK(obj_face_get(NULL, 0, NULL), OBJ_BAD_ARGUMENT);
+ CHECK(obj_face_get(obj, 0, NULL), OBJ_BAD_ARGUMENT);
+ CHECK(obj_face_get(NULL, SIZE_MAX, &face), OBJ_BAD_ARGUMENT);
+ CHECK(obj_face_get(obj, SIZE_MAX, &face), OBJ_BAD_ARGUMENT);
+ CHECK(obj_face_get(NULL, 0, &face), OBJ_BAD_ARGUMENT);
+ CHECK(obj_face_get(obj, 0, &face), OBJ_OK);
+ CHECK(face.vertex_id, 0);
+ CHECK(face.vertices_count, 4);
+ CHECK(face.group_id, OBJ_ID_NONE);
+ CHECK(face.smooth_group_id, OBJ_ID_NONE);
+ CHECK(face.mtl_id, 0);
+}
+
+static void
+test_squares(struct obj* obj)
+{
+ static const char* squares_obj =
+ "v 0.000000 2.000000 0.000000\n"
+ "v 0.000000 0.000000 0.000000\n"
+ "v 2.000000 0.000000 0.000000\n"
+ "v 2.000000 2.000000 0.000000\n"
+ "v 4.000000 0.000000 -1.255298\n"
+ "v 4.000000 2.000000 -1.255298\n"
+ "vn 0.000000 0.000000 1.000000\n"
+ "vn 0.000000 0.000000 1.000000\n"
+ "vn 0.276597 0.000000 0.960986\n"
+ "vn 0.276597 0.000000 0.960986\n"
+ "vn 0.531611 0.000000 0.846988\n"
+ "vn 0.531611 0.000000 0.846988\n"
+ "# 6 vertices\n"
+ "\n"
+ "# 6 normals\n"
+ "\n"
+ "g all\n"
+ "s 1\n"
+ "f 1//1 2//2 3//3 4//4\n"
+ "f 4//4 3//3 5//5 6//6\n"
+ "# 2 elements\n";
+ struct obj_desc desc;
+ struct obj_face face;
+ FILE* file;
+
+ NCHECK(obj, NULL);
+
+ file = fopen("test_obj_squares.obj", "w");
+ NCHECK(file, NULL);
+ fwrite(squares_obj, sizeof(char), strlen(squares_obj), file);
+ fclose(file);
CHECK(obj_load(obj, "test_obj_squares.obj"), OBJ_OK);
+
CHECK(obj_desc_get(obj, &desc), OBJ_OK);
CHECK(desc.faces_count, 2);
CHECK(desc.groups_count, 1);
@@ -137,7 +107,68 @@ main(int argc, char** argv)
CHECK(desc.usemtls_count, 0);
CHECK(desc.mtllibs_count, 0);
+ CHECK(obj_face_get(obj, 0, &face), OBJ_OK);
+ CHECK(face.vertex_id, 0);
+ CHECK(face.vertices_count, 4);
+ CHECK(face.group_id, 0);
+ CHECK(face.smooth_group_id, 0);
+ CHECK(face.mtl_id, OBJ_ID_NONE);
+
+ CHECK(obj_face_get(obj, 1, &face), OBJ_OK);
+ CHECK(face.vertex_id, 4);
+ CHECK(face.vertices_count, 4);
+ CHECK(face.group_id, 0);
+ CHECK(face.smooth_group_id, 0);
+ CHECK(face.mtl_id, OBJ_ID_NONE);
+}
+
+static void
+test_cube(struct obj* obj)
+{
+ static const char* cube_obj =
+ "# Cube with a different material applied to each of its faces\n"
+ "mtllib master.mtl\n"
+ "v 0.0000 2.0000 2.0000\n"
+ "v 0.0000 0.0000 2.0000\n"
+ "v 2.0000 0.0000 2.0000\n"
+ "v 2.0000 2.0000 2.0000\n"
+ "v 0.0000 2.0000 0.0000\n"
+ "v 0.0000 0.0000 0.0000\n"
+ "v 2.0000 0.0000 0.0000\n"
+ "v 2.0000 2.0000 0.0000\n"
+ "# 8 vertices\n"
+ "g front\n"
+ "usemtl red\n"
+ "f 1 2 3 4\n"
+ "g back\n"
+ "usemtl blue\n"
+ "f 8 7 6 5\n"
+ "g right\n"
+ "usemtl green\n"
+ "f 4 3 7 8\n"
+ "g top\n"
+ "usemtl gold\n"
+ "f 5 1 4 8\n"
+ "g left\n"
+ "usemtl orange\n"
+ "f 5 6 2 1\n"
+ "g bottom\n"
+ "usemtl purple\n"
+ "f 2 6 7 3\n"
+ "# 6 elements\n";
+ struct obj_desc desc;
+ struct obj_face face;
+ FILE* file;
+ size_t iface;
+
+ NCHECK(obj, NULL);
+
+ file = fopen("test_obj_cube.obj", "w");
+ NCHECK(file, NULL);
+ fwrite(cube_obj, sizeof(char), strlen(cube_obj), file);
+ fclose(file);
CHECK(obj_load(obj, "test_obj_cube.obj"), OBJ_OK);
+
CHECK(obj_desc_get(obj, &desc), OBJ_OK);
CHECK(desc.faces_count, 6);
CHECK(desc.groups_count, 6);
@@ -145,6 +176,41 @@ main(int argc, char** argv)
CHECK(desc.usemtls_count, 6);
CHECK(desc.mtllibs_count, 1);
+ FOR_EACH(iface, 0, 6) {
+ CHECK(obj_face_get(obj, iface, &face), OBJ_OK);
+ CHECK(face.vertex_id, iface*4);
+ CHECK(face.vertices_count, 4);
+ CHECK(face.group_id, iface);
+ CHECK(face.smooth_group_id, OBJ_ID_NONE);
+ CHECK(face.mtl_id, iface);
+ }
+}
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct obj* obj;
+ (void)argc, (void)argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(obj_create(NULL, NULL), OBJ_BAD_ARGUMENT);
+ CHECK(obj_create(&allocator, NULL), OBJ_BAD_ARGUMENT);
+ CHECK(obj_create(NULL, &obj), OBJ_OK);
+
+ CHECK(obj_ref_get(NULL), OBJ_BAD_ARGUMENT);
+ CHECK(obj_ref_get(obj), OBJ_OK);
+ CHECK(obj_ref_put(NULL), OBJ_BAD_ARGUMENT);
+ CHECK(obj_ref_put(obj), OBJ_OK);
+ CHECK(obj_ref_put(obj), OBJ_OK);
+
+ CHECK(obj_create(&allocator, &obj), OBJ_OK);
+
+ test_plane(obj);
+ test_squares(obj);
+ test_cube(obj);
+
CHECK(obj_ref_put(obj), OBJ_OK);
if(MEM_ALLOCATED_SIZE(&allocator)) {