[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41347] branches/soc-2011-onion-uv-tools/ source/blender/editors/uvedit/uvedit_ops.c: smart stitching

Antony Riakiotakis kalast at gmail.com
Fri Oct 28 20:46:51 CEST 2011


Revision: 41347
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41347
Author:   psy-fi
Date:     2011-10-28 18:46:50 +0000 (Fri, 28 Oct 2011)
Log Message:
-----------
smart stitching
================
*fix incorrect proximity calculation for edge limit stitch
*enable switching selection from edge to uv after operator redo. Previous selection gets converted if mode is different than the stored format of selection.
This is not 100% tested yet because edge stitch is not working currently but should be correct.

--Edge stitch implementation and we're set for review :)

Modified Paths:
--------------
    branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c

Modified: branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c
===================================================================
--- branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c	2011-10-28 17:00:53 UTC (rev 41346)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c	2011-10-28 18:46:50 UTC (rev 41347)
@@ -2358,8 +2358,8 @@
 								MTFace *mtface_orig1 = CustomData_em_get(&state->em->fdata, element1->face->data, CD_MTFACE);
 								MTFace *mtface_iter1 = CustomData_em_get(&state->em->fdata, element_iter1->face->data, CD_MTFACE);
 
-								MTFace *mtface_orig2 = CustomData_em_get(&state->em->fdata, element1->face->data, CD_MTFACE);
-								MTFace *mtface_iter2 = CustomData_em_get(&state->em->fdata, element_iter1->face->data, CD_MTFACE);
+								MTFace *mtface_orig2 = CustomData_em_get(&state->em->fdata, element2->face->data, CD_MTFACE);
+								MTFace *mtface_iter2 = CustomData_em_get(&state->em->fdata, element_iter2->face->data, CD_MTFACE);
 
 								if(fabs(mtface_orig1->uv[element1->tfindex][0] - mtface_iter1->uv[element_iter1->tfindex][0]) < state->limitDist
 										&& fabs(mtface_orig1->uv[element1->tfindex][1] - mtface_iter1->uv[element_iter1->tfindex][1]) < state->limitDist
@@ -2638,7 +2638,7 @@
 	return 1;
 }
 
-/* Stitch initialization functions */
+/* Stitch hash initialization functions */
 static unsigned int	uv_edge_hash(const void *key){
 	UvEdge *edge = (UvEdge *)key;
 	return
@@ -2656,6 +2656,165 @@
 	return 1;
 }
 
