[Bf-blender-cvs] [acfc5f7820a] temp-object-multi-mode: Multi-Edit UV select

Campbell Barton noreply at git.blender.org
Mon Mar 12 03:04:59 CET 2018


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. @@



More information about the Bf-blender-cvs mailing list