[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39315] branches/soc-2011-onion/source/ blender/editors/sculpt_paint/paint_uv.c: Smooth Brushes

Antony Riakiotakis kalast at gmail.com
Fri Aug 12 02:06:04 CEST 2011


Revision: 39315
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39315
Author:   psy-fi
Date:     2011-08-12 00:06:03 +0000 (Fri, 12 Aug 2011)
Log Message:
-----------
Smooth Brushes
=====================
-implemented connectivity data (Not as expensive as I thought though I do have a relatively fast PC)

Now keep on to use it into the brush!

Modified Paths:
--------------
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c

Modified: branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c	2011-08-11 22:14:07 UTC (rev 39314)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c	2011-08-12 00:06:03 UTC (rev 39315)
@@ -78,9 +78,9 @@
 } UvAdjacencyElement;
 
 typedef struct UvAdjacencyEdge {
-	UvAdjacencyElement *uv1;
-	UvAdjacencyElement *uv2;
-	/* flag whether edge is boundary */
+	unsigned int uv1;
+	unsigned int uv2;
+	/* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */
 	char flag;
 }UvAdjacencyEdge;
 
@@ -329,7 +329,7 @@
 	int *uniqueUv;
 
 	/* Edges used for adjacency info, used with laplacian smoothing */
-	GHash *uvedges;
+	UvAdjacencyEdge *uvedges;
 
 	/* Timer to be used for airbrush-type brush */
 	wmTimer *timer;
@@ -404,6 +404,9 @@
 	if(data->uniqueUv){
 		MEM_freeN(data->uniqueUv);
 	}
+	if(data->uvedges){
+		MEM_freeN(data->uvedges);
+	}
 	MEM_freeN(data);
 	op->customdata = NULL;
 }
@@ -418,6 +421,23 @@
 	return -1;
 }
 
+
+static unsigned int	uv_edge_hash(const void *key){
+	UvAdjacencyEdge *edge = (UvAdjacencyEdge *)key;
+	return BLI_ghashutil_inthash(edge->uv2) + BLI_ghashutil_inthash(edge->uv1);
+}
+
+static int uv_edge_compare(const void *a, const void *b){
+	UvAdjacencyEdge *edge1 = (UvAdjacencyEdge *)a;
+	UvAdjacencyEdge *edge2 = (UvAdjacencyEdge *)b;
+
+	if((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)){
+		return 0;
+	}
+	return -1;
+}
+
+
 static SmoothBrushData *uv_smooth_stroke_init(bContext *C, wmOperator *op)
 {
 	Scene *scene = CTX_data_scene(C);
@@ -434,6 +454,9 @@
 		 * of coincident UVs.*/
 		int numOfSeparators = 0, i;
 		EditFace *efa;
+		UvAdjacencyEdge *edges;
+		GHash *edgeHash;
+		GHashIterator* ghi;
 
 		data->uvpaint = &ts->uvsmooth->paint;
 		data->elementMap = EM_make_uv_element_map(em, 0, 0);
@@ -452,7 +475,9 @@
 		/* Allocate the unique uv buffers */
 		data->uv = MEM_mallocN(sizeof(*data->uv)*numOfSeparators, "uv_brush_unique_uvs");
 		data->uniqueUv = MEM_mallocN(sizeof(*data->uniqueUv)*data->elementMap->totalUVs, "uv_brush_unique_uv_map");
-		if(!data->uv || !data->uniqueUv){
+		edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "uv_brush_edge_hash");
+		edges = MEM_mallocN(sizeof(*edges)*data->elementMap->totalUVs, "uv_brush_all_edges");
+		if(!data->uv || !data->uniqueUv || !edgeHash || !edges){
 			uv_smooth_stroke_exit(C, op);
 			return NULL;
 		}
@@ -475,13 +500,52 @@
 		}
 
 		/* Now, to generate our uv connectivity data...Man, this is gonna be -slow-! */
-		for(efa = em->faces.first; efa; efa = efa->next){
+		for(efa = em->faces.first, numOfSeparators = 0; efa; efa = efa->next){
 			int nverts = efa->v4 ? 4 : 3;
 			for(i = 0; i < nverts; i++){
 				int offset1 = get_uv_element_offset_from_face(data->elementMap, efa, i);
 				int offset2 = get_uv_element_offset_from_face(data->elementMap, efa, (i+1)%nverts);
+				if(offset1 < offset2){
+					edges[numOfSeparators].uv1 = data->uniqueUv[offset1];
+					edges[numOfSeparators].uv2 = data->uniqueUv[offset2];
+					edges[numOfSeparators].flag = 0;
+				}
+				else{
+					edges[numOfSeparators].uv1 = data->uniqueUv[offset2];
+					edges[numOfSeparators].uv2 = data->uniqueUv[offset1];
+					edges[numOfSeparators].flag = 0;
+				}
+				/* 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(edgeHash, &edges[numOfSeparators])){
+					char *flag = BLI_ghash_lookup(edgeHash, &edges[numOfSeparators]);
+					*flag = 1;
+				}
+				else{
+					/* Hack mentioned */
+					BLI_ghash_insert(edgeHash, &edges[numOfSeparators], &edges[numOfSeparators].flag);
+				}
+				numOfSeparators++;
 			}
 		}
+
+//		printf("total Uvs %d, total edgeKeys %d\n", data->elementMap->totalUVs, BLI_ghash_size(edgeHash));
+		/* Allocate connectivity data, we allocate edges once */
+		data->uvedges = MEM_mallocN(sizeof(*data->uvedges)*BLI_ghash_size(edgeHash), "uv_brush_edge_connectivity_data");
+
+		ghi = BLI_ghashIterator_new(edgeHash);
+		if(!ghi){
+			BLI_ghash_free(edgeHash, NULL, NULL);
+			MEM_freeN(edges);
+			uv_smooth_stroke_exit(C, op);
+			return NULL;
+		}
+		/* fill the edges with data */
+		for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi), i++){
+			data->uvedges[i] = *((UvAdjacencyEdge *)BLI_ghashIterator_getKey(ghi));
+		}
+		BLI_ghashIterator_free(ghi);
+		BLI_ghash_free(edgeHash, NULL, NULL);
+		MEM_freeN(edges);
 	}
 
 	return op->customdata;




More information about the Bf-blender-cvs mailing list