Major reorganization to improve performance

This commit is contained in:
Hugues Delorme 2014-01-28 19:06:24 +01:00
parent dbe36c0eb1
commit 59e5daf983
16 changed files with 291 additions and 226 deletions

View File

@ -30,7 +30,9 @@ HEADERS += \
../src/transfer.h \
\
../src/internal/convert.h \
../src/internal/ascii_parse.h
../src/internal/ascii_parse.h \
../src/internal/byte_swap.h \
../src/internal/byte_codec.h
SOURCES += \
../src/endian.c \
@ -55,19 +57,28 @@ contains(DATAX, stl) {
#DEFINES += FOUG_STLB_READWRITE_ALIGNSAFE
HEADERS += \
../src/libstl/stl_error.h \
../src/libstl/stl_format.h \
../src/libstl/stl_global.h \
../src/libstl/stl_triangle.h \
../src/libstl/stla_read.h \
../src/libstl/stla_write.h \
../src/libstl/stlb_read.h \
../src/libstl/stlb_write.h \
../src/libstl/stl_triangle.h \
../src/libstl/stlb_triangle.h
../src/libstl/stlb_triangle.h \
\
../src/internal/libstl/stlb_byte_swap.h \
../src/internal/libstl/stlb_rw_common.h
SOURCES += \
../src/libstl/stl_format.c \
../src/libstl/stla_read.c \
../src/libstl/stla_write.c \
../src/libstl/stlb_read.c \
../src/libstl/stlb_write.c
../src/libstl/stlb_write.c \
\
../src/internal/libstl/stlb_byte_swap.c \
../src/internal/libstl/stlb_rw_common.c
libstl_inc.path = $$PREFIX_DIR/include/datax/libstl
libstl_inc.files = ../src/libstl/*.h
@ -141,4 +152,7 @@ contains(DATAX, occ_support) {
OTHER_FILES += \
../doc/main_page.cpp \
../doc/Doxyfile
../doc/Doxyfile \
\
../src/config.h.cmake

View File

@ -2,15 +2,12 @@
#include "internal/convert.h"
#ifdef FOUG_HAVE_MSVC_BUILTIN_BSWAP_FUNC
# include <stdlib.h>
#endif
#include <string.h>
typedef union
{
uint32_t integer;
uint8_t bytes[4];
uint8_t bytes[4];
} _internal_foug_int_bytes_32_convert_t;
/*! Endianness (byte order) of the host's CPU architecture */
@ -29,122 +26,3 @@ foug_endianness_t foug_host_endianness()
return FOUG_OTHER_ENDIAN;
}
/*! Returns \p val with the order of bytes reversed.
*
* Uses compiler builtin functions if available
*/
uint16_t foug_uint16_bswap(uint16_t val)
{
#ifdef FOUG_HAVE_GCC_BUILTIN_BSWAP_FUNC
return __builtin_bswap16(val);
#elif defined(FOUG_HAVE_MSVC_BUILTIN_BSWAP_FUNC)
return _byteswap_ushort(val);
#else
return ((val & 0x00FF) << 8) | ((val >> 8) & 0x00FF);
#endif
}
/*! Read a 16bit integer from memory-location \p bytes (little-endian byte order) */
uint16_t foug_decode_uint16_le(const uint8_t* bytes)
{
/* |0 |1 | */
/* |BB|AA| -> 0xAABB */
return (bytes[1] << 8) | bytes[0];
}
/*! Read a 16bit integer from memory-location \p bytes (big-endian byte order) */
uint16_t foug_decode_uint16_be(const uint8_t* bytes)
{
/* |0 |1 | */
/* |AA|BB| -> 0xAABB */
return (bytes[0] << 8) | bytes[1];
}
/*! Write 16bit integer \p val to the memory location at \p bytes in little-endian byte order */
void foug_encode_uint16_le(uint16_t val, uint8_t* bytes)
{
bytes[0] = val & 0xFF;
bytes[1] = (val >> 8) & 0xFF;
}
/*! Returns \p val with the order of bytes reversed.
*
* Uses compiler builtin functions if available
*/
uint32_t foug_uint32_bswap(uint32_t val)
{
#ifdef FOUG_HAVE_GCC_BUILTIN_BSWAP_FUNC
return __builtin_bswap32(val);
#elif defined(FOUG_HAVE_MSVC_BUILTIN_BSWAP_FUNC)
return _byteswap_ulong(val);
#else
return
((val & 0x000000FF) << 24)
| ((val & 0x0000FF00) << 8)
| ((val >> 8) & 0x0000FF00)
| ((val >> 24) & 0x000000FF);
#endif
}
/*! Read a 32bit integer from memory-location \p bytes (little-endian byte order) */
uint32_t foug_decode_uint32_le(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xAABBCCDD */
return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
}
/*! Read a 32bit integer from memory-location \p bytes (mixed-endian byte order) */
uint32_t foug_decode_uint32_me(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xCCDDAABB */
return (bytes[0] >> 8) | (bytes[2] << 8) | (bytes[3] << 8) | (bytes[1] << 8);
}
/*! Read a 32bit integer from memory-location \p bytes (big-endian byte order) */
uint32_t foug_decode_uint32_be(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xDDCCBBAA */
return bytes[3] | (bytes[2] << 8) | (bytes[1] << 16) | (bytes[0] << 24);
}
/*! Write 32bit integer \p val to the memory location at \p bytes in little-endian byte order */
void foug_encode_uint32_le(uint32_t val, uint8_t* bytes)
{
bytes[0] = val & 0xFF;
bytes[1] = (val >> 8) & 0xFF;
bytes[2] = (val >> 16) & 0xFF;
bytes[3] = (val >> 24) & 0xFF;
}
/*! Write 32bit integer \p val to the memory location at \p bytes in big-endian byte order */
void foug_encode_uint32_be(uint32_t val, uint8_t* bytes)
{
bytes[0] = (val >> 24) & 0xFF;
bytes[1] = (val >> 16) & 0xFF;
bytes[2] = (val >> 8) & 0xFF;
bytes[3] = val & 0xFF;
}
/*! Read a 32bit real from memory-location \p bytes (little-endian byte order) */
foug_real32_t foug_decode_real32_le(const uint8_t* bytes)
{
return foug_convert_real32(foug_decode_uint32_le(bytes));
}
/*! Read a 32bit real from memory-location \p bytes (mixed-endian byte order) */
foug_real32_t foug_decode_real32_me(const uint8_t* bytes)
{
return foug_convert_real32(foug_decode_uint32_me(bytes));
}
/*! Read a 32bit real from memory-location \p bytes (big-endian byte order) */
foug_real32_t foug_decode_real32_be(const uint8_t* bytes)
{
return foug_convert_real32(foug_decode_uint32_be(bytes));
}
/*! Write 32bit real \p val to the memory location at \p bytes in little-endian byte order */
void foug_encode_real32_le(foug_real32_t val, uint8_t* bytes)
{
foug_encode_uint32_le(foug_convert_uint32(val), bytes);
}

