diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 4bffc7098b3..85c7d324145 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2743,97 +2743,56 @@ static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, SpaceIma static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obedit) { BMEditMesh *em = BMEdit_FromObject(obedit); - BMFace *efa; - BMLoop *l; - BMIter iter, liter; - BMVert *eve; + BMesh *bm = em->bm; + BMFace *f; + BMLoop *l, *lsub; + BMIter iter, liter, lsubiter; MTexPoly *tface; MLoopUV *luv; - short change = 0; - int count = 0; - float *coords; - short *usercount, users; - - /* BMESH_TODO - stop setting the index, bad juju - * not totally simple because 3 states and because the count is not - * based on the global vertex index :S - campbell */ - - /* set all verts to -1 : an unused index*/ - BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) - BM_elem_index_set(eve, -1); /* set_dirty! */ - em->bm->elem_index_dirty |= BM_VERT; + short change = FALSE; /* index every vert that has a selected UV using it, but only once so as to * get unique indices and to count how much to malloc */ - BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { - tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if (!uvedit_face_visible(scene, ima, efa, tface)) { - BM_elem_flag_disable(efa, BM_ELEM_TAG); - continue; + BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) { + tface = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_MTEXPOLY); + if (uvedit_face_visible(scene, ima, f, tface)) { + BM_elem_flag_enable(f, BM_ELEM_TAG); + BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) { + BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_selected(em, scene, l)); + } } else { - BM_elem_flag_enable(efa, BM_ELEM_TAG); + BM_elem_flag_disable(f, BM_ELEM_TAG); } + } - change = 1; - BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { - if (uvedit_uv_selected(em, scene, l) && BM_elem_index_get(l->v) == -1) { - BM_elem_index_set(l->v, count); /* set_dirty! */ - count++; + BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) { + if (BM_elem_flag_test(f, BM_ELEM_TAG)) { /* face: visible */ + BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) { + if (BM_elem_flag_test(f, BM_ELEM_TAG)) { /* loop: selected*/ + float uv[2] = {0.0f, 0.0f}; + int uv_tot = 0; + + BM_ITER(lsub, &lsubiter, bm, BM_LOOPS_OF_VERT, l->v) { + if (BM_elem_flag_test(lsub->f, BM_ELEM_TAG) && /* face: visible */ + !BM_elem_flag_test(lsub, BM_ELEM_TAG)) /* loop: unselected */ + { + + luv = CustomData_bmesh_get(&bm->ldata, lsub->head.data, CD_MLOOPUV); + add_v2_v2(uv, luv->uv); + uv_tot++; + } + } + + if (uv_tot) { + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + mul_v2_v2fl(luv->uv, uv, 1.0f / (float)uv_tot); + change = TRUE; + } + } } } } - em->bm->elem_index_dirty |= BM_VERT; /* set above but include for completeness since they are made dirty again */ - - coords = MEM_callocN(sizeof(float)*count*2, "snap to adjacent coords"); - usercount = MEM_callocN(sizeof(short)*count, "snap to adjacent counts"); - - /* add all UV coords from visible, unselected UV coords as well as counting them to average later */ - BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { - if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) - continue; - - tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if (!uvedit_face_visible(scene, ima, efa, tface)) - continue; - - BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { - if (BM_elem_index_get(l->v) >= 0 && - (!uvedit_uv_selected(em, scene, l))) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - add_v2_v2(&coords[BM_elem_index_get(l->v) * 2], luv->uv); - change = 1; - } - } - } - - /* no other verts selected, bail out */ - if (!change) { - MEM_freeN(coords); - MEM_freeN(usercount); - return change; - } - - /* copy the averaged unselected UVs back to the selected UVs */ - BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { - if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) - continue; - - tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if (!uvedit_face_visible(scene, ima, efa, tface)) - continue; - - BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { - if (uvedit_uv_selected(em, scene, l) && BM_elem_index_get(l->v) >= 0 - && (users = usercount[BM_elem_index_get(l->v)])) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(luv->uv, &coords[BM_elem_index_get(l->v) * 2]); - } - } - } - - MEM_freeN(coords); - MEM_freeN(usercount); return change; }