[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39505] branches/soc-2011-onion/source/ blender: uv paint brushes

Antony Riakiotakis kalast at gmail.com
Wed Aug 17 21:00:07 CEST 2011


Revision: 39505
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39505
Author:   psy-fi
Date:     2011-08-17 19:00:07 +0000 (Wed, 17 Aug 2011)
Log Message:
-----------
uv paint brushes
=================
-Implementation of grab brush.
-Use corrected (root of) distance for brush influence

Modified Paths:
--------------
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c
    branches/soc-2011-onion/source/blender/makesdna/DNA_scene_types.h
    branches/soc-2011-onion/source/blender/makesrna/intern/rna_scene.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-17 18:42:02 UTC (rev 39504)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c	2011-08-17 19:00:07 UTC (rev 39505)
@@ -85,6 +85,27 @@
 }UvAdjacencyEdge;
 
 
+typedef struct UVInitialStrokeElement{
+	/* index to unique uv */
+	int uv;
+	/* strength of brush on initial position */
+	float strength;
+	/* initial uv position */
+	float initial_uv[2];
+}UVInitialStrokeElement;
+
+typedef struct UVInitialStroke{
+	/* Initial Selection,for grab brushes for instance */
+	UVInitialStrokeElement *initialSelection;
+
+	/* total initially selected UVs*/
+	int totalInitialSelected;
+
+	/* initial mouse coordinates */
+	float init_coord[2];
+}UVInitialStroke;
+
+
 /* custom data for uv smoothing brush */
 typedef struct UvBrushData{
 	/* Contains the first of each set of coincident uvs.
@@ -104,11 +125,14 @@
 	/* Need I say more? */
 	int totalUvEdges;
 
+	UVInitialStroke *initial_stroke;
+
 	/* Timer to be used for airbrush-type brush */
 	wmTimer *timer;
 
 	/* To determine quickly adjacent uvs */
 	UvElementMap *elementMap;
+
 	/* uvsmooth Paint for fast reference */
 	Paint *uvpaint;
 }UvBrushData;
@@ -129,6 +153,7 @@
 	Temp_UVData *tmp_uvdata;
 	float diff[2];
 	int i;
