[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43182] 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 22:39:55 CET 2012


Revision: 43182
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43182
Author:   psy-fi
Date:     2012-01-05 21:39:45 +0000 (Thu, 05 Jan 2012)
Log Message:
-----------
smart stitch
==============
-avoid inf calculation when computing rotation.
-fix crash when part of the mesh is hidden.

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 19:09:37 UTC (rev 43181)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_smart_stitch.c	2012-01-05 21:39:45 UTC (rev 43182)
@@ -120,6 +120,8 @@
 	UvEdge *uvedges;
 	/* container of first of a group of coincident uvs, these will be operated upon */
 	UvElement **uvs;
+	/* maps uvelements to their first coincident uv */
+	int *map;
 	/* 2D normals per uv to calculate rotation for snapping */
 	float *normals;
 	/* edge storage */
@@ -129,7 +131,7 @@
 	int total_boundary_edges;
 	int total_separate_uvs;
 	/* hold selection related information */
-	void **selection_stack;
+	UvElement **selection_stack;
 	int selection_size;
 	/* island that stays in place */
 	int static_island;
@@ -350,32 +352,50 @@
 
 	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].rotation += (edgesin > 0)? acos(MAX2(-1.0, MIN2(1.0, edgecos))): -acos(MAX2(-1.0, MIN2(1.0, edgecos)));
 }
-/*
+
 static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data)
 {
+	EditFace *efa;
+	MTFace *mt;
 	float normal1[2], normal2[2];
 	float edgecos, edgesin;
 	int index;
+	UvElement *element_iter;
 
+	if((element->island == state->static_island) && !state->midpoints)
+		return;
+
+	efa = element->face;
+	mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+
 	index = (*(&element->face->v1 + element->tfindex))->tmp.l;
 
-	normalize_v2(normal1);
-	normalize_v2(normal2);
+	element_iter = state->element_map->vert[index];
 
-	edgecos = uv1[0]*uv2[0] + uv1[1]*uv2[1];
-	edgesin = uv1[0]*uv2[1] - uv2[0]*uv1[1];
+	for(; element_iter; element_iter = element_iter->next){
+		if(element_iter->separate && (element_iter != element) &&
+			(element_iter->flag & STITCH_STITCHABLE)){
+			int index_tmp;
+			/* easily possible*/
+			if(element_iter->island == element->island){
+				continue;
+			}
+			index_tmp = element_iter - state->element_map->buf;
+			index_tmp = state->map[index_tmp];
+		}
+	}
+	edgecos = 0;
+	edgesin = 0;
 
-	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;
+	island_stitch_data[element->island].medianPoint[0] += mt->uv[element->tfindex][0];
+	island_stitch_data[element->island].medianPoint[1] += mt->uv[element->tfindex][1];;
 }
-*/
 