+
+/* Make sure we are selecting only one of a vertex's common uv */
+static void stitch_select_uv(UvElement *element, StitchState *stitch_state, void **selection_stack, int *total_selected, int select)
+{
+	int uniqueIndex;
+	/* This works due to setting of tmp in find nearest uv vert */
+	UvElement *element_iter, *unique_element;
+	uniqueIndex = stitch_state->map[element - stitch_state->elementMap->buf];
+	unique_element = stitch_state->uvs[uniqueIndex];
+	element_iter = stitch_state->elementMap->vert[(*(&element->face->v1 + element->tfindex))->tmp.l];
+	/* first deselect all common uvs */
+	for(; element_iter; element_iter = element_iter->next){
+		if(element_iter->separate){
+			/* only separators go to selection */
+			if(element_iter->flag & STITCH_SELECTED){
+				int i;
+				element_iter->flag &= ~STITCH_SELECTED;
+				for(i = 0; i < *total_selected; i++){
+					if(((UvElement *)selection_stack[i]) == element_iter){
+						(*total_selected)--;
+						selection_stack[i] = selection_stack[*total_selected];
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	if(select && !(unique_element->flag & STITCH_SELECTED)){
+		unique_element->flag |= STITCH_SELECTED;
+		selection_stack[(*total_selected)++] = unique_element;
+	}
+}
+
+/* Make sure we are selecting only one of edges with common vertices */
+static void stitch_select_edge(UvEdge *edge, StitchState *state, void **selection_stack, int *total_selected, int select)
+{
+	UvElement *element1 = state->uvs[edge->uv1];
+	UvElement *element2 = state->uvs[edge->uv2];
+
+	UvElement *element_iter1 = state->elementMap->vert[(*(&element1->face->v1 + element1->tfindex))->tmp.l];
+
+	for(;element_iter1; element_iter1 = element_iter1->next){
+
+		UvElement *element_iter2 = state->elementMap->vert[(*(&element2->face->v1 + element2->tfindex))->tmp.l];
+
+		for(;element_iter2; element_iter2 = element_iter2->next){
+			int uniqueIndex1;
+			int uniqueIndex2;
+			UvEdge tmp_edge, *edge_iter;
+
+			uniqueIndex1 = state->map[element_iter1 - state->elementMap->buf];
+			uniqueIndex2 = state->map[element_iter2 - state->elementMap->buf];
+
+			if(uniqueIndex2 > uniqueIndex1){
+				tmp_edge.uv1 = uniqueIndex1;
+				tmp_edge.uv2 = uniqueIndex2;
+			}else{
+				tmp_edge.uv1 = uniqueIndex2;
+				tmp_edge.uv2 = uniqueIndex1;
+			}
+
+			edge_iter = (UvEdge *)BLI_ghash_lookup(state->edgeHash, &tmp_edge);
+
+			if(edge_iter && edge_iter->flag & STITCH_SELECTED){
+				int i;
+				edge_iter->flag &= ~STITCH_SELECTED;
+				for(i = 0; i < *total_selected; i++){
+					if(((UvEdge *)selection_stack[i]) == edge_iter){
+						(*total_selected)--;
+						selection_stack[i] = selection_stack[*total_selected];
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	if(select){
+		edge->flag |= STITCH_SELECTED;
+		selection_stack[(*total_selected)++] = edge;
+	}
+}
+
+/* Switch between edge/uv selection mode*/
+static void stitch_switch_mode(StitchState *stitch_state){
+	EditVert *ev;
+	int i;
+
+	void **new_selection = MEM_mallocN(sizeof(*new_selection)*stitch_state->elementMap->totalUVs, "uv_stitch_selection_stack");
+
+	/* Store Indices to editVerts. */
+	for(ev = stitch_state->em->verts.first, i = 0; ev; ev = ev->next, i++){
+		ev->tmp.l = i;
+	}
+
+	if(stitch_state->mode == EDGE_STITCH){
+		int i;
+		int total_uvs_selected = 0;
+
+		for(i = 0; i < stitch_state->selection_size; i++){
+			UvEdge *edge = stitch_state->selection_stack[i];
+
+			stitch_select_uv(stitch_state->uvs[edge->uv1], stitch_state, new_selection, &total_uvs_selected, 1);
+			stitch_select_uv(stitch_state->uvs[edge->uv2], stitch_state, new_selection, &total_uvs_selected, 1);
+
+			edge->flag &= ~STITCH_SELECTED;
+		}
+
+		stitch_state->mode = VERT_STITCH;
+		MEM_freeN(stitch_state->selection_stack);
+		stitch_state->selection_size = total_uvs_selected;
+	}
+	else{
+		int i;
+		int total_edges_selected = 0;
+
+		/* first do a quick evaluation of stitchability of uvs */
+		for(i = 0; i < stitch_state->selection_size; i++){
+			UvElement *element = (UvElement *)stitch_state->selection_stack[i];
+			UvElement *element_iter = stitch_state->elementMap->vert[(*(&element->face->v1 + element->tfindex))->tmp.l];
+			for(; element_iter; element_iter = element_iter->next){
+				if(element_iter->separate){
+					if(stitch_state->use_limit){
+						MTFace *mtface_orig = CustomData_em_get(&stitch_state->em->fdata, element->face->data, CD_MTFACE);
+						MTFace *mtface_iter = CustomData_em_get(&stitch_state->em->fdata, element_iter->face->data, CD_MTFACE);
+
+						if(fabs(mtface_orig->uv[element->tfindex][0] - mtface_iter->uv[element_iter->tfindex][0]) < stitch_state->limitDist
+							&& fabs(mtface_orig->uv[element->tfindex][1] - mtface_iter->uv[element_iter->tfindex][1]) < stitch_state->limitDist){
+							element_iter->flag |= STITCH_STITCHABLE;
+						}
+					}else{
+						element_iter->flag |= STITCH_STITCHABLE;
+					}
+				}
+			}
+		}
+		/* Then select one of the edges */
+		for(i = 0; i < stitch_state->total_edges; i++){
+			UvEdge *edge = stitch_state->edges + i;
+
+			if(stitch_state->uvs[edge->uv1]->flag & STITCH_STITCHABLE && stitch_state->uvs[edge->uv2]->flag & STITCH_STITCHABLE){
+				stitch_select_edge(edge, stitch_state, new_selection, &total_edges_selected, 1);
+			}
+		}
+
+		/* Cleanup old uv element selection */
+		for(i = 0; i < stitch_state->total_separate_uvs; i++){
+			((UvElement *)stitch_state->uvs[i])->flag &= ~(STITCH_SELECTED | STITCH_STITCHABLE);
+		}
+		stitch_state->mode = EDGE_STITCH;
+		MEM_freeN(stitch_state->selection_stack);
+		stitch_state->selection_size = total_edges_selected;
+	}
+
+	stitch_state->selection_stack = new_selection;
+}
+
+
 static int stitch_init(bContext *C, wmOperator *op)
 {
 	int counter = 0, i;
@@ -2810,24 +2969,64 @@
 	stitch_state->selection_size = 0;
 
 	/* Fill selection stack */
+
+	/* Load old selection if redoing operator with different settings */
 	if(RNA_property_is_set(op->ptr, "selection")){
+		unsigned int oldMode =  RNA_enum_get(op->ptr, "mode_old");
 		int faceIndex, elementIndex, uniqueIndex;
 		UvElement *element;
 
 		EM_init_index_arrays(em, 0, 0, 1);
 
-		RNA_BEGIN(op->ptr, itemptr, "selection") {
-			faceIndex = RNA_int_get(&itemptr, "face_index");
-			elementIndex = RNA_int_get(&itemptr, "element_index");
-			element = get_uv_element(stitch_state->elementMap, EM_get_face_for_index(faceIndex), elementIndex);
-			uniqueIndex = stitch_state->map[element - stitch_state->elementMap->buf];
-			if(!(stitch_state->uvs[uniqueIndex]->flag & STITCH_SELECTED)){
-				stitch_state->selection_stack[stitch_state->selection_size++] = stitch_state->uvs[uniqueIndex];
-				stitch_state->uvs[uniqueIndex]->flag |= STITCH_SELECTED;
+
+			RNA_BEGIN(op->ptr, itemptr, "selection") {
+				faceIndex = RNA_int_get(&itemptr, "face_index");
+				elementIndex = RNA_int_get(&itemptr, "element_index");
+				efa = EM_get_face_for_index(faceIndex);
+				element = get_uv_element(stitch_state->elementMap, efa, elementIndex);
+				uniqueIndex = stitch_state->map[element - stitch_state->elementMap->buf];
+
+				if(oldMode == VERT_STITCH){
+					if(!(stitch_state->uvs[uniqueIndex]->flag & STITCH_SELECTED)){
+						stitch_state->selection_stack[stitch_state->selection_size++] = stitch_state->uvs[uniqueIndex];
+						stitch_state->uvs[uniqueIndex]->flag |= STITCH_SELECTED;
+					}
+				}else{
+					UvEdge *edge, tmp_edge;
+					int uniqueIndex2, nverts;
+					UvElement *element2;
+
+					nverts = efa->v4? 4 : 3;
+
+					element2 = get_uv_element(stitch_state->elementMap, efa, (elementIndex+1)%nverts);
+					uniqueIndex2 = stitch_state->map[element2 - stitch_state->elementMap->buf];
+
+					if(uniqueIndex2 > uniqueIndex){
+						tmp_edge.uv1 = uniqueIndex;
+						tmp_edge.uv2 = uniqueIndex2;
+					}else{
+						tmp_edge.uv1 = uniqueIndex2;
+						tmp_edge.uv2 = uniqueIndex;
+					}
+
+					edge = (UvEdge *)BLI_ghash_lookup(stitch_state->edgeHash, &tmp_edge);
+
+					if(!(edge->flag & STITCH_SELECTED)){
+						stitch_state->selection_stack[stitch_state->selection_size++] = edge;
+						edge->flag |= STITCH_SELECTED;
+					}
+				}
 			}
+			RNA_END;
+
+		EM_free_index_arrays();
+		/* Clear the selection */
+		RNA_collection_clear(op->ptr, "selection");
+
+		if(stitch_state->mode != oldMode){
+			stitch_state->mode = oldMode;
+			stitch_switch_mode(stitch_state);
 		}
-		RNA_END;
-		EM_free_index_arrays();
 	} else {
 		for(efa = stitch_state->em->faces.first ; efa; efa = efa->next){
 			int numOfVerts;
@@ -2893,11 +3092,13 @@
 		RNA_boolean_set(op->ptr, "snap_islands", stitch_state->snapIslands);
 		RNA_int_set(op->ptr, "static_island", stitch_state->static_island);
 		RNA_enum_set(op->ptr, "mode", stitch_state->mode);
+		RNA_enum_set(op->ptr, "mode_old", stitch_state->mode);
 		RNA_boolean_set(op->ptr, "midpoint_snap", stitch_state->midpoints);
 
 		for(i = 0, efa = stitch_state->em->faces.first; efa; efa = efa->next, i++){
 			efa->tmp.l = i;
 		}
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list