[Bf-blender-cvs] [9930f7e] soc-2016-pbvh-painting: Added blur, although I might rename this tool as smudge and make a seperate blur tool.
Nathan Vollmer
noreply at git.blender.org
Sun Jun 19 05:16:35 CEST 2016
Commit: 9930f7ed33841ae6e114fec1a060cce06bb9da6d
Author: Nathan Vollmer
Date: Sat Jun 18 21:16:33 2016 -0600
Branches: soc-2016-pbvh-painting
https://developer.blender.org/rB9930f7ed33841ae6e114fec1a060cce06bb9da6d
Added blur, although I might rename this tool as smudge and make a seperate blur tool.
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/pbvh.c
M source/blender/editors/sculpt_paint/paint_vertex.c
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 39ca3fe..f99019b 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -190,6 +190,7 @@ void BKE_pbvh_node_num_verts(
void BKE_pbvh_node_get_verts(
PBVH *bvh, PBVHNode *node,
const int **r_vert_indices, struct MVert **r_verts);
+void BKE_pbvh_node_num_nodes(PBVH *bvh, int* r_totnode);
void BKE_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3]);
void BKE_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3]);
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 000070f..72bcfff 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1406,6 +1406,10 @@ void BKE_pbvh_node_num_verts(
}
}
+void BKE_pbvh_node_num_nodes(PBVH *bvh, int* r_totnode) {
+ *r_totnode = bvh->totnode;
+}
+
void BKE_pbvh_node_get_grids(
PBVH *bvh, PBVHNode *node,
int **r_grid_indices, int *r_totgrid, int *r_maxgrid, int *r_gridsize, CCGElem ***r_griddata)
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 58c404e..eae55a0 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2091,6 +2091,18 @@ static void vwpaint_update_cache_invariants(bContext *C, VPaint *vd, SculptSessi
BKE_mesh_vert_loop_map_create(&cache->vert_to_loop, &cache->map_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
}
+ int totNode = 0;
+ //I think the totNodes might include internal nodes, and we really only need the tot leaves.
+ BKE_pbvh_node_num_nodes(ss->pbvh, &totNode);
+
+ if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
+ ob->sculpt->cache->totalRed = MEM_callocN(totNode*sizeof(unsigned int), "totalRed");
+ ob->sculpt->cache->totalGreen = MEM_callocN(totNode * sizeof(unsigned int), "totalGreen");
+ ob->sculpt->cache->totalBlue = MEM_callocN(totNode * sizeof(unsigned int), "totalBlue");
+ ob->sculpt->cache->totalAlpha = MEM_callocN(totNode * sizeof(unsigned int), "totalAlpha");
+ ob->sculpt->cache->totloopsHit = MEM_callocN(totNode * sizeof(unsigned int), "totloopsHit");
+ }
+
}
/* Initialize the stroke cache variants from operator properties */
@@ -3076,6 +3088,48 @@ static void vpaint_paint_loop(VPaint *vp, VPaintData *vpd, Mesh *me,
}
}
+static void do_vpaint_brush_calc_ave_color_cb_ex(
+ void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id) {
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ StrokeCache *cache = ss->cache;
+
+ unsigned int *lcol = data->lcol;
+ unsigned int blend[4] = { 0 };
+ char *col;
+
+ data->totloopsHit[n] = 0;
+
+ //for each vertex
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SculptBrushTest test;
+ sculpt_brush_test_init(ss, &test);
+
+ //Test to see if the vertex coordinates are within the spherical brush region.
+ if (sculpt_brush_test(&test, vd.co)) {
+ int vertexIndex = vd.vert_indices[vd.i];
+
+ data->totloopsHit[n] += cache->vert_to_loop[vertexIndex].count;
+ //if a vertex is within the brush region, then add it's color to the blend.
+ for (int j = 0; j < cache->vert_to_loop[vertexIndex].count; ++j) {
+ int loopIndex = cache->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];
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+ }
+ data->totalRed[n] = blend[0];
+ data->totalGreen[n] = blend[1];
+ data->totalBlue[n] = blend[2];
+ data->totalAlpha[n] = blend[3];
+}
+
static void do_vpaint_brush_draw_task_cb_ex(
void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id)
{
@@ -3085,13 +3139,8 @@ static void do_vpaint_brush_draw_task_cb_ex(
StrokeCache *cache = ss->cache;
const float bstrength = cache->bstrength;
- unsigned int *lcol;
- if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
- lcol = data->vp->vpaint_prev;
- printf("Bluring currently unsupported.\n");
- }
- else
- lcol = data->lcol;
+ unsigned int *lcol = data->lcol;
+
unsigned int *lcolorig = data->vp->vpaint_prev;
//for each vertex
@@ -3100,22 +3149,18 @@ static void do_vpaint_brush_draw_task_cb_ex(
{
SculptBrushTest test;
sculpt_brush_test_init(ss, &test);
+
+ //Test to see if the vertex coordinates are within the spherical brush region.
if (sculpt_brush_test(&test, vd.co)) {
const float fade = tex_strength(ss, brush, vd.co, test.dist, vd.no, vd.fno, 0.0f, thread_id);
int vertexIndex = vd.vert_indices[vd.i];
- MVert vert = cache->verts[vertexIndex];
- //Test to see if the vertex coordinates are within the spherical brush region.
- if (sculpt_brush_test(&test, vert.co)) {
- unsigned int original[4] = { 0 };
- //if a vertex is within the brush region, then paint each loop that vertex owns.
- for (int j = 0; j < cache->vert_to_loop[vertexIndex].count; ++j) {
- int loopIndex = cache->vert_to_loop[vertexIndex].indices[j];
- //Mix the new color with the original based on the brush strength and the curve.
- lcol[loopIndex] = vpaint_blend(data->vp, data->lcol[loopIndex], data->vp->vpaint_prev[loopIndex], data->vpd->paintcol, 255.0 * fade, 255.0 * bstrength);
- //lcol[i] = vpaint_blend(vp, lcol[i], lcolorig[i], paintcol, alpha_i, brush_alpha_pressure_i);
-
- }
+
+ //if a vertex is within the brush region, then paint each loop that vertex owns.
+ for (int j = 0; j < cache->vert_to_loop[vertexIndex].count; ++j) {
+ int loopIndex = cache->vert_to_loop[vertexIndex].indices[j];
+ //Mix the new color with the original based on the brush strength and the curve.
+ lcol[loopIndex] = vpaint_blend(data->vp, lcol[loopIndex], lcolorig[loopIndex], data->vpd->paintcol, 255.0 * fade, 255.0 * bstrength);
}
}
BKE_pbvh_vertex_iter_end;
@@ -3135,9 +3180,41 @@ static void vpaint_paint_leaves(Sculpt *sd, VPaint *vp, VPaintData *vpd, Object
data.vpd = vpd;
data.lcol = (unsigned int*)me->mloopcol;
+ if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
+ //To be moved
+ data.totalRed = ob->sculpt->cache->totalRed; //MEM_callocN(totnode*sizeof(unsigned int), "totalRed");
+ data.totalGreen = ob->sculpt->cache->totalGreen; // MEM_callocN(totnode*sizeof(unsigned int), "totalGreen");
+ data.totalBlue = ob->sculpt->cache->totalBlue; //MEM_callocN(totnode*sizeof(unsigned int), "totalBlue");
+ data.totalAlpha = ob->sculpt->cache->totalAlpha;// MEM_callocN(totnode*sizeof(unsigned int), "totalAlpha");
+ data.totloopsHit = ob->sculpt->cache->totloopsHit; //MEM_callocN(totnode*sizeof(unsigned int), "totloopsHit");
+
+ BLI_task_parallel_range_ex(
+ 0, totnode, &data, NULL, 0, do_vpaint_brush_calc_ave_color_cb_ex,
+ ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT), false);
+
+ unsigned int totalHitLoops = 0;
+ unsigned int totalColor[4] = { 0 };
+ unsigned char blend[4] = { 0 };
+ for (int i = 0; i < totnode; ++i) {
+ totalHitLoops += data.totloopsHit[i];
+ totalColor[0] += data.totalRed[i];
+ totalColor[1] += data.totalGreen[i];
+ totalColor[2] += data.totalBlue[i];
+ totalColor[3] += data.totalAlpha[i];
+ }
+ if (totalHitLoops != 0) {
+ blend[0] = divide_round_i(totalColor[0], totalHitLoops);
+ blend[1] = divide_round_i(totalColor[1], totalHitLoops);
+ blend[2] = divide_round_i(totalColor[2], totalHitLoops);
+ blend[3] = divide_round_i(totalColor[3], totalHitLoops);
+ data.vpd->paintcol = *((unsigned int*)blend);
+ }
+ }
+
BLI_task_parallel_range_ex(
0, totnode, &data, NULL, 0, do_vpaint_brush_draw_task_cb_ex,
((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT), false);
+
}
static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 8eeeda9..b04d383 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -3795,8 +3795,23 @@ void sculpt_cache_free(StrokeCache *cache)
{
if (cache->dial)
MEM_freeN(cache->dial);
+
+ // vwpaint loop mapping
if (cache->vert_to_loop)
MEM_freeN(cache->vert_to_loop);
+
+ //For vw paint blending
+ if (cache->totloopsHit)
+ MEM_freeN(cache->totloopsHit);
+ if (cache->totalRed)
+ MEM_freeN(cache->totalRed);
+ if (cache->totalGreen)
+ MEM_freeN(cache->totalGreen);
+ if (cache->totalBlue)
+ MEM_freeN(cache->totalBlue);
+ if (cache->totalAlpha)
+ MEM_freeN(cache->totalAlpha);
+
MEM_freeN(cache);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 72f1256..c0944e37 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -229,6 +229,11 @@ typedef struct StrokeCache {
MVert *verts;
int *map_mem;
MeshElemMap* vert_to_loop;
+ unsigned int* totalRed;
+ unsigned int* totalGreen;
+ unsigned int* totalBlue;
+ unsigned int* totalAlpha;
+ unsigned int *totloopsHit;
} StrokeCache;
@@ -257,8 +262,14 @@ typedef struct SculptThreadedTaskData {
VPaint *vp;
VPaintData *vpd;
unsigned int* lcol;
+ unsigned int* totalRed;
+ unsigned int* totalGreen;
+ unsigned int* totalBlue;
+ unsigned int* totalAlpha;
+ unsigned int *totloopsHit;
MeshElemMap **vertToLoopMaps;
+
/* Data specific to some callbacks. */
/* Note: even if only one or two of those are used at a time, keeping them separated, names help figuring out
* what it is, and memory overhead is ridiculous anyway... */
More information about the Bf-blender-cvs
mailing list