Simplify cookie mechanism

This commit is contained in:
Hugues Delorme 2014-01-27 15:03:50 +01:00
parent 90f5f084f6
commit 11d5668d4b
15 changed files with 302 additions and 322 deletions

View File

@ -54,7 +54,7 @@
*/
/* foug_stream_fwd_iterator */
struct foug_stream_fwd_iterator
typedef struct
{
foug_stream_t* stream;
char* buffer;
@ -62,31 +62,25 @@ struct foug_stream_fwd_iterator
uint32_t buffer_size;
void* cookie;
void (*stream_read_hook)(struct foug_stream_fwd_iterator* it);
};
typedef struct foug_stream_fwd_iterator
foug_stream_fwd_iterator_t;
void (*stream_read_hook)(void*, const char*, uint32_t);
} foug_stream_fwd_iterator_t;
/* foug_string_buffer */
struct foug_string_buffer
typedef struct
{
char* data;
size_t max_len;
size_t len;
};
typedef struct foug_string_buffer
foug_string_buffer_t;
} foug_string_buffer_t;
/* foug_stream_fwd_iterator_stla_cookie */
struct foug_stream_fwd_iterator_stla_cookie
typedef struct
{
foug_task_control_t* task_control;
size_t stream_data_size;
size_t stream_offset;
foug_bool_t is_stop_requested;
};
typedef struct foug_stream_fwd_iterator_stla_cookie
foug_stream_fwd_iterator_stla_cookie_t;
} foug_stream_fwd_iterator_stla_cookie_t;
/* foug_stla_token */
enum foug_stla_token
@ -107,7 +101,7 @@ enum foug_stla_token
typedef enum foug_stla_token foug_stla_token_t;
/* foug_stla_parse_data */
struct foug_stla_parse_data
typedef struct
{
foug_stla_token_t token;
foug_bool_t error;
@ -115,18 +109,17 @@ struct foug_stla_parse_data
foug_stream_fwd_iterator_stla_cookie_t stream_iterator_cookie;
foug_string_buffer_t string_buffer;
foug_stla_geom_input_t* geom;
};
typedef struct foug_stla_parse_data
foug_stla_parse_data_t;
} foug_stla_parse_data_t;
static void foug_stream_fwd_iterator_stla_read_hook(foug_stream_fwd_iterator_t* it)
static void foug_stream_fwd_iterator_stla_read_hook(void* cookie,
const char* buffer,
uint32_t buffer_len)
{
foug_stream_fwd_iterator_stla_cookie_t* cookie =
it != NULL ? (foug_stream_fwd_iterator_stla_cookie_t*)(it->cookie) : NULL;
if (cookie != NULL) {
const uint8_t progress_pc = foug_percentage(0, cookie->stream_data_size, cookie->stream_offset);
cookie->is_stop_requested = !foug_task_control_handle_progress(cookie->task_control, progress_pc);
cookie->stream_offset += it->buffer_size;
foug_stream_fwd_iterator_stla_cookie_t* tcookie = (foug_stream_fwd_iterator_stla_cookie_t*)(cookie);
if (tcookie != NULL) {
const uint8_t progress_pc = foug_percentage(0, tcookie->stream_data_size, tcookie->stream_offset);
tcookie->is_stop_requested = !foug_task_control_handle_progress(tcookie->task_control, progress_pc);
tcookie->stream_offset += buffer_len;
}
}
@ -164,7 +157,7 @@ static char* next_char(foug_stream_fwd_iterator_t* it)
it->buffer_offset = 0;
it->buffer_size = char_count_read;
if (it->stream_read_hook != NULL)
it->stream_read_hook(it);
it->stream_read_hook(it->cookie, it->buffer, it->buffer_size);
return it->buffer;
}
}
@ -185,9 +178,9 @@ static void skip_spaces(foug_stream_fwd_iterator_t* it)
static int eat_string(foug_stream_fwd_iterator_t* it, foug_string_buffer_t* str_buffer)
{
size_t i;
const char* stream_curr_char;
int isspace_res;
const char* stream_curr_char = NULL;
int isspace_res = 0;
size_t i = 0;
if (str_buffer == NULL || str_buffer->data == NULL || str_buffer->max_len == 0)
return -1;
@ -196,11 +189,9 @@ static int eat_string(foug_stream_fwd_iterator_t* it, foug_string_buffer_t* str_
skip_spaces(it);
stream_curr_char = current_char(it);
isspace_res = 0;
i = 0;
while (i < str_buffer->max_len && stream_curr_char != NULL && !isspace_res) {
while (i < str_buffer->max_len && stream_curr_char != NULL && isspace_res == 0) {
isspace_res = isspace(*stream_curr_char);
if (!isspace_res) {
if (isspace_res == 0) {
str_buffer->data[i] = *stream_curr_char;
stream_curr_char = next_char(it);
++i;
@ -221,10 +212,14 @@ static int get_real32(const char* str, foug_real32_t* value_ptr)
{
char* end_ptr; /* for strtod() */
/* printf("DEBUG get_real32(): ");
fflush(stdout);
printf("str=\"%s\"\n", str);*/
#ifdef FOUG_HAVE_STRTOF_FUNC
*value_ptr = strtof(str, &end_ptr); /* Requires C99 */
#else
*value_ptr = (foug_real32_t)strtod(str, &end_ptr);
/* *value_ptr = (foug_real32_t)strtod(str, &end_ptr); */
*value_ptr = (foug_real32_t)atof(str);
#endif
if (end_ptr == str || errno == ERANGE)
@ -381,7 +376,7 @@ static void parse_beginsolid(foug_stla_parse_data_t* data)
parsing_eat_token(SOLID_token, data);
parse_solidname_beg(data);
if (parsing_can_continue(data) && data->geom != NULL && data->geom->begin_solid_func != NULL)
data->geom->begin_solid_func(data->geom, current_token_as_identifier(data));
data->geom->begin_solid_func(data->geom->cookie, current_token_as_identifier(data));
if (data->token == ID_token)
parsing_eat_token(ID_token, data);
break;
@ -401,7 +396,7 @@ static void parse_endsolid(foug_stla_parse_data_t* data)
parsing_eat_token(ENDSOLID_token, data);
parse_solidname_end(data);
if (parsing_can_continue(data) && data->geom != NULL && data->geom->end_solid_func != NULL)
data->geom->end_solid_func(data->geom, current_token_as_identifier(data));
data->geom->end_solid_func(data->geom->cookie/*, current_token_as_identifier(data)*/);
if (data->token == ID_token)
parsing_eat_token(ID_token, data);
break;
@ -466,7 +461,7 @@ static void parse_facets(foug_stla_parse_data_t* data, size_t i_facet_offset)
&& data->geom != NULL
&& data->geom->process_triangle_func != NULL)
{
data->geom->process_triangle_func(data->geom, &facet, i_facet_offset);
data->geom->process_triangle_func(data->geom->cookie, i_facet_offset, &facet);
}
parse_facets(data, i_facet_offset + 1);
@ -493,20 +488,6 @@ static void parse_solid(foug_stla_parse_data_t* data)
}
}
static void parse_contents(foug_stla_parse_data_t* data)
{
if (!parsing_can_continue(data))
return;
switch (data->token) {
case SOLID_token:
parse_solid(data);
break;
default:
parsing_error(data);
}
}
#define FOUG_STLA_READ_STRING_BUFFER_LEN 512
int foug_stla_read(foug_stla_geom_input_t* geom,
@ -546,7 +527,7 @@ int foug_stla_read(foug_stla_geom_input_t* geom,
parse_data.geom = geom;
parsing_advance(&parse_data);
parse_contents(&parse_data);
parse_solid(&parse_data);
if (parse_data.error)
return FOUG_STLA_READ_PARSE_ERROR;

View File

@ -6,14 +6,15 @@
#include "../transfer.h"
/* foug_stla_geom_input */
typedef struct foug_stla_geom_input foug_stla_geom_input_t;
struct foug_stla_geom_input
typedef struct
{
void* cookie;
void (*begin_solid_func) (foug_stla_geom_input_t*, const char*); /* Optional */
void (*process_triangle_func)(foug_stla_geom_input_t*, const foug_stl_triangle_t*, uint32_t);
void (*end_solid_func) (foug_stla_geom_input_t*, const char*); /* Optional */
};
void* cookie;
void (*begin_solid_func) (void*, const char*); /* Optional */
void (*process_triangle_func)(void*, uint32_t, const foug_stl_triangle_t*);
void (*end_solid_func) (void*); /* Optional */
} foug_stla_geom_input_t;
typedef void (*foug_stla_begin_solid_func_t)(void*, const char*);
typedef void (*foug_stla_process_triangle_func_t)(void*, uint32_t, const foug_stl_triangle_t*);
/* foug_stla_read() */
FOUG_DATAX_LIBSTL_EXPORT int foug_stla_read(foug_stla_geom_input_t* geom,

View File

@ -53,16 +53,17 @@ static char* foug_write_eol(char* buffer)
return buffer + 1;
}*/
static char* foug_write_nspaces(char* buffer, size_t n)
static char* foug_write_nspaces(char* buffer, int n)
{
const int offset = n;
while (n > 0)
buffer[--n] = ' ';
return buffer + n;
*(buffer + (--n)) = ' ';
return buffer + offset;
}
static char* foug_write_stdio_format(char* buffer, uint8_t prec)
{
size_t prec_len = 0 ;
int prec_len = 0;
buffer[0] = '%';
buffer[1] = '.';
@ -88,6 +89,8 @@ static foug_bool_t foug_tansfer_flush_buffer(foug_transfer_t* trsf, size_t n)
return foug_stream_write(&trsf->stream, trsf->buffer, sizeof(char), n) == n;
}
#define _FOUG_INTERNAL_MIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
/*! \brief Write geometry in the STL ascii format
*
* \param geom Defines the custom geometry to write
@ -100,7 +103,6 @@ static foug_bool_t foug_tansfer_flush_buffer(foug_transfer_t* trsf, size_t n)
* \retval FOUG_DATAX_NULL_BUFFER_ERROR If trsf->buffer is NULL
* \retval FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR If trsf->buffer_size is less than 512 bytes
* \retval FOUG_STLA_WRITE_INVALID_REAL32_PRECISION If \p real_prec is not inside [1..9]
* \retval FOUG_STLA_WRITE_NULL_GET_TRIANGLE_COUNT_FUNC If geom->get_triangle_count_func is NULL
* \retval FOUG_STLA_WRITE_NULL_GET_TRIANGLE_FUNC If geom->get_triangle_func is NULL
* \retval FOUG_DATAX_STREAM_ERROR For any writing error
* \retval FOUG_DATAX_TASK_STOPPED_ERROR If the operation was interrupted foug_task_control
@ -109,11 +111,11 @@ int foug_stla_write(foug_stla_geom_output_t* geom,
foug_transfer_t* trsf,
uint8_t real32_prec)
{
const size_t solid_count = geom != NULL ? geom->solid_count : 0;
size_t total_facet_count = 0;
size_t written_facet_count = 0;
size_t isolid = 0;
const size_t buffer_facet_count = trsf != NULL ? trsf->buffer_size / FOUG_STLA_FACET_SIZE_P2 : 0;
const char* solid_name = geom != NULL && geom->solid_name != NULL ? geom->solid_name : "";
const uint32_t total_facet_count = geom != NULL ? geom->triangle_count : 0;
uint32_t written_facet_count = 0;
const uint32_t buffer_facet_count = trsf != NULL ? trsf->buffer_size / FOUG_STLA_FACET_SIZE_P2 : 0;
uint32_t ifacet = 0;
char* buffer_iterator = trsf != NULL ? trsf->buffer : NULL;
char coords_format[64];
int error = FOUG_DATAX_NO_ERROR;
@ -124,8 +126,6 @@ int foug_stla_write(foug_stla_geom_output_t* geom,
return FOUG_DATAX_NULL_BUFFER_ERROR;
if (trsf->buffer_size < FOUG_STLA_FACET_SIZE_P2)
return FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR;
if (geom->get_triangle_count_func == NULL)
return FOUG_STLA_WRITE_NULL_GET_TRIANGLE_COUNT_FUNC;
if (geom->get_triangle_func == NULL)
return FOUG_STLA_WRITE_NULL_GET_TRIANGLE_FUNC;
@ -136,89 +136,71 @@ int foug_stla_write(foug_stla_geom_output_t* geom,
coords_format_iterator = foug_write_stdio_format(coords_format_iterator, real32_prec);
coords_format_iterator = foug_write_nspaces(coords_format_iterator, 2);
coords_format_iterator = foug_write_stdio_format(coords_format_iterator, real32_prec);
*coords_format_iterator = 0; /* Write terminating null byte */
/* TODO: check the "format" string can contain the given precision */
}
/* Compute total facet count */
if (trsf->task_control.handle_progress_func != NULL) {
for (isolid = 0; isolid < solid_count; ++isolid)
total_facet_count += geom->get_triangle_count_func(geom, isolid);
}
/* Write solids */
for (isolid = 0; isolid < solid_count && foug_datax_no_error(error); ++isolid) {
char solid_name[FOUG_STLA_SOLID_NAME_MAX_LEN];
const size_t facet_count = geom->get_triangle_count_func(geom, isolid);
size_t ifacet = 0;
/* Get current solid name */
if (geom->get_solid_name != NULL)
geom->get_solid_name(geom, isolid, solid_name);
else
sprintf(solid_name, "solid_%u", (unsigned int)isolid);
/* Write solid declaration */
solid_name[FOUG_STLA_SOLID_NAME_MAX_LEN - 1] = 0; /* Ensure string is null-terminated */
/* Write solid declaration */
{
buffer_iterator = foug_write_string(buffer_iterator, "solid ");
buffer_iterator = foug_write_string_eol(buffer_iterator, solid_name);
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
return FOUG_DATAX_STREAM_ERROR;
}
/* Write current solid's facets */
for (ifacet = 0;
ifacet < facet_count && foug_datax_no_error(error);
ifacet += buffer_facet_count)
{
foug_stl_triangle_t tri;
size_t ibuffer_facet;
/* Write solid's facets */
for (ifacet = 0;
ifacet < total_facet_count && foug_datax_no_error(error);
ifacet += buffer_facet_count)
{
const uint32_t clamped_facet_count = _FOUG_INTERNAL_MIN(ifacet + buffer_facet_count,
total_facet_count);
foug_stl_triangle_t tri;
uint32_t ibuffer_facet;
/* Writing of facets is buffered */
buffer_iterator = trsf->buffer;
for (ibuffer_facet = ifacet;
ibuffer_facet < (ifacet + buffer_facet_count);
++ibuffer_facet)
{
geom->get_triangle_func(geom, isolid, ibuffer_facet, &tri);
buffer_iterator = foug_write_string(buffer_iterator, "facet normal ");
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.normal);
buffer_iterator = foug_write_eol(buffer_iterator);
/* Writing of facets is buffered */
buffer_iterator = trsf->buffer;
for (ibuffer_facet = ifacet; ibuffer_facet < clamped_facet_count; ++ibuffer_facet) {
geom->get_triangle_func(geom->cookie, ibuffer_facet, &tri);
buffer_iterator = foug_write_string(buffer_iterator, "facet normal ");
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.normal);
buffer_iterator = foug_write_eol(buffer_iterator);
buffer_iterator = foug_write_string_eol(buffer_iterator, " outer loop");
buffer_iterator = foug_write_string(buffer_iterator, " vertex ");
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.v1);
buffer_iterator = foug_write_eol(buffer_iterator);
buffer_iterator = foug_write_string(buffer_iterator, " vertex ");
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.v2);
buffer_iterator = foug_write_eol(buffer_iterator);
buffer_iterator = foug_write_string(buffer_iterator, " vertex ");
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.v3);
buffer_iterator = foug_write_eol(buffer_iterator);
buffer_iterator = foug_write_string_eol(buffer_iterator, " endloop");
buffer_iterator = foug_write_string_eol(buffer_iterator, " outer loop");
buffer_iterator = foug_write_string(buffer_iterator, " vertex ");
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.v1);
buffer_iterator = foug_write_eol(buffer_iterator);
buffer_iterator = foug_write_string(buffer_iterator, " vertex ");
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.v2);
buffer_iterator = foug_write_eol(buffer_iterator);
buffer_iterator = foug_write_string(buffer_iterator, " vertex ");
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.v3);
buffer_iterator = foug_write_eol(buffer_iterator);
buffer_iterator = foug_write_string_eol(buffer_iterator, " endloop");
buffer_iterator = foug_write_string_eol(buffer_iterator, "endfacet");
} /* end for (ibuffer_facet) */
buffer_iterator = foug_write_string_eol(buffer_iterator, "endfacet");
} /* end for (ibuffer_facet) */
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
error = FOUG_DATAX_STREAM_ERROR;
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
error = FOUG_DATAX_STREAM_ERROR;
/* Task control */
if (foug_datax_no_error(error) && trsf->task_control.handle_progress_func != NULL) {
size_t percentage = 0;
written_facet_count += buffer_facet_count;
percentage = foug_percentage(0, total_facet_count, written_facet_count);
if (!foug_task_control_handle_progress(&trsf->task_control, percentage))
error = FOUG_DATAX_TASK_STOPPED_ERROR;
}
} /* end for (ifacet) */
/* Write end of solid */
if (foug_datax_no_error(error)) {
buffer_iterator = foug_write_string(trsf->buffer, "endsolid ");
buffer_iterator = foug_write_string_eol(buffer_iterator, solid_name);
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
error = FOUG_DATAX_STREAM_ERROR;
/* Task control */
if (foug_datax_no_error(error) && trsf->task_control.handle_progress_func != NULL) {
uint32_t percentage = 0;
written_facet_count += buffer_facet_count;
percentage = foug_percentage(0, total_facet_count, written_facet_count);
if (!foug_task_control_handle_progress(&trsf->task_control, percentage))
error = FOUG_DATAX_TASK_STOPPED_ERROR;
}
} /* end for (isolid) */
} /* end for (ifacet) */
/* Write end of solid */
if (foug_datax_no_error(error)) {
buffer_iterator = foug_write_string(trsf->buffer, "endsolid ");
buffer_iterator = foug_write_string_eol(buffer_iterator, solid_name);
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
error = FOUG_DATAX_STREAM_ERROR;
}
return error;
}