View File

@ -13,21 +13,4 @@ typedef enum
FOUG_LIB_EXPORT foug_endianness_t foug_host_endianness();
FOUG_LIB_EXPORT uint16_t foug_uint16_bswap(uint16_t val);
FOUG_LIB_EXPORT uint16_t foug_decode_uint16_le(const uint8_t* bytes);
FOUG_LIB_EXPORT uint16_t foug_decode_uint16_be(const uint8_t* bytes);
FOUG_LIB_EXPORT void foug_encode_uint16_le(uint16_t val, uint8_t* bytes);
FOUG_LIB_EXPORT uint32_t foug_uint32_bswap(uint32_t val);
FOUG_LIB_EXPORT uint32_t foug_decode_uint32_le(const uint8_t* bytes);
FOUG_LIB_EXPORT uint32_t foug_decode_uint32_me(const uint8_t* bytes);
FOUG_LIB_EXPORT uint32_t foug_decode_uint32_be(const uint8_t* bytes);
FOUG_LIB_EXPORT void foug_encode_uint32_le(uint32_t val, uint8_t* bytes);
FOUG_LIB_EXPORT void foug_encode_uint32_be(uint32_t val, uint8_t* bytes);
FOUG_LIB_EXPORT foug_real32_t foug_decode_real32_le(const uint8_t* bytes);
FOUG_LIB_EXPORT foug_real32_t foug_decode_real32_me(const uint8_t* bytes);
FOUG_LIB_EXPORT foug_real32_t foug_decode_real32_be(const uint8_t* bytes);
FOUG_LIB_EXPORT void foug_encode_real32_le(foug_real32_t val, uint8_t* bytes);
#endif /* FOUG_ENDIAN_H */

