fix [#30880] Selected to Adjacent Unselected broken
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user