diff options
author | Chris Blackbourn <chrisbblend@gmail.com> | 2022-06-16 00:51:48 +0300 |
---|---|---|
committer | Chris Blackbourn <chrisbblend@gmail.com> | 2022-06-16 00:53:50 +0300 |
commit | e6e9f1ac5a2dae42dc523784b03395a50671afaa (patch) | |
tree | 80d1d828846ef3d0974538509cb334aded091319 /source/blender/editors/uvedit/uvedit_unwrap_ops.c | |
parent | 28044973123516b0ecce5a29d22e70eb6965542e (diff) |
Fix T98239: During UV Unwrap, create unique indices for each pinned UV
Originally reported in T75007.
Differential Revision: https://developer.blender.org/D15199
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_unwrap_ops.c')
-rw-r--r-- | source/blender/editors/uvedit/uvedit_unwrap_ops.c | 101 |
1 files changed, 54 insertions, 47 deletions
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index cbc9b2a8d06..3618286ec01 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -298,6 +298,44 @@ void ED_uvedit_get_aspect(Object *ob, float *r_aspx, float *r_aspy) ED_uvedit_get_aspect_from_material(ob, efa->mat_nr, r_aspx, r_aspy); } +static bool uvedit_is_face_affected(const Scene *scene, + BMFace *efa, + const UnwrapOptions *options, + const int cd_loop_uv_offset) +{ + if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + return false; + } + + if (options->only_selected_faces && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + return false; + } + + if (options->topology_from_uvs && options->only_selected_uvs && + !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + return false; + } + + return true; +} + +/* Prepare unique indices for each unique pinned UV, even if it shares a BMVert. + */ +static void uvedit_prepare_pinned_indices(ParamHandle *handle, + BMFace *efa, + const int cd_loop_uv_offset) +{ + BMIter liter; + BMLoop *l; + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (luv->flag & MLOOPUV_PINNED) { + int bmvertindex = BM_elem_index_get(l->v); + GEO_uv_prepare_pin_index(handle, bmvertindex, luv->uv); + } + } +} + static void construct_param_handle_face_add(ParamHandle *handle, const Scene *scene, BMFace *efa, @@ -319,7 +357,7 @@ static void construct_param_handle_face_add(ParamHandle *handle, BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - vkeys[i] = (ParamKey)BM_elem_index_get(l->v); + vkeys[i] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv->uv); co[i] = l->v->co; uv[i] = luv->uv; pin[i] = (luv->flag & MLOOPUV_PINNED) != 0; @@ -337,13 +375,10 @@ static ParamHandle *construct_param_handle(const Scene *scene, UnwrapResultInfo *result_info) { BMFace *efa; - BMLoop *l; BMEdge *eed; - BMIter iter, liter; + BMIter iter; int i; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); if (options->correct_aspect) { @@ -359,30 +394,17 @@ static ParamHandle *construct_param_handle(const Scene *scene, /* we need the vert indices */ BM_mesh_elem_index_ensure(bm, BM_VERT); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - - if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) || - (options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { - continue; + if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) { + uvedit_prepare_pinned_indices(handle, efa, cd_loop_uv_offset); } + } - if (options->topology_from_uvs) { - bool is_loopsel = false; - - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (options->only_selected_uvs && - (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) == false)) { - continue; - } - is_loopsel = true; - break; - } - if (is_loopsel == false) { - continue; - } + BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { + if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) { + construct_param_handle_face_add(handle, scene, efa, i, cd_loop_uv_offset); } - - construct_param_handle_face_add(handle, scene, efa, i, cd_loop_uv_offset); } if (!options->topology_from_uvs || options->topology_from_uvs_use_seams) { @@ -414,9 +436,8 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, int *count_fail) { BMFace *efa; - BMLoop *l; BMEdge *eed; - BMIter iter, liter; + BMIter iter; int i; ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); @@ -448,29 +469,15 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, } BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - - if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) || - (options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { - continue; + if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) { + uvedit_prepare_pinned_indices(handle, efa, cd_loop_uv_offset); } + } - if (options->topology_from_uvs) { - bool is_loopsel = false; - - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (options->only_selected_uvs && - (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) == false)) { - continue; - } - is_loopsel = true; - break; - } - if (is_loopsel == false) { - continue; - } + BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { + if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) { + construct_param_handle_face_add(handle, scene, efa, i + offset, cd_loop_uv_offset); } - - construct_param_handle_face_add(handle, scene, efa, i + offset, cd_loop_uv_offset); } if (!options->topology_from_uvs || options->topology_from_uvs_use_seams) { |