View File

@ -6,16 +6,13 @@
#include "../transfer.h"
/* Custom geometry expressed with STL ascii interface */
typedef struct foug_stla_geom_output foug_stla_geom_output_t;
struct foug_stla_geom_output
typedef struct foug_stla_geom_output
{
void* cookie;
size_t solid_count;
void (*get_solid_name) (const foug_stla_geom_output_t*, size_t, char*); /* Optional */
size_t (*get_triangle_count_func)(const foug_stla_geom_output_t*, size_t);
void (*get_triangle_func) (const foug_stla_geom_output_t*, size_t, size_t, foug_stl_triangle_t*);
};
const char* solid_name; /* May be NULL to generate default name */
uint32_t triangle_count;
const void* cookie;
void (*get_triangle_func)(const void*, uint32_t, foug_stl_triangle_t*);
} foug_stla_geom_output_t;
/* Write geometry in the STL ascii format */
FOUG_DATAX_LIBSTL_EXPORT int foug_stla_write(foug_stla_geom_output_t* geom,
@ -23,8 +20,7 @@ FOUG_DATAX_LIBSTL_EXPORT int foug_stla_write(foug_stla_geom_output_t* geom,
uint8_t real32_prec);
/* Specific error codes returned by foug_stla_write() */
#define FOUG_STLA_WRITE_NULL_GET_TRIANGLE_COUNT_FUNC 1 /*!< get_triangle_count_func is null */
#define FOUG_STLA_WRITE_NULL_GET_TRIANGLE_FUNC 2 /*!< get_triangle_func is null */
#define FOUG_STLA_WRITE_INVALID_REAL32_PRECISION 3 /*!< real32_prec is not in [1..9] */
#define FOUG_STLA_WRITE_NULL_GET_TRIANGLE_FUNC 1 /*!< get_triangle_func is null */
#define FOUG_STLA_WRITE_INVALID_REAL32_PRECISION 2 /*!< real32_prec is not in [1..9] */
#endif /* FOUG_DATAX_C_LIBSTL_STLA_WRITE_H */

View File

@ -6,6 +6,19 @@
#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)
{
/* *triangle = *((foug_stlb_triangle_t*)(buffer)); */
@ -27,10 +40,11 @@ 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,
uint8_t* buffer,
uint32_t facet_count,
uint32_t i_facet_offset)
const uint8_t* buffer,
const _internal_foug_read_params_helper* params)
{
const uint32_t facet_count = params->facet_count;
const uint32_t i_facet_offset = params->i_facet_offset;
foug_stlb_triangle_t triangle;
uint32_t buffer_offset;
uint32_t i_facet;
@ -49,7 +63,10 @@ static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom,
buffer_offset += FOUG_STLB_TRIANGLE_RAWSIZE;
/* Declare triangle */
geom->process_triangle_func(geom, &triangle, i_facet_offset + i_facet);
geom->process_triangle_func(geom->cookie,
i_facet_offset + i_facet,
&triangle.data,
triangle.attribute_byte_count);
}
}
@ -57,10 +74,11 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
foug_transfer_t* trsf,
foug_endianness_t byte_order)
{
uint32_t total_facet_count;
size_t accum_facet_count_read;
int error;
_internal_foug_read_params_helper read_params;
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)
@ -68,6 +86,11 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
if (byte_order != FOUG_LITTLE_ENDIAN)
return FOUG_STLB_READ_UNSUPPORTED_BYTE_ORDER;
/* 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;
/* Read header */
{
uint8_t header_data[FOUG_STLB_HEADER_SIZE];
@ -77,7 +100,7 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
return FOUG_STLB_READ_HEADER_WRONG_SIZE_ERROR;
}
if (geom != NULL && geom->process_header_func != NULL)
geom->process_header_func(geom, header_data);
geom->process_header_func(geom->cookie, header_data);
}
/* Read facet count */
@ -86,19 +109,19 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
total_facet_count = foug_decode_uint32_le(trsf->buffer);
if (geom != NULL && geom->begin_triangles_func != NULL)
geom->begin_triangles_func(geom, total_facet_count);
geom->begin_triangles_func(geom->cookie, total_facet_count);
/* Read triangles */
accum_facet_count_read = 0;
error = FOUG_DATAX_NO_ERROR;
while (foug_datax_no_error(error) && accum_facet_count_read < total_facet_count) {
const size_t facet_count_read = foug_stream_read(&trsf->stream,
trsf->buffer,
FOUG_STLB_TRIANGLE_RAWSIZE,
trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE);
while (foug_datax_no_error(error)
&& read_params.i_facet_offset < total_facet_count)
{
read_params.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 (facet_count_read > 0)
else if (read_params.facet_count > 0)
error = FOUG_DATAX_NO_ERROR;
else
break; /* Exit if no facet to read */
@ -106,9 +129,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, facet_count_read, accum_facet_count_read);
accum_facet_count_read += facet_count_read;
progress_pc = foug_percentage(0, total_facet_count, accum_facet_count_read);
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);
if (!foug_task_control_handle_progress(&trsf->task_control, progress_pc))
error = FOUG_DATAX_TASK_STOPPED_ERROR;
}
@ -117,10 +140,10 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
if (foug_datax_no_error(error)
&& geom != NULL && geom->end_triangles_func != NULL)
{
geom->end_triangles_func(geom);
geom->end_triangles_func(geom->cookie);
}
if (foug_datax_no_error(error) && accum_facet_count_read != total_facet_count)
if (foug_datax_no_error(error) && read_params.i_facet_offset != total_facet_count)
error = FOUG_STLB_READ_FACET_COUNT_ERROR;
return error;
}

