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

Antony Riakiotakis kalast at gmail.com
Wed Aug 17 23:10:25 CEST 2011


Revision: 39510
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39510
Author:   psy-fi
Date:     2011-08-17 21:10:25 +0000 (Wed, 17 Aug 2011)
Log Message:
-----------
uv paint brushes
=================
-Implemented 'all islands' option. By unticking it, only uvs of the island underneath the cursor during the first stroke are registered, so brush does not accidentally influence other islands. It may also save some performance, since not all uvs are checked for brush collisions anymore.

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

Modified: branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_image.c	2011-08-17 20:44:15 UTC (rev 39509)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_image.c	2011-08-17 21:10:25 UTC (rev 39510)
@@ -5105,9 +5105,9 @@
 {
 	if(!settings->uvpaint){
 		settings->uvpaint = MEM_callocN(sizeof(*settings->uvpaint), "UV Smooth paint");
-		settings->uv_paint_tool = UV_PAINT_TOOL_PINCH;
+		settings->uv_paint_tool = UV_PAINT_TOOL_GRAB;
 		settings->uv_paint_settings = UV_PAINT_PIN_EDGES | UV_PAINT_ALL_ISLANDS;
-		settings->uv_relax_method = UV_PAINT_TOOL_RELAX_HC;
+		settings->uv_relax_method = UV_PAINT_TOOL_RELAX_LAPLACIAN;
 	}
 	paint_mode_init(
 		wm,

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 20:44:15 UTC (rev 39509)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c	2011-08-17 21:10:25 UTC (rev 39510)
@@ -125,6 +125,7 @@
 	/* Need I say more? */
 	int totalUvEdges;
 
+	/* data for initial stroke, used by tools like grab */
 	UVInitialStroke *initial_stroke;
 
 	/* Timer to be used for airbrush-type brush */
@@ -399,17 +400,26 @@
 	op->customdata = NULL;
 }
 
-
-int get_uv_element_offset_from_face(UvElementMap *map, EditFace *efa, int index){
+static UvElement *get_uv_element(UvElementMap *map, EditFace *efa, int index){
 	UvElement *element = map->vert[(*(&efa->v1 + index))->tmp.l];
 	for(;element; element = element->next){
-		if(element->face == efa)
-			return element - map->buf;
+		if(element->face == efa){
+			return element;
+		}
 	}
-	return -1;
+	return NULL;
 }
 
 
+static int get_uv_element_offset_from_face(UvElementMap *map, EditFace *efa, int index, int island_index, int doIslands){
+	UvElement *element = get_uv_element(map, efa, index);
+	if(!element || (doIslands && element->island != island_index)){
+		return -1;
+	}
+	return element - map->buf;
+}
+
+
 static unsigned int	uv_edge_hash(const void *key){
 	UvAdjacencyEdge *edge = (UvAdjacencyEdge *)key;
 	return 
@@ -440,22 +450,67 @@
 
 	if(data){
 		int counter = 0, i;
+		ARegion *ar= CTX_wm_region(C);
+		float co[2];
 		EditFace *efa;
 		UvAdjacencyEdge *edges;
 		GHash *edgeHash;
 		GHashIterator* ghi;
 		MTFace *mt;
+		int do_island_optimization = !(ts->uv_paint_settings & UV_PAINT_ALL_ISLANDS);
+		int island_index = 0;
 
 		data->uvpaint = &ts->uvpaint->paint;
-		data->elementMap = EM_make_uv_element_map(em, 0, 0);
+
+		if(do_island_optimization){
+			data->elementMap = EM_make_uv_element_map(em, 0, 1);
+		}else {
+			/* We will need island information */
+			data->elementMap = EM_make_uv_element_map(em, 0, 0);
+		}
+
 		if(!data->elementMap){
 			uv_paint_stroke_exit(C, op);
 			return NULL;
 		}
 
+		/* Mouse coordinates, useful for some functions like grab and paint one islands */
+		UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
+
+		/* we need to find the active island here */
+		if(do_island_optimization){
+			float mindist = 1e10;
+			EditFace *nearest_face;
+			int nearest_index;
+			UvElement *element;
+
+			for(efa = em->faces.first; efa; efa = efa->next){
+				int nverts = efa->v4 ? 4 : 3;
+				if(efa->h)
+					continue;
+				mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+				for(i = 0; i < nverts; i++){
+					float diff[2], dist;
+					sub_v2_v2v2(diff, mt->uv[i], co);
+					dist = fabs(diff[0]) + fabs(diff[0]);
+					if(dist <= mindist)
+					{
+						mindist = dist;
+						nearest_face = efa;
+						nearest_index = i;
+					}
+				}
+			}
+
+			element = get_uv_element(data->elementMap, nearest_face, nearest_index);
+			island_index = element->island;
+		}
+
+
 		/* Count 'unique' uvs */
 		for(i = 0; i < data->elementMap->totalUVs; i++){
-			if(data->elementMap->buf[i].separate){
+			if(data->elementMap->buf[i].separate
+			&& (!do_island_optimization || data->elementMap->buf[i].island == island_index)){
 				counter++;
 			}
 		}
@@ -464,7 +519,7 @@
 		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*/
+		/* we have at most totalUVs edges */
 		edges = MEM_mallocN(sizeof(*edges)*data->elementMap->totalUVs, "uv_brush_all_edges");
 		if(!data->uv || !data->uniqueUv || !edgeHash || !edges){
 			uv_paint_stroke_exit(C, op);
@@ -472,13 +527,19 @@
 		}
 
 		data->totalUniqueUvs = counter;
-		/* So that we can use this as index for the UvElements*/
+		/* So that we can use this as index for the UvElements */
 		counter = -1;
 		/* initialize the unique UVs */
 		for(i = 0; i < em->totvert; i++){
 			UvElement *element = data->elementMap->vert[i];
 			for(; element; element = element->next){
 				if(element->separate){
+					if(do_island_optimization && (element->island != island_index)){
+						/* skip this uv if not on the active island */
+						for(; element->next && !(element->next->separate); element = element->next)
+							;
+						continue;
+					}
 					efa = element->face;
 					mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 
@@ -496,9 +557,16 @@
 		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)];
+				int offset1, itmp1 = get_uv_element_offset_from_face(data->elementMap, efa, i, island_index, do_island_optimization);
+				int offset2, itmp2 = get_uv_element_offset_from_face(data->elementMap, efa, (i+1)%nverts, island_index, do_island_optimization);
 
+				/* Skip edge if not found(unlikely) or not on valid island */
+				if(itmp1 == -1 || itmp2 == -1)
+					continue;
+
+				offset1 = data->uniqueUv[itmp1];
+				offset2 = data->uniqueUv[itmp2];
+
 				edges[counter].flag = 0;
 				if(offset1 < offset2){
 					edges[counter].uv1 = offset1;
@@ -547,7 +615,7 @@
 		BLI_ghash_free(edgeHash, NULL, NULL);
 		MEM_freeN(edges);
 
-		/* */
+		/* transfer boundary edge property to uvs */
 		if(ts->uv_paint_settings & UV_PAINT_PIN_EDGES){
 			for(i = 0; i < data->totalUvEdges; i++){
 				if(!data->uvedges[i].flag){
@@ -559,8 +627,7 @@
 
 		/* 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);
+			float radius, radius_root;
 			unsigned int tool;
 			UvBrushData *brushdata = (UvBrushData *)op->customdata;
 			SpaceImage *sima;
@@ -571,7 +638,6 @@
 			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);
@@ -616,6 +682,14 @@
 
 			data->initial_stroke->totalInitialSelected = counter;
 		}
+
+		if(!(ts->uv_paint_settings & UV_PAINT_ALL_ISLANDS)){
+/*			UvElement *element = map->vert[(*(&efa->v1 + index))->tmp.l];
+				for(;element; element = element->next){
+					if(element->face == efa)
+						return element - map->buf;
+				}*/
+		}
 	}
 
 	return op->customdata;




More information about the Bf-blender-cvs mailing list