[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40859] branches/soc-2011-onion-uv-tools/ source/blender/editors: Smart Stitch

Antony Riakiotakis kalast at gmail.com
Sat Oct 8 22:38:42 CEST 2011


Revision: 40859
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40859
Author:   psy-fi
Date:     2011-10-08 20:38:41 +0000 (Sat, 08 Oct 2011)
Log Message:
-----------
Smart Stitch
============
*create edge data structures on initialization
*remove old stitch vertex selection code path

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

Modified: branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
===================================================================
--- branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c	2011-10-08 17:28:37 UTC (rev 40858)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c	2011-10-08 20:38:41 UTC (rev 40859)
@@ -609,8 +609,8 @@
 			return NULL;
 		}
 		/* fill the edges with data */
-		for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi), i++){
-			data->uvedges[i] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
+		for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){
+			data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
 		}
 		data->totalUvEdges = BLI_ghash_size(edgeHash);
 

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-08 17:28:37 UTC (rev 40858)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c	2011-10-08 20:38:41 UTC (rev 40859)
@@ -1297,13 +1297,11 @@
 	EditMesh *em;
 	/* element map for getting info about uv connectivity */
 	UvElementMap *elementMap;
-
-#ifdef STITCHNEW
 	/* Edge container */
 	UvEdge *uvedges;
 	/* container of first of a group of coincident uvs, these will be operated upon */
 	UvElement **uvs;
-	int numOfSeparateUvs;
+	int total_separate_uvs;
 	/* maps uvelements to their first coincident uv */
 	int *map;
 	/* hold selection related information */
@@ -1311,7 +1309,11 @@
 	int selection_size;
 	/* island that stays in place */
 	int static_island;
-#endif
+	/* For fast edge lookup... */
+	GHash *edgeHash;
+	/* ...And actual edge storage */
+	UvEdge *edges;
+	int total_edges;
 } StitchState;
 
 
@@ -1329,6 +1331,7 @@
 #define STITCH_SELECTED 1
 #define STITCH_STITCHABLE 2
 #define STITCH_PROCESSED 4
+#define STITCH_BOUNDARY 8
 #endif
 /* Previewer stuff (see uvedit_intern.h for more info) */
 static StitchPreviewer *_stitch_preview;
@@ -1389,6 +1392,7 @@
 	return _stitch_preview;
 }
 
+
 /* This function updates the header of the UV editor when the stitch tool updates its settings */
 static void stitch_update_header(StitchState *stitch_state, bContext *C)
 {
@@ -2176,7 +2180,12 @@
 		if(stitch_state->map){
 			MEM_freeN(stitch_state->map);
 		}
-
+		if(stitch_state->edgeHash){
+			BLI_ghash_free(stitch_state->edgeHash, NULL, NULL);
+		}
+		if(stitch_state->edges){
+			MEM_freeN(stitch_state->edges);
+		}
 		MEM_freeN(stitch_state);
 	}
 }
