gmio_stl: simplify API of gmio_stl_mesh_creator

This commit is contained in:
Hugues Delorme 2016-02-01 16:53:45 +01:00
parent cdcc407071
commit f8e73f5747
10 changed files with 162 additions and 155 deletions

View File

@ -131,40 +131,32 @@ static void allocate_stl_scene(aiScene* pScene)
pScene->mRootNode->mMeshes[0] = 0; pScene->mRootNode->mMeshes[0] = 0;
} }
static void func_ascii_begin_solid( static void func_begin_solid(
void* cookie, gmio_streamsize_t stream_size, const char* solid_name) void* cookie, const struct gmio_stl_mesh_creator_infos* infos)
{ {
aiSceneHelper* helper = (aiSceneHelper*)cookie; aiSceneHelper* helper = static_cast<aiSceneHelper*>(cookie);
helper->hasToCountTriangle = 1; // true
aiScene* pScene = helper->scene; aiScene* pScene = helper->scene;
allocate_stl_scene(pScene); allocate_stl_scene(pScene);
aiMesh* pMesh = pScene->mMeshes[0]; aiMesh* pMesh = pScene->mMeshes[0];
std::strcpy(pScene->mRootNode->mName.data, solid_name); if (infos->format == GMIO_STL_FORMAT_ASCII) {
pScene->mRootNode->mName.length = std::strlen(solid_name); helper->hasToCountTriangle = 1; // true
std::strcpy(pScene->mRootNode->mName.data, infos->stla_solid_name);
pScene->mRootNode->mName.length = std::strlen(infos->stla_solid_name);
// try to guess how many vertices we could have // try to guess how many vertices we could have
// assume we'll need 200 bytes for each face // assume we'll need 200 bytes for each face
const unsigned facetSize = 200u; const unsigned estimatedFacetCount =
pMesh->mNumFaces = static_cast<unsigned>(infos->stla_stream_size) / 200u;
std::max(1u, static_cast<unsigned>(stream_size) / facetSize); pMesh->mNumFaces = std::max(1u, estimatedFacetCount);
pMesh->mNumVertices = pMesh->mNumFaces * 3;
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
} }
else {
static void binary_begin_solid(
void* cookie, uint32_t tri_count, const gmio_stlb_header* /*header*/)
{
aiSceneHelper* helper = (aiSceneHelper*)cookie;
helper->hasToCountTriangle = 0; // false helper->hasToCountTriangle = 0; // false
aiScene* pScene = helper->scene;
allocate_stl_scene(pScene);
aiMesh* pMesh = pScene->mMeshes[0];
pScene->mRootNode->mName.Set("<STL_BINARY>"); pScene->mRootNode->mName.Set("<STL_BINARY>");
pMesh->mNumFaces = tri_count; pMesh->mNumFaces = infos->stlb_triangle_count;
}
pMesh->mNumVertices = pMesh->mNumFaces*3; pMesh->mNumVertices = pMesh->mNumFaces*3;
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
@ -173,7 +165,7 @@ static void binary_begin_solid(
static void add_triangle( static void add_triangle(
void* cookie, uint32_t tri_id, const gmio_stl_triangle* triangle) void* cookie, uint32_t tri_id, const gmio_stl_triangle* triangle)
{ {
aiSceneHelper* helper = (aiSceneHelper*)cookie; aiSceneHelper* helper = static_cast<aiSceneHelper*>(cookie);
aiScene* pScene = helper->scene; aiScene* pScene = helper->scene;
aiMesh* pMesh = pScene->mMeshes[0]; aiMesh* pMesh = pScene->mMeshes[0];
if (pMesh->mNumFaces <= tri_id) { if (pMesh->mNumFaces <= tri_id) {
@ -220,7 +212,7 @@ static void add_triangle(
static void end_solid(void* cookie) static void end_solid(void* cookie)
{ {
aiSceneHelper* helper = (aiSceneHelper*)cookie; aiSceneHelper* helper = static_cast<aiSceneHelper*>(cookie);
aiScene* pScene = helper->scene; aiScene* pScene = helper->scene;
aiMesh* pMesh = pScene->mMeshes[0]; aiMesh* pMesh = pScene->mMeshes[0];
@ -260,7 +252,7 @@ static void end_solid(void* cookie)
static void get_triangle( static void get_triangle(
const void* cookie, uint32_t tri_id, gmio_stl_triangle* triangle) const void* cookie, uint32_t tri_id, gmio_stl_triangle* triangle)
{ {
const aiMesh* mesh = (const aiMesh*)cookie; const aiMesh* mesh = static_cast<const aiMesh*>(cookie);
const aiFace& f = mesh->mFaces[tri_id]; const aiFace& f = mesh->mFaces[tri_id];
// we need per-face normals. We specified aiProcess_GenNormals as // we need per-face normals. We specified aiProcess_GenNormals as
@ -288,8 +280,7 @@ static void stl_read(const void* filepath)
const char* str_filepath = static_cast<const char*>(filepath); const char* str_filepath = static_cast<const char*>(filepath);
gmio_stl_mesh_creator mesh_creator = {}; gmio_stl_mesh_creator mesh_creator = {};
mesh_creator.cookie = &globalSceneHelper; mesh_creator.cookie = &globalSceneHelper;
mesh_creator.func_ascii_begin_solid = func_ascii_begin_solid; mesh_creator.func_begin_solid = func_begin_solid;
mesh_creator.func_binary_begin_solid = binary_begin_solid;
mesh_creator.func_add_triangle = add_triangle; mesh_creator.func_add_triangle = add_triangle;
mesh_creator.func_end_solid = end_solid; mesh_creator.func_end_solid = end_solid;

View File

@ -83,15 +83,20 @@ struct stl_readwrite_conv
uint32_t total_triangle_count; uint32_t total_triangle_count;
}; };
static void readwrite_ascii_begin_solid( static void readwrite_begin_solid(
void* cookie, gmio_streamsize_t stream_size, const char* solid_name) void* cookie, const struct gmio_stl_mesh_creator_infos* infos)
{ {
struct stl_readwrite_conv* rw_conv = (struct stl_readwrite_conv*)cookie; struct stl_readwrite_conv* rw_conv = (struct stl_readwrite_conv*)cookie;
struct gmio_stream* stream = &rw_conv->stream; struct gmio_stream* stream = &rw_conv->stream;
GMIO_UNUSED(stream_size);
if (infos->format == GMIO_STL_FORMAT_ASCII) {
if (rw_conv->out_format == GMIO_STL_FORMAT_ASCII) { if (rw_conv->out_format == GMIO_STL_FORMAT_ASCII) {
stream->func_write(stream->cookie, "solid ", 1, 6); stream->func_write(stream->cookie, "solid ", 1, 6);
stream->func_write(stream->cookie, solid_name, 1, strlen(solid_name)); stream->func_write(
stream->cookie,
infos->stla_solid_name,
sizeof(char),
strlen(infos->stla_solid_name));
stream->func_write(stream->cookie, "\n", 1, 1); stream->func_write(stream->cookie, "\n", 1, 1);
} }
else { else {
@ -103,18 +108,17 @@ static void readwrite_ascii_begin_solid(
gmio_stlb_write_header(stream, byte_order, NULL, 0); gmio_stlb_write_header(stream, byte_order, NULL, 0);
} }
} }
else {
static void readwrite_binary_begin_solid(
void* cookie, uint32_t tri_count, const struct gmio_stlb_header* header)
{
struct stl_readwrite_conv* rw_conv = (struct stl_readwrite_conv*)cookie;
struct gmio_stream* stream = &rw_conv->stream;
if (rw_conv->out_format == GMIO_STL_FORMAT_ASCII) { if (rw_conv->out_format == GMIO_STL_FORMAT_ASCII) {
stream->func_write(stream->cookie, "solid\n", 1, 6); stream->func_write(stream->cookie, "solid\n", 1, 6);
} }
else { else {
const enum gmio_endianness byte_order = to_byte_order(rw_conv->out_format); gmio_stlb_write_header(
gmio_stlb_write_header(stream, byte_order, header, tri_count); stream,
to_byte_order(rw_conv->out_format),
infos->stlb_header,
infos->stlb_triangle_count);
}
} }
} }
@ -197,8 +201,7 @@ static void bmk_gmio_stl_readwrite_conv(const void* filepath)
} }
mesh_creator.cookie = &rw_conv; mesh_creator.cookie = &rw_conv;
mesh_creator.func_ascii_begin_solid = &readwrite_ascii_begin_solid; mesh_creator.func_begin_solid = &readwrite_begin_solid;
mesh_creator.func_binary_begin_solid = &readwrite_binary_begin_solid;
mesh_creator.func_add_triangle = &readwrite_add_triangle; mesh_creator.func_add_triangle = &readwrite_add_triangle;
mesh_creator.func_end_solid = &readwrite_end_solid; mesh_creator.func_end_solid = &readwrite_end_solid;

View File

@ -59,9 +59,10 @@ Handle_StlMesh_Mesh stlMesh;
static void stl_read(const void* filepath) static void stl_read(const void* filepath)
{ {
stlMesh = new StlMesh_Mesh; stlMesh = new StlMesh_Mesh;
gmio_stl_read_args read = {}; const int error = gmio_stl_read_file(
read.mesh_creator = gmio_stl_hnd_occmesh_creator(stlMesh); static_cast<const char*>(filepath),
int error = gmio_stl_read_file(&read, static_cast<const char*>(filepath)); gmio_stl_hnd_occmesh_creator(stlMesh),
NULL);
if (error != GMIO_ERROR_OK) if (error != GMIO_ERROR_OK)
printf("gmio error: 0x%X\n", error); printf("gmio error: 0x%X\n", error);
} }
@ -69,12 +70,15 @@ static void stl_read(const void* filepath)
static void stl_write(const char* filepath, gmio_stl_format format) static void stl_write(const char* filepath, gmio_stl_format format)
{ {
const gmio_occ_stl_mesh_domain occ_mesh_domain(stlMesh); const gmio_occ_stl_mesh_domain occ_mesh_domain(stlMesh);
gmio_stl_write_args write = {}; gmio_stl_write_options options = {};
write.mesh = gmio_stl_occmesh(&occ_mesh_domain); options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_UPPERCASE;
write.options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_UPPERCASE; options.stla_float32_prec = 7;
write.options.stla_float32_prec = 7;
const int error = const int error =
gmio_stl_write_file(&write, format, static_cast<const char*>(filepath)); gmio_stl_write_file(
format,
static_cast<const char*>(filepath),
gmio_stl_occmesh(&occ_mesh_domain),
&options);
if (error != GMIO_ERROR_OK) if (error != GMIO_ERROR_OK)
printf("gmio error: 0x%X\n", error); printf("gmio error: 0x%X\n", error);
} }

View File

@ -19,27 +19,13 @@
#include "../stl_mesh_creator.h" #include "../stl_mesh_creator.h"
/*! Safe and convenient function for /*! Safe and convenient function for
* gmio_stl_mesh_creator::func_ascii_begin_solid() */ * gmio_stl_mesh_creator::func_begin_solid() */
GMIO_INLINE void gmio_stl_mesh_creator_ascii_begin_solid( GMIO_INLINE void gmio_stl_mesh_creator_begin_solid(
struct gmio_stl_mesh_creator* creator, struct gmio_stl_mesh_creator* creator,
gmio_streamsize_t stream_size, const struct gmio_stl_mesh_creator_infos* infos)
const char* solid_name)
{ {
if (creator != NULL && creator->func_ascii_begin_solid != NULL) { if (creator != NULL && creator->func_begin_solid != NULL)
creator->func_ascii_begin_solid( creator->func_begin_solid(creator->cookie, infos);
creator->cookie, stream_size, solid_name);
}
}
/*! Safe and convenient function for
* gmio_stl_mesh_creator::func_binary_begin_solid() */
GMIO_INLINE void gmio_stl_mesh_creator_binary_begin_solid(
struct gmio_stl_mesh_creator* creator,
uint32_t tri_count,
const struct gmio_stlb_header* header)
{
if (creator != NULL && creator->func_binary_begin_solid != NULL)
creator->func_binary_begin_solid(creator->cookie, tri_count, header);
} }
/*! Safe and convenient function for /*! Safe and convenient function for

View File

@ -24,12 +24,48 @@
#define GMIO_STL_MESH_CREATOR_H #define GMIO_STL_MESH_CREATOR_H
#include "stl_global.h" #include "stl_global.h"
#include "stl_format.h"
#include "stl_triangle.h" #include "stl_triangle.h"
#include "stlb_header.h" #include "stlb_header.h"
#include "../gmio_core/stream.h" #include "../gmio_core/stream.h"
#include <stddef.h> #include <stddef.h>
/*! Informations about the STL stream, used in
* gmio_stl_mesh_creator::begin_solid() */
struct gmio_stl_mesh_creator_infos
{
/*! Format of the input STL mesh */
enum gmio_stl_format format;
/*! Null terminated C-string holding the STL mesh(solid) name
*
* Available only if STL ASCII format, \c NULL otherwise
*/
const char* stla_solid_name;
/*! Total size (in bytes) of the input stream
*
* This is the result of gmio_stl_read_options::func_stla_get_streamsize()
*
* Useful to roughly estimate the facet count in the input mesh.
* Available only if STL ASCII format, \c 0 otherwise
*/
gmio_streamsize_t stla_stream_size;
/*! Contains the header data(80 bytes)
*
* Available only if binary STL, \c NULL otherwise
*/
const struct gmio_stlb_header* stlb_header;
/*! Count of mesh facets(triangles)
*
* Available only if binary STL, \c 0 otherwise
*/
uint32_t stlb_triangle_count;
};
/*! Provides an interface for the creation of the underlying(hidden) /*! Provides an interface for the creation of the underlying(hidden)
* user mesh */ * user mesh */
struct gmio_stl_mesh_creator struct gmio_stl_mesh_creator
@ -40,30 +76,9 @@ struct gmio_stl_mesh_creator
/* All function pointers are optional (ie can be set to NULL) */ /* All function pointers are optional (ie can be set to NULL) */
/*! Pointer on a function that handles declaration of a solid of /*! Optional pointer on a function that handles declaration of a solid */
* name \p solid_name void (*func_begin_solid)(
* void* cookie, const struct gmio_stl_mesh_creator_infos* infos);
* Optional function useful only with STL ascii (ie. gmio_stla_read())
*
* The argument \p stream_size is the total size (in bytes) of the input
* stream
*/
void (*func_ascii_begin_solid)(
void* cookie,
gmio_streamsize_t stream_size,
const char* solid_name);
/*! Pointer on a function that handles declaration of a mesh with
* \p tri_count number of triangles
*
* Optional function useful only with STL binary (ie. gmio_stlb_read()).
*
* The argument \p header contains the header data(80 bytes)
*/
void (*func_binary_begin_solid)(
void* cookie,
uint32_t tri_count,
const struct gmio_stlb_header* header);
/*! Pointer on a function that adds a triangle to the user mesh /*! Pointer on a function that adds a triangle to the user mesh
* *

View File

@ -518,10 +518,11 @@ int parse_beginsolid(struct gmio_stla_parse_data* data)
{ {
if (gmio_stla_eat_next_token(data, SOLID_token) == 0) { if (gmio_stla_eat_next_token(data, SOLID_token) == 0) {
if (gmio_stla_parse_solidname_beg(data) == 0) { if (gmio_stla_parse_solidname_beg(data) == 0) {
gmio_stl_mesh_creator_ascii_begin_solid( struct gmio_stl_mesh_creator_infos infos = {0};
data->creator, infos.format = GMIO_STL_FORMAT_ASCII;
data->strstream_cookie.stream_size, infos.stla_solid_name = data->strbuff.ptr;
data->strbuff.ptr); infos.stla_stream_size = data->strstream_cookie.stream_size;
gmio_stl_mesh_creator_begin_solid(data->creator, &infos);
return 0; return 0;
} }
} }

View File

@ -139,8 +139,16 @@ int gmio_stlb_read(
total_facet_count = gmio_uint32_bswap(total_facet_count); total_facet_count = gmio_uint32_bswap(total_facet_count);
/* Callback to notify triangle count and header data */ /* Callback to notify triangle count and header data */
gmio_stl_mesh_creator_binary_begin_solid( {
&mesh_creator, total_facet_count, &header); struct gmio_stl_mesh_creator_infos infos = {0};
infos.format =
byte_order == GMIO_ENDIANNESS_LITTLE ?
GMIO_STL_FORMAT_BINARY_LE :
GMIO_STL_FORMAT_BINARY_BE;
infos.stlb_header = &header;
infos.stlb_triangle_count = total_facet_count;
gmio_stl_mesh_creator_begin_solid(&mesh_creator, &infos);
}
/* Read triangles */ /* Read triangles */
gmio_task_iface_handle_progress(task, 0, total_facet_count); gmio_task_iface_handle_progress(task, 0, total_facet_count);

View File

@ -44,34 +44,35 @@ struct gmio_stl_triangle_array gmio_stl_triangle_array_malloc(size_t tri_count)
return array; return array;
} }
static void gmio_stl_data__ascii_begin_solid( static void gmio_stl_data__begin_solid(
void* cookie, gmio_streamsize_t stream_size, const char* solid_name) void* cookie, const struct gmio_stl_mesh_creator_infos* infos)
{ {
struct gmio_stl_data* data = (struct gmio_stl_data*)cookie; struct gmio_stl_data* data = (struct gmio_stl_data*)cookie;
if (infos->format == GMIO_STL_FORMAT_ASCII) {
memset(data->solid_name, 0, sizeof(data->solid_name)); memset(data->solid_name, 0, sizeof(data->solid_name));
if (solid_name != NULL) { if (infos->stla_solid_name != NULL) {
const size_t len = const size_t len =
GMIO_MIN(sizeof(data->solid_name), strlen(solid_name)); GMIO_MIN(sizeof(data->solid_name),
strncpy(data->solid_name, solid_name, len); strlen(infos->stla_solid_name));
strncpy(data->solid_name, infos->stla_solid_name, len);
} }
/* Try to guess how many vertices we could have assume we'll need 200 bytes /* Try to guess how many vertices we could have assume we'll need
* for each face */ * 200 bytes for each face */
{ {
const size_t facet_size = 200; const size_t facet_size = 200;
const size_t facet_count = const size_t facet_count =
gmio_streamsize_to_size(GMIO_MAX(1, stream_size / facet_size)); gmio_streamsize_to_size(
GMIO_MAX(1, infos->stla_stream_size / facet_size));
data->tri_array = gmio_stl_triangle_array_malloc(facet_count); data->tri_array = gmio_stl_triangle_array_malloc(facet_count);
} }
} }
else {
static void gmio_stl_data__binary_begin_solid( memcpy(&data->header, infos->stlb_header, GMIO_STLB_HEADER_SIZE);
void* cookie, uint32_t tri_count, const struct gmio_stlb_header* header) data->tri_array =
{ gmio_stl_triangle_array_malloc(infos->stlb_triangle_count);
struct gmio_stl_data* data = (struct gmio_stl_data*)cookie; }
memcpy(&data->header, header, GMIO_STLB_HEADER_SIZE);
data->tri_array = gmio_stl_triangle_array_malloc(tri_count);
} }
static void gmio_stl_data__add_triangle( static void gmio_stl_data__add_triangle(
@ -100,8 +101,7 @@ struct gmio_stl_mesh_creator gmio_stl_data_mesh_creator(struct gmio_stl_data *da
{ {
struct gmio_stl_mesh_creator creator = {0}; struct gmio_stl_mesh_creator creator = {0};
creator.cookie = data; creator.cookie = data;
creator.func_ascii_begin_solid = &gmio_stl_data__ascii_begin_solid; creator.func_begin_solid = &gmio_stl_data__begin_solid;
creator.func_binary_begin_solid = &gmio_stl_data__binary_begin_solid;
creator.func_add_triangle = &gmio_stl_data__add_triangle; creator.func_add_triangle = &gmio_stl_data__add_triangle;
return creator; return creator;
} }

View File

@ -55,8 +55,6 @@ const char* generic_test_stl_infos(const struct gmio_test_stl_infos* test)
struct gmio_stream stream = gmio_stream_stdio(file); struct gmio_stream stream = gmio_stream_stdio(file);
int error = GMIO_ERROR_OK; int error = GMIO_ERROR_OK;
printf("\n%s\n", test->filepath);
error = gmio_stl_infos_get(&infos, stream, GMIO_STL_INFO_FLAG_ALL, NULL); error = gmio_stl_infos_get(&infos, stream, GMIO_STL_INFO_FLAG_ALL, NULL);
if (test->format != GMIO_STL_FORMAT_UNKNOWN) { if (test->format != GMIO_STL_FORMAT_UNKNOWN) {
UTEST_COMPARE_INT(GMIO_ERROR_OK, error); UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
@ -71,7 +69,7 @@ const char* generic_test_stl_infos(const struct gmio_test_stl_infos* test)
fclose(file); fclose(file);
if (test->expected_size != -2) if (test->expected_size != -2)
UTEST_COMPARE_UINT(expected_size, infos.size); UTEST_COMPARE_INT(expected_size, infos.size);
return NULL; return NULL;
} }

View File

@ -35,15 +35,16 @@ struct stl_testcase_result
char solid_name[2048]; char solid_name[2048];
}; };
void stl_testcase_result__ascii_begin_solid( void stl_testcase_result__begin_solid(
void* cookie, gmio_streamsize_t stream_size, const char* solid_name) void* cookie, const struct gmio_stl_mesh_creator_infos* infos)
{ {
if (infos->format == GMIO_STL_FORMAT_ASCII) {
struct stl_testcase_result* res = (struct stl_testcase_result*)cookie; struct stl_testcase_result* res = (struct stl_testcase_result*)cookie;
GMIO_UNUSED(stream_size);
if (res != NULL) { if (res != NULL) {
res->solid_name[0] = 0; res->solid_name[0] = 0;
if (solid_name != NULL) if (infos->stla_solid_name != NULL)
strcpy(res->solid_name, solid_name); strcpy(res->solid_name, infos->stla_solid_name);
}
} }
} }
@ -131,7 +132,7 @@ const char* test_stl_read()
struct stl_testcase_result result = {0}; struct stl_testcase_result result = {0};
mesh_creator.cookie = &result; mesh_creator.cookie = &result;
mesh_creator.func_ascii_begin_solid = &stl_testcase_result__ascii_begin_solid; mesh_creator.func_begin_solid = &stl_testcase_result__begin_solid;
mesh_creator.func_add_triangle = &gmio_stl_nop_add_triangle; mesh_creator.func_add_triangle = &gmio_stl_nop_add_triangle;
for (i = 0; i < expected_count; ++i) { for (i = 0; i < expected_count; ++i) {