star-uvm

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

commit 9eeb638438df54945bcf6eb8105e611e7c61a2f5
parent 1e73722d4cee936b677eef817c8b5494b37a4f7a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 15 Dec 2020 11:48:46 +0100

Fix the setup of the tetrahedron

If a tetrahedron plane was orthogonal to an axis, its silhouette edges
along this axis might be wrongly oriented and could point outward the
tetrahedron. This commit fix this issue.

Diffstat:
Msrc/suvm_primitive.c | 37++++++++++++-------------------------
1 file changed, 12 insertions(+), 25 deletions(-)

diff --git a/src/suvm_primitive.c b/src/suvm_primitive.c @@ -148,9 +148,7 @@ tetrahedron_setup const float* upp = upper; float low__[3]; float upp__[3]; -#ifndef NDEBUG float center[AXES_COUNT]; /* Center of the tetrahedron */ -#endif float e[6][AXES_COUNT]; float (*v)[AXES_COUNT]; float (*N)[AXES_COUNT]; @@ -165,12 +163,10 @@ tetrahedron_setup volume_primitive_get_vertex_position(vol, itetra, 3, tetra->v[3]); v = tetra->v; -#ifndef NDEBUG /* Compute the center of the tetrahedron */ center[X] = (v[0][X] + v[1][X] + v[2][X] + v[3][X]) * 0.25f; center[Y] = (v[0][Y] + v[1][Y] + v[2][Y] + v[3][Y]) * 0.25f; center[Z] = (v[0][Z] + v[1][Z] + v[2][Z] + v[3][Z]) * 0.25f; -#endif /* Define the primitive AABB if necessary */ if(!low) { @@ -232,6 +228,8 @@ tetrahedron_setup * repairs are defined by the 'j' and 'k' variables. */ Ep = tetra->Ep; FOR_EACH(i, 0, AXES_COUNT) { + float c[2]; /* Projected tetrahedron center */ + /* On 1st iteration 'j' and 'k' define the YZ plane * On 2nd iteration 'j' and 'k' define the ZX plane * On 3rd ietration 'j' and 'k' define the XY plane */ @@ -241,6 +239,12 @@ tetrahedron_setup /* Register the number of detected silhouette edges */ int n = 0; + int iedge; + + /* Project the tetrahedron center */ + c[0] = center[j]; + c[1] = center[k]; + /* To detect the silhouette edges, check the sign of the normals of two * adjacent facets for the coordinate of the projection axis. If the signs * are the same, the facets look at the same direction regarding the @@ -280,37 +284,31 @@ tetrahedron_setup * vertices. */ if(signf(N[0][i]) != signf(N[1][i])) { /* The edge 0 is silhouette */ f2_normalize(Ep[i][n], f2(Ep[i][n], e[0][k], -e[0][j])); - if(N[0][i] > 0) f2_minus(Ep[i][n], Ep[i][n]); Ep[i][n][2] = -f2_dot(Ep[i][n], v[0]); ++n; } if(signf(N[0][i]) != signf(N[2][i])) { /* The edge 1 is silhouette */ f2_normalize(Ep[i][n], f2(Ep[i][n], e[1][k], -e[1][j])); - if(N[0][i] > 0) f2_minus(Ep[i][n], Ep[i][n]); Ep[i][n][2] = -f2_dot(Ep[i][n], v[1]); ++n; } if(signf(N[0][i]) != signf(N[3][i])) { /* The edge 2 is silhouette */ f2_normalize(Ep[i][n], f2(Ep[i][n], e[2][k], -e[2][j])); - if(N[0][i] > 0) f2_minus(Ep[i][n], Ep[i][n]); Ep[i][n][2] = -f2_dot(Ep[i][n], v[2]); ++n; } if(signf(N[1][i]) != signf(N[3][i])) { /* The edge 3 is silhouette */ f2_normalize(Ep[i][n], f2(Ep[i][n], e[3][k], -e[3][j])); - if(N[1][i] > 0) f2_minus(Ep[i][n], Ep[i][n]); Ep[i][n][2] = -f2_dot(Ep[i][n], v[0]); ++n; } if(signf(N[1][i]) != signf(N[2][i])) { /* The edge 4 is silhouette */ f2_normalize(Ep[X][n], f2(Ep[i][n], e[4][k], -e[4][j])); - if(N[2][i] > 0) f2_minus(Ep[i][n], Ep[i][n]); Ep[i][n][2] = -f2_dot(Ep[i][n], v[1]); ++n; } if(signf(N[2][i]) != signf(N[3][i])) { /* The edge 5 is silhouette */ f2_normalize(Ep[i][n], f2(Ep[i][n], e[5][k], -e[5][j])); - if(N[3][i] > 0) f2_minus(Ep[i][n], Ep[i][n]); Ep[i][n][2] = -f2_dot(Ep[i][n], v[2]); ++n; } @@ -318,22 +316,11 @@ tetrahedron_setup ASSERT(n == 3 || n == 4); tetra->nEp[i] = n; /* Register the #silouhette edges for this project axis */ -#ifndef NDEBUG - /* Assert that the normals points toward the expected half space */ - { - int iedge; - FOR_EACH(iedge, 0, n) { - /* Evaluate the edge equation regarding the projected polyhedron center - * and check that its sign is positive */ - const float dst = - Ep[i][iedge][0] * center[j] - + Ep[i][iedge][1] * center[k] - + Ep[i][iedge][2]; - ASSERT(dst > 0); - } + /* Ensure that the edge normals point toward the tetrahedron center */ + FOR_EACH(iedge, 0, n) { + if(f2_dot(Ep[i][iedge], c) + Ep[i][iedge][2] < 0) + f3_minus(Ep[i][iedge], Ep[i][iedge]); } -#endif } } -