@@ -2359,7 +2368,7 @@
 		}
 		if(state->mode == VERT_STITCH){
 			/* Fill the preview buffers with stitchable only uvs */
-			for(i = 0; i < state->numOfSeparateUvs; i++){
+			for(i = 0; i < state->total_separate_uvs; i++){
 				UvElement *element = (UvElement *)state->uvs[i];
 				if(element->flag & STITCH_STITCHABLE){
 					MTFace *mt;
@@ -2493,11 +2502,30 @@
 	return 1;
 }
 
+/* Stitch initialization functions */
+static unsigned int	uv_edge_hash(const void *key){
+	UvEdge *edge = (UvEdge *)key;
+	return
+		BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
+		BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
+}
 
+static int uv_edge_compare(const void *a, const void *b){
+	UvEdge *edge1 = (UvEdge *)a;
+	UvEdge *edge2 = (UvEdge *)b;
+
+	if((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)){
+		return 0;
+	}
+	return 1;
+}
+
 static int stitch_init(bContext *C, wmOperator *op)
 {
 	int counter = 0, i;
 	EditFace *efa;
+	GHashIterator* ghi;
+	UvEdge *edges;
 	StitchState *stitch_state = MEM_mallocN(sizeof(StitchState), "stitch_state");
 	StitchPreviewer *preview = stitch_preview_init();
 	Scene *scene = CTX_data_scene(C);
@@ -2536,13 +2564,18 @@
 		}
 	}
 
+	/* Allocate the unique uv buffers */
 	stitch_state->uvs = MEM_mallocN(sizeof(*stitch_state->uvs)*counter, "uv_stitch_unique_uvs");
-	stitch_state->numOfSeparateUvs = counter;
+	stitch_state->total_separate_uvs = counter;
 	/* we can at most have totalUVs edges or uvs selected. Actually they are less, considering we store only
 	 * unique uvs for processing but I am accounting for all bizarre cases, especially for edges, this way */
 	stitch_state->selection_stack = MEM_mallocN(sizeof(*stitch_state->selection_stack)*stitch_state->elementMap->totalUVs, "uv_stitch_selection_stack");
 	stitch_state->map = MEM_mallocN(sizeof(*stitch_state->map)*stitch_state->elementMap->totalUVs, "uv_stitch_unique_map");
-	if(!stitch_state->selection_stack || !stitch_state->uvs || !stitch_state->map){
+	/* Allcate the edge stack */
+	stitch_state->edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
+	edges = MEM_mallocN(sizeof(*edges)*stitch_state->elementMap->totalUVs, "stitch_all_edges");
+
+	if(!stitch_state->selection_stack || !stitch_state->uvs || !stitch_state->map || !stitch_state->edgeHash || !edges){
 		stitch_state_delete(stitch_state);
 		return 0;
 	}
@@ -2566,6 +2599,72 @@
 		}
 	}
 
+	/* Now, on to generate our uv connectivity data */
+	for(efa = stitch_state->em->faces.first, counter = 0; efa; efa = efa->next){
+		int nverts = efa->v4 ? 4 : 3;
+		for(i = 0; i < nverts; i++){
+			int offset1, itmp1 = get_uv_element(stitch_state->elementMap, efa, i) - stitch_state->elementMap->buf;
+			int offset2, itmp2 = get_uv_element(stitch_state->elementMap, efa, (i+1)%nverts) - stitch_state->elementMap->buf;
+
+			offset1 = stitch_state->map[itmp1];
+			offset2 = stitch_state->map[itmp2];
+
+			edges[counter].flag = 0;
+			/* using an order policy, sort uvs according to address space. This avoids
+			 * Having two different UvEdges with the same uvs on different positions  */
+			if(offset1 < offset2){
+				edges[counter].uv1 = offset1;
+				edges[counter].uv2 = offset2;
+			}
+			else{
+				edges[counter].uv1 = offset2;
+				edges[counter].uv2 = offset1;
+			}
+			/* Hack! Set the value of the key to its flag. Now we can set the flag when an edge exists twice :) */
+			if(BLI_ghash_haskey(stitch_state->edgeHash, &edges[counter])){
+				char *flag = BLI_ghash_lookup(stitch_state->edgeHash, &edges[counter]);
+				*flag = 0;
+			}
+			else{
+				/* Hack mentioned */
+				BLI_ghash_insert(stitch_state->edgeHash, &edges[counter], &edges[counter].flag);
+				edges[counter].flag = STITCH_BOUNDARY;
+			}
+			counter++;
+		}
+	}
+
+	ghi = BLI_ghashIterator_new(stitch_state->edgeHash);
+	stitch_state->edges = MEM_mallocN(sizeof(*stitch_state->edges)*BLI_ghash_size(stitch_state->edgeHash), "stitch_edges");
+	if(!ghi || !stitch_state->edges){
+		MEM_freeN(edges);
+		stitch_state_delete(stitch_state);
+		return 0;
+	}
+	/* fill the edges with data */
+	for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){
+		stitch_state->edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
+	}
+	stitch_state->total_edges = BLI_ghash_size(stitch_state->edgeHash);
+
+	/* cleanup temporary stuff */
+	BLI_ghashIterator_free(ghi);
+	MEM_freeN(edges);
+
+	/* refill hash with new pointers */
+	BLI_ghash_free(stitch_state->edgeHash, NULL, NULL);
+	stitch_state->edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
+	for(i = 0; i < stitch_state->total_edges; i++){
+		BLI_ghash_insert(stitch_state->edgeHash, &stitch_state->edges + i, NULL);
+	}
+
+	for(i = 0; i < stitch_state->total_edges; i++){
+		if(stitch_state->edges[i].flag & STITCH_BOUNDARY){
+			stitch_state->uvs[stitch_state->edges[i].uv1]->flag |= STITCH_BOUNDARY;
+			stitch_state->uvs[stitch_state->edges[i].uv2]->flag |= STITCH_BOUNDARY;
+		}
+	}
+
 	stitch_state->selection_size = 0;
 
 	/* Fill selection stack */
