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

Antony Riakiotakis kalast at gmail.com
Thu Jul 21 18:15:33 CEST 2011


Revision: 38567
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38567
Author:   psy-fi
Date:     2011-07-21 16:15:31 +0000 (Thu, 21 Jul 2011)
Log Message:
-----------
smart stitch
============================
-Island rotation works in preview, spoiled in final. Fix coming soon

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

Modified: branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c	2011-07-21 16:05:21 UTC (rev 38566)
+++ branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c	2011-07-21 16:15:31 UTC (rev 38567)
@@ -1116,7 +1116,7 @@
 	ot->poll= ED_operator_uvedit;
 }
 
-/* ******************** stitch operator **************** */
+/* ********************** smart stitch operator *********************** */
 
 
 struct IslandStitchData;
@@ -1130,6 +1130,7 @@
 	/* Used for rotation, the island will rotate around this point */
 	float medianPoint[2];
 	int numOfElements;
+	int numOfEdges;
 	/* Flag to remember if island has been aded for preview */
 	char addedForPreview;
 }IslandStitchData;
@@ -1260,7 +1261,20 @@
 	}
 }
 
+static void stitch_island_rotate(float rotation, float medianPoint[2], float uv[2]){
+	float uv_rotation_result[2];
 
+	uv[0] -= medianPoint[0];
+	uv[1] -= medianPoint[1];
+
+	uv_rotation_result[0] = cos(rotation)*uv[0] - sin(rotation)*uv[1];
+	uv_rotation_result[1] = sin(rotation)*uv[0] + cos(rotation)*uv[1];
+
+	uv[0] = uv_rotation_result[0] + medianPoint[0];
+	uv[1] = uv_rotation_result[1] + medianPoint[1];
+}
+
+
 /* Calculate snapping for islands */
 static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final){
 	int i;
@@ -1268,41 +1282,51 @@
 	MTFace *mt;
 	UvElement *element;
 
-	if(state->snapIslands){
-		for(i = 0; i <  state->vmap->numOfIslands; i++){
-			if(island_stitch_data[i].addedForPreview){
-				int previewIslandUVs = 0, j;
-
-				island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
-				island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
-
-				if(i == state->vmap->numOfIslands-1){
-					previewIslandUVs = state->vmap->numOfUVs - state->vmap->islandIndices[i];
-				}else{
-					previewIslandUVs = state->vmap->islandIndices[i+1] - state->vmap->islandIndices[i];
-				}
-
-				element = &state->vmap->buf[state->vmap->islandIndices[i]];
-				for(j = 0; j < previewIslandUVs; j++, element++){
-					/* stitchable uvs have already been processed, don't process */
-					if(!(element->flag & STITCH_STITCHABLE)){
-						efa = element->face;
-						mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
-						if(final){
-							mt->uv[element->tfindex][0] += island_stitch_data[i].translation[0];
-							mt->uv[element->tfindex][1] += island_stitch_data[i].translation[1];
+	for(i = 0; i <  state->vmap->numOfIslands; i++){
+		if(island_stitch_data[i].addedForPreview){
+			int previewIslandUVs = 0, j;
+			/* check to avoid divide by 0 */
+			if(state->mode == EDGE_STITCH){
+				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;
+			}
+			island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
+			island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
+			if(i == state->vmap->numOfIslands-1){
+				previewIslandUVs = state->vmap->numOfUVs - state->vmap->islandIndices[i];
+			}else{
+				previewIslandUVs = state->vmap->islandIndices[i+1] - state->vmap->islandIndices[i];
+			}
+			element = &state->vmap->buf[state->vmap->islandIndices[i]];
+			for(j = 0; j < previewIslandUVs; j++, element++){
+				/* stitchable uvs have already been processed, don't process */
+				if(!(element->flag & STITCH_STITCHABLE)){
+					efa = element->face;
+					mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+					if(final){
+						if(state->mode == EDGE_STITCH){
+							stitch_island_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, mt->uv[element->tfindex]);
 						}
-						else{
-							if(efa->v4){
-								preview->previewQuads[efa->tmp.l + 2*element->tfindex] += island_stitch_data[i].translation[0];
-								preview->previewQuads[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
+						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->v4){
+							if(state->mode == EDGE_STITCH){
+								stitch_island_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->previewQuads[efa->tmp.l + 2*element->tfindex]);
 							}
-							else {
-								preview->previewTris[efa->tmp.l + 2*element->tfindex]  += island_stitch_data[i].translation[0];
-								preview->previewTris[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
+							preview->previewQuads[efa->tmp.l + 2*element->tfindex] += island_stitch_data[i].translation[0];
+							preview->previewQuads[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
+						}
+						else {
+							if(state->mode == EDGE_STITCH){
+								stitch_island_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->previewTris[efa->tmp.l + 2*element->tfindex]);
 							}
-							element->flag = 0;
+							preview->previewTris[efa->tmp.l + 2*element->tfindex]  += island_stitch_data[i].translation[0];
+							preview->previewTris[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
 						}
+						element->flag = 0;
 					}
 				}
 			}
@@ -1310,6 +1334,50 @@
 	}
 }
 
+static void stitch_island_calculate_rotation(UvElement *element, int i, StitchState *state, UVVertAverage *uv_average, IslandStitchData *island_stitch_data)
+{
+	EditFace *efa;
+	MTFace *mt;
+	int nverts;
+	float uv1[2], uv2[2];
+	UvElement *element2;
+	float edgecos, edgesin;
+	int i2;
+
+	efa = element->face;
+	nverts = (efa->v4)? 4 : 3;
+	mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+
+	/* find second UV element */
+	element2 = state->vmap->vert[(*(&efa->v1 + (element->tfindex + 1)%nverts))->tmp.l];
+	for(; element2; element2 = element2->next){
+		if(element2->face == efa){
+			break;
+		}
+	}
+	i2 = element2 - state->vmap->buf;
+
+	/* 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... */
+	uv1[0] = mt->uv[(element->tfindex + 1)%nverts][0] - mt->uv[element->tfindex][0];
+	uv1[1] = mt->uv[(element->tfindex + 1)%nverts][1] - mt->uv[element->tfindex][1];
+
+	uv2[0] = uv_average[i2].uv[0]/uv_average[i2].count - uv_average[i].uv[0]/uv_average[i].count;
+	uv2[1] = uv_average[i2].uv[1]/uv_average[i2].count - uv_average[i].uv[1]/uv_average[i].count;
+
+	normalize_v2(uv1);
+	normalize_v2(uv2);
+
+	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;
+
+}
+
 /* This function prepares the data of the previewer for display */
 static int stitch_process_data(StitchState *state, int final, Scene *scene, int doIndexInit)
 {
@@ -1792,26 +1860,8 @@
 
 					/* we will have to calculate the rotation of the edges here */
 					if(state->snapIslands && element->flag & STITCH_EDGE_STITCHABLE){
-						float uv1[2], uv2[2];
-
-						efa = element->face;
-						nverts = (efa->v4)? 4 : 3;
-						mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
-
-						/* grab original uv's*/
-						uv1[0] = mt->uv[(element->tfindex + 1)%nverts][0] - mt->uv[element->tfindex][0];
-						uv1[1] = mt->uv[(element->tfindex + 1)%nverts][1] - mt->uv[element->tfindex][1];
-
-						//uv2[0] = ;
-						//uv2[1] = ;
-
-						/* The idea here is to take the directions of the edges and find the rotation between final and initial
-						 * edge */
-						normalize_v2(uv1);
-						//normalize_v2(uv2);
-
+						stitch_island_calculate_rotation(element, i, state, uv_average, island_stitch_data);
 					}
-
 					if(element->flag & STITCH_EDGE_STITCHABLE){
 						preview->previewOrigColors[bufferIterator*2] = 0x0000FF00;
 						preview->previewOrigColors[bufferIterator*2 + 1] = 0x0000FF00;
@@ -1827,8 +1877,9 @@
 				element->flag = 0;
 			}
 		}
-
-		stitch_calculate_island_snapping(state, preview, island_stitch_data, 0);
+		if(state->snapIslands){
+			stitch_calculate_island_snapping(state, preview, island_stitch_data, 0);
+		}
 	}
 
 
@@ -1849,6 +1900,10 @@
 					island_stitch_data[element->island].translation[0] += uv[0] - mt->uv[element->tfindex][0];
 					island_stitch_data[element->island].translation[1] += uv[1] - mt->uv[element->tfindex][1];
 					island_stitch_data[element->island].numOfElements++;
+
+					if(element->flag & STITCH_EDGE_STITCHABLE){
+						stitch_island_calculate_rotation(element, i, state, uv_average, island_stitch_data);
+					}
 				}
 
 				mt->uv[element->tfindex][0] = uv[0];
@@ -1857,7 +1912,9 @@
 				uvedit_uv_select(scene, efa, mt, element->tfindex);
 			}
 		}
-		stitch_calculate_island_snapping(state, preview, island_stitch_data, 1);
+		if(state->snapIslands){
+			stitch_calculate_island_snapping(state, preview, island_stitch_data, 1);
+		}
 	}
 
 	if(island_stitch_data)




More information about the Bf-blender-cvs mailing list