View File

@ -20,7 +20,10 @@
# define FOUG_LIB_EXPORT
#endif /* FOUG_LIB_DLL */
#include "config.h" /* Generated by build system */
/* "config.h" is generated by cmake, it should reside in the out-of-source build dir.
* In CMakeFiles.txt, the directory where resides "config.h" is added to the include path list
*/
#include "config.h"
#ifdef FOUG_HAVE_STDINT_H
# include <stdint.h>
@ -48,4 +51,14 @@ typedef int8_t foug_bool_t;
typedef float foug_real32_t;
typedef double foug_real64_t;
#ifndef FOUG_INLINE
# if defined(__GNUC__)
# define FOUG_INLINE __inline__ /* Compatible with C90 */
# elif defined(_MSC_VER)
# define FOUG_INLINE __inline
# else
# define FOUG_INLINE
# endif
#endif /* !FOUG_INLINE */
#endif /* FOUG_C_GLOBAL_H */

68
src/internal/byte_codec.h Normal file
View File

@ -0,0 +1,68 @@
/* Warning : this header has no multi-inclusion guard. It must be included only once in the
* translation unit of use. The reason is that all functions defined here are meant to
* be inlined for performance purpose
*/
#include "../global.h"
/*! Read a 16bit integer from memory-location \p bytes (little-endian byte order) */
FOUG_INLINE static uint16_t foug_decode_uint16_le(const uint8_t* bytes)
{
/* |0 |1 | */
/* |BB|AA| -> 0xAABB */
return (bytes[1] << 8) | bytes[0];
}
/*! Read a 16bit integer from memory-location \p bytes (big-endian byte order) */
FOUG_INLINE static uint16_t foug_decode_uint16_be(const uint8_t* bytes)
{
/* |0 |1 | */
/* |AA|BB| -> 0xAABB */
return (bytes[0] << 8) | bytes[1];
}
/*! Write 16bit integer \p val to the memory location at \p bytes in little-endian byte order */
FOUG_INLINE static void foug_encode_uint16_le(uint16_t val, uint8_t* bytes)
{
bytes[0] = val & 0xFF;
bytes[1] = (val >> 8) & 0xFF;
}
/*! Read a 32bit integer from memory-location \p bytes (little-endian byte order) */
FOUG_INLINE static uint32_t foug_decode_uint32_le(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xAABBCCDD */
return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
}
/*! Read a 32bit integer from memory-location \p bytes (mixed-endian byte order) */
FOUG_INLINE static uint32_t foug_decode_uint32_me(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xCCDDAABB */
return (bytes[0] >> 8) | (bytes[2] << 8) | (bytes[3] << 8) | (bytes[1] << 8);
}
/*! Read a 32bit integer from memory-location \p bytes (big-endian byte order) */
FOUG_INLINE static uint32_t foug_decode_uint32_be(const uint8_t* bytes)
{
/* |DD|CC|BB|AA| -> 0xDDCCBBAA */
return bytes[3] | (bytes[2] << 8) | (bytes[1] << 16) | (bytes[0] << 24);
}
/*! Write 32bit integer \p val to the memory location at \p bytes in little-endian byte order */
FOUG_INLINE static void foug_encode_uint32_le(uint32_t val, uint8_t* bytes)
{
bytes[0] = val & 0xFF;
bytes[1] = (val >> 8) & 0xFF;
bytes[2] = (val >> 16) & 0xFF;
bytes[3] = (val >> 24) & 0xFF;
}
/*! Write 32bit integer \p val to the memory location at \p bytes in big-endian byte order */
FOUG_INLINE static void foug_encode_uint32_be(uint32_t val, uint8_t* bytes)
{
bytes[0] = (val >> 24) & 0xFF;
bytes[1] = (val >> 16) & 0xFF;
bytes[2] = (val >> 8) & 0xFF;
bytes[3] = val & 0xFF;
}

38
src/internal/byte_swap.h Normal file
View File

