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
path: root/source
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2021-11-03 22:15:13 +0300
committerJoseph Eagar <joeedh@gmail.com>2021-11-03 22:15:13 +0300
commit1dcc741f433367b32ca2b7557bc4160f05e985c6 (patch)
treeb52297a1214bbb0fd65438f573e4c906e79f41b5 /source
parent6cf734a2e5d2496d1b2d33bc7613b56a9f9fc2ec (diff)
temp-sculpt-colors: commit patch
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_data_transfer.h16
-rw-r--r--source/blender/blenkernel/BKE_paint.h6
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h9
-rw-r--r--source/blender/blenkernel/intern/brush.c2
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c7
-rw-r--r--source/blender/blenkernel/intern/paint.c89
-rw-r--r--source/blender/blenkernel/intern/pbvh.c47
-rw-r--r--source/blender/blenloader/intern/versioning_300.c13
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c18
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc44
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt2
-rw-r--r--source/blender/editors/include/UI_icons.h1
-rw-r--r--source/blender/editors/object/object_bake_api.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c190
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_detail.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_dyntopo.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_expand.c13
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c15
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mask.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_expand.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_init.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c42
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c8
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_transform.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c154
-rw-r--r--source/blender/editors/space_node/drawnode.cc3
-rw-r--r--source/blender/gpu/GPU_buffers.h7
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c55
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c4
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c17
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.c6
-rw-r--r--source/blender/windowmanager/intern/wm_toolsystem.c7
m---------source/tools0
41 files changed, 647 insertions, 190 deletions
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index d71cb559911..4a34a7ec2fc 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 22
+#define BLENDER_FILE_SUBVERSION 26
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenkernel/BKE_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h
index a2544e43c3d..e1e8eb598f4 100644
--- a/source/blender/blenkernel/BKE_data_transfer.h
+++ b/source/blender/blenkernel/BKE_data_transfer.h
@@ -54,9 +54,11 @@ enum {
DT_TYPE_UV = 1 << 24,
DT_TYPE_SHARP_FACE = 1 << 25,
DT_TYPE_FREESTYLE_FACE = 1 << 26,
-#define DT_TYPE_MAX 27
+ DT_TYPE_PROPCOL = 1 << 27,
+#define DT_TYPE_MAX 28
- DT_TYPE_VERT_ALL = DT_TYPE_MDEFORMVERT | DT_TYPE_SHAPEKEY | DT_TYPE_SKIN | DT_TYPE_BWEIGHT_VERT,
+ DT_TYPE_VERT_ALL = DT_TYPE_MDEFORMVERT | DT_TYPE_SHAPEKEY | DT_TYPE_SKIN | DT_TYPE_BWEIGHT_VERT |
+ DT_TYPE_PROPCOL,
DT_TYPE_EDGE_ALL = DT_TYPE_SHARP_EDGE | DT_TYPE_SEAM | DT_TYPE_CREASE | DT_TYPE_BWEIGHT_EDGE |
DT_TYPE_FREESTYLE_EDGE,
DT_TYPE_LOOP_ALL = DT_TYPE_VCOL | DT_TYPE_LNOR | DT_TYPE_UV,
@@ -74,7 +76,12 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type);
int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type);
#define DT_DATATYPE_IS_VERT(_dt) \
- ELEM(_dt, DT_TYPE_MDEFORMVERT, DT_TYPE_SHAPEKEY, DT_TYPE_SKIN, DT_TYPE_BWEIGHT_VERT)
+ ELEM(_dt, \
+ DT_TYPE_MDEFORMVERT, \
+ DT_TYPE_SHAPEKEY, \
+ DT_TYPE_SKIN, \
+ DT_TYPE_BWEIGHT_VERT, \
+ DT_TYPE_PROPCOL)
#define DT_DATATYPE_IS_EDGE(_dt) \
ELEM(_dt, \
DT_TYPE_CREASE, \
@@ -94,7 +101,8 @@ enum {
DT_MULTILAYER_INDEX_SHAPEKEY = 1,
DT_MULTILAYER_INDEX_VCOL = 2,
DT_MULTILAYER_INDEX_UV = 3,
- DT_MULTILAYER_INDEX_MAX = 4,
+ DT_MULTILAYER_INDEX_PROPCOL = 4,
+ DT_MULTILAYER_INDEX_MAX = 5,
};
/* Below we keep positive values for real layers idx (generated dynamically). */
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 73413b61456..2d2406fb17b 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -467,6 +467,12 @@ typedef struct SculptSession {
struct KeyBlock *shapekey_active;
struct MPropCol *vcol;
+ float (*f3col)[3];
+ struct MLoopCol *mcol;
+
+ int vcol_domain;
+ int vcol_type;
+
float *vmask;
/* Mesh connectivity maps. */
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 056a7e2d897..929a2d03b97 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -25,6 +25,7 @@
#include "BLI_ghash.h"
/* For embedding CCGKey in iterator. */
+#include "BKE_attribute.h"
#include "BKE_ccg.h"
#ifdef __cplusplus
@@ -358,7 +359,6 @@ typedef struct PBVHVertexIter {
struct MVert *mverts;
int totvert;
const int *vert_indices;
- struct MPropCol *vcol;
float *vmask;
/* bmesh */
@@ -375,7 +375,6 @@ typedef struct PBVHVertexIter {
short *no;
float *fno;
float *mask;
- float *col;
bool visible;
} PBVHVertexIter;
@@ -431,9 +430,6 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
if (vi.vmask) { \
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)) { \
@@ -489,6 +485,9 @@ 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);
+bool BKE_pbvh_get_color_layer(const struct Mesh *me,
+ CustomDataLayer **cl_out,
+ AttributeDomain *attr_out);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index d70b941695e..69773b43173 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1843,6 +1843,8 @@ void BKE_brush_sculpt_reset(Brush *br)
br->density = 1.0f;
br->flag &= ~BRUSH_SPACE_ATTEN;
zero_v3(br->rgb);
+ add_v3_fl(br->rgb, 1.0f);
+ zero_v3(br->secondary_rgb);
break;
case SCULPT_TOOL_SMEAR:
br->alpha = 1.0f;
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index b83621e8b79..c4414f93a87 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -150,6 +150,7 @@ bool BKE_object_data_transfer_get_dttypes_capacity(const int dtdata_types,
case DT_TYPE_UV:
ret = true;
break;
+ case DT_TYPE_PROPCOL:
case DT_TYPE_VCOL:
*r_advanced_mixing = true;
*r_threshold = true;
@@ -230,12 +231,12 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
return CD_FAKE_SHARP;
case DT_TYPE_FREESTYLE_FACE:
return CD_FREESTYLE_FACE;
-
case DT_TYPE_VCOL:
return CD_MLOOPCOL;
case DT_TYPE_LNOR:
return CD_FAKE_LNOR;
-
+ case DT_TYPE_PROPCOL:
+ return CD_PROP_COLOR;
default:
BLI_assert(0);
}
@@ -253,6 +254,8 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
return DT_MULTILAYER_INDEX_UV;
case DT_TYPE_VCOL:
return DT_MULTILAYER_INDEX_VCOL;
+ case DT_TYPE_PROPCOL:
+ return DT_MULTILAYER_INDEX_PROPCOL;
default:
return DT_MULTILAYER_INDEX_INVALID;
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d6030941c6d..53f3692a7bd 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -45,6 +45,7 @@
#include "BLT_translation.h"
+#include "BKE_attribute.h"
#include "BKE_brush.h"
#include "BKE_ccg.h"
#include "BKE_colortools.h"
@@ -1673,7 +1674,31 @@ static void sculpt_update_object(Depsgraph *depsgraph,
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);
+
+ CustomDataLayer *cl;
+ AttributeDomain domain;
+
+ ss->vcol = NULL;
+ ss->mcol = NULL;
+ ss->f3col = NULL;
+
+ if (BKE_pbvh_get_color_layer(me, &cl, &domain)) {
+ if (cl->type == CD_PROP_COLOR) {
+ ss->vcol = cl->data;
+ }
+ else if (cl->type == CD_PROP_FLOAT3) {
+ ss->f3col = cl->data;
+ }
+ else {
+ ss->mcol = cl->data;
+ }
+
+ ss->vcol_domain = domain;
+ ss->vcol_type = cl->type;
+ }
+ else {
+ ss->vcol_type = -1;
+ }
}
/* Sculpt Face Sets. */
@@ -1798,17 +1823,53 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
{
Mesh *orig_me = BKE_object_get_original_mesh(object);
- if (!U.experimental.use_sculpt_vertex_colors) {
- return;
+
+ int types[] = {CD_PROP_COLOR, CD_PROP_FLOAT3, CD_MLOOPCOL};
+ bool has_color = false;
+
+ for (int i = 0; i < 3; i++) {
+ bool ok = CustomData_has_layer(&orig_me->vdata, types[i]);
+ ok = ok || CustomData_has_layer(&orig_me->ldata, types[i]);
+
+ if (ok) {
+ has_color = true;
+ break;
+ }
}
- if (CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) {
- return;
+ CustomDataLayer *cl;
+ if (has_color) {
+ cl = BKE_id_attributes_active_get(&orig_me->id);
+ if (!ELEM(cl->type, CD_PROP_COLOR, CD_MLOOPCOL, CD_PROP_FLOAT3)) {
+ cl = NULL;
+
+ /* find a color layer */
+ for (int step = 0; !cl && step < 2; step++) {
+ CustomData *cdata = step ? &orig_me->ldata : &orig_me->vdata;
+
+ for (int i = 0; i < cdata->totlayer; i++) {
+ if (ELEM(cdata->layers[i].type, CD_PROP_COLOR, CD_MLOOPCOL, CD_PROP_FLOAT3)) {
+ cl = cdata->layers + i;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ cl = NULL; /* no need to update active layer */
+ }
}
+ else {
+ CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
+ cl = orig_me->vdata.layers + CustomData_get_layer_index(&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_ALL_MODES);
+ BKE_mesh_update_customdata_pointers(orig_me, true);
+ }
+
+ if (cl) {
+ BKE_id_attributes_active_set(&orig_me->id, cl);
+ DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
+ }
}
/** \warning Expects a fully evaluated depsgraph. */
@@ -2026,8 +2087,8 @@ void BKE_sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv
const bool is_hidden = (face_sets[face_index] < 0);
/* Avoid creating and modifying the grid_hidden bitmap if the base mesh face is visible and
- * there is not bitmap for the grid. This is because missing grid_hidden implies grid is fully
- * visible. */
+ * there is not bitmap for the grid. This is because missing grid_hidden implies grid is
+ * fully visible. */
if (is_hidden) {
BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg, i);
}
@@ -2066,8 +2127,8 @@ void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object)
object->sculpt->face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
/* NOTE: In theory we could add that on the fly when required by sculpt code.
- * But this then requires proper update of depsgraph etc. For now we play safe, optimization is
- * always possible later if it's worth it. */
+ * But this then requires proper update of depsgraph etc. For now we play safe, optimization
+ * is always possible later if it's worth it. */
BKE_sculpt_mask_layers_ensure(object, mmd);
}
@@ -2075,8 +2136,8 @@ void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object)
BKE_mesh_tessface_clear(mesh);
/* We always need to flush updates from depsgraph here, since at the very least
- * `BKE_sculpt_face_sets_ensure_from_base_mesh_visibility()` will have updated some data layer of
- * the mesh.
+ * `BKE_sculpt_face_sets_ensure_from_base_mesh_visibility()` will have updated some data layer
+ * of the mesh.
*
* All known potential sources of updates:
* - Addition of, or changes to, the `CD_SCULPT_FACE_SETS` data layer
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index ca1fada8c76..0b4b8fa0eed 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -31,6 +31,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "BKE_attribute.h"
#include "BKE_ccg.h"
#include "BKE_mesh.h" /* for BKE_mesh_calc_normals */
#include "BKE_paint.h"
@@ -1258,6 +1259,33 @@ static int pbvh_get_buffers_update_flags(PBVH *UNUSED(pbvh))
return update_flags;
}
+bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_cl, AttributeDomain *r_attr)
+{
+ CustomDataLayer *cl = BKE_id_attributes_active_get((ID *)me);
+ AttributeDomain domain;
+
+ if (!cl || !ELEM(cl->type, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_MLOOPCOL)) {
+ return false;
+ }
+
+ domain = BKE_id_attribute_domain((ID *)me, cl);
+
+ if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
+ return false;
+ }
+
+ if (cl) {
+ *r_cl = cl;
+ *r_attr = domain;
+
+ return true;
+ }
+ else {
+ *r_cl = NULL;
+ return false;
+ }
+}
+
static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict UNUSED(tls))
@@ -1308,17 +1336,23 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
&pbvh->gridkey,
update_flags);
break;
- case PBVH_FACES:
+ case PBVH_FACES: {
+ CustomDataLayer *cl = NULL;
+ AttributeDomain domain;
+
+ BKE_pbvh_get_color_layer(pbvh->mesh, &cl, &domain);
+
GPU_pbvh_mesh_buffers_update(node->draw_buffers,
pbvh->verts,
CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK),
- CustomData_get_layer(pbvh->ldata, CD_MLOOPCOL),
+ cl ? cl->data : NULL,
+ cl ? cl->type : -1,
+ cl ? domain : ATTR_DOMAIN_AUTO,
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;
+ } break;
case PBVH_BMESH:
GPU_pbvh_bmesh_buffers_update(node->draw_buffers,
pbvh->bm,
@@ -1445,7 +1479,9 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
}
if (flag & (PBVH_UpdateColor)) {
- /* Do nothing */
+ for (int i = 0; i < totnode; i++) {
+ nodes[i]->flag |= PBVH_UpdateRedraw | PBVH_UpdateDrawBuffers | PBVH_UpdateColor;
+ }
}
if (flag & (PBVH_UpdateVisibility)) {
@@ -2981,7 +3017,6 @@ 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/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 538634f4c9e..04c0a4ebc79 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -1250,6 +1250,19 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 26)) {
+ LISTBASE_FOREACH (Brush *, br, &bmain->brushes) {
+ /* buggy code in wm_toolsystem broke smear in old files,
+ reset to defaults*/
+ if (br->sculpt_tool == SCULPT_TOOL_SMEAR) {
+ br->alpha = 1.0f;
+ br->spacing = 5;
+ br->flag &= ~BRUSH_ALPHA_PRESSURE;
+ br->flag &= ~BRUSH_SPACE_ATTEN;
+ br->curve_preset = BRUSH_CURVE_SPHERE;
+ }
+ }
+ }
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index f09c019ef8d..7e374ba016c 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -186,12 +186,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
geom = DRW_cache_mesh_surface_vertpaint_get(ob);
}
else {
- if (U.experimental.use_sculpt_vertex_colors) {
- geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
- }
- else {
- geom = DRW_cache_mesh_surface_vertpaint_get(ob);
- }
+ geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
}
}
else {
@@ -272,15 +267,8 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
}
}
else if (color_type == V3D_SHADING_VERTEX_COLOR) {
- if (U.experimental.use_sculpt_vertex_colors) {
- if ((me == NULL) || !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
- color_type = V3D_SHADING_OBJECT_COLOR;
- }
- }
- else {
- if ((me == NULL) || !CustomData_has_layer(&me->ldata, CD_MLOOPCOL)) {
- color_type = V3D_SHADING_OBJECT_COLOR;
- }
+ if ((me == NULL) || !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
}
}
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 18664498d00..f36d3ab21f9 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -374,10 +374,8 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
type = CD_MTFACE;
if (layer == -1) {
- if (U.experimental.use_sculpt_vertex_colors) {
- layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
- type = CD_PROP_COLOR;
- }
+ layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
+ type = CD_PROP_COLOR;
}
if (layer == -1) {
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc
index 2c7770c8e72..21d0dea0537 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc
@@ -74,28 +74,26 @@ static void extract_vcol_init(const MeshRenderData *mr,
}
/* Sculpt Vertex Colors */
- if (U.experimental.use_sculpt_vertex_colors) {
- for (int i = 0; i < 8; i++) {
- if (svcol_layers & (1 << i)) {
- char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
- const char *layer_name = CustomData_get_layer_name(cd_vdata, CD_PROP_COLOR, i);
- GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
-
- BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
- GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- if (i == CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR)) {
- GPU_vertformat_alias_add(&format, "c");
- }
- if (i == CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR)) {
- GPU_vertformat_alias_add(&format, "ac");
- }
- /* Gather number of auto layers. */
- /* We only do `vcols` that are not overridden by `uvs`. */
- if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, layer_name) == -1) {
- BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
- GPU_vertformat_alias_add(&format, attr_name);
- }
+ for (int i = 0; i < 8; i++) {
+ if (svcol_layers & (1 << i)) {
+ char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
+ const char *layer_name = CustomData_get_layer_name(cd_vdata, CD_PROP_COLOR, i);
+ GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
+
+ BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
+ GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ if (i == CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR)) {
+ GPU_vertformat_alias_add(&format, "c");
+ }
+ if (i == CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR)) {
+ GPU_vertformat_alias_add(&format, "ac");
+ }
+ /* Gather number of auto layers. */
+ /* We only do `vcols` that are not overridden by `uvs`. */
+ if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, layer_name) == -1) {
+ BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
+ GPU_vertformat_alias_add(&format, attr_name);
}
}
}
@@ -140,7 +138,7 @@ static void extract_vcol_init(const MeshRenderData *mr,
}
}
- if (svcol_layers & (1 << i) && U.experimental.use_sculpt_vertex_colors) {
+ if (svcol_layers & (1 << i)) {
if (mr->extract_type == MR_EXTRACT_BMESH) {
int cd_ofs = CustomData_get_n_offset(cd_vdata, CD_PROP_COLOR, i);
BMIter f_iter;
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 702fd2e375a..bd0bc4c3a11 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -763,9 +763,11 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
brush.sculpt.mask
brush.sculpt.multiplane_scrape
brush.sculpt.nudge
+ brush.sculpt.paint
brush.sculpt.pinch
brush.sculpt.pose
brush.sculpt.rotate
+ brush.sculpt.smear
brush.sculpt.scrape
brush.sculpt.simplify
brush.sculpt.smooth
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index ddd9ca4a98c..ebc26095940 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -919,6 +919,7 @@ DEF_ICON_COLOR(BRUSH_TEXFILL)
DEF_ICON_COLOR(BRUSH_TEXMASK)
DEF_ICON_COLOR(BRUSH_THUMB)
DEF_ICON_COLOR(BRUSH_ROTATE)
+DEF_ICON_COLOR(BRUSH_PAINT)
/* grease pencil sculpt */
DEF_ICON_COLOR(GPBRUSH_SMOOTH)
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 0a2df655395..adb6497aed6 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -451,7 +451,7 @@ static bool bake_object_check(ViewLayer *view_layer,
if (target == R_BAKE_TARGET_VERTEX_COLORS) {
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
- const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
+ const bool mcol_valid = (mcol != NULL);
MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
if (mloopcol == NULL && !mcol_valid) {
BKE_reportf(reports,
@@ -937,7 +937,7 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re
Mesh *me = ob->data;
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
- const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
+ const bool mcol_valid = (mcol != NULL);
MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
if (mloopcol == NULL && !mcol_valid) {
BKE_report(reports, RPT_ERROR, "No vertex colors layer found to bake to");
@@ -1092,7 +1092,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
{
Mesh *me = ob->data;
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
- const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
+ const bool mcol_valid = (mcol != NULL);
MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
const int num_channels = targets->num_channels;
const float *result = targets->result;
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index da627c6b7db..17bd101554a 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -392,7 +392,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
}
/* End undo. */
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
/* Ensure that edges and faces get hidden as well (not used by
* sculpt but it looks wrong when entering editmode otherwise). */
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index e65d6ce2d48..e7e9eb9e509 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -189,7 +189,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
if (nodes) {
MEM_freeN(nodes);
@@ -723,7 +723,7 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext)
operation->sculpt_gesture_end(C, sgcontext);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(CTX_data_active_object(C));
SCULPT_tag_update_overlays(C);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 7bde864e73f..84f1907fb11 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -46,6 +46,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_attribute.h"
#include "BKE_brush.h"
#include "BKE_ccg.h"
#include "BKE_colortools.h"
@@ -154,19 +155,141 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, int index)
return NULL;
}
-const float *SCULPT_vertex_color_get(SculptSession *ss, int index)
+bool SCULPT_has_colors(const SculptSession *ss)
+{
+ return ss->vcol || ss->mcol || ss->f3col;
+}
+
+bool SCULPT_vertex_color_get(SculptSession *ss, int index, float out[4])
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ if (!(ss->vcol || ss->mcol || ss->f3col)) {
+ zero_v4(out);
+ return false;
+ }
+
+ if (ss->vcol_domain == ATTR_DOMAIN_CORNER) {
+ zero_v4(out);
+
+ int count = ss->pmap[index].count;
+ for (int i = 0; i < count; i++) {
+ MPoly *mp = ss->mpoly + ss->pmap[index].indices[i];
+ MLoop *ml = ss->mloop + mp->loopstart;
+ int li = mp->loopstart;
+
+ for (int j = 0; j < mp->totloop; j++, li++, ml++) {
+ if (ml->v != index) {
+ continue;
+ }
+
+ if (ss->vcol_type == CD_MLOOPCOL) {
+ MLoopCol *col = ss->mcol + li;
+
+ float tmp[4];
+
+ rgba_uchar_to_float(tmp, (const char *)col);
+ add_v4_v4(out, tmp);
+ }
+ else if (ss->vcol_type == CD_PROP_FLOAT3) {
+ add_v3_v3(out, ss->f3col[li]);
+ out[3] += 1.0f;
+ }
+ else {
+ add_v4_v4(out, ss->vcol[li].color);
+ }
+ }
+ }
+
+ if (count) {
+ mul_v4_fl(out, 1.0f / (float)count);
+ }
+ }
+ else {
+ if (ss->vcol_type == CD_MLOOPCOL) {
+ MLoopCol *col = ss->mcol + index;
+
+ float tmp[4];
+ rgba_uchar_to_float(tmp, (const char *)col);
+ copy_v4_v4(out, tmp);
+ }
+ else if (ss->vcol_type == CD_PROP_FLOAT3) {
+ copy_v3_v3(out, ss->f3col[index]);
+ out[3] = 1.0f;
+ }
+ else {
+ copy_v4_v4(out, ss->vcol[index].color);
+ }
+ }
+
+ return ss->vcol || ss->mcol || ss->f3col;
+ case PBVH_BMESH:
+ case PBVH_GRIDS:
+ break;
+ }
+
+ return false;
+}
+
+void SCULPT_vertex_color_set(SculptSession *ss, int index, float color[4])
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
- if (ss->vcol) {
- return ss->vcol[index].color;
+ if (!(ss->vcol || ss->mcol || ss->f3col)) {
+ return;
+ }
+
+ if (ss->vcol_domain == ATTR_DOMAIN_CORNER) {
+ int count = ss->pmap[index].count;
+ for (int i = 0; i < count; i++) {
+ MPoly *mp = ss->mpoly + ss->pmap[index].indices[i];
+ MLoop *ml = ss->mloop + mp->loopstart;
+ int li = mp->loopstart;
+
+ for (int j = 0; j < mp->totloop; j++, li++, ml++) {
+ if (ml->v != index) {
+ continue;
+ }
+
+ if (ss->vcol_type == CD_MLOOPCOL) {
+ MLoopCol *col = ss->mcol + li;
+
+ col->r = (unsigned char)(color[0] * 255.0f);
+ col->g = (unsigned char)(color[1] * 255.0f);
+ col->b = (unsigned char)(color[2] * 255.0f);
+ col->a = (unsigned char)(color[3] * 255.0f);
+ }
+ else if (ss->vcol_type == CD_PROP_FLOAT3) {
+ copy_v3_v3(ss->f3col[li], color);
+ }
+ else {
+ copy_v4_v4(ss->vcol[li].color, color);
+ }
+ }
+ }
+ }
+ else {
+ if (ss->vcol_type == CD_MLOOPCOL) {
+ MLoopCol *col = ss->mcol + index;
+
+ col->r = (unsigned char)(color[0] * 255.0f);
+ col->g = (unsigned char)(color[1] * 255.0f);
+ col->b = (unsigned char)(color[2] * 255.0f);
+ col->a = (unsigned char)(color[3] * 255.0f);
+ }
+ else if (ss->vcol_type == CD_PROP_FLOAT3) {
+ copy_v3_v3(ss->f3col[index], color);
+ }
+ else {
+ copy_v4_v4(ss->vcol[index].color, color);
+ }
}
+
break;
case PBVH_BMESH:
case PBVH_GRIDS:
break;
}
- return NULL;
}
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
@@ -1506,7 +1629,10 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
*vd.mask = orig_data.mask;
}
else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
- copy_v4_v4(vd.col, orig_data.col);
+ float col[4];
+ SCULPT_vertex_color_get(ss, vd.index, col);
+
+ copy_v4_v4(col, orig_data.col);
}
if (vd.mvert) {
@@ -6584,9 +6710,6 @@ bool SCULPT_mode_poll(bContext *C)
bool SCULPT_vertex_colors_poll(bContext *C)
{
- if (!U.experimental.use_sculpt_vertex_colors) {
- return false;
- }
return SCULPT_mode_poll(C);
}
@@ -7285,7 +7408,8 @@ static bool sculpt_needs_connectivity_info(const Sculpt *sd,
return ((stroke_mode == BRUSH_STROKE_SMOOTH) || (ss && ss->cache && ss->cache->alt_smooth) ||
(brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || (brush->autosmooth_factor > 0) ||
((brush->sculpt_tool == SCULPT_TOOL_MASK) && (brush->mask_tool == BRUSH_MASK_SMOOTH)) ||
- (brush->sculpt_tool == SCULPT_TOOL_POSE) ||
+ (brush->sculpt_tool == SCULPT_TOOL_POSE) || (brush->sculpt_tool == SCULPT_TOOL_PAINT) ||
+ (brush->sculpt_tool == SCULPT_TOOL_SMEAR) ||
(brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) ||
(brush->sculpt_tool == SCULPT_TOOL_SLIDE_RELAX) ||
(brush->sculpt_tool == SCULPT_TOOL_CLOTH) || (brush->sculpt_tool == SCULPT_TOOL_SMEAR) ||
@@ -8022,7 +8146,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
SCULPT_cache_free(ss->cache);
ss->cache = NULL;
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
@@ -8272,7 +8396,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
/* Finish undo. */
BM_log_all_added(ss->bm, ss->bm_log);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
break;
case PBVH_FACES:
@@ -8434,7 +8558,7 @@ void ED_object_sculptmode_enter_ex(Main *bmain,
SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob);
if (has_undo) {
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
}
}
else {
@@ -8697,15 +8821,25 @@ static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
+bool SCULPT_convert_colors_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+
+ bool ok = ob && ob->data && ob->type == OB_MESH;
+ ok = ok && ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_OBJECT);
+
+ return ok;
+}
+
static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Sculpt Vertex Color to Vertex Color";
- ot->description = "Copy the Sculpt Vertex Color to a regular color layer";
+ ot->description = "Copy to active face corner color attribute";
ot->idname = "SCULPT_OT_vertex_to_loop_colors";
/* api callbacks */
- ot->poll = SCULPT_vertex_colors_poll;
+ ot->poll = SCULPT_convert_colors_poll;
ot->exec = vertex_to_loop_colors_exec;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8764,11 +8898,11 @@ static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Vertex Color to Sculpt Vertex Color";
- ot->description = "Copy the active loop color layer to the vertex color";
+ ot->description = "Load from active face corner color attribute";
ot->idname = "SCULPT_OT_loop_to_vertex_colors";
/* api callbacks */
- ot->poll = SCULPT_vertex_colors_poll;
+ ot->poll = SCULPT_convert_colors_poll;
ot->exec = loop_to_vertex_colors_exec;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8784,8 +8918,9 @@ static int sculpt_sample_color_invoke(bContext *C,
Brush *brush = BKE_paint_brush(&sd->paint);
SculptSession *ss = ob->sculpt;
int active_vertex = SCULPT_active_vertex_get(ss);
- const float *active_vertex_color = SCULPT_vertex_color_get(ss, active_vertex);
- if (!active_vertex_color) {
+ float active_vertex_color[4];
+
+ if (!SCULPT_vertex_color_get(ss, active_vertex, active_vertex_color)) {
return OPERATOR_CANCELLED;
}
@@ -9180,7 +9315,9 @@ static bool sculpt_mask_by_color_contiguous_floodfill_cb(
SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
{
MaskByColorContiguousFloodFillData *data = userdata;
- const float *current_color = SCULPT_vertex_color_get(ss, to_v);
+ float current_color[4];
+ SCULPT_vertex_color_get(ss, to_v, current_color);
+
float new_vertex_mask = sculpt_mask_by_color_delta_get(
current_color, data->initial_color, data->threshold, data->invert);
data->new_mask[to_v] = new_vertex_mask;
@@ -9219,7 +9356,7 @@ static void sculpt_mask_by_color_contiguous(Object *object,
ffd.threshold = threshold;
ffd.invert = invert;
ffd.new_mask = new_mask;
- copy_v3_v3(ffd.initial_color, SCULPT_vertex_color_get(ss, vertex));
+ SCULPT_vertex_color_get(ss, vertex, ffd.initial_color);
SCULPT_floodfill_execute(ss, &flood, sculpt_mask_by_color_contiguous_floodfill_cb, &ffd);
SCULPT_floodfill_free(&flood);
@@ -9261,12 +9398,17 @@ static void do_mask_by_color_task_cb(void *__restrict userdata,
const float threshold = data->mask_by_color_threshold;
const bool invert = data->mask_by_color_invert;
const bool preserve_mask = data->mask_by_color_preserve_mask;
- const float *active_color = SCULPT_vertex_color_get(ss, data->mask_by_color_vertex);
+ float active_color[4];
+
+ SCULPT_vertex_color_get(ss, data->mask_by_color_vertex, active_color);
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
+ float col[4];
+ SCULPT_vertex_color_get(ss, vd.index, col);
+
const float current_mask = *vd.mask;
- const float new_mask = sculpt_mask_by_color_delta_get(active_color, vd.col, threshold, invert);
+ const float new_mask = sculpt_mask_by_color_delta_get(active_color, col, threshold, invert);
*vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
if (current_mask == *vd.mask) {
@@ -9324,7 +9466,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven
return OPERATOR_CANCELLED;
}
- if (!ss->vcol) {
+ if (!SCULPT_has_colors(ss)) {
return OPERATOR_CANCELLED;
}
@@ -9353,7 +9495,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven
}
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index a53a2126af4..1db2dd638f0 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -1519,7 +1519,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
SCULPT_filter_cache_free(ss);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c
index 188bb0a88eb..9cea7aa3e72 100644
--- a/source/blender/editors/sculpt_paint/sculpt_detail.c
+++ b/source/blender/editors/sculpt_paint/sculpt_detail.c
@@ -123,7 +123,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
}
MEM_SAFE_FREE(nodes);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
/* Force rebuild of PBVH for better BB placement. */
SCULPT_pbvh_clear(ob);
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index ae6dcbdbff4..6a179e0f596 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -290,7 +290,7 @@ void sculpt_dynamic_topology_disable_with_undo(Main *bmain,
}
SCULPT_dynamic_topology_disable_ex(bmain, depsgraph, scene, ob, NULL);
if (use_undo) {
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
}
}
}
@@ -310,7 +310,7 @@ static void sculpt_dynamic_topology_enable_with_undo(Main *bmain,
SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob);
if (use_undo) {
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
}
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c
index 40874375772..20af95ba3cc 100644
--- a/source/blender/editors/sculpt_paint/sculpt_expand.c
+++ b/source/blender/editors/sculpt_paint/sculpt_expand.c
@@ -1144,7 +1144,7 @@ static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *exp
PBVHNode *node = nodes[n];
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
- copy_v4_v4(vd.col, expand_cache->original_colors[vd.index]);
+ SCULPT_vertex_color_set(ss, vd.index, expand_cache->original_colors[vd.index]);
}
BKE_pbvh_vertex_iter_end;
BKE_pbvh_node_mark_redraw(node);
@@ -1208,7 +1208,7 @@ static void sculpt_expand_cancel(bContext *C, wmOperator *UNUSED(op))
sculpt_expand_restore_original_state(C, ob, ss->expand_cache);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
sculpt_expand_cache_free(ss);
}
@@ -1303,7 +1303,7 @@ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) {
float initial_color[4];
- copy_v4_v4(initial_color, vd.col);
+ SCULPT_vertex_color_get(ss, vd.index, initial_color);
const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.index);
float fade;
@@ -1330,7 +1330,8 @@ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata,
continue;
}
- copy_v4_v4(vd.col, final_color);
+ SCULPT_vertex_color_set(ss, vd.index, final_color);
+
any_changed = true;
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -1386,7 +1387,7 @@ static void sculpt_expand_original_state_store(Object *ob, ExpandCache *expand_c
if (expand_cache->target == SCULPT_EXPAND_TARGET_COLORS) {
expand_cache->original_colors = MEM_malloc_arrayN(totvert, sizeof(float[4]), "initial colors");
for (int i = 0; i < totvert; i++) {
- copy_v4_v4(expand_cache->original_colors[i], SCULPT_vertex_color_get(ss, i));
+ SCULPT_vertex_color_get(ss, i, expand_cache->original_colors[i]);
}
}
}
@@ -1542,7 +1543,7 @@ static void sculpt_expand_finish(bContext *C)
{
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
/* Tag all nodes to redraw to avoid artifacts after the fast partial updates. */
PBVHNode **nodes;
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index bdbdb75732a..027cedf3b01 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -412,7 +412,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
MEM_SAFE_FREE(nodes);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
SCULPT_tag_update_overlays(C);
@@ -749,7 +749,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
break;
}
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
SCULPT_visibility_sync_all_face_sets_to_vertices(ob);
@@ -939,7 +939,7 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
/* Sync face sets visibility and vertex visibility. */
SCULPT_visibility_sync_all_face_sets_to_vertices(ob);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_update_visibility(nodes[i]);
@@ -1365,7 +1365,7 @@ static void sculpt_face_set_edit_modify_face_sets(Object *ob,
SCULPT_undo_push_begin(ob, "face set edit");
SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS);
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
face_set_edit_do_post_visibility_updates(ob, nodes, totnode);
MEM_freeN(nodes);
}
@@ -1393,7 +1393,7 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C,
}
SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
MEM_freeN(nodes);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
index 4b49bf2cefb..7ebc0630c14 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -197,12 +197,19 @@ static void color_filter_task_cb(void *__restrict userdata,
fade = clamp_f(fade, -1.0f, 1.0f);
float smooth_color[4];
SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
- blend_color_interpolate_float(final_color, vd.col, smooth_color, fade);
+
+ float col[4];
+ SCULPT_vertex_color_get(ss, vd.index, col);
+
+ blend_color_interpolate_float(final_color, col, smooth_color, fade);
break;
}
}
- copy_v3_v3(vd.col, final_color);
+ float col[4];
+ SCULPT_vertex_color_get(ss, vd.index, col);
+
+ copy_v3_v3(col, final_color);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -221,7 +228,7 @@ static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent
float filter_strength = RNA_float_get(op->ptr, "strength");
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
SCULPT_filter_cache_free(ss);
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COLOR);
return OPERATOR_FINISHED;
@@ -285,7 +292,7 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
- if (!ss->vcol) {
+ if (!SCULPT_has_colors(ss)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
index 10f141e2311..29e5eafc45f 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
@@ -255,7 +255,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
MEM_SAFE_FREE(nodes);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
SCULPT_tag_update_overlays(C);
@@ -470,7 +470,7 @@ static int sculpt_dirty_mask_exec(bContext *C, wmOperator *op)
BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index 3fc1a7674f7..7abea1ba538 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -615,7 +615,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
SCULPT_filter_cache_free(ss);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 696c3332a2b..5ef62b0dacb 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -98,10 +98,14 @@ char SCULPT_mesh_symmetry_xyz_get(Object *object);
void SCULPT_vertex_random_access_ensure(struct SculptSession *ss);
int SCULPT_vertex_count_get(struct SculptSession *ss);
+
const float *SCULPT_vertex_co_get(struct SculptSession *ss, int index);
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]);
float SCULPT_vertex_mask_get(struct SculptSession *ss, int index);
-const float *SCULPT_vertex_color_get(SculptSession *ss, int index);
+
+bool SCULPT_vertex_color_get(SculptSession *ss, int index, float out[4]);
+void SCULPT_vertex_color_set(SculptSession *ss, int index, float color[4]);
+bool SCULPT_has_colors(const SculptSession *ss);
const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index);
void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]);
@@ -1306,8 +1310,8 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
SculptUndoNode *SCULPT_undo_get_node(PBVHNode *node);
SculptUndoNode *SCULPT_undo_get_first_node(void);
void SCULPT_undo_push_begin(struct Object *ob, const char *name);
-void SCULPT_undo_push_end(void);
-void SCULPT_undo_push_end_ex(const bool use_nested_undo);
+void SCULPT_undo_push_end(struct Object *ob);
+void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo);
void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]);
diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
index 9b06b2ee5d5..9f19341df29 100644
--- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
+++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
@@ -98,7 +98,7 @@ static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
}
SCULPT_filter_cache_free(ss);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
ED_workspace_status_text(C, NULL);
}
@@ -253,7 +253,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
SCULPT_filter_cache_free(ss);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
ED_workspace_status_text(C, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_init.c b/source/blender/editors/sculpt_paint/sculpt_mask_init.c
index 0c383cdf035..a3b431bd6ce 100644
--- a/source/blender/editors/sculpt_paint/sculpt_mask_init.c
+++ b/source/blender/editors/sculpt_paint/sculpt_mask_init.c
@@ -166,7 +166,7 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
multires_stitch_grids(ob);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
MEM_SAFE_FREE(nodes);
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index 936ebb7e8f7..3cfdf6dc710 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -101,7 +101,11 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
float smooth_color[4];
SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
- blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
+ float col[4];
+
+ SCULPT_vertex_color_get(ss, vd.index, col);
+ blend_color_interpolate_float(col, col, smooth_color, fade);
+ SCULPT_vertex_color_set(ss, vd.index, col);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -193,9 +197,11 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
/* Final mix over the original color using brush alpha. */
mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
- IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
-
- CLAMP4(vd.col, 0.0f, 1.0f);
+ float col[4];
+ SCULPT_vertex_color_get(ss, vd.index, col);
+ IMB_blend_color_float(col, orig_data.col, buffer_color, brush->blend);
+ CLAMP4(col, 0.0f, 1.0f);
+ SCULPT_vertex_color_set(ss, vd.index, col);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -230,7 +236,10 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata,
continue;
}
- add_v4_v4(swptd->color, vd.col);
+ float col[4];
+ SCULPT_vertex_color_get(ss, vd.index, col);
+
+ add_v4_v4(swptd->color, col);
swptd->tot_samples++;
}
BKE_pbvh_vertex_iter_end;
@@ -252,7 +261,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
Brush *brush = BKE_paint_brush(&sd->paint);
SculptSession *ss = ob->sculpt;
- if (!ss->vcol) {
+ if (!SCULPT_has_colors(ss)) {
return;
}
@@ -305,7 +314,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BKE_pbvh_parallel_range_settings(&settings, false, totnode);
BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings);
return;
}
@@ -361,7 +370,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BKE_pbvh_parallel_range_settings(&settings, false, totnode);
BLI_task_parallel_range(0, totnode, &data, do_paint_brush_task_cb_ex, &settings);
}
@@ -433,7 +442,10 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
+ float col[4];
+ SCULPT_vertex_color_get(ss, vd.index, col);
+ blend_color_interpolate_float(col, ss->cache->prev_colors[vd.index], interp_color, fade);
+ SCULPT_vertex_color_set(ss, vd.index, col);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -451,7 +463,10 @@ static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- copy_v4_v4(ss->cache->prev_colors[vd.index], SCULPT_vertex_color_get(ss, vd.index));
+ float tmp[4] = {0};
+
+ SCULPT_vertex_color_get(ss, vd.index, tmp);
+ copy_v4_v4(ss->cache->prev_colors[vd.index], tmp);
}
BKE_pbvh_vertex_iter_end;
}
@@ -461,7 +476,7 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
Brush *brush = BKE_paint_brush(&sd->paint);
SculptSession *ss = ob->sculpt;
- if (!ss->vcol) {
+ if (!SCULPT_has_colors(ss)) {
return;
}
@@ -471,7 +486,10 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
if (!ss->cache->prev_colors) {
ss->cache->prev_colors = MEM_callocN(sizeof(float[4]) * totvert, "prev colors");
for (int i = 0; i < totvert; i++) {
- copy_v4_v4(ss->cache->prev_colors[i], SCULPT_vertex_color_get(ss, i));
+ float tmp[4] = {0};
+
+ SCULPT_vertex_color_get(ss, i, tmp);
+ copy_v4_v4(ss->cache->prev_colors[i], tmp);
}
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 38165b7622f..e364a413345 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -197,7 +197,11 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
- add_v4_v4(avg, SCULPT_vertex_color_get(ss, ni.index));
+ float tmp[4] = {0};
+
+ SCULPT_vertex_color_get(ss, ni.index, tmp);
+
+ add_v4_v4(avg, tmp);
total++;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -206,7 +210,7 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index
mul_v4_v4fl(result, avg, 1.0f / total);
}
else {
- copy_v4_v4(result, SCULPT_vertex_color_get(ss, index));
+ SCULPT_vertex_color_get(ss, index, result);
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index 3c0a591e8a7..d85404ae517 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -250,7 +250,7 @@ void ED_sculpt_end_transform(struct bContext *C, Object *ob)
* undo system works separate from regular undo and this is require to properly
* finish an undo step also when canceling. */
const bool use_nested_undo = true;
- SCULPT_undo_push_end_ex(use_nested_undo);
+ SCULPT_undo_push_end_ex(ob, use_nested_undo);
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 501a1e53276..a01dcc91d5d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -40,6 +40,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "BKE_attribute.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
@@ -47,6 +48,7 @@
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -109,13 +111,36 @@
* End of dynamic topology and symmetrize in this mode are handled in a special
* manner as well. */
+#define NO_ACTIVE_LAYER ATTR_DOMAIN_AUTO
+
typedef struct UndoSculpt {
ListBase nodes;
size_t undo_size;
} UndoSculpt;
+typedef struct SculptAttrRef {
+ AttributeDomain domain;
+ int type;
+ char name[MAX_CUSTOMDATA_LAYER_NAME];
+ bool was_set;
+} SculptAttrRef;
+
+typedef struct SculptUndoStep {
+ UndoStep step;
+ /* NOTE: will split out into list for multi-object-sculpt-mode. */
+ UndoSculpt data;
+
+ // active vcol layer
+ SculptAttrRef active_attr_start;
+ SculptAttrRef active_attr_end;
+
+ bContext *C;
+} SculptUndoStep;
+
static UndoSculpt *sculpt_undo_get_nodes(void);
+static bool sculpt_attr_ref_equals(SculptAttrRef *a, SculptAttrRef *b);
+static void sculpt_save_active_attr(Object *ob, SculptAttrRef *attr);
static void update_cb(PBVHNode *node, void *rebuild)
{
@@ -328,14 +353,25 @@ static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode)
Object *ob = OBACT(view_layer);
SculptSession *ss = ob->sculpt;
+ if (!ss->pmap) {
+ Mesh *me = BKE_object_get_original_mesh(ob);
+
+ BKE_mesh_vert_poly_map_create(
+ &ss->pmap, &ss->pmap_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
+ }
+
if (unode->maxvert) {
/* regular mesh restore */
int *index = unode->index;
MVert *mvert = ss->mvert;
- MPropCol *vcol = ss->vcol;
for (int i = 0; i < unode->totvert; i++) {
- copy_v4_v4(vcol[index[i]].color, unode->col[i]);
+ float tmp[4];
+
+ SCULPT_vertex_color_get(ss, index[i], tmp);
+ SCULPT_vertex_color_set(ss, index[i], unode->col[i]);
+ copy_v4_v4(unode->col[i], tmp);
+
mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
}
}
@@ -859,6 +895,9 @@ static void sculpt_undo_free_list(ListBase *lb)
if (unode->co) {
MEM_freeN(unode->co);
}
+ if (unode->col) {
+ MEM_freeN(unode->col);
+ }
if (unode->no) {
MEM_freeN(unode->no);
}
@@ -1033,7 +1072,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt
usculpt->undo_size += alloc_size;
/* FIXME: Should explain why this is allocated here, to be freed in
- * `SCULPT_undo_push_end_ex()`? */
+ * `SCULPT_undo_push_end_ex(ob)`? */
alloc_size = sizeof(*unode->no) * (size_t)allvert;
unode->no = MEM_callocN(alloc_size, "SculptUndoNode.no");
usculpt->undo_size += alloc_size;
@@ -1158,7 +1197,10 @@ static void sculpt_undo_store_color(Object *ob, SculptUndoNode *unode)
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) {
- copy_v4_v4(unode->col[vd.i], vd.col);
+ float col[4];
+ SCULPT_vertex_color_get(ss, vd.index, col);
+
+ copy_v4_v4(unode->col[vd.i], col);
}
BKE_pbvh_vertex_iter_end;
}
@@ -1378,10 +1420,36 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
return unode;
}
+static bool sculpt_attr_ref_equals(SculptAttrRef *a, SculptAttrRef *b)
+{
+ return a->domain == b->domain && a->type == b->type && STREQ(a->name, b->name);
+}
+
+static void sculpt_save_active_attr(Object *ob, SculptAttrRef *attr)
+{
+ Mesh *me = BKE_object_get_original_mesh(ob);
+ CustomDataLayer *cl;
+
+ if (ob && me && (cl = BKE_id_attributes_active_get((ID *)me))) {
+ attr->domain = BKE_id_attribute_domain((ID *)me, cl);
+ BLI_strncpy(attr->name, cl->name, sizeof(attr->name));
+ attr->type = cl->type;
+ }
+ else {
+ attr->domain = NO_ACTIVE_LAYER;
+ attr->name[0] = 0;
+ }
+
+ attr->was_set = true;
+}
+
void SCULPT_undo_push_begin(Object *ob, const char *name)
{
UndoStack *ustack = ED_undo_stack_get();
+ SculptUndoStep *us;
+ if (!ob->sculpt->pmap && ob->sculpt->pbvh && BKE_pbvh_type(ob->sculpt->pbvh) == PBVH_FACES) {
+ }
if (ob != NULL) {
/* If possible, we need to tag the object and its geometry data as 'changed in the future' in
* the previous undo step if it's a memfile one. */
@@ -1392,15 +1460,20 @@ void SCULPT_undo_push_begin(Object *ob, const char *name)
/* Special case, we never read from this. */
bContext *C = NULL;
- BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT);
+ us = (SculptUndoStep *)BKE_undosys_step_push_init_with_type(
+ ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT);
+
+ if (!us->active_attr_start.was_set) {
+ sculpt_save_active_attr(ob, &us->active_attr_start);
+ }
}
-void SCULPT_undo_push_end(void)
+void SCULPT_undo_push_end(Object *ob)
{
- SCULPT_undo_push_end_ex(false);
+ SCULPT_undo_push_end_ex(ob, false);
}
-void SCULPT_undo_push_end_ex(const bool use_nested_undo)
+void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo)
{
UndoSculpt *usculpt = sculpt_undo_get_nodes();
SculptUndoNode *unode;
@@ -1424,28 +1497,53 @@ void SCULPT_undo_push_end_ex(const bool use_nested_undo)
}
WM_file_tag_modified();
}
+
+ UndoStack *ustack = ED_undo_stack_get();
+ SculptUndoStep *us = (SculptUndoStep *)BKE_undosys_stack_init_or_active_with_type(
+ ustack, BKE_UNDOSYS_TYPE_SCULPT);
+
+ sculpt_save_active_attr(ob, &us->active_attr_end);
}
/* -------------------------------------------------------------------- */
/** \name Implements ED Undo System
* \{ */
-typedef struct SculptUndoStep {
- UndoStep step;
- /* NOTE: will split out into list for multi-object-sculpt-mode. */
- UndoSculpt data;
-} SculptUndoStep;
+static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr)
+{
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = BKE_object_get_original_mesh(ob);
+
+ if (attr->domain == NO_ACTIVE_LAYER) {
+ // from reading the code, it appears you cannot set
+ // the active layer to NULL, so don't worry about it.
+ // BKE_id_attributes_active_set(&me->id, NULL);
+ return;
+ }
-static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p)
+ SculptAttrRef existing;
+ sculpt_save_active_attr(ob, &existing);
+
+ if (!sculpt_attr_ref_equals(&existing, attr) && ob->sculpt && ob->sculpt->pbvh) {
+ BKE_pbvh_update_vertex_data(ob->sculpt->pbvh, PBVH_UpdateColor);
+ }
+
+ CustomDataLayer *cl;
+ cl = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain);
+
+ if (cl) {
+ BKE_id_attributes_active_set(&me->id, cl);
+ }
+}
+
+static void sculpt_undosys_step_encode_init(struct bContext *C, UndoStep *us_p)
{
SculptUndoStep *us = (SculptUndoStep *)us_p;
/* Dummy, memory is cleared anyway. */
BLI_listbase_clear(&us->data.nodes);
}
-static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C),
- struct Main *bmain,
- UndoStep *us_p)
+static bool sculpt_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p)
{
/* Dummy, encoding is done along the way by adding tiles
* to the current 'SculptUndoStep' added by encode_init. */
@@ -1472,12 +1570,16 @@ static void sculpt_undosys_step_decode_undo_impl(struct bContext *C,
BLI_assert(us->step.is_applied == true);
sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
us->step.is_applied = false;
+
+ // sculpt_undo_load_vcol_layer(C, us);
}
static void sculpt_undosys_step_decode_redo_impl(struct bContext *C,
Depsgraph *depsgraph,
SculptUndoStep *us)
{
+ // sculpt_undo_load_vcol_layer(C, us);
+
BLI_assert(us->step.is_applied == false);
sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
us->step.is_applied = true;
@@ -1500,10 +1602,18 @@ static void sculpt_undosys_step_decode_undo(struct bContext *C,
while ((us_iter != us) || (!is_final && us_iter == us)) {
BLI_assert(us_iter->step.type == us->step.type); /* Previous loop ensures this. */
+
+ sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_attr_start);
sculpt_undosys_step_decode_undo_impl(C, depsgraph, us_iter);
+ // sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_attr_start);
+
if (us_iter == us) {
+ if (us_iter->step.prev && us_iter->step.prev->type == BKE_UNDOSYS_TYPE_SCULPT) {
+ sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter->step.prev)->active_attr_end);
+ }
break;
}
+
us_iter = (SculptUndoStep *)us_iter->step.prev;
}
}
@@ -1520,8 +1630,14 @@ static void sculpt_undosys_step_decode_redo(struct bContext *C,
us_iter = (SculptUndoStep *)us_iter->step.prev;
}
while (us_iter && (us_iter->step.is_applied == false)) {
+ sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_attr_start);
sculpt_undosys_step_decode_redo_impl(C, depsgraph, us_iter);
+
if (us_iter == us) {
+ sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_attr_end);
+ // if (us_iter->step.next && us_iter->step.next->type == BKE_UNDOSYS_TYPE_SCULPT) {
+ // sculpt_undo_load_vcol_layer(C, (SculptUndoStep *)us_iter->step.next);
+ //}
break;
}
us_iter = (SculptUndoStep *)us_iter->step.next;
@@ -1595,7 +1711,7 @@ void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
void ED_sculpt_undo_geometry_end(struct Object *ob)
{
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY);
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(ob);
}
/* Export for ED_undo_sys. */
@@ -1722,7 +1838,7 @@ void ED_sculpt_undo_push_multires_mesh_end(bContext *C, const char *str)
SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY);
geometry_unode->geometry_clear_pbvh = false;
- SCULPT_undo_push_end();
+ SCULPT_undo_push_end(object);
}
/** \} */
diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc
index 4b859de0ac9..a3fd8ab5f4a 100644
--- a/source/blender/editors/space_node/drawnode.cc
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -977,8 +977,7 @@ static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, Pointer
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- if (U.experimental.use_sculpt_vertex_colors &&
- RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
+ if (RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
uiItemPointerR(
layout, ptr, "layer_name", &dataptr, "sculpt_vertex_colors", "", ICON_GROUP_VCOL);
}
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index b770bde65fc..eedc3c240f9 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -25,6 +25,8 @@
#include <stddef.h>
+#include "BKE_attribute.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -78,11 +80,12 @@ enum {
void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const struct MVert *mvert,
const float *vmask,
- const struct MLoopCol *vcol,
+ const void *vcol_data,
+ const int vcol_type,
+ const AttributeDomain vcol_domain,
const int *sculpt_face_sets,
const int face_sets_color_seed,
const int face_sets_color_default,
- const struct MPropCol *vtcol,
const int update_flags);
void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 43483916236..81d8d073b30 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -41,7 +41,9 @@
#include "DNA_userdef_types.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_attribute.h"
#include "BKE_ccg.h"
+#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
@@ -208,18 +210,25 @@ static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt,
void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const MVert *mvert,
const float *vmask,
- const MLoopCol *vcol,
+ const void *vcol_data,
+ const int vcol_type,
+ const AttributeDomain vcol_domain,
const int *sculpt_face_sets,
const int face_sets_color_seed,
const int face_sets_color_default,
- const MPropCol *vtcol,
const int update_flags)
{
+ const MPropCol *vtcol = vcol_type == CD_PROP_COLOR ? vcol_data : NULL;
+ const MLoopCol *vcol = vcol_type == CD_MLOOPCOL ? vcol_data : NULL;
+ const float(*f3col)[3] = vcol_type == CD_PROP_FLOAT3 ? vcol_data : NULL;
+
+ const bool color_loops = vcol_domain == ATTR_DOMAIN_CORNER;
+ const bool show_vcol = (vtcol || vcol || f3col) &&
+ (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
+
const bool show_mask = vmask && (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
const bool show_face_sets = sculpt_face_sets &&
(update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
- const bool show_vcol = (vcol || (vtcol && U.experimental.use_sculpt_vertex_colors)) &&
- (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
bool empty_mask = true;
bool default_face_set = true;
@@ -302,16 +311,40 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
/* Vertex Colors. */
if (show_vcol) {
ushort scol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- if (vtcol && U.experimental.use_sculpt_vertex_colors) {
- scol[0] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[0]);
- scol[1] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[1]);
- scol[2] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[2]);
- scol[3] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[3]);
+ if (vtcol) {
+ if (color_loops) {
+ scol[0] = unit_float_to_ushort_clamp(vtcol[lt->tri[j]].color[0]);
+ scol[1] = unit_float_to_ushort_clamp(vtcol[lt->tri[j]].color[1]);
+ scol[2] = unit_float_to_ushort_clamp(vtcol[lt->tri[j]].color[2]);
+ scol[3] = unit_float_to_ushort_clamp(vtcol[lt->tri[j]].color[3]);
+ }
+ else {
+ scol[0] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[0]);
+ scol[1] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[1]);
+ scol[2] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[2]);
+ scol[3] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[3]);
+ }
memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
}
- else {
+ else if (f3col) {
+ if (color_loops) {
+ scol[0] = unit_float_to_ushort_clamp(f3col[lt->tri[j]][0]);
+ scol[1] = unit_float_to_ushort_clamp(f3col[lt->tri[j]][1]);
+ scol[2] = unit_float_to_ushort_clamp(f3col[lt->tri[j]][2]);
+ scol[3] = USHRT_MAX;
+ }
+ else {
+ scol[0] = unit_float_to_ushort_clamp(f3col[vtri[j]][0]);
+ scol[1] = unit_float_to_ushort_clamp(f3col[vtri[j]][1]);
+ scol[2] = unit_float_to_ushort_clamp(f3col[vtri[j]][2]);
+ scol[3] = USHRT_MAX;
+ }
+ memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
+ }
+ else if (vcol) {
const uint loop_index = lt->tri[j];
- const MLoopCol *mcol = &vcol[loop_index];
+ const MLoopCol *mcol = vcol + (color_loops ? loop_index : vtri[j]);
+
scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]);
scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]);
scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 563c6ea35e0..84f30e513d5 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -6307,10 +6307,6 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Cycles Debug", "Enable Cycles debugging options for developers");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "use_sculpt_vertex_colors", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_vertex_colors", 1);
- RNA_def_property_ui_text(prop, "Sculpt Vertex Colors", "Use the new Vertex Painting system");
-
prop = RNA_def_property(srna, "use_sculpt_tools_tilt", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_tools_tilt", 1);
RNA_def_property_ui_text(
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
index e2b2cc58d48..4d670ba8afd 100644
--- a/source/blender/modifiers/intern/MOD_datatransfer.c
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -369,6 +369,20 @@ static void face_corner_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "loop_mapping", 0, IFACE_("Mapping"), ICON_NONE);
}
+static void vert_propcol_panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+
+ uiLayoutSetPropSep(layout, true);
+
+ uiLayoutSetActive(layout, RNA_enum_get(ptr, "data_types_verts") & DT_TYPE_PROPCOL);
+
+ uiItemR(layout, ptr, "layers_propcol_select_src", 0, IFACE_("Layer Selection"), ICON_NONE);
+ uiItemR(layout, ptr, "layers_propcol_select_dst", 0, IFACE_("Layer Mapping"), ICON_NONE);
+}
+
static void face_corner_vcol_panel_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *layout = panel->layout;
@@ -450,6 +464,9 @@ static void panelRegister(ARegionType *region_type)
region_type, "vertex_vgroup", "Vertex Groups", NULL, vertex_vgroup_panel_draw, vertex_panel);
modifier_subpanel_register(
+ region_type, "vert_propcol", "Sculpt Colors", NULL, vert_propcol_panel_draw, vertex_panel);
+
+ modifier_subpanel_register(
region_type, "edge", "", edge_panel_draw_header, edge_panel_draw, panel_type);
PanelType *face_corner_panel = modifier_subpanel_register(region_type,
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
index 40576b68dd5..b48473b6070 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
@@ -39,11 +39,7 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage;
- if (U.experimental.use_sculpt_vertex_colors) {
- GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_PROP_COLOR, vertexColor->layer_name);
- return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
- }
- GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_MCOL, vertexColor->layer_name);
+ GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_PROP_COLOR, vertexColor->layer_name);
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
}
diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c
index 5eaf026191f..ca54895bb81 100644
--- a/source/blender/windowmanager/intern/wm_toolsystem.c
+++ b/source/blender/windowmanager/intern/wm_toolsystem.c
@@ -31,6 +31,7 @@
#include "BLI_utildefines.h"
#include "DNA_ID.h"
+#include "DNA_brush_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -211,6 +212,12 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre
}
else {
brush = BKE_brush_add(bmain, items[i].name, paint->runtime.ob_mode);
+
+ if (paint->runtime.ob_mode == OB_MODE_SCULPT) {
+ brush->sculpt_tool = slot_index;
+ BKE_brush_sculpt_reset(brush);
+ }
+
BKE_brush_tool_set(brush, paint, slot_index);
}
BKE_paint_brush_set(paint, brush);
diff --git a/source/tools b/source/tools
-Subproject c8579c5cf43229843df505da9644b5b0b720197
+Subproject 548055f40213c775a6b77025525c91e8466e70d