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:
| M | src/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;