admesh: Fixed a problem in loading an STL when compiled with

Visual Studio 2013. Added multiple compile time checks for data
sizes and alignment. The library STL import is not big endian safe, so
added a test for endianity, modified STL export to a faster little endian only.
This commit is contained in:
bubnikv 2016-11-17 16:57:58 +01:00
parent 9772584d78
commit 2085a482c7
3 changed files with 24 additions and 72 deletions

View file

@ -25,6 +25,12 @@
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <boost/predef/detail/endian_compat.h>
#ifndef BOOST_LITTLE_ENDIAN
#error "admesh works correctly on little endian machines only!"
#endif
#ifdef __cplusplus
extern "C" {
@ -51,12 +57,16 @@ typedef struct {
float z;
} stl_vertex;
static_assert(sizeof(stl_vertex) == 12, "size of stl_vertex incorrect");
typedef struct {
float x;
float y;
float z;
} stl_normal;
static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect");
typedef char stl_extra[2];
typedef struct {
@ -66,6 +76,11 @@ typedef struct {
} stl_facet;
#define SIZEOF_STL_FACET 50
static_assert(offsetof(stl_facet, normal) == 0, "stl_facet.normal has correct offset");
static_assert(offsetof(stl_facet, vertex) == 12, "stl_facet.vertex has correct offset");
static_assert(offsetof(stl_facet, extra ) == 48, "stl_facet.extra has correct offset");
static_assert(sizeof(stl_facet) >= SIZEOF_STL_FACET, "size of stl_facet incorrect");
typedef enum {binary, ascii, inmemory} stl_type;
typedef struct {
@ -85,6 +100,8 @@ typedef struct stl_hash_edge {
struct stl_hash_edge *next;
} stl_hash_edge;
static_assert(offsetof(stl_hash_edge, facet_number) == SIZEOF_EDGE_SORT, "size of stl_hash_edge.key incorrect");
typedef struct {
// Index of a neighbor facet.
int neighbor[3];

View file

@ -203,63 +203,6 @@ stl_print_neighbors(stl_file *stl, char *file) {
fclose(fp);
}
void
stl_put_little_int(FILE *fp, int value_in) {
int new_value;
union {
int int_value;
char char_value[4];
} value;
value.int_value = value_in;
new_value = value.char_value[0] & 0xFF;
new_value |= (value.char_value[1] & 0xFF) << 0x08;
new_value |= (value.char_value[2] & 0xFF) << 0x10;
new_value |= (value.char_value[3] & 0xFF) << 0x18;
fwrite(&new_value, sizeof(int), 1, fp);
}
void
stl_put_little_float(FILE *fp, float value_in) {
int new_value;
union {
float float_value;
char char_value[4];
} value;
value.float_value = value_in;
new_value = value.char_value[0] & 0xFF;
new_value |= (value.char_value[1] & 0xFF) << 0x08;
new_value |= (value.char_value[2] & 0xFF) << 0x10;
new_value |= (value.char_value[3] & 0xFF) << 0x18;
fwrite(&new_value, sizeof(int), 1, fp);
}
void
stl_write_binary_block(stl_file *stl, FILE *fp)
{
int i;
for(i = 0; i < stl->stats.number_of_facets; i++)
{
stl_put_little_float(fp, stl->facet_start[i].normal.x);
stl_put_little_float(fp, stl->facet_start[i].normal.y);
stl_put_little_float(fp, stl->facet_start[i].normal.z);
stl_put_little_float(fp, stl->facet_start[i].vertex[0].x);
stl_put_little_float(fp, stl->facet_start[i].vertex[0].y);
stl_put_little_float(fp, stl->facet_start[i].vertex[0].z);
stl_put_little_float(fp, stl->facet_start[i].vertex[1].x);
stl_put_little_float(fp, stl->facet_start[i].vertex[1].y);
stl_put_little_float(fp, stl->facet_start[i].vertex[1].z);
stl_put_little_float(fp, stl->facet_start[i].vertex[2].x);
stl_put_little_float(fp, stl->facet_start[i].vertex[2].y);
stl_put_little_float(fp, stl->facet_start[i].vertex[2].z);
fputc(stl->facet_start[i].extra[0], fp);
fputc(stl->facet_start[i].extra[1], fp);
}
}
void
stl_write_binary(stl_file *stl, const char *file, const char *label) {
FILE *fp;
@ -285,11 +228,9 @@ stl_write_binary(stl_file *stl, const char *file, const char *label) {
for(i = strlen(label); i < LABEL_SIZE; i++) putc(0, fp);
fseek(fp, LABEL_SIZE, SEEK_SET);
stl_put_little_int(fp, stl->stats.number_of_facets);
stl_write_binary_block(stl, fp);
fwrite(&stl->stats.number_of_facets, 4, 1, fp);
for(i = 0; i < stl->stats.number_of_facets; i++)
fwrite(stl->facet_start + i, SIZEOF_STL_FACET, 1, fp);
fclose(fp);
}

View file

@ -27,10 +27,8 @@
#include "stl.h"
#if !defined(SEEK_SET)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#ifndef SEEK_SET
#error "SEEK_SET not defined"
#endif
void
@ -277,10 +275,7 @@ stl_read(stl_file *stl, int first_facet, int first) {
/* Read a single facet from a binary .STL file */
{
/* we assume little-endian architecture! */
if (fread(&facet.normal, sizeof(stl_normal), 1, stl->fp) \
+ fread(&facet.vertex, sizeof(stl_vertex), 3, stl->fp) \
+ fread(&facet.extra, sizeof(char), 2, stl->fp) != 6) {
perror("Cannot read facet");
if (fread(&facet, 1, SIZEOF_STL_FACET, stl->fp) != SIZEOF_STL_FACET) {
stl->error = 1;
return;
}
@ -343,8 +338,7 @@ stl_read(stl_file *stl, int first_facet, int first) {
}
#endif
/* Write the facet into memory. */
stl->facet_start[i] = facet;
memcpy(stl->facet_start+i, &facet, SIZEOF_STL_FACET);
stl_facet_stats(stl, facet, first);
first = 0;
}