gmio_stl: add utility function gmio_stl_triangle_compute_normal()

This commit is contained in:
Hugues Delorme 2016-02-05 12:20:14 +01:00
parent 07fdbb81f3
commit f6b71695c0
8 changed files with 189 additions and 22 deletions

View File

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

View File

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

View File

@ -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 */
/*! @} */

View File

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

View File

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

View File

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

View File

@ -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 <stddef.h>
#include <string.h>
@ -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);

59
tests/test_stl_triangle.c Normal file
View File

@ -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 <stddef.h>
#include <string.h>
/* 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()