[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39123] branches/soc-2011-onion/source/ blender: Revision: 30823

Jason Wilkins Jason.A.Wilkins at gmail.com
Sun Aug 7 11:13:37 CEST 2011


Revision: 39123
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39123
Author:   jwilkins
Date:     2011-08-07 09:13:37 +0000 (Sun, 07 Aug 2011)
Log Message:
-----------
Revision: 30823
Author: nicholasbishop
Date: 12:41:32 AM, Wednesday, July 28, 2010
Message:
== VPaint ==

* Implemented blur brush for non-multires models

----
Modified : /branches/soc-2010-nicolasbishop/source/blender/editors/sculpt_paint/paint_vertex.c

--
jwilkins: 

Nick had tried to use IMB_BLEND* values for brush.vertexpaint_tool, but I do not think it is completely compatible because IMB_BLEND* are integers not char and there is no IMB_BLEND* value for blur.  The more vertex tools are added that are not exactly the same as IMB_BLEND* modes the more hacky this will seem, so I just decoupled them made a lookup function for the vertexpaint_tools that happen to correspond to IMB_BLEND* modes.

Modified Paths:
--------------
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c
    branches/soc-2011-onion/source/blender/makesdna/DNA_brush_types.h
    branches/soc-2011-onion/source/blender/makesrna/intern/rna_brush.c

Modified: branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c	2011-08-07 08:58:03 UTC (rev 39122)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c	2011-08-07 09:13:37 UTC (rev 39123)
@@ -654,7 +654,7 @@
 		}
 	}
 	
-	if(tool==IMB_BLEND_MIX || tool==VERTEX_PAINT_BLUR)
+	if(tool==IMB_BLEND_MIX || tool==VERTEX_PAINT_TOOL_BLUR)
 		dw->weight = paintval*alpha + dw->weight*(1.0f-alpha);
 	else if(tool==IMB_BLEND_ADD)
 		dw->weight += paintval*alpha;
@@ -677,7 +677,7 @@
 		float testw=0.0f;
 		
 		alpha= brush_alpha(brush);
-		if(tool==IMB_BLEND_MIX || tool==VERTEX_PAINT_BLUR)
+		if(tool==IMB_BLEND_MIX || tool==VERTEX_PAINT_TOOL_BLUR)
 			testw = paintval*alpha + uw->weight*(1.0f-alpha);
 		else if(tool==IMB_BLEND_ADD)
 			testw = uw->weight + paintval*alpha;
@@ -1301,7 +1301,7 @@
 	/* make sure each vertex gets treated only once */
 	/* and calculate filter weight */
 	totw= 0;
-	if(brush->vertexpaint_tool==VERTEX_PAINT_BLUR) 
+	if(brush->vertexpaint_tool==VERTEX_PAINT_TOOL_BLUR) 
 		paintweight= 0.0f;
 	else
 		paintweight= ts->vgroup_weight;
@@ -1315,7 +1315,7 @@
 			(me->dvert+mface->v3)->flag= 1;
 			if(mface->v4) (me->dvert+mface->v4)->flag= 1;
 					
-			if(brush->vertexpaint_tool==VERTEX_PAINT_BLUR) {
+			if(brush->vertexpaint_tool==VERTEX_PAINT_TOOL_BLUR) {
 				MDeformWeight *dw, *(*dw_func)(MDeformVert *, const int);
 						
 				if(wp->flag & VP_ONLYVGROUP)
@@ -1337,7 +1337,7 @@
 		}
 	}
 			
-	if(brush->vertexpaint_tool==VERTEX_PAINT_BLUR) 
+	if(brush->vertexpaint_tool==VERTEX_PAINT_TOOL_BLUR) 
 		paintweight/= (float)totw;
 			
 	for(index=0; index<totindex; index++) {
@@ -1576,11 +1576,31 @@
 			0);
 }
 
