Fix T4199: Knife holes in concave ngons failed

BM_face_point_inside_test assumed the face center was inside the face.
This commit is contained in:
Campbell Barton 2014-10-07 10:07:06 +02:00
parent 4c60aae66c
commit 5e809c45ed
Notes: blender-bot 2023-02-14 10:02:24 +01:00
Referenced by issue #41991, Knife projection tool doesn't work when similar cuts are performed
1 changed files with 14 additions and 38 deletions

View File

@ -666,49 +666,25 @@ static bool line_crosses_v2f(const float v1[2], const float v2[2], const float v
*/
bool BM_face_point_inside_test(BMFace *f, const float co[3])
{
int ax, ay;
float co2[2], cent[2] = {0.0f, 0.0f}, out[2] = {FLT_MAX * 0.5f, FLT_MAX * 0.5f};
float axis_mat[3][3];
float (*projverts)[2] = BLI_array_alloca(projverts, f->len);
float co_2d[2];
BMLoop *l_iter;
BMLoop *l_first;
int crosses = 0;
float onepluseps = 1.0f + (float)FLT_EPSILON * 150.0f;
int i;
if (is_zero_v3(f->no))
BM_face_normal_update(f);
/* find best projection of face XY, XZ or YZ: barycentric weights of
* the 2d projected coords are the same and faster to compute
*
* this probably isn't all that accurate, but it has the advantage of
* being fast (especially compared to projecting into the face orientation)
*/
axis_dominant_v3(&ax, &ay, f->no);
co2[0] = co[ax];
co2[1] = co[ay];
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
cent[0] += l_iter->v->co[ax];
cent[1] += l_iter->v->co[ay];
} while ((l_iter = l_iter->next) != l_first);
mul_v2_fl(cent, 1.0f / (float)f->len);
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
float v1[2], v2[2];
v1[0] = (l_iter->prev->v->co[ax] - cent[0]) * onepluseps + cent[0];
v1[1] = (l_iter->prev->v->co[ay] - cent[1]) * onepluseps + cent[1];
v2[0] = (l_iter->v->co[ax] - cent[0]) * onepluseps + cent[0];
v2[1] = (l_iter->v->co[ay] - cent[1]) * onepluseps + cent[1];
crosses += line_crosses_v2f(v1, v2, co2, out) != 0;
} while ((l_iter = l_iter->next) != l_first);
return crosses % 2 != 0;
axis_dominant_v3_to_m3(axis_mat, f->no);
mul_v2_m3v3(co_2d, axis_mat, co);
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) {
mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co);
}
return isect_point_poly_v2(co_2d, (const float (*)[2])projverts, f->len, false);
}
/**