[Bf-blender-cvs] [0cd2eb11ee1] blender2.8: UV: stitch multi-object support

Campbell Barton noreply at git.blender.org
Wed Aug 8 06:09:30 CEST 2018


Commit: 0cd2eb11ee1762aed076e1f45cbb66d25c90ae17
Author: Campbell Barton
Date:   Wed Aug 8 13:56:53 2018 +1000
Branches: blender2.8
https://developer.blender.org/rB0cd2eb11ee1762aed076e1f45cbb66d25c90ae17

UV: stitch multi-object support

D3561 by @Al

===================================================================

M	source/blender/editors/uvedit/uvedit_smart_stitch.c

===================================================================

diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 18f1bc872c0..a5e18851f12 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -54,6 +54,7 @@
 #include "BKE_customdata.h"
 #include "BKE_mesh_mapping.h"
 #include "BKE_editmesh.h"
+#include "BKE_layer.h"
 
 #include "DEG_depsgraph.h"
 
@@ -150,20 +151,11 @@ typedef struct UvEdge {
 /* stitch state object */
 typedef struct StitchState {
 	float aspect;
-	/* use limit flag */
-	bool use_limit;
-	/* limit to operator, same as original operator */
-	float limit_dist;
-	/* snap uv islands together during stitching */
-	bool snap_islands;
-	/* stitch at midpoints or at islands */
-	bool midpoints;
 	/* object for editmesh */
 	Object *obedit;
 	/* editmesh, cached for use in modal handler */
 	BMEditMesh *em;
-	/* clear seams of stitched edges after stitch */
-	bool clear_seams;
+
 	/* element map for getting info about uv connectivity */
 	UvElementMap *element_map;
 	/* edge container */
@@ -178,6 +170,8 @@ typedef struct StitchState {
 	UvEdge *edges;
 	/* hash for quick lookup of edges */
 	GHash *edge_hash;
+	/* which islands to stop at (to make active) when pressing 'I' */
+	bool *island_is_stitchable;
 
 	/* count of separate uvs and edges */
 	int total_separate_edges;
@@ -185,18 +179,39 @@ typedef struct StitchState {
 	/* hold selection related information */
 	void **selection_stack;
 	int selection_size;
-	/* island that stays in place */
-	int static_island;
+
 	/* store number of primitives per face so that we can allocate the active island buffer later */
 	unsigned int *tris_per_island;
+	/* preview data */
+	StitchPreviewer *stitch_preview;
+} StitchState;
 
+/* Stitch state container. */
+typedef struct StitchStateContainer {
+	/* clear seams of stitched edges after stitch */
+	bool clear_seams;
+	/* use limit flag */
+	bool use_limit;
+	/* limit to operator, same as original operator */
+	float limit_dist;
+	/* snap uv islands together during stitching */
+	bool snap_islands;
+	/* stitch at midpoints or at islands */
+	bool midpoints;
 	/* vert or edge mode used for stitching */
 	char mode;
 	/* handle for drawing */
 	void *draw_handle;
-	/* preview data */
-	StitchPreviewer *stitch_preview;
-} StitchState;
+	/* island that stays in place */
+	int static_island;
+
+	/* Objects and states are aligned. */
+	int      objects_len;
+	Object **objects;
+	StitchState **states;
+
+	int active_object_index;
+} StitchStateContainer;
 
 typedef struct PreviewPosition {
 	int data_position;
@@ -270,7 +285,7 @@ static void stitch_preview_delete(StitchPreviewer *stitch_preview)
 }
 
 /* This function updates the header of the UV editor when the stitch tool updates its settings */
-static void stitch_update_header(StitchState *state, bContext *C)
+static void stitch_update_header(StitchStateContainer *ssc, bContext *C)
 {
 	const char *str = IFACE_(
 	    "Mode(TAB) %s, "
@@ -285,12 +300,13 @@ static void stitch_update_header(StitchState *state, bContext *C)
 	ScrArea *sa = CTX_wm_area(C);
 
 	if (sa) {
-		BLI_snprintf(msg, sizeof(msg), str,
-		             state->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"),
-		             WM_bool_as_string(state->snap_islands),
-		             WM_bool_as_string(state->midpoints),
-		             state->limit_dist,
-		             WM_bool_as_string(state->use_limit));
+		BLI_snprintf(
+		        msg, sizeof(msg), str,
+		        ssc->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"),
+		        WM_bool_as_string(ssc->snap_islands),
+		        WM_bool_as_string(ssc->midpoints),
+		        ssc->limit_dist,
+		        WM_bool_as_string(ssc->use_limit));
 
 		ED_workspace_status_text(C, msg);
 	}
@@ -320,7 +336,9 @@ static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2],
 }
 
 /* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */
-static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
+static bool stitch_check_uvs_stitchable(
+        UvElement *element, UvElement *element_iter,
+        StitchStateContainer *ssc, StitchState *state)
 {
 	BMesh *bm = state->em->bm;
 	float limit;
@@ -329,9 +347,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_i
 		return 0;
 	}
 
-	limit = state->limit_dist;
+	limit = ssc->limit_dist;
 
-	if (state->use_limit) {
+	if (ssc->use_limit) {
 		MLoopUV *luv, *luv_iter;
 		BMLoop *l;
 
@@ -355,7 +373,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_i
 	}
 }
 
-static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+static bool stitch_check_edges_stitchable(
+        UvEdge *edge, UvEdge *edge_iter,
+        StitchStateContainer *ssc, StitchState *state)
 {
 	BMesh *bm = state->em->bm;
 	float limit;
@@ -364,9 +384,9 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitc
 		return 0;
 	}
 
-	limit = state->limit_dist;
+	limit = ssc->limit_dist;
 
-	if (state->use_limit) {
+	if (ssc->use_limit) {
 		BMLoop *l;
 		MLoopUV *luv_orig1, *luv_iter1;
 		MLoopUV *luv_orig2, *luv_iter2;
@@ -397,27 +417,30 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitc
 	}
 }
 
-static bool stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
+static bool stitch_check_uvs_state_stitchable(
+        UvElement *element, UvElement *element_iter,
+        StitchStateContainer *ssc, StitchState *state)
 {
-	if ((state->snap_islands && element->island == element_iter->island) ||
-	    (!state->midpoints && element->island == element_iter->island))
+	if ((ssc->snap_islands && element->island == element_iter->island) ||
+	    (!ssc->midpoints && element->island == element_iter->island))
 	{
 		return 0;
 	}
 
-	return stitch_check_uvs_stitchable(element, element_iter, state);
+	return stitch_check_uvs_stitchable(element, element_iter, ssc, state);
 }
 
-
-static bool stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+static bool stitch_check_edges_state_stitchable(
+        UvEdge *edge, UvEdge *edge_iter,
+        StitchStateContainer *ssc, StitchState *state)
 {
-	if ((state->snap_islands && edge->element->island == edge_iter->element->island) ||
-	    (!state->midpoints && edge->element->island == edge_iter->element->island))
+	if ((ssc->snap_islands && edge->element->island == edge_iter->element->island) ||
+	    (!ssc->midpoints && edge->element->island == edge_iter->element->island))
 	{
 		return 0;
 	}
 
-	return stitch_check_edges_stitchable(edge, edge_iter, state);
+	return stitch_check_edges_stitchable(edge, edge_iter, ssc, state);
 }
 
 /* calculate snapping for islands */
@@ -506,8 +529,8 @@ static void stitch_calculate_island_snapping(
 
 
 static void stitch_island_calculate_edge_rotation(
-        UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map,
-        IslandStitchData *island_stitch_data)
+        UvEdge *edge, StitchStateContainer *ssc, StitchState *state, UVVertAverage *uv_average,
+        unsigned int *uvfinal_map, IslandStitchData *island_stitch_data)
 {
 	BMesh *bm = state->em->bm;
 	UvElement *element1, *element2;
@@ -523,7 +546,7 @@ static void stitch_island_calculate_edge_rotation(
 	luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_MLOOPUV);
 	luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_MLOOPUV);
 
-	if (state->mode == STITCH_VERT) {
+	if (ssc->mode == STITCH_VERT) {
 		index1 = uvfinal_map[element1 - state->element_map->buf];
 		index2 = uvfinal_map[element2 - state->element_map->buf];
 	}
@@ -562,7 +585,7 @@ static void stitch_island_calculate_edge_rotation(
 
 
 static void stitch_island_calculate_vert_rotation(
-        UvElement *element, StitchState *state,
+        UvElement *element, StitchStateContainer *ssc, StitchState *state,
         IslandStitchData *island_stitch_data)
 {
 	float edgecos = 1.0f, edgesin = 0.0f;
@@ -572,7 +595,7 @@ static void stitch_island_calculate_vert_rotation(
 	int rot_elem = 0, rot_elem_neg = 0;
 	BMLoop *l;
 
-	if (element->island == state->static_island && !state->midpoints)
+	if (element->island == ssc->static_island && !ssc->midpoints)
 		return;
 
 	l = element->l;
@@ -582,12 +605,12 @@ static void stitch_island_calculate_vert_rotation(
 	element_iter = state->element_map->vert[index];
 
 	for (; element_iter; element_iter = element_iter->next) {
-		if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) {
+		if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
 			int index_tmp1, index_tmp2;
 			float normal[2];
 
 			/* only calculate rotation against static island uv verts */
-			if (!state->midpoints && element_iter->island != state->static_island)
+			if (!ssc->midpoints && element_iter->island != ssc->static_island)
 				continue;
 
 			index_tmp1 = element_iter - state->element_map->buf;
@@ -609,7 +632,7 @@ static void stitch_island_calculate_vert_rotation(
 		}
 	}
 
-	if (state->midpoints) {
+	if (ssc->midpoints) {
 		rotation /= 2.0f;
 		rotation_neg /= 2.0f;
 	}
@@ -623,6 +646,9 @@ static void stitch_island_calculate_vert_rotation(
 static void state_delete(StitchState *state)
 {
 	if (state) {
+		if (state->island_is_stitchable) {
+			MEM_freeN(state->island_is_stitchable);
+		}
 		if (state->element_map) {
 			BM_uv_element_map_free(state->element_map);
 		}
@@ -654,6 +680,18 @@ static void state_delete(StitchState *state)
 	}
 }
 
+static void state_delete_all(StitchStateContainer *ssc)
+{
+	if (ssc) {
+		for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+			state_delete(ssc->states[ob_index]);
+		}
+		MEM_freeN(ssc->states);
+		MEM_freeN(ssc->objects);
+		MEM_freeN(ssc);
+	}
+}
+
 static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state)
 {
 	UvEdge *edges = state->edges;
@@ -736,7 +774,7 @@ static void stitch_uv_edge_generate_linked_e

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list