change UvElement to directly use BMLoop * instead of tfindex. This saves quite some lookups on uv sculpting and stitching. Based on BMESH todo by Campbell, thanks for the idea!
This commit is contained in:
@@ -193,7 +193,7 @@ typedef struct UvElement {
|
||||
/* Face the element belongs to */
|
||||
struct BMFace *face;
|
||||
/* Index in the editFace of the uv */
|
||||
unsigned char tfindex;
|
||||
struct BMLoop *l;
|
||||
/* Whether this element is the first of coincident elements */
|
||||
unsigned char separate;
|
||||
/* general use flag */
|
||||
|
@@ -771,7 +771,7 @@ UvElementMap *EDBM_make_uv_element_map(BMEditMesh *em, int selected, int do_isla
|
||||
if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
|
||||
i = 0;
|
||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
|
||||
buf->tfindex = i;
|
||||
buf->l = l;
|
||||
buf->face = efa;
|
||||
buf->separate = 0;
|
||||
buf->island = INVALID_ISLAND;
|
||||
@@ -798,10 +798,7 @@ UvElementMap *EDBM_make_uv_element_map(BMEditMesh *em, int selected, int do_isla
|
||||
v->next = newvlist;
|
||||
newvlist = v;
|
||||
|
||||
efa = v->face;
|
||||
/* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
|
||||
|
||||
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa, v->tfindex);
|
||||
l = v->l;
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
uv = luv->uv;
|
||||
|
||||
@@ -810,10 +807,8 @@ UvElementMap *EDBM_make_uv_element_map(BMEditMesh *em, int selected, int do_isla
|
||||
|
||||
while (iterv) {
|
||||
next = iterv->next;
|
||||
efa = iterv->face;
|
||||
/* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
|
||||
|
||||
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex);
|
||||
l = iterv->l;
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
uv2 = luv->uv;
|
||||
|
||||
@@ -867,7 +862,7 @@ UvElementMap *EDBM_make_uv_element_map(BMEditMesh *em, int selected, int do_isla
|
||||
/* found the uv corresponding to our face and vertex. Now fill it to the buffer */
|
||||
element->island = nislands;
|
||||
map[element - element_map->buf] = islandbufsize;
|
||||
islandbuf[islandbufsize].tfindex = element->tfindex;
|
||||
islandbuf[islandbufsize].l = element->l;
|
||||
islandbuf[islandbufsize].face = element->face;
|
||||
islandbuf[islandbufsize].separate = element->separate;
|
||||
islandbuf[islandbufsize].island = nislands;
|
||||
|
@@ -215,7 +215,7 @@ void HC_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *sculptdata, float
|
||||
if(element->separate && element != sculptdata->uv[i].element)
|
||||
break;
|
||||
|
||||
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
|
||||
}
|
||||
@@ -279,7 +279,7 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *scul
|
||||
if(element->separate && element != sculptdata->uv[i].element)
|
||||
break;
|
||||
|
||||
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
|
||||
}
|
||||
@@ -355,7 +355,7 @@ static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, wmEvent *event,
|
||||
if(element->separate && element != sculptdata->uv[i].element)
|
||||
break;
|
||||
|
||||
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
|
||||
}
|
||||
@@ -397,7 +397,7 @@ static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, wmEvent *event,
|
||||
if(element->separate && element != sculptdata->uv[uvindex].element)
|
||||
break;
|
||||
|
||||
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
copy_v2_v2(luv->uv, sculptdata->uv[uvindex].uv);
|
||||
}
|
||||
@@ -433,8 +433,8 @@ static void uv_sculpt_stroke_exit(bContext *C, wmOperator *op)
|
||||
op->customdata = NULL;
|
||||
}
|
||||
|
||||
static int get_uv_element_offset_from_face(UvElementMap *map, BMFace *efa, int index, int island_index, int doIslands){
|
||||
UvElement *element = ED_get_uv_element(map, efa, index);
|
||||
static int get_uv_element_offset_from_face(UvElementMap *map, BMFace *efa, BMLoop *l, int island_index, int doIslands){
|
||||
UvElement *element = ED_get_uv_element(map, efa, l);
|
||||
if(!element || (doIslands && element->island != island_index)){
|
||||
return -1;
|
||||
}
|
||||
@@ -523,7 +523,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
|
||||
Image *ima= CTX_data_edit_image(C);
|
||||
uv_find_nearest_vert(scene, ima, em, co, NULL, &hit);
|
||||
|
||||
element = ED_get_uv_element(data->elementMap, hit.efa, hit.lindex);
|
||||
element = ED_get_uv_element(data->elementMap, hit.efa, hit.l);
|
||||
island_index = element->island;
|
||||
}
|
||||
|
||||
@@ -571,8 +571,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
|
||||
continue;
|
||||
}
|
||||
|
||||
efa = element->face;
|
||||
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
|
||||
counter++;
|
||||
@@ -589,11 +588,9 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
|
||||
/* Now, on to generate our uv connectivity data */
|
||||
counter = 0;
|
||||
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
|
||||
int nverts = efa->len;
|
||||
i = 0;
|
||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
|
||||
int offset1, itmp1 = get_uv_element_offset_from_face(data->elementMap, efa, i, island_index, do_island_optimization);
|
||||
int offset2, itmp2 = get_uv_element_offset_from_face(data->elementMap, efa, (i+1)%nverts, island_index, do_island_optimization);
|
||||
int offset1, itmp1 = get_uv_element_offset_from_face(data->elementMap, efa, l, island_index, do_island_optimization);
|
||||
int offset2, itmp2 = get_uv_element_offset_from_face(data->elementMap, efa, l->next, island_index, do_island_optimization);
|
||||
|
||||
/* Skip edge if not found(unlikely) or not on valid island */
|
||||
if(itmp1 == -1 || itmp2 == -1)
|
||||
@@ -623,7 +620,6 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
|
||||
BLI_ghash_insert(edgeHash, &edges[counter], &edges[counter].flag);
|
||||
}
|
||||
counter++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -81,7 +81,7 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM
|
||||
|
||||
/* utility tool functions */
|
||||
|
||||
struct UvElement *ED_get_uv_element(struct UvElementMap *map, struct BMFace *efa, int index);
|
||||
struct UvElement *ED_get_uv_element(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l);
|
||||
void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit);
|
||||
|
||||
/* smart stitch */
|
||||
|
@@ -938,15 +938,10 @@ static UvMapVert *uv_vertex_map_get(UvVertMap *vmap, BMFace *efa, int a)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* BMESH_TODO - in some cases we already know the loop so looking up the index isnt needed */
|
||||
|
||||
UvElement *ED_get_uv_element(UvElementMap *map, BMFace *efa, int index)
|
||||
UvElement *ED_get_uv_element(UvElementMap *map, BMFace *efa, BMLoop *l)
|
||||
{
|
||||
BMLoop *l;
|
||||
UvElement *element;
|
||||
|
||||
l = BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, index);
|
||||
|
||||
element = map->vert[BM_elem_index_get(l->v)];
|
||||
|
||||
for(; element; element = element->next)
|
||||
|
@@ -274,9 +274,9 @@ static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_it
|
||||
BMLoop *l_orig, *l_iter;
|
||||
|
||||
|
||||
l_orig = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l_orig = element->l;
|
||||
luv_orig = CustomData_bmesh_get(&state->em->bm->ldata, l_orig->head.data, CD_MLOOPUV);
|
||||
l_iter = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element->face, element_iter->tfindex);
|
||||
l_iter = element_iter->l;
|
||||
luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l_iter->head.data, CD_MLOOPUV);
|
||||
|
||||
if(fabs(luv_orig->uv[0] - luv_iter->uv[0]) < limit
|
||||
@@ -323,7 +323,7 @@ static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer
|
||||
MLoopUV *luv;
|
||||
BMLoop *l;
|
||||
|
||||
l = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
|
||||
if(final){
|
||||
@@ -366,9 +366,9 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *sta
|
||||
element1 = state->uvs[edge->uv1];
|
||||
element2 = state->uvs[edge->uv2];
|
||||
|
||||
l1 = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element1->face, element1->tfindex);
|
||||
l1 = element1->l;
|
||||
luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l1->head.data, CD_MLOOPUV);
|
||||
l2 = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element2->face, element2->tfindex);
|
||||
l2 = element2->l;
|
||||
luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l2->head.data, CD_MLOOPUV);
|
||||
|
||||
index1 = uvfinal_map[element1 - state->element_map->buf];
|
||||
@@ -406,7 +406,7 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
|
||||
if(element->island == state->static_island && !state->midpoints)
|
||||
return;
|
||||
|
||||
l = BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
|
||||
index = BM_elem_index_get(l->v);
|
||||
|
||||
@@ -473,7 +473,7 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I
|
||||
UvElement *element_iter;
|
||||
BMLoop *l;
|
||||
|
||||
l = BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
|
||||
vert_index = BM_elem_index_get(l->v);
|
||||
element_iter = state->element_map->vert[vert_index];
|
||||
@@ -537,7 +537,7 @@ static void stitch_validate_stichability (UvElement *element, StitchState *state
|
||||
int vert_index;
|
||||
BMLoop *l;
|
||||
|
||||
l = BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
|
||||
vert_index = BM_elem_index_get(l->v);
|
||||
|
||||
@@ -675,7 +675,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
|
||||
/* copy data from MTFaces to the preview display buffers */
|
||||
BM_ITER(efa, &iter, state->em->bm, BM_FACES_OF_MESH, NULL) {
|
||||
/* just to test if face was added for processing. uvs of inselected vertices will return NULL */
|
||||
UvElement *element = ED_get_uv_element(state->element_map, efa, 0);
|
||||
UvElement *element = ED_get_uv_element(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
|
||||
|
||||
if(element){
|
||||
int index = BM_elem_index_get(efa);
|
||||
@@ -711,7 +711,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
|
||||
for(i = 0; i < state->total_separate_uvs; i++){
|
||||
UvElement *element = (UvElement *)state->uvs[i];
|
||||
if(element->flag & STITCH_STITCHABLE){
|
||||
l = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
|
||||
copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex*2], luv->uv);
|
||||
@@ -719,7 +719,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
|
||||
stitchBufferIndex++;
|
||||
}
|
||||
else if(element->flag & STITCH_SELECTED){
|
||||
l = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
|
||||
copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex*2], luv->uv);
|
||||
@@ -743,7 +743,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
|
||||
MLoopUV *luv;
|
||||
UvElement *element_iter;
|
||||
|
||||
l = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
|
||||
|
||||
@@ -760,7 +760,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
|
||||
for(;element_iter; element_iter = element_iter->next){
|
||||
if(element_iter->separate){
|
||||
if(stitch_check_uvs_state_stitchable(element, element_iter, state)){
|
||||
l = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element_iter->face, element_iter->tfindex);
|
||||
l = element_iter->l;
|
||||
luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
if(stitch_midpoints){
|
||||
add_v2_v2(final_position[i].uv, luv->uv);
|
||||
@@ -789,7 +789,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
|
||||
BMLoop *l;
|
||||
MLoopUV *luv;
|
||||
|
||||
l = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
|
||||
/* accumulate each islands' translation from stitchable elements. it is important to do here
|
||||
@@ -832,7 +832,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
|
||||
BMLoop *l;
|
||||
MLoopUV *luv;
|
||||
|
||||
l = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element_iter->face, element_iter->tfindex);
|
||||
l = element_iter->l;
|
||||
luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
|
||||
element_iter->flag |= STITCH_PROCESSED;
|
||||
@@ -897,7 +897,7 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_
|
||||
UvElement *element_iter;
|
||||
UvElement **selection_stack = state->selection_stack;
|
||||
|
||||
l = BM_iter_at_index(state->em->bm, BM_LOOPS_OF_FACE, element->face, element->tfindex);
|
||||
l = element->l;
|
||||
|
||||
element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
|
||||
/* first deselect all common uvs */
|
||||
@@ -1049,18 +1049,13 @@ static int stitch_init(bContext *C, wmOperator *op)
|
||||
counter = 0;
|
||||
/* Now, on to generate our uv connectivity data */
|
||||
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
|
||||
int nverts;
|
||||
|
||||
if (!(ts->uv_flag & UV_SYNC_SELECTION) && ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || !BM_elem_flag_test(efa, BM_ELEM_SELECT)))
|
||||
continue;
|
||||
|
||||
nverts = efa->len;
|
||||
i = 0;
|
||||
|
||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
|
||||
UvElement *element = ED_get_uv_element(state->element_map, efa, i);
|
||||
UvElement *element = ED_get_uv_element(state->element_map, efa, l);
|
||||
int offset1, itmp1 = element - state->element_map->buf;
|
||||
int offset2, itmp2 = ED_get_uv_element(state->element_map, efa, (i+1)%nverts) - state->element_map->buf;
|
||||
int offset2, itmp2 = ED_get_uv_element(state->element_map, efa, l->next) - state->element_map->buf;
|
||||
|
||||
offset1 = map[itmp1];
|
||||
offset2 = map[itmp2];
|
||||
@@ -1087,7 +1082,6 @@ static int stitch_init(bContext *C, wmOperator *op)
|
||||
all_edges[counter].flag = STITCH_BOUNDARY;
|
||||
}
|
||||
counter++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,7 +1153,7 @@ static int stitch_init(bContext *C, wmOperator *op)
|
||||
faceIndex = RNA_int_get(&itemptr, "face_index");
|
||||
elementIndex = RNA_int_get(&itemptr, "element_index");
|
||||
efa = EDBM_get_face_for_index(em, faceIndex);
|
||||
element = ED_get_uv_element(state->element_map, efa, elementIndex);
|
||||
element = ED_get_uv_element(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
|
||||
stitch_select_uv(element, state, 1);
|
||||
}
|
||||
RNA_END;
|
||||
@@ -1173,7 +1167,7 @@ static int stitch_init(bContext *C, wmOperator *op)
|
||||
i = 0;
|
||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
|
||||
if(uvedit_uv_selected(em, scene, l)){
|
||||
UvElement *element = ED_get_uv_element(state->element_map, efa, i);
|
||||
UvElement *element = ED_get_uv_element(state->element_map, efa, l);
|
||||
stitch_select_uv(element, state, 1);
|
||||
}
|
||||
i++;
|
||||
@@ -1190,7 +1184,7 @@ static int stitch_init(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
|
||||
UvElement *element = ED_get_uv_element(state->element_map, efa, 0);
|
||||
UvElement *element = ED_get_uv_element(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
|
||||
|
||||
if(element){
|
||||
state->tris_per_island[element->island] += (efa->len > 2)? efa->len-2 : 0;
|
||||
@@ -1243,12 +1237,21 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
|
||||
/* Store selection for re-execution of stitch */
|
||||
for(i = 0; i < stitch_state->selection_size; i++){
|
||||
PointerRNA itemptr;
|
||||
int j = 0;
|
||||
BMIter liter;
|
||||
BMLoop *l;
|
||||
UvElement *element = stitch_state->selection_stack[i];
|
||||
|
||||
RNA_collection_add(op->ptr, "selection", &itemptr);
|
||||
|
||||
RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->face));
|
||||
RNA_int_set(&itemptr, "element_index", element->tfindex);
|
||||
|
||||
/* iterate to get the loop index. Better have this once here than everywhere else */
|
||||
BM_ITER(l, &liter, stitch_state->em->bm, BM_LOOPS_OF_FACE, element->face) {
|
||||
if(element->l == l)
|
||||
RNA_int_set(&itemptr, "element_index", j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1306,7 +1309,7 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState
|
||||
* you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
|
||||
|
||||
/* This works due to setting of tmp in find nearest uv vert */
|
||||
UvElement *element = ED_get_uv_element(stitch_state->element_map, hit.efa, hit.lindex);
|
||||
UvElement *element = ED_get_uv_element(stitch_state->element_map, hit.efa, hit.l);
|
||||
stitch_select_uv(element, stitch_state, 0);
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user