From f8e73f5747410bade51f57af4c55ced537ff3794 Mon Sep 17 00:00:00 2001 From: Hugues Delorme Date: Mon, 1 Feb 2016 16:53:45 +0100 Subject: [PATCH] gmio_stl: simplify API of gmio_stl_mesh_creator --- benchmarks/benchmark_assimp/main.cpp | 55 +++++++--------- benchmarks/benchmark_gmio/main.c | 59 +++++++++-------- benchmarks/benchmark_opencascade/main.cpp | 20 +++--- .../internal/helper_stl_mesh_creator.h | 24 ++----- src/gmio_stl/stl_mesh_creator.h | 65 ++++++++++++------- src/gmio_stl/stla_read.c | 9 +-- src/gmio_stl/stlb_read.c | 12 +++- tests/stl_utils.c | 50 +++++++------- tests/test_stl_infos.c | 4 +- tests/test_stl_io.c | 19 +++--- 10 files changed, 162 insertions(+), 155 deletions(-) diff --git a/benchmarks/benchmark_assimp/main.cpp b/benchmarks/benchmark_assimp/main.cpp index 945c9ee..0688863 100644 --- a/benchmarks/benchmark_assimp/main.cpp +++ b/benchmarks/benchmark_assimp/main.cpp @@ -131,40 +131,32 @@ static void allocate_stl_scene(aiScene* pScene) pScene->mRootNode->mMeshes[0] = 0; } -static void func_ascii_begin_solid( - void* cookie, gmio_streamsize_t stream_size, const char* solid_name) +static void func_begin_solid( + void* cookie, const struct gmio_stl_mesh_creator_infos* infos) { - aiSceneHelper* helper = (aiSceneHelper*)cookie; - helper->hasToCountTriangle = 1; // true + aiSceneHelper* helper = static_cast(cookie); + aiScene* pScene = helper->scene; allocate_stl_scene(pScene); aiMesh* pMesh = pScene->mMeshes[0]; - std::strcpy(pScene->mRootNode->mName.data, solid_name); - pScene->mRootNode->mName.length = std::strlen(solid_name); + if (infos->format == GMIO_STL_FORMAT_ASCII) { + helper->hasToCountTriangle = 1; // true - // try to guess how many vertices we could have - // assume we'll need 200 bytes for each face - const unsigned facetSize = 200u; - pMesh->mNumFaces = - std::max(1u, static_cast(stream_size) / facetSize); - pMesh->mNumVertices = pMesh->mNumFaces * 3; - pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; - pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; -} - -static void binary_begin_solid( - void* cookie, uint32_t tri_count, const gmio_stlb_header* /*header*/) -{ - aiSceneHelper* helper = (aiSceneHelper*)cookie; - helper->hasToCountTriangle = 0; // false - aiScene* pScene = helper->scene; - allocate_stl_scene(pScene); - aiMesh* pMesh = pScene->mMeshes[0]; - - pScene->mRootNode->mName.Set(""); - pMesh->mNumFaces = tri_count; + 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 + // assume we'll need 200 bytes for each face + const unsigned estimatedFacetCount = + static_cast(infos->stla_stream_size) / 200u; + pMesh->mNumFaces = std::max(1u, estimatedFacetCount); + } + else { + helper->hasToCountTriangle = 0; // false + pScene->mRootNode->mName.Set(""); + pMesh->mNumFaces = infos->stlb_triangle_count; + } pMesh->mNumVertices = pMesh->mNumFaces*3; pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; @@ -173,7 +165,7 @@ static void binary_begin_solid( static void add_triangle( void* cookie, uint32_t tri_id, const gmio_stl_triangle* triangle) { - aiSceneHelper* helper = (aiSceneHelper*)cookie; + aiSceneHelper* helper = static_cast(cookie); aiScene* pScene = helper->scene; aiMesh* pMesh = pScene->mMeshes[0]; if (pMesh->mNumFaces <= tri_id) { @@ -220,7 +212,7 @@ static void add_triangle( static void end_solid(void* cookie) { - aiSceneHelper* helper = (aiSceneHelper*)cookie; + aiSceneHelper* helper = static_cast(cookie); aiScene* pScene = helper->scene; aiMesh* pMesh = pScene->mMeshes[0]; @@ -260,7 +252,7 @@ static void end_solid(void* cookie) static void get_triangle( const void* cookie, uint32_t tri_id, gmio_stl_triangle* triangle) { - const aiMesh* mesh = (const aiMesh*)cookie; + const aiMesh* mesh = static_cast(cookie); const aiFace& f = mesh->mFaces[tri_id]; // 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(filepath); gmio_stl_mesh_creator mesh_creator = {}; mesh_creator.cookie = &globalSceneHelper; - mesh_creator.func_ascii_begin_solid = func_ascii_begin_solid; - mesh_creator.func_binary_begin_solid = binary_begin_solid; + mesh_creator.func_begin_solid = func_begin_solid; mesh_creator.func_add_triangle = add_triangle; mesh_creator.func_end_solid = end_solid; diff --git a/benchmarks/benchmark_gmio/main.c b/benchmarks/benchmark_gmio/main.c index 2bd1876..6d223e4 100644 --- a/benchmarks/benchmark_gmio/main.c +++ b/benchmarks/benchmark_gmio/main.c @@ -83,38 +83,42 @@ struct stl_readwrite_conv uint32_t total_triangle_count; }; -static void readwrite_ascii_begin_solid( - void* cookie, gmio_streamsize_t stream_size, const char* solid_name) +static void readwrite_begin_solid( + void* cookie, const struct gmio_stl_mesh_creator_infos* infos) { struct stl_readwrite_conv* rw_conv = (struct stl_readwrite_conv*)cookie; struct gmio_stream* stream = &rw_conv->stream; - GMIO_UNUSED(stream_size); - if (rw_conv->out_format == GMIO_STL_FORMAT_ASCII) { - stream->func_write(stream->cookie, "solid ", 1, 6); - stream->func_write(stream->cookie, solid_name, 1, strlen(solid_name)); - stream->func_write(stream->cookie, "\n", 1, 1); - } - else { - /* For binary STL, facet count <- 0 because it cannot be known at this - * point. Header will be correctly rewritten at the end of the read - * procedure (in gmio_stl_mesh_creator::func_end_solid() callback) - */ - const enum gmio_endianness byte_order = to_byte_order(rw_conv->out_format); - gmio_stlb_write_header(stream, byte_order, NULL, 0); - } -} -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) { - stream->func_write(stream->cookie, "solid\n", 1, 6); + if (infos->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, + infos->stla_solid_name, + sizeof(char), + strlen(infos->stla_solid_name)); + stream->func_write(stream->cookie, "\n", 1, 1); + } + else { + /* For binary STL, facet count <- 0 because it cannot be known at this + * point. Header will be correctly rewritten at the end of the read + * procedure (in gmio_stl_mesh_creator::func_end_solid() callback) + */ + const enum gmio_endianness byte_order = to_byte_order(rw_conv->out_format); + gmio_stlb_write_header(stream, byte_order, NULL, 0); + } } else { - const enum gmio_endianness byte_order = to_byte_order(rw_conv->out_format); - gmio_stlb_write_header(stream, byte_order, header, tri_count); + if (rw_conv->out_format == GMIO_STL_FORMAT_ASCII) { + stream->func_write(stream->cookie, "solid\n", 1, 6); + } + else { + gmio_stlb_write_header( + 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.func_ascii_begin_solid = &readwrite_ascii_begin_solid; - mesh_creator.func_binary_begin_solid = &readwrite_binary_begin_solid; + mesh_creator.func_begin_solid = &readwrite_begin_solid; mesh_creator.func_add_triangle = &readwrite_add_triangle; mesh_creator.func_end_solid = &readwrite_end_solid; diff --git a/benchmarks/benchmark_opencascade/main.cpp b/benchmarks/benchmark_opencascade/main.cpp index 99693b5..095bf90 100644 --- a/benchmarks/benchmark_opencascade/main.cpp +++ b/benchmarks/benchmark_opencascade/main.cpp @@ -59,9 +59,10 @@ Handle_StlMesh_Mesh stlMesh; static void stl_read(const void* filepath) { stlMesh = new StlMesh_Mesh; - gmio_stl_read_args read = {}; - read.mesh_creator = gmio_stl_hnd_occmesh_creator(stlMesh); - int error = gmio_stl_read_file(&read, static_cast(filepath)); + const int error = gmio_stl_read_file( + static_cast(filepath), + gmio_stl_hnd_occmesh_creator(stlMesh), + NULL); if (error != GMIO_ERROR_OK) 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) { const gmio_occ_stl_mesh_domain occ_mesh_domain(stlMesh); - gmio_stl_write_args write = {}; - write.mesh = gmio_stl_occmesh(&occ_mesh_domain); - write.options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_UPPERCASE; - write.options.stla_float32_prec = 7; + gmio_stl_write_options options = {}; + options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_UPPERCASE; + options.stla_float32_prec = 7; const int error = - gmio_stl_write_file(&write, format, static_cast(filepath)); + gmio_stl_write_file( + format, + static_cast(filepath), + gmio_stl_occmesh(&occ_mesh_domain), + &options); if (error != GMIO_ERROR_OK) printf("gmio error: 0x%X\n", error); } diff --git a/src/gmio_stl/internal/helper_stl_mesh_creator.h b/src/gmio_stl/internal/helper_stl_mesh_creator.h index 0ee06fd..f90628f 100644 --- a/src/gmio_stl/internal/helper_stl_mesh_creator.h +++ b/src/gmio_stl/internal/helper_stl_mesh_creator.h @@ -19,27 +19,13 @@ #include "../stl_mesh_creator.h" /*! Safe and convenient function for - * gmio_stl_mesh_creator::func_ascii_begin_solid() */ -GMIO_INLINE void gmio_stl_mesh_creator_ascii_begin_solid( + * gmio_stl_mesh_creator::func_begin_solid() */ +GMIO_INLINE void gmio_stl_mesh_creator_begin_solid( struct gmio_stl_mesh_creator* creator, - gmio_streamsize_t stream_size, - const char* solid_name) + const struct gmio_stl_mesh_creator_infos* infos) { - if (creator != NULL && creator->func_ascii_begin_solid != NULL) { - creator->func_ascii_begin_solid( - 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); + if (creator != NULL && creator->func_begin_solid != NULL) + creator->func_begin_solid(creator->cookie, infos); } /*! Safe and convenient function for diff --git a/src/gmio_stl/stl_mesh_creator.h b/src/gmio_stl/stl_mesh_creator.h index f184691..16733ec 100644 --- a/src/gmio_stl/stl_mesh_creator.h +++ b/src/gmio_stl/stl_mesh_creator.h @@ -24,14 +24,50 @@ #define GMIO_STL_MESH_CREATOR_H #include "stl_global.h" +#include "stl_format.h" #include "stl_triangle.h" #include "stlb_header.h" #include "../gmio_core/stream.h" #include +/*! 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) - * user mesh */ + * user mesh */ struct gmio_stl_mesh_creator { /*! Opaque pointer on the user mesh, passed as first argument to hook @@ -40,30 +76,9 @@ struct gmio_stl_mesh_creator /* All function pointers are optional (ie can be set to NULL) */ - /*! Pointer on a function that handles declaration of a solid of - * name \p solid_name - * - * 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); + /*! Optional pointer on a function that handles declaration of a solid */ + void (*func_begin_solid)( + void* cookie, const struct gmio_stl_mesh_creator_infos* infos); /*! Pointer on a function that adds a triangle to the user mesh * diff --git a/src/gmio_stl/stla_read.c b/src/gmio_stl/stla_read.c index d6a9880..3fb9579 100644 --- a/src/gmio_stl/stla_read.c +++ b/src/gmio_stl/stla_read.c @@ -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_parse_solidname_beg(data) == 0) { - gmio_stl_mesh_creator_ascii_begin_solid( - data->creator, - data->strstream_cookie.stream_size, - data->strbuff.ptr); + struct gmio_stl_mesh_creator_infos infos = {0}; + infos.format = GMIO_STL_FORMAT_ASCII; + infos.stla_solid_name = data->strbuff.ptr; + infos.stla_stream_size = data->strstream_cookie.stream_size; + gmio_stl_mesh_creator_begin_solid(data->creator, &infos); return 0; } } diff --git a/src/gmio_stl/stlb_read.c b/src/gmio_stl/stlb_read.c index 9054b85..d2ed88c 100644 --- a/src/gmio_stl/stlb_read.c +++ b/src/gmio_stl/stlb_read.c @@ -139,8 +139,16 @@ int gmio_stlb_read( total_facet_count = gmio_uint32_bswap(total_facet_count); /* 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 */ gmio_task_iface_handle_progress(task, 0, total_facet_count); diff --git a/tests/stl_utils.c b/tests/stl_utils.c index 6e1f12e..e0ebc9e 100644 --- a/tests/stl_utils.c +++ b/tests/stl_utils.c @@ -44,34 +44,35 @@ struct gmio_stl_triangle_array gmio_stl_triangle_array_malloc(size_t tri_count) return array; } -static void gmio_stl_data__ascii_begin_solid( - void* cookie, gmio_streamsize_t stream_size, const char* solid_name) +static void gmio_stl_data__begin_solid( + void* cookie, const struct gmio_stl_mesh_creator_infos* infos) { struct gmio_stl_data* data = (struct gmio_stl_data*)cookie; - memset(data->solid_name, 0, sizeof(data->solid_name)); - if (solid_name != NULL) { - const size_t len = - GMIO_MIN(sizeof(data->solid_name), strlen(solid_name)); - strncpy(data->solid_name, solid_name, len); - } + if (infos->format == GMIO_STL_FORMAT_ASCII) { + memset(data->solid_name, 0, sizeof(data->solid_name)); + if (infos->stla_solid_name != NULL) { + const size_t len = + GMIO_MIN(sizeof(data->solid_name), + 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 - * for each face */ - { - const size_t facet_size = 200; - const size_t facet_count = - gmio_streamsize_to_size(GMIO_MAX(1, stream_size / facet_size)); - data->tri_array = gmio_stl_triangle_array_malloc(facet_count); + /* Try to guess how many vertices we could have assume we'll need + * 200 bytes for each face */ + { + const size_t facet_size = 200; + const size_t facet_count = + gmio_streamsize_to_size( + GMIO_MAX(1, infos->stla_stream_size / facet_size)); + data->tri_array = gmio_stl_triangle_array_malloc(facet_count); + } + } + else { + memcpy(&data->header, infos->stlb_header, GMIO_STLB_HEADER_SIZE); + data->tri_array = + gmio_stl_triangle_array_malloc(infos->stlb_triangle_count); } -} - -static void gmio_stl_data__binary_begin_solid( - void* cookie, uint32_t tri_count, const struct gmio_stlb_header* header) -{ - 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( @@ -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}; creator.cookie = data; - creator.func_ascii_begin_solid = &gmio_stl_data__ascii_begin_solid; - creator.func_binary_begin_solid = &gmio_stl_data__binary_begin_solid; + creator.func_begin_solid = &gmio_stl_data__begin_solid; creator.func_add_triangle = &gmio_stl_data__add_triangle; return creator; } diff --git a/tests/test_stl_infos.c b/tests/test_stl_infos.c index cf3c2df..faf6ca5 100644 --- a/tests/test_stl_infos.c +++ b/tests/test_stl_infos.c @@ -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); int error = GMIO_ERROR_OK; - printf("\n%s\n", test->filepath); - error = gmio_stl_infos_get(&infos, stream, GMIO_STL_INFO_FLAG_ALL, NULL); if (test->format != GMIO_STL_FORMAT_UNKNOWN) { 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); if (test->expected_size != -2) - UTEST_COMPARE_UINT(expected_size, infos.size); + UTEST_COMPARE_INT(expected_size, infos.size); return NULL; } diff --git a/tests/test_stl_io.c b/tests/test_stl_io.c index d05c049..bb122ef 100644 --- a/tests/test_stl_io.c +++ b/tests/test_stl_io.c @@ -35,15 +35,16 @@ struct stl_testcase_result char solid_name[2048]; }; -void stl_testcase_result__ascii_begin_solid( - void* cookie, gmio_streamsize_t stream_size, const char* solid_name) +void stl_testcase_result__begin_solid( + void* cookie, const struct gmio_stl_mesh_creator_infos* infos) { - struct stl_testcase_result* res = (struct stl_testcase_result*)cookie; - GMIO_UNUSED(stream_size); - if (res != NULL) { - res->solid_name[0] = 0; - if (solid_name != NULL) - strcpy(res->solid_name, solid_name); + if (infos->format == GMIO_STL_FORMAT_ASCII) { + struct stl_testcase_result* res = (struct stl_testcase_result*)cookie; + if (res != NULL) { + res->solid_name[0] = 0; + if (infos->stla_solid_name != NULL) + strcpy(res->solid_name, infos->stla_solid_name); + } } } @@ -131,7 +132,7 @@ const char* test_stl_read() struct stl_testcase_result result = {0}; 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; for (i = 0; i < expected_count; ++i) {