diff --git a/src/gmio_stl/internal/stla_write.c b/src/gmio_stl/internal/stla_write.c index 6c7d552..974e85f 100644 --- a/src/gmio_stl/internal/stla_write.c +++ b/src/gmio_stl/internal/stla_write.c @@ -129,10 +129,7 @@ static gmio_bool_t gmio_transfer_flush_buffer(gmio_transfer_t* trsf, size_t n) int gmio_stla_write( gmio_transfer_t* trsf, const gmio_stl_mesh_t* mesh, - /* Options */ - const char* solid_name, - gmio_float_text_format_t float32_format, - uint8_t float32_prec) + const gmio_stl_write_options_t *options) { /* Constants */ const uint32_t total_facet_count = mesh != NULL ? mesh->triangle_count : 0; @@ -140,6 +137,16 @@ int gmio_stla_write( trsf != NULL ? gmio_size_to_uint32(trsf->buffer.size / GMIO_STLA_FACET_SIZE_P2) : 0; + const char* solid_name = + options != NULL ? options->stla_solid_name : NULL; + const gmio_float_text_format_t float32_format = + options != NULL ? + options->stla_float32_format : + GMIO_FLOAT_TEXT_FORMAT_DECIMAL_LOWERCASE; + const uint8_t float32_prec = + options != NULL ? options->stla_float32_prec : 9; + const gmio_bool_t write_triangles_only = + options != NULL ? options->stl_write_triangles_only : GMIO_FALSE; /* Variables */ uint32_t ifacet = 0; void* buffer_ptr = trsf != NULL ? trsf->buffer.ptr : NULL; @@ -171,7 +178,7 @@ int gmio_stla_write( } /* Write solid declaration */ - { + if (!write_triangles_only) { buffc = gmio_write_string(buffc, "solid "); buffc = gmio_write_string_eol(buffc, solid_name); if (!gmio_transfer_flush_buffer(trsf, buffc - (char*)buffer_ptr)) @@ -225,7 +232,7 @@ int gmio_stla_write( } /* end for (ifacet) */ /* Write end of solid */ - if (gmio_no_error(error)) { + if (gmio_no_error(error) && !write_triangles_only) { buffc = gmio_write_string(trsf->buffer.ptr, "endsolid "); buffc = gmio_write_string_eol(buffc, solid_name); if (!gmio_transfer_flush_buffer(trsf, buffc - (char*)buffer_ptr)) diff --git a/src/gmio_stl/internal/stla_write.h b/src/gmio_stl/internal/stla_write.h index 1c23340..c9e7cd3 100644 --- a/src/gmio_stl/internal/stla_write.h +++ b/src/gmio_stl/internal/stla_write.h @@ -17,6 +17,7 @@ #define GMIO_INTERNAL_STLA_WRITE_H #include "../stl_mesh.h" +#include "../stl_io_options.h" #include "../../gmio_core/text_format.h" #include "../../gmio_core/transfer.h" @@ -29,9 +30,6 @@ int gmio_stla_write( gmio_transfer_t* trsf, const gmio_stl_mesh_t* mesh, - /* Options */ - const char* solid_name, - gmio_float_text_format_t float32_format, - uint8_t float32_prec); + const gmio_stl_write_options_t* options); #endif /* GMIO_INTERNAL_STLA_WRITE_H */ diff --git a/src/gmio_stl/internal/stlb_write.c b/src/gmio_stl/internal/stlb_write.c index e07a189..3e94bee 100644 --- a/src/gmio_stl/internal/stlb_write.c +++ b/src/gmio_stl/internal/stlb_write.c @@ -18,6 +18,7 @@ #include "stl_rw_common.h" #include "stlb_byte_swap.h" #include "../stl_error.h" +#include "../stl_io.h" #include "../../gmio_core/error.h" #include "../../gmio_core/internal/byte_codec.h" @@ -67,13 +68,14 @@ static void gmio_stlb_write_facets( int gmio_stlb_write( gmio_transfer_t* trsf, const gmio_stl_mesh_t* mesh, - /* Options */ - const uint8_t* header_data, + const gmio_stl_write_options_t* options, gmio_endianness_t byte_order) { /* Constants */ const uint32_t facet_count = mesh != NULL ? mesh->triangle_count : 0; + const gmio_bool_t write_triangles_only = + options != NULL ? options->stl_write_triangles_only : GMIO_FALSE; /* Variables */ void* buffer_ptr = trsf != NULL ? trsf->buffer.ptr : NULL; gmio_stlb_readwrite_helper_t wparams = {0}; @@ -92,25 +94,15 @@ int gmio_stlb_write( wparams.facet_count = gmio_size_to_uint32( trsf->buffer.size / GMIO_STLB_TRIANGLE_RAWSIZE); - /* Write header */ - if (header_data == NULL) { - /* Use buffer to store an empty header (filled with zeroes) */ - memset(buffer_ptr, 0, GMIO_STLB_HEADER_SIZE); - header_data = (const uint8_t*)buffer_ptr; + if (!write_triangles_only) { + error = gmio_stlb_write_header( + &trsf->stream, + byte_order, + options != NULL ? options->stlb_header_data : NULL, + facet_count); + if (gmio_error(error)) + return error; } - if (gmio_stream_write(&trsf->stream, header_data, GMIO_STLB_HEADER_SIZE, 1) - != 1) - { - return GMIO_ERROR_STREAM; - } - - /* Write facet count */ - if (byte_order == GMIO_ENDIANNESS_LITTLE) - gmio_encode_uint32_le(facet_count, buffer_ptr); - else - gmio_encode_uint32_be(facet_count, buffer_ptr); - if (gmio_stream_write(&trsf->stream, buffer_ptr, sizeof(uint32_t), 1) != 1) - return GMIO_ERROR_STREAM; /* Write triangles */ for (i_facet = 0; diff --git a/src/gmio_stl/internal/stlb_write.h b/src/gmio_stl/internal/stlb_write.h index 8aeb789..ce5e58b 100644 --- a/src/gmio_stl/internal/stlb_write.h +++ b/src/gmio_stl/internal/stlb_write.h @@ -17,6 +17,7 @@ #define GMIO_INTERNAL_STLB_WRITE_H #include "../stl_mesh.h" +#include "../stl_io_options.h" #include "../../gmio_core/endian.h" #include "../../gmio_core/transfer.h" @@ -29,8 +30,7 @@ int gmio_stlb_write( gmio_transfer_t* trsf, const gmio_stl_mesh_t* mesh, - /* Options */ - const uint8_t* header_data, + const gmio_stl_write_options_t* options, gmio_endianness_t byte_order); #endif /* GMIO_INTERNAL_STLB_WRITE_H */ diff --git a/src/gmio_stl/stl_io.c b/src/gmio_stl/stl_io.c index c7a877b..40fd466 100644 --- a/src/gmio_stl/stl_io.c +++ b/src/gmio_stl/stl_io.c @@ -22,6 +22,7 @@ #include "../gmio_core/error.h" #include "../gmio_core/stream.h" #include "../gmio_core/transfer.h" +#include "../gmio_core/internal/byte_codec.h" #include "../gmio_core/internal/helper_stream.h" int gmio_stl_read_file( @@ -118,32 +119,20 @@ int gmio_stl_write( const gmio_stl_mesh_t *mesh, const gmio_stl_write_options_t *options) { - const uint8_t* header_data = - options != NULL ? options->stlb_header_data : NULL; int error = GMIO_ERROR_OK; if (trsf != NULL) { switch (format) { case GMIO_STL_FORMAT_ASCII: { - const char* solid_name = - options != NULL ? options->stla_solid_name : NULL; - const gmio_float_text_format_t float_fmt = - options != NULL ? options->stla_float32_format : - GMIO_FLOAT_TEXT_FORMAT_DECIMAL_LOWERCASE; - const uint8_t float_prec = - options != NULL ? options->stla_float32_prec : 9; - error = gmio_stla_write( - trsf, mesh, solid_name, float_fmt, float_prec); + error = gmio_stla_write(trsf, mesh, options); break; } case GMIO_STL_FORMAT_BINARY_BE: { - error = gmio_stlb_write( - trsf, mesh, header_data, GMIO_ENDIANNESS_BIG); + error = gmio_stlb_write(trsf, mesh, options, GMIO_ENDIANNESS_BIG); break; } case GMIO_STL_FORMAT_BINARY_LE: { - error = gmio_stlb_write( - trsf, mesh, header_data, GMIO_ENDIANNESS_LITTLE); + error = gmio_stlb_write(trsf, mesh, options, GMIO_ENDIANNESS_LITTLE); break; } case GMIO_STL_FORMAT_UNKNOWN: { @@ -157,3 +146,36 @@ int gmio_stl_write( return error; } + +static const uint8_t internal_stlb_zero_header[GMIO_STLB_HEADER_SIZE] = { 0 }; + +int gmio_stlb_write_header( + gmio_stream_t *stream, + gmio_endianness_t byte_order, + const uint8_t *header, + uint32_t facet_count) +{ + uint8_t facet_count_bytes[sizeof(uint32_t)]; + const uint8_t* non_null_header = + header != NULL ? header : &internal_stlb_zero_header[0]; + + /* Write 80-byte header */ + if (gmio_stream_write(stream, non_null_header, GMIO_STLB_HEADER_SIZE, 1) + != 1) + { + return GMIO_ERROR_STREAM; + } + + /* Write facet count */ + if (byte_order == GMIO_ENDIANNESS_LITTLE) + gmio_encode_uint32_le(facet_count, &facet_count_bytes[0]); + else + gmio_encode_uint32_be(facet_count, &facet_count_bytes[0]); + if (gmio_stream_write(stream, &facet_count_bytes[0], sizeof(uint32_t), 1) + != 1) + { + return GMIO_ERROR_STREAM; + } + + return GMIO_ERROR_OK; +} diff --git a/src/gmio_stl/stl_io.h b/src/gmio_stl/stl_io.h index 8596ff2..5ad9ef4 100644 --- a/src/gmio_stl/stl_io.h +++ b/src/gmio_stl/stl_io.h @@ -141,6 +141,27 @@ int gmio_stlb_read( gmio_stl_mesh_creator_t* creator, gmio_endianness_t byte_order); +/*! Writes STL binary header data to stream + * + * This functions only writes the 80-bytes header array and the count of facets + * in the mesh(with respect of the specified byte order). + * + * \param stream Output stream where is written the header data + * \param byte_order Byte order of the output STL data + * \param header 80-bytes array of header data, can be safely set to NULL (to + * generate an array of zeroes) + * \param facet_count Total count of facets (triangles) in the mesh to be + * written + * + * \return Error code (see error.h and stl_error.h) + */ +GMIO_LIBSTL_EXPORT +int gmio_stlb_write_header( + gmio_stream_t* stream, + gmio_endianness_t byte_order, + const uint8_t* header, + uint32_t facet_count); + GMIO_C_LINKAGE_END #endif /* GMIO_STL_IO_H */ diff --git a/src/gmio_stl/stl_io_options.h b/src/gmio_stl/stl_io_options.h index 074d896..ee193b5 100644 --- a/src/gmio_stl/stl_io_options.h +++ b/src/gmio_stl/stl_io_options.h @@ -27,6 +27,17 @@ /*! Options for gmio_stl_write() */ struct gmio_stl_write_options { + /*! Flag allowing to skip writting of any header/footer data, but just + * triangles + * + * If set to \c GMIO_TRUE then : + * \li for STL ASCII format, "solid " and + * "endsolid" will no be written to output stream + * \li for STL binary format, the 80 bytes header followed bt the mesh + * facet count (4bytes) will no be written to output stream + */ + gmio_bool_t stl_write_triangles_only; + /*! Name of the solid to appear in "solid \n facet normal ..." * * Option useful only with STL ascii format (GMIO_STL_FORMAT_ASCII). @@ -54,7 +65,7 @@ struct gmio_stl_write_options */ uint8_t stla_float32_prec; - /*! Header data consisting of 80 bytes + /*! Header data whose first 80 bytes have to be written * * Option useful only with STL binary formats (GMIO_STL_FORMAT_BINARY_LE * or GMIO_STL_FORMAT_BINARY_BE).