@@ -2581,26 +2680,26 @@
 		}
 		RNA_END;
 	} else {
-	for(efa = stitch_state->em->faces.first ; efa; efa = efa->next){
-		int numOfVerts;
-		MTFace *mt;
-		mt = CustomData_em_get(&stitch_state->em->fdata, efa->data, CD_MTFACE);
-		numOfVerts = efa->v4 ? 4 : 3;
+		for(efa = stitch_state->em->faces.first ; efa; efa = efa->next){
+			int numOfVerts;
+			MTFace *mt;
+			mt = CustomData_em_get(&stitch_state->em->fdata, efa->data, CD_MTFACE);
+			numOfVerts = efa->v4 ? 4 : 3;
 
-		for(i = 0; i < numOfVerts; i++){
-			if(uvedit_uv_selected(scene, efa, mt, i)){
-				int uniqueIndex;
-				UvElement *element = get_uv_element(stitch_state->elementMap, efa, i);
-				uniqueIndex = stitch_state->map[element - stitch_state->elementMap->buf];
-				/* count a uv only once, or duplicates will happen */
-				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;
+			for(i = 0; i < numOfVerts; i++){
+				if(uvedit_uv_selected(scene, efa, mt, i)){
+					int uniqueIndex;
+					UvElement *element = get_uv_element(stitch_state->elementMap, efa, i);
+					uniqueIndex = stitch_state->map[element - stitch_state->elementMap->buf];
+					/* count a uv only once, or duplicates will happen */
+					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;
+					}
 				}
 			}
 		}
 	}
-	}
 
 	if(!stitch_process_data(stitch_state, scene, 0, 1)){
 		stitch_state_delete(stitch_state);
@@ -2812,7 +2911,6 @@
 					 * becomes dependent on the order of stitching different uv's corresponding to the same vertex */
 					if(stitch_state->mode == VERT_STITCH)
 					{
-						#ifdef STITCHNEW
 						int uniqueIndex;
 						/* This works due to setting of tmp in find nearest uv vert */
 						UvElement *element_iter, *unique_element, *element = get_uv_element(stitch_state->elementMap, hit.efa, hit.uv);
@@ -2841,39 +2939,6 @@
 							unique_element->flag |= STITCH_SELECTED;
 							stitch_state->selection_stack[stitch_state->selection_size++] = unique_element;
 						}
-						#else
-						UvElement *element = stitch_state->elementMap->vert[(*(&hit.efa->v1 + hit.uv))->tmp.l];
-						UvElement *firstCoincident;
-						for(; element; element = element->next)
-						{
-							MTFace *tface;
-							tface =  CustomData_em_get(&stitch_state->em->fdata, element->face->data, CD_MTFACE);
-							if(element->separate)
-								firstCoincident = element;
-							if(element->face == hit.efa){

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list