+static int vpaint_to_imb_blend(int vpaint_tool)
+{
+	static int table[8] = {
+		IMB_BLEND_MIX,       /*VERTEX_PAINT_TOOL_MIX*/
+		IMB_BLEND_ADD,       /*VERTEX_PAINT_TOOL_ADD*/
+		IMB_BLEND_SUB,       /*VERTEX_PAINT_TOOL_SUB*/
+		IMB_BLEND_MUL,       /*VERTEX_PAINT_TOOL_MUL*/
+		0, /* invalid value, VERTEX_PAINT_TOOL_BLUR */
+		IMB_BLEND_LIGHTEN,   /*VERTEX_PAINT_TOOL_LIGHTEN*/
+		IMB_BLEND_DARKEN,    /*VERTEX_PAINT_TOOL_DARKEN*/
+		IMB_BLEND_ADD_ALPHA, /*VERTEX_PAINT_TOOL_ADD_ALPHA*/
+	};
+
+	assert(vpaint_tool != VERTEX_PAINT_TOOL_BLUR);
+	assert(vpaint_tool >= 0);
+	assert(vpaint_tool < VERTEX_PAINT_TOOL_BLUR);
+
+	return table[vpaint_tool];
+}
+
 static void vpaint_blend(Brush *brush, float dst[4], float src1[4], float src2[4], float fac)
 {
-	int tool = brush->vertexpaint_tool;
+	if (brush->vertexpaint_tool != VERTEX_PAINT_TOOL_BLUR) {
+		int tool= vpaint_to_imb_blend(brush->vertexpaint_tool);
 
-	if (tool != VERTEX_PAINT_BLUR) {
 		if (tool == IMB_BLEND_ADD_ALPHA && (brush->flag & BRUSH_DIR_IN))
 			tool = IMB_BLEND_ERASE_ALPHA;
 
@@ -1588,9 +1608,14 @@
 	}
 }
 
-static float tex_strength(struct VPaint* vp, struct Brush *brush, struct PaintStroke *stroke,
-			  float co[3], float mask, float len,
-			  float radius3d)
+static float tex_strength(
+	struct Brush *brush,
+	struct BrushSpace *bspace,
+	struct PaintStroke *stroke,
+	float co[3],
+	float mask,
+	float len,
+	float radius3d)
 {
 #if 0 // SNIP
 	struct Object *ob= CTX_data_active_object(C);
@@ -1621,20 +1646,24 @@
 			tex_mouse,
 			mats);
 #else
-	const BrushSpace *bspace= vp->paint.cache->bspace_symm_curr;
 	return paint_strength(brush, bspace, co, NULL, mask, len);
 #endif
 }
 
 /* apply paint at specified coordinate
    returns 1 if paint was applied, 0 otherwise */
-static int vpaint_paint_coord(struct VPaint *vp, struct PaintStroke *stroke,
-			      float co[3], float col[4],
-			      float center[3], float radius,
-			      float radius_squared, float mask)
+static int vpaint_paint_coord(
+	struct Brush *brush,
+	struct BrushSpace *bspace,
+	struct PaintStroke *stroke,
+	float co[3],
+	float col[4],
+	float center[3],
+	float radius,
+	float radius_squared,
+	float mask)
 {
 	VPaintData *vpd= paint_stroke_mode_data(stroke);
-	struct Brush *brush = paint_brush(&vp->paint);
 	float fac, dist, dist_squared;
 
 	dist_squared = len_squared_v3v3(center, co);
@@ -1643,7 +1672,7 @@
 		dist = sqrtf(dist_squared);
 
 		fac= vpd->fac *
-			tex_strength(vp, brush, stroke, co, mask, dist, radius);
+			tex_strength(brush, bspace, stroke, co, mask, dist, radius);
 
 		vpaint_blend(brush, col, col, vpd->color, fac);
 
@@ -1653,42 +1682,62 @@
 	return 0;
 }
 
