285 lines
9.2 KiB
C
285 lines
9.2 KiB
C
#include <exceptions.h>
|
|
#include <group.h>
|
|
#include <string.h>
|
|
#include <triangle.h>
|
|
#include <tuples.h>
|
|
#include <unity.h>
|
|
|
|
#include "wavefrontobj.h"
|
|
|
|
#include "../testutils.h"
|
|
|
|
void setUp(void) {}
|
|
void tearDown(void) {}
|
|
|
|
CEXCEPTION_T exception;
|
|
|
|
static WAVEFRONTOBJ_Obj *obj_from_string(char *str) {
|
|
TEST_ASSERT_NOT_NULL(str);
|
|
FILE *stream = fmemopen(str, strlen(str), "r");
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(stream, "fmemopen failed");
|
|
WAVEFRONTOBJ_Obj *obj = WAVEFRONTOBJ_parse_obj_stream(stream);
|
|
fclose(stream);
|
|
TEST_ASSERT_NOT_NULL(obj);
|
|
return obj;
|
|
}
|
|
|
|
void test_ignore_unrecognized_lines(void) {
|
|
char *gibberish = "Test line 1\n"
|
|
"Test line 2\n"
|
|
"Another test line\n";
|
|
WAVEFRONTOBJ_Obj *obj = obj_from_string(gibberish);
|
|
TEST_ASSERT_EQUAL(3, obj->ignored_lines);
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
|
|
void check_point(TUPLES_Point *p, double x, double y, double z) {
|
|
TEST_ASSERT_NOT_NULL(p);
|
|
TEST_ASSERT_TRUE(TUPLES_is_point(p));
|
|
TEST_ASSERT_EQUAL_DOUBLE(x, p->x);
|
|
TEST_ASSERT_EQUAL_DOUBLE(y, p->y);
|
|
TEST_ASSERT_EQUAL_DOUBLE(z, p->z);
|
|
}
|
|
|
|
void check_vector(TUPLES_Vector *v, double x, double y, double z) {
|
|
TEST_ASSERT_NOT_NULL(v);
|
|
TEST_ASSERT_TRUE(TUPLES_is_vector(v));
|
|
TEST_ASSERT_EQUAL_DOUBLE(x, v->x);
|
|
TEST_ASSERT_EQUAL_DOUBLE(y, v->y);
|
|
TEST_ASSERT_EQUAL_DOUBLE(z, v->z);
|
|
}
|
|
|
|
void test_parse_vertex(void) {
|
|
char *vertexes = "\n"
|
|
"v -1 1 0\n"
|
|
"v -1.0000 0.5000 0.0000\n"
|
|
"v 1 0 0\n"
|
|
"v 1 1 0\n"
|
|
"\n";
|
|
WAVEFRONTOBJ_Obj *obj = obj_from_string(vertexes);
|
|
Try {
|
|
check_point(WAVEFRONTOBJ_get_vertex(obj, 1), -1, 1, 0);
|
|
check_point(WAVEFRONTOBJ_get_vertex(obj, 2), -1, 0.5, 0);
|
|
check_point(WAVEFRONTOBJ_get_vertex(obj, 3), 1, 0, 0);
|
|
check_point(WAVEFRONTOBJ_get_vertex(obj, 4), 1, 1, 0);
|
|
}
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
|
|
void test_wavefrontobj_normalize(void) {
|
|
char *data = "\n"
|
|
"v -10 10 0\n"
|
|
"v -10 0 0\n"
|
|
"v 10 0 0\n"
|
|
"v 10 10 0\n"
|
|
"\n"
|
|
"f 1 2 3\n"
|
|
"f 1 3 4\n"
|
|
"\n";
|
|
|
|
Try {
|
|
WAVEFRONTOBJ_Obj *obj = obj_from_string(data);
|
|
WAVEFRONTOBJ_normalize(obj);
|
|
BOUND_Box box;
|
|
SHAPE_parent_space_bounds_of(&box, (SHAPE_Shape *)WAVEFRONTOBJ_get_default_group(obj));
|
|
TEST_ASSERT_LESS_OR_EQUAL(1.0, box.max.x);
|
|
TEST_ASSERT_LESS_OR_EQUAL(1.0, box.max.y);
|
|
TEST_ASSERT_LESS_OR_EQUAL(1.0, box.max.z);
|
|
TEST_ASSERT_GREATER_OR_EQUAL(-1.0, box.min.x);
|
|
TEST_ASSERT_GREATER_OR_EQUAL(-1.0, box.min.y);
|
|
TEST_ASSERT_GREATER_OR_EQUAL(-1.0, box.min.z);
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
}
|
|
|
|
void test_parse_triangle_face(void) {
|
|
char *data = "\n"
|
|
"v -1 1 0\n"
|
|
"v -1 0 0\n"
|
|
"v 1 0 0\n"
|
|
"v 1 1 0\n"
|
|
"\n"
|
|
"f 1 2 3\n"
|
|
"f 1 3 4\n"
|
|
"\n";
|
|
|
|
Try {
|
|
WAVEFRONTOBJ_Obj *obj = obj_from_string(data);
|
|
GROUP_Group *g = WAVEFRONTOBJ_get_default_group(obj);
|
|
TRIANGLE_Triangle *t1 = (TRIANGLE_Triangle *)GROUP_get_child(g, 0);
|
|
TRIANGLE_Triangle *t2 = (TRIANGLE_Triangle *)GROUP_get_child(g, 1);
|
|
test_tuples(&t1->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t1->p2, WAVEFRONTOBJ_get_vertex(obj, 2));
|
|
test_tuples(&t1->p3, WAVEFRONTOBJ_get_vertex(obj, 3));
|
|
test_tuples(&t2->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t2->p2, WAVEFRONTOBJ_get_vertex(obj, 3));
|
|
test_tuples(&t2->p3, WAVEFRONTOBJ_get_vertex(obj, 4));
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
}
|
|
|
|
void test_triangulating_polygons(void) {
|
|
char *data = "\n"
|
|
"v -1 1 0\n"
|
|
"v -1 0 0\n"
|
|
"v 1 0 0\n"
|
|
"v 1 1 0\n"
|
|
"v 0 2 0\n"
|
|
"\n"
|
|
"f 1 2 3 4 5\n"
|
|
"\n";
|
|
Try {
|
|
WAVEFRONTOBJ_Obj *obj = obj_from_string(data);
|
|
GROUP_Group *g = WAVEFRONTOBJ_get_default_group(obj);
|
|
TRIANGLE_Triangle *t1 = (TRIANGLE_Triangle *)GROUP_get_child(g, 0);
|
|
TRIANGLE_Triangle *t2 = (TRIANGLE_Triangle *)GROUP_get_child(g, 1);
|
|
TRIANGLE_Triangle *t3 = (TRIANGLE_Triangle *)GROUP_get_child(g, 2);
|
|
test_tuples(&t1->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t1->p2, WAVEFRONTOBJ_get_vertex(obj, 2));
|
|
test_tuples(&t1->p3, WAVEFRONTOBJ_get_vertex(obj, 3));
|
|
test_tuples(&t2->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t2->p2, WAVEFRONTOBJ_get_vertex(obj, 3));
|
|
test_tuples(&t2->p3, WAVEFRONTOBJ_get_vertex(obj, 4));
|
|
test_tuples(&t3->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t3->p2, WAVEFRONTOBJ_get_vertex(obj, 4));
|
|
test_tuples(&t3->p3, WAVEFRONTOBJ_get_vertex(obj, 5));
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
}
|
|
|
|
void test_parse_from_file(void) {
|
|
WAVEFRONTOBJ_Obj *volatile obj = NULL;
|
|
Try { obj = WAVEFRONTOBJ_parse_file_by_name("triangles.obj"); }
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
|
|
void test_triangles_in_groups(void) {
|
|
WAVEFRONTOBJ_Obj *volatile obj;
|
|
Try {
|
|
obj = WAVEFRONTOBJ_parse_file_by_name("triangles.obj");
|
|
GROUP_Group *def_group = WAVEFRONTOBJ_get_default_group(obj);
|
|
GROUP_Group *g1 = GROUP_get_child(def_group, 0);
|
|
GROUP_Group *g2 = GROUP_get_child(def_group, 1);
|
|
TRIANGLE_Triangle *t1 = GROUP_get_child(g1, 0);
|
|
TRIANGLE_Triangle *t2 = GROUP_get_child(g2, 0);
|
|
test_tuples(&t1->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t1->p2, WAVEFRONTOBJ_get_vertex(obj, 2));
|
|
test_tuples(&t1->p3, WAVEFRONTOBJ_get_vertex(obj, 3));
|
|
test_tuples(&t2->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t2->p2, WAVEFRONTOBJ_get_vertex(obj, 3));
|
|
test_tuples(&t2->p3, WAVEFRONTOBJ_get_vertex(obj, 4));
|
|
}
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
|
|
void test_parse_many_poly_teapot(void) {
|
|
WAVEFRONTOBJ_Obj *volatile obj;
|
|
Try {
|
|
obj = WAVEFRONTOBJ_parse_file_by_name("teapot.obj");
|
|
TEST_ASSERT_EQUAL(2256, obj->face_count);
|
|
}
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
|
|
void test_vertex_normal_records(void) {
|
|
char *data = "\n"
|
|
"vn 0 0 1\n"
|
|
"vn 0.707 0 -0.707\n"
|
|
"vn 1 2 3\n"
|
|
"\n";
|
|
|
|
Try {
|
|
WAVEFRONTOBJ_Obj *obj = obj_from_string(data);
|
|
check_vector(WAVEFRONTOBJ_get_normal(obj, 1), 0, 0, 1);
|
|
check_vector(WAVEFRONTOBJ_get_normal(obj, 2), 0.707, 0, -0.707);
|
|
check_vector(WAVEFRONTOBJ_get_normal(obj, 3), 1, 2, 3);
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
}
|
|
|
|
void test_faces_with_normals(void) {
|
|
char *data = "\n"
|
|
"v 0 1 0\n"
|
|
"v -1 0 0\n"
|
|
"v 1 0 0\n"
|
|
"\n"
|
|
"vn -1 0 0\n"
|
|
"vn 1 0 0\n"
|
|
"vn 0 1 0\n"
|
|
"\n"
|
|
"f 1//3 2//1 3//2\n"
|
|
"f 1/0/3 2/102/1 3/14/2\n"
|
|
"\n";
|
|
|
|
Try {
|
|
WAVEFRONTOBJ_Obj *obj = obj_from_string(data);
|
|
GROUP_Group *g = WAVEFRONTOBJ_get_default_group(obj);
|
|
TRIANGLE_SmoothTriangle *t1 = (TRIANGLE_SmoothTriangle *)GROUP_get_child(g, 0);
|
|
TRIANGLE_SmoothTriangle *t2 = (TRIANGLE_SmoothTriangle *)GROUP_get_child(g, 1);
|
|
test_tuples(&t1->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t1->p2, WAVEFRONTOBJ_get_vertex(obj, 2));
|
|
test_tuples(&t1->p3, WAVEFRONTOBJ_get_vertex(obj, 3));
|
|
test_tuples(&t1->n1, WAVEFRONTOBJ_get_normal(obj, 3));
|
|
test_tuples(&t1->n2, WAVEFRONTOBJ_get_normal(obj, 1));
|
|
test_tuples(&t1->n3, WAVEFRONTOBJ_get_normal(obj, 2));
|
|
test_tuples(&t2->p1, WAVEFRONTOBJ_get_vertex(obj, 1));
|
|
test_tuples(&t2->p2, WAVEFRONTOBJ_get_vertex(obj, 2));
|
|
test_tuples(&t2->p3, WAVEFRONTOBJ_get_vertex(obj, 3));
|
|
test_tuples(&t2->n1, WAVEFRONTOBJ_get_normal(obj, 3));
|
|
test_tuples(&t2->n2, WAVEFRONTOBJ_get_normal(obj, 1));
|
|
test_tuples(&t2->n3, WAVEFRONTOBJ_get_normal(obj, 2));
|
|
WAVEFRONTOBJ_delete(obj);
|
|
}
|
|
Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
}
|
|
|
|
int main(void) {
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_ignore_unrecognized_lines);
|
|
RUN_TEST(test_parse_vertex);
|
|
RUN_TEST(test_parse_triangle_face);
|
|
RUN_TEST(test_triangulating_polygons);
|
|
RUN_TEST(test_parse_from_file);
|
|
RUN_TEST(test_triangles_in_groups);
|
|
RUN_TEST(test_parse_many_poly_teapot);
|
|
RUN_TEST(test_vertex_normal_records);
|
|
RUN_TEST(test_faces_with_normals);
|
|
RUN_TEST(test_wavefrontobj_normalize);
|
|
UNITY_END();
|
|
}
|