Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_mesh_remesh_voxel.h1
-rw-r--r--source/blender/blenkernel/BKE_paint.h4
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h15
-rw-r--r--source/blender/blenkernel/intern/brush.c30
-rw-r--r--source/blender/blenkernel/intern/customdata.c50
-rw-r--r--source/blender/blenkernel/intern/mesh_remesh_voxel.c31
-rw-r--r--source/blender/blenkernel/intern/object_update.c2
-rw-r--r--source/blender/blenkernel/intern/paint.c29
-rw-r--r--source/blender/blenkernel/intern/pbvh.c31
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h3
10 files changed, 154 insertions, 42 deletions
diff --git a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
index b63f9a9814b..24f95f7ed20 100644
--- a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
+++ b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
@@ -60,6 +60,7 @@ struct Mesh *BKE_mesh_remesh_quadriflow_to_mesh_nomain(struct Mesh *mesh,
/* Data reprojection functions */
void BKE_mesh_remesh_reproject_paint_mask(struct Mesh *target, struct Mesh *source);
+void BKE_remesh_reproject_vertex_paint(struct Mesh *target, struct Mesh *source);
void BKE_remesh_reproject_sculpt_face_sets(struct Mesh *target, struct Mesh *source);
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 6e4f2efeeb8..56503a0bcc6 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -308,6 +308,7 @@ typedef struct SculptSession {
int totvert, totpoly;
struct KeyBlock *shapekey_active;
+ struct MPropCol *vcol;
float *vmask;
/* Mesh connectivity */
@@ -430,7 +431,8 @@ void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph,
struct Object *ob_orig,
bool need_pmap,
- bool need_mask);
+ bool need_mask,
+ bool need_colors);
void BKE_sculpt_update_object_before_eval(struct Object *ob_eval);
void BKE_sculpt_update_object_after_eval(struct Depsgraph *depsgraph, struct Object *ob_eval);
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 8fb6f140822..87875314aec 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -58,6 +58,10 @@ typedef struct {
float (*co)[3];
} PBVHProxyNode;
+typedef struct {
+ float (*color)[4];
+} PBVHColorBufferNode;
+
typedef enum {
PBVH_Leaf = 1 << 0,
@@ -75,6 +79,7 @@ typedef enum {
PBVH_FullyUnmasked = 1 << 12,
PBVH_UpdateTopology = 1 << 13,
+ PBVH_UpdateColor = 1 << 14,
} PBVHNodeFlags;
typedef struct PBVHFrustumPlanes {
@@ -252,6 +257,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
void BKE_pbvh_node_mark_update(PBVHNode *node);
void BKE_pbvh_node_mark_update_mask(PBVHNode *node);
+void BKE_pbvh_node_mark_update_color(PBVHNode *node);
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node);
void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node);
void BKE_pbvh_node_mark_redraw(PBVHNode *node);
@@ -352,6 +358,7 @@ typedef struct PBVHVertexIter {
struct MVert *mverts;
int totvert;
const int *vert_indices;
+ struct MPropCol *vcol;
float *vmask;
/* bmesh */
@@ -368,6 +375,7 @@ typedef struct PBVHVertexIter {
short *no;
float *fno;
float *mask;
+ float *col;
bool visible;
} PBVHVertexIter;
@@ -419,7 +427,9 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi.no = vi.mvert->no; \
vi.index = vi.vert_indices[vi.i]; \
if (vi.vmask) \
- vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
+ vi.mask = &vi.vmask[vi.index]; \
+ if (vi.vcol) \
+ vi.col = vi.vcol[vi.index].color; \
} \
else { \
if (!BLI_gsetIterator_done(&vi.bm_unique_verts)) { \
@@ -472,6 +482,9 @@ void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings,
struct MVert *BKE_pbvh_get_verts(const PBVH *pbvh);
+PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node);
+void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index b66df6b1da6..0a991d3ef4a 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1570,6 +1570,23 @@ void BKE_brush_sculpt_reset(Brush *br)
br->alpha = 1.0f;
br->height = 0.05f;
break;
+ case SCULPT_TOOL_PAINT:
+ br->hardness = 0.4f;
+ br->spacing = 10;
+ br->alpha = 0.6f;
+ br->flow = 1.0f;
+ br->tip_scale_x = 1.0f;
+ br->tip_roundness = 1.0f;
+ br->density = 1.0f;
+ br->flag &= ~BRUSH_SPACE_ATTEN;
+ zero_v3(br->rgb);
+ break;
+ case SCULPT_TOOL_SMEAR:
+ br->alpha = 1.0f;
+ br->spacing = 7;
+ br->flag &= ~BRUSH_SPACE_ATTEN;
+ br->curve_preset = BRUSH_CURVE_SPHERE;
+ break;
default:
break;
}
@@ -1629,14 +1646,15 @@ void BKE_brush_sculpt_reset(Brush *br)
break;
case SCULPT_TOOL_SIMPLIFY:
+ case SCULPT_TOOL_PAINT:
case SCULPT_TOOL_MASK:
case SCULPT_TOOL_DRAW_FACE_SETS:
- br->add_col[0] = 0.750000;
- br->add_col[1] = 0.750000;
- br->add_col[2] = 0.750000;
- br->sub_col[0] = 0.750000;
- br->sub_col[1] = 0.750000;
- br->sub_col[2] = 0.750000;
+ br->add_col[0] = 0.75f;
+ br->add_col[1] = 0.75f;
+ br->add_col[2] = 0.75f;
+ br->sub_col[0] = 0.75f;
+ br->sub_col[1] = 0.75f;
+ br->sub_col[2] = 0.75f;
break;
case SCULPT_TOOL_CLOTH:
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 7dd4d1178ef..642a865afab 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -858,7 +858,6 @@ static void layerDoMinMax_mloopcol(const void *data, void *vmin, void *vmax)
if (m->a < min->a) {
min->a = m->a;
}
-
if (m->r > max->r) {
max->r = m->r;
}
@@ -1355,7 +1354,7 @@ static void layerCopyValue_propcol(const void *source,
/* Modes that do a full copy or nothing. */
if (ELEM(mixmode, CDT_MIX_REPLACE_ABOVE_THRESHOLD, CDT_MIX_REPLACE_BELOW_THRESHOLD)) {
/* TODO: Check for a real valid way to get 'factor' value of our dest color? */
- const float f = (m2->col[0] + m2->col[1] + m2->col[2]) / 3.0f;
+ const float f = (m2->color[0] + m2->color[1] + m2->color[2]) / 3.0f;
if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) {
return; /* Do Nothing! */
}
@@ -1363,29 +1362,29 @@ static void layerCopyValue_propcol(const void *source,
return; /* Do Nothing! */
}
}
- copy_v3_v3(m2->col, m1->col);
+ copy_v3_v3(m2->color, m1->color);
}
else { /* Modes that support 'real' mix factor. */
if (mixmode == CDT_MIX_MIX) {
- blend_color_mix_float(tmp_col, m2->col, m1->col);
+ blend_color_mix_float(tmp_col, m2->color, m1->color);
}
else if (mixmode == CDT_MIX_ADD) {
- blend_color_add_float(tmp_col, m2->col, m1->col);
+ blend_color_add_float(tmp_col, m2->color, m1->color);
}
else if (mixmode == CDT_MIX_SUB) {
- blend_color_sub_float(tmp_col, m2->col, m1->col);
+ blend_color_sub_float(tmp_col, m2->color, m1->color);
}
else if (mixmode == CDT_MIX_MUL) {
- blend_color_mul_float(tmp_col, m2->col, m1->col);
+ blend_color_mul_float(tmp_col, m2->color, m1->color);
}
else {
- memcpy(tmp_col, m1->col, sizeof(tmp_col));
+ memcpy(tmp_col, m1->color, sizeof(tmp_col));
}
- blend_color_interpolate_float(m2->col, m2->col, tmp_col, mixfactor);
+ blend_color_interpolate_float(m2->color, m2->color, tmp_col, mixfactor);
- copy_v3_v3(m2->col, m1->col);
+ copy_v3_v3(m2->color, m1->color);
}
- m2->col[3] = m1->col[3];
+ m2->color[3] = m1->color[3];
}
static bool layerEqual_propcol(const void *data1, const void *data2)
@@ -1394,7 +1393,7 @@ static bool layerEqual_propcol(const void *data1, const void *data2)
float tot = 0;
for (int i = 0; i < 4; i++) {
- float c = (m1->col[i] - m2->col[i]);
+ float c = (m1->color[i] - m2->color[i]);
tot += c * c;
}
@@ -1404,29 +1403,29 @@ static bool layerEqual_propcol(const void *data1, const void *data2)
static void layerMultiply_propcol(void *data, float fac)
{
MPropCol *m = data;
- mul_v4_fl(m->col, fac);
+ mul_v4_fl(m->color, fac);
}
static void layerAdd_propcol(void *data1, const void *data2)
{
MPropCol *m = data1;
const MPropCol *m2 = data2;
- add_v4_v4(m->col, m2->col);
+ add_v4_v4(m->color, m2->color);
}
static void layerDoMinMax_propcol(const void *data, void *vmin, void *vmax)
{
const MPropCol *m = data;
MPropCol *min = vmin, *max = vmax;
- minmax_v4v4_v4(min->col, max->col, m->col);
+ minmax_v4v4_v4(min->color, max->color, m->color);
}
static void layerInitMinMax_propcol(void *vmin, void *vmax)
{
MPropCol *min = vmin, *max = vmax;
- copy_v4_fl(min->col, FLT_MAX);
- copy_v4_fl(max->col, FLT_MIN);
+ copy_v4_fl(min->color, FLT_MAX);
+ copy_v4_fl(max->color, FLT_MIN);
}
static void layerDefault_propcol(void *data, int count)
@@ -1436,7 +1435,7 @@ static void layerDefault_propcol(void *data, int count)
MPropCol *pcol = (MPropCol *)data;
int i;
for (i = 0; i < count; i++) {
- copy_v4_v4(pcol[i].col, default_propcol.col);
+ copy_v4_v4(pcol[i].color, default_propcol.color);
}
}
@@ -1450,14 +1449,14 @@ static void layerInterp_propcol(
float weight = weights ? weights[i] : 1.0f;
const MPropCol *src = sources[i];
if (sub_weights) {
- madd_v4_v4fl(col, src->col, (*sub_weight) * weight);
+ madd_v4_v4fl(col, src->color, (*sub_weight) * weight);
sub_weight++;
}
else {
- madd_v4_v4fl(col, src->col, weight);
+ madd_v4_v4fl(col, src->color, weight);
}
}
- copy_v4_v4(mc->col, col);
+ copy_v4_v4(mc->color, col);
}
static int layerMaxNum_propcol(void)
@@ -1871,7 +1870,7 @@ const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = {
};
const CustomData_MeshMasks CD_MASK_MESH = {
.vmask = (CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK |
- CD_MASK_GENERIC_DATA),
+ CD_MASK_GENERIC_DATA | CD_MASK_PROP_COLOR),
.emask = (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_GENERIC_DATA),
.fmask = 0,
.lmask = (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL |
@@ -1881,7 +1880,7 @@ const CustomData_MeshMasks CD_MASK_MESH = {
};
const CustomData_MeshMasks CD_MASK_EDITMESH = {
.vmask = (CD_MASK_MDEFORMVERT | CD_MASK_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY |
- CD_MASK_SHAPE_KEYINDEX | CD_MASK_GENERIC_DATA),
+ CD_MASK_SHAPE_KEYINDEX | CD_MASK_GENERIC_DATA | CD_MASK_PROP_COLOR),
.emask = (CD_MASK_GENERIC_DATA),
.fmask = 0,
.lmask = (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL |
@@ -1901,7 +1900,8 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
};
const CustomData_MeshMasks CD_MASK_BMESH = {
.vmask = (CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY |
- CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_GENERIC_DATA),
+ CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_GENERIC_DATA |
+ CD_MASK_PROP_COLOR),
.emask = (CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_GENERIC_DATA),
.fmask = 0,
.lmask = (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL |
@@ -1925,7 +1925,7 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = {
.vmask = (CD_MASK_MVERT | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_NORMAL |
CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_ORCO |
CD_MASK_CLOTH_ORCO | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK |
- CD_MASK_GENERIC_DATA),
+ CD_MASK_GENERIC_DATA | CD_MASK_PROP_COLOR),
.emask = (CD_MASK_MEDGE | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_BWEIGHT |
CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_GENERIC_DATA),
.fmask = (CD_MASK_MFACE | CD_MASK_ORIGINDEX | CD_MASK_NORMAL | CD_MASK_MTFACE | CD_MASK_MCOL |
diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.c b/source/blender/blenkernel/intern/mesh_remesh_voxel.c
index 3daf9f2752e..010b306ec76 100644
--- a/source/blender/blenkernel/intern/mesh_remesh_voxel.c
+++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.c
@@ -405,6 +405,37 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source)
free_bvhtree_from_mesh(&bvhtree);
}
+void BKE_remesh_reproject_vertex_paint(Mesh *target, Mesh *source)
+{
+ BVHTreeFromMesh bvhtree = {
+ .nearest_callback = NULL,
+ };
+ BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
+
+ int tot_color_layer = CustomData_number_of_layers(&source->vdata, CD_PROP_COLOR);
+
+ for (int layer_n = 0; layer_n < tot_color_layer; layer_n++) {
+ const char *layer_name = CustomData_get_layer_name(&source->vdata, CD_PROP_COLOR, layer_n);
+ CustomData_add_layer_named(
+ &target->vdata, CD_PROP_COLOR, CD_CALLOC, NULL, target->totvert, layer_name);
+
+ MPropCol *target_color = CustomData_get_layer_n(&target->vdata, CD_PROP_COLOR, layer_n);
+ MVert *target_verts = CustomData_get_layer(&target->vdata, CD_MVERT);
+ MPropCol *source_color = CustomData_get_layer_n(&source->vdata, CD_PROP_COLOR, layer_n);
+ for (int i = 0; i < target->totvert; i++) {
+ BVHTreeNearest nearest;
+ nearest.index = -1;
+ nearest.dist_sq = FLT_MAX;
+ BLI_bvhtree_find_nearest(
+ bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
+ if (nearest.index != -1) {
+ copy_v4_v4(target_color[i].color, source_color[nearest.index].color);
+ }
+ }
+ }
+ free_bvhtree_from_mesh(&bvhtree);
+}
+
struct Mesh *BKE_mesh_remesh_voxel_fix_poles(struct Mesh *mesh)
{
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index c5ef5acb08b..d8c3e0bf714 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -183,7 +183,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
#endif
/* Always compute UVs, vertex colors as orcos for render. */
cddata_masks.lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
- cddata_masks.vmask |= CD_MASK_ORCO;
+ cddata_masks.vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
}
if (em) {
makeDerivedMesh(depsgraph, scene, ob, em, &cddata_masks); /* was CD_MASK_BAREMESH */
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index f26b478c680..151e0006092 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1474,8 +1474,12 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
/**
* \param need_mask: So that the evaluated mesh that is returned has mask data.
*/
-static void sculpt_update_object(
- Depsgraph *depsgraph, Object *ob, Mesh *me_eval, bool need_pmap, bool need_mask)
+static void sculpt_update_object(Depsgraph *depsgraph,
+ Object *ob,
+ Mesh *me_eval,
+ bool need_pmap,
+ bool need_mask,
+ bool need_colors)
{
Scene *scene = DEG_get_input_scene(depsgraph);
Sculpt *sd = scene->toolsettings->sculpt;
@@ -1503,6 +1507,16 @@ static void sculpt_update_object(
}
}
+ /* Add a color layer if a color tool is used. */
+ Mesh *orig_me = BKE_object_get_original_mesh(ob);
+ if (need_colors) {
+ if (!CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) {
+ CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
+ BKE_mesh_update_customdata_pointers(orig_me, true);
+ DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY);
+ }
+ }
+
/* tessfaces aren't used and will become invalid */
BKE_mesh_tessface_clear(me);
@@ -1535,6 +1549,7 @@ static void sculpt_update_object(
ss->multires.modifier = NULL;
ss->multires.level = 0;
ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
+ ss->vcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
}
/* Sculpt Face Sets. */
@@ -1663,13 +1678,11 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
BLI_assert(me_eval != NULL);
- sculpt_update_object(depsgraph, ob_orig, me_eval, false, false);
+ sculpt_update_object(depsgraph, ob_orig, me_eval, false, false, false);
}
-void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph,
- Object *ob_orig,
- bool need_pmap,
- bool need_mask)
+void BKE_sculpt_update_object_for_edit(
+ Depsgraph *depsgraph, Object *ob_orig, bool need_pmap, bool need_mask, bool need_colors)
{
/* Update from sculpt operators and undo, to update sculpt session
* and PBVH after edits. */
@@ -1679,7 +1692,7 @@ void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph,
BLI_assert(ob_orig == DEG_get_original_object(ob_orig));
- sculpt_update_object(depsgraph, ob_orig, me_eval, need_pmap, need_mask);
+ sculpt_update_object(depsgraph, ob_orig, me_eval, need_pmap, need_mask, need_colors);
}
int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 19f28047b80..8d7dabf9859 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1325,6 +1325,7 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
pbvh->face_sets_color_seed,
pbvh->face_sets_color_default,
+ CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR),
update_flags);
break;
case PBVH_BMESH:
@@ -1442,6 +1443,10 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
pbvh_update_mask_redraw(pbvh, nodes, totnode, flag);
}
+ if (flag & (PBVH_UpdateColor)) {
+ /* Do nothing */
+ }
+
if (flag & (PBVH_UpdateVisibility)) {
pbvh_update_visibility_redraw(pbvh, nodes, totnode, flag);
}
@@ -1729,6 +1734,11 @@ void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
node->flag |= PBVH_UpdateMask | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
+void BKE_pbvh_node_mark_update_color(PBVHNode *node)
+{
+ node->flag |= PBVH_UpdateColor | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
+}
+
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node)
{
node->flag |= PBVH_UpdateVisibility | PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers |
@@ -2905,6 +2915,26 @@ void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
*r_tot = tot;
}
+PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node)
+{
+
+ if (!node->color_buffer.color) {
+ node->color_buffer.color = MEM_callocN(node->uniq_verts * sizeof(float) * 4, "Color buffer");
+ }
+ return &node->color_buffer;
+}
+
+void BKE_pbvh_node_color_buffer_free(PBVH *pbvh)
+{
+ PBVHNode **nodes;
+ int totnode;
+ BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ for (int i = 0; i < totnode; i++) {
+ MEM_SAFE_FREE(nodes[i]->color_buffer.color);
+ }
+ MEM_SAFE_FREE(nodes);
+}
+
void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode)
{
struct CCGElem **grids;
@@ -2958,6 +2988,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->mask = NULL;
if (pbvh->type == PBVH_FACES) {
vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK);
+ vi->vcol = CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR);
}
}
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index 7397f939894..6f8bae822ea 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -105,6 +105,9 @@ struct PBVHNode {
float (*bm_orco)[3];
int (*bm_ortri)[3];
int bm_tot_ortri;
+
+ /* Used to store the brush color during a stroke and composite it over the original color */
+ PBVHColorBufferNode color_buffer;
};
typedef enum {