gmio/src/gmio_stl/stlb_read.c

159 lines
5.6 KiB
C
Raw Normal View History

2015-03-03 00:38:33 +08:00
/****************************************************************************
2015-05-28 15:40:24 +08:00
** gmio
2015-05-01 00:19:45 +08:00
** Copyright Fougue (2 Mar. 2015)
2015-07-13 17:42:03 +08:00
** contact@fougue.pro
2015-03-03 00:38:33 +08:00
**
** This software is a reusable library whose purpose is to provide complete
** I/O support for various CAD file formats (eg. STL)
**
** This software is governed by the CeCILL-B license under French law and
** abiding by the rules of distribution of free software. You can use,
** modify and/ or redistribute the software under the terms of the CeCILL-B
** license as circulated by CEA, CNRS and INRIA at the following URL
2015-03-30 15:05:25 +08:00
** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html".
2015-03-03 00:38:33 +08:00
****************************************************************************/
#include "stl_io.h"
#include "stl_error.h"
#include "internal/helper_stl_mesh_creator.h"
#include "internal/stl_funptr_typedefs.h"
#include "internal/stl_rw_common.h"
#include "internal/stlb_byte_swap.h"
#include "../gmio_core/endian.h"
#include "../gmio_core/error.h"
#include "../gmio_core/internal/byte_swap.h"
#include "../gmio_core/internal/convert.h"
#include "../gmio_core/internal/helper_rwargs.h"
#include "../gmio_core/internal/helper_stream.h"
#include "../gmio_core/internal/safe_cast.h"
#include <string.h>
2015-03-31 16:10:26 +08:00
GMIO_INLINE void read_triangle_memcpy(
const uint8_t* buffer, struct gmio_stl_triangle* triangle)
{
/* *triangle = *((struct gmio_stl_triangle*)(buffer)); */
2015-03-03 17:35:36 +08:00
memcpy(triangle, buffer, GMIO_STLB_TRIANGLE_RAWSIZE);
}
2015-03-20 00:31:08 +08:00
static void gmio_stlb_read_facets(
struct gmio_stl_mesh_creator* creator,
2015-03-20 00:31:08 +08:00
const uint8_t* buffer,
const struct gmio_stlb_readwrite_helper* rparams)
{
2015-03-03 17:35:36 +08:00
const uint32_t facet_count = rparams->facet_count;
const uint32_t i_facet_offset = rparams->i_facet_offset;
const gmio_stl_triangle_func_fix_endian_t func_fix_endian =
rparams->func_fix_endian;
/* coverity[var_deref_op : FALSE] */
const gmio_stl_mesh_creator_func_add_triangle_t func_add_triangle =
creator != NULL ? creator->func_add_triangle : NULL;
void* cookie = creator->cookie;
struct gmio_stl_triangle triangle;
2015-03-03 17:35:36 +08:00
uint32_t buffer_offset = 0;
uint32_t i_facet = 0;
if (func_add_triangle == NULL)
2015-03-03 17:35:36 +08:00
return;
for (i_facet = 0; i_facet < facet_count; ++i_facet) {
read_triangle_memcpy(buffer + buffer_offset, &triangle);
buffer_offset += GMIO_STLB_TRIANGLE_RAWSIZE;
if (func_fix_endian != NULL)
func_fix_endian(&triangle);
2015-03-03 17:35:36 +08:00
func_add_triangle(cookie, i_facet_offset + i_facet, &triangle);
2015-03-03 17:35:36 +08:00
}
}
2015-03-20 00:31:08 +08:00
int gmio_stlb_read(
2015-12-10 01:51:03 +08:00
struct gmio_stl_read_args* args, enum gmio_endianness byte_order)
{
2015-03-20 00:31:08 +08:00
/* Constants */
2015-03-03 17:35:36 +08:00
const uint32_t max_facet_count_per_read =
args != NULL ?
gmio_size_to_uint32(
2015-12-10 01:51:03 +08:00
args->core.memblock.size / GMIO_STLB_TRIANGLE_RAWSIZE)
: 0;
2015-03-20 00:31:08 +08:00
/* Variables */
2015-12-10 01:51:03 +08:00
struct gmio_rwargs* core_args =
args != NULL ? &args->core : NULL;
struct gmio_stl_mesh_creator* mesh_creator =
args != NULL ? &args->mesh_creator : NULL;
void* mblock_ptr =
core_args != NULL ? core_args->memblock.ptr : NULL;
struct gmio_stlb_readwrite_helper rparams = {0};
struct gmio_stlb_header header;
2015-03-20 00:31:08 +08:00
uint32_t total_facet_count = 0; /* Facet count, as declared in the stream */
int error = GMIO_ERROR_OK; /* Helper to store function result error code */
2015-03-03 17:35:36 +08:00
/* Check validity of input parameters */
2015-12-10 01:51:03 +08:00
if (!gmio_stlb_check_params(&error, core_args, byte_order))
2015-03-03 17:35:36 +08:00
return error;
/* Initialize rparams */
if (byte_order != GMIO_ENDIANNESS_HOST)
rparams.func_fix_endian = gmio_stl_triangle_bswap;
2015-03-03 17:35:36 +08:00
/* Read header */
2015-12-10 01:51:03 +08:00
if (gmio_stream_read(&core_args->stream, &header, GMIO_STLB_HEADER_SIZE, 1)
!= 1)
2015-03-03 17:35:36 +08:00
{
return GMIO_STL_ERROR_HEADER_WRONG_SIZE;
2015-03-03 17:35:36 +08:00
}
2015-03-03 17:35:36 +08:00
/* Read facet count */
2015-12-10 01:51:03 +08:00
if (gmio_stream_read(&core_args->stream, mblock_ptr, sizeof(uint32_t), 1)
!= 1)
{
return GMIO_STL_ERROR_FACET_COUNT;
}
2015-03-03 17:35:36 +08:00
2015-09-25 19:16:41 +08:00
memcpy(&total_facet_count, mblock_ptr, sizeof(uint32_t));
if (byte_order != GMIO_ENDIANNESS_HOST)
2015-03-03 17:35:36 +08:00
total_facet_count = gmio_uint32_bswap(total_facet_count);
/* Callback to notify triangle count and header data */
gmio_stl_mesh_creator_binary_begin_solid(
2015-12-10 01:51:03 +08:00
mesh_creator, total_facet_count, &header);
2015-03-03 17:35:36 +08:00
/* Read triangles */
while (gmio_no_error(error)
&& rparams.i_facet_offset < total_facet_count)
{
gmio_rwargs_handle_progress(
2015-12-10 01:51:03 +08:00
core_args, rparams.i_facet_offset, total_facet_count);
2015-03-03 17:35:36 +08:00
rparams.facet_count =
gmio_size_to_uint32(
gmio_stream_read(
2015-12-10 01:51:03 +08:00
&core_args->stream,
2015-09-25 19:16:41 +08:00
mblock_ptr,
2015-03-03 17:35:36 +08:00
GMIO_STLB_TRIANGLE_RAWSIZE,
max_facet_count_per_read));
2015-12-10 01:51:03 +08:00
if (gmio_stream_error(&core_args->stream) != 0)
error = GMIO_ERROR_STREAM;
2015-03-03 17:35:36 +08:00
else if (rparams.facet_count > 0)
error = GMIO_ERROR_OK;
2015-03-03 17:35:36 +08:00
else
break; /* Exit if no facet to read */
if (gmio_no_error(error)) {
2015-12-10 01:51:03 +08:00
gmio_stlb_read_facets(mesh_creator, mblock_ptr, &rparams);
2015-03-03 17:35:36 +08:00
rparams.i_facet_offset += rparams.facet_count;
2015-12-10 01:51:03 +08:00
if (gmio_rwargs_is_stop_requested(core_args))
error = GMIO_ERROR_TRANSFER_STOPPED;
2015-03-03 17:35:36 +08:00
}
} /* end while */
if (gmio_no_error(error))
2015-12-10 01:51:03 +08:00
gmio_stl_mesh_creator_end_solid(mesh_creator);
2015-03-03 17:35:36 +08:00
if (gmio_no_error(error) && rparams.i_facet_offset != total_facet_count)
error = GMIO_STL_ERROR_FACET_COUNT;
2015-03-03 17:35:36 +08:00
return error;
}