diff --git a/xs/src/admesh/stl.h b/xs/src/admesh/stl.h index 82c860636..dc0f7ae19 100644 --- a/xs/src/admesh/stl.h +++ b/xs/src/admesh/stl.h @@ -26,11 +26,6 @@ #include #include #include -#include - -#ifndef BOOST_LITTLE_ENDIAN -#error "admesh works correctly on little endian machines only!" -#endif #define STL_MAX(A,B) ((A)>(B)? (A):(B)) #define STL_MIN(A,B) ((A)<(B)? (A):(B)) @@ -112,7 +107,7 @@ typedef struct { typedef struct { char header[81]; stl_type type; - int number_of_facets; + uint32_t number_of_facets; stl_vertex max; stl_vertex min; stl_vertex size; diff --git a/xs/src/admesh/stl_io.cpp b/xs/src/admesh/stl_io.cpp index e223c0097..1603981fc 100644 --- a/xs/src/admesh/stl_io.cpp +++ b/xs/src/admesh/stl_io.cpp @@ -23,9 +23,9 @@ #include #include #include "stl.h" -//#include "config.h" #include +#include #if !defined(SEEK_SET) #define SEEK_SET 0 @@ -204,6 +204,17 @@ stl_print_neighbors(stl_file *stl, char *file) { fclose(fp); } +#ifndef BOOST_LITTLE_ENDIAN +// Swap a buffer of 32bit data from little endian to big endian and vice versa. +void stl_internal_reverse_quads(char *buf, size_t cnt) +{ + for (size_t i = 0; i < cnt; i += 4) { + std::swap(buf[i], buf[i+3]); + std::swap(buf[i+1], buf[i+2]); + } +} +#endif + void stl_write_binary(stl_file *stl, const char *file, const char *label) { FILE *fp; @@ -229,9 +240,23 @@ 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); +#ifdef BOOST_LITTLE_ENDIAN fwrite(&stl->stats.number_of_facets, 4, 1, fp); - for(i = 0; i < stl->stats.number_of_facets; i++) + for (i = 0; i < stl->stats.number_of_facets; ++ i) fwrite(stl->facet_start + i, SIZEOF_STL_FACET, 1, fp); +#else /* BOOST_LITTLE_ENDIAN */ + char buffer[50]; + // Convert the number of facets to little endian. + memcpy(buffer, &stl->stats.number_of_facets, 4); + stl_internal_reverse_quads(buffer, 4); + fwrite(buffer, 4, 1, fp); + for (i = 0; i < stl->stats.number_of_facets; ++ i) { + memcpy(buffer, stl->facet_start + i, 50); + // Convert to little endian. + stl_internal_reverse_quads(buffer, 48); + fwrite(buffer, SIZEOF_STL_FACET, 1, fp); + } +#endif /* BOOST_LITTLE_ENDIAN */ fclose(fp); } diff --git a/xs/src/admesh/stlinit.cpp b/xs/src/admesh/stlinit.cpp index f5110d394..84fc8d2c1 100644 --- a/xs/src/admesh/stlinit.cpp +++ b/xs/src/admesh/stlinit.cpp @@ -27,6 +27,7 @@ #include #include +#include #include "stl.h" @@ -50,11 +51,15 @@ stl_initialize(stl_file *stl) { stl->stats.volume = -1.0; } +#ifndef BOOST_LITTLE_ENDIAN +extern void stl_internal_reverse_quads(char *buf, size_t cnt); +#endif /* BOOST_LITTLE_ENDIAN */ + void stl_count_facets(stl_file *stl, const char *file) { long file_size; int header_num_facets; - int num_facets; + uint32_t num_facets; int i; size_t s; unsigned char chtest[128]; @@ -113,7 +118,12 @@ stl_count_facets(stl_file *stl, const char *file) { } /* Read the int following the header. This should contain # of facets */ - if((!fread(&header_num_facets, sizeof(int), 1, stl->fp)) || (num_facets != header_num_facets)) { + bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, stl->fp); +#ifndef BOOST_LITTLE_ENDIAN + // Convert from little endian to big endian. + stl_internal_reverse_quads((char*)&header_num_facets, 4); +#endif /* BOOST_LITTLE_ENDIAN */ + if (! header_num_faces_read || num_facets != header_num_facets) { fprintf(stderr, "Warning: File size doesn't match number of facets in the header\n"); } @@ -268,6 +278,10 @@ stl_read(stl_file *stl, int first_facet, int first) { stl->error = 1; return; } +#ifndef BOOST_LITTLE_ENDIAN + // Convert the loaded little endian data to big endian. + stl_internal_reverse_quads((char*)&facet, 48); +#endif /* BOOST_LITTLE_ENDIAN */ } else /* Read a single facet from an ASCII .STL file */ {