Support for connected style proportional editing in UV editor. Now when connected proportional editing is on, only UVs on the same island will be proportionally moved. The implementation simply rejects UVs whose island does not belong to islands of selected vertices and decrements the total count of transform elements appropriately. Memory usage could be better but it would require some more preprocessing.

This commit is contained in:
Antony Riakiotakis 2012-10-22 07:29:38 +00:00
parent 492518f5e4
commit ffd98941b5
5 changed files with 56 additions and 18 deletions

@ -61,6 +61,7 @@ struct BMEditMesh;
struct BMEditSelection;
struct BMesh;
struct BMVert;
struct BMLoop;
struct MLoopCol;
struct BMEdge;
struct BMFace;
@ -118,6 +119,7 @@ void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, const short
struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, int selected, int doIslands);
void EDBM_uv_element_map_free(struct UvElementMap *vmap);
struct UvElement *ED_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l);
int EDBM_mtexpoly_check(struct BMEditMesh *em);
struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace **r_act_efa, int sloppy, int selected);

@ -1012,6 +1012,19 @@ void EDBM_uv_element_map_free(UvElementMap *element_map)
}
}
UvElement *ED_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l)
{
UvElement *element;
element = map->vert[BM_elem_index_get(l->v)];
for (; element; element = element->next)
if (element->face == efa)
return element;
return NULL;
}
/* last_sel, use em->act_face otherwise get the last selected face in the editselections
* at the moment, last_sel is mainly useful for making sure the space image dosnt flicker */
MTexPoly *EDBM_mtexpoly_active_get(BMEditMesh *em, BMFace **r_act_efa, int sloppy, int selected)

@ -76,6 +76,7 @@
#include "BKE_gpencil.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_movieclip.h"
#include "BKE_nla.h"
@ -2359,6 +2360,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
SpaceImage *sima = CTX_wm_space_image(C);
Image *ima = CTX_data_edit_image(C);
Scene *scene = t->scene;
ToolSettings *ts = CTX_data_tool_settings(C);
TransData *td = NULL;
TransData2D *td2d = NULL;
MTexPoly *tf;
@ -2367,12 +2369,25 @@ static void createTransUVs(bContext *C, TransInfo *t)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
int count = 0, countsel = 0;
UvElementMap *elementmap;
char *island_enabled;
int count = 0, countsel = 0, count_rejected = 0;
int propmode = t->flag & T_PROP_EDIT;
int propconnected = t->flag & T_PROP_CONNECTED;
if (!ED_space_image_show_uvedit(sima, t->obedit)) return;
/* count */
if(propconnected) {
/* create element map with island information */
if (ts->uv_flag & UV_SYNC_SELECTION) {
elementmap = EDBM_uv_element_map_create (em, FALSE, TRUE);
} else {
elementmap = EDBM_uv_element_map_create (em, TRUE, TRUE);
}
island_enabled = MEM_callocN(sizeof(*island_enabled) * elementmap->totalIslands, "TransIslandData(UV Editing)");
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
@ -2380,14 +2395,22 @@ static void createTransUVs(bContext *C, TransInfo *t)
BM_elem_flag_disable(efa, BM_ELEM_TAG);
continue;
}
BM_elem_flag_enable(efa, BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l))
if (uvedit_uv_select_test(em, scene, l)) {
countsel++;
if (propmode)
if(propconnected) {
UvElement *element = ED_uv_element_get(elementmap, efa, l);
island_enabled[element->island] = TRUE;
}
}
if (propmode) {
count++;
}
}
}
@ -2413,12 +2436,26 @@ static void createTransUVs(bContext *C, TransInfo *t)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (!propmode && !uvedit_uv_select_test(em, scene, l))
continue;
if (propconnected) {
UvElement *element = ED_uv_element_get(elementmap, efa, l);
if (!island_enabled[element->island]) {
count_rejected++;
continue;
}
}
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
UVsToTransData(sima, td++, td2d++, luv->uv, uvedit_uv_select_test(em, scene, l));
}
}
if (propconnected) {
t->total -= count_rejected;
EDBM_uv_element_map_free(elementmap);
MEM_freeN(island_enabled);
}
if (sima->flag & SI_LIVE_UNWRAP)
ED_uvedit_live_unwrap_begin(t->scene, t->obedit);
}

@ -72,7 +72,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM
/* utility tool functions */
struct UvElement *ED_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l);
void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit);
/* operators */

@ -895,19 +895,6 @@ int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float c
return found;
}
UvElement *ED_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l)
{
UvElement *element;
element = map->vert[BM_elem_index_get(l->v)];
for (; element; element = element->next)
if (element->face == efa)
return element;
return NULL;
}
/*********************** loop select ***********************/
static void select_edgeloop_uv_vertex_loop_flag(UvMapVert *first)