[Bf-blender-cvs] [ed9fee8] soc-2016-pbvh-painting: Added smudge tool to vertex paint. WPaint implementation coming soon. Fixed blend to use physically accurate blending model.

Nathan Vollmer noreply at git.blender.org
Sun Jul 31 03:15:36 CEST 2016


Commit: ed9fee8605419cdc14589e16dc54b23d2ecaa19e
Author: Nathan Vollmer
Date:   Sat Jul 30 19:15:28 2016 -0600
Branches: soc-2016-pbvh-painting
https://developer.blender.org/rBed9fee8605419cdc14589e16dc54b23d2ecaa19e

Added smudge tool to vertex paint. WPaint implementation coming soon. Fixed blend to use physically accurate blending model.

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenlib/BLI_math_base.h
M	source/blender/blenlib/intern/math_base_inline.c
M	source/blender/blenloader/intern/versioning_defaults.c
M	source/blender/editors/sculpt_paint/paint_vertex.c
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 5d563c5..3cb11f6 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -205,10 +205,10 @@ typedef struct SculptSession {
 	int *poly_map_mem;
 	MeshElemMap* vert_to_poly;
 
-  unsigned int* totalRed;
-  unsigned int* totalGreen;
-  unsigned int* totalBlue;
-  unsigned int* totalAlpha;
+  unsigned long* totalRed;
+  unsigned long* totalGreen;
+  unsigned long* totalBlue;
+  unsigned long* totalAlpha;
   double* totalWeight;
   unsigned int *totloopsHit;
 } SculptSession;
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index e97a250..5751aee 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -205,6 +205,7 @@ MINLINE unsigned int power_of_2_min_u(unsigned int x);
 
 MINLINE int iroundf(float a);
 MINLINE int divide_round_i(int a, int b);
+MINLINE unsigned long divide_round_ul(unsigned long a, unsigned long b);
 MINLINE int mod_i(int i, int n);
 
 int pow_i(int base, int exp);
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index 8d2d80c..e7362ed 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -193,6 +193,11 @@ MINLINE int divide_round_i(int a, int b)
 	return (2 * a + b) / (2 * b);
 }
 
+MINLINE unsigned long divide_round_ul(unsigned long a, unsigned long b)
+{
+  return (2 * a + b) / (2 * b);
+}
+
 /**
  * modulo that handles negative numbers, works the same as Python's.
  */
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 01a40d8..4901098 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -280,6 +280,13 @@ void BLO_update_defaults_startup_blend(Main *bmain)
 		    br->vertexpaint_tool = PAINT_BLEND_AVERAGE;
 		    br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT;
 		}
+
+    br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Smudge");
+    if (!br) {
+      br = BKE_brush_add(bmain, "Smudge", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT);
+      br->vertexpaint_tool = PAINT_BLEND_SMUDGE;
+      br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT;
+    }
 	}
 }
 
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 9ae86b2..32da4e9 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -613,9 +613,18 @@ BLI_INLINE unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac
 	cp2 = (unsigned char *)&col2;
 	cp  = (unsigned char *)&col;
 
-	cp[0] = divide_round_i((mfac * cp1[0] + fac * cp2[0]), 255);
-	cp[1] = divide_round_i((mfac * cp1[1] + fac * cp2[1]), 255);
-	cp[2] = divide_round_i((mfac * cp1[2] + fac * cp2[2]), 255);
+  // Updated to use physically correct color model. -N8V
+  int red1 = cp1[0] * cp1[0];
+  int green1 = cp1[1] * cp1[1];
+  int blue1 = cp1[2] * cp1[2];
+
+  int red2 = cp2[0] * cp2[0];
+  int green2 = cp2[1] * cp2[1];
+  int blue2 = cp2[2] * cp2[2];
+
+  cp[0] = (unsigned char)round(sqrt(divide_round_i((mfac * red1 + fac * red2), 255)));
+  cp[1] = (unsigned char)round(sqrt(divide_round_i((mfac * green1 + fac * green2), 255)));
+  cp[2] = (unsigned char)round(sqrt(divide_round_i((mfac * blue1 + fac * blue2), 255)));
 	cp[3] = 255;
 
 	return col;
