star-uvm

Spatial structuring of unstructured volumetric meshes
git clone git://git.meso-star.fr/star-uvm.git
Log | Files | Refs | README | LICENSE

commit 4bc52ec46c917821897244cbb059ca4438af29f5
parent 034371c6de126ed6e76fbcb8bd9846ee2df2b7d1
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 12 Oct 2020 11:09:09 +0200

Check vertex ordering on tetrahedral mesh creation

Diffstat:
Msrc/suvm_volume.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+), 0 deletions(-)

diff --git a/src/suvm_volume.c b/src/suvm_volume.c @@ -425,6 +425,68 @@ error: goto exit; } +static res_T +check_tetrahedra_normals(const struct suvm_volume* vol) +{ + size_t itetra, ntetra; + res_T res = RES_OK; + ASSERT(vol); + + ntetra = volume_get_primitives_count(vol); + + FOR_EACH(itetra, 0, ntetra) { + const uint32_t* ids = NULL; + const float* verts[4]; + float normals[4][3]; + float pt[3]; + float v0[3], v1[3]; + + + /* Fetch tetrahedron indices */ + ids = darray_u32_cdata_get(&vol->indices) + itetra*4; + ASSERT(ids[0] < volume_get_vertices_count(vol)); + ASSERT(ids[1] < volume_get_vertices_count(vol)); + ASSERT(ids[2] < volume_get_vertices_count(vol)); + ASSERT(ids[3] < volume_get_vertices_count(vol)); + + /* Fetch the tetrahedron vertices */ + verts[0] = darray_float_cdata_get(&vol->positions) + ids[0]*3/*#coords*/; + verts[1] = darray_float_cdata_get(&vol->positions) + ids[1]*3/*#coords*/; + verts[2] = darray_float_cdata_get(&vol->positions) + ids[2]*3/*#coords*/; + verts[3] = darray_float_cdata_get(&vol->positions) + ids[3]*3/*#coords*/; + + /* Fetch the tetrahedron normals */ + volume_get_tetrahedron_normal(vol, itetra, 0, normals[0]); + volume_get_tetrahedron_normal(vol, itetra, 1, normals[1]); + volume_get_tetrahedron_normal(vol, itetra, 2, normals[2]); + volume_get_tetrahedron_normal(vol, itetra, 3, normals[3]); + + /* Compute the position at the center of the tetrahedron */ + pt[0] = (verts[0][0] + verts[1][0] + verts[2][0] + verts[3][0]) * 0.25f; + pt[1] = (verts[0][1] + verts[1][1] + verts[2][1] + verts[3][1]) * 0.25f; + pt[2] = (verts[0][2] + verts[1][2] + verts[2][2] + verts[3][2]) * 0.25f; + + /* Check that normals look toward the tetrahedron center */ + f3_sub(v0, pt, verts[0]); + f3_sub(v1, pt, verts[3]); + if(f3_dot(normals[0], v0) < 0 + || f3_dot(normals[1], v1) < 0 + || f3_dot(normals[2], v1) < 0 + || f3_dot(normals[3], v1) < 0) { + log_err(vol->dev, + "Invalid vertex orientation for the tetrahedron %lu.\n", + (unsigned long)itetra); + res = RES_BAD_ARG; + goto error; + } + } + +exit: + return res; +error: + goto exit; +} + static void volume_release(ref_T* ref) { @@ -476,6 +538,11 @@ suvm_tetrahedral_mesh_create res = setup_tetrahedral_mesh(vol, args); if(res != RES_OK) goto error; + /* Ensure that the vertices of the tetrahedra are well ordered regarding the + * normal convention */ + res = check_tetrahedra_normals(vol); + if(res != RES_OK) goto error; + /* Build the BVH of the volumetric mesh */ res = build_bvh(vol); if(res != RES_OK) goto error;