[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