Commit: acfc5f7820abfecdcf25fcd981a8a79eab76575c Author: Campbell Barton Date: Sun Mar 11 23:50:18 2018 +1100 Branches: temp-object-multi-mode https://developer.blender.org/rBacfc5f7820abfecdcf25fcd981a8a79eab76575c
Multi-Edit UV select - (de)select all - select linked - mouse picking (vert/face/island) (refactor selecting nearest UV so it can be used with many meshes) =================================================================== M source/blender/editors/sculpt_paint/sculpt_uv.c M source/blender/editors/uvedit/uvedit_intern.h M source/blender/editors/uvedit/uvedit_ops.c M source/blender/editors/uvedit/uvedit_smart_stitch.c =================================================================== diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 700b0969277..fde8ef2e4de 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -650,9 +650,9 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm /* we need to find the active island here */ if (do_island_optimization) { UvElement *element; - NearestHit hit; + UvNearestHit hit = UV_NEAREST_HIT_INIT; Image *ima = CTX_data_edit_image(C); - uv_find_nearest_vert(scene, ima, obedit, em, co, NULL, &hit); + uv_find_nearest_vert_single(scene, ima, obedit, co, 0.0f, &hit); element = BM_uv_element_get(data->elementMap, hit.efa, hit.l); island_index = element->island; diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index eb92f17544f..9441dafb7c9 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -50,19 +50,41 @@ void uv_poly_center(struct BMFace *f, float r_cent[2], const int cd_loop_uv_off /* find nearest */ -typedef struct NearestHit { +typedef struct UvNearestHit { + /** Only for `*_multi(..)` versions of functions. */ + struct Object *ob; + /** Always set if we have a hit. */ struct BMFace *efa; struct BMLoop *l; struct MLoopUV *luv, *luv_next; - int lindex; /* index of loop within face */ -} NearestHit; - -void uv_find_nearest_vert( - struct Scene *scene, struct Image *ima, struct Object *obedit, struct BMEditMesh *em, - const float co[2], const float penalty[2], struct NearestHit *hit); -void uv_find_nearest_edge( - struct Scene *scene, struct Image *ima, struct Object *obedit, struct BMEditMesh *em, - const float co[2], struct NearestHit *hit); + /** Index of loop within face */ + int lindex; + /** Needs to be set. */ + float dist_sq; +} UvNearestHit; + +#define UV_NEAREST_HIT_INIT { .dist_sq = FLT_MAX, } + +bool uv_find_nearest_vert_single( + struct Scene *scene, struct Image *ima, struct Object *obedit, + const float co[2], const float penalty_dist, struct UvNearestHit *hit_final); +bool uv_find_nearest_vert_multi( + struct Scene *scene, struct Image *ima, struct ViewLayer *view_layer, + const float co[2], const float penalty_dist, struct UvNearestHit *hit_final); + +bool uv_find_nearest_edge_single( + struct Scene *scene, struct Image *ima, struct Object *obedit, + const float co[2], struct UvNearestHit *hit_final); +bool uv_find_nearest_edge_multi( + struct Scene *scene, struct Image *ima, struct ViewLayer *view_layer, + const float co[2], struct UvNearestHit *hit_final); + +bool uv_find_nearest_face_single( + struct Scene *scene, struct Image *ima, struct Object *obedit, + const float co[2], struct UvNearestHit *hit_final); +bool uv_find_nearest_face_multi( + struct Scene *scene, struct Image *ima, struct ViewLayer *view_layer, + const float co[2], struct UvNearestHit *hit_final); /* utility tool functions */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 9a25e7cc127..298a48a483d 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -90,8 +90,10 @@ #include "uvedit_intern.h" -static bool uv_select_is_any_selected(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em); -static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, int action); +static bool uv_select_is_any_selected(Scene *scene, Image *ima, Object *obedit); +static bool uv_select_is_any_selected_multi(Scene *scene, Image *ima, ViewLayer *view_layer); +static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, int action); +static void uv_select_all_perform_multi(Scene *scene, Image *ima, ViewLayer *view_layer, int action); static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object *obedit, const bool select); static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object *obedit, const bool select); @@ -709,76 +711,117 @@ bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], c /************************** find nearest ****************************/ -void uv_find_nearest_edge(Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, const float co[2], NearestHit *hit) +bool uv_find_nearest_edge_single( + Scene *scene, Image *ima, Object *obedit, const float co[2], + UvNearestHit *hit) { + BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; BMLoop *l; BMIter iter, liter; MLoopUV *luv, *luv_next; - float mindist_squared, dist_squared; int i; + bool found = false; const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - mindist_squared = 1e10f; - memset(hit, 0, sizeof(*hit)); - BM_mesh_elem_index_ensure(em->bm, BM_VERT); - + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, obedit, ima, efa)) + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) { continue; - + } BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - dist_squared = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv); + const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv); - if (dist_squared < mindist_squared) { + if (dist_test_sq < hit->dist_sq) { hit->efa = efa; - + hit->l = l; hit->luv = luv; hit->luv_next = luv_next; hit->lindex = i; - mindist_squared = dist_squared; + hit->dist_sq = dist_test_sq; + found = true; } } } + return found; } -static void uv_find_nearest_face( - Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, const float co[2], NearestHit *hit) +bool uv_find_nearest_edge_multi( + Scene *scene, Image *ima, ViewLayer *view_layer, const float co[2], + UvNearestHit *hit_final) { - BMFace *efa; - BMIter iter; - float mindist, dist, cent[2]; + bool found = false; + FOREACH_OBJECT_IN_EDIT_MODE_BEGIN (view_layer, ob_iter) { + if (uv_find_nearest_edge_single(scene, ima, ob_iter, co, hit_final)) { + hit_final->ob = ob_iter; + found = true; + } + } FOREACH_OBJECT_IN_EDIT_MODE_END; + return found; +} + +bool uv_find_nearest_face_single( + Scene *scene, Image *ima, Object *obedit, const float co[2], + UvNearestHit *hit_final) +{ + BMEditMesh *em = BKE_editmesh_from_object(obedit); + bool found = false; const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - mindist = 1e10f; - memset(hit, 0, sizeof(*hit)); + /* this will fill in hit.vert1 and hit.vert2 */ + float dist_sq_init = hit_final->dist_sq; + UvNearestHit hit = *hit_final; + if (uv_find_nearest_edge_single(scene, ima, obedit, co, &hit)) { + hit.dist_sq = dist_sq_init; + hit.l = NULL; + hit.luv = hit.luv_next = NULL; - /*this will fill in hit.vert1 and hit.vert2*/ - uv_find_nearest_edge(scene, ima, obedit, em, co, hit); - hit->l = NULL; - hit->luv = hit->luv_next = NULL; + BMIter iter; + BMFace *efa; - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, obedit, ima, efa)) - continue; + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) { + continue; + } - uv_poly_center(efa, cent, cd_loop_uv_offset); + float cent[2]; + uv_poly_center(efa, cent, cd_loop_uv_offset); - dist = len_manhattan_v2v2(co, cent); + const float dist_test_sq = len_squared_v2v2(co, cent); - if (dist < mindist) { - hit->efa = efa; - mindist = dist; + if (dist_test_sq < hit.dist_sq) { + hit.efa = efa; + hit.dist_sq = dist_test_sq; + found = true; + } } } + if (found) { + *hit_final = hit; + } + return found; +} + +bool uv_find_nearest_face_multi( + Scene *scene, Image *ima, ViewLayer *view_layer, const float co[2], + UvNearestHit *hit_final) +{ + bool found = false; + FOREACH_OBJECT_IN_EDIT_MODE_BEGIN (view_layer, ob_iter) { + if (uv_find_nearest_face_single(scene, ima, ob_iter, co, hit_final)) { + hit_final->ob = ob_iter; + found = true; + } + } FOREACH_OBJECT_IN_EDIT_MODE_END; + return found; } static bool uv_nearest_between(const BMLoop *l, const float co[2], @@ -792,57 +835,87 @@ static bool uv_nearest_between(const BMLoop *l, const float co[2], (line_point_side_v2(uv_next, uv_curr, co) <= 0.0f)); } -void uv_find_nearest_vert( - Scene *scene, Image *ima, Object *obedit, BMEditMesh *em, - float const co[2], const float penalty[2], NearestHit *hit) +bool uv_find_nearest_vert_single( + Scene *scene, Image *ima, Object *obedit, + float const co[2], const float penalty_dist, UvNearestHit *hit_final) { - BMFace *efa; - BMLoop *l; - BMIter iter, liter; - MLoopUV *luv; - float mindist, dist; - int i; + bool found = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + /* this will fill in hit.vert1 and hit.vert2 */ + float dist_sq_init = hit_final->dist_sq; + UvNearestHit hit = *hit_final; + if (uv_find_nearest_edge_single(scene, ima, obedit, co, &hit)) { + hit.dist_sq = dist_sq_init; - /*this will fill in hit.vert1 and hit.vert2*/ - uv_find_nearest_edge(scene, ima, obedit, em, co, hit); - hit->l = NULL; - hit->luv = hit->luv_next = NULL; + hit.l = NULL; + hit.luv = hit.luv_next = NULL; - mindist = 1e10f; - memset(hit, 0, sizeof(*hit)); - - BM_mesh_elem_index_ensure(em->bm, BM_VERT); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMFace *efa; + BMIter iter; - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!uvedit_face_visible_test(scene, obedit, ima, efa)) - continue; + BM_mesh_elem_index_ensure(em->bm, BM_VERT); - BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs