From 764afc79252affeedaaa2b671320975fb80c0942 Mon Sep 17 00:00:00 2001 From: Hugues Delorme Date: Tue, 1 Mar 2016 17:05:52 +0100 Subject: [PATCH] Add examples --- examples/3d_mesh.h | 26 ++++++ examples/occstl_read_file.cpp | 38 ++++++++ examples/occstl_redefine_mesh_creator.cpp | 54 ++++++++++++ examples/occstl_write_file.cpp | 44 ++++++++++ examples/stl_read_file.c | 102 ++++++++++++++++++++++ examples/stl_write_file.c | 67 ++++++++++++++ 6 files changed, 331 insertions(+) create mode 100644 examples/3d_mesh.h create mode 100644 examples/occstl_read_file.cpp create mode 100644 examples/occstl_redefine_mesh_creator.cpp create mode 100644 examples/occstl_write_file.cpp create mode 100644 examples/stl_read_file.c create mode 100644 examples/stl_write_file.c diff --git a/examples/3d_mesh.h b/examples/3d_mesh.h new file mode 100644 index 0000000..dd4d676 --- /dev/null +++ b/examples/3d_mesh.h @@ -0,0 +1,26 @@ +#ifndef GMIO_EXAMPLES_3D_MESH_H +#define GMIO_EXAMPLES_3D_MESH_H + +#include + +/* User-defined 3D point */ +struct my_3d_point +{ + double coords[3]; +}; + +/* User-defined 3D triangle */ +struct my_3d_triangle +{ + struct my_3d_point vertex[3]; +}; + +/* An example of user-defined 3D mesh */ +struct my_3d_mesh +{ + struct my_3d_triangle* triangle_array; + size_t triangle_array_count; + size_t triangle_array_capacity; +}; + +#endif /* GMIO_EXAMPLES_3D_MESH_H */ diff --git a/examples/occstl_read_file.cpp b/examples/occstl_read_file.cpp new file mode 100644 index 0000000..5a2d33b --- /dev/null +++ b/examples/occstl_read_file.cpp @@ -0,0 +1,38 @@ +/* ----------------------------------------------------------------------------- + * + * Example: read a STL file into OpenCascade StlMesh_Mesh + * + * Just give a filepath and an initialized gmio_stl_mesh_creator object to + * gmio_stl_read_file(). + * The gmio_stl_mesh_creator object holds pointers to the callbacks invoked + * during the read operation. + * These callbacks creates the final mesh object. + * + * Note if you want to have control over the stream to be used, call + * gmio_stl_read() instead. + * + * -------------------------------------------------------------------------- */ + +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + int error = 0; + if (argc > 1) { + // Path to the STL file + const char* filepath = argv[1]; + // StlMesh_Mesh object to be constructed + Handle_StlMesh_Mesh mesh = new StlMesh_Mesh; + // Holds callbacks functions + gmio_stl_mesh_creator mesh_creator = gmio_stl_occmesh_creator(mesh); + + // Read, using default options(NULL) + error = gmio_stl_read_file(filepath, &mesh_creator, NULL); + if (error != GMIO_ERROR_OK) + std::cerr << "gmio error: 0x" << std::hex << error << std::endl; + } + return error; +} diff --git a/examples/occstl_redefine_mesh_creator.cpp b/examples/occstl_redefine_mesh_creator.cpp new file mode 100644 index 0000000..ec1d0a8 --- /dev/null +++ b/examples/occstl_redefine_mesh_creator.cpp @@ -0,0 +1,54 @@ +/* ----------------------------------------------------------------------------- + * + * Example: redefine the callbacks of some gmio_stl_mesh_creator base object + * + * -------------------------------------------------------------------------- */ + +#include +#include +#include +#include + +// Redefine func_begin_solid of some gmio_stl_mesh_creator object +void my_mesh_creator__begin_solid( + void* cookie, const gmio_stl_mesh_creator_infos* infos) +{ + gmio_stl_mesh_creator* base_creator = + reinterpret_cast(cookie); + base_creator->func_begin_solid(base_creator->cookie, infos); + // Do something more ... +} + +// Redefine func_add_triangle of some gmio_stl_mesh_creator object +void my_mesh_creator__add_triangle( + void* cookie, uint32_t tri_id, const gmio_stl_triangle* triangle) +{ + gmio_stl_mesh_creator* base_creator = + reinterpret_cast(cookie); + base_creator->func_add_triangle(base_creator->cookie, tri_id, triangle); + // Do something more ... +} + +int main(int argc, char** argv) +{ + int error = 0; + if (argc > 1) { + // Path to the STL file + const char* filepath = argv[1]; + // StlMesh_Mesh object to be constructed + Handle_StlMesh_Mesh mesh = new StlMesh_Mesh; + // mesh_creator to be redefined + gmio_stl_mesh_creator base_creator = gmio_stl_occmesh_creator(mesh); + // Holds callbacks functions + gmio_stl_mesh_creator creator = {}; + creator.cookie = &base_creator; + creator.func_begin_solid = my_mesh_creator__begin_solid; + creator.func_add_triangle = my_mesh_creator__add_triangle; + + // Read, using default options(NULL) + error = gmio_stl_read_file(filepath, &creator, NULL); + if (error != GMIO_ERROR_OK) + std::cerr << "gmio error: 0x" << std::hex << error << std::endl; + } + return error; +} diff --git a/examples/occstl_write_file.cpp b/examples/occstl_write_file.cpp new file mode 100644 index 0000000..c70789d --- /dev/null +++ b/examples/occstl_write_file.cpp @@ -0,0 +1,44 @@ +/* ----------------------------------------------------------------------------- + * + * Example: write a STL file + * + * Just give the filepath and an initialized gmio_stl_mesh object to + * gmio_stl_write_file(). + * The gmio_stl_mesh object defines the interface to access the underlying user + * mesh. + * + * Note if you want to have control over the stream to be used, call + * gmio_stl_write() instead. + * + * -------------------------------------------------------------------------- */ + +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + int error = 0; + if (argc > 1) { + // Path to the STL file + const char* filepath = argv[1]; + // StlMesh_Mesh object to be constructed + Handle_StlMesh_Mesh occmesh = new StlMesh_Mesh; + + // Initialize the OpenCascade StlMesh_Mesh here + // ... + + // Will give fast access to all the triangles of the StlMesh_Mesh object + const gmio_stl_occmesh_iterator occmesh_it(occmesh); + // The gmio interface over OpenCascade's StlMesh_Mesh + const gmio_stl_mesh mesh = gmio_stl_occmesh(occmesh_it); + + // Write binary STL little-endian, using default options(NULL) + error = gmio_stl_write_file( + GMIO_STL_FORMAT_BINARY_LE, filepath, &mesh, NULL); + if (error != GMIO_ERROR_OK) + std::cerr << "gmio error: 0x" << std::hex << error << std::endl; + } + return error; +} diff --git a/examples/stl_read_file.c b/examples/stl_read_file.c new file mode 100644 index 0000000..3df51cf --- /dev/null +++ b/examples/stl_read_file.c @@ -0,0 +1,102 @@ +/* ----------------------------------------------------------------------------- + * + * Example: read a STL file + * + * Just give a filepath and an initialized gmio_stl_mesh_creator object to + * gmio_stl_read_file(). + * The gmio_stl_mesh_creator object holds pointers to the callbacks invoked + * during the read operation. + * These callbacks creates the final mesh object. + * + * Note if you want to have control over the stream to be used, call + * gmio_stl_read() instead. + * + * -------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "3d_mesh.h" + +/* Callback invoked at the beginning of mesh creation + * This is a good place to initialize your mesh object */ +static void my_3d_mesh__begin_solid( + void* cookie, const struct gmio_stl_mesh_creator_infos* infos) +{ + struct my_3d_mesh* my_mesh = (struct my_3d_mesh*)cookie; + size_t tri_count = 0; + if (infos->format == GMIO_STL_FORMAT_ASCII) /* Assume facet size ~200B */ + tri_count = infos->stla_stream_size / 200u; + else /* Binary STL */ + tri_count = infos->stlb_triangle_count; + my_mesh->triangle_array = + (struct my_3d_triangle*)malloc( + tri_count * sizeof(struct my_3d_triangle)); + my_mesh->triangle_array_count = 0; + my_mesh->triangle_array_capacity = tri_count; +} + +/* Callback invoked sequentially for each triangle in the STL mesh + * Just do something with the "triangle" passed in */ +static void my_3d_mesh__copy_triangle( + void* cookie, + uint32_t triangle_id, + const struct gmio_stl_triangle* triangle) +{ + struct my_3d_mesh* my_mesh = (struct my_3d_mesh*)cookie; + + if (triangle_id >= my_mesh->triangle_array_capacity) { + /* Capacity of the triangle array is too small, this can happen only + * when reading STL ascii data, where the count of triangles in not + * precisely known. + * To overcome this just grow capacity of the triangle array of 12.5% */ + size_t new_capacity = my_mesh->triangle_array_capacity; + new_capacity += new_capacity >> 3; + my_mesh->triangle_array = + (struct my_3d_triangle*)realloc( + my_mesh->triangle_array, + new_capacity * sizeof(struct my_3d_triangle)); + my_mesh->triangle_array_capacity = new_capacity; + } + + { /* Copy new triangle */ + struct my_3d_triangle* my_tri = &my_mesh->triangle_array[triangle_id]; + const struct gmio_stl_coords* tri_vertices = &triangle->v1; + for (int i = 0; i < 3; ++i) { + my_tri->vertex[i][0] = tri_vertices[i].x; + my_tri->vertex[i][1] = tri_vertices[i].y; + my_tri->vertex[i][2] = tri_vertices[i].z; + } + } + my_mesh->triangle_array_count = triangle_id + 1; +} + +int main(int argc, char** argv) +{ + int error = 0; + if (argc > 1) { + /* Path to the STL file */ + const char* filepath = argv[1]; + /* User-defined mesh object, to be constructed */ + struct my_3d_mesh my_mesh = {0}; + /* Holds callbacks functions */ + struct gmio_stl_mesh_creator mesh_creator = {0}; + + /* Initialize the callback object */ + /* -- Cookie object passed to callbacks of gmio_stl_mesh_creator */ + mesh_creator.cookie = &my_mesh; + /* -- Function called initially at the beginning of a STL solid(mesh) */ + mesh_creator.func_begin_solid = &my_stl_mesh__begin_solid; + /* -- Function called for each triangle in the STL mesh */ + mesh_creator.func_add_triangle = &my_stl_mesh__copy_triangle; + + /* Read, using default options(NULL) */ + error = gmio_stl_read_file(filepath, &mesh_creator, NULL); + if (error != GMIO_ERROR_OK) + fprintf(stderr, "gmio error: 0x%X\n", error); + + free(my_mesh.triangle_array); + } + return error; +} diff --git a/examples/stl_write_file.c b/examples/stl_write_file.c new file mode 100644 index 0000000..97f3f1f --- /dev/null +++ b/examples/stl_write_file.c @@ -0,0 +1,67 @@ +/* ----------------------------------------------------------------------------- + * + * Example: write a STL file + * + * Just give the filepath and an initialized gmio_stl_mesh object to + * gmio_stl_write_file(). + * The gmio_stl_mesh object defines the interface to access the underlying user + * mesh. + * + * Note if you want to have control over the stream to be used, call + * gmio_stl_write() instead. + * + * -------------------------------------------------------------------------- */ + +#include +#include +#include +#include "3d_mesh.h" + +/* Callback invoked sequentially for each triangle in the STL mesh + * Just transfer the triangle of index 'tri_id' into 'triangle' */ +static void my_3d_mesh__get_triangle( + const void* cookie, uint32_t tri_id, struct gmio_stl_triangle* triangle) +{ + const struct my_3d_mesh* my_mesh = (const struct my_3d_mesh*)cookie; + const struct my_3d_triangle* my_tri = &my_mesh->triangle_array[tri_id]; + struct gmio_stl_coords* tri_vertices = &triangle->v1; + for (int i = 0; i < 3; ++i) { + tri_vertices[i].x = my_tri[i][0]; + tri_vertices[i].y = my_tri[i][1]; + tri_vertices[i].z = my_tri[i][2]; + } + gmio_stl_triangle_compute_normal(triangle); +} + +int main(int argc, char** argv) +{ + int error = 0; + if (argc > 1) { + /* Path to the STL file */ + const char* filepath = argv[1]; + /* User-defined mesh object */ + struct my_3d_mesh my_mesh = {0}; + /* The interface to the user-defined mesh object */ + struct gmio_stl_mesh mesh = {0}; + + /* Construct the user mesh */ + /* ... */ + + /* Initialize the mesh interface */ + /* -- Cookie object passed to callbacks of gmio_stl_mesh */ + mesh.cookie = &my_mesh; + /* -- Count of triangles in the mesh */ + mesh.triangle_count = my_mesh.facet_count; + /* -- Pointer on a function that retrieves a triangle from the mesh */ + mesh.func_get_triangle = &my_3d_mesh__get_triangle; + + /* Write binary STL little-endian, using default options(NULL) */ + error = gmio_stl_write_file( + GMIO_STL_FORMAT_BINARY_LE, filepath, &mesh, NULL); + if (error != GMIO_ERROR_OK) + fprintf(stderr, "gmio error: 0x%X\n", error); + + free(my_mesh.triangle_array); + } + return 0; +}