/* See {stl.h} */ /* Last edited on 2021-08-13 15:46:42 by stolfi */ /* From Y. Matsuzake's {cviewer.c} */ #include #include #include #include #include static void stl_write_impl_binary(stl_format_t const* stl, FILE* out) { } static void stl_write_impl_ascii(stl_format_t const* stl, FILE* out) { } void stl_create(stl_format_t* stl, uint32_t triangle_count) { stl->triangles = dyna_create(stl_triangle_t, triangle_count); } void stl_destroy(stl_format_t const* stl) { dyna_destroy(stl->triangles); } void stl_write(stl_format_t const* stl, FILE* out, int binary) { if(binary > 0) stl_write_impl_binary(stl, out); else stl_write_impl_ascii(stl, out); } static void stl_read_binary_after_header(stl_format_t* stl, FILE* in) { uint32_t triangle_count; // read triangle count if(!read_ok(&triangle_count, sizeof(uint32_t), 1, in)) return; stl_create(stl, triangle_count); if(stl->triangles == NULL){ log_err("could not alloc %d triangles\n", triangle_count); return; } for (int32_t i=0; itriangles = dyna_add(stl->triangles, &t); uint16_t dumb_attr_byte; if(!read_ok(&dumb_attr_byte, sizeof(uint16_t), 1, in)){ log_err("could not read dumb attr byte value\n"); return; } } } static int read_triangle(FILE* in, char** line, size_t* line_sz, stl_triangle_t* v) { size_t n_read = 0; typedef enum{ FACET, NORMAL, OUTER_LOOP, VERTEX, END_LOOP = VERTEX + 3, END_FACET, VERTEX_READ }stage_t; stage_t s = FACET; size_t vidx = 0; while(s != VERTEX_READ && (n_read = getline(line, line_sz, in) > 0)){ if(s == FACET){ if(strstr(*line, "facet") != NULL) s++; }else if(s == NORMAL){ int n = sscanf( *line, " normal %f %f %f", &v->normal[0], &v->normal[1], &v->normal[2] ); if(n == 3) s++; }else if(s == OUTER_LOOP){ if(strstr(*line, "outer loop") != NULL) s++; }else if(s >= VERTEX && s < END_LOOP){ int n = sscanf( *line, " vertex %f %f %f", &v->vertex[vidx][0], &v->vertex[vidx][1], &v->vertex[vidx][2] ); if(n == 3){ s++; vidx++; } }else if(s == END_LOOP){ if(strstr(*line, "endloop") != NULL) s++; }else if(s == END_FACET){ if(strstr(*line, "endfacet") != NULL) s++; } } return s == VERTEX_READ; } static void stl_read_ascii_after_solid(stl_format_t* stl, FILE* in) { stl_triangle_t t; stl_create(stl, 0); char* line = NULL; size_t n = 0; while(read_triangle(in, &line, &n, &t)) stl->triangles = dyna_add(stl->triangles, &t); free(line); } void stl_read(stl_format_t* stl, FILE* in) { char solid[5]; size_t solid_siz = sizeof(solid) / sizeof(char); size_t n = fread(solid, sizeof(char), solid_siz, in); if(n != solid_siz){ log_err("file is too short"); return; } if(memcmp(solid, "solid", solid_siz) != 0){ char header[80]; size_t header_siz = sizeof(header) / sizeof(char); memcpy(header, solid, solid_siz); if(!read_ok(header + solid_siz, sizeof(char), header_siz - solid_siz, in)){ log_err("could not read the header\n"); return; } stl_read_binary_after_header(stl, in); }else{ stl_read_ascii_after_solid(stl, in); } }