-static void vpaint_nodes_grids(struct VPaint *vp, struct PaintStroke *stroke,
-			       DMGridData **grids, CustomData *vdata,
-			       GridKey *gridkey,
-			       int *grid_indices, int totgrid,
-			       int gridsize, int active, float center[3],
-			       float radius)
+static void vpaint_nodes_grids(
+	struct Brush *brush,
+	struct BrushSpace *bspace,
+	struct PaintStroke *stroke,
+	struct DMGridData **grids,
+	struct CustomData *vdata,
+	struct GridKey *gridkey,
+	int *grid_indices,
+	int totgrid,
+	int gridsize,
+	int active,
+	float center[3],
+	float radius)
 {
-	float radius_squared = radius*radius;
+	float radius_squared= radius*radius;
 	int i, x, y;
 
 	for(i = 0; i < totgrid; ++i) {
-		DMGridData *grid = grids[grid_indices[i]];
+		struct DMGridData *grid= grids[grid_indices[i]];
 
 		for(y = 0; y < gridsize; ++y) {
 			for(x = 0; x < gridsize; ++x) {
-				DMGridData *elem = GRIDELEM_AT(grid,
-							       y*gridsize+x,
-							       gridkey);
-				float *co = GRIDELEM_CO(elem, gridkey);
-				float *gridcol = GRIDELEM_COLOR(elem, gridkey)[active];
-				float mask = paint_mask_from_gridelem(elem,
-								      gridkey,
-								      vdata);
+				struct DMGridData *elem=
+					GRIDELEM_AT(
+						grid,
+						y*gridsize + x,
+						gridkey);
 
-				vpaint_paint_coord(vp, stroke, co,
-						   gridcol,
-					center, radius,
-						   radius_squared,
-						   mask);
-				}
+				float *co= GRIDELEM_CO(elem, gridkey);
+
+				float *gridcol= GRIDELEM_COLOR(elem, gridkey)[active];
+
+				float mask=
+					paint_mask_from_gridelem(
+						elem,
+						gridkey,
+						vdata);
+
+				vpaint_paint_coord(
+					brush,
+					bspace,
+					stroke,
+					co,
+					gridcol,
+					center,
+					radius,
+					radius_squared,
+					mask);
 			}
 		}
 	}
+}
 
 static void vpaint_nodes_faces(
-	struct VPaint *vp,
+	struct Brush *brush,
+	struct BrushSpace *bspace,
 	struct PaintStroke *stroke,
 	struct MFace *mface,
 	struct MVert *mvert,
@@ -1733,7 +1782,8 @@
 					pmask_first_layer);
 
 			vpaint_paint_coord(
-				vp,
+				brush,
+				bspace,
 				stroke,
 				co,
 				fcol,
@@ -1750,6 +1800,95 @@
 	}
 }
 
+static void vpaint_nodes_faces_smooth(
+	struct Brush *brush,
+	struct BrushSpace *bspace,
+	struct PaintStroke *stroke,
+	struct PBVH *pbvh,
+	struct PBVHNode *node,
+	struct MFace *mface,
+	struct CustomData *fdata,
+	struct ListBase *fmap,
+	float center[3],
+	float radius,
+	float radius_squared)
+{
+	struct PBVHVertexIter vd;
+	struct PaintStrokeTest test;
+	struct MCol *mcol;
+	
+	paint_stroke_test_init(&test, center, radius_squared);
+	mcol = CustomData_get_layer(fdata, CD_MCOL);
+
+	BLI_pbvh_vertex_iter_begin(pbvh, node, vd, PBVH_ITER_UNIQUE) {
+		if(paint_stroke_test(&test, vd.co)) {
+			struct IndexNode *n;
+			float strength, avg_col[4] = {0, 0, 0, 0};
+			int vndx = vd.vert_indices[vd.i], totcol, i, j;
+
+			/* first find average color from neighboring faces */
+			totcol = 0;
+			for(n = fmap[vndx].first; n; n = n->next) {
+				int fndx = n->index;
+				MFace *f = &mface[fndx];
+				int S = f->v4 ? 4 : 3;
+
+				for(i = 0; i < S; ++i) {
+					int cndx = fndx*4 + i;
+
+					avg_col[0] += mcol[cndx].b / 255.0;
+					avg_col[1] += mcol[cndx].g / 255.0;
+					avg_col[2] += mcol[cndx].r / 255.0;
+					avg_col[3] += mcol[cndx].a / 255.0;
+					
+					++totcol;
+				}
+			}
+
+			for(i = 0; i < 4; ++i)
+				avg_col[i] /= totcol;
+
+			/* for all face corners matching vndx,
+			   interp towards the averaged color */
+			for(n = fmap[vndx].first; n; n = n->next) {
+				int fndx = n->index;
+				MFace *f = &mface[fndx];
+				int S = f->v4 ? 4 : 3;
+
+				for(i = 0; i < S; ++i) {
+					int cndx = fndx*4 + i;
+
+					if((&f->v1)[i] != vndx)
+						continue;
+
+					strength =
+						brush->alpha *
+						tex_strength(
+							brush,
+							bspace,
+							stroke,
+							vd.co,
+							vd.mask_combined,
+							test.dist,
+							radius);
+
+					for(j = 0; j < 4; ++j) {
+						unsigned char *c;
+						float col;
+
+						c = ((unsigned char*)(&mcol[cndx])) + j;
+
+						col = *c / 255.0f;
+						col = interpf(avg_col[3 - j], col, strength);
+						*c = col * 255.0f;
+					}
+				}
+			}
+		}
+	}
+	BLI_pbvh_vertex_iter_end;
+}
+
 static int vpaint_find_gridkey_active_layer(CustomData *fdata, GridKey *gridkey)
 {
 	int active, i;
@@ -1768,14 +1907,25 @@
 	return -1;
 }
 
