Considerable simplify libstl API

This commit is contained in:
Hugues Delorme 2014-01-29 16:59:19 +01:00
parent a2f39de890
commit 6abac58deb
19 changed files with 265 additions and 265 deletions

View File

@ -59,13 +59,14 @@ contains(DATAX, stl) {
HEADERS += \ HEADERS += \
../src/libstl/stl_error.h \ ../src/libstl/stl_error.h \
../src/libstl/stl_format.h \ ../src/libstl/stl_format.h \
../src/libstl/stl_geom.h \
../src/libstl/stl_geom_creator.h \
../src/libstl/stl_global.h \ ../src/libstl/stl_global.h \
../src/libstl/stl_triangle.h \ ../src/libstl/stl_triangle.h \
../src/libstl/stla_read.h \ ../src/libstl/stla_read.h \
../src/libstl/stla_write.h \ ../src/libstl/stla_write.h \
../src/libstl/stlb_read.h \ ../src/libstl/stlb_read.h \
../src/libstl/stlb_write.h \ ../src/libstl/stlb_write.h \
../src/libstl/stlb_triangle.h \
\ \
../src/internal/libstl/stlb_byte_swap.h \ ../src/internal/libstl/stlb_byte_swap.h \
../src/internal/libstl/stlb_rw_common.h ../src/internal/libstl/stlb_rw_common.h

View File

@ -2,10 +2,10 @@
#include "../byte_swap.h" #include "../byte_swap.h"
void foug_stlb_triangle_bswap(foug_stlb_triangle_t* triangle) void foug_stl_triangle_bswap(foug_stl_triangle_t* triangle)
{ {
int i; int i;
uint32_t* uintcoord_ptr = (uint32_t*)&(triangle->data.normal.x); uint32_t* uintcoord_ptr = (uint32_t*)&(triangle->normal.x);
for (i = 0; i < 12; ++i) for (i = 0; i < 12; ++i)
*(uintcoord_ptr + i) = foug_uint32_bswap(*(uintcoord_ptr + i)); *(uintcoord_ptr + i) = foug_uint32_bswap(*(uintcoord_ptr + i));

View File

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

View File

@ -4,13 +4,13 @@
#include "../../global.h" #include "../../global.h"
#include "../../endian.h" #include "../../endian.h"
#include "../../transfer.h" #include "../../transfer.h"
#include "../../libstl/stlb_triangle.h" #include "../../libstl/stl_triangle.h"
typedef struct typedef struct
{ {
uint32_t facet_count; uint32_t facet_count;
uint32_t i_facet_offset; uint32_t i_facet_offset;
void (*fix_endian_func)(foug_stlb_triangle_t*); void (*fix_endian_func)(foug_stl_triangle_t*);
} foug_readwrite_helper; } foug_readwrite_helper;
int foug_stlb_check_params(const foug_transfer_t* trsf, int foug_stlb_check_params(const foug_transfer_t* trsf,

View File

@ -3,7 +3,7 @@
#include "../endian.h" #include "../endian.h"
#include "../internal/byte_codec.h" #include "../internal/byte_codec.h"
#include "../internal/byte_swap.h" #include "../internal/byte_swap.h"
#include "stlb_triangle.h" #include "stl_triangle.h"
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
@ -44,7 +44,7 @@ foug_stl_format_t foug_stl_get_format(foug_stream_t *stream, size_t data_size)
/* Next token (if exists) must match "solid " */ /* Next token (if exists) must match "solid " */
if (pos < _INTERNAL_FOUG_FIXED_BUFFER_SIZE if (pos < _INTERNAL_FOUG_FIXED_BUFFER_SIZE
&& strcmp(fixed_buffer + pos, "solid ") == 0) && strncmp(fixed_buffer + pos, "solid ", 6) == 0)
{ {
return FOUG_STL_ASCII_FORMAT; return FOUG_STL_ASCII_FORMAT;
} }

14
src/libstl/stl_geom.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef FOUG_LIBSTL_STL_GEOM_H
#define FOUG_LIBSTL_STL_GEOM_H
#include "stl_global.h"
#include "stl_triangle.h"
typedef struct foug_stl_geom
{
const void* cookie;
uint32_t triangle_count;
void (*get_triangle_func)(const void*, uint32_t, foug_stl_triangle_t*);
} foug_stl_geom_t;
#endif /* FOUG_LIBSTL_STL_GEOM_H */

View File

@ -0,0 +1,19 @@
#ifndef FOUG_LIBSTL_STL_GEOM_CREATOR_H
#define FOUG_LIBSTL_STL_GEOM_CREATOR_H
#include "stl_global.h"
#include "stl_triangle.h"
typedef struct
{
void* cookie;
void (*ascii_begin_solid_func)(void*, const char*); /* Optional */
void (*binary_begin_solid_func)(void*, uint32_t, const uint8_t*); /* Optional */
void (*add_triangle_func)(void*, uint32_t, const foug_stl_triangle_t*); /* Optional */
void (*end_solid_func) (void*); /* Optional */
} foug_stl_geom_creator_t;
#endif /* FOUG_LIBSTL_STL_GEOM_CREATOR_H */

View File

@ -17,7 +17,9 @@ typedef struct foug_stl_triangle
foug_stl_coords_t v1; foug_stl_coords_t v1;
foug_stl_coords_t v2; foug_stl_coords_t v2;
foug_stl_coords_t v3; foug_stl_coords_t v3;
uint16_t attribute_byte_count; /* Useful only for STL binary format */
} foug_stl_triangle_t; } foug_stl_triangle_t;
#define FOUG_STL_TRIANGLE_RAWSIZE (4 * FOUG_STL_COORDS_RAWSIZE) #define FOUG_STLA_TRIANGLE_RAWSIZE (4 * FOUG_STL_COORDS_RAWSIZE)
#define FOUG_STLB_TRIANGLE_RAWSIZE (FOUG_STLA_TRIANGLE_RAWSIZE + sizeof(uint16_t))
#endif /* FOUG_DATAX_C_LIBSTL_TRIANGLE_H */ #endif /* FOUG_DATAX_C_LIBSTL_TRIANGLE_H */

View File

@ -8,6 +8,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h>
/* /*
* *
* STL ASCII grammar: * STL ASCII grammar:
@ -77,6 +79,7 @@ typedef enum
OUTER_token, OUTER_token,
SOLID_token, SOLID_token,
VERTEX_token, VERTEX_token,
empty_token,
unknown_token unknown_token
} foug_stla_token_t; } foug_stla_token_t;
@ -88,7 +91,7 @@ typedef struct
foug_ascii_stream_fwd_iterator_t stream_iterator; foug_ascii_stream_fwd_iterator_t stream_iterator;
_internal_foug_fwd_iterator_cookie_t stream_iterator_cookie; _internal_foug_fwd_iterator_cookie_t stream_iterator_cookie;
foug_ascii_string_buffer_t string_buffer; foug_ascii_string_buffer_t string_buffer;
foug_stla_geom_input_t* geom; foug_stl_geom_creator_t* creator;
} foug_stla_parse_data_t; } foug_stla_parse_data_t;
static void foug_stream_fwd_iterator_stla_read_hook(void* cookie, static void foug_stream_fwd_iterator_stla_read_hook(void* cookie,
@ -126,79 +129,89 @@ FOUG_INLINE static void parsing_error(foug_stla_parse_data_t* data)
{ {
data->error = 1; data->error = 1;
data->token = unknown_token; data->token = unknown_token;
printf("parsing_error, token: %s\n", data->string_buffer.ptr);
}
static foug_stla_token_t parsing_find_token(const foug_ascii_string_buffer_t* str_buffer)
{
const char* word = str_buffer->ptr;
const size_t word_len = str_buffer->len;
/* Get rid of ill-formed token */
if (word_len == 0)
return empty_token;
/* Try to guess if it's a float */
if (word[0] == '+' || word[0] == '-' || isdigit(word[0]))
return FLOAT_token;
/* Try to find non "endXxx" token */
if (word_len >= 4) {
switch (word[0]) {
case 'f':
if (strcmp(word + 1, "acet") == 0)
return FACET_token;
break;
case 'l':
if (strcmp(word + 1, "oop") == 0)
return LOOP_token;
break;
case 'n':
if (strcmp(word + 1, "ormal") == 0)
return NORMAL_token;
break;
case 'o':
if (strcmp(word + 1, "uter") == 0)
return OUTER_token;
break;
case 's':
if (strcmp(word + 1, "olid") == 0)
return SOLID_token;
break;
case 'v':
if (strcmp(word + 1, "ertex") == 0)
return VERTEX_token;
break;
default:
break;
}
}
/* Might be "end..." token */
if (word_len >= 7 && strncmp(word, "end", 3) == 0) {
switch (word[3]) {
case 'f':
if (strcmp(word + 4, "acet") == 0)
return ENDFACET_token;
break;
case 'l':
if (strcmp(word + 4, "oop") == 0)
return ENDLOOP_token;
break;
case 's':
if (strcmp(word + 4, "olid") == 0)
return ENDSOLID_token;
break;
default:
break;
}
}
return ID_token;
} }
static void parsing_advance(foug_stla_parse_data_t* data) static void parsing_advance(foug_stla_parse_data_t* data)
{ {
const char* word = data->string_buffer.ptr;
if (!parsing_can_continue(data)) if (!parsing_can_continue(data))
return; return;
data->token = unknown_token; if (foug_eat_word(&data->stream_iterator, &data->string_buffer) == 0)
if (foug_eat_word(&data->stream_iterator, &data->string_buffer) == 0) { data->token = parsing_find_token(&data->string_buffer);
const size_t word_len = data->string_buffer.len; else
if (word_len >= 7 && strncmp(word, "end", 3) == 0) { /* Might be "end..." token */
switch (word[3]) {
case 'f':
if (strcmp(word + 4, "acet") == 0)
data->token = ENDFACET_token;
break;
case 'l':
if (strcmp(word + 4, "oop") == 0)
data->token = ENDLOOP_token;
break;
case 's':
if (strcmp(word + 4, "olid") == 0)
data->token = ENDSOLID_token;
break;
default:
data->token = ID_token;
} /* end switch */
}
else if (word_len >= 4) {
switch (word[0]) {
case 'f':
if (strcmp(word + 1, "acet") == 0)
data->token = FACET_token;
break;
case 'l':
if (strcmp(word + 1, "oop") == 0)
data->token = LOOP_token;
break;
case 'n':
if (strcmp(word + 1, "ormal") == 0)
data->token = NORMAL_token;
break;
case 'o':
if (strcmp(word + 1, "uter") == 0)
data->token = OUTER_token;
break;
case 's':
if (strcmp(word + 1, "olid") == 0)
data->token = SOLID_token;
break;
case 'v':
if (strcmp(word + 1, "ertex") == 0)
data->token = VERTEX_token;
break;
default:
data->token = unknown_token;
}
}
if (data->token == unknown_token) {
if (word[0] == '+' || word[0] == '-' || isdigit(word[0])) /* Try to guess if it's a float */
data->token = FLOAT_token;
else
data->token = ID_token;
}
}
else {
data->token = unknown_token; data->token = unknown_token;
if (data->token == unknown_token)
parsing_error(data); parsing_error(data);
}
} }
static void parsing_eat_token(foug_stla_token_t token, foug_stla_parse_data_t* data) static void parsing_eat_token(foug_stla_token_t token, foug_stla_parse_data_t* data)
@ -235,6 +248,7 @@ static void parse_solidname_end(foug_stla_parse_data_t* data)
switch (data->token) { switch (data->token) {
case SOLID_token: case SOLID_token:
case ID_token: case ID_token:
case empty_token:
break; break;
default: default:
parsing_error(data); parsing_error(data);
@ -250,8 +264,13 @@ static void parse_beginsolid(foug_stla_parse_data_t* data)
case SOLID_token: { case SOLID_token: {
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->begin_solid_func(data->geom->cookie, current_token_as_identifier(data)); && data->creator != NULL
&& data->creator->ascii_begin_solid_func != NULL)
{
data->creator->ascii_begin_solid_func(data->creator->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;
@ -270,8 +289,12 @@ static void parse_endsolid(foug_stla_parse_data_t* data)
case ENDSOLID_token: { case ENDSOLID_token: {
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->end_solid_func(data->geom->cookie/*, current_token_as_identifier(data)*/); && data->creator != NULL
&& data->creator->end_solid_func != NULL)
{
data->creator->end_solid_func(data->creator->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;
@ -331,8 +354,8 @@ static void parse_facets(foug_stla_parse_data_t* data)
while (data->token == FACET_token && parsing_can_continue(data)) { while (data->token == FACET_token && parsing_can_continue(data)) {
parse_facet(data, &facet); parse_facet(data, &facet);
if (data->geom != NULL && data->geom->process_triangle_func != NULL) if (data->creator != NULL && data->creator->add_triangle_func != NULL)
data->geom->process_triangle_func(data->geom->cookie, i_facet_offset, &facet); data->creator->add_triangle_func(data->creator->cookie, i_facet_offset, &facet);
++i_facet_offset; ++i_facet_offset;
} }
} }
@ -354,7 +377,7 @@ static void parse_solid(foug_stla_parse_data_t* 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_stl_geom_creator_t *creator,
foug_transfer_t *trsf, foug_transfer_t *trsf,
size_t data_size_hint) size_t data_size_hint)
{ {
@ -387,7 +410,7 @@ int foug_stla_read(foug_stla_geom_input_t* geom,
parse_data.string_buffer.len = 0; parse_data.string_buffer.len = 0;
parse_data.string_buffer.max_len = FOUG_STLA_READ_STRING_BUFFER_LEN; parse_data.string_buffer.max_len = FOUG_STLA_READ_STRING_BUFFER_LEN;
parse_data.geom = geom; parse_data.creator = creator;
parsing_advance(&parse_data); parsing_advance(&parse_data);
parse_solid(&parse_data); parse_solid(&parse_data);

View File

@ -2,21 +2,12 @@
#define FOUG_DATAX_C_LIBSTL_STLA_READ_H #define FOUG_DATAX_C_LIBSTL_STLA_READ_H
#include "stl_global.h" #include "stl_global.h"
#include "stl_triangle.h" #include "stl_geom_creator.h"
#include "../transfer.h" #include "../transfer.h"
/* foug_stla_geom_input */
typedef struct
{
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;
/* 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_stl_geom_creator_t* creator,
foug_transfer_t* trsf, foug_transfer_t* trsf,
size_t data_size_hint); size_t data_size_hint);
#endif /* FOUG_DATAX_C_LIBSTL_STLA_READ_H */ #endif /* FOUG_DATAX_C_LIBSTL_STLA_READ_H */

View File

@ -30,14 +30,16 @@
static char* foug_write_string(char* buffer, const char* str) static char* foug_write_string(char* buffer, const char* str)
{ {
strcpy(buffer, str); const char* safe_str = str != NULL ? str : "";
return buffer + strlen(str); strcpy(buffer, safe_str);
return buffer + strlen(safe_str);
} }
static char* foug_write_string_eol(char* buffer, const char* str) static char* foug_write_string_eol(char* buffer, const char* str)
{ {
const size_t len = strlen(str); const char* safe_str = str != NULL ? str : "";
strncpy(buffer, str, len); const size_t len = strlen(safe_str);
strncpy(buffer, safe_str, len);
buffer[len] = '\n'; buffer[len] = '\n';
return buffer + len + 1; return buffer + len + 1;
} }
@ -85,7 +87,7 @@ static char* foug_write_coords(char* buffer,
return buffer + sprintf(buffer, coords_format, coords->x, coords->y, coords->z); return buffer + sprintf(buffer, coords_format, coords->x, coords->y, coords->z);
} }
static foug_bool_t foug_tansfer_flush_buffer(foug_transfer_t* trsf, size_t n) static foug_bool_t foug_transfer_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;
} }
@ -96,6 +98,7 @@ static foug_bool_t foug_tansfer_flush_buffer(foug_transfer_t* trsf, size_t n)
* *
* \param geom Defines the custom geometry to write * \param geom Defines the custom geometry to write
* \param trsf Defines needed objects (stream, buffer, ...) for the writing operation * \param trsf Defines needed objects (stream, buffer, ...) for the writing operation
* \param solid_name May be NULL to generate default name
* \param real32_prec The maximum number of significant digits * \param real32_prec The maximum number of significant digits
* *
* \return Error code * \return Error code
@ -108,11 +111,11 @@ static foug_bool_t foug_tansfer_flush_buffer(foug_transfer_t* trsf, size_t n)
* \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
*/ */
int foug_stla_write(foug_stla_geom_output_t* geom, int foug_stla_write(foug_stl_geom_t* geom,
foug_transfer_t* trsf, foug_transfer_t* trsf,
const char* solid_name,
uint8_t real32_prec) uint8_t real32_prec)
{ {
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; const uint32_t total_facet_count = geom != NULL ? geom->triangle_count : 0;
uint32_t written_facet_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; const uint32_t buffer_facet_count = trsf != NULL ? trsf->buffer_size / FOUG_STLA_FACET_SIZE_P2 : 0;
@ -145,7 +148,7 @@ int foug_stla_write(foug_stla_geom_output_t* geom,
{ {
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_transfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
return FOUG_DATAX_STREAM_ERROR; return FOUG_DATAX_STREAM_ERROR;
} }
@ -182,7 +185,7 @@ int foug_stla_write(foug_stla_geom_output_t* geom,
buffer_iterator = foug_write_string_eol(buffer_iterator, "endfacet"); buffer_iterator = foug_write_string_eol(buffer_iterator, "endfacet");
} /* end for (ibuffer_facet) */ } /* end for (ibuffer_facet) */
if (!foug_tansfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer)) if (!foug_transfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
error = FOUG_DATAX_STREAM_ERROR; error = FOUG_DATAX_STREAM_ERROR;
/* Task control */ /* Task control */
@ -199,7 +202,7 @@ int foug_stla_write(foug_stla_geom_output_t* geom,
if (foug_datax_no_error(error)) { if (foug_datax_no_error(error)) {
buffer_iterator = foug_write_string(trsf->buffer, "endsolid "); buffer_iterator = foug_write_string(trsf->buffer, "endsolid ");
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_transfer_flush_buffer(trsf, buffer_iterator - (char*)trsf->buffer))
error = FOUG_DATAX_STREAM_ERROR; error = FOUG_DATAX_STREAM_ERROR;
} }

View File

@ -2,21 +2,13 @@
#define FOUG_DATAX_C_LIBSTL_STLA_WRITE_H #define FOUG_DATAX_C_LIBSTL_STLA_WRITE_H
#include "stl_global.h" #include "stl_global.h"
#include "stl_triangle.h" #include "stl_geom.h"
#include "../transfer.h" #include "../transfer.h"
/* Custom geometry expressed with STL ascii interface */
typedef struct foug_stla_geom_output
{
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 */ /* 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_stl_geom_t* geom,
foug_transfer_t* trsf, foug_transfer_t* trsf,
uint8_t real32_prec); const char* solid_name,
uint8_t real32_prec);
#endif /* FOUG_DATAX_C_LIBSTL_STLA_WRITE_H */ #endif /* FOUG_DATAX_C_LIBSTL_STLA_WRITE_H */

View File

@ -12,9 +12,9 @@
#include <string.h> #include <string.h>
FOUG_INLINE static void read_triangle_memcpy(const uint8_t* buffer, FOUG_INLINE static void read_triangle_memcpy(const uint8_t* buffer,
foug_stlb_triangle_t* triangle) foug_stl_triangle_t* triangle)
{ {
/* *triangle = *((foug_stlb_triangle_t*)(buffer)); */ /* *triangle = *((foug_stl_triangle_t*)(buffer)); */
memcpy(triangle, buffer, FOUG_STLB_TRIANGLE_RAWSIZE); memcpy(triangle, buffer, FOUG_STLB_TRIANGLE_RAWSIZE);
} }
@ -23,29 +23,28 @@ static void read_coords_alignsafe(const uint8_t* buffer, foug_stl_coords_t* coor
memcpy(coords, buffer, FOUG_STL_COORDS_RAWSIZE); memcpy(coords, buffer, FOUG_STL_COORDS_RAWSIZE);
} }
static void read_triangle_alignsafe(const uint8_t* buffer, foug_stlb_triangle_t* triangle) static void read_triangle_alignsafe(const uint8_t* buffer, foug_stl_triangle_t* triangle)
{ {
read_coords_alignsafe(buffer, &triangle->data.normal); read_coords_alignsafe(buffer, &triangle->normal);
read_coords_alignsafe(buffer + 1*FOUG_STL_COORDS_RAWSIZE, &triangle->data.v1); read_coords_alignsafe(buffer + 1*FOUG_STL_COORDS_RAWSIZE, &triangle->v1);
read_coords_alignsafe(buffer + 2*FOUG_STL_COORDS_RAWSIZE, &triangle->data.v2); read_coords_alignsafe(buffer + 2*FOUG_STL_COORDS_RAWSIZE, &triangle->v2);
read_coords_alignsafe(buffer + 3*FOUG_STL_COORDS_RAWSIZE, &triangle->data.v3); read_coords_alignsafe(buffer + 3*FOUG_STL_COORDS_RAWSIZE, &triangle->v3);
memcpy(&triangle->attribute_byte_count, buffer + 4*FOUG_STL_COORDS_RAWSIZE, sizeof(uint16_t)); memcpy(&triangle->attribute_byte_count, buffer + 4*FOUG_STL_COORDS_RAWSIZE, sizeof(uint16_t));
} }
static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom, static void foug_stlb_read_facets(foug_stl_geom_creator_t* creator,
const uint8_t* buffer, const uint8_t* buffer,
const foug_readwrite_helper* rparams) const foug_readwrite_helper* rparams)
{ {
const uint32_t facet_count = rparams->facet_count; const uint32_t facet_count = rparams->facet_count;
const uint32_t i_facet_offset = rparams->i_facet_offset; const uint32_t i_facet_offset = rparams->i_facet_offset;
foug_stlb_triangle_t triangle; foug_stl_triangle_t triangle;
uint32_t buffer_offset; uint32_t buffer_offset = 0;
uint32_t i_facet; uint32_t i_facet = 0;
if (geom == NULL || geom->process_triangle_func == NULL) if (creator == NULL || creator->add_triangle_func == NULL)
return; return;
buffer_offset = 0;
for (i_facet = 0; i_facet < facet_count; ++i_facet) { for (i_facet = 0; i_facet < facet_count; ++i_facet) {
/* Decode data */ /* Decode data */
#ifdef FOUG_STLB_READWRITE_ALIGNSAFE #ifdef FOUG_STLB_READWRITE_ALIGNSAFE
@ -59,14 +58,11 @@ static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom,
rparams->fix_endian_func(&triangle); rparams->fix_endian_func(&triangle);
/* Declare triangle */ /* Declare triangle */
geom->process_triangle_func(geom->cookie, creator->add_triangle_func(creator->cookie, i_facet_offset + i_facet, &triangle);
i_facet_offset + i_facet,
&triangle.data,
triangle.attribute_byte_count);
} }
} }
int foug_stlb_read(foug_stlb_geom_input_t* geom, int foug_stlb_read(foug_stl_geom_creator_t *creator,
foug_transfer_t* trsf, foug_transfer_t* trsf,
foug_endianness_t byte_order) foug_endianness_t byte_order)
{ {
@ -84,7 +80,7 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
/* Initialize rparams */ /* Initialize rparams */
memset(&rparams, 0, sizeof(foug_readwrite_helper)); memset(&rparams, 0, sizeof(foug_readwrite_helper));
if (host_byte_order != byte_order) if (host_byte_order != byte_order)
rparams.fix_endian_func = foug_stlb_triangle_bswap; rparams.fix_endian_func = foug_stl_triangle_bswap;
/* Read header */ /* Read header */
if (foug_stream_read(&trsf->stream, header_data, 1, FOUG_STLB_HEADER_SIZE) if (foug_stream_read(&trsf->stream, header_data, 1, FOUG_STLB_HEADER_SIZE)
@ -102,8 +98,8 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
total_facet_count = foug_uint32_bswap(total_facet_count); total_facet_count = foug_uint32_bswap(total_facet_count);
/* Callback to notify triangle count and header data */ /* Callback to notify triangle count and header data */
if (geom != NULL && geom->begin_triangles_func != NULL) if (creator != NULL && creator->binary_begin_solid_func != NULL)
geom->begin_triangles_func(geom->cookie, total_facet_count, header_data); creator->binary_begin_solid_func(creator->cookie, total_facet_count, header_data);
/* Read triangles */ /* Read triangles */
while (foug_datax_no_error(error) while (foug_datax_no_error(error)
@ -123,7 +119,7 @@ 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, &rparams); foug_stlb_read_facets(creator, trsf->buffer, &rparams);
rparams.i_facet_offset += rparams.facet_count; rparams.i_facet_offset += rparams.facet_count;
progress_pc = foug_percentage(0, total_facet_count, rparams.i_facet_offset); progress_pc = foug_percentage(0, total_facet_count, rparams.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))
@ -132,9 +128,10 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom,
} /* end while */ } /* end while */
if (foug_datax_no_error(error) if (foug_datax_no_error(error)
&& geom != NULL && geom->end_triangles_func != NULL) && creator != NULL
&& creator->end_solid_func != NULL)
{ {
geom->end_triangles_func(geom->cookie); creator->end_solid_func(creator->cookie);
} }
if (foug_datax_no_error(error) && rparams.i_facet_offset != total_facet_count) if (foug_datax_no_error(error) && rparams.i_facet_offset != total_facet_count)

View File

@ -2,23 +2,13 @@
#define FOUG_DATAX_C_LIBSTL_STLB_READ_H #define FOUG_DATAX_C_LIBSTL_STLB_READ_H
#include "stl_global.h" #include "stl_global.h"
#include "stlb_triangle.h" #include "stl_geom_creator.h"
#include "../endian.h" #include "../endian.h"
#include "../transfer.h" #include "../transfer.h"
/* foug_stlb_geom_input */
typedef struct
{
void* cookie;
/* All function pointers can be safely set to NULL */
void (*begin_triangles_func) (void*, uint32_t, const uint8_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;
/* 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_stl_geom_creator_t* creator,
foug_transfer_t* trsf, foug_transfer_t* trsf,
foug_endianness_t byte_order); foug_endianness_t byte_order);
#endif /* FOUG_DATAX_C_LIBSTL_STLB_READ_H */ #endif /* FOUG_DATAX_C_LIBSTL_STLB_READ_H */

View File

@ -1,13 +0,0 @@
#ifndef FOUG_DATAX_C_LIBSTL_STLB_TRIANGLE_H
#define FOUG_DATAX_C_LIBSTL_STLB_TRIANGLE_H
#include "stl_triangle.h"
typedef struct foug_stlb_triangle
{
foug_stl_triangle_t data;
uint16_t attribute_byte_count;
} foug_stlb_triangle_t;
#define FOUG_STLB_TRIANGLE_RAWSIZE (FOUG_STL_TRIANGLE_RAWSIZE + sizeof(uint16_t))
#endif /* FOUG_DATAX_C_LIBSTL_STLB_TRIANGLE_H */

View File

@ -10,7 +10,7 @@
#include <string.h> #include <string.h>
FOUG_INLINE static void write_triangle_memcpy(const foug_stlb_triangle_t* triangle, FOUG_INLINE static void write_triangle_memcpy(const foug_stl_triangle_t* triangle,
uint8_t* buffer) uint8_t* buffer)
{ {
memcpy(buffer, triangle, FOUG_STLB_TRIANGLE_RAWSIZE); memcpy(buffer, triangle, FOUG_STLB_TRIANGLE_RAWSIZE);
@ -21,22 +21,22 @@ static void write_coords_alignsafe(const foug_stl_coords_t* coords, uint8_t* buf
memcpy(buffer, coords, FOUG_STL_COORDS_RAWSIZE); memcpy(buffer, coords, FOUG_STL_COORDS_RAWSIZE);
} }
static void write_triangle_alignsafe(const foug_stlb_triangle_t* triangle, uint8_t* buffer) static void write_triangle_alignsafe(const foug_stl_triangle_t* triangle, uint8_t* buffer)
{ {
write_coords_alignsafe(&triangle->data.normal, buffer); write_coords_alignsafe(&triangle->normal, buffer);
write_coords_alignsafe(&triangle->data.v1, buffer + 1*FOUG_STL_COORDS_RAWSIZE); write_coords_alignsafe(&triangle->v1, buffer + 1*FOUG_STL_COORDS_RAWSIZE);
write_coords_alignsafe(&triangle->data.v2, buffer + 2*FOUG_STL_COORDS_RAWSIZE); write_coords_alignsafe(&triangle->v2, buffer + 2*FOUG_STL_COORDS_RAWSIZE);
write_coords_alignsafe(&triangle->data.v3, buffer + 3*FOUG_STL_COORDS_RAWSIZE); write_coords_alignsafe(&triangle->v3, buffer + 3*FOUG_STL_COORDS_RAWSIZE);
memcpy(buffer + 4*FOUG_STL_COORDS_RAWSIZE, &triangle->attribute_byte_count, sizeof(uint16_t)); memcpy(buffer + 4*FOUG_STL_COORDS_RAWSIZE, &triangle->attribute_byte_count, sizeof(uint16_t));
} }
static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom, static void foug_stlb_write_facets(const foug_stl_geom_t* geom,
uint8_t* buffer, uint8_t* buffer,
const foug_readwrite_helper* wparams) const foug_readwrite_helper* wparams)
{ {
const uint32_t facet_count = wparams->facet_count; const uint32_t facet_count = wparams->facet_count;
const uint32_t i_facet_offset = wparams->i_facet_offset; const uint32_t i_facet_offset = wparams->i_facet_offset;
foug_stlb_triangle_t triangle; foug_stl_triangle_t triangle;
uint32_t buffer_offset = 0; uint32_t buffer_offset = 0;
uint32_t i_facet = 0; uint32_t i_facet = 0;
@ -45,9 +45,7 @@ static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom,
triangle.attribute_byte_count = 0; triangle.attribute_byte_count = 0;
for (i_facet = i_facet_offset; i_facet < (i_facet_offset + facet_count); ++i_facet) { for (i_facet = i_facet_offset; i_facet < (i_facet_offset + facet_count); ++i_facet) {
geom->get_triangle_func(geom->cookie, i_facet, &triangle.data); geom->get_triangle_func(geom->cookie, i_facet, &triangle);
if (geom->get_attr_byte_count_func != NULL)
geom->get_attr_byte_count_func(geom->cookie, i_facet, &triangle.attribute_byte_count);
if (wparams->fix_endian_func != NULL) if (wparams->fix_endian_func != NULL)
wparams->fix_endian_func(&triangle); wparams->fix_endian_func(&triangle);
@ -62,8 +60,9 @@ static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom,
} /* end for */ } /* end for */
} }
int foug_stlb_write(const foug_stlb_geom_output_t* geom, int foug_stlb_write(const foug_stl_geom_t *geom,
foug_transfer_t* trsf, foug_transfer_t* trsf,
const uint8_t *header_data,
foug_endianness_t byte_order) foug_endianness_t byte_order)
{ {
foug_readwrite_helper wparams; foug_readwrite_helper wparams;
@ -81,16 +80,12 @@ int foug_stlb_write(const foug_stlb_geom_output_t* geom,
/* Initialize wparams */ /* Initialize wparams */
memset(&wparams, 0, sizeof(foug_readwrite_helper)); memset(&wparams, 0, sizeof(foug_readwrite_helper));
if (foug_host_endianness() != byte_order) if (foug_host_endianness() != byte_order)
wparams.fix_endian_func = foug_stlb_triangle_bswap; wparams.fix_endian_func = foug_stl_triangle_bswap;
wparams.facet_count = trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE; wparams.facet_count = trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE;
/* Write header */ /* Write header */
{ {
const uint8_t* header_data = NULL; if (header_data == NULL) {
if (geom->header != NULL) {
header_data = geom->header;
}
else {
/* Use buffer to store an empty header (filled with zeroes) */ /* Use buffer to store an empty header (filled with zeroes) */
memset(trsf->buffer, 0, FOUG_STLB_HEADER_SIZE); memset(trsf->buffer, 0, FOUG_STLB_HEADER_SIZE);
header_data = (const uint8_t*)trsf->buffer; header_data = (const uint8_t*)trsf->buffer;

View File

@ -2,22 +2,14 @@
#define FOUG_DATAX_C_LIBSTL_STLB_WRITE_H #define FOUG_DATAX_C_LIBSTL_STLB_WRITE_H
#include "stl_global.h" #include "stl_global.h"
#include "stlb_triangle.h" #include "stl_geom.h"
#include "../endian.h" #include "../endian.h"
#include "../transfer.h" #include "../transfer.h"
typedef struct
{
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*, uint32_t, 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_stl_geom_t* geom,
foug_transfer_t* trsf, foug_transfer_t* trsf,
foug_endianness_t byte_order); const uint8_t* header_data,
foug_endianness_t byte_order);
#endif /* FOUG_DATAX_C_LIBSTL_STLB_WRITE_H */ #endif /* FOUG_DATAX_C_LIBSTL_STLB_WRITE_H */

View File

@ -20,14 +20,12 @@ static void occmesh_add_triangle(void* cookie,
const foug_stl_triangle_t* tri) const foug_stl_triangle_t* tri)
{ {
StlMesh_Mesh* mesh = static_cast<StlMesh_Mesh*>(cookie); StlMesh_Mesh* mesh = static_cast<StlMesh_Mesh*>(cookie);
if (tri_id == 0) if (tri_id == 0)
mesh->AddDomain(); mesh->AddDomain();
mesh->AddTriangle(mesh->AddOnlyNewVertex(tri->v1.x, tri->v1.y, tri->v1.z),
const int uId = mesh->AddOnlyNewVertex(tri->v1.x, tri->v1.y, tri->v1.z); mesh->AddOnlyNewVertex(tri->v2.x, tri->v2.y, tri->v2.z),
const int vId = mesh->AddOnlyNewVertex(tri->v2.x, tri->v2.y, tri->v2.z); mesh->AddOnlyNewVertex(tri->v3.x, tri->v3.y, tri->v3.z),
const int wId = mesh->AddOnlyNewVertex(tri->v3.x, tri->v3.y, tri->v3.z); tri->normal.x, tri->normal.y, tri->normal.z);
mesh->AddTriangle(uId, vId, wId, tri->normal.x, tri->normal.y, tri->normal.z);
} }
static void occmesh_get_triangle(const void* cookie, static void occmesh_get_triangle(const void* cookie,
@ -35,7 +33,7 @@ static void occmesh_get_triangle(const void* cookie,
foug_stl_triangle_t* triangle) foug_stl_triangle_t* triangle)
{ {
const foug_OccStlMeshDomain* meshCookie = static_cast<const foug_OccStlMeshDomain*>(cookie); const foug_OccStlMeshDomain* meshCookie = static_cast<const foug_OccStlMeshDomain*>(cookie);
const StlMesh_SequenceOfMeshTriangle& occTriangles = meshCookie->mesh->Triangles(meshCookie->domainId); const StlMesh_SequenceOfMeshTriangle& occTriangles = meshCookie->mesh()->Triangles(meshCookie->domainId());
const Handle_StlMesh_MeshTriangle& occTri = occTriangles.Value(tri_id + 1); const Handle_StlMesh_MeshTriangle& occTri = occTriangles.Value(tri_id + 1);
Standard_Integer v1; Standard_Integer v1;
Standard_Integer v2; Standard_Integer v2;
@ -48,7 +46,7 @@ static void occmesh_get_triangle(const void* cookie,
triangle->normal.y = float(yN); triangle->normal.y = float(yN);
triangle->normal.z = float(zN); triangle->normal.z = float(zN);
const TColgp_SequenceOfXYZ& vertices = meshCookie->mesh->Vertices(meshCookie->domainId); 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);
@ -65,51 +63,47 @@ static void occmesh_get_triangle(const void* cookie,
triangle->v3.z = float(coordsV3.Z()); triangle->v3.z = float(coordsV3.Z());
} }
static void occmesh_stlb_add_triangle(void* cookie,
uint32_t tri_id,
const foug_stl_triangle_t* triangle,
uint16_t /*attr_byte_count*/)
{
occmesh_add_triangle(cookie, tri_id, triangle);
}
} // namespace internal } // namespace internal
void foug_stla_geom_input_set_occmesh(foug_stla_geom_input_t* input, const Handle_StlMesh_Mesh &mesh) void foug_stl_occmesh_geom(foug_stl_geom_t *geom,
const foug_OccStlMeshDomain &meshCookie)
{ {
input->cookie = internal::occMeshPtr(mesh); std::memset(geom, 0, sizeof(foug_stl_geom_t));
memset(input, 0, sizeof(foug_stla_geom_input_t)); geom->cookie = &meshCookie;
input->process_triangle_func = internal::occmesh_add_triangle; geom->triangle_count = meshCookie.mesh()->NbTriangles(meshCookie.domainId());
geom->get_triangle_func = internal::occmesh_get_triangle;
} }
void foug_stla_geom_output_set_occmesh(foug_stla_geom_output_t *output, void foug_stl_occmesh_geom_creator(foug_stl_geom_creator_t *creator,
const foug_OccStlMeshDomain &meshCookie) const Handle_StlMesh_Mesh &mesh)
{ {
output->cookie = &meshCookie; std::memset(creator, 0, sizeof(foug_stl_geom_creator_t));
memset(output, 0, sizeof(foug_stla_geom_output_t)); creator->cookie = internal::occMeshPtr(mesh);
output->triangle_count = meshCookie.mesh->NbTriangles(meshCookie.domainId); creator->add_triangle_func = internal::occmesh_add_triangle;
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) foug_OccStlMeshDomain::foug_OccStlMeshDomain(const Handle_StlMesh_Mesh &stlMesh, int domId)
: m_mesh(stlMesh),
m_domainId(domId)
{ {
input->cookie = internal::occMeshPtr(mesh);
memset(input, 0, sizeof(foug_stlb_geom_input_t));
input->process_triangle_func = internal::occmesh_stlb_add_triangle;
} }
void foug_stlb_geom_output_set_occmesh(foug_stlb_geom_output_t* output, const Handle_StlMesh_Mesh &foug_OccStlMeshDomain::mesh() const
const foug_OccStlMeshDomain &meshCookie)
{ {
static const char occMeshBinaryHeader[] = "Generated by libfougdatax, occmesh geometry"; return m_mesh;
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) void foug_OccStlMeshDomain::setMesh(const Handle_StlMesh_Mesh &stlMesh)
: mesh(stlMesh),
domainId(stlDomainId)
{ {
m_mesh = stlMesh;
}
int foug_OccStlMeshDomain::domainId() const
{
return m_domainId;
}
void foug_OccStlMeshDomain::setDomainId(int domId)
{
m_domainId = domId;
} }

View File

@ -10,31 +10,31 @@ extern "C" {
} }
#include <Handle_StlMesh_Mesh.hxx> #include <Handle_StlMesh_Mesh.hxx>
struct FOUG_LIBSUPPORT_EXPORT foug_OccStlMeshDomain class FOUG_LIBSUPPORT_EXPORT foug_OccStlMeshDomain
{ {
foug_OccStlMeshDomain(const Handle_StlMesh_Mesh& stlMesh, int stlDomainId = 1); public:
Handle_StlMesh_Mesh mesh; foug_OccStlMeshDomain(const Handle_StlMesh_Mesh& stlMesh, int domId = 1);
int domainId;
const Handle_StlMesh_Mesh& mesh() const;
void setMesh(const Handle_StlMesh_Mesh& stlMesh);
int domainId() const;
void setDomainId(int domId);
private:
Handle_StlMesh_Mesh m_mesh;
int m_domainId;
Standard_Integer m_triVertexId[3];
Standard_Real m_triNormalCoords[3];
}; };
/* ASCII STL */ FOUG_LIBSUPPORT_EXPORT
void foug_stl_occmesh_geom(foug_stl_geom_t* geom,
const foug_OccStlMeshDomain& meshCookie);
FOUG_LIBSUPPORT_EXPORT FOUG_LIBSUPPORT_EXPORT
void foug_stla_geom_input_set_occmesh(foug_stla_geom_input_t* input, void foug_stl_occmesh_geom_creator(foug_stl_geom_creator_t* creator,
const Handle_StlMesh_Mesh& mesh); const Handle_StlMesh_Mesh& mesh);
FOUG_LIBSUPPORT_EXPORT
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,
const Handle_StlMesh_Mesh& mesh);
FOUG_LIBSUPPORT_EXPORT
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 */