@ -0,0 +1,38 @@
/* Warning : this header has no multi-inclusion guard. It must be included only once in the
* translation unit of use. The reason is that all functions defined here are meant to
* be inlined for performance purpose
*/
#include "../global.h"
#ifdef FOUG_HAVE_MSVC_BUILTIN_BSWAP_FUNC
# include <stdlib.h>
#endif
/*! Returns \p val with the order of bytes reversed, uses compiler builtin functions if available */
FOUG_INLINE static uint16_t foug_uint16_bswap(uint16_t val)
{
#ifdef FOUG_HAVE_GCC_BUILTIN_BSWAP_FUNC
return __builtin_bswap16(val);
#elif defined(FOUG_HAVE_MSVC_BUILTIN_BSWAP_FUNC)
return _byteswap_ushort(val);
#else
return ((val & 0x00FF) << 8) | ((val >> 8) & 0x00FF);
#endif
}
/*! Returns \p val with the order of bytes reversed, uses compiler builtin functions if available */
FOUG_INLINE static uint32_t foug_uint32_bswap(uint32_t val)
{
#ifdef FOUG_HAVE_GCC_BUILTIN_BSWAP_FUNC
return __builtin_bswap32(val);
#elif defined(FOUG_HAVE_MSVC_BUILTIN_BSWAP_FUNC)
return _byteswap_ulong(val);
#else
return
((val & 0x000000FF) << 24)
| ((val & 0x0000FF00) << 8)
| ((val >> 8) & 0x0000FF00)
| ((val >> 24) & 0x000000FF);
#endif
}

View File

@ -1,21 +1,15 @@
#include "convert.h"
typedef union
{
uint32_t as_integer;
foug_real32_t as_float;
} _internal_foug_int_real_32_convert_t;
foug_real32_t foug_convert_real32(uint32_t val)
{
_internal_foug_int_real_32_convert_t conv;
conv.as_integer = val;
foug_uint32_float_t conv;
conv.as_uint32 = val;
return conv.as_float;
}
uint32_t foug_convert_uint32(foug_real32_t val)
{
_internal_foug_int_real_32_convert_t conv;
foug_uint32_float_t conv;
conv.as_float = val;
return conv.as_integer;
return conv.as_uint32;
}

View File

@ -1,9 +1,15 @@
#ifndef FOUG_CONVERT_H
#define FOUG_CONVERT_H
#ifndef FOUG_INTERNAL_CONVERT_H
#define FOUG_INTERNAL_CONVERT_H
#include "../global.h"
typedef union
{
uint32_t as_uint32;
float as_float;
} foug_uint32_float_t;
foug_real32_t foug_convert_real32(uint32_t val);
uint32_t foug_convert_uint32(foug_real32_t val);
#endif /* FOUG_CONVERT_H */
#endif /* FOUG_INTERNAL_CONVERT_H */

View File

@ -0,0 +1,14 @@
#include "stlb_byte_swap.h"
#include "../byte_swap.h"
void foug_stlb_triangle_bswap(foug_stlb_triangle_t* triangle)
{
int i;
uint32_t* uintcoord_ptr = (uint32_t*)&(triangle->data.normal.x);
for (i = 0; i < 12; ++i)
*(uintcoord_ptr + i) = foug_uint32_bswap(*(uintcoord_ptr + i));
if (triangle->attribute_byte_count != 0)
triangle->attribute_byte_count = foug_uint16_bswap(triangle->attribute_byte_count);
}

View File

@ -0,0 +1,9 @@
#ifndef FOUG_INTERNAL_STLB_ENDIAN_H
#define FOUG_INTERNAL_STLB_ENDIAN_H
#include "../../global.h"
#include "../../libstl/stlb_triangle.h"
void foug_stlb_triangle_bswap(foug_stlb_triangle_t* triangle);
#endif /* FOUG_INTERNAL_STLB_ENDIAN_H */

View File

@ -0,0 +1,19 @@
#include "stlb_rw_common.h"
#include "../../error.h"
#include "../../libstl/stl_error.h"
int foug_stlb_check_params(const foug_transfer_t *trsf,
foug_endianness_t byte_order)
{
if (trsf == NULL)
return FOUG_DATAX_NULL_TRANSFER_ERROR;
if (trsf->buffer == NULL)
return FOUG_DATAX_NULL_BUFFER_ERROR;
if (trsf->buffer_size < FOUG_STLB_MIN_CONTENTS_SIZE)
return FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR;
if (byte_order != FOUG_LITTLE_ENDIAN && byte_order != FOUG_BIG_ENDIAN)
return FOUG_STLB_READWRITE_UNSUPPORTED_BYTE_ORDER;
return FOUG_DATAX_NO_ERROR;
}

View File

