diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh_remesh_voxel.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 50 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_remesh_voxel.c | 31 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_update.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 29 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 31 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_intern.h | 3 |
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 { |