star-stl

Load STereo Lithography (StL) file format
git clone git://git.meso-star.fr/star-stl.git
Log | Files | Refs | README | LICENSE

commit 6a2254ad0fc93a79e3c8ee4ff48d416203aad0be
parent 408de0cef4631a5e209dfb2025b598ecec890312
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  6 Jan 2016 16:46:10 +0100

Add and test the sstl_get_desc function

Diffstat:
Msrc/sstl.c | 29+++++++++++++++++++++++------
Msrc/sstl.h | 18++++++++++++++++++
Msrc/test_sstl_load.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 98 insertions(+), 8 deletions(-)

diff --git a/src/sstl.c b/src/sstl.c @@ -38,7 +38,7 @@ struct solid { char* name; - size_t* indices; + unsigned* indices; float* vertices; float* normals; }; @@ -61,7 +61,7 @@ eq_vertex(const struct vertex* a, const struct vertex* b) /* Declare the hash table that map a vertex to its index */ #define HTABLE_NAME vertex -#define HTABLE_DATA size_t +#define HTABLE_DATA unsigned #define HTABLE_KEY struct vertex #define HTABLE_KEY_FUNCTOR_EQ eq_vertex #include <rsys/hash_table.h> @@ -250,13 +250,13 @@ static INLINE res_T parse_solid_vertex (struct sstl* sstl, struct solid* solid, - size_t* const index, + unsigned* const index, char* line, const char* filename, const size_t iline) { struct vertex vertex; - size_t* found_id; + unsigned* found_id; res_T res = RES_OK; ASSERT(sstl && solid && index); @@ -277,7 +277,7 @@ parse_solid_vertex *index = *found_id; } else { /* Add a new vertex */ - *index = sa_size(solid->indices); + *index = (unsigned)sa_size(solid->indices); res = htable_vertex_set(&sstl->vertex2id, &vertex, index); if(res != RES_OK) { print_log(sstl, LOG_ERROR, @@ -368,7 +368,7 @@ load_stream(struct sstl* sstl, FILE* stream, const char* stream_name) for(;;) { /* Parse the solid facets */ float normal[3]; - size_t facet[3]; + unsigned facet[3]; int ivertex; line = streamer_read_line(&streamer); @@ -561,3 +561,20 @@ sstl_load_stream(struct sstl* sstl, FILE* stream) return load_stream(sstl, stream, "STREAM"); } +res_T +sstl_get_desc(const struct sstl* sstl, struct sstl_desc* desc) +{ + if(!sstl || !desc) return RES_BAD_ARG; + desc->solid_name = sstl->solid.name; + desc->vertices_count = sa_size(sstl->solid.vertices); + ASSERT(desc->triangles_count % 3 == 0); + desc->vertices_count /= 3/* # coords per vertex */; + desc->triangles_count = sa_size(sstl->solid.indices); + ASSERT(desc->triangles_count % 3 == 0); + desc->triangles_count /= 3/* # indices per triange */; + desc->vertices = sstl->solid.vertices; + desc->indices = sstl->solid.indices; + desc->normals = sstl->solid.normals; + return RES_OK; +} + diff --git a/src/sstl.h b/src/sstl.h @@ -49,6 +49,18 @@ #define SSTL(Func) sstl_ ## Func #endif +/* Descriptor of a loaded STL */ +struct sstl_desc { + const char* solid_name; /* May be NULL <=> no name */ + + const float* vertices; /* triangles_count * 3 coordinates */ + const unsigned* indices; /* triangles_count * 3 indices */ + const float* normals; /* Per triangle normal */ + + size_t triangles_count; + size_t vertices_count; +}; + /* Forward declaration of external types */ struct logger; struct mem_allocator; @@ -86,6 +98,12 @@ sstl_load_stream (struct sstl* sstl, FILE* stream); +/* The returned descriptor is valid until a new load process */ +SSTL_API res_T +sstl_get_desc + (const struct sstl* sstl, + struct sstl_desc* desc); + END_DECLS #endif /* SSTL_H */ diff --git a/src/test_sstl_load.c b/src/test_sstl_load.c @@ -29,6 +29,7 @@ #include "sstl.h" #include "test_sstl_utils.h" +#include <rsys/float3.h> #include <rsys/logger.h> static void @@ -58,7 +59,16 @@ test_basic(struct sstl* sstl) static const char* test2 = "solid my_solid\n" "endsolid my_solid\n"; - + static const char* test3 = + "solid\n" + " facet normal 0.0 0.0 0.0\n" + " outer loop\n" + " vertex 0.0 0.0 0.0\n" + " vertex 1.0 0.0 0.0\n" + " vertex 0.0 0.0 1.0\n" + " endloop\n" + " endfacet\n" + "endsolid"; static const char* bad[] = { "solid\n" " facet normal 0.0 -1.0 0.0\n" @@ -126,7 +136,8 @@ test_basic(struct sstl* sstl) "endsolid\n" }; const size_t nbads = sizeof(bad)/sizeof(const char*); - + float tmp[3]; + struct sstl_desc desc; FILE* file; size_t i; @@ -143,6 +154,22 @@ test_basic(struct sstl* sstl) CHECK(sstl_load(sstl, "none.stl"), RES_IO_ERR); CHECK(sstl_load(sstl, "test_basic.stl"), RES_OK); + CHECK(sstl_get_desc(NULL, NULL), RES_BAD_ARG); + CHECK(sstl_get_desc(sstl, NULL), RES_BAD_ARG); + CHECK(sstl_get_desc(NULL, &desc), RES_BAD_ARG); + CHECK(sstl_get_desc(sstl, &desc), RES_OK); + + CHECK(desc.solid_name, NULL); + CHECK(desc.vertices_count, 3); + CHECK(desc.triangles_count, 1); + CHECK(desc.indices[0], 0); + CHECK(desc.indices[1], 1); + CHECK(desc.indices[2], 2); + CHECK(f3_eq(desc.vertices + 0*3, f3(tmp, 0.f, 0.f, 0.f)), 1); + CHECK(f3_eq(desc.vertices + 1*3, f3(tmp, 1.f, 0.f, 0.f)), 1); + CHECK(f3_eq(desc.vertices + 2*3, f3(tmp, 0.f, 0.f, 1.f)), 1); + CHECK(f3_eq(desc.normals, f3(tmp, 0.f, -1.f, 0.f)), 1); + file = tmpfile(); NCHECK(file, NULL); fwrite(test1, sizeof(char), strlen(test1), file); @@ -153,12 +180,40 @@ test_basic(struct sstl* sstl) CHECK(sstl_load_stream(sstl, file), RES_OK); fclose(file); + CHECK(sstl_get_desc(sstl, &desc), RES_OK); + CHECK(strcmp(desc.solid_name, "my_solid"), 0); + CHECK(desc.vertices_count, 3); + CHECK(desc.triangles_count, 1); + CHECK(desc.indices[0], 0); + CHECK(desc.indices[1], 1); + CHECK(desc.indices[2], 2); + CHECK(f3_eq(desc.vertices + 0*3, f3(tmp, 0.f, 0.f, 0.f)), 1); + CHECK(f3_eq(desc.vertices + 1*3, f3(tmp, 1.f, 0.f, 0.f)), 1); + CHECK(f3_eq(desc.vertices + 2*3, f3(tmp, 0.f, 0.f, 1.f)), 1); + CHECK(f3_eq(desc.normals, f3(tmp, 0.f, -1.f, 0.f)), 1); + file = tmpfile(); fwrite(test2, sizeof(char), strlen(test2), file); rewind(file); CHECK(sstl_load_stream(sstl, file), RES_OK); fclose(file); + CHECK(sstl_get_desc(sstl, &desc), RES_OK); + CHECK(strcmp(desc.solid_name, "my_solid"), 0); + CHECK(desc.vertices_count, 0); + CHECK(desc.triangles_count, 0); + + file = tmpfile(); + fwrite(test3, sizeof(char), strlen(test3), file); + rewind(file); + CHECK(sstl_load_stream(sstl, file), RES_OK); + fclose(file); + + CHECK(sstl_get_desc(sstl, &desc), RES_OK); + CHECK(desc.vertices_count, 3); + CHECK(desc.triangles_count, 1); + CHECK(f3_eq(desc.normals, f3(tmp, 0.f, -1.f, 0.f)), 1); + FOR_EACH(i, 0, nbads) { file = tmpfile(); fwrite(bad[i], sizeof(char), strlen(bad[i]), file);