diff --git a/src/gmio_core/internal/vecgeom_utils.h b/src/gmio_core/internal/vecgeom_utils.h new file mode 100644 index 0000000..e21a1e2 --- /dev/null +++ b/src/gmio_core/internal/vecgeom_utils.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** gmio +** Copyright Fougue (2 Mar. 2015) +** contact@fougue.pro +** +** 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 +** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". +****************************************************************************/ + +#ifndef GMIO_INTERNAL_VECGEOM_UTILS_H +#define GMIO_INTERNAL_VECGEOM_UTILS_H + +#include "../global.h" + +/*! Cross product of float32 vectors (ux,uy,uz) and (vx,vy,vz) */ +GMIO_INLINE void gmio_cross_product_f32( + float ux, float uy, float uz, + float vx, float vy, float vz, + float* nx, float* ny, float* nz); + +/*! Cross product of float64 vectors (ux,uy,uz) and (vx,vy,vz) */ +GMIO_INLINE void gmio_cross_product_f64( + double ux, double uy, double uz, + double vx, double vy, double vz, + double* nx, double* ny, double* nz); + + +/* + * Implementation + */ + +void gmio_cross_product_f32( + float ux, float uy, float uz, + float vx, float vy, float vz, + float* nx, float* ny, float* nz) +{ + *nx = uy*vz - uz*vx; + *ny = uz*vx - ux*vz; + *nz = ux*vy - uy*vx; + { + const float d = (float)sqrt((*nx)*(*nx) + (*ny)*(*ny) + (*nz)*(*nz)); + if (d > 0.f) { + *nx /= d; + *ny /= d; + *nz /= d; + } + } +} + +void gmio_cross_product_f64( + double ux, double uy, double uz, + double vx, double vy, double vz, + double* nx, double* ny, double* nz) +{ + *nx = uy*vz - uz*vx; + *ny = uz*vx - ux*vz; + *nz = ux*vy - uy*vx; + { + const double d = sqrt((*nx)*(*nx) + (*ny)*(*ny) + (*nz)*(*nz)); + if (d > 0.) { + *nx /= d; + *ny /= d; + *nz /= d; + } + } +} + +#endif /* GMIO_INTERNAL_VECGEOM_UTILS_H */ diff --git a/src/gmio_stl/stl_triangle.c b/src/gmio_stl/stl_triangle.c new file mode 100644 index 0000000..58e919c --- /dev/null +++ b/src/gmio_stl/stl_triangle.c @@ -0,0 +1,36 @@ +/**************************************************************************** +** gmio +** Copyright Fougue (2 Mar. 2015) +** contact@fougue.pro +** +** 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 +** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". +****************************************************************************/ + +#include "stl_triangle.h" + +#include "../gmio_core/internal/vecgeom_utils.h" + +GMIO_INLINE struct gmio_stl_coords gmio_stl_coords_diff( + const struct gmio_stl_coords* u, const struct gmio_stl_coords* v) +{ + struct gmio_stl_coords diff; + diff.x = u->x - v->x; + diff.y = u->y - v->y; + diff.z = u->z - v->z; + return diff; +} + +void gmio_stl_triangle_compute_normal(struct gmio_stl_triangle* tri) +{ + const struct gmio_stl_coords u = gmio_stl_coords_diff(&tri->v2, &tri->v1); + const struct gmio_stl_coords v = gmio_stl_coords_diff(&tri->v3, &tri->v1); + struct gmio_stl_coords* n = &tri->n; + gmio_cross_product_f32(u.x, u.y, u.z, v.x, v.y, v.z, &n->x, &n->y, &n->z); +} diff --git a/src/gmio_stl/stl_triangle.h b/src/gmio_stl/stl_triangle.h index f4b2ac3..ae8aafd 100644 --- a/src/gmio_stl/stl_triangle.h +++ b/src/gmio_stl/stl_triangle.h @@ -45,5 +45,13 @@ struct gmio_stl_triangle uint16_t attribute_byte_count; /*!< Useful only for STL binary format */ }; +GMIO_C_LINKAGE_BEGIN + +/*! Computes the normal vector of triangle \p tri */ +GMIO_LIBSTL_EXPORT +void gmio_stl_triangle_compute_normal(struct gmio_stl_triangle* tri); + +GMIO_C_LINKAGE_END + #endif /* GMIO_STL_TRIANGLE_H */ /*! @} */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6eed3cc..6c52acc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -53,8 +53,9 @@ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/models set(GMIO_TEST_STL_SRC main_test_stl.c test_stl_internal.c - test_stl_io.c test_stl_infos.c + test_stl_io.c + test_stl_triangle.c test_stlb_header.c core_utils.c stl_utils.c) diff --git a/tests/main_test_core.c b/tests/main_test_core.c index 0624e09..8ebd172 100644 --- a/tests/main_test_core.c +++ b/tests/main_test_core.c @@ -28,7 +28,6 @@ const char* test_internal__stringstream(); const char* test_internal__string_utils(); const char* test_internal__benchmark_gmio_fast_atof(); -const char* test_platform__alignment(); const char* test_platform__global_h(); const char* test_platform__compiler(); @@ -49,7 +48,6 @@ const char* all_tests() UTEST_RUN(test_internal__string_utils); UTEST_RUN(test_internal__benchmark_gmio_fast_atof); - UTEST_RUN(test_platform__alignment); UTEST_RUN(test_platform__global_h); UTEST_RUN(test_platform__compiler); diff --git a/tests/main_test_stl.c b/tests/main_test_stl.c index 0b6f7ae..2e08dd1 100644 --- a/tests/main_test_stl.c +++ b/tests/main_test_stl.c @@ -15,6 +15,10 @@ #include "utest_lib.h" +const char* test_stl_coords_packing(); +const char* test_stl_triangle_packing(); +const char* test_stl_triangle_compute_normal(); + const char* test_stl_internal__rw_common(); const char* test_stl_infos(); @@ -31,13 +35,19 @@ const char* all_tests() { UTEST_SUITE_START(); + UTEST_RUN(test_stl_coords_packing); + UTEST_RUN(test_stl_triangle_packing); + UTEST_RUN(test_stl_triangle_compute_normal); + UTEST_RUN(test_stl_internal__rw_common); UTEST_RUN(test_stl_infos); + UTEST_RUN(test_stl_read); UTEST_RUN(test_stla_write); UTEST_RUN(test_stlb_write_header); UTEST_RUN(test_stlb_write); + UTEST_RUN(test_stlb_header_str); UTEST_RUN(test_stlb_header_to_printable_str); diff --git a/tests/test_core_platform.c b/tests/test_core_platform.c index e94f02d..4ac0b5e 100644 --- a/tests/test_core_platform.c +++ b/tests/test_core_platform.c @@ -17,8 +17,6 @@ #include "../src/gmio_core/global.h" #include "../src/gmio_core/stream.h" -#include "../src/gmio_stl/stl_constants.h" -#include "../src/gmio_stl/stl_triangle.h" #include #include @@ -26,23 +24,6 @@ /* Disable MSVC warning "conditional expression is constant" */ GMIO_PRAGMA_MSVC_WARNING_PUSH_AND_DISABLE(4127) -const char* test_platform__alignment() -{ - UTEST_ASSERT(offsetof(struct gmio_stl_coords, x) == 0); - UTEST_ASSERT(offsetof(struct gmio_stl_coords, y) == 4); - UTEST_ASSERT(offsetof(struct gmio_stl_coords, z) == 8); - UTEST_ASSERT(sizeof(struct gmio_stl_coords) == GMIO_STL_COORDS_RAWSIZE); - - UTEST_ASSERT(offsetof(struct gmio_stl_triangle, n) == 0); - UTEST_ASSERT(offsetof(struct gmio_stl_triangle, v1) == GMIO_STL_COORDS_RAWSIZE); - UTEST_ASSERT(offsetof(struct gmio_stl_triangle, v2) == 2*GMIO_STL_COORDS_RAWSIZE); - UTEST_ASSERT(offsetof(struct gmio_stl_triangle, v3) == 3*GMIO_STL_COORDS_RAWSIZE); - UTEST_ASSERT(offsetof(struct gmio_stl_triangle, attribute_byte_count) == 4*GMIO_STL_COORDS_RAWSIZE); - UTEST_ASSERT(sizeof(struct gmio_stl_triangle) >= GMIO_STLB_TRIANGLE_RAWSIZE); - - return NULL; -} - const char* test_platform__global_h() { UTEST_ASSERT(sizeof(int8_t) == 1); diff --git a/tests/test_stl_triangle.c b/tests/test_stl_triangle.c new file mode 100644 index 0000000..0b7f720 --- /dev/null +++ b/tests/test_stl_triangle.c @@ -0,0 +1,59 @@ +/**************************************************************************** +** gmio +** Copyright Fougue (2 Mar. 2015) +** contact@fougue.pro +** +** 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 +** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". +****************************************************************************/ + +#include "utest_assert.h" + +#include "../src/gmio_stl/stl_constants.h" +#include "../src/gmio_stl/stl_triangle.h" + +#include +#include + +/* Disable MSVC warning "conditional expression is constant" */ +GMIO_PRAGMA_MSVC_WARNING_PUSH_AND_DISABLE(4127) + +const char* test_stl_coords_packing() +{ + UTEST_COMPARE_UINT(0, offsetof(struct gmio_stl_coords, x)); + UTEST_COMPARE_UINT(4, offsetof(struct gmio_stl_coords, y)); + UTEST_COMPARE_UINT(8, offsetof(struct gmio_stl_coords, z)); + UTEST_COMPARE_UINT(GMIO_STL_COORDS_RAWSIZE, sizeof(struct gmio_stl_coords)); + return NULL; +} + +const char* test_stl_triangle_packing() +{ + UTEST_COMPARE_UINT(0, offsetof(struct gmio_stl_triangle, n)); + UTEST_COMPARE_UINT(GMIO_STL_COORDS_RAWSIZE, offsetof(struct gmio_stl_triangle, v1)); + UTEST_COMPARE_UINT(2*GMIO_STL_COORDS_RAWSIZE, offsetof(struct gmio_stl_triangle, v2)); + UTEST_COMPARE_UINT(3*GMIO_STL_COORDS_RAWSIZE, offsetof(struct gmio_stl_triangle, v3)); + UTEST_COMPARE_UINT(4*GMIO_STL_COORDS_RAWSIZE, offsetof(struct gmio_stl_triangle, attribute_byte_count)); + UTEST_ASSERT(sizeof(struct gmio_stl_triangle) >= GMIO_STLB_TRIANGLE_RAWSIZE); + return NULL; +} + +const char* test_stl_triangle_compute_normal() +{ + { /* Doesn't fail on invalid facet */ + const struct gmio_stl_coords null_coords = {0}; + struct gmio_stl_triangle tri = {0}; + gmio_stl_triangle_compute_normal(&tri); + UTEST_ASSERT(memcmp(&tri.n, &null_coords, sizeof(struct gmio_stl_triangle)) + == 0); + } + return NULL; +} + +GMIO_PRAGMA_MSVC_WARNING_POP()