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

Antony Riakiotakis kalast at gmail.com
Thu Jan 5 17:21:23 CET 2012


Revision: 43171
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43171
Author:   psy-fi
Date:     2012-01-05 16:21:15 +0000 (Thu, 05 Jan 2012)
Log Message:
-----------
smart stitch
============
-Island rotation re-enabled, using edge information. I have also included some code to detect rotation based on uv vertices (not functional yet) if user didn't select any whole edges. There are still some graphics issues to solve.

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

Modified: branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_smart_stitch.c
===================================================================
--- branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_smart_stitch.c	2012-01-05 16:04:25 UTC (rev 43170)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_smart_stitch.c	2012-01-05 16:21:15 UTC (rev 43171)
@@ -103,8 +103,6 @@
 
 /* stitch state object */
 typedef struct StitchState {
-	/* edge or vertex stitch mode */
-	char mode;
 	/* use limit flag */
 	char use_limit;
 	/* limit to operator, same as original operator */
@@ -121,9 +119,14 @@
 	UvEdge *uvedges;
 	/* container of first of a group of coincident uvs, these will be operated upon */
 	UvElement **uvs;
+	/* 2D normals per uv to calculate rotation for snapping */
+	float *normals;
+	/* edge storage */
+	UvEdge *edges;
+
+	/* count of separate uvs and edges */
+	int total_boundary_edges;
 	int total_separate_uvs;
-	/* maps uvelements to their first coincident uv */
-	int *map;
 	/* hold selection related information */
 	void **selection_stack;
 	int selection_size;
@@ -266,7 +269,8 @@
 		if(island_stitch_data[i].addedForPreview){
 			int numOfIslandUVs = 0, j;
 			/* check to avoid divide by 0 */
-			if(0){
+
+			if( island_stitch_data[i].numOfEdges>0){
 				island_stitch_data[i].rotation /= island_stitch_data[i].numOfEdges;
 				island_stitch_data[i].medianPoint[0] /= island_stitch_data[i].numOfEdges;
 				island_stitch_data[i].medianPoint[1] /= island_stitch_data[i].numOfEdges;
@@ -281,24 +285,24 @@
 					efa = element->face;
 					mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
 					if(final){
-						if(0){
-							stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, mt->uv[element->tfindex]);
-						}
+
+						stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, mt->uv[element->tfindex]);
+
 						mt->uv[element->tfindex][0] += island_stitch_data[i].translation[0];
 						mt->uv[element->tfindex][1] += island_stitch_data[i].translation[1];
 					}
 					else if(efa->tmp.l != STITCH_NO_PREVIEW){
 						if(efa->v4){
-							if(0){
-								stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_quads[efa->tmp.l + 2*element->tfindex]);
-							}
+
+							stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_quads[efa->tmp.l + 2*element->tfindex]);
+
 							preview->preview_quads[efa->tmp.l + 2*element->tfindex] += island_stitch_data[i].translation[0];
 							preview->preview_quads[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
 						}
 						else {
-							if(0){
-								stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_tris[efa->tmp.l + 2*element->tfindex]);
-							}
+
+							stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_tris[efa->tmp.l + 2*element->tfindex]);
+
 							preview->preview_tris[efa->tmp.l + 2*element->tfindex]  += island_stitch_data[i].translation[0];
 							preview->preview_tris[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
 						}
@@ -313,7 +317,7 @@
 
 
 
-static void stitch_island_calculate_rotation(UvEdge *edge, StitchState *state, UVVertAverage *uv_average, IslandStitchData *island_stitch_data)
+static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map, IslandStitchData *island_stitch_data)
 {
 	UvElement *element;
 	EditFace *efa;
@@ -328,8 +332,8 @@
 	nverts = (efa->v4)? 4 : 3;
 	mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
 
-	index1 = (*(&element->face->v1 + element->tfindex))->tmp.l;
-	index2 = (*(&element->face->v1 + (element->tfindex + 1)%nverts))->tmp.l;
+	index1 = uvfinal_map[(*(&element->face->v1 + element->tfindex))->tmp.l];
+	index2 = uvfinal_map[(*(&element->face->v1 + (element->tfindex + 1)%nverts))->tmp.l];
 
 	/* the idea here is to take the directions of the edges and find the rotation between final and initial
 	* direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */
@@ -350,8 +354,28 @@
 	island_stitch_data[element->island].medianPoint[0] += (mt->uv[(element->tfindex + 1)%nverts][0] + mt->uv[element->tfindex][0]) / 2.0;
 	island_stitch_data[element->island].medianPoint[1] += (mt->uv[(element->tfindex + 1)%nverts][1] + mt->uv[element->tfindex][1]) / 2.0;
 }
