Mesh: minor optimization to concave quad check for tessellation

Use the face normal (when available) for a faster concave quad test.
This commit is contained in:
Campbell Barton
2021-06-20 13:47:53 +10:00
parent 513f566b40
commit 2d60c496a2
4 changed files with 36 additions and 6 deletions

View File

@@ -476,10 +476,19 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop,
ML_TO_MLT(0, 2, 3);
MLoopTri *mlt_b = mlt;
if (UNLIKELY(is_quad_flip_v3_first_third_fast(mvert[mloop[mlt_a->tri[0]].v].co,
mvert[mloop[mlt_a->tri[1]].v].co,
mvert[mloop[mlt_a->tri[2]].v].co,
mvert[mloop[mlt_b->tri[2]].v].co))) {
if (UNLIKELY(face_normal ? is_quad_flip_v3_first_third_fast_with_normal(
/* Simpler calculation (using the normal). */
mvert[mloop[mlt_a->tri[0]].v].co,
mvert[mloop[mlt_a->tri[1]].v].co,
mvert[mloop[mlt_a->tri[2]].v].co,
mvert[mloop[mlt_b->tri[2]].v].co,
normal_precalc) :
is_quad_flip_v3_first_third_fast(
/* Expensive calculation (no normal). */
mvert[mloop[mlt_a->tri[0]].v].co,
mvert[mloop[mlt_a->tri[1]].v].co,
mvert[mloop[mlt_a->tri[2]].v].co,
mvert[mloop[mlt_b->tri[2]].v].co))) {
/* Flip out of degenerate 0-2 state. */
mlt_a->tri[2] = mlt_b->tri[2];
mlt_b->tri[0] = mlt_a->tri[1];

View File

@@ -105,6 +105,11 @@ bool is_quad_flip_v3_first_third_fast(const float v1[3],
const float v2[3],
const float v3[3],
const float v4[3]);
bool is_quad_flip_v3_first_third_fast_with_normal(const float v1[3],
const float v2[3],
const float v3[3],
const float v4[3],
const float normal[3]);
/********************************* Distance **********************************/

View File

@@ -6218,6 +6218,19 @@ bool is_quad_flip_v3_first_third_fast(const float v1[3],
return dot_v3v3(cross_a, cross_b) > 0.0f;
}
bool is_quad_flip_v3_first_third_fast_with_normal(const float v1[3],
const float v2[3],
const float v3[3],
const float v4[3],
const float normal[3])
{
float dir_v3v1[3], tangent[3];
sub_v3_v3v3(dir_v3v1, v3, v1);
cross_v3_v3v3(tangent, dir_v3v1, normal);
const float dot = dot_v3v3(v1, tangent);
return (dot_v3v3(v4, tangent) >= dot) || (dot_v3v3(v2, tangent) <= dot);
}
/**
* Return the value which the distance between points will need to be scaled by,
* to define a handle, given both points are on a perfect circle.

View File

@@ -95,8 +95,11 @@ BLI_INLINE void bmesh_calc_tessellation_for_face_impl(BMLoop *(*looptris)[3],
efa->no, l_ptr_a[0]->v->co, l_ptr_a[1]->v->co, l_ptr_a[2]->v->co, l_ptr_b[2]->v->co);
}
if (UNLIKELY(is_quad_flip_v3_first_third_fast(
l_ptr_a[0]->v->co, l_ptr_a[1]->v->co, l_ptr_a[2]->v->co, l_ptr_b[2]->v->co))) {
if (UNLIKELY(is_quad_flip_v3_first_third_fast_with_normal(l_ptr_a[0]->v->co,
l_ptr_a[1]->v->co,
l_ptr_a[2]->v->co,
l_ptr_b[2]->v->co,
efa->no))) {
/* Flip out of degenerate 0-2 state. */
l_ptr_a[2] = l_ptr_b[2];
l_ptr_b[0] = l_ptr_a[1];