[Bf-blender-cvs] [28b9e3f9222] soc-2016-pbvh-painting: Merge branch 'master' into soc-2016-pbvh-painting

Campbell Barton noreply at git.blender.org
Wed Sep 27 03:09:55 CEST 2017


Commit: 28b9e3f92220c38af81583b145dc42e39f14e34e
Author: Campbell Barton
Date:   Wed Sep 27 11:19:21 2017 +1000
Branches: soc-2016-pbvh-painting
https://developer.blender.org/rB28b9e3f92220c38af81583b145dc42e39f14e34e

Merge branch 'master' into soc-2016-pbvh-painting

===================================================================



===================================================================

diff --cc source/blender/editors/sculpt_paint/paint_vertex.c
index 53e4f639540,729dd9dc57b..2d45bc5504d
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@@ -575,22 -605,13 +575,22 @@@ BLI_INLINE uint mcol_blend(uint col1, u
  
  	mfac = 255 - fac;
  
 -	cp1 = (unsigned char *)&col1;
 -	cp2 = (unsigned char *)&col2;
 -	cp  = (unsigned char *)&col;
 +	cp1 = (uchar *)&col1;
 +	cp2 = (uchar *)&col2;
 +	cp  = (uchar *)&col;
  
 -	cp[0] = divide_round_i((mfac * cp1[0] + fac * cp2[0]), 255);
 -	cp[1] = divide_round_i((mfac * cp1[1] + fac * cp2[1]), 255);
 -	cp[2] = divide_round_i((mfac * cp1[2] + fac * cp2[2]), 255);
 +	/* Updated to use the rgb squared color model which blends nicer. */
 +	int r1 = cp1[0] * cp1[0];
 +	int g1 = cp1[1] * cp1[1];
 +	int b1 = cp1[2] * cp1[2];
 +
 +	int r2 = cp2[0] * cp2[0];
 +	int g2 = cp2[1] * cp2[1];
 +	int b2 = cp2[2] * cp2[2];
 +
- 	cp[0] = iroundf(sqrtf(divide_round_i((mfac * r1 + fac * r2), 255)));
- 	cp[1] = iroundf(sqrtf(divide_round_i((mfac * g1 + fac * g2), 255)));
- 	cp[2] = iroundf(sqrtf(divide_round_i((mfac * b1 + fac * b2), 255)));
++	cp[0] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * r1 + fac * r2), 255)));
++	cp[1] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * g1 + fac * g2), 255)));
++	cp[2] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * b1 + fac * b2), 255)));
  	cp[3] = 255;
  
  	return col;
