Changeset View
Changeset View
Standalone View
Standalone View
source/blender/bmesh/intern/bmesh_polygon.c
| Context not available. | |||||
| */ | */ | ||||
| bool BM_face_point_inside_test(BMFace *f, const float co[3]) | bool BM_face_point_inside_test(BMFace *f, const float co[3]) | ||||
| { | { | ||||
| float axis_mat[3][3]; | int ax, ay; | ||||
| float (*projverts)[2] = BLI_array_alloca(projverts, f->len); | float co2[2], cent[2] = {0.0f, 0.0f}, out[2] = {FLT_MAX * 0.5f, FLT_MAX * 0.5f}; | ||||
| float co_2d[2]; | |||||
| BMLoop *l_iter; | BMLoop *l_iter; | ||||
| int i; | BMLoop *l_first; | ||||
| int crosses = 0; | |||||
| float onepluseps = 1.0f + (float)FLT_EPSILON * 150.0f; | |||||
| if (is_zero_v3(f->no)) | if (is_zero_v3(f->no)) | ||||
| BM_face_normal_update(f); | BM_face_normal_update(f); | ||||
| axis_dominant_v3_to_m3(axis_mat, f->no); | /* find best projection of face XY, XZ or YZ: barycentric weights of | ||||
| * the 2d projected coords are the same and faster to compute | |||||
| mul_v2_m3v3(co_2d, axis_mat, co); | * | ||||
| * this probably isn't all that accurate, but it has the advantage of | |||||
| for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) { | * being fast (especially compared to projecting into the face orientation) | ||||
| mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co); | */ | ||||
| } | axis_dominant_v3(&ax, &ay, f->no); | ||||
| return isect_point_poly_v2(co_2d, (const float (*)[2])projverts, f->len, false); | 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; | |||||
| } | } | ||||
| /** | /** | ||||
| Context not available. | |||||