View File

@ -7,15 +7,17 @@
#include "../transfer.h"
/* foug_stlb_geom_input */
typedef struct foug_stlb_geom_input foug_stlb_geom_input_t;
struct foug_stlb_geom_input
typedef struct
{
void* cookie;
void (*process_header_func) (foug_stlb_geom_input_t*, const uint8_t*); /* Optional */
void (*begin_triangles_func) (foug_stlb_geom_input_t*, uint32_t); /* Optional */
void (*process_triangle_func)(foug_stlb_geom_input_t*, const foug_stlb_triangle_t*, uint32_t);
void (*end_triangles_func) (foug_stlb_geom_input_t*); /* Optional */
};
/* All function pointers can be safely set to NULL */
void (*process_header_func) (void*, const uint8_t*);
void (*begin_triangles_func) (void*, uint32_t);
void (*process_triangle_func)(void*, uint32_t, const foug_stl_triangle_t*, uint16_t);
void (*end_triangles_func) (void*);
} foug_stlb_geom_input_t;
typedef void (*foug_stlb_begin_triangles_func_t)(void*, uint32_t);
typedef void (*foug_stlb_process_triangle_func_t)(void*, uint32_t, const foug_stl_triangle_t*, uint16_t);
/* foug_stlb_read() */
FOUG_DATAX_LIBSTL_EXPORT int foug_stlb_read(foug_stlb_geom_input_t* geom,

View File

@ -35,9 +35,12 @@ static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom,
if (geom == NULL || geom->get_triangle_func == NULL)
return;
triangle.attribute_byte_count = 0;
buffer_offset = 0;
for (i_facet = ifacet_start; i_facet < (ifacet_start + facet_count); ++i_facet) {
geom->get_triangle_func(geom, i_facet, &triangle);
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);
#ifdef FOUG_STLB_READWRITE_ALIGNSAFE
write_triangle_alignsafe(&triangle, buffer + buffer_offset);

View File

@ -6,15 +6,14 @@
#include "../endian.h"
#include "../transfer.h"
/* foug_stlb_geom_output */
typedef struct foug_stlb_geom_output foug_stlb_geom_output_t;
struct foug_stlb_geom_output
typedef struct
{
void* cookie;
uint8_t* header; /* May be NULL if empty header*/
uint32_t triangle_count;
void (*get_triangle_func)(const foug_stlb_geom_output_t*, uint32_t, foug_stlb_triangle_t*);
};
const uint8_t* header; /* May be NULL if empty header */
uint32_t triangle_count;
const void* cookie;
void (*get_triangle_func)(const void*, uint32_t, foug_stl_triangle_t*);
void (*get_attr_byte_count_func)(const void*, uint16_t*); /* Optional : may be NULL */
} foug_stlb_geom_output_t;
/* foug_stlb_write() */
FOUG_DATAX_LIBSTL_EXPORT int foug_stlb_write(const foug_stlb_geom_output_t* geom,

View File

@ -12,30 +12,30 @@ void foug_stream_set_null(foug_stream_t* stream)
memset(stream, 0, sizeof(foug_stream_t));
}
static foug_bool_t foug_stream_stdio_at_end(foug_stream_t* stream)
static foug_bool_t foug_stream_stdio_at_end(void* cookie)
{
return feof((FILE*) stream->cookie);
return feof((FILE*) cookie);
}
static int32_t foug_stream_stdio_error(foug_stream_t* stream)
static int32_t foug_stream_stdio_error(void* cookie)
{
return ferror((FILE*) stream->cookie);
return ferror((FILE*) cookie);
}
static size_t foug_stream_stdio_read(foug_stream_t* stream,
static size_t foug_stream_stdio_read(void* cookie,
void* ptr,
size_t item_size,
size_t item_count)
{
return fread(ptr, item_size, item_count, (FILE*) stream->cookie);
return fread(ptr, item_size, item_count, (FILE*) cookie);
}
static size_t foug_stream_stdio_write(foug_stream_t* stream,
static size_t foug_stream_stdio_write(void* cookie,
const void* ptr,
size_t item_size,
size_t item_count)
{
return fwrite(ptr, item_size, item_count, (FILE*) stream->cookie);
return fwrite(ptr, item_size, item_count, (FILE*) cookie);
}
/*!
@ -56,7 +56,7 @@ void foug_stream_set_stdio(foug_stream_t* stream, FILE* file)
foug_bool_t foug_stream_at_end(foug_stream_t* stream)
{
if (stream != NULL && stream->at_end_func != NULL)
return stream->at_end_func(stream);
return stream->at_end_func(stream->cookie);
return 0;
}
@ -71,7 +71,7 @@ foug_bool_t foug_stream_at_end(foug_stream_t* stream)
int foug_stream_error(foug_stream_t* stream)
{
if (stream != NULL && stream->error_func != NULL)
return stream->error_func(stream);
return stream->error_func(stream->cookie);
return 0;
}
@ -93,7 +93,7 @@ int foug_stream_error(foug_stream_t* stream)
size_t foug_stream_read(foug_stream_t* stream, void *ptr, size_t item_size, size_t item_count)
{
if (stream != NULL && stream->read_func != NULL)
return stream->read_func(stream, ptr, item_size, item_count);
return stream->read_func(stream->cookie, ptr, item_size, item_count);
return 0;
}
@ -108,6 +108,6 @@ size_t foug_stream_read(foug_stream_t* stream, void *ptr, size_t item_size, size
size_t foug_stream_write(foug_stream_t* stream, const void *ptr, size_t item_size, size_t item_count)
{
if (stream != NULL && stream->write_func != NULL)
return stream->write_func(stream, ptr, item_size, item_count);
return stream->write_func(stream->cookie, ptr, item_size, item_count);
return 0;
}

View File

@ -5,8 +5,6 @@
#include "memory.h"
#include <stdio.h>
typedef struct foug_stream foug_stream_t;
/*! \brief Stream that can get input from an arbitrary data source or can write output to an
* arbitrary data sink
*
@ -18,15 +16,15 @@ typedef struct foug_stream foug_stream_t;
* implemented by defining hook functions that know how to read/write the data.
*
*/
struct foug_stream
typedef struct
{
void* cookie;
foug_bool_t (*at_end_func)(foug_stream_t*);
int32_t (*error_func)(foug_stream_t*);
size_t (*read_func)(foug_stream_t*, void*, size_t, size_t);
size_t (*write_func)(foug_stream_t*, const void*, size_t, size_t);
};
foug_bool_t (*at_end_func)(void*);
int32_t (*error_func)(void*);
size_t (*read_func)(void*, void*, size_t, size_t);
size_t (*write_func)(void*, const void*, size_t, size_t);
} foug_stream_t;
/* Initialization */

View File

@ -6,121 +6,108 @@
#include <StlMesh_SequenceOfMeshTriangle.hxx>
#include <TColgp_SequenceOfXYZ.hxx>
namespace internal {
/* Common */
static void occ_mesh_stl_add_triangle(Handle_StlMesh_Mesh* mesh, const foug_stl_triangle_t* tri)
static StlMesh_Mesh* occMeshPtr(const Handle_StlMesh_Mesh& mesh)
{
const int uId = (*mesh)->AddOnlyNewVertex(tri->v1.x, tri->v1.y, tri->v1.z);
const int vId = (*mesh)->AddOnlyNewVertex(tri->v2.x, tri->v2.y, tri->v2.z);
const int wId = (*mesh)->AddOnlyNewVertex(tri->v3.x, tri->v3.y, tri->v3.z);
(*mesh)->AddTriangle(uId, vId, wId, tri->normal.x, tri->normal.y, tri->normal.z);
return mesh.operator->();
}
/* ASCII STL */
static void occ_mesh_stla_igeom_begin_solid(foug_stla_geom_input_t* geom, const char* /*name*/)
static void occmesh_add_triangle(void* cookie,
uint32_t /*tri_id*/,
const foug_stl_triangle_t* tri,
void* /*dummy*/)
{
Handle_StlMesh_Mesh* mesh = static_cast<Handle_StlMesh_Mesh*>(geom->cookie);
if (mesh->IsNull())
*mesh = new StlMesh_Mesh;
(*mesh)->AddDomain();
StlMesh_Mesh* mesh = static_cast<StlMesh_Mesh*>(cookie);
const int uId = mesh->AddOnlyNewVertex(tri->v1.x, tri->v1.y, tri->v1.z);
const int vId = mesh->AddOnlyNewVertex(tri->v2.x, tri->v2.y, tri->v2.z);
const int wId = mesh->AddOnlyNewVertex(tri->v3.x, tri->v3.y, tri->v3.z);
mesh->AddTriangle(uId, vId, wId, tri->normal.x, tri->normal.y, tri->normal.z);
}
static void occ_mesh_stla_igeom_process_next_triangle(foug_stla_geom_input_t* geom,
const foug_stl_triangle_t* tri)
static void occmesh_get_triangle(const void* cookie,
uint32_t tri_id,
foug_stl_triangle_t* triangle)
{
Handle_StlMesh_Mesh* mesh = static_cast<Handle_StlMesh_Mesh*>(geom->cookie);
occ_mesh_stl_add_triangle(mesh, tri);
}
void foug_stla_geom_input_set_occmesh(foug_stla_geom_input_t* input, Handle_StlMesh_Mesh* mesh)
{
input->cookie = mesh;
input->begin_solid_func = occ_mesh_stla_igeom_begin_solid;
input->process_next_triangle_func = occ_mesh_stla_igeom_process_next_triangle;
input->end_solid_func = NULL;
}
/* Binary STL */
static void occ_mesh_stlb_igeom_begin_triangles(foug_stlb_geom_input_t* geom, uint32_t /*count*/)
{
Handle_StlMesh_Mesh* mesh = static_cast<Handle_StlMesh_Mesh*>(geom->cookie);
*mesh = new StlMesh_Mesh;
(*mesh)->AddDomain();
}
static void occ_mesh_stlb_igeom_process_next_triangle(foug_stlb_geom_input_t* geom,
const foug_stlb_triangle_t* face)
{
Handle_StlMesh_Mesh* mesh = static_cast<Handle_StlMesh_Mesh*>(geom->cookie);
occ_mesh_stl_add_triangle(mesh, &(face->data));
}
void foug_stlb_geom_input_set_occmesh(foug_stlb_geom_input_t* input, Handle_StlMesh_Mesh* mesh)
{
input->cookie = mesh;
input->process_header_func = NULL;
input->begin_triangles_func = occ_mesh_stlb_igeom_begin_triangles;
input->process_next_triangle_func = occ_mesh_stlb_igeom_process_next_triangle;
input->end_triangles_func = NULL;
}
static void occ_mesh_stlb_ogeom_get_header(const foug_stlb_geom_output_t* /*geom*/, uint8_t* header)
{
std::memcpy(header, "Generated by libfougdatax-c", FOUG_STLB_HEADER_SIZE);
}
static uint32_t occ_mesh_stlb_ogeom_get_triangle_count(const foug_stlb_geom_output_t* geom)
{
Handle_StlMesh_Mesh* mesh = static_cast<Handle_StlMesh_Mesh*>(geom->cookie);
if ((*mesh)->NbDomains() >= 1)
return (*mesh)->NbTriangles(1);
return 0;
}
static void occ_mesh_stlb_ogeom_get_triangle(const foug_stlb_geom_output_t* geom,
uint32_t index,
foug_stlb_triangle_t* facet)
{
Handle_StlMesh_Mesh* mesh = static_cast<Handle_StlMesh_Mesh*>(geom->cookie);
const StlMesh_SequenceOfMeshTriangle& meshTriangles = (*mesh)->Triangles(1);
const Handle_StlMesh_MeshTriangle& tri = meshTriangles.Value(index + 1);
const foug_OccStlMeshDomain* meshCookie = static_cast<const foug_OccStlMeshDomain*>(cookie);
const StlMesh_SequenceOfMeshTriangle& occTriangles = meshCookie->mesh->Triangles(meshCookie->domainId);
const Handle_StlMesh_MeshTriangle& occTri = occTriangles.Value(tri_id + 1);
Standard_Integer v1;
Standard_Integer v2;
Standard_Integer v3;
Standard_Real xN;
Standard_Real yN;
Standard_Real zN;
tri->GetVertexAndOrientation(v1, v2, v3, xN, yN, zN);
facet->data.normal.x = static_cast<foug_real32_t>(xN);
facet->data.normal.y = static_cast<foug_real32_t>(yN);
facet->data.normal.z = static_cast<foug_real32_t>(zN);
occTri->GetVertexAndOrientation(v1, v2, v3, xN, yN, zN);
triangle->normal.x = float(xN);
triangle->normal.y = float(yN);
triangle->normal.z = float(zN);
const TColgp_SequenceOfXYZ& vertices = (*mesh)->Vertices(1);
const TColgp_SequenceOfXYZ& vertices = meshCookie->mesh->Vertices(meshCookie->domainId);
const gp_XYZ& coordsV1 = vertices.Value(v1);
const gp_XYZ& coordsV2 = vertices.Value(v2);
const gp_XYZ& coordsV3 = vertices.Value(v3);
facet->data.v1.x = static_cast<foug_real32_t>(coordsV1.X());
facet->data.v2.x = static_cast<foug_real32_t>(coordsV2.X());
facet->data.v3.x = static_cast<foug_real32_t>(coordsV3.X());
triangle->v1.x = float(coordsV1.X());
triangle->v2.x = float(coordsV2.X());
triangle->v3.x = float(coordsV3.X());
facet->data.v1.y = static_cast<foug_real32_t>(coordsV1.Y());
facet->data.v2.y = static_cast<foug_real32_t>(coordsV2.Y());
facet->data.v3.y = static_cast<foug_real32_t>(coordsV3.Y());
triangle->v1.y = float(coordsV1.Y());
triangle->v2.y = float(coordsV2.Y());
triangle->v3.y = float(coordsV3.Y());
facet->data.v1.z = static_cast<foug_real32_t>(coordsV1.Z());
facet->data.v2.z = static_cast<foug_real32_t>(coordsV2.Z());
facet->data.v3.z = static_cast<foug_real32_t>(coordsV3.Z());
facet->attribute_byte_count = 0;
triangle->v1.z = float(coordsV1.Z());
triangle->v2.z = float(coordsV2.Z());
triangle->v3.z = float(coordsV3.Z());
}
void foug_stlb_geom_output_set_occmesh(foug_stlb_geom_output_t* output, Handle_StlMesh_Mesh* mesh)
static void occmesh_add_domain(void* cookie, void* /*dummy*/)
{
StlMesh_Mesh* mesh = static_cast<StlMesh_Mesh*>(cookie);
mesh->AddDomain();
}
} // namespace internal
void foug_stla_geom_input_set_occmesh(foug_stla_geom_input_t* input, const Handle_StlMesh_Mesh &mesh)
{
input->cookie = internal::occMeshPtr(mesh);
input->begin_solid_func = (foug_stla_begin_solid_func_t)internal::occmesh_add_domain;
input->process_triangle_func = (foug_stla_process_triangle_func_t)internal::occmesh_add_triangle;
input->end_solid_func = NULL;
}
void foug_stla_geom_output_set_occmesh(foug_stla_geom_output_t *output,
const foug_OccStlMeshDomain &meshCookie)
{
output->cookie = &meshCookie;
output->solid_name = NULL;
output->triangle_count = meshCookie.mesh->NbTriangles(meshCookie.domainId);
output->get_triangle_func = internal::occmesh_get_triangle;
}
void foug_stlb_geom_input_set_occmesh(foug_stlb_geom_input_t* input, const Handle_StlMesh_Mesh &mesh)
{
input->cookie = internal::occMeshPtr(mesh);
input->process_header_func = NULL;
input->begin_triangles_func = (foug_stlb_begin_triangles_func_t)internal::occmesh_add_domain;
input->process_triangle_func = (foug_stlb_process_triangle_func_t)internal::occmesh_add_triangle;
input->end_triangles_func = NULL;
}
void foug_stlb_geom_output_set_occmesh(foug_stlb_geom_output_t* output,
const foug_OccStlMeshDomain &meshCookie)
{
static const char occMeshBinaryHeader[] = "Generated by libfougdatax, occmesh geometry";
output->cookie = &meshCookie;
output->header = reinterpret_cast<const uint8_t*>(occMeshBinaryHeader);
output->triangle_count = meshCookie.mesh->NbTriangles(meshCookie.domainId);
output->get_triangle_func = internal::occmesh_get_triangle;
}
foug_OccStlMeshDomain::foug_OccStlMeshDomain(const Handle_StlMesh_Mesh &stlMesh, int stlDomainId)
: mesh(stlMesh),
domainId(stlDomainId)
{
output->cookie = mesh;
output->get_header_func = occ_mesh_stlb_ogeom_get_header;
output->get_triangle_count_func = occ_mesh_stlb_ogeom_get_triangle_count;
output->get_triangle_func = occ_mesh_stlb_ogeom_get_triangle;
}

View File

@ -8,23 +8,33 @@ extern "C" {
#include "../libstl/stlb_read.h"
#include "../libstl/stlb_write.h"
}
#include <Handle_StlMesh_Mesh.hxx>
class Handle_StlMesh_Mesh;
struct FOUG_LIBSUPPORT_EXPORT foug_OccStlMeshDomain
{
foug_OccStlMeshDomain(const Handle_StlMesh_Mesh& stlMesh, int stlDomainId = 1);
Handle_StlMesh_Mesh mesh;
int domainId;
};
/* ASCII STL */
FOUG_LIBSUPPORT_EXPORT
void foug_stla_geom_input_set_occmesh(foug_stla_geom_input_t* input, Handle_StlMesh_Mesh* mesh);
void foug_stla_geom_input_set_occmesh(foug_stla_geom_input_t* input,
const Handle_StlMesh_Mesh& mesh);
FOUG_LIBSUPPORT_EXPORT
void foug_stla_geom_output_set_occmesh(foug_stla_geom_output_t* output, Handle_StlMesh_Mesh* mesh);
void foug_stla_geom_output_set_occmesh(foug_stla_geom_output_t* output,
const foug_OccStlMeshDomain& meshCookie);
/* Binary STL */
FOUG_LIBSUPPORT_EXPORT
void foug_stlb_geom_input_set_occmesh(foug_stlb_geom_input_t* input, Handle_StlMesh_Mesh* mesh);
void foug_stlb_geom_input_set_occmesh(foug_stlb_geom_input_t* input,
const Handle_StlMesh_Mesh& mesh);
FOUG_LIBSUPPORT_EXPORT
void foug_stlb_geom_output_set_occmesh(foug_stlb_geom_output_t* output, Handle_StlMesh_Mesh* mesh);
void foug_stlb_geom_output_set_occmesh(foug_stlb_geom_output_t* output,
const foug_OccStlMeshDomain& meshCookie);
#endif /* FOUG_SUPPORT_OCC_LIBSTL_H */

View File

@ -3,41 +3,41 @@
#include <QtCore/QFile>
#include <QtCore/QIODevice>
static foug_bool_t foug_stream_qiodevice_at_end(foug_stream_t* stream)
static foug_bool_t foug_stream_qiodevice_at_end(void* cookie)
{
return static_cast<QIODevice*>(stream->cookie)->atEnd();
return static_cast<QIODevice*>(cookie)->atEnd();
}
static int32_t foug_stream_qiodevice_error(foug_stream_t* stream)
static int32_t foug_stream_qiodevice_error(void* cookie)
{
const QIODevice* device = static_cast<QIODevice*>(stream->cookie);
const QIODevice* device = static_cast<QIODevice*>(cookie);
const QFile* file = dynamic_cast<const QFile*>(device);
if (file != NULL) {
return file->error();
}
else {
const QString err_str = static_cast<QIODevice*>(stream->cookie)->errorString();
const QString err_str = static_cast<QIODevice*>(cookie)->errorString();
return !err_str.isEmpty() ? 1 : 0;
}
return 0;
}
static size_t foug_stream_qiodevice_read(foug_stream_t* stream,
static size_t foug_stream_qiodevice_read(void* cookie,
void* ptr,
size_t item_size,
size_t item_count)
{
QIODevice* device = static_cast<QIODevice*>(stream->cookie);
QIODevice* device = static_cast<QIODevice*>(cookie);
const qint64 c = device->read(static_cast<char*>(ptr), item_size * item_count);
return c / item_size;
}
static size_t foug_stream_qiodevice_write(foug_stream_t* stream,
static size_t foug_stream_qiodevice_write(void* cookie,
const void* ptr,
size_t item_size,
size_t item_count)
{
QIODevice* device = static_cast<QIODevice*>(stream->cookie);
QIODevice* device = static_cast<QIODevice*>(cookie);
const qint64 c = device->write(static_cast<const char*>(ptr), item_size * item_count);
return c / item_size;
}

View File

@ -13,7 +13,7 @@
foug_bool_t foug_task_control_handle_progress(foug_task_control_t* ctrl, uint8_t progress_pc)
{
if (ctrl != NULL && ctrl->handle_progress_func != NULL)
return ctrl->handle_progress_func(ctrl, progress_pc);
return ctrl->handle_progress_func(ctrl->cookie, progress_pc);
return 1;
}

View File

@ -4,13 +4,11 @@
#include "global.h"
#include "memory.h"
/* foug_task_control */
typedef struct foug_task_control foug_task_control_t;
struct foug_task_control
typedef struct foug_task_control
{
void* cookie;
foug_bool_t (*handle_progress_func)(foug_task_control_t*, uint8_t);
};
foug_bool_t (*handle_progress_func)(void*, uint8_t);
} foug_task_control_t;
FOUG_LIB_EXPORT
foug_bool_t foug_task_control_handle_progress(foug_task_control_t* ctrl, uint8_t progress_pc);