[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43547] trunk/blender/source/blender/ editors/uvedit/uvedit_smart_stitch.c: smart stitch

Antony Riakiotakis kalast at gmail.com
Fri Jan 20 01:02:49 CET 2012


Revision: 43547
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43547
Author:   psy-fi
Date:     2012-01-20 00:02:48 +0000 (Fri, 20 Jan 2012)
Log Message:
-----------
smart stitch
=============
* refactoring, separate common functionality to functions.
* enable each uv to check independently for other stitchable uvs. This allows to limit stitch uvs belonging to the same vertex, while previously this was impossible.
* made changes to island rotation when calculated from sole uvs when using midpoint stitch. It should now be evenly distributed across islands. 

There are still some glitches with vertices that have multiple uvs per island for the snap island + midpoint stitch combination. The solution is to precalculate the static island rotation/translation in this case. If I haven't managed to make this work correctly I may turn this combination off before release. It's more like an extra feature than really necessary.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/uvedit/uvedit_smart_stitch.c

Modified: trunk/blender/source/blender/editors/uvedit/uvedit_smart_stitch.c
===================================================================
--- trunk/blender/source/blender/editors/uvedit/uvedit_smart_stitch.c	2012-01-19 23:51:40 UTC (rev 43546)
+++ trunk/blender/source/blender/editors/uvedit/uvedit_smart_stitch.c	2012-01-20 00:02:48 UTC (rev 43547)
@@ -80,10 +80,12 @@
 	float medianPoint[2];
 	int numOfElements;
 	int num_rot_elements;
-	/* Flag to remember if island has been added for preview */
+	/* flag to remember if island has been added for preview */
 	char addedForPreview;
-	/* Flag an island to be considered for determining static island */
+	/* flag an island to be considered for determining static island */
 	char stitchableCandidate;
+	/* if edge rotation is used, flag so that vertex rotation is not used */
+	char use_edge_rotation;
 }IslandStitchData;
 
 /* just for averaging UVs */
@@ -262,7 +264,39 @@
 	uv[1] = uv_rotation_result[1] + medianPoint[1];
 }
 
+static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state){
+	float limit;
+	int do_limit;
 
+	if(element_iter == element){
+		return 0;
+	}
+
+	limit = state->limit_dist;
+	do_limit = state->use_limit;
+
+	if(do_limit){
+		MTFace *mtface_orig = CustomData_em_get(&state->em->fdata, element->face->data, CD_MTFACE);
+		MTFace *mtface_iter = CustomData_em_get(&state->em->fdata, element_iter->face->data, CD_MTFACE);
+
+		if(fabs(mtface_orig->uv[element->tfindex][0] - mtface_iter->uv[element_iter->tfindex][0]) < limit
+			&& fabs(mtface_orig->uv[element->tfindex][1] - mtface_iter->uv[element_iter->tfindex][1]) < limit){
+			return 1;
+		}else
+			return 0;
+	}else
+		return 1;
+}
+
+
+static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state){
+	if(state->snap_islands && element->island == element_iter->island)
+		return 0;
+
+	return stitch_check_uvs_stitchable(element, element_iter, state);
+}
+
+
 /* calculate snapping for islands */
 static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final){
 	int i;
@@ -324,26 +358,31 @@
 
 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;
-	MTFace *mt;
-	int nverts;
+	UvElement *element1, *element2;
+	EditFace *efa1;
+	EditFace *efa2;
+	MTFace *mt1;
+	MTFace *mt2;
 	float uv1[2], uv2[2];
 	float edgecos, edgesin;
 	int index1, index2;
+	float rotation;
 
-	element = edge->element;
-	efa = element->face;
-	nverts = (efa->v4)? 4 : 3;
-	mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+	element1 = state->uvs[edge->uv1];
+	element2 = state->uvs[edge->uv2];
 
-	index1 = uvfinal_map[(*(&element->face->v1 + element->tfindex))->tmp.l];
-	index2 = uvfinal_map[(*(&element->face->v1 + (element->tfindex + 1)%nverts))->tmp.l];
+	efa1 = element1->face;
+	mt1 = CustomData_em_get(&state->em->fdata, efa1->data, CD_MTFACE);
+	efa2 = element2->face;
+	mt2 = CustomData_em_get(&state->em->fdata, efa2->data, CD_MTFACE);
 
+	index1 = uvfinal_map[element1 - state->element_map->buf];
+	index2 = uvfinal_map[element2 - state->element_map->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];
+	uv1[0] = mt2->uv[element2->tfindex][0] - mt1->uv[element1->tfindex][0];
+	uv1[1] = mt2->uv[element2->tfindex][1] - mt1->uv[element1->tfindex][1];
 
 	uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0];
 	uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1];