@ -0,0 +1,19 @@
#ifndef FOUG_INTERNAL_STLB_RW_COMMON_H
#define FOUG_INTERNAL_STLB_RW_COMMON_H
#include "../../global.h"
#include "../../endian.h"
#include "../../transfer.h"
#include "../../libstl/stlb_triangle.h"
typedef struct
{
uint32_t facet_count;
uint32_t i_facet_offset;
void (*fix_endian_func)(foug_stlb_triangle_t*);
} foug_readwrite_helper;
int foug_stlb_check_params(const foug_transfer_t* trsf,
foug_endianness_t byte_order);
#endif /* FOUG_INTERNAL_STLB_RW_COMMON_H */

View File

@ -1,7 +1,8 @@
#include "stla_read.h"
#include "../error.h"
#include "../internal/ascii_parse.h"
#include "../error.h"
#include "stl_error.h"
#include <ctype.h>
#include <stdlib.h>
@ -101,26 +102,27 @@ static void foug_stream_fwd_iterator_stla_read_hook(void* cookie,
}
}
foug_bool_t parsing_can_continue(const foug_stla_parse_data_t* data)
FOUG_INLINE static foug_bool_t parsing_can_continue(const foug_stla_parse_data_t* data)
{
if (data->error || data->stream_iterator_cookie.is_stop_requested)
return 0;
return 1;
}
static const char* current_token_as_identifier(const foug_stla_parse_data_t* data)
FOUG_INLINE static const char* current_token_as_identifier(const foug_stla_parse_data_t* data)
{
return data->token == ID_token ? data->string_buffer.ptr : "";
}
static int get_current_token_as_real32(const foug_stla_parse_data_t* data, foug_real32_t* value_ptr)
FOUG_INLINE static int get_current_token_as_real32(const foug_stla_parse_data_t* data,
foug_real32_t* value_ptr)
{
if (data->token == FLOAT_token)
return foug_get_real32(data->string_buffer.ptr, value_ptr);
return -3;
}
static void parsing_error(foug_stla_parse_data_t* data)
FOUG_INLINE static void parsing_error(foug_stla_parse_data_t* data)
{
data->error = 1;
data->token = unknown_token;

View File

@ -1,6 +1,7 @@
#include "stla_write.h"
#include "../error.h"
#include "stl_error.h"
#include <stdio.h>
#include <string.h>

View File

@ -2,24 +2,17 @@
#include "../endian.h"
#include "../error.h"
#include "stl_error.h"
#include "../internal/convert.h"
#include "../internal/byte_swap.h"
#include "../internal/libstl/stlb_byte_swap.h"
#include "../internal/libstl/stlb_rw_common.h"
#include <string.h>
typedef struct
{
foug_endianness_t host_endianness;
foug_endianness_t stream_endianness;
} _internal_foug_endianness_info_t;
typedef struct
{
uint32_t facet_count;
uint32_t i_facet_offset;
_internal_foug_endianness_info_t endian_info;
} _internal_foug_read_params_helper;
static void read_triangle_memcpy(const uint8_t* buffer, foug_stlb_triangle_t* triangle)
FOUG_INLINE static void read_triangle_memcpy(const uint8_t* buffer,
foug_stlb_triangle_t* triangle)
{
/* *triangle = *((foug_stlb_triangle_t*)(buffer)); */
memcpy(triangle, buffer, FOUG_STLB_TRIANGLE_RAWSIZE);
@ -41,10 +34,10 @@ static void read_triangle_alignsafe(const uint8_t* buffer, foug_stlb_triangle_t*
static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom,
const uint8_t* buffer,
const _internal_foug_read_params_helper* params)
const foug_readwrite_helper* rparams)
{
const uint32_t facet_count = params->facet_count;
const uint32_t i_facet_offset = params->i_facet_offset;
const uint32_t facet_count = rparams->facet_count;
const uint32_t i_facet_offset = rparams->i_facet_offset;
foug_stlb_triangle_t triangle;
uint32_t buffer_offset;
uint32_t i_facet;
@ -62,6 +55,9 @@ static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom,
#endif
buffer_offset += FOUG_STLB_TRIANGLE_RAWSIZE;
if (rparams->fix_endian_func != NULL)
rparams->fix_endian_func(&triangle);
/* Declare triangle */
geom->process_triangle_func(geom->cookie,
i_facet_offset + i_facet,
@ -74,22 +70,20 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
foug_transfer_t* trsf,
foug_endianness_t byte_order)
{
_internal_foug_read_params_helper read_params;
const foug_endianness_t host_byte_order = foug_host_endianness();
foug_readwrite_helper rparams;
uint32_t total_facet_count = 0; /* Count of facets as declared in the stream */
int error = FOUG_DATAX_NO_ERROR; /* Helper variable to store function result error code */
/* Check validity of input parameters */
if (trsf->buffer == NULL)
return FOUG_DATAX_NULL_BUFFER_ERROR;
if (trsf->buffer_size < FOUG_STLB_MIN_CONTENTS_SIZE)
return FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR;
if (byte_order != FOUG_LITTLE_ENDIAN)
return FOUG_STLB_READ_UNSUPPORTED_BYTE_ORDER;
error = foug_stlb_check_params(trsf, byte_order);
if (foug_datax_error(error))
return error;
/* Initialize read_params */
memset(&read_params, 0, sizeof(_internal_foug_read_params_helper));
read_params.endian_info.host_endianness = foug_host_endianness();
read_params.endian_info.stream_endianness = byte_order;
/* Initialize rparams */
memset(&rparams, 0, sizeof(foug_readwrite_helper));
if (host_byte_order != byte_order)
rparams.fix_endian_func = foug_stlb_triangle_bswap;
/* Read header */
{
@ -107,21 +101,23 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
if (foug_stream_read(&trsf->stream, trsf->buffer, sizeof(uint32_t), 1) != 1)
return FOUG_STLB_READ_FACET_COUNT_ERROR;
total_facet_count = foug_decode_uint32_le(trsf->buffer);
memcpy(&total_facet_count, trsf->buffer, sizeof(uint32_t));
if (host_byte_order != byte_order)
total_facet_count = foug_uint32_bswap(total_facet_count);
if (geom != NULL && geom->begin_triangles_func != NULL)
geom->begin_triangles_func(geom->cookie, total_facet_count);
/* Read triangles */
while (foug_datax_no_error(error)
&& read_params.i_facet_offset < total_facet_count)
&& rparams.i_facet_offset < total_facet_count)
{
read_params.facet_count = foug_stream_read(&trsf->stream,
rparams.facet_count = foug_stream_read(&trsf->stream,
trsf->buffer,
FOUG_STLB_TRIANGLE_RAWSIZE,
trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE);
if (foug_stream_error(&trsf->stream) != 0)
error = FOUG_DATAX_STREAM_ERROR;
else if (read_params.facet_count > 0)
else if (rparams.facet_count > 0)
error = FOUG_DATAX_NO_ERROR;
else
break; /* Exit if no facet to read */
@ -129,9 +125,9 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
if (foug_datax_no_error(error)) {
uint8_t progress_pc;
foug_stlb_read_facets(geom, trsf->buffer, &read_params);
read_params.i_facet_offset += read_params.facet_count;
progress_pc = foug_percentage(0, total_facet_count, read_params.i_facet_offset);
foug_stlb_read_facets(geom, trsf->buffer, &rparams);
rparams.i_facet_offset += rparams.facet_count;
progress_pc = foug_percentage(0, total_facet_count, rparams.i_facet_offset);
if (!foug_task_control_handle_progress(&trsf->task_control, progress_pc))
error = FOUG_DATAX_TASK_STOPPED_ERROR;
}
@ -143,7 +139,7 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
geom->end_triangles_func(geom->cookie);
}
if (foug_datax_no_error(error) && read_params.i_facet_offset != total_facet_count)
if (foug_datax_no_error(error) && rparams.i_facet_offset != total_facet_count)
error = FOUG_STLB_READ_FACET_COUNT_ERROR;
return error;
}

View File

@ -2,9 +2,16 @@
#include "../endian.h"
#include "../error.h"
#include "stl_error.h"
#include "../internal/byte_codec.h"
#include "../internal/libstl/stlb_byte_swap.h"
#include "../internal/libstl/stlb_rw_common.h"
#include <string.h>
static void write_triangle_memcpy(const foug_stlb_triangle_t* triangle, uint8_t* buffer)
FOUG_INLINE static void write_triangle_memcpy(const foug_stlb_triangle_t* triangle,
uint8_t* buffer)
{
memcpy(buffer, triangle, FOUG_STLB_TRIANGLE_RAWSIZE);
}
@ -25,9 +32,10 @@ static void write_triangle_alignsafe(const foug_stlb_triangle_t* triangle, uint8
static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom,
uint8_t* buffer,
uint32_t ifacet_start,
uint32_t facet_count)
const foug_readwrite_helper* wparams)
{
const uint32_t facet_count = wparams->facet_count;
const uint32_t i_facet_offset = wparams->i_facet_offset;
foug_stlb_triangle_t triangle;
uint32_t buffer_offset;
uint32_t i_facet;
@ -37,10 +45,13 @@ static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom,
triangle.attribute_byte_count = 0;
buffer_offset = 0;
for (i_facet = ifacet_start; i_facet < (ifacet_start + facet_count); ++i_facet) {
for (i_facet = i_facet_offset; i_facet < (i_facet_offset + facet_count); ++i_facet) {
geom->get_triangle_func(geom->cookie, i_facet, &triangle.data);
if (geom->get_attr_byte_count_func != NULL)
geom->get_attr_byte_count_func(geom->cookie, &triangle.attribute_byte_count);
geom->get_attr_byte_count_func(geom->cookie, i_facet, &triangle.attribute_byte_count);
if (wparams->fix_endian_func != NULL)
wparams->fix_endian_func(&triangle);
#ifdef FOUG_STLB_READWRITE_ALIGNSAFE
write_triangle_alignsafe(&triangle, buffer + buffer_offset);
@ -56,20 +67,23 @@ int foug_stlb_write(const foug_stlb_geom_output_t* geom,
foug_transfer_t* trsf,
foug_endianness_t byte_order)
{
foug_readwrite_helper wparams;
const uint32_t facet_count = geom != NULL ? geom->triangle_count : 0;
uint32_t i_facet;
uint32_t buffer_facet_count;
uint32_t ifacet_start;
int error;
uint32_t i_facet = 0;
int error = FOUG_DATAX_NO_ERROR;
if (trsf->buffer == NULL)
return FOUG_DATAX_NULL_BUFFER_ERROR;
if (trsf->buffer_size < FOUG_STLB_MIN_CONTENTS_SIZE)
return FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR;
/* Check validity of input parameters */
error = foug_stlb_check_params(trsf, byte_order);
if (foug_datax_error(error))
return error;
if (geom == NULL || geom->get_triangle_func == NULL)
return FOUG_STLB_WRITE_NULL_GET_TRIANGLE_FUNC;
if (byte_order != FOUG_LITTLE_ENDIAN/* && byte_order != FOUG_BIG_ENDIAN*/)
return FOUG_STLB_WRITE_UNSUPPORTED_BYTE_ORDER;
/* Initialize wparams */
memset(&wparams, 0, sizeof(foug_readwrite_helper));
if (foug_host_endianness() != byte_order)
wparams.fix_endian_func = foug_stlb_triangle_bswap;
wparams.facet_count = trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE;
/* Write header */
{
@ -95,23 +109,20 @@ int foug_stlb_write(const foug_stlb_geom_output_t* geom,
return FOUG_DATAX_STREAM_ERROR;
/* Write triangles */
error = FOUG_DATAX_NO_ERROR;
buffer_facet_count = trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE;
ifacet_start = 0;
for (i_facet = 0;
i_facet < facet_count && foug_datax_no_error(error);
i_facet += buffer_facet_count)
i_facet += wparams.facet_count)
{
/* Write to buffer */
if (buffer_facet_count > (facet_count - ifacet_start))
buffer_facet_count = facet_count - ifacet_start;
foug_stlb_write_facets(geom, trsf->buffer, ifacet_start, buffer_facet_count);
ifacet_start += buffer_facet_count;
if (wparams.facet_count > (facet_count - wparams.i_facet_offset))
wparams.facet_count = facet_count - wparams.i_facet_offset;
foug_stlb_write_facets(geom, trsf->buffer, &wparams);
wparams.i_facet_offset += wparams.facet_count;
/* Write buffer to stream */
if (foug_stream_write(&trsf->stream, trsf->buffer, FOUG_STLB_TRIANGLE_RAWSIZE, buffer_facet_count)
!= buffer_facet_count)
if (foug_stream_write(&trsf->stream, trsf->buffer, FOUG_STLB_TRIANGLE_RAWSIZE, wparams.facet_count)
!= wparams.facet_count)
{
error = FOUG_DATAX_STREAM_ERROR;
}