+/*
+static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data)
+{
+	float normal1[2], normal2[2];
+	float edgecos, edgesin;
+	int index;
 
+	index = (*(&element->face->v1 + element->tfindex))->tmp.l;
 
+	normalize_v2(normal1);
+	normalize_v2(normal2);
+
+	edgecos = uv1[0]*uv2[0] + uv1[1]*uv2[1];
+	edgesin = uv1[0]*uv2[1] - uv2[0]*uv1[1];
+
+	island_stitch_data[element->island].numOfEdges++;
+	island_stitch_data[element->island].rotation += (edgesin > 0)? acos(edgecos): -acos(edgecos);
+	island_stitch_data[element->island].medianPoint[0] += (mt->uv[(element->tfindex + 1)%nverts][0] + mt->uv[element->tfindex][0]) / 2.0;
+	island_stitch_data[element->island].medianPoint[1] += (mt->uv[(element->tfindex + 1)%nverts][1] + mt->uv[element->tfindex][1]) / 2.0;
+}
+*/
+
 static void stitch_state_delete(StitchState *stitch_state)
 {
 	if(stitch_state){
@@ -364,15 +388,18 @@
 		if(stitch_state->selection_stack){
 			MEM_freeN(stitch_state->selection_stack);
 		}
-		if(stitch_state->map){
-			MEM_freeN(stitch_state->map);
-		}
 		if(stitch_state->quads_per_island){
 			MEM_freeN(stitch_state->quads_per_island);
 		}
 		if(stitch_state->tris_per_island){
 			MEM_freeN(stitch_state->tris_per_island);
 		}
+		if(stitch_state->normals){
+			MEM_freeN(stitch_state->normals);
+		}
+		if(stitch_state->edges){
+			MEM_freeN(stitch_state->edges);
+		}
 		MEM_freeN(stitch_state);
 	}
 }
@@ -505,11 +532,13 @@
 	int i;
 	StitchPreviewer *preview = uv_get_stitch_previewer();
 	IslandStitchData *island_stitch_data = NULL;
-	int previousIsland = state->static_island;
+	int previous_island = state->static_island;
 	EditFace *efa;
 	EditVert *ev;
-	UVVertAverage *averageUvPosition;
-	char stitchAtMidpoints = state->midpoints;
+	UVVertAverage *final_position;
+	char stitch_midpoints = state->midpoints;
+	/* used to map uv indices to uvaverage indices for selection */
+	unsigned int *uvfinal_map;
 
 	/* cleanup previous preview */
 	stitch_preview_delete();
@@ -546,7 +575,7 @@
 		state->static_island++;
 		state->static_island %= state->element_map->totalIslands;
 		/* this is entirely possible if for example limit stitching with no stitchable verts or no selection */
-		if(state->static_island == previousIsland)
+		if(state->static_island == previous_island)
 			break;
 	}
 
@@ -653,32 +682,34 @@
 	 * Here we calculate the final coordinates of the uvs *
 	 ******************************************************/
 
-	averageUvPosition = MEM_callocN(state->selection_size*sizeof(*averageUvPosition), "stitch_uv_average");
+	final_position = MEM_callocN(state->selection_size*sizeof(*final_position), "stitch_uv_average");
+	uvfinal_map = MEM_mallocN(state->em->totvert*sizeof(*uvfinal_map), "stitch_uv_final_map");
 
 	/* first pass, calculate final position for stitchable uvs */
 	for(i = 0; i < state->selection_size; i++){
 		UvElement *element = (UvElement *)state->selection_stack[i];
 		if(element->flag & STITCH_STITCHABLE){
 			UvElement *element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l];
+			uvfinal_map[(*(&element->face->v1 + element->tfindex))->tmp.l] = i;
 			for(;element_iter; element_iter = element_iter->next){
 				if(element_iter->flag & STITCH_STITCHABLE){
 					MTFace *mt;
 					efa = element_iter->face;
 					mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
-					if(stitchAtMidpoints){
-						averageUvPosition[i].uv[0] += mt->uv[element_iter->tfindex][0];
-						averageUvPosition[i].uv[1] += mt->uv[element_iter->tfindex][1];
-						averageUvPosition[i].count++;
+					if(stitch_midpoints){
+						final_position[i].uv[0] += mt->uv[element_iter->tfindex][0];
+						final_position[i].uv[1] += mt->uv[element_iter->tfindex][1];
+						final_position[i].count++;
 					}else if(element_iter->island == state->static_island){
-						averageUvPosition[i].uv[0] = mt->uv[element_iter->tfindex][0];
-						averageUvPosition[i].uv[1] = mt->uv[element_iter->tfindex][1];
+						final_position[i].uv[0] = mt->uv[element_iter->tfindex][0];
+						final_position[i].uv[1] = mt->uv[element_iter->tfindex][1];
 					}
 				}
 			}
 		}
-		if(stitchAtMidpoints){
-			averageUvPosition[i].uv[0] /= averageUvPosition[i].count;
-			averageUvPosition[i].uv[1] /= averageUvPosition[i].count;
+		if(stitch_midpoints){
+			final_position[i].uv[0] /= final_position[i].count;
+			final_position[i].uv[1] /= final_position[i].count;
 		}
 	}
 
@@ -693,12 +724,20 @@
 
 				/* accumulate each islands' translation from stitchable elements. it is important to do here
 				 * because in final pass MTFaces get modified and result is zero. */
-				island_stitch_data[element->island].translation[0] += averageUvPosition[i].uv[0] - mt->uv[element->tfindex][0];
-				island_stitch_data[element->island].translation[1] += averageUvPosition[i].uv[1] - mt->uv[element->tfindex][1];
+				island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - mt->uv[element->tfindex][0];
+				island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - mt->uv[element->tfindex][1];
 				island_stitch_data[element->island].numOfElements++;
 			}
 		}
 	}
+	/* only calculate rotation when an edge has been fully selected */
+	for(i = 0; i < state->total_boundary_edges; i++){
+		UvEdge *edge = state->edges+i;
+		if((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) &&
+				(state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)){
+			stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
+		}
+	}
 
 	/* third pass, propagate changes to stitchable uvs */
 	for(i = 0; i < state->selection_size; i++){
@@ -720,22 +759,22 @@
 						element_iter->flag |= STITCH_PROCESSED;

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-blender-cvs mailing list