gmio_stl: add option "stl_write_triangles_only" and function gmio_stlb_write_header()

This commit is contained in:
Hugues Delorme 2015-05-27 17:29:48 +02:00
parent cad2a28f65
commit 6eb38fcd8b
7 changed files with 99 additions and 48 deletions

View File

@ -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))

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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, <tt>"solid <name>"</tt> and
* <tt>"endsolid"</tt> 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 <name> \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).