+	float radius_root = sqrt(radius);
 	Brush *brush = paint_brush(brushdata->uvpaint);
 
 	tmp_uvdata = (Temp_UVData *)MEM_callocN(brushdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
@@ -171,7 +196,7 @@
 		if((dist = dot_v2v2(diff, diff)) <= radius){
 			UvElement *element;
 			float strength;
-			strength = alpha*brush_curve_strength(brush, dist, radius);
+			strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root);
 
 			brushdata->uv[i].uv[0] = (1.0-strength)*brushdata->uv[i].uv[0] + strength*(tmp_uvdata[i].p[0] - 0.5f*(tmp_uvdata[i].b[0] + tmp_uvdata[i].sum_b[0]/tmp_uvdata[i].ncounter));
 			brushdata->uv[i].uv[1] = (1.0-strength)*brushdata->uv[i].uv[1] + strength*(tmp_uvdata[i].p[1] - 0.5f*(tmp_uvdata[i].b[1] + tmp_uvdata[i].sum_b[1]/tmp_uvdata[i].ncounter));
@@ -193,10 +218,10 @@
 
 static void smooth_laplacian_iteration_uv(EditMesh *em, UvBrushData *brushdata, float mouse_coord[2], float alpha, float radius, float aspectRatio)
 {
-
 	Temp_UVData *tmp_uvdata;
 	float diff[2];
 	int i;
+	float radius_root = sqrt(radius);
 	Brush *brush = paint_brush(brushdata->uvpaint);
 
 	tmp_uvdata = (Temp_UVData *)MEM_callocN(brushdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
@@ -231,7 +256,7 @@
 		if((dist = dot_v2v2(diff, diff)) <= radius){
 			UvElement *element;
 			float strength;
-			strength = alpha*brush_curve_strength(brush, dist, radius);
+			strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root);
 
 			brushdata->uv[i].uv[0] = (1.0-strength)*brushdata->uv[i].uv[0] + strength*tmp_uvdata[i].p[0];
 			brushdata->uv[i].uv[1] = (1.0-strength)*brushdata->uv[i].uv[1] + strength*tmp_uvdata[i].p[1];
@@ -254,10 +279,9 @@
 
 static void uv_paint_stroke_apply(bContext *C, wmOperator *op, wmEvent *event, Object *obedit)
 {
-	float co[2], radius;
+	float co[2], radius, radius_root;
 	ARegion *ar= CTX_wm_region(C);
 	EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
-	EditFace *efa;
 	unsigned int tool;
 	UvBrushData *brushdata = (UvBrushData *)op->customdata;
 	SpaceImage *sima;
@@ -269,7 +293,7 @@
 	tool = CTX_data_scene(C)->toolsettings->uv_paint_tool;
 
 	invert = RNA_boolean_get(op->ptr, "invert")? -1 : 1;
-	alpha = brush_alpha(brush);//*invert;
+	alpha = brush_alpha(brush);
 	UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
 
 	radius = brush_size(brush);
@@ -279,6 +303,7 @@
 	radius /= width;
 	/* We will compare squares to save some computation */
 	radius = radius*radius;
+	radius_root = sqrt(radius);
 
 	if(tool == UV_PAINT_TOOL_PINCH){
 		int i;
@@ -296,7 +321,7 @@
 			if((dist = dot_v2v2(diff, diff)) <= radius){
 				UvElement *element;
 				float strength;
-				strength = alpha*brush_curve_strength(brush, dist, radius);
+				strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root);
 				normalize_v2(diff);
 
 				brushdata->uv[i].uv[0] -= strength*diff[0]*0.001;
@@ -319,6 +344,26 @@
 		}else{
 			smooth_laplacian_iteration_uv(em, brushdata, co, alpha, radius, aspectRatio);
 		}
+	}else if(tool == UV_PAINT_TOOL_GRAB){
+		int i;
+		float diff[2];
+		sub_v2_v2v2(diff, co, brushdata->initial_stroke->init_coord);
+
+		for(i = 0; i < brushdata->initial_stroke->totalInitialSelected; i++ ){
+			UvElement *element;
+			int uvindex = brushdata->initial_stroke->initialSelection[i].uv;
+			float strength = brushdata->initial_stroke->initialSelection[i].strength;
+			brushdata->uv[uvindex].uv[0] = brushdata->initial_stroke->initialSelection[i].initial_uv[0] + strength*diff[0];
+			brushdata->uv[uvindex].uv[1] = brushdata->initial_stroke->initialSelection[i].initial_uv[1] +  strength*diff[1];
+
+			for(element = brushdata->uv[uvindex].element; element; element = element->next){
+				MTFace *mt;
+				if(element->separate && element != brushdata->uv[uvindex].element)
+					break;
+				mt = CustomData_em_get(&em->fdata, element->face->data, CD_MTFACE);
+				copy_v2_v2(mt->uv[element->tfindex], brushdata->uv[uvindex].uv);
+			}
+		}
 	}
 
 	BKE_mesh_end_editmesh(obedit->data, em);
@@ -344,6 +389,12 @@
 	if(data->uvedges){
 		MEM_freeN(data->uvedges);
 	}
+	if(data->initial_stroke){
+		if(data->initial_stroke->initialSelection){
+			MEM_freeN(data->initial_stroke->initialSelection);
+		}
+		MEM_freeN(data->initial_stroke);
+	}
 	MEM_freeN(data);
 	op->customdata = NULL;
 }
@@ -377,7 +428,7 @@
 }
 
 
-static UvBrushData *uv_paint_stroke_init(bContext *C, wmOperator *op)
+static UvBrushData *uv_paint_stroke_init(bContext *C, wmOperator *op, wmEvent *event)
 {
 	Scene *scene = CTX_data_scene(C);
 	Object *obedit = CTX_data_edit_object(C);
@@ -388,10 +439,7 @@
 	op->customdata = data;
 
 	if(data){
-		/* This holds a simple information: how many -unique- uvs we have in the uv layer.
-		 * Unique Uvs are important because they help us make one UVAdjacencyEdge for a group
-		 * of coincident UVs.*/
-		int numOfSeparators = 0, i;
+		int counter = 0, i;
 		EditFace *efa;
 		UvAdjacencyEdge *edges;
 		GHash *edgeHash;
@@ -408,12 +456,12 @@
 		/* Count 'unique' uvs */
 		for(i = 0; i < data->elementMap->totalUVs; i++){
 			if(data->elementMap->buf[i].separate){
-				numOfSeparators++;
+				counter++;
 			}
 		}
 
 		/* Allocate the unique uv buffers */
-		data->uv = MEM_mallocN(sizeof(*data->uv)*numOfSeparators, "uv_brush_unique_uvs");
+		data->uv = MEM_mallocN(sizeof(*data->uv)*counter, "uv_brush_unique_uvs");
 		data->uniqueUv = MEM_mallocN(sizeof(*data->uniqueUv)*data->elementMap->totalUVs, "uv_brush_unique_uv_map");
 		edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "uv_brush_edge_hash");
 		/* we have at most totalUVs edges*/
@@ -423,9 +471,9 @@
 			return NULL;
 		}
 
-		data->totalUniqueUvs = numOfSeparators;
+		data->totalUniqueUvs = counter;
 		/* So that we can use this as index for the UvElements*/
-		numOfSeparators = -1;
+		counter = -1;
 		/* initialize the unique UVs */
 		for(i = 0; i < em->totvert; i++){
 			UvElement *element = data->elementMap->vert[i];
@@ -434,42 +482,42 @@
 					efa = element->face;
 					mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 
-					numOfSeparators++;
-					data->uv[numOfSeparators].element = element;
-					data->uv[numOfSeparators].flag = 0;
-					data->uv[numOfSeparators].uv = mt->uv[element->tfindex];
+					counter++;
+					data->uv[counter].element = element;
+					data->uv[counter].flag = 0;
+					data->uv[counter].uv = mt->uv[element->tfindex];
 				}
 				/* pointer arithmetic to the rescue, as always :)*/
-				data->uniqueUv[element - data->elementMap->buf] = numOfSeparators;
+				data->uniqueUv[element - data->elementMap->buf] = counter;
 			}
 		}
 
 		/* Now, on to generate our uv connectivity data */
