Compare commits
2 Commits
temp-node-
...
temp-uv-fa
Author | SHA1 | Date | |
---|---|---|---|
cb261c96f5 | |||
44c1a018f4 |
@@ -203,3 +203,22 @@ bool BM_edge_uv_share_vert_check(BMEdge *e, BMLoop *l_a, BMLoop *l_b, const int
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the point is inside the UV face.
|
||||
*/
|
||||
bool BM_face_uv_point_inside_test(const BMFace *f, const float co[2], const int cd_loop_uv_offset)
|
||||
{
|
||||
float(*projverts)[2] = BLI_array_alloca(projverts, f->len);
|
||||
|
||||
BMLoop *l_iter;
|
||||
int i;
|
||||
|
||||
BLI_assert(BM_face_is_normal_valid(f));
|
||||
|
||||
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) {
|
||||
copy_v2_v2(projverts[i], BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset));
|
||||
}
|
||||
|
||||
return isect_point_poly_v2(co, projverts, f->len, false);
|
||||
}
|
||||
|
@@ -58,3 +58,8 @@ bool BM_loop_uv_share_vert_check(BMLoop *l_a,
|
||||
BMLoop *l_b,
|
||||
const int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_NONNULL();
|
||||
|
||||
bool BM_face_uv_point_inside_test(const BMFace *f,
|
||||
const float co[2],
|
||||
const int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_NONNULL();
|
||||
|
@@ -75,33 +75,44 @@ bool uv_find_nearest_vert(struct Scene *scene,
|
||||
struct Object *obedit,
|
||||
const float co[2],
|
||||
const float penalty_dist,
|
||||
struct UvNearestHit *hit_final);
|
||||
struct UvNearestHit *hit);
|
||||
bool uv_find_nearest_vert_multi(struct Scene *scene,
|
||||
struct Object **objects,
|
||||
const uint objects_len,
|
||||
const float co[2],
|
||||
const float penalty_dist,
|
||||
struct UvNearestHit *hit_final);
|
||||
struct UvNearestHit *hit);
|
||||
|
||||
bool uv_find_nearest_edge(struct Scene *scene,
|
||||
struct Object *obedit,
|
||||
const float co[2],
|
||||
struct UvNearestHit *hit_final);
|
||||
struct UvNearestHit *hit);
|
||||
bool uv_find_nearest_edge_multi(struct Scene *scene,
|
||||
struct Object **objects,
|
||||
const uint objects_len,
|
||||
const float co[2],
|
||||
struct UvNearestHit *hit_final);
|
||||
struct UvNearestHit *hit);
|
||||
|
||||
bool uv_find_nearest_face_ex(struct Scene *scene,
|
||||
struct Object *obedit,
|
||||
const float co[2],
|
||||
struct UvNearestHit *hit,
|
||||
struct UvNearestHit *hit_in_face);
|
||||
bool uv_find_nearest_face(struct Scene *scene,
|
||||
struct Object *obedit,
|
||||
const float co[2],
|
||||
struct UvNearestHit *hit_final);
|
||||
struct UvNearestHit *hit);
|
||||
bool uv_find_nearest_face_multi_ex(struct Scene *scene,
|
||||
struct Object **objects,
|
||||
const uint objects_len,
|
||||
const float co[2],
|
||||
struct UvNearestHit *hit,
|
||||
struct UvNearestHit *hit_in_face);
|
||||
bool uv_find_nearest_face_multi(struct Scene *scene,
|
||||
struct Object **objects,
|
||||
const uint objects_len,
|
||||
const float co[2],
|
||||
struct UvNearestHit *hit_final);
|
||||
struct UvNearestHit *hit);
|
||||
|
||||
BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene,
|
||||
struct Object *obedit,
|
||||
|
@@ -695,6 +695,7 @@ bool uv_find_nearest_edge(Scene *scene, Object *obedit, const float co[2], UvNea
|
||||
const float dist_test_sq = len_squared_v2(delta);
|
||||
|
||||
if (dist_test_sq < hit->dist_sq) {
|
||||
hit->ob = obedit;
|
||||
hit->efa = efa;
|
||||
|
||||
hit->l = l;
|
||||
@@ -707,24 +708,21 @@ bool uv_find_nearest_edge(Scene *scene, Object *obedit, const float co[2], UvNea
|
||||
return found;
|
||||
}
|
||||
|
||||
bool uv_find_nearest_edge_multi(Scene *scene,
|
||||
Object **objects,
|
||||
const uint objects_len,
|
||||
const float co[2],
|
||||
UvNearestHit *hit_final)
|
||||
bool uv_find_nearest_edge_multi(
|
||||
Scene *scene, Object **objects, const uint objects_len, const float co[2], UvNearestHit *hit)
|
||||
{
|
||||
bool found = false;
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
if (uv_find_nearest_edge(scene, obedit, co, hit_final)) {
|
||||
hit_final->ob = obedit;
|
||||
if (uv_find_nearest_edge(scene, obedit, co, hit)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit)
|
||||
bool uv_find_nearest_face_ex(
|
||||
Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit, UvNearestHit *hit_in_face)
|
||||
{
|
||||
BLI_assert((hit->scale[0] > 0.0f) && (hit->scale[1] > 0.0f));
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
@@ -750,29 +748,52 @@ bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNea
|
||||
const float dist_test_sq = len_squared_v2(delta);
|
||||
|
||||
if (dist_test_sq < hit->dist_sq) {
|
||||
hit->ob = obedit;
|
||||
hit->efa = efa;
|
||||
hit->dist_sq = dist_test_sq;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (hit_in_face != NULL) {
|
||||
if (dist_test_sq < hit_in_face->dist_sq) {
|
||||
if (BM_face_uv_point_inside_test(efa, co, cd_loop_uv_offset)) {
|
||||
hit_in_face->ob = obedit;
|
||||
hit_in_face->efa = efa;
|
||||
hit_in_face->dist_sq = dist_test_sq;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit)
|
||||
{
|
||||
return uv_find_nearest_face_ex(scene, obedit, co, hit, NULL);
|
||||
}
|
||||
|
||||
bool uv_find_nearest_face_multi_ex(Scene *scene,
|
||||
Object **objects,
|
||||
const uint objects_len,
|
||||
const float co[2],
|
||||
UvNearestHit *hit,
|
||||
UvNearestHit *hit_in_face)
|
||||
{
|
||||
bool found = false;
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
if (uv_find_nearest_face_ex(scene, obedit, co, hit, hit_in_face)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
bool uv_find_nearest_face_multi(Scene *scene,
|
||||
Object **objects,
|
||||
const uint objects_len,
|
||||
const float co[2],
|
||||
UvNearestHit *hit_final)
|
||||
bool uv_find_nearest_face_multi(
|
||||
Scene *scene, Object **objects, const uint objects_len, const float co[2], UvNearestHit *hit)
|
||||
{
|
||||
bool found = false;
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
if (uv_find_nearest_face(scene, obedit, co, hit_final)) {
|
||||
hit_final->ob = obedit;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
return uv_find_nearest_face_multi_ex(scene, objects, objects_len, co, hit, NULL);
|
||||
}
|
||||
|
||||
static bool uv_nearest_between(const BMLoop *l, const float co[2], const int cd_loop_uv_offset)
|
||||
@@ -830,8 +851,9 @@ bool uv_find_nearest_vert(
|
||||
|
||||
hit->dist_sq = dist_test_sq;
|
||||
|
||||
hit->l = l;
|
||||
hit->ob = obedit;
|
||||
hit->efa = efa;
|
||||
hit->l = l;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -845,13 +867,12 @@ bool uv_find_nearest_vert_multi(Scene *scene,
|
||||
const uint objects_len,
|
||||
float const co[2],
|
||||
const float penalty_dist,
|
||||
UvNearestHit *hit_final)
|
||||
UvNearestHit *hit)
|
||||
{
|
||||
bool found = false;
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
if (uv_find_nearest_vert(scene, obedit, co, penalty_dist, hit_final)) {
|
||||
hit_final->ob = obedit;
|
||||
if (uv_find_nearest_vert(scene, obedit, co, penalty_dist, hit)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -1298,7 +1319,7 @@ static int uv_select_edgering(
|
||||
static void uv_select_linked_multi(Scene *scene,
|
||||
Object **objects,
|
||||
const uint objects_len,
|
||||
UvNearestHit *hit_final,
|
||||
UvNearestHit *hit,
|
||||
const bool extend,
|
||||
bool deselect,
|
||||
const bool toggle,
|
||||
@@ -1306,12 +1327,12 @@ static void uv_select_linked_multi(Scene *scene,
|
||||
{
|
||||
const bool uv_sync_select = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION);
|
||||
|
||||
/* loop over objects, or just use hit_final->ob */
|
||||
/* loop over objects, or just use hit->ob */
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
if (hit_final && ob_index != 0) {
|
||||
if (hit && ob_index != 0) {
|
||||
break;
|
||||
}
|
||||
Object *obedit = hit_final ? hit_final->ob : objects[ob_index];
|
||||
Object *obedit = hit ? hit->ob : objects[ob_index];
|
||||
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
@@ -1342,7 +1363,7 @@ static void uv_select_linked_multi(Scene *scene,
|
||||
stack = MEM_mallocN(sizeof(*stack) * (em->bm->totface + 1), "UvLinkStack");
|
||||
flag = MEM_callocN(sizeof(*flag) * em->bm->totface, "UvLinkFlag");
|
||||
|
||||
if (hit_final == NULL) {
|
||||
if (hit == NULL) {
|
||||
/* Use existing selection */
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (uvedit_face_visible_test(scene, efa)) {
|
||||
@@ -1399,7 +1420,7 @@ static void uv_select_linked_multi(Scene *scene,
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (efa == hit_final->efa) {
|
||||
if (efa == hit->efa) {
|
||||
stack[stacksize] = a;
|
||||
stacksize++;
|
||||
flag[a] = 1;
|
||||
@@ -1941,8 +1962,14 @@ static int uv_mouse_select_multi(bContext *C,
|
||||
}
|
||||
else if (selectmode == UV_SELECT_FACE) {
|
||||
/* find face */
|
||||
found_item = uv_find_nearest_face_multi(scene, objects, objects_len, co, &hit);
|
||||
UvNearestHit hit_in_face = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
|
||||
found_item = uv_find_nearest_face_multi_ex(
|
||||
scene, objects, objects_len, co, &hit, &hit_in_face);
|
||||
if (found_item) {
|
||||
if (hit.ob == NULL) {
|
||||
hit = hit_in_face;
|
||||
printf("Using hit in face\n");
|
||||
}
|
||||
BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm;
|
||||
BM_mesh_active_face_set(bm, hit.efa);
|
||||
}
|
||||
|
Reference in New Issue
Block a user