@@ -768,7 +777,8 @@ static unsigned int vpaint_blend_tool(const int tool, const unsigned int col,
 	switch (tool) {
 		case PAINT_BLEND_MIX:
 		case PAINT_BLEND_BLUR:     return mcol_blend(col, paintcol, alpha_i);
-		case PAINT_BLEND_AVERAGE:  return mcol_blend(col, paintcol, alpha_i);
+    case PAINT_BLEND_AVERAGE:  return mcol_blend(col, paintcol, alpha_i);
+    case PAINT_BLEND_SMUDGE:   return mcol_blend(col, paintcol, alpha_i);
 		case PAINT_BLEND_ADD:      return mcol_add(col, paintcol, alpha_i);
 		case PAINT_BLEND_SUB:      return mcol_sub(col, paintcol, alpha_i);
 		case PAINT_BLEND_MUL:      return mcol_mul(col, paintcol, alpha_i);
@@ -965,6 +975,7 @@ static float wpaint_blend_tool(const int tool,
 	switch (tool) {
 		case PAINT_BLEND_MIX:
     case PAINT_BLEND_AVERAGE:
+    case PAINT_BLEND_SMUDGE:
 		case PAINT_BLEND_BLUR:     return wval_blend(weight, paintval, alpha);
 		case PAINT_BLEND_ADD:      return wval_add(weight, paintval, alpha);
 		case PAINT_BLEND_SUB:      return wval_sub(weight, paintval, alpha);
@@ -1756,10 +1767,10 @@ static void vertex_paint_init_session_average_arrays(Object *ob){
   int totNode = 0;
   //I think the totNodes might include internal nodes, and we really only need the tot leaves.
   BKE_pbvh_node_num_nodes(ob->sculpt->pbvh, &totNode);
-  ob->sculpt->totalRed = MEM_callocN(totNode*sizeof(unsigned int), "totalRed");
-  ob->sculpt->totalGreen = MEM_callocN(totNode * sizeof(unsigned int), "totalGreen");
-  ob->sculpt->totalBlue = MEM_callocN(totNode * sizeof(unsigned int), "totalBlue");
-  ob->sculpt->totalAlpha = MEM_callocN(totNode * sizeof(unsigned int), "totalAlpha");
+  ob->sculpt->totalRed = MEM_callocN(totNode*sizeof(unsigned long), "totalRed");
+  ob->sculpt->totalGreen = MEM_callocN(totNode * sizeof(unsigned long), "totalGreen");
+  ob->sculpt->totalBlue = MEM_callocN(totNode * sizeof(unsigned long), "totalBlue");
+  ob->sculpt->totalAlpha = MEM_callocN(totNode * sizeof(unsigned long), "totalAlpha");
   ob->sculpt->totalWeight = MEM_callocN(totNode * sizeof(double), "totalWeight");
   ob->sculpt->totloopsHit = MEM_callocN(totNode * sizeof(unsigned int), "totloopsHit");
 }
@@ -2433,6 +2444,7 @@ static void calc_brushdata_symm(VPaint *vd, StrokeCache *cache, const char symm,
   (void)vd; /* unused */
 
   flip_v3_v3(cache->location, cache->true_location, symm);
+  flip_v3_v3(cache->last_location, cache->true_last_location, symm);
   flip_v3_v3(cache->grab_delta_symmetry, cache->grab_delta, symm);
   flip_v3_v3(cache->view_normal, cache->true_view_normal, symm);
 
@@ -2460,6 +2472,7 @@ static void calc_brushdata_symm(VPaint *vd, StrokeCache *cache, const char symm,
   }
 
   mul_m4_v3(cache->symm_rot_mat, cache->location);
+  mul_m4_v3(cache->symm_rot_mat, cache->last_location);
   mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry);
 
   if (cache->supports_gravity) {
@@ -2640,7 +2653,7 @@ static void wpaint_paint_leaves(bContext *C, Object *ob, Sculpt *sd, VPaint *vp,
   data.C = C;
 
   //This might change to a case switch. 
-  if (brush->vertexpaint_tool == PAINT_BLEND_AVERAGE) {
+  if (brush->vertexpaint_tool == PAINT_BLEND_AVERAGE || brush->vertexpaint_tool == PAINT_BLEND_SMUDGE) {
     calculate_average_weight(&data, nodes, totnode);
     BLI_task_parallel_range_ex(
       0, totnode, &data, NULL, 0, do_wpaint_brush_draw_task_cb_ex,
@@ -3414,7 +3427,7 @@ static void do_vpaint_brush_calc_ave_color_cb_ex(
 	StrokeCache *cache = ss->cache;
 	
 	unsigned int *lcol = data->lcol;
-	unsigned int blend[4] = { 0 };
+	unsigned long blend[4] = { 0 };
 	char *col;
 	
 	data->ob->sculpt->totloopsHit[n] = 0;
@@ -3436,10 +3449,11 @@ static void do_vpaint_brush_calc_ave_color_cb_ex(
 				for (int j = 0; j < ss->vert_to_loop[vertexIndex].count; ++j) {
 					int loopIndex = ss->vert_to_loop[vertexIndex].indices[j];
 					col = (char *)(&lcol[loopIndex]);
-					blend[0] += col[0];
-					blend[1] += col[1];
-					blend[2] += col[2];
-					blend[3] += col[3];
+          // Color is squared to compensate the sqrt color encoding.
+          blend[0] += (long)col[0] * (long)col[0];
+          blend[1] += (long)col[1] * (long)col[1];
+          blend[2] += (long)col[2] * (long)col[2];
+          blend[3] += (long)col[3] * (long)col[3];
 				}
 			}
 		}
@@ -3502,7 +3516,7 @@ static void do_vpaint_brush_blur_task_cb_ex(
 	unsigned int *lcolorig = data->vp->vpaint_prev;
 
 	int totalHitLoops;
-	unsigned int blend[4] = { 0 };
+	unsigned long blend[4] = { 0 };
 	char *col;
 	unsigned int finalColor;
 
@@ -3532,18 +3546,19 @@ static void do_vpaint_brush_blur_task_cb_ex(
 				for (int k = 0; k < poly.totloop; k++) {
 					unsigned int loopIndex = poly.loopstart + k;
 					col = (char *)(&lcol[loopIndex]);
-					blend[0] += col[0];
-					blend[1] += col[1];
-					blend[2] += col[2];
-					blend[3] += col[3];
+          // Color is squared to compensate the sqrt color encoding.
+          blend[0] += (unsigned long)col[0] * (unsigned long)col[0];
+          blend[1] += (unsigned long)col[1] * (unsigned long)col[1];
+          blend[2] += (unsigned long)col[2] * (unsigned long)col[2];
+          blend[3] += (unsigned long)col[3] * (unsigned long)col[3];
 				}
 			}
 			if (totalHitLoops != 0) {
 				col = (char*)(&finalColor);
-				col[0] = divide_round_i(blend[0], totalHitLoops);
-				col[1] = divide_round_i(blend[1], totalHitLoops);
-				col[2] = divide_round_i(blend[2], totalHitLoops);
-				col[3] = divide_round_i(blend[3], totalHitLoops);
+				col[0] = (unsigned char)round(sqrtl(divide_round_ul(blend[0], totalHitLoops)));
+        col[1] = (unsigned char)round(sqrtl(divide_round_ul(blend[1], totalHitLoops)));
+        col[2] = (unsigned char)round(sqrtl(divide_round_ul(blend[2], totalHitLoops)));
+        col[3] = (unsigned char)round(sqrtl(divide_round_ul(blend[3], totalHitLoops)));
 
 				//if a vertex is within the brush region, then paint each loop that vertex owns.
 				for (int j = 0; j < ss->vert_to_loop[vertexIndex].count; ++j) {
@@ -3557,6 +3572,78 @@ static void do_vpaint_brush_blur_task_cb_ex(
 	}
 }
 
+static void do_vpaint_brush_smudge_task_cb_ex(
+  void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id)
+{
+  SculptThreadedTaskData *data = userdata;
+  SculptSession *ss = data->ob->sculpt;
+  Brush *brush = data->brush;
+  StrokeCache *cache = ss->cache;
+  const float bstrength = cache->bstrength;
+  bool shouldColor = false;
+  unsigned int *lcol = data->lcol;
+  unsigned int *lcolorig = data->vp->vpaint_prev;
+  unsigned int finalColor;
+  float brushDirection[3];
+  sub_v3_v3v3(brushDirection, cache->location, cache->las

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list