@@ -353,47 +392,50 @@
 
 	edgecos = uv1[0]*uv2[0] + uv1[1]*uv2[1];
 	edgesin = uv1[0]*uv2[1] - uv2[0]*uv1[1];
-	island_stitch_data[element->island].num_rot_elements++;
-	island_stitch_data[element->island].rotation += (edgesin > 0)? acos(MAX2(-1.0, MIN2(1.0, edgecos))): -acos(MAX2(-1.0, MIN2(1.0, edgecos)));
+
+	rotation = (edgesin > 0)? acos(MAX2(-1.0, MIN2(1.0, edgecos))): -acos(MAX2(-1.0, MIN2(1.0, edgecos)));
+
+	island_stitch_data[element1->island].num_rot_elements++;
+	island_stitch_data[element1->island].rotation += rotation;
 }
 
-static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, char do_static)
+
+static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data)
 {
 	float edgecos = 1, edgesin = 0;
 	int index;
 	UvElement *element_iter;
+	float rotation = 0;
 
-	if((element->island == state->static_island) && !do_static)
+	if(element->island == state->static_island && !state->midpoints)
 		return;
 
 	index = (*(&element->face->v1 + element->tfindex))->tmp.l;
 
 	element_iter = state->element_map->vert[index];
 
-	if(!do_static){
-		for(; element_iter; element_iter = element_iter->next){
-			if((element_iter->separate) && (element_iter->flag & STITCH_STITCHABLE) &&
-					(element_iter != element) && (element_iter->island == state->static_island)
-			){
-				int index_tmp1, index_tmp2;
-				float normal[2];
-				/* easily possible*/
+	for(; element_iter; element_iter = element_iter->next){
+		if(element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)){
+			int index_tmp1, index_tmp2;
+			float normal[2];
+			/* easily possible*/
 
-				index_tmp1 = element_iter - state->element_map->buf;
-				index_tmp1 = state->map[index_tmp1];
-				index_tmp2 = element - state->element_map->buf;
-				index_tmp2 = state->map[index_tmp2];
+			index_tmp1 = element_iter - state->element_map->buf;
+			index_tmp1 = state->map[index_tmp1];
+			index_tmp2 = element - state->element_map->buf;
+			index_tmp2 = state->map[index_tmp2];
 
-				negate_v2_v2(normal, state->normals + index_tmp2*2);
-				edgecos = dot_v2v2(normal, state->normals + index_tmp1*2);
-				edgesin = cross_v2v2(normal, state->normals + index_tmp1*2);
-				break;
-			}
+			negate_v2_v2(normal, state->normals + index_tmp2*2);
+			edgecos = dot_v2v2(normal, state->normals + index_tmp1*2);
+			edgesin = cross_v2v2(normal, state->normals + index_tmp1*2);
+			rotation += (edgesin > 0)? acos(edgecos): -acos(edgecos);
 		}
 	}
 
+	if(state->midpoints)
+		rotation /= 2.0;
 	island_stitch_data[element->island].num_rot_elements++;
-	island_stitch_data[element->island].rotation += (edgesin > 0)? acos(edgecos): -acos(edgecos);
+	island_stitch_data[element->island].rotation += rotation;
 }
 
 
@@ -434,8 +476,6 @@
 static void determine_uv_stitchability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){
 	int vert_index;
 	UvElement *element_iter;
-	float limit= state->limit_dist;
-	int do_limit = state->use_limit;
 
 	vert_index = (*(&element->face->v1 + element->tfindex))->tmp.l;
 	element_iter = state->element_map->vert[vert_index];
@@ -445,18 +485,7 @@
 			if(element_iter == element){
 				continue;
 			}
-			if(do_limit){
-				MTFace *mtface_orig = CustomData_em_get(&state->em->fdata, element->face->data, CD_MTFACE);
-				MTFace *mtface_iter = CustomData_em_get(&state->em->fdata, element_iter->face->data, CD_MTFACE);
-
-				if(fabs(mtface_orig->uv[element->tfindex][0] - mtface_iter->uv[element_iter->tfindex][0]) < limit
-						&& fabs(mtface_orig->uv[element->tfindex][1] - mtface_iter->uv[element_iter->tfindex][1]) < limit){
-					island_stitch_data[element_iter->island].stitchableCandidate = 1;
-					island_stitch_data[element->island].stitchableCandidate = 1;
-					element->flag |= STITCH_STITCHABLE_CANDIDATE;
-				}
-			}else{
-				/* if no limit exists, then the mere existence of a separate uv means that the uv is stitchable */
+			if(stitch_check_uvs_stitchable(element, element_iter, state)){
 				island_stitch_data[element_iter->island].stitchableCandidate = 1;
 				island_stitch_data[element->island].stitchableCandidate = 1;
 				element->flag |= STITCH_STITCHABLE_CANDIDATE;
@@ -466,7 +495,6 @@
 }
 
 
-
 /* set preview buffer position of UV face in editface->tmp.l */
 static void stitch_set_face_preview_buffer_position(EditFace *efa, StitchPreviewer *preview)
 {
@@ -489,8 +517,8 @@
 	StitchPreviewer *preview = uv_get_stitch_previewer();
 
 	/* static island does not change so returning immediately */
-	//if(state->snap_islands && !state->midpoints && state->static_island == element->island)
-	//	return;
+	if(state->snap_islands && !state->midpoints && state->static_island == element->island)
+		return;
 
 	if(state->snap_islands){
 		island_stitch_data[element->island].addedForPreview = 1;
@@ -515,21 +543,7 @@
 		if(element_iter->separate){
 			if(element_iter == element)
 				continue;
-			if(state->use_limit){
-				MTFace *mtface_orig = CustomData_em_get(&state->em->fdata, element->face->data, CD_MTFACE);
-				MTFace *mtface_iter = CustomData_em_get(&state->em->fdata, element_iter->face->data, CD_MTFACE);
-
-				if(fabs(mtface_orig->uv[element->tfindex][0] - mtface_iter->uv[element_iter->tfindex][0]) < state->limit_dist
-						&& fabs(mtface_orig->uv[element->tfindex][1] - mtface_iter->uv[element_iter->tfindex][1]) < state->limit_dist){
-					if(((element_iter->island == state->static_island) || (element->island == state->static_island)) &&
-							!((element_iter->island == element->island) && state->snap_islands)){
-						element->flag |= STITCH_STITCHABLE;
-						preview->num_stitchable++;
-						stitch_setup_face_preview_for_uv_group(element, state, island_stitch_data);
-						return;
-					}
-				}
-			}else{
+			if(stitch_check_uvs_stitchable(element, element_iter, state)){
 				if(((element_iter->island == state->static_island) || (element->island == state->static_island)) &&
 						!((element_iter->island == element->island) && state->snap_islands)){
 					element->flag |= STITCH_STITCHABLE;
@@ -558,8 +572,6 @@
 	EditVert *ev;
 	UVVertAverage *final_position;
 	char stitch_midpoints = state->midpoints;
-	/* use vertex normals for snapping rotation */
-	char use_vert_normals = 1;
 	/* used to map uv indices to uvaverage indices for selection */
 	unsigned int *uvfinal_map;
 
@@ -578,7 +590,7 @@
 		return 0;
 	}
 

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-blender-cvs mailing list