Simplify cookie mechanism
This commit is contained in:
parent
90f5f084f6
commit
11d5668d4b
@ -54,7 +54,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* foug_stream_fwd_iterator */
|
/* foug_stream_fwd_iterator */
|
||||||
struct foug_stream_fwd_iterator
|
typedef struct
|
||||||
{
|
{
|
||||||
foug_stream_t* stream;
|
foug_stream_t* stream;
|
||||||
char* buffer;
|
char* buffer;
|
||||||
@ -62,31 +62,25 @@ struct foug_stream_fwd_iterator
|
|||||||
uint32_t buffer_size;
|
uint32_t buffer_size;
|
||||||
|
|
||||||
void* cookie;
|
void* cookie;
|
||||||
void (*stream_read_hook)(struct foug_stream_fwd_iterator* it);
|
void (*stream_read_hook)(void*, const char*, uint32_t);
|
||||||
};
|
} foug_stream_fwd_iterator_t;
|
||||||
typedef struct foug_stream_fwd_iterator
|
|
||||||
foug_stream_fwd_iterator_t;
|
|
||||||
|
|
||||||
/* foug_string_buffer */
|
/* foug_string_buffer */
|
||||||
struct foug_string_buffer
|
typedef struct
|
||||||
{
|
{
|
||||||
char* data;
|
char* data;
|
||||||
size_t max_len;
|
size_t max_len;
|
||||||
size_t len;
|
size_t len;
|
||||||
};
|
} foug_string_buffer_t;
|
||||||
typedef struct foug_string_buffer
|
|
||||||
foug_string_buffer_t;
|
|
||||||
|
|
||||||
/* foug_stream_fwd_iterator_stla_cookie */
|
/* foug_stream_fwd_iterator_stla_cookie */
|
||||||
struct foug_stream_fwd_iterator_stla_cookie
|
typedef struct
|
||||||
{
|
{
|
||||||
foug_task_control_t* task_control;
|
foug_task_control_t* task_control;
|
||||||
size_t stream_data_size;
|
size_t stream_data_size;
|
||||||
size_t stream_offset;
|
size_t stream_offset;
|
||||||
foug_bool_t is_stop_requested;
|
foug_bool_t is_stop_requested;
|
||||||
};
|
} foug_stream_fwd_iterator_stla_cookie_t;
|
||||||
typedef struct foug_stream_fwd_iterator_stla_cookie
|
|
||||||
foug_stream_fwd_iterator_stla_cookie_t;
|
|
||||||
|
|
||||||
/* foug_stla_token */
|
/* foug_stla_token */
|
||||||
enum foug_stla_token
|
enum foug_stla_token
|
||||||
@ -107,7 +101,7 @@ enum foug_stla_token
|
|||||||
typedef enum foug_stla_token foug_stla_token_t;
|
typedef enum foug_stla_token foug_stla_token_t;
|
||||||
|
|
||||||
/* foug_stla_parse_data */
|
/* foug_stla_parse_data */
|
||||||
struct foug_stla_parse_data
|
typedef struct
|
||||||
{
|
{
|
||||||
foug_stla_token_t token;
|
foug_stla_token_t token;
|
||||||
foug_bool_t error;
|
foug_bool_t error;
|
||||||
@ -115,18 +109,17 @@ struct foug_stla_parse_data
|
|||||||
foug_stream_fwd_iterator_stla_cookie_t stream_iterator_cookie;
|
foug_stream_fwd_iterator_stla_cookie_t stream_iterator_cookie;
|
||||||
foug_string_buffer_t string_buffer;
|
foug_string_buffer_t string_buffer;
|
||||||
foug_stla_geom_input_t* geom;
|
foug_stla_geom_input_t* geom;
|
||||||
};
|
} foug_stla_parse_data_t;
|
||||||
typedef struct foug_stla_parse_data
|
|
||||||
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 =
|
foug_stream_fwd_iterator_stla_cookie_t* tcookie = (foug_stream_fwd_iterator_stla_cookie_t*)(cookie);
|
||||||
it != NULL ? (foug_stream_fwd_iterator_stla_cookie_t*)(it->cookie) : NULL;
|
if (tcookie != NULL) {
|
||||||
if (cookie != NULL) {
|
const uint8_t progress_pc = foug_percentage(0, tcookie->stream_data_size, tcookie->stream_offset);
|
||||||
const uint8_t progress_pc = foug_percentage(0, cookie->stream_data_size, cookie->stream_offset);
|
tcookie->is_stop_requested = !foug_task_control_handle_progress(tcookie->task_control, progress_pc);
|
||||||
cookie->is_stop_requested = !foug_task_control_handle_progress(cookie->task_control, progress_pc);
|
tcookie->stream_offset += buffer_len;
|
||||||
cookie->stream_offset += it->buffer_size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +157,7 @@ static char* next_char(foug_stream_fwd_iterator_t* it)
|
|||||||
it->buffer_offset = 0;
|
it->buffer_offset = 0;
|
||||||
it->buffer_size = char_count_read;
|
it->buffer_size = char_count_read;
|
||||||
if (it->stream_read_hook != NULL)
|
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;
|
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)
|
static int eat_string(foug_stream_fwd_iterator_t* it, foug_string_buffer_t* str_buffer)
|
||||||
{
|
{
|
||||||
size_t i;
|
const char* stream_curr_char = NULL;
|
||||||
const char* stream_curr_char;
|
int isspace_res = 0;
|
||||||
int isspace_res;
|
size_t i = 0;
|
||||||
|
|
||||||
if (str_buffer == NULL || str_buffer->data == NULL || str_buffer->max_len == 0)
|
if (str_buffer == NULL || str_buffer->data == NULL || str_buffer->max_len == 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -196,11 +189,9 @@ static int eat_string(foug_stream_fwd_iterator_t* it, foug_string_buffer_t* str_
|
|||||||
skip_spaces(it);
|
skip_spaces(it);
|
||||||
stream_curr_char = current_char(it);
|
stream_curr_char = current_char(it);
|
||||||
|
|
||||||
isspace_res = 0;
|
while (i < str_buffer->max_len && stream_curr_char != NULL && isspace_res == 0) {
|
||||||
i = 0;
|
|
||||||
while (i < str_buffer->max_len && stream_curr_char != NULL && !isspace_res) {
|
|
||||||
isspace_res = isspace(*stream_curr_char);
|
isspace_res = isspace(*stream_curr_char);
|
||||||
if (!isspace_res) {
|
if (isspace_res == 0) {
|
||||||
str_buffer->data[i] = *stream_curr_char;
|
str_buffer->data[i] = *stream_curr_char;
|
||||||
stream_curr_char = next_char(it);
|
stream_curr_char = next_char(it);
|
||||||
++i;
|
++i;
|
||||||
@ -221,10 +212,14 @@ static int get_real32(const char* str, foug_real32_t* value_ptr)
|
|||||||
{
|
{
|
||||||
char* end_ptr; /* for strtod() */
|
char* end_ptr; /* for strtod() */
|
||||||
|
|
||||||
|
/* printf("DEBUG get_real32(): ");
|
||||||
|
fflush(stdout);
|
||||||
|
printf("str=\"%s\"\n", str);*/
|
||||||
#ifdef FOUG_HAVE_STRTOF_FUNC
|
#ifdef FOUG_HAVE_STRTOF_FUNC
|
||||||
*value_ptr = strtof(str, &end_ptr); /* Requires C99 */
|
*value_ptr = strtof(str, &end_ptr); /* Requires C99 */
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
if (end_ptr == str || errno == ERANGE)
|
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);
|
parsing_eat_token(SOLID_token, data);
|
||||||
parse_solidname_beg(data);
|
parse_solidname_beg(data);
|
||||||
if (parsing_can_continue(data) && data->geom != NULL && data->geom->begin_solid_func != NULL)
|
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)
|
if (data->token == ID_token)
|
||||||
parsing_eat_token(ID_token, data);
|
parsing_eat_token(ID_token, data);
|
||||||
break;
|
break;
|
||||||
@ -401,7 +396,7 @@ static void parse_endsolid(foug_stla_parse_data_t* data)
|
|||||||
parsing_eat_token(ENDSOLID_token, data);
|
parsing_eat_token(ENDSOLID_token, data);
|
||||||
parse_solidname_end(data);
|
parse_solidname_end(data);
|
||||||
if (parsing_can_continue(data) && data->geom != NULL && data->geom->end_solid_func != NULL)
|
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)
|
if (data->token == ID_token)
|
||||||
parsing_eat_token(ID_token, data);
|
parsing_eat_token(ID_token, data);
|
||||||
break;
|
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 != NULL
|
||||||
&& data->geom->process_triangle_func != 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);
|
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
|
#define FOUG_STLA_READ_STRING_BUFFER_LEN 512
|
||||||
|
|
||||||
int foug_stla_read(foug_stla_geom_input_t* geom,
|
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;
|
parse_data.geom = geom;
|
||||||
|
|
||||||
parsing_advance(&parse_data);
|
parsing_advance(&parse_data);
|
||||||
parse_contents(&parse_data);
|
parse_solid(&parse_data);
|
||||||
|
|
||||||
if (parse_data.error)
|
if (parse_data.error)
|
||||||
return FOUG_STLA_READ_PARSE_ERROR;
|
return FOUG_STLA_READ_PARSE_ERROR;
|
||||||
|
@ -6,14 +6,15 @@
|
|||||||
#include "../transfer.h"
|
#include "../transfer.h"
|
||||||
|
|
||||||
/* foug_stla_geom_input */
|
/* foug_stla_geom_input */
|
||||||
typedef struct foug_stla_geom_input foug_stla_geom_input_t;
|
typedef struct
|
||||||
struct foug_stla_geom_input
|
|
||||||
{
|
{
|
||||||
void* cookie;
|
void* cookie;
|
||||||
void (*begin_solid_func) (foug_stla_geom_input_t*, const char*); /* Optional */
|
void (*begin_solid_func) (void*, const char*); /* Optional */
|
||||||
void (*process_triangle_func)(foug_stla_geom_input_t*, const foug_stl_triangle_t*, uint32_t);
|
void (*process_triangle_func)(void*, uint32_t, const foug_stl_triangle_t*);
|
||||||
void (*end_solid_func) (foug_stla_geom_input_t*, const char*); /* Optional */
|
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_stla_read() */
|
||||||
FOUG_DATAX_LIBSTL_EXPORT int foug_stla_read(foug_stla_geom_input_t* geom,
|
FOUG_DATAX_LIBSTL_EXPORT int foug_stla_read(foug_stla_geom_input_t* geom,
|
||||||
|
@ -53,16 +53,17 @@ static char* foug_write_eol(char* buffer)
|
|||||||
return buffer + 1;
|
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)
|
while (n > 0)
|
||||||
buffer[--n] = ' ';
|
*(buffer + (--n)) = ' ';
|
||||||
return buffer + n;
|
return buffer + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* foug_write_stdio_format(char* buffer, uint8_t prec)
|
static char* foug_write_stdio_format(char* buffer, uint8_t prec)
|
||||||
{
|
{
|
||||||
size_t prec_len = 0 ;
|
int prec_len = 0;
|
||||||
|
|
||||||
buffer[0] = '%';
|
buffer[0] = '%';
|
||||||
buffer[1] = '.';
|
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;
|
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
|
/*! \brief Write geometry in the STL ascii format
|
||||||
*
|
*
|
||||||
* \param geom Defines the custom geometry to write
|
* \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_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_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_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_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_STREAM_ERROR For any writing error
|
||||||
* \retval FOUG_DATAX_TASK_STOPPED_ERROR If the operation was interrupted foug_task_control
|
* \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,
|
foug_transfer_t* trsf,
|
||||||
uint8_t real32_prec)
|
uint8_t real32_prec)
|
||||||
{
|
{
|
||||||
const size_t solid_count = geom != NULL ? geom->solid_count : 0;
|
const char* solid_name = geom != NULL && geom->solid_name != NULL ? geom->solid_name : "";
|
||||||
size_t total_facet_count = 0;
|
const uint32_t total_facet_count = geom != NULL ? geom->triangle_count : 0;
|
||||||
size_t written_facet_count = 0;
|
uint32_t written_facet_count = 0;
|
||||||
size_t isolid = 0;
|
const uint32_t buffer_facet_count = trsf != NULL ? trsf->buffer_size / FOUG_STLA_FACET_SIZE_P2 : 0;
|
||||||
const size_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* buffer_iterator = trsf != NULL ? trsf->buffer : NULL;
|
||||||
char coords_format[64];
|
char coords_format[64];
|
||||||
int error = FOUG_DATAX_NO_ERROR;
|
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;
|
return FOUG_DATAX_NULL_BUFFER_ERROR;
|
||||||
if (trsf->buffer_size < FOUG_STLA_FACET_SIZE_P2)
|
if (trsf->buffer_size < FOUG_STLA_FACET_SIZE_P2)
|
||||||
return FOUG_DATAX_INVALID_BUFFER_SIZE_ERROR;
|
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)
|
if (geom->get_triangle_func == NULL)
|
||||||
return FOUG_STLA_WRITE_NULL_GET_TRIANGLE_FUNC;
|
return FOUG_STLA_WRITE_NULL_GET_TRIANGLE_FUNC;
|
||||||
|
|
||||||
@ -136,49 +136,32 @@ 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_stdio_format(coords_format_iterator, real32_prec);
|
||||||
coords_format_iterator = foug_write_nspaces(coords_format_iterator, 2);
|
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 = 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 */
|
/* 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 */
|
/* Write solid declaration */
|
||||||
solid_name[FOUG_STLA_SOLID_NAME_MAX_LEN - 1] = 0; /* Ensure string is null-terminated */
|
{
|
||||||
buffer_iterator = foug_write_string(buffer_iterator, "solid ");
|
buffer_iterator = foug_write_string(buffer_iterator, "solid ");
|
||||||
buffer_iterator = foug_write_string_eol(buffer_iterator, solid_name);
|
buffer_iterator = foug_write_string_eol(buffer_iterator, solid_name);
|
||||||
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
|
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
|
||||||
return FOUG_DATAX_STREAM_ERROR;
|
return FOUG_DATAX_STREAM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write current solid's facets */
|
/* Write solid's facets */
|
||||||
for (ifacet = 0;
|
for (ifacet = 0;
|
||||||
ifacet < facet_count && foug_datax_no_error(error);
|
ifacet < total_facet_count && foug_datax_no_error(error);
|
||||||
ifacet += buffer_facet_count)
|
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;
|
foug_stl_triangle_t tri;
|
||||||
size_t ibuffer_facet;
|
uint32_t ibuffer_facet;
|
||||||
|
|
||||||
/* Writing of facets is buffered */
|
/* Writing of facets is buffered */
|
||||||
buffer_iterator = trsf->buffer;
|
buffer_iterator = trsf->buffer;
|
||||||
for (ibuffer_facet = ifacet;
|
for (ibuffer_facet = ifacet; ibuffer_facet < clamped_facet_count; ++ibuffer_facet) {
|
||||||
ibuffer_facet < (ifacet + buffer_facet_count);
|
geom->get_triangle_func(geom->cookie, ibuffer_facet, &tri);
|
||||||
++ibuffer_facet)
|
|
||||||
{
|
|
||||||
geom->get_triangle_func(geom, isolid, ibuffer_facet, &tri);
|
|
||||||
buffer_iterator = foug_write_string(buffer_iterator, "facet normal ");
|
buffer_iterator = foug_write_string(buffer_iterator, "facet normal ");
|
||||||
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.normal);
|
buffer_iterator = foug_write_coords(buffer_iterator, coords_format, &tri.normal);
|
||||||
buffer_iterator = foug_write_eol(buffer_iterator);
|
buffer_iterator = foug_write_eol(buffer_iterator);
|
||||||
@ -203,7 +186,7 @@ int foug_stla_write(foug_stla_geom_output_t* geom,
|
|||||||
|
|
||||||
/* Task control */
|
/* Task control */
|
||||||
if (foug_datax_no_error(error) && trsf->task_control.handle_progress_func != NULL) {
|
if (foug_datax_no_error(error) && trsf->task_control.handle_progress_func != NULL) {
|
||||||
size_t percentage = 0;
|
uint32_t percentage = 0;
|
||||||
written_facet_count += buffer_facet_count;
|
written_facet_count += buffer_facet_count;
|
||||||
percentage = foug_percentage(0, total_facet_count, written_facet_count);
|
percentage = foug_percentage(0, total_facet_count, written_facet_count);
|
||||||
if (!foug_task_control_handle_progress(&trsf->task_control, percentage))
|
if (!foug_task_control_handle_progress(&trsf->task_control, percentage))
|
||||||
@ -218,7 +201,6 @@ int foug_stla_write(foug_stla_geom_output_t* geom,
|
|||||||
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
|
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
|
||||||
error = FOUG_DATAX_STREAM_ERROR;
|
error = FOUG_DATAX_STREAM_ERROR;
|
||||||
}
|
}
|
||||||
} /* end for (isolid) */
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -6,16 +6,13 @@
|
|||||||
#include "../transfer.h"
|
#include "../transfer.h"
|
||||||
|
|
||||||
/* Custom geometry expressed with STL ascii interface */
|
/* Custom geometry expressed with STL ascii interface */
|
||||||
typedef struct foug_stla_geom_output foug_stla_geom_output_t;
|
typedef struct foug_stla_geom_output
|
||||||
struct foug_stla_geom_output
|
|
||||||
{
|
{
|
||||||
void* cookie;
|
const char* solid_name; /* May be NULL to generate default name */
|
||||||
|
uint32_t triangle_count;
|
||||||
size_t solid_count;
|
const void* cookie;
|
||||||
void (*get_solid_name) (const foug_stla_geom_output_t*, size_t, char*); /* Optional */
|
void (*get_triangle_func)(const void*, uint32_t, foug_stl_triangle_t*);
|
||||||
size_t (*get_triangle_count_func)(const foug_stla_geom_output_t*, size_t);
|
} foug_stla_geom_output_t;
|
||||||
void (*get_triangle_func) (const foug_stla_geom_output_t*, size_t, size_t, foug_stl_triangle_t*);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Write geometry in the STL ascii format */
|
/* Write geometry in the STL ascii format */
|
||||||
FOUG_DATAX_LIBSTL_EXPORT int foug_stla_write(foug_stla_geom_output_t* geom,
|
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);
|
uint8_t real32_prec);
|
||||||
|
|
||||||
/* Specific error codes returned by foug_stla_write() */
|
/* 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 1 /*!< get_triangle_func is null */
|
||||||
#define FOUG_STLA_WRITE_NULL_GET_TRIANGLE_FUNC 2 /*!< get_triangle_func is null */
|
#define FOUG_STLA_WRITE_INVALID_REAL32_PRECISION 2 /*!< real32_prec is not in [1..9] */
|
||||||
#define FOUG_STLA_WRITE_INVALID_REAL32_PRECISION 3 /*!< real32_prec is not in [1..9] */
|
|
||||||
|
|
||||||
#endif /* FOUG_DATAX_C_LIBSTL_STLA_WRITE_H */
|
#endif /* FOUG_DATAX_C_LIBSTL_STLA_WRITE_H */
|
||||||
|
@ -6,6 +6,19 @@
|
|||||||
|
|
||||||
#include <string.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)
|
static void read_triangle_memcpy(const uint8_t* buffer, foug_stlb_triangle_t* triangle)
|
||||||
{
|
{
|
||||||
/* *triangle = *((foug_stlb_triangle_t*)(buffer)); */
|
/* *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,
|
static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom,
|
||||||
uint8_t* buffer,
|
const uint8_t* buffer,
|
||||||
uint32_t facet_count,
|
const _internal_foug_read_params_helper* params)
|
||||||
uint32_t i_facet_offset)
|
|
||||||
{
|
{
|
||||||
|
const uint32_t facet_count = params->facet_count;
|
||||||
|
const uint32_t i_facet_offset = params->i_facet_offset;
|
||||||
foug_stlb_triangle_t triangle;
|
foug_stlb_triangle_t triangle;
|
||||||
uint32_t buffer_offset;
|
uint32_t buffer_offset;
|
||||||
uint32_t i_facet;
|
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;
|
buffer_offset += FOUG_STLB_TRIANGLE_RAWSIZE;
|
||||||
|
|
||||||
/* Declare triangle */
|
/* 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_transfer_t* trsf,
|
||||||
foug_endianness_t byte_order)
|
foug_endianness_t byte_order)
|
||||||
{
|
{
|
||||||
uint32_t total_facet_count;
|
_internal_foug_read_params_helper read_params;
|
||||||
size_t accum_facet_count_read;
|
uint32_t total_facet_count = 0; /* Count of facets as declared in the stream */
|
||||||
int error;
|
int error = FOUG_DATAX_NO_ERROR; /* Helper variable to store function result error code */
|
||||||
|
|
||||||
|
/* Check validity of input parameters */
|
||||||
if (trsf->buffer == NULL)
|
if (trsf->buffer == NULL)
|
||||||
return FOUG_DATAX_NULL_BUFFER_ERROR;
|
return FOUG_DATAX_NULL_BUFFER_ERROR;
|
||||||
if (trsf->buffer_size < FOUG_STLB_MIN_CONTENTS_SIZE)
|
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)
|
if (byte_order != FOUG_LITTLE_ENDIAN)
|
||||||
return FOUG_STLB_READ_UNSUPPORTED_BYTE_ORDER;
|
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 */
|
/* Read header */
|
||||||
{
|
{
|
||||||
uint8_t header_data[FOUG_STLB_HEADER_SIZE];
|
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;
|
return FOUG_STLB_READ_HEADER_WRONG_SIZE_ERROR;
|
||||||
}
|
}
|
||||||
if (geom != NULL && geom->process_header_func != NULL)
|
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 */
|
/* 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);
|
total_facet_count = foug_decode_uint32_le(trsf->buffer);
|
||||||
if (geom != NULL && geom->begin_triangles_func != NULL)
|
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 */
|
/* Read triangles */
|
||||||
accum_facet_count_read = 0;
|
while (foug_datax_no_error(error)
|
||||||
error = FOUG_DATAX_NO_ERROR;
|
&& read_params.i_facet_offset < total_facet_count)
|
||||||
while (foug_datax_no_error(error) && accum_facet_count_read < total_facet_count) {
|
{
|
||||||
const size_t facet_count_read = foug_stream_read(&trsf->stream,
|
read_params.facet_count = foug_stream_read(&trsf->stream,
|
||||||
trsf->buffer,
|
trsf->buffer,
|
||||||
FOUG_STLB_TRIANGLE_RAWSIZE,
|
FOUG_STLB_TRIANGLE_RAWSIZE,
|
||||||
trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE);
|
trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE);
|
||||||
if (foug_stream_error(&trsf->stream) != 0)
|
if (foug_stream_error(&trsf->stream) != 0)
|
||||||
error = FOUG_DATAX_STREAM_ERROR;
|
error = FOUG_DATAX_STREAM_ERROR;
|
||||||
else if (facet_count_read > 0)
|
else if (read_params.facet_count > 0)
|
||||||
error = FOUG_DATAX_NO_ERROR;
|
error = FOUG_DATAX_NO_ERROR;
|
||||||
else
|
else
|
||||||
break; /* Exit if no facet to read */
|
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)) {
|
if (foug_datax_no_error(error)) {
|
||||||
uint8_t progress_pc;
|
uint8_t progress_pc;
|
||||||
|
|
||||||
foug_stlb_read_facets(geom, trsf->buffer, facet_count_read, accum_facet_count_read);
|
foug_stlb_read_facets(geom, trsf->buffer, &read_params);
|
||||||
accum_facet_count_read += facet_count_read;
|
read_params.i_facet_offset += read_params.facet_count;
|
||||||
progress_pc = foug_percentage(0, total_facet_count, accum_facet_count_read);
|
progress_pc = foug_percentage(0, total_facet_count, read_params.i_facet_offset);
|
||||||
if (!foug_task_control_handle_progress(&trsf->task_control, progress_pc))
|
if (!foug_task_control_handle_progress(&trsf->task_control, progress_pc))
|
||||||
error = FOUG_DATAX_TASK_STOPPED_ERROR;
|
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)
|
if (foug_datax_no_error(error)
|
||||||
&& geom != NULL && geom->end_triangles_func != NULL)
|
&& 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;
|
error = FOUG_STLB_READ_FACET_COUNT_ERROR;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,17 @@
|
|||||||
#include "../transfer.h"
|
#include "../transfer.h"
|
||||||
|
|
||||||
/* foug_stlb_geom_input */
|
/* foug_stlb_geom_input */
|
||||||
typedef struct foug_stlb_geom_input foug_stlb_geom_input_t;
|
typedef struct
|
||||||
struct foug_stlb_geom_input
|
|
||||||
{
|
{
|
||||||
void* cookie;
|
void* cookie;
|
||||||
void (*process_header_func) (foug_stlb_geom_input_t*, const uint8_t*); /* Optional */
|
/* All function pointers can be safely set to NULL */
|
||||||
void (*begin_triangles_func) (foug_stlb_geom_input_t*, uint32_t); /* Optional */
|
void (*process_header_func) (void*, const uint8_t*);
|
||||||
void (*process_triangle_func)(foug_stlb_geom_input_t*, const foug_stlb_triangle_t*, uint32_t);
|
void (*begin_triangles_func) (void*, uint32_t);
|
||||||
void (*end_triangles_func) (foug_stlb_geom_input_t*); /* Optional */
|
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_stlb_read() */
|
||||||
FOUG_DATAX_LIBSTL_EXPORT int foug_stlb_read(foug_stlb_geom_input_t* geom,
|
FOUG_DATAX_LIBSTL_EXPORT int foug_stlb_read(foug_stlb_geom_input_t* geom,
|
||||||
|
@ -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)
|
if (geom == NULL || geom->get_triangle_func == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
triangle.attribute_byte_count = 0;
|
||||||
buffer_offset = 0;
|
buffer_offset = 0;
|
||||||
for (i_facet = ifacet_start; i_facet < (ifacet_start + facet_count); ++i_facet) {
|
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
|
#ifdef FOUG_STLB_READWRITE_ALIGNSAFE
|
||||||
write_triangle_alignsafe(&triangle, buffer + buffer_offset);
|
write_triangle_alignsafe(&triangle, buffer + buffer_offset);
|
||||||
|
@ -6,15 +6,14 @@
|
|||||||
#include "../endian.h"
|
#include "../endian.h"
|
||||||
#include "../transfer.h"
|
#include "../transfer.h"
|
||||||
|
|
||||||
/* foug_stlb_geom_output */
|
typedef struct
|
||||||
typedef struct foug_stlb_geom_output foug_stlb_geom_output_t;
|
|
||||||
struct foug_stlb_geom_output
|
|
||||||
{
|
{
|
||||||
void* cookie;
|
const uint8_t* header; /* May be NULL if empty header */
|
||||||
uint8_t* header; /* May be NULL if empty header*/
|
|
||||||
uint32_t triangle_count;
|
uint32_t triangle_count;
|
||||||
void (*get_triangle_func)(const foug_stlb_geom_output_t*, uint32_t, foug_stlb_triangle_t*);
|
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_stlb_write() */
|
||||||
FOUG_DATAX_LIBSTL_EXPORT int foug_stlb_write(const foug_stlb_geom_output_t* geom,
|
FOUG_DATAX_LIBSTL_EXPORT int foug_stlb_write(const foug_stlb_geom_output_t* geom,
|
||||||
|
24
src/stream.c
24
src/stream.c
@ -12,30 +12,30 @@ void foug_stream_set_null(foug_stream_t* stream)
|
|||||||
memset(stream, 0, sizeof(foug_stream_t));
|
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,
|
void* ptr,
|
||||||
size_t item_size,
|
size_t item_size,
|
||||||
size_t item_count)
|
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,
|
const void* ptr,
|
||||||
size_t item_size,
|
size_t item_size,
|
||||||
size_t item_count)
|
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)
|
foug_bool_t foug_stream_at_end(foug_stream_t* stream)
|
||||||
{
|
{
|
||||||
if (stream != NULL && stream->at_end_func != NULL)
|
if (stream != NULL && stream->at_end_func != NULL)
|
||||||
return stream->at_end_func(stream);
|
return stream->at_end_func(stream->cookie);
|
||||||
return 0;
|
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)
|
int foug_stream_error(foug_stream_t* stream)
|
||||||
{
|
{
|
||||||
if (stream != NULL && stream->error_func != NULL)
|
if (stream != NULL && stream->error_func != NULL)
|
||||||
return stream->error_func(stream);
|
return stream->error_func(stream->cookie);
|
||||||
return 0;
|
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)
|
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)
|
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;
|
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)
|
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)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
14
src/stream.h
14
src/stream.h
@ -5,8 +5,6 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include <stdio.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
|
/*! \brief Stream that can get input from an arbitrary data source or can write output to an
|
||||||
* arbitrary data sink
|
* 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.
|
* implemented by defining hook functions that know how to read/write the data.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct foug_stream
|
typedef struct
|
||||||
{
|
{
|
||||||
void* cookie;
|
void* cookie;
|
||||||
|
|
||||||
foug_bool_t (*at_end_func)(foug_stream_t*);
|
foug_bool_t (*at_end_func)(void*);
|
||||||
int32_t (*error_func)(foug_stream_t*);
|
int32_t (*error_func)(void*);
|
||||||
size_t (*read_func)(foug_stream_t*, void*, size_t, size_t);
|
size_t (*read_func)(void*, void*, size_t, size_t);
|
||||||
size_t (*write_func)(foug_stream_t*, const void*, size_t, size_t);
|
size_t (*write_func)(void*, const void*, size_t, size_t);
|
||||||
};
|
} foug_stream_t;
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
|
|
||||||
|
@ -6,121 +6,108 @@
|
|||||||
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
||||||
#include <TColgp_SequenceOfXYZ.hxx>
|
#include <TColgp_SequenceOfXYZ.hxx>
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
/* Common */
|
/* 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);
|
return mesh.operator->();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ASCII STL */
|
static void occmesh_add_triangle(void* cookie,
|
||||||
|
uint32_t /*tri_id*/,
|
||||||
static void occ_mesh_stla_igeom_begin_solid(foug_stla_geom_input_t* geom, const char* /*name*/)
|
const foug_stl_triangle_t* tri,
|
||||||
|
void* /*dummy*/)
|
||||||
{
|
{
|
||||||
Handle_StlMesh_Mesh* mesh = static_cast<Handle_StlMesh_Mesh*>(geom->cookie);
|
StlMesh_Mesh* mesh = static_cast<StlMesh_Mesh*>(cookie);
|
||||||
if (mesh->IsNull())
|
const int uId = mesh->AddOnlyNewVertex(tri->v1.x, tri->v1.y, tri->v1.z);
|
||||||
*mesh = new StlMesh_Mesh;
|
const int vId = mesh->AddOnlyNewVertex(tri->v2.x, tri->v2.y, tri->v2.z);
|
||||||
(*mesh)->AddDomain();
|
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,
|
static void occmesh_get_triangle(const void* cookie,
|
||||||
const foug_stl_triangle_t* tri)
|
uint32_t tri_id,
|
||||||
|
foug_stl_triangle_t* triangle)
|
||||||
{
|
{
|
||||||
Handle_StlMesh_Mesh* mesh = static_cast<Handle_StlMesh_Mesh*>(geom->cookie);
|
const foug_OccStlMeshDomain* meshCookie = static_cast<const foug_OccStlMeshDomain*>(cookie);
|
||||||
occ_mesh_stl_add_triangle(mesh, tri);
|
const StlMesh_SequenceOfMeshTriangle& occTriangles = meshCookie->mesh->Triangles(meshCookie->domainId);
|
||||||
}
|
const Handle_StlMesh_MeshTriangle& occTri = occTriangles.Value(tri_id + 1);
|
||||||
|
|
||||||
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);
|
|
||||||
Standard_Integer v1;
|
Standard_Integer v1;
|
||||||
Standard_Integer v2;
|
Standard_Integer v2;
|
||||||
Standard_Integer v3;
|
Standard_Integer v3;
|
||||||
Standard_Real xN;
|
Standard_Real xN;
|
||||||
Standard_Real yN;
|
Standard_Real yN;
|
||||||
Standard_Real zN;
|
Standard_Real zN;
|
||||||
tri->GetVertexAndOrientation(v1, v2, v3, xN, yN, zN);
|
occTri->GetVertexAndOrientation(v1, v2, v3, xN, yN, zN);
|
||||||
facet->data.normal.x = static_cast<foug_real32_t>(xN);
|
triangle->normal.x = float(xN);
|
||||||
facet->data.normal.y = static_cast<foug_real32_t>(yN);
|
triangle->normal.y = float(yN);
|
||||||
facet->data.normal.z = static_cast<foug_real32_t>(zN);
|
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& coordsV1 = vertices.Value(v1);
|
||||||
const gp_XYZ& coordsV2 = vertices.Value(v2);
|
const gp_XYZ& coordsV2 = vertices.Value(v2);
|
||||||
const gp_XYZ& coordsV3 = vertices.Value(v3);
|
const gp_XYZ& coordsV3 = vertices.Value(v3);
|
||||||
facet->data.v1.x = static_cast<foug_real32_t>(coordsV1.X());
|
triangle->v1.x = float(coordsV1.X());
|
||||||
facet->data.v2.x = static_cast<foug_real32_t>(coordsV2.X());
|
triangle->v2.x = float(coordsV2.X());
|
||||||
facet->data.v3.x = static_cast<foug_real32_t>(coordsV3.X());
|
triangle->v3.x = float(coordsV3.X());
|
||||||
|
|
||||||
facet->data.v1.y = static_cast<foug_real32_t>(coordsV1.Y());
|
triangle->v1.y = float(coordsV1.Y());
|
||||||
facet->data.v2.y = static_cast<foug_real32_t>(coordsV2.Y());
|
triangle->v2.y = float(coordsV2.Y());
|
||||||
facet->data.v3.y = static_cast<foug_real32_t>(coordsV3.Y());
|
triangle->v3.y = float(coordsV3.Y());
|
||||||
|
|
||||||
facet->data.v1.z = static_cast<foug_real32_t>(coordsV1.Z());
|
triangle->v1.z = float(coordsV1.Z());
|
||||||
facet->data.v2.z = static_cast<foug_real32_t>(coordsV2.Z());
|
triangle->v2.z = float(coordsV2.Z());
|
||||||
facet->data.v3.z = static_cast<foug_real32_t>(coordsV3.Z());
|
triangle->v3.z = float(coordsV3.Z());
|
||||||
|
|
||||||
facet->attribute_byte_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
@ -8,23 +8,33 @@ extern "C" {
|
|||||||
#include "../libstl/stlb_read.h"
|
#include "../libstl/stlb_read.h"
|
||||||
#include "../libstl/stlb_write.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 */
|
/* ASCII STL */
|
||||||
|
|
||||||
FOUG_LIBSUPPORT_EXPORT
|
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
|
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 */
|
/* Binary STL */
|
||||||
|
|
||||||
FOUG_LIBSUPPORT_EXPORT
|
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
|
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 */
|
#endif /* FOUG_SUPPORT_OCC_LIBSTL_H */
|
||||||
|
@ -3,41 +3,41 @@
|
|||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QIODevice>
|
#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);
|
const QFile* file = dynamic_cast<const QFile*>(device);
|
||||||
if (file != NULL) {
|
if (file != NULL) {
|
||||||
return file->error();
|
return file->error();
|
||||||
}
|
}
|
||||||
else {
|
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 !err_str.isEmpty() ? 1 : 0;
|
||||||
}
|
}
|
||||||
return 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,
|
void* ptr,
|
||||||
size_t item_size,
|
size_t item_size,
|
||||||
size_t item_count)
|
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);
|
const qint64 c = device->read(static_cast<char*>(ptr), item_size * item_count);
|
||||||
return c / item_size;
|
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,
|
const void* ptr,
|
||||||
size_t item_size,
|
size_t item_size,
|
||||||
size_t item_count)
|
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);
|
const qint64 c = device->write(static_cast<const char*>(ptr), item_size * item_count);
|
||||||
return c / item_size;
|
return c / item_size;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
foug_bool_t foug_task_control_handle_progress(foug_task_control_t* ctrl, uint8_t progress_pc)
|
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)
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,13 +4,11 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
/* foug_task_control */
|
typedef struct foug_task_control
|
||||||
typedef struct foug_task_control foug_task_control_t;
|
|
||||||
struct foug_task_control
|
|
||||||
{
|
{
|
||||||
void* cookie;
|
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_LIB_EXPORT
|
||||||
foug_bool_t foug_task_control_handle_progress(foug_task_control_t* ctrl, uint8_t progress_pc);
|
foug_bool_t foug_task_control_handle_progress(foug_task_control_t* ctrl, uint8_t progress_pc);
|
||||||
|
Loading…
Reference in New Issue
Block a user