| 
						
					 | 
					 | 
					@@ -88,6 +88,66 @@ struct WPaintAverageAccum {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						double value;
 | 
					 | 
					 | 
					 | 
						double value;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					};
 | 
					 | 
					 | 
					 | 
					};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					struct NormalAnglePrecalc {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						bool do_mask_normal;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						/* what angle to mask at */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						float angle;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						/* cos(angle), faster to compare */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						float angle__cos;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						float angle_inner;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						float angle_inner__cos;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						/* difference between angle and angle_inner, for easy access */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						float angle_range;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void view_angle_limits_init(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        struct NormalAnglePrecalc *a, float angle, bool do_mask_normal)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						a->do_mask_normal = do_mask_normal;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (do_mask_normal) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							a->angle_inner = angle;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							a->angle = (a->angle_inner + 90.0f) * 0.5f;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							a->angle_inner = a->angle = angle;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						a->angle_inner *=   (float)(M_PI_2 / 90);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						a->angle *=         (float)(M_PI_2 / 90);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						a->angle_range = a->angle - a->angle_inner;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (a->angle_range <= 0.0f) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							a->do_mask_normal = false;  /* no need to do blending */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						a->angle__cos       = cosf(a->angle);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						a->angle_inner__cos = cosf(a->angle_inner);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static float view_angle_limits_apply_falloff(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        const struct NormalAnglePrecalc *a, float angle_cos, float *mask_p)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (angle_cos <= a->angle__cos) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							/* outsize the normal limit */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							return false;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						else if (angle_cos < a->angle_inner__cos) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							*mask_p *= (a->angle - acosf(angle_cos)) / a->angle_range;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							return true;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							return true;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static bool vwpaint_use_normal(const VPaint *vp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						return ((vp->flag & VP_FLAG_PROJECT_BACKFACE) == 0) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						       ((vp->flag & VP_FLAG_PROJECT_FLAT) == 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void defweight_prev_restore_or_init(MDeformVert *dvert_prev, MDeformVert *dvert_curr, int index)
 | 
					 | 
					 | 
					 | 
					static void defweight_prev_restore_or_init(MDeformVert *dvert_prev, MDeformVert *dvert_curr, int index)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						MDeformVert *dv_curr = &dvert_curr[index];
 | 
					 | 
					 | 
					 | 
						MDeformVert *dv_curr = &dvert_curr[index];
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -185,7 +245,7 @@ static VPaint *new_vpaint(int wpaint)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint");
 | 
					 | 
					 | 
					 | 
						VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vp->flag = (wpaint) ? 0 : VP_SPRAY;
 | 
					 | 
					 | 
					 | 
						vp->flag = (wpaint) ? 0 : VP_FLAG_SPRAY;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vp->paint.flags |= PAINT_SHOW_BRUSH;
 | 
					 | 
					 | 
					 | 
						vp->paint.flags |= PAINT_SHOW_BRUSH;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return vp;
 | 
					 | 
					 | 
					 | 
						return vp;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -213,7 +273,7 @@ static uint vpaint_blend(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						uint color_blend = ED_vpaint_blend_tool(tool, color_curr, color_paint, alpha_i);
 | 
					 | 
					 | 
					 | 
						uint color_blend = ED_vpaint_blend_tool(tool, color_curr, color_paint, alpha_i);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* if no spray, clip color adding with colorig & orig alpha */
 | 
					 | 
					 | 
					 | 
						/* if no spray, clip color adding with colorig & orig alpha */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if ((vp->flag & VP_SPRAY) == 0) {
 | 
					 | 
					 | 
					 | 
						if ((vp->flag & VP_FLAG_SPRAY) == 0) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							uint color_test, a;
 | 
					 | 
					 | 
					 | 
							uint color_test, a;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							char *cp, *ct, *co;
 | 
					 | 
					 | 
					 | 
							char *cp, *ct, *co;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -299,7 +359,7 @@ static float calc_vp_alpha_col_dl(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (strength > 0.0f) {
 | 
					 | 
					 | 
					 | 
						if (strength > 0.0f) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							float alpha = brush_alpha_pressure * strength;
 | 
					 | 
					 | 
					 | 
							float alpha = brush_alpha_pressure * strength;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (vp->flag & VP_NORMALS) {
 | 
					 | 
					 | 
					 | 
							if ((vp->flag & VP_FLAG_PROJECT_FLAT) == 0) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								float dvec[3];
 | 
					 | 
					 | 
					 | 
								float dvec[3];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								/* transpose ! */
 | 
					 | 
					 | 
					 | 
								/* transpose ! */
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -670,7 +730,7 @@ static void do_weight_paint_vertex_single(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							index_mirr = vgroup_mirr = -1;
 | 
					 | 
					 | 
					 | 
							index_mirr = vgroup_mirr = -1;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if ((wp->flag & VP_SPRAY) == 0) {
 | 
					 | 
					 | 
					 | 
						if ((wp->flag & VP_FLAG_SPRAY) == 0) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							struct MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
 | 
					 | 
					 | 
					 | 
							struct MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							defweight_prev_restore_or_init(dvert_prev, me->dvert, index);
 | 
					 | 
					 | 
					 | 
							defweight_prev_restore_or_init(dvert_prev, me->dvert, index);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (index_mirr != -1) {
 | 
					 | 
					 | 
					 | 
							if (index_mirr != -1) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -678,7 +738,7 @@ static void do_weight_paint_vertex_single(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (wp->flag & VP_ONLYVGROUP) {
 | 
					 | 
					 | 
					 | 
						if (wp->flag & VP_FLAG_VGROUP_RESTRICT) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							dw = defvert_find_index(dv, wpi->active.index);
 | 
					 | 
					 | 
					 | 
							dw = defvert_find_index(dv, wpi->active.index);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						else {
 | 
					 | 
					 | 
					 | 
						else {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -692,7 +752,7 @@ static void do_weight_paint_vertex_single(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* get the mirror def vars */
 | 
					 | 
					 | 
					 | 
						/* get the mirror def vars */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (index_mirr != -1) {
 | 
					 | 
					 | 
					 | 
						if (index_mirr != -1) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							dv_mirr = &me->dvert[index_mirr];
 | 
					 | 
					 | 
					 | 
							dv_mirr = &me->dvert[index_mirr];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (wp->flag & VP_ONLYVGROUP) {
 | 
					 | 
					 | 
					 | 
							if (wp->flag & VP_FLAG_VGROUP_RESTRICT) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								dw_mirr = defvert_find_index(dv_mirr, vgroup_mirr);
 | 
					 | 
					 | 
					 | 
								dw_mirr = defvert_find_index(dv_mirr, vgroup_mirr);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (dw_mirr == NULL) {
 | 
					 | 
					 | 
					 | 
								if (dw_mirr == NULL) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -814,7 +874,7 @@ static void do_weight_paint_vertex_multi(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if ((wp->flag & VP_SPRAY) == 0) {
 | 
					 | 
					 | 
					 | 
						if ((wp->flag & VP_FLAG_SPRAY) == 0) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							struct MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
 | 
					 | 
					 | 
					 | 
							struct MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							defweight_prev_restore_or_init(dvert_prev, me->dvert, index);
 | 
					 | 
					 | 
					 | 
							defweight_prev_restore_or_init(dvert_prev, me->dvert, index);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (index_mirr != -1) {
 | 
					 | 
					 | 
					 | 
							if (index_mirr != -1) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -947,7 +1007,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* Create average brush arrays */
 | 
					 | 
					 | 
					 | 
						/* Create average brush arrays */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (ob->mode == OB_MODE_VERTEX_PAINT) {
 | 
					 | 
					 | 
					 | 
						if (ob->mode == OB_MODE_VERTEX_PAINT) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if ((ts->vpaint->flag & VP_SPRAY) == 0) {
 | 
					 | 
					 | 
					 | 
							if ((ts->vpaint->flag & VP_FLAG_SPRAY) == 0) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (ob->sculpt->mode.vpaint.previous_color == NULL) {
 | 
					 | 
					 | 
					 | 
								if (ob->sculpt->mode.vpaint.previous_color == NULL) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									ob->sculpt->mode.vpaint.previous_color =
 | 
					 | 
					 | 
					 | 
									ob->sculpt->mode.vpaint.previous_color =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									        MEM_callocN(me->totloop * sizeof(uint), __func__);
 | 
					 | 
					 | 
					 | 
									        MEM_callocN(me->totloop * sizeof(uint), __func__);
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -968,7 +1028,7 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
 | 
					 | 
					 | 
					 | 
						else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if ((ts->wpaint->flag & VP_SPRAY) == 0) {
 | 
					 | 
					 | 
					 | 
							if ((ts->wpaint->flag & VP_FLAG_SPRAY) == 0) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (ob->sculpt->mode.wpaint.alpha_weight == NULL) {
 | 
					 | 
					 | 
					 | 
								if (ob->sculpt->mode.wpaint.alpha_weight == NULL) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									ob->sculpt->mode.wpaint.alpha_weight =
 | 
					 | 
					 | 
					 | 
									ob->sculpt->mode.wpaint.alpha_weight =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									        MEM_callocN(me->totvert * sizeof(float), __func__);
 | 
					 | 
					 | 
					 | 
									        MEM_callocN(me->totvert * sizeof(float), __func__);
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1116,6 +1176,7 @@ void PAINT_OT_weight_paint_toggle(wmOperatorType *ot)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					struct WPaintData {
 | 
					 | 
					 | 
					 | 
					struct WPaintData {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ViewContext vc;
 | 
					 | 
					 | 
					 | 
						ViewContext vc;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						struct NormalAnglePrecalc normal_angle_precalc;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						struct WeightPaintGroupData active, mirror;
 | 
					 | 
					 | 
					 | 
						struct WeightPaintGroupData active, mirror;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1138,12 +1199,12 @@ struct WPaintData {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* Initialize the stroke cache invariants from operator properties */
 | 
					 | 
					 | 
					 | 
					/* Initialize the stroke cache invariants from operator properties */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void vwpaint_update_cache_invariants(
 | 
					 | 
					 | 
					 | 
					static void vwpaint_update_cache_invariants(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        bContext *C, VPaint *vd, SculptSession *ss, wmOperator *op, const float mouse[2])
 | 
					 | 
					 | 
					 | 
					        bContext *C, VPaint *vp, SculptSession *ss, wmOperator *op, const float mouse[2])
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache;
 | 
					 | 
					 | 
					 | 
						StrokeCache *cache;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(C);
 | 
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(C);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
 | 
					 | 
					 | 
					 | 
						UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = BKE_paint_brush(&vd->paint);
 | 
					 | 
					 | 
					 | 
						Brush *brush = BKE_paint_brush(&vp->paint);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ViewContext *vc = paint_stroke_view_context(op->customdata);
 | 
					 | 
					 | 
					 | 
						ViewContext *vc = paint_stroke_view_context(op->customdata);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Object *ob = CTX_data_active_object(C);
 | 
					 | 
					 | 
					 | 
						Object *ob = CTX_data_active_object(C);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float mat[3][3];
 | 
					 | 
					 | 
					 | 
						float mat[3][3];
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1195,12 +1256,12 @@ static void vwpaint_update_cache_invariants(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* Initialize the stroke cache variants from operator properties */
 | 
					 | 
					 | 
					 | 
					/* Initialize the stroke cache variants from operator properties */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void vwpaint_update_cache_variants(bContext *C, VPaint *vd, Object *ob, PointerRNA *ptr)
 | 
					 | 
					 | 
					 | 
					static void vwpaint_update_cache_variants(bContext *C, VPaint *vp, Object *ob, PointerRNA *ptr)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(C);
 | 
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(C);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = BKE_paint_brush(&vd->paint);
 | 
					 | 
					 | 
					 | 
						Brush *brush = BKE_paint_brush(&vp->paint);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* This effects the actual brush radius, so things farther away
 | 
					 | 
					 | 
					 | 
						/* This effects the actual brush radius, so things farther away
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * are compared with a larger radius and vise versa. */
 | 
					 | 
					 | 
					 | 
						 * are compared with a larger radius and vise versa. */
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1258,7 +1319,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int defbase_tot, defbase_tot_sel;
 | 
					 | 
					 | 
					 | 
						int defbase_tot, defbase_tot_sel;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						bool *defbase_sel;
 | 
					 | 
					 | 
					 | 
						bool *defbase_sel;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						VPaint *vd = CTX_data_tool_settings(C)->wpaint;
 | 
					 | 
					 | 
					 | 
						VPaint *vp = CTX_data_tool_settings(C)->wpaint;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float mat[4][4], imat[4][4];
 | 
					 | 
					 | 
					 | 
						float mat[4][4], imat[4][4];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1313,6 +1374,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						wpd = MEM_callocN(sizeof(struct WPaintData), "WPaintData");
 | 
					 | 
					 | 
					 | 
						wpd = MEM_callocN(sizeof(struct WPaintData), "WPaintData");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						paint_stroke_set_mode_data(stroke, wpd);
 | 
					 | 
					 | 
					 | 
						paint_stroke_set_mode_data(stroke, wpd);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						view3d_set_viewcontext(C, &wpd->vc);
 | 
					 | 
					 | 
					 | 
						view3d_set_viewcontext(C, &wpd->vc);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						view_angle_limits_init(&wpd->normal_angle_precalc, vp->normal_angle, (vp->flag & VP_FLAG_PROJECT_FLAT) == 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						wpd->active.index = vgroup_index.active;
 | 
					 | 
					 | 
					 | 
						wpd->active.index = vgroup_index.active;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						wpd->mirror.index = vgroup_index.mirror;
 | 
					 | 
					 | 
					 | 
						wpd->mirror.index = vgroup_index.mirror;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1369,7 +1431,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* If not previously created, create vertex/weight paint mode session data */
 | 
					 | 
					 | 
					 | 
						/* If not previously created, create vertex/weight paint mode session data */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vertex_paint_init_session(scene, ob);
 | 
					 | 
					 | 
					 | 
						vertex_paint_init_session(scene, ob);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vwpaint_update_cache_invariants(C, vd, ss, op, mouse);
 | 
					 | 
					 | 
					 | 
						vwpaint_update_cache_invariants(C, vp, ss, op, mouse);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vertex_paint_init_session_data(ts, ob);
 | 
					 | 
					 | 
					 | 
						vertex_paint_init_session_data(ts, ob);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (ob->sculpt->mode.wpaint.dvert_prev != NULL) {
 | 
					 | 
					 | 
					 | 
						if (ob->sculpt->mode.wpaint.dvert_prev != NULL) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1391,7 +1453,7 @@ static float dot_vf3vs3(const float brushNormal[3], const short vertexNormal[3])
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void get_brush_alpha_data(
 | 
					 | 
					 | 
					 | 
					static void get_brush_alpha_data(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Scene *scene, SculptSession *ss, Brush *brush,
 | 
					 | 
					 | 
					 | 
					        const Scene *scene, const SculptSession *ss, const Brush *brush,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        float *r_brush_size_pressure, float *r_brush_alpha_value, float *r_brush_alpha_pressure)
 | 
					 | 
					 | 
					 | 
					        float *r_brush_size_pressure, float *r_brush_alpha_value, float *r_brush_alpha_pressure)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						*r_brush_size_pressure =
 | 
					 | 
					 | 
					 | 
						*r_brush_size_pressure =
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1417,6 +1479,22 @@ static float wpaint_get_active_weight(const MDeformVert *dv, const WeightPaintIn
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static SculptBrushTestFn sculpt_brush_test_init_with_falloff_shape(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        SculptSession *ss, SculptBrushTest *test, char falloff_shape)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						sculpt_brush_test_init(ss, test);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						SculptBrushTestFn sculpt_brush_test_sq_fn;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (falloff_shape == VP_FALLOFF_SHAPE_SPHERE) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							sculpt_brush_test_sq_fn = sculpt_brush_test_sphere_sq;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							/* VP_FALLOFF_SHAPE_TUBE */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							plane_from_point_normal_v3(test->plane, test->location, ss->cache->view_normal);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							sculpt_brush_test_sq_fn = sculpt_brush_test_circle_sq;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						return sculpt_brush_test_sq_fn;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void do_wpaint_brush_blur_task_cb_ex(
 | 
					 | 
					 | 
					 | 
					static void do_wpaint_brush_blur_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id))
 | 
					 | 
					 | 
					 | 
					        void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1425,25 +1503,26 @@ static void do_wpaint_brush_blur_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap;
 | 
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = data->brush;
 | 
					 | 
					 | 
					 | 
						const Brush *brush = data->brush;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						const StrokeCache *cache = ss->cache;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const float brush_strength = cache->bstrength;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
						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);
 | 
					 | 
					 | 
					 | 
						get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const bool use_normal = vwpaint_use_normal(data->vp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_brush_test_init(ss, &test);
 | 
					 | 
					 | 
					 | 
						SculptBrushTestFn sculpt_brush_test_sq_fn =
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 | 
					 | 
					 | 
					 | 
						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. */
 | 
					 | 
					 | 
					 | 
							/* Test to see if the vertex coordinates are within the spherical brush region. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
 | 
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								/* For grid based pbvh, take the vert whose loop coopresponds to the current grid.
 | 
					 | 
					 | 
					 | 
								/* For grid based pbvh, take the vert whose loop coopresponds to the current grid.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								 * Otherwise, take the current vert. */
 | 
					 | 
					 | 
					 | 
								 * 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 int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1469,16 +1548,19 @@ static void do_wpaint_brush_blur_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									/* Apply the weight to the vertex. */
 | 
					 | 
					 | 
					 | 
									/* Apply the weight to the vertex. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (total_hit_loops != 0) {
 | 
					 | 
					 | 
					 | 
									if (total_hit_loops != 0) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
 | 
					 | 
					 | 
					 | 
										float brush_strength = cache->bstrength;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										if (view_dot > 0.0f) {
 | 
					 | 
					 | 
					 | 
										const float angle_cos = (use_normal && vd.no) ?
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										        dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										     (angle_cos > 0.0f)) &&
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										    ((data->vp->flag & VP_FLAG_PROJECT_FLAT) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										     view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
					 | 
					 | 
					 | 
											const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											float final_alpha =
 | 
					 | 
					 | 
					 | 
											float final_alpha =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											        brush_fade * brush_strength *
 | 
					 | 
					 | 
					 | 
											        brush_fade * brush_strength *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											        grid_alpha * brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
											        grid_alpha * brush_alpha_pressure;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											if (data->vp->flag & VP_NORMALS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												final_alpha *= view_dot;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											if (brush->flag & BRUSH_ACCUMULATE) {
 | 
					 | 
					 | 
					 | 
											if (brush->flag & BRUSH_ACCUMULATE) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												float mask_accum = ss->mode.wpaint.previous_accum[v_index];
 | 
					 | 
					 | 
					 | 
												float mask_accum = ss->mode.wpaint.previous_accum[v_index];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												final_alpha = min_ff(final_alpha + mask_accum, brush_strength);
 | 
					 | 
					 | 
					 | 
												final_alpha = min_ff(final_alpha + mask_accum, brush_strength);
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1506,12 +1588,12 @@ static void do_wpaint_brush_smear_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap;
 | 
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = data->brush;
 | 
					 | 
					 | 
					 | 
						const Brush *brush = data->brush;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
					 | 
					 | 
					 | 
						const Scene *scene = CTX_data_scene(data->C);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						const StrokeCache *cache = ss->cache;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const float brush_strength = cache->bstrength;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
						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);
 | 
					 | 
					 | 
					 | 
						get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const bool use_normal = vwpaint_use_normal(data->vp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float brush_dir[3];
 | 
					 | 
					 | 
					 | 
						float brush_dir[3];
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1522,26 +1604,32 @@ static void do_wpaint_brush_smear_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (normalize_v3(brush_dir) != 0.0f) {
 | 
					 | 
					 | 
					 | 
						if (normalize_v3(brush_dir) != 0.0f) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							SculptBrushTest test;
 | 
					 | 
					 | 
					 | 
							SculptBrushTest test;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							sculpt_brush_test_init(ss, &test);
 | 
					 | 
					 | 
					 | 
							SculptBrushTestFn sculpt_brush_test_sq_fn =
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							/* For each vertex */
 | 
					 | 
					 | 
					 | 
							/* For each vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							PBVHVertexIter vd;
 | 
					 | 
					 | 
					 | 
							PBVHVertexIter vd;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 | 
					 | 
					 | 
					 | 
							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. */
 | 
					 | 
					 | 
					 | 
								/* Test to see if the vertex coordinates are within the spherical brush region. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (sculpt_brush_test_sphere_fast(&test, vd.co)) {
 | 
					 | 
					 | 
					 | 
								if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
 | 
					 | 
					 | 
					 | 
									/* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (view_dot > 0.0f) {
 | 
					 | 
					 | 
					 | 
									 * Otherwise, take the current vert. */
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										bool do_color = false;
 | 
					 | 
					 | 
					 | 
									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_curr = &data->me->mvert[v_index];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										/* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 | 
					 | 
					 | 
					 | 
									/* If the vertex is selected */
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										 * Otherwise, take the current vert. */
 | 
					 | 
					 | 
					 | 
									if (!(use_face_sel || use_vert_sel) || mv_curr->flag & SELECT) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
 | 
					 | 
					 | 
					 | 
										float brush_strength = cache->bstrength;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
 | 
					 | 
					 | 
					 | 
										const float angle_cos = (use_normal && vd.no) ?
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										const MVert *mv_curr = &data->me->mvert[v_index];
 | 
					 | 
					 | 
					 | 
										        dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
										if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) ||
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										/* If the vertex is selected */
 | 
					 | 
					 | 
					 | 
										     (angle_cos > 0.0f)) &&
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										if (!(use_face_sel || use_vert_sel) || mv_curr->flag & SELECT) {
 | 
					 | 
					 | 
					 | 
										    ((data->vp->flag & VP_FLAG_PROJECT_FLAT) ||
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										     view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
											bool do_color = false;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											/* Minimum dot product between brush direction and current
 | 
					 | 
					 | 
					 | 
											/* Minimum dot product between brush direction and current
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											 * to neighbor direction is 0.0, meaning orthogonal. */
 | 
					 | 
					 | 
					 | 
											 * to neighbor direction is 0.0, meaning orthogonal. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											float stroke_dot_max = 0.0f;
 | 
					 | 
					 | 
					 | 
											float stroke_dot_max = 0.0f;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1578,14 +1666,10 @@ static void do_wpaint_brush_smear_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											}
 | 
					 | 
					 | 
					 | 
											}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											/* Apply weight to vertex */
 | 
					 | 
					 | 
					 | 
											/* Apply weight to vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											if (do_color) {
 | 
					 | 
					 | 
					 | 
											if (do_color) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												const float brush_fade = BKE_brush_curve_strength(brush, test.dist, cache->radius);
 | 
					 | 
					 | 
					 | 
												const float brush_fade = BKE_brush_curve_strength(brush, 0.0f, cache->radius);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												float final_alpha =
 | 
					 | 
					 | 
					 | 
												float final_alpha =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												        brush_fade * brush_strength *
 | 
					 | 
					 | 
					 | 
												        brush_fade * brush_strength *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												        grid_alpha * brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
												        grid_alpha * brush_alpha_pressure;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												if (data->vp->flag & VP_NORMALS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													final_alpha *= view_dot;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												do_weight_paint_vertex(
 | 
					 | 
					 | 
					 | 
												do_weight_paint_vertex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												        data->vp, data->ob, data->wpi,
 | 
					 | 
					 | 
					 | 
												        data->vp, data->ob, data->wpi,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												        v_index, final_alpha, (float)weight_final);
 | 
					 | 
					 | 
					 | 
												        v_index, final_alpha, (float)weight_final);
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1604,26 +1688,27 @@ static void do_wpaint_brush_draw_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptThreadedTaskData *data = userdata;
 | 
					 | 
					 | 
					 | 
						SculptThreadedTaskData *data = userdata;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptSession *ss = data->ob->sculpt;
 | 
					 | 
					 | 
					 | 
						SculptSession *ss = data->ob->sculpt;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
					 | 
					 | 
					 | 
						const Scene *scene = CTX_data_scene(data->C);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = data->brush;
 | 
					 | 
					 | 
					 | 
						const Brush *brush = data->brush;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						const StrokeCache *cache = ss->cache;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const float brush_strength = cache->bstrength;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const float paintweight = BKE_brush_weight_get(scene, brush);
 | 
					 | 
					 | 
					 | 
						const float paintweight = BKE_brush_weight_get(scene, brush);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
						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);
 | 
					 | 
					 | 
					 | 
						get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const bool use_normal = vwpaint_use_normal(data->vp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_brush_test_init(ss, &test);
 | 
					 | 
					 | 
					 | 
						SculptBrushTestFn sculpt_brush_test_sq_fn =
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 | 
					 | 
					 | 
					 | 
						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. */
 | 
					 | 
					 | 
					 | 
							/* Test to see if the vertex coordinates are within the spherical brush region. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
 | 
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								/* Note: grids are 1:1 with corners (aka loops).
 | 
					 | 
					 | 
					 | 
								/* Note: grids are 1:1 with corners (aka loops).
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								 * For multires, take the vert whose loop cooresponds to the current grid.
 | 
					 | 
					 | 
					 | 
								 * For multires, take the vert whose loop cooresponds to the current grid.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								 * Otherwise, take the current vert. */
 | 
					 | 
					 | 
					 | 
								 * Otherwise, take the current vert. */
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1633,14 +1718,16 @@ static void do_wpaint_brush_draw_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								const char v_flag = data->me->mvert[v_index].flag;
 | 
					 | 
					 | 
					 | 
								const char v_flag = data->me->mvert[v_index].flag;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								/* If the vertex is selected */
 | 
					 | 
					 | 
					 | 
								/* If the vertex is selected */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
 | 
					 | 
					 | 
					 | 
								if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
 | 
					 | 
					 | 
					 | 
									float brush_strength = cache->bstrength;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (view_dot > 0.0f) {
 | 
					 | 
					 | 
					 | 
									const float angle_cos = (use_normal && vd.no) ?
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									        dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									     (angle_cos > 0.0f)) &&
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									    ((data->vp->flag & VP_FLAG_PROJECT_FLAT) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									     view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
					 | 
					 | 
					 | 
										const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										float final_alpha = brush_fade * brush_strength * grid_alpha * brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
										float final_alpha = brush_fade * brush_strength * grid_alpha * brush_alpha_pressure;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										if (data->vp->flag & VP_NORMALS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											final_alpha *= view_dot;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										if (brush->flag & BRUSH_ACCUMULATE) {
 | 
					 | 
					 | 
					 | 
										if (brush->flag & BRUSH_ACCUMULATE) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											float mask_accum = ss->mode.wpaint.previous_accum[v_index];
 | 
					 | 
					 | 
					 | 
											float mask_accum = ss->mode.wpaint.previous_accum[v_index];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											final_alpha = min_ff(final_alpha + mask_accum, brush_strength);
 | 
					 | 
					 | 
					 | 
											final_alpha = min_ff(final_alpha + mask_accum, brush_strength);
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1648,7 +1735,7 @@ static void do_wpaint_brush_draw_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										}
 | 
					 | 
					 | 
					 | 
										}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										/* Non-spray logic. */
 | 
					 | 
					 | 
					 | 
										/* Non-spray logic. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										if ((data->vp->flag & VP_SPRAY) == 0) {
 | 
					 | 
					 | 
					 | 
										if ((data->vp->flag & VP_FLAG_SPRAY) == 0) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											/* Only paint if we have greater alpha. */
 | 
					 | 
					 | 
					 | 
											/* Only paint if we have greater alpha. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											if (ss->mode.wpaint.alpha_weight[v_index] < final_alpha) {
 | 
					 | 
					 | 
					 | 
											if (ss->mode.wpaint.alpha_weight[v_index] < final_alpha) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												ss->mode.wpaint.alpha_weight[v_index] = final_alpha;
 | 
					 | 
					 | 
					 | 
												ss->mode.wpaint.alpha_weight[v_index] = final_alpha;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1676,6 +1763,7 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const bool use_normal = vwpaint_use_normal(data->vp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1684,16 +1772,18 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						accum->value = 0.0;
 | 
					 | 
					 | 
					 | 
						accum->value = 0.0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_brush_test_init(ss, &test);
 | 
					 | 
					 | 
					 | 
						SculptBrushTestFn sculpt_brush_test_sq_fn =
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 | 
					 | 
					 | 
					 | 
						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. */
 | 
					 | 
					 | 
					 | 
							/* Test to see if the vertex coordinates are within the spherical brush region. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
 | 
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
 | 
					 | 
					 | 
					 | 
								const float angle_cos = (use_normal && vd.no) ?
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (view_dot > 0.0 && BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) {
 | 
					 | 
					 | 
					 | 
								        dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								if (angle_cos > 0.0 && BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
 | 
					 | 
					 | 
					 | 
									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 float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									const char v_flag = data->me->mvert[v_index].flag;
 | 
					 | 
					 | 
					 | 
									const char v_flag = data->me->mvert[v_index].flag;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1776,6 +1866,50 @@ static void wpaint_paint_leaves(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static PBVHNode **vwpaint_pbvh_gather_generic(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        Object *ob, VPaint *wp, Sculpt *sd, Brush *brush, int *r_totnode)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const bool use_normal = vwpaint_use_normal(wp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						PBVHNode **nodes = NULL;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						/* Build a list of all nodes that are potentially within the brush's area of influence */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (wp->falloff_shape == VP_FALLOFF_SHAPE_SPHERE) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							SculptSearchSphereData data = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.ss = ss,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.sd = sd,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.radius_squared = ss->cache->radius_squared,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.original = true,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, r_totnode);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (use_normal) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								sculpt_pbvh_calc_area_normal(brush, ob, nodes, *r_totnode, true, ss->cache->sculpt_normal_symm);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								zero_v3(ss->cache->sculpt_normal_symm);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							struct DistRayAABB_Precalc dist_ray_to_aabb_precalc;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							dist_squared_ray_to_aabb_precalc(&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							SculptSearchCircleData data = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.ss = ss,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.sd = sd,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.radius_squared = ss->cache->radius_squared,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.original = true,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							BKE_pbvh_search_gather(ss->pbvh, sculpt_search_circle_cb, &data, &nodes, r_totnode);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (use_normal) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								copy_v3_v3(ss->cache->sculpt_normal_symm, ss->cache->view_normal);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								zero_v3(ss->cache->sculpt_normal_symm);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						return nodes;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void wpaint_do_paint(
 | 
					 | 
					 | 
					 | 
					static void wpaint_do_paint(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        bContext *C, Object *ob, VPaint *wp, Sculpt *sd, struct WPaintData *wpd, WeightPaintInfo *wpi,
 | 
					 | 
					 | 
					 | 
					        bContext *C, Object *ob, VPaint *wp, Sculpt *sd, struct WPaintData *wpd, WeightPaintInfo *wpi,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Mesh *me, Brush *brush, const char symm, const int axis, const int i, const float angle)
 | 
					 | 
					 | 
					 | 
					        Mesh *me, Brush *brush, const char symm, const int axis, const int i, const float angle)
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -1784,19 +1918,9 @@ static void wpaint_do_paint(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ss->cache->radial_symmetry_pass = i;
 | 
					 | 
					 | 
					 | 
						ss->cache->radial_symmetry_pass = i;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
 | 
					 | 
					 | 
					 | 
						sculpt_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptSearchSphereData data;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						PBVHNode **nodes = NULL;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int totnode;
 | 
					 | 
					 | 
					 | 
						int totnode;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, wp, sd, brush, &totnode);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* Build a list of all nodes that are potentially within the brush's area of influence */
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data.ss = ss;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data.sd = sd;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data.radius_squared = ss->cache->radius_squared;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data.original = true;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, ss->cache->sculpt_normal_symm);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						wpaint_paint_leaves(C, ob, sd, wp, wpd, wpi, me, nodes, totnode);
 | 
					 | 
					 | 
					 | 
						wpaint_paint_leaves(C, ob, sd, wp, wpd, wpi, me, nodes, totnode);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (nodes)
 | 
					 | 
					 | 
					 | 
						if (nodes)
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2179,6 +2303,8 @@ typedef struct PolyFaceMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					struct VPaintData {
 | 
					 | 
					 | 
					 | 
					struct VPaintData {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ViewContext vc;
 | 
					 | 
					 | 
					 | 
						ViewContext vc;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						struct NormalAnglePrecalc normal_angle_precalc;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						uint paintcol;
 | 
					 | 
					 | 
					 | 
						uint paintcol;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						struct VertProjHandle *vp_handle;
 | 
					 | 
					 | 
					 | 
						struct VertProjHandle *vp_handle;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2223,6 +2349,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vpd = MEM_callocN(sizeof(*vpd), "VPaintData");
 | 
					 | 
					 | 
					 | 
						vpd = MEM_callocN(sizeof(*vpd), "VPaintData");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						paint_stroke_set_mode_data(stroke, vpd);
 | 
					 | 
					 | 
					 | 
						paint_stroke_set_mode_data(stroke, vpd);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						view3d_set_viewcontext(C, &vpd->vc);
 | 
					 | 
					 | 
					 | 
						view3d_set_viewcontext(C, &vpd->vc);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						view_angle_limits_init(&vpd->normal_angle_precalc, vp->normal_angle, (vp->flag & VP_FLAG_PROJECT_FLAT) == 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vpd->paintcol = vpaint_get_current_col(scene, vp);
 | 
					 | 
					 | 
					 | 
						vpd->paintcol = vpaint_get_current_col(scene, vp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2287,16 +2414,17 @@ static void do_vpaint_brush_calc_average_color_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						memset(accum->value, 0, sizeof(accum->value));
 | 
					 | 
					 | 
					 | 
						memset(accum->value, 0, sizeof(accum->value));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_brush_test_init(ss, &test);
 | 
					 | 
					 | 
					 | 
						SculptBrushTestFn sculpt_brush_test_sq_fn =
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 | 
					 | 
					 | 
					 | 
						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. */
 | 
					 | 
					 | 
					 | 
							/* Test to see if the vertex coordinates are within the spherical brush region. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sphere_fast(&test, vd.co)) {
 | 
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
 | 
					 | 
					 | 
					 | 
								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 (BKE_brush_curve_strength(data->brush, 0.0, cache->radius) > 0.0) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									/* If the vertex is selected for painting. */
 | 
					 | 
					 | 
					 | 
									/* If the vertex is selected for painting. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									const MVert *mv = &data->me->mvert[v_index];
 | 
					 | 
					 | 
					 | 
									const MVert *mv = &data->me->mvert[v_index];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (!use_vert_sel || mv->flag & SELECT) {
 | 
					 | 
					 | 
					 | 
									if (!use_vert_sel || mv->flag & SELECT) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2344,25 +2472,26 @@ static void do_vpaint_brush_draw_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
					 | 
					 | 
					 | 
						CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
 | 
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = data->brush;
 | 
					 | 
					 | 
					 | 
						const Brush *brush = data->brush;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						const StrokeCache *cache = ss->cache;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const float brush_strength = cache->bstrength;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						uint *lcol = data->lcol;
 | 
					 | 
					 | 
					 | 
						uint *lcol = data->lcol;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
					 | 
					 | 
					 | 
						const Scene *scene = CTX_data_scene(data->C);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
						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);
 | 
					 | 
					 | 
					 | 
						get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const bool use_normal = vwpaint_use_normal(data->vp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_brush_test_init(ss, &test);
 | 
					 | 
					 | 
					 | 
						SculptBrushTestFn sculpt_brush_test_sq_fn =
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 | 
					 | 
					 | 
					 | 
						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. */
 | 
					 | 
					 | 
					 | 
							/* Test to see if the vertex coordinates are within the spherical brush region. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
 | 
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								/* Note: Grids are 1:1 with corners (aka loops).
 | 
					 | 
					 | 
					 | 
								/* Note: Grids are 1:1 with corners (aka loops).
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								 * For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 | 
					 | 
					 | 
					 | 
								 * For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								 * Otherwise, take the current vert. */
 | 
					 | 
					 | 
					 | 
								 * Otherwise, take the current vert. */
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2374,8 +2503,14 @@ static void do_vpaint_brush_draw_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (!use_vert_sel || mv->flag & SELECT) {
 | 
					 | 
					 | 
					 | 
								if (!use_vert_sel || mv->flag & SELECT) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									/* Calc the dot prod. between ray norm on surf and current vert
 | 
					 | 
					 | 
					 | 
									/* Calc the dot prod. between ray norm on surf and current vert
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									 * (ie splash prevention factor), and only paint front facing verts. */
 | 
					 | 
					 | 
					 | 
									 * (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;
 | 
					 | 
					 | 
					 | 
									float brush_strength = cache->bstrength;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (view_dot > 0.0f) {
 | 
					 | 
					 | 
					 | 
									const float angle_cos = (use_normal && vd.no) ?
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									        dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									     (angle_cos > 0.0f)) &&
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									    ((data->vp->flag & VP_FLAG_PROJECT_FLAT) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									     view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
					 | 
					 | 
					 | 
										const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										uint color_final = data->vpd->paintcol;
 | 
					 | 
					 | 
					 | 
										uint color_final = data->vpd->paintcol;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2404,10 +2539,6 @@ static void do_vpaint_brush_draw_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												float final_alpha =
 | 
					 | 
					 | 
					 | 
												float final_alpha =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												        255 * brush_fade * brush_strength *
 | 
					 | 
					 | 
					 | 
												        255 * brush_fade * brush_strength *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												        tex_alpha * brush_alpha_pressure * grid_alpha;
 | 
					 | 
					 | 
					 | 
												        tex_alpha * brush_alpha_pressure * grid_alpha;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												if (data->vp->flag & VP_NORMALS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													final_alpha *= view_dot;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												if (brush->flag & BRUSH_ACCUMULATE) {
 | 
					 | 
					 | 
					 | 
												if (brush->flag & BRUSH_ACCUMULATE) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													float mask_accum = ss->mode.vpaint.previous_accum[l_index];
 | 
					 | 
					 | 
					 | 
													float mask_accum = ss->mode.vpaint.previous_accum[l_index];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													final_alpha = min_ff(final_alpha + mask_accum, 255.0f * brush_strength);
 | 
					 | 
					 | 
					 | 
													final_alpha = min_ff(final_alpha + mask_accum, 255.0f * brush_strength);
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2436,36 +2567,43 @@ static void do_vpaint_brush_blur_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
 | 
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = data->brush;
 | 
					 | 
					 | 
					 | 
						const Brush *brush = data->brush;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						const StrokeCache *cache = ss->cache;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const float brush_strength = cache->bstrength;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						uint *lcol = data->lcol;
 | 
					 | 
					 | 
					 | 
						uint *lcol = data->lcol;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
						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);
 | 
					 | 
					 | 
					 | 
						get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const bool use_normal = vwpaint_use_normal(data->vp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
					 | 
					 | 
					 | 
						SculptBrushTest test;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_brush_test_init(ss, &test);
 | 
					 | 
					 | 
					 | 
						SculptBrushTestFn sculpt_brush_test_sq_fn =
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
					 | 
					 | 
					 | 
						/* For each vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
					 | 
					 | 
					 | 
						PBVHVertexIter vd;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 | 
					 | 
					 | 
					 | 
						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. */
 | 
					 | 
					 | 
					 | 
							/* Test to see if the vertex coordinates are within the spherical brush region. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
 | 
					 | 
					 | 
					 | 
							if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								/* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 | 
					 | 
					 | 
					 | 
								/* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								 * Otherwise, take the current vert. */
 | 
					 | 
					 | 
					 | 
								 * 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 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 float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								const MVert *mv = &data->me->mvert[v_index];
 | 
					 | 
					 | 
					 | 
								const MVert *mv = &data->me->mvert[v_index];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0;
 | 
					 | 
					 | 
					 | 
								/* If the vertex is selected for painting. */
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (view_dot > 0.0f) {
 | 
					 | 
					 | 
					 | 
								if (!use_vert_sel || mv->flag & SELECT) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
					 | 
					 | 
					 | 
									float brush_strength = cache->bstrength;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									const float angle_cos = (use_normal && vd.no) ?
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									        dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									     (angle_cos > 0.0f)) &&
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									    ((data->vp->flag & VP_FLAG_PROJECT_FLAT) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									     view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									/* If the vertex is selected for painting. */
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (!use_vert_sel || mv->flag & SELECT) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										/* Get the average poly color */
 | 
					 | 
					 | 
					 | 
										/* Get the average poly color */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										uint color_final = 0;
 | 
					 | 
					 | 
					 | 
										uint color_final = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										int total_hit_loops = 0;
 | 
					 | 
					 | 
					 | 
										int total_hit_loops = 0;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2512,10 +2650,6 @@ static void do_vpaint_brush_blur_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													float final_alpha =
 | 
					 | 
					 | 
					 | 
													float final_alpha =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													        255 * brush_fade * brush_strength *
 | 
					 | 
					 | 
					 | 
													        255 * brush_fade * brush_strength *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													        brush_alpha_pressure * grid_alpha;
 | 
					 | 
					 | 
					 | 
													        brush_alpha_pressure * grid_alpha;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													if (data->vp->flag & VP_NORMALS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														final_alpha *= view_dot;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													/* Mix the new color with the original
 | 
					 | 
					 | 
					 | 
													/* Mix the new color with the original
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													 * based on the brush strength and the curve. */
 | 
					 | 
					 | 
					 | 
													 * based on the brush strength and the curve. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													lcol[l_index] = vpaint_blend(
 | 
					 | 
					 | 
					 | 
													lcol[l_index] = vpaint_blend(
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2540,13 +2674,13 @@ static void do_vpaint_brush_smear_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
					 | 
					 | 
					 | 
						Scene *scene = CTX_data_scene(data->C);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
 | 
					 | 
					 | 
					 | 
						const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = data->brush;
 | 
					 | 
					 | 
					 | 
						const Brush *brush = data->brush;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						const StrokeCache *cache = ss->cache;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const float brush_strength = cache->bstrength;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						uint *lcol = data->lcol;
 | 
					 | 
					 | 
					 | 
						uint *lcol = data->lcol;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
 | 
					 | 
					 | 
					 | 
						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);
 | 
					 | 
					 | 
					 | 
						get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						float brush_dir[3];
 | 
					 | 
					 | 
					 | 
						float brush_dir[3];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const bool use_normal = vwpaint_use_normal(data->vp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
					 | 
					 | 
					 | 
						const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2556,14 +2690,15 @@ static void do_vpaint_brush_smear_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (normalize_v3(brush_dir) != 0.0f) {
 | 
					 | 
					 | 
					 | 
						if (normalize_v3(brush_dir) != 0.0f) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							SculptBrushTest test;
 | 
					 | 
					 | 
					 | 
							SculptBrushTest test;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							sculpt_brush_test_init(ss, &test);
 | 
					 | 
					 | 
					 | 
							SculptBrushTestFn sculpt_brush_test_sq_fn =
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							/* For each vertex */
 | 
					 | 
					 | 
					 | 
							/* For each vertex */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							PBVHVertexIter vd;
 | 
					 | 
					 | 
					 | 
							PBVHVertexIter vd;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
 | 
					 | 
					 | 
					 | 
							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. */
 | 
					 | 
					 | 
					 | 
								/* Test to see if the vertex coordinates are within the spherical brush region. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
 | 
					 | 
					 | 
					 | 
								if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									/* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 | 
					 | 
					 | 
					 | 
									/* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									 * Otherwise, take the current vert. */
 | 
					 | 
					 | 
					 | 
									 * 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 int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2574,8 +2709,14 @@ static void do_vpaint_brush_smear_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (!use_vert_sel || mv_curr->flag & SELECT) {
 | 
					 | 
					 | 
					 | 
									if (!use_vert_sel || mv_curr->flag & SELECT) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										/* Calc the dot prod. between ray norm on surf and current vert
 | 
					 | 
					 | 
					 | 
										/* Calc the dot prod. between ray norm on surf and current vert
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										 * (ie splash prevention factor), and only paint front facing verts. */
 | 
					 | 
					 | 
					 | 
										 * (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;
 | 
					 | 
					 | 
					 | 
										float brush_strength = cache->bstrength;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										if (view_dot > 0.0f) {
 | 
					 | 
					 | 
					 | 
										const float angle_cos = (use_normal && vd.no) ?
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										        dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										     (angle_cos > 0.0f)) &&
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										    ((data->vp->flag & VP_FLAG_PROJECT_FLAT) ||
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										     view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
					 | 
					 | 
					 | 
											const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											bool do_color = false;
 | 
					 | 
					 | 
					 | 
											bool do_color = false;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2636,10 +2777,6 @@ static void do_vpaint_brush_smear_task_cb_ex(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														float final_alpha =
 | 
					 | 
					 | 
					 | 
														float final_alpha =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														        255 * brush_fade * brush_strength *
 | 
					 | 
					 | 
					 | 
														        255 * brush_fade * brush_strength *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														        brush_alpha_pressure * grid_alpha;
 | 
					 | 
					 | 
					 | 
														        brush_alpha_pressure * grid_alpha;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														if (data->vp->flag & VP_NORMALS) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
															final_alpha *= view_dot;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														/* Mix the new color with the original
 | 
					 | 
					 | 
					 | 
														/* Mix the new color with the original
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														 * based on the brush strength and the curve. */
 | 
					 | 
					 | 
					 | 
														 * based on the brush strength and the curve. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
														lcol[l_index] = vpaint_blend(
 | 
					 | 
					 | 
					 | 
														lcol[l_index] = vpaint_blend(
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2721,27 +2858,18 @@ static void vpaint_paint_leaves(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void vpaint_do_paint(
 | 
					 | 
					 | 
					 | 
					static void vpaint_do_paint(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        bContext *C, Sculpt *sd, VPaint *vd, struct VPaintData *vpd,
 | 
					 | 
					 | 
					 | 
					        bContext *C, Sculpt *sd, VPaint *vp, struct VPaintData *vpd,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Object *ob, Mesh *me, Brush *brush, const char symm, const int axis, const int i, const float angle)
 | 
					 | 
					 | 
					 | 
					        Object *ob, Mesh *me, Brush *brush, const char symm, const int axis, const int i, const float angle)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						ss->cache->radial_symmetry_pass = i;
 | 
					 | 
					 | 
					 | 
						ss->cache->radial_symmetry_pass = i;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
 | 
					 | 
					 | 
					 | 
						sculpt_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptSearchSphereData data;
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						PBVHNode **nodes = NULL;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int totnode;
 | 
					 | 
					 | 
					 | 
						int totnode;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
						PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, vp, sd, brush, &totnode);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* Build a list of all nodes that are potentially within the brush's area of influence */
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data.ss = ss;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data.sd = sd;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data.radius_squared = ss->cache->radius_squared;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						data.original = true;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sculpt_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, ss->cache->sculpt_normal_symm);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* Paint those leaves. */
 | 
					 | 
					 | 
					 | 
						/* Paint those leaves. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vpaint_paint_leaves(C, sd, vd, vpd, ob, me, nodes, totnode);
 | 
					 | 
					 | 
					 | 
						vpaint_paint_leaves(C, sd, vp, vpd, ob, me, nodes, totnode);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (nodes) {
 | 
					 | 
					 | 
					 | 
						if (nodes) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							MEM_freeN(nodes);
 | 
					 | 
					 | 
					 | 
							MEM_freeN(nodes);
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2749,31 +2877,31 @@ static void vpaint_do_paint(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void vpaint_do_radial_symmetry(
 | 
					 | 
					 | 
					 | 
					static void vpaint_do_radial_symmetry(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        bContext *C, Sculpt *sd, VPaint *vd, struct VPaintData *vpd, Object *ob, Mesh *me,
 | 
					 | 
					 | 
					 | 
					        bContext *C, Sculpt *sd, VPaint *vp, struct VPaintData *vpd, Object *ob, Mesh *me,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Brush *brush, const char symm, const int axis)
 | 
					 | 
					 | 
					 | 
					        Brush *brush, const char symm, const int axis)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for (int i = 1; i < vd->radial_symm[axis - 'X']; i++) {
 | 
					 | 
					 | 
					 | 
						for (int i = 1; i < vp->radial_symm[axis - 'X']; i++) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							const float angle = (2.0 * M_PI) * i / vd->radial_symm[axis - 'X'];
 | 
					 | 
					 | 
					 | 
							const float angle = (2.0 * M_PI) * i / vp->radial_symm[axis - 'X'];
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							vpaint_do_paint(C, sd, vd, vpd, ob, me, brush, symm, axis, i, angle);
 | 
					 | 
					 | 
					 | 
							vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, symm, axis, i, angle);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* near duplicate of: sculpt.c's, 'do_symmetrical_brush_actions' and 'wpaint_do_symmetrical_brush_actions'. */
 | 
					 | 
					 | 
					 | 
					/* near duplicate of: sculpt.c's, 'do_symmetrical_brush_actions' and 'wpaint_do_symmetrical_brush_actions'. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void vpaint_do_symmetrical_brush_actions(
 | 
					 | 
					 | 
					 | 
					static void vpaint_do_symmetrical_brush_actions(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        bContext *C, Sculpt *sd, VPaint *vd, struct VPaintData *vpd, Object *ob)
 | 
					 | 
					 | 
					 | 
					        bContext *C, Sculpt *sd, VPaint *vp, struct VPaintData *vpd, Object *ob)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Brush *brush = BKE_paint_brush(&vd->paint);
 | 
					 | 
					 | 
					 | 
						Brush *brush = BKE_paint_brush(&vp->paint);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Mesh *me = ob->data;
 | 
					 | 
					 | 
					 | 
						Mesh *me = ob->data;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
					 | 
					 | 
					 | 
						SculptSession *ss = ob->sculpt;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
					 | 
					 | 
					 | 
						StrokeCache *cache = ss->cache;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const char symm = vd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
 | 
					 | 
					 | 
					 | 
						const char symm = vp->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int i = 0;
 | 
					 | 
					 | 
					 | 
						int i = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* initial stroke */
 | 
					 | 
					 | 
					 | 
						/* initial stroke */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vpaint_do_paint(C, sd, vd, vpd, ob, me, brush, i, 'X', 0, 0);
 | 
					 | 
					 | 
					 | 
						vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, i, 'X', 0, 0);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vpaint_do_radial_symmetry(C, sd, vd, vpd, ob, me, brush, i, 'X');
 | 
					 | 
					 | 
					 | 
						vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'X');
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vpaint_do_radial_symmetry(C, sd, vd, vpd, ob, me, brush, i, 'Y');
 | 
					 | 
					 | 
					 | 
						vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'Y');
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						vpaint_do_radial_symmetry(C, sd, vd, vpd, ob, me, brush, i, 'Z');
 | 
					 | 
					 | 
					 | 
						vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'Z');
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						cache->symmetry = symm;
 | 
					 | 
					 | 
					 | 
						cache->symmetry = symm;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -2785,16 +2913,16 @@ static void vpaint_do_symmetrical_brush_actions(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								sculpt_cache_calc_brushdata_symm(cache, i, 0, 0);
 | 
					 | 
					 | 
					 | 
								sculpt_cache_calc_brushdata_symm(cache, i, 0, 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (i & (1 << 0)) {
 | 
					 | 
					 | 
					 | 
								if (i & (1 << 0)) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									vpaint_do_paint(C, sd, vd, vpd, ob, me, brush, i, 'X', 0, 0);
 | 
					 | 
					 | 
					 | 
									vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, i, 'X', 0, 0);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									vpaint_do_radial_symmetry(C, sd, vd, vpd, ob, me, brush, i, 'X');
 | 
					 | 
					 | 
					 | 
									vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'X');
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (i & (1 << 1)) {
 | 
					 | 
					 | 
					 | 
								if (i & (1 << 1)) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									vpaint_do_paint(C, sd, vd, vpd, ob, me, brush, i, 'Y', 0, 0);
 | 
					 | 
					 | 
					 | 
									vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, i, 'Y', 0, 0);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									vpaint_do_radial_symmetry(C, sd, vd, vpd, ob, me, brush, i, 'Y');
 | 
					 | 
					 | 
					 | 
									vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'Y');
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (i & (1 << 2)) {
 | 
					 | 
					 | 
					 | 
								if (i & (1 << 2)) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									vpaint_do_paint(C, sd, vd, vpd, ob, me, brush, i, 'Z', 0, 0);
 | 
					 | 
					 | 
					 | 
									vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, i, 'Z', 0, 0);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									vpaint_do_radial_symmetry(C, sd, vd, vpd, ob, me, brush, i, 'Z');
 | 
					 | 
					 | 
					 | 
									vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'Z');
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					 
 |