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;
}
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<aiSceneHelper*>(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<unsigned>(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("<STL_BINARY>");
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<unsigned>(infos->stla_stream_size) / 200u;
pMesh->mNumFaces = std::max(1u, estimatedFacetCount);
}
else {
helper->hasToCountTriangle = 0; // false
pScene->mRootNode->mName.Set("<STL_BINARY>");
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<aiSceneHelper*>(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<aiSceneHelper*>(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<const aiMesh*>(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<const char*>(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;

View File

@ -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;

View File

@ -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<const char*>(filepath));
const int error = gmio_stl_read_file(
static_cast<const char*>(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<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)
printf("gmio error: 0x%X\n", error);
}

View File

@ -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

View File

@ -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 <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)
* 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
*

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_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;
}
}

View File

@ -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);

View File

@ -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;
}

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);
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;
}

View File

@ -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) {