-		for(efa = em->faces.first, numOfSeparators = 0; efa; efa = efa->next){
+		for(efa = em->faces.first, counter = 0; efa; efa = efa->next){
 			int nverts = efa->v4 ? 4 : 3;
 			for(i = 0; i < nverts; i++){
 				int offset1 = data->uniqueUv[get_uv_element_offset_from_face(data->elementMap, efa, i)];
 				int offset2 = data->uniqueUv[get_uv_element_offset_from_face(data->elementMap, efa, (i+1)%nverts)];
 
-				edges[numOfSeparators].flag = 0;
+				edges[counter].flag = 0;
 				if(offset1 < offset2){
-					edges[numOfSeparators].uv1 = offset1;
-					edges[numOfSeparators].uv2 = offset2;
+					edges[counter].uv1 = offset1;
+					edges[counter].uv2 = offset2;
 				}
 				else{
-					edges[numOfSeparators].uv1 = offset2;
-					edges[numOfSeparators].uv2 = offset1;
+					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(edgeHash, &edges[numOfSeparators])){
-					char *flag = BLI_ghash_lookup(edgeHash, &edges[numOfSeparators]);
+				if(BLI_ghash_haskey(edgeHash, &edges[counter])){
+					char *flag = BLI_ghash_lookup(edgeHash, &edges[counter]);
 					*flag = 1;
 				}
 				else{
 					/* Hack mentioned */
-					BLI_ghash_insert(edgeHash, &edges[numOfSeparators], &edges[numOfSeparators].flag);
+					BLI_ghash_insert(edgeHash, &edges[counter], &edges[counter].flag);
 				}
-				numOfSeparators++;
+				counter++;
 			}
 		}
 
@@ -508,6 +556,66 @@
 				}
 			}
 		}
+
+		/* Allocate initial selection for grab tool */
+		if(ts->uv_paint_tool == UV_PAINT_TOOL_GRAB){
+			float co[2], radius, radius_root;
+			ARegion *ar= CTX_wm_region(C);
+			unsigned int tool;
+			UvBrushData *brushdata = (UvBrushData *)op->customdata;
+			SpaceImage *sima;
+			int width, height;
+			float aspectRatio;
+			float alpha;
+			Brush *brush = paint_brush(brushdata->uvpaint);
+			tool = CTX_data_scene(C)->toolsettings->uv_paint_tool;
+
+			alpha = brush_alpha(brush);
+			UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
+
+			radius = brush_size(brush);
+			sima = CTX_wm_space_image(C);
+			ED_space_image_size(sima, &width, &height);
+			aspectRatio = width/(float)height;
+			radius /= width;
+			radius = radius*radius;
+			radius_root = sqrt(radius);
+
+			/* Allocate selection stack */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list