@@@ -3237,492 -2721,73 +3237,492 @@@ static bool vpaint_stroke_test_start(bC
  	return 1;
  }
  
 -static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
 -                              const unsigned int index, const float mval[2],
 -                              const float brush_size_pressure, const float brush_alpha_pressure)
 +static void do_vpaint_brush_calc_ave_color_cb_ex(
 +	void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id)) {
 +	SculptThreadedTaskData *data = userdata;
 +	SculptSession *ss = data->ob->sculpt;
 +	CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 +
 +	StrokeCache *cache = ss->cache;
 +	uint *lcol = data->lcol;
 +	uint blend[3] = {0};
 +	char *col;
 +	data->ob->sculpt->modes.vwpaint.tot_loops_hit[n] = 0;
 +	const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 +
 +	SculptBrushTest test;
 +	sculpt_brush_test_init(ss, &test);
 +
 +	/* For each vertex */
 +	PBVHVertexIter vd;
 +	BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 +	{
 +		/* Test to see if the vertex coordinates are within the spherical brush region. */
 +		if (sculpt_brush_test_fast(&test, vd.co)) {
 +			const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
 +			if (BKE_brush_curve_strength(data->brush, test.dist, cache->radius) > 0.0) {
 +				/* If the vertex is selected for painting. */
 +				const MVert *mv = &data->me->mvert[v_index];
 +				if (!use_face_sel || mv->flag & SELECT) {
 +					ss->modes.vwpaint.tot_loops_hit[n] += ss->modes.vwpaint.vert_to_loop[v_index].count;
 +					/* if a vertex is within the brush region, then add it's color to the blend. */
 +					for (int j = 0; j < ss->modes.vwpaint.vert_to_loop[v_index].count; j++) {
 +						const int l_index = ss->modes.vwpaint.vert_to_loop[v_index].indices[j];
 +						col = (char *)(&lcol[l_index]);
 +						/* Color is squared to compensate the sqrt color encoding. */
 +						blend[0] += col[0] * col[0];
 +						blend[1] += col[1] * col[1];
 +						blend[2] += col[2] * col[2];
 +					}
 +				}
 +			}
 +		}
 +	}
 +	BKE_pbvh_vertex_iter_end;
 +
 +	data->ob->sculpt->modes.vwpaint.total_color[n][0] = blend[0];
 +	data->ob->sculpt->modes.vwpaint.total_color[n][1] = blend[1];
 +	data->ob->sculpt->modes.vwpaint.total_color[n][2] = blend[2];
 +}
 +
 +static void handle_texture_brush(
 +        SculptThreadedTaskData *data, PBVHVertexIter vd, float size_pressure, float alpha_pressure,
 +        float *r_alpha, uint *r_color)
  {
 -	ViewContext *vc = &vpd->vc;
 -	Brush *brush = BKE_paint_brush(&vp->paint);
 -	MPoly *mpoly = &me->mpoly[index];
 -	MLoop *ml;
 -	unsigned int *lcol = ((unsigned int *)me->mloopcol) + mpoly->loopstart;
 -	unsigned int *lcolorig = ((unsigned int *)vp->vpaint_prev) + mpoly->loopstart;
 -	bool *mlooptag = (vpd->mlooptag) ? vpd->mlooptag + mpoly->loopstart : NULL;
 -	float alpha;
 -	int i, j;
 -	int totloop = mpoly->totloop;
 +	SculptSession *ss = data->ob->sculpt;
 +	CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 +	const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
  
 -	int brush_alpha_pressure_i = (int)(brush_alpha_pressure * 255.0f);
 +	float rgba[4];
 +	float rgba_br[3];
  
 -	if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
 -		unsigned int blend[4] = {0};
 -		unsigned int tcol;
 -		char *col;
 -
 -		for (j = 0; j < totloop; j++) {
 -			col = (char *)(lcol + j);
 -			blend[0] += col[0];
 -			blend[1] += col[1];
 -			blend[2] += col[2];
 -			blend[3] += col[3];
 -		}
 -
 -		blend[0] = divide_round_i(blend[0], totloop);
 -		blend[1] = divide_round_i(blend[1], totloop);
 -		blend[2] = divide_round_i(blend[2], totloop);
 -		blend[3] = divide_round_i(blend[3], totloop);
 -		col = (char *)&tcol;
 -		col[0] = blend[0];
 -		col[1] = blend[1];
 -		col[2] = blend[2];
 -		col[3] = blend[3];
 -
 -		vpd->paintcol = *((unsigned int *)col);
 -	}
 -
 -	ml = me->mloop + mpoly->loopstart;
 -	for (i = 0; i < totloop; i++, ml++) {
 -		float rgba[4];
 -		unsigned int paintcol;
 -		alpha = calc_vp_alpha_col_dl(vp, vc, vpd->vpimat,
 -		                         &vpd->vertexcosnos[ml->v], mval,
 -		                         brush_size_pressure, brush_alpha_pressure, rgba);
 -
 -		if (vpd->is_texbrush) {
 -			float rgba_br[3];
 -			rgb_uchar_to_float(rgba_br, (const unsigned char *)&vpd->paintcol);
 -			mul_v3_v3(rgba_br, rgba);
 -			rgb_float_to_uchar((unsigned char *)&paintcol, rgba_br);
 +	*r_alpha = calc_vp_alpha_col_dl(
 +	        data->vp, &data->vpd->vc, data->vpd->vpimat,
 +	        &data->vpd->vertexcosnos[v_index], ss->cache->mouse, size_pressure, alpha_pressure, rgba);
 +	rgb_uchar_to_float(rgba_br, (const uchar *)&data->vpd->paintcol);
 +	mul_v3_v3(rgba_br, rgba);
 +	rgb_float_to_uchar((uchar *)r_color, rgba_br);
 +}
 +
 +static void do_vpaint_brush_draw_task_cb_ex(
 +        void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id))
 +{
 +	SculptThreadedTaskData *data = userdata;
 +	SculptSession *ss = data->ob->sculpt;
 +	CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 +
 +	Brush *brush = data->brush;
 +	StrokeCache *cache = ss->cache;
 +	const float brush_strength = cache->bstrength;
 +	uint *lcol = data->lcol;
 +	Scene *scene = CTX_data_scene(data->C);
 +	float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
 +	get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
 +	const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 +
 +	SculptBrushTest test;
 +	sculpt_brush_test_init(ss, &test);
 +
 +	/* For each vertex*/
 +	PBVHVertexIter vd;
 +	BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 +	{
 +		/* Test to see if the vertex coordinates are within the spherical brush region. */
 +		if (sculpt_brush_test(&test, vd.co)) {
 +			/* Note: Grids are 1:1 with corners (aka loops).
 +			 * For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 +			 * Otherwise, take the current vert. */
 +			const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
 +			const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
 +			const MVert *mv = &data->me->mvert[v_index];
 +
 +			/* If the vertex is selected for painting. */
 +			if (!use_face_sel || mv->flag & SELECT) {
 +				/* Calc the dot prod. between ray norm on surf and current vert
 +				 * (ie splash prevention factor), and only paint front facing verts. */
 +				const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
 +				if (view_dot > 0.0f) {
 +					const float brush_fade = BKE_brush_curve_strength(brush, test.dist, cache->radius);
 +					uint color_final = data->vpd->paintcol;
 +
 +					/* If we're painting with a texture, sample the texture color and alpha. */
 +					float tex_alpha = 1.0;
 +					if (data->vpd->is_texbrush) {
 +						handle_texture_brush(
 +						        data, vd, brush_size_pressure, brush_alpha_pressure,
 +						        &tex_alpha, &color_final);
 +					}
 +					/* For each poly owning this vert, paint each loop belonging to this vert. */
 +					for (int j = 0; j < ss->modes.vwpaint.vert_to_poly[v_index].count; j++) {
 +						const int p_index = ss->modes.vwpaint.vert_to_poly[v_index].indices[j];
 +						const int l_index = ss->modes.vwpaint.vert_to_loop[v_index].indices[j];
 +						BLI_assert(data->me->mloop[l_index].v == v_index);
 +						const MPoly *mp = &data->me->mpoly[p_index];
 +						if (!use_face_sel || mp->flag & ME_FACE_SEL) {
 +							/* Get the previous loop color */
 +							if (ss->modes.vwpaint.previous_color[l_index] == 0) {
 +								ss->modes.vwpaint.previous_color[l_index] = lcol[l_index];
 +							}
 +							const float final_alpha =
 +							        255 * brush_fade * brush_strength * view_dot *
 +							        tex_alpha * brush_alpha_pressure * grid_alpha;
 +							/* Mix the new color with the original based on final_alpha. */
 +							lcol[l_index] = vpaint_blend(
 +							        data->vp, lcol[l_index],
 +							        ss->modes.vwpaint.previous_color[l_index], color_final,
 +							        final_alpha, 255 * brush_strength);
 +						}
 +					}
 +				}
 +			}
  		}
 -		else
 -			paintcol = vpd->paintcol;
 +	}
 +	BKE_pbvh_vertex_iter_end;
 +}
 +
 +static void do_vpaint_brush_blur_task_cb_ex(
 +        void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id))
 +{
 +	SculptThreadedTaskData *data = userdata;
 +	SculptSession *ss = data->ob->sculpt;
 +	CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 +
 +	Brush *brush = data->brush;
 +	StrokeCache *cache = ss->cache;
 +	const float brush_strength = cache->bstrength;
 +	uint *lcol = dat

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list