+
 static void stitch_state_delete(StitchState *stitch_state)
 {
 	if(stitch_state){
@@ -394,6 +414,9 @@
 		if(stitch_state->tris_per_island){
 			MEM_freeN(stitch_state->tris_per_island);
 		}
+		if(stitch_state->map){
+			MEM_freeN(stitch_state->map);
+		}
 		if(stitch_state->normals){
 			MEM_freeN(stitch_state->normals);
 		}
@@ -465,8 +488,8 @@
 	StitchPreviewer *preview = uv_get_stitch_previewer();
 
 	/* static island does not change so returning immediately */
-	if(!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;
@@ -479,15 +502,11 @@
 }
 
 
-/* registers uvs so that they can be shown in preview */
-static void stitch_setup_preview_for_stitchable_uv(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){
+/* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
+static void stitch_validate_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){
 	UvElement *element_iter;
 	StitchPreviewer *preview;
 
-	if(element->flag & STITCH_STITCHABLE){
-		return;
-	}
-
 	preview = uv_get_stitch_previewer();
 	element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l];
 
@@ -536,6 +555,8 @@
 	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;
 
@@ -564,7 +585,7 @@
 	 *****************************************/
 
 	for(i = 0; i < state->selection_size; i++){
-		UvElement *element = (UvElement *)state->selection_stack[i];
+		UvElement *element = state->selection_stack[i];
 		determine_uv_stitchability(element, state, island_stitch_data);
 	}
 
@@ -579,10 +600,10 @@
 	}
 
 	for(i = 0; i < state->selection_size; i++){
-		UvElement *element = (UvElement *)state->selection_stack[i];
+		UvElement *element = state->selection_stack[i];
 		if(element->flag & STITCH_STITCHABLE_CANDIDATE){
 			element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
-			stitch_setup_preview_for_stitchable_uv(element, state, island_stitch_data);
+			stitch_validate_stichability(element, state, island_stitch_data);
 		}else{
 			/* add to preview for unstitchable */
 			preview->num_unstitchable++;
@@ -634,21 +655,23 @@
 			MTFace *mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
 			UvElement *element = ED_get_uv_element(state->element_map, efa, 0);
 
-			if(efa->tmp.l != STITCH_NO_PREVIEW){
-				if(efa->v4) {
-					memcpy(preview->preview_quads+efa->tmp.l, &mt->uv[0][0], 8*sizeof(float));
-				} else {
-					memcpy(preview->preview_tris+efa->tmp.l, &mt->uv[0][0], 6*sizeof(float));
+			if(element){
+				if(efa->tmp.l != STITCH_NO_PREVIEW){
+					if(efa->v4) {
+						memcpy(preview->preview_quads+efa->tmp.l, &mt->uv[0][0], 8*sizeof(float));
+					} else {
+						memcpy(preview->preview_tris+efa->tmp.l, &mt->uv[0][0], 6*sizeof(float));
+					}
 				}
-			}
 
-			if(element->island == state->static_island){
-				if(efa->v4) {
-					memcpy(preview->static_quads + quadcount*8, &mt->uv[0][0], 8*sizeof(float));
-					quadcount++;
-				} else {
-					memcpy(preview->static_tris + tricount*6, &mt->uv[0][0], 6*sizeof(float));
-					tricount++;
+				if(element->island == state->static_island){
+					if(efa->v4) {
+						memcpy(preview->static_quads + quadcount*8, &mt->uv[0][0], 8*sizeof(float));
+						quadcount++;
+					} else {
+						memcpy(preview->static_tris + tricount*6, &mt->uv[0][0], 6*sizeof(float));
+						tricount++;
+					}
 				}
 			}
 		}
@@ -686,7 +709,7 @@
 
 	/* first pass, calculate final position for stitchable uvs */
 	for(i = 0; i < state->selection_size; i++){
-		UvElement *element = (UvElement *)state->selection_stack[i];
+		UvElement *element = 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;
@@ -715,7 +738,7 @@
 	/* second pass, calculate island rotation and translation before modifying any uvs */
 	if(state->snap_islands){
 		for(i = 0; i < state->selection_size; i++){
-			UvElement *element = (UvElement *)state->selection_stack[i];
+			UvElement *element = state->selection_stack[i];
 			if(element->flag & STITCH_STITCHABLE){
 				MTFace *mt;
 				efa = element->face;
@@ -730,19 +753,28 @@
 				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);
+
+		/* 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);
+				use_vert_normals = 0;
+			}
 		}
+		if(0){
+			for(i = 0; i < state->selection_size; i++){
+				UvElement *element = state->selection_stack[i];
+				if(element->flag & STITCH_STITCHABLE){
+					stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
+				}
+			}
+		}
 	}
 
 	/* third pass, propagate changes to stitchable uvs */
 	for(i = 0; i < state->selection_size; i++){
-		UvElement *element = (UvElement *)state->selection_stack[i];
+		UvElement *element = state->selection_stack[i];
 		if(element->flag & STITCH_STITCHABLE){
 			UvElement *element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l];
 			for(;element_iter;){
@@ -821,10 +853,11 @@
 
 
 /* Select all common uvs */
-static void stitch_select_uv(UvElement *element, StitchState *stitch_state, void **selection_stack, int *total_selected, int always_select)
+static void stitch_select_uv(UvElement *element, StitchState *stitch_state, int always_select)
 {
 	/* This works due to setting of tmp in find nearest uv vert */
 	UvElement *element_iter;
+	UvElement **selection_stack = stitch_state->selection_stack;
 
 	element_iter = stitch_state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l];
 	/* first deselect all common uvs */
@@ -837,16 +870,16 @@
 					continue;
 
 				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];
+				for(i = 0; i < stitch_state->selection_size; i++){
+					if(selection_stack[i] == element_iter){
+						(stitch_state->selection_size)--;
+						selection_stack[i] = selection_stack[stitch_state->selection_size];
 						break;
 					}
 				}
 			}else{
 				element_iter->flag |= STITCH_SELECTED;

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-blender-cvs mailing list