-static void vpaint_nodes(struct VPaint *vp, struct PaintStroke *stroke,
-			 PBVH *pbvh,
-			 PBVHNode **nodes, int totnode,
-			 float center[3], float radius)
+static void vpaint_nodes(
+	struct VPaint *vp,
+	struct BrushSpace *bspace,
+	struct PaintStroke *stroke,
+	struct Scene *scene,
+	struct Object *ob,
+	struct PBVHNode **nodes,
+	int totnode,
+	float center[3],
+	float radius)
 {
+	PBVH *pbvh = ob->paint->pbvh;
+	Brush *brush = paint_brush(&vp->paint);
 	int n;
 
 	for(n = 0; n < totnode; ++n) {
+		DerivedMesh *dm;
+		ListBase *fmap;
+
 		MVert *mvert;
 		MFace *mface;
 		CustomData *vdata = NULL;
@@ -1788,32 +1938,79 @@
 
 		BLI_pbvh_node_get_verts(pbvh, nodes[n], NULL, &mvert, &vdata);
 
-		BLI_pbvh_node_get_faces(pbvh, nodes[n], &mface, &fdata,
-					&face_indices, NULL, &totface);
+		BLI_pbvh_node_get_faces(
+			pbvh,
+			nodes[n],
+			&mface,
+			&fdata,
+			&face_indices,
+			NULL,
+			&totface);
 
-		BLI_pbvh_node_get_grids(pbvh, nodes[n], &grid_indices,
-					&totgrid, NULL, &gridsize, &grids,
-					NULL, &gridkey);
+		BLI_pbvh_node_get_grids(
+			pbvh,
+			nodes[n],
+			&grid_indices,
+			&totgrid,
+			NULL,
+			&gridsize,
+			&grids,
+			NULL,
+			&gridkey);
 
-		if(grids) {
-			int active = vpaint_find_gridkey_active_layer(fdata,
-								      gridkey);
+		if (grids) {
+			int active= vpaint_find_gridkey_active_layer(fdata, gridkey);
 
 			if(active != -1) {
-				vpaint_nodes_grids(vp, stroke, grids, vdata,
-						   gridkey,
-						   grid_indices, totgrid,
-						   gridsize, active, center,
-						   radius);
+				vpaint_nodes_grids(
+					brush,
+					bspace,
+					stroke,
+					grids,
+					vdata,
+					gridkey,
+					grid_indices,
+					totgrid,
+					gridsize,
+					active,
+					center,
+					radius);
 			}
 		}

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list