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:
authorPablo Dobarro <pablodp606@gmail.com>2020-06-22 21:05:28 +0300
committerPablo Dobarro <pablodp606@gmail.com>2020-06-23 17:28:50 +0300
commitf7bbc7cdbb6cb0d28504c6a8dd51bee5330d1f17 (patch)
tree1045d1253114fb67286330f069bde6eb0e7bb068 /source/blender/draw
parent27972c4225c26780eb957ddf0c98ce4cee3d29e5 (diff)
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time. This commit includes: - SCULPT_UNDO_COLOR for undo support in sculpt mode - SCULPT_UPDATE_COLOR and PBVH flags and rendering - Sculpt Color API functions - Sculpt capability for sculpt tools (only enabled in the Paint Brush for now) - Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint) - Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint) - Remesher reprojection in the Voxel Remehser - Paint Brush and Smear Brush with color smoothing in alt-smooth mode - Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors - Color Filter - Color picker (uses S shortcut, replaces smooth) - Color selector in the top bar Reviewed By: brecht Maniphest Tasks: T72866 Differential Revision: https://developer.blender.org/D5975
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c24
-rw-r--r--source/blender/draw/intern/draw_cache.c6
-rw-r--r--source/blender/draw/intern/draw_cache.h1
-rw-r--r--source/blender/draw/intern/draw_cache_extract.h1
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c62
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h1
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c81
7 files changed, 166 insertions, 10 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 828a9127fb1..791b83a22a8 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -174,8 +174,19 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
color_type, V3D_SHADING_MATERIAL_COLOR, V3D_SHADING_TEXTURE_COLOR);
if (use_single_drawcall) {
- struct GPUBatch *geom = (use_vcol) ? DRW_cache_mesh_surface_vertpaint_get(ob) :
- DRW_cache_object_surface_get(ob);
+ struct GPUBatch *geom;
+ if (use_vcol) {
+ if (ob->mode & OB_MODE_VERTEX_PAINT) {
+ geom = DRW_cache_mesh_surface_vertpaint_get(ob);
+ }
+ else {
+ geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
+ }
+ }
+ else {
+ geom = DRW_cache_object_surface_get(ob);
+ }
+
if (geom) {
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, 0, color_type, r_transp);
DRW_shgroup_call(grp, geom, ob);
@@ -247,8 +258,13 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
if ((color_type == V3D_SHADING_TEXTURE_COLOR) && (me == NULL || me->mloopuv == NULL)) {
color_type = V3D_SHADING_MATERIAL_COLOR;
}
- if ((color_type == V3D_SHADING_VERTEX_COLOR) && (me == NULL || me->mloopcol == NULL)) {
- color_type = V3D_SHADING_OBJECT_COLOR;
+ if (color_type == V3D_SHADING_VERTEX_COLOR) {
+ if (me == NULL) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
+ }
+ if (!CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
+ }
}
if (r_sculpt_pbvh) {
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index f5540362041..9f30cd85957 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -2870,6 +2870,12 @@ GPUBatch *DRW_cache_mesh_surface_vertpaint_get(Object *ob)
return DRW_mesh_batch_cache_get_surface_vertpaint(ob->data);
}
+GPUBatch *DRW_cache_mesh_surface_sculptcolors_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+ return DRW_mesh_batch_cache_get_surface_sculpt(ob->data);
+}
+
GPUBatch *DRW_cache_mesh_surface_weights_get(Object *ob)
{
BLI_assert(ob->type == OB_MESH);
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 5703f616ad1..2f289bf4110 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -136,6 +136,7 @@ struct GPUBatch **DRW_cache_mesh_surface_shaded_get(struct Object *ob,
struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_vertpaint_get(struct Object *ob);
+struct GPUBatch *DRW_cache_mesh_surface_sculptcolors_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_face_wireframe_get(struct Object *ob);
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index f203c2ff1ea..0b1f625dc2c 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -53,6 +53,7 @@ typedef struct DRW_MeshCDMask {
uint32_t uv : 8;
uint32_t tan : 8;
uint32_t vcol : 8;
+ uint32_t sculpt_vcol : 8;
uint32_t orco : 1;
uint32_t tan_orco : 1;
/** Edit uv layer is from the base edit mesh as
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index e1f0cc98745..a8ba716f7b0 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -2177,7 +2177,9 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
GPU_vertformat_deinterleave(&format);
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
+ CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata;
uint32_t vcol_layers = mr->cache->cd_used.vcol;
+ uint32_t svcol_layers = mr->cache->cd_used.sculpt_vcol;
for (int i = 0; i < MAX_MCOL; i++) {
if (vcol_layers & (1 << i)) {
@@ -2194,6 +2196,33 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL)) {
GPU_vertformat_alias_add(&format, "ac");
}
+
+ /* Gather number of auto layers. */
+ /* We only do vcols that are not overridden by uvs and sculpt vertex colors */
+ if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, layer_name) == -1 &&
+ CustomData_get_named_layer_index(cd_vdata, CD_PROP_COLOR, layer_name) == -1) {
+ BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
+ GPU_vertformat_alias_add(&format, attr_name);
+ }
+ }
+ }
+
+ /* 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) {
@@ -2202,6 +2231,7 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
}
}
}
+
GPUVertBuf *vbo = buf;
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len);
@@ -2211,6 +2241,8 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
} gpuMeshVcol;
gpuMeshVcol *vcol_data = (gpuMeshVcol *)vbo->data;
+ MLoop *loops = CustomData_get_layer(cd_ldata, CD_MLOOP);
+
for (int i = 0; i < MAX_MCOL; i++) {
if (vcol_layers & (1 << i)) {
if (mr->extract_type == MR_EXTRACT_BMESH) {
@@ -2239,6 +2271,36 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
}
}
}
+
+ 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 l_iter, f_iter;
+ BMLoop *loop;
+ BMFace *efa;
+ BM_ITER_MESH (efa, &f_iter, mr->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (loop, &l_iter, efa, BM_LOOPS_OF_FACE) {
+ const MPropCol *prop_col = BM_ELEM_CD_GET_VOID_P(loop->v, cd_ofs);
+ vcol_data->r = unit_float_to_ushort_clamp(prop_col->color[0]);
+ vcol_data->g = unit_float_to_ushort_clamp(prop_col->color[1]);
+ vcol_data->b = unit_float_to_ushort_clamp(prop_col->color[2]);
+ vcol_data->a = unit_float_to_ushort_clamp(prop_col->color[3]);
+ vcol_data++;
+ }
+ }
+ }
+ else {
+ MPropCol *vcol = CustomData_get_layer_n(cd_vdata, CD_PROP_COLOR, i);
+ for (int l = 0; l < mr->loop_len; l++, vcol_data++) {
+ vcol_data->r = unit_float_to_ushort_clamp(vcol[loops[l].v].color[0]);
+ vcol_data->g = unit_float_to_ushort_clamp(vcol[loops[l].v].color[1]);
+ vcol_data->b = unit_float_to_ushort_clamp(vcol[loops[l].v].color[2]);
+ vcol_data->a = unit_float_to_ushort_clamp(vcol[loops[l].v].color[3]);
+ }
+ }
+
+ vcol_data += mr->loop_len;
+ }
}
return NULL;
}
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index f670343140a..5cf1c24af0b 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -170,6 +170,7 @@ struct GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(struct Mesh *me,
struct GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(struct Mesh *me);
+struct GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_surface_weights(struct Mesh *me);
/* edit-mesh drawing */
struct GPUBatch *DRW_mesh_batch_cache_get_edit_triangles(struct Mesh *me);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 7207345f13c..ea1717f0684 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -112,6 +112,21 @@ BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me)
return &me->ldata;
}
+BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me)
+{
+ switch ((eMeshWrapperType)me->runtime.wrapper_type) {
+ case ME_WRAPPER_TYPE_MDATA:
+ return &me->vdata;
+ break;
+ case ME_WRAPPER_TYPE_BMESH:
+ return &me->edit_mesh->bm->vdata;
+ break;
+ }
+
+ BLI_assert(0);
+ return &me->vdata;
+}
+
static void mesh_cd_calc_active_uv_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
@@ -135,7 +150,19 @@ static void mesh_cd_calc_active_mask_uv_layer(const Mesh *me, DRW_MeshCDMask *cd
static void mesh_cd_calc_active_vcol_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
- const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
+ const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final);
+
+ int layer = CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR);
+ if (layer != -1) {
+ cd_used->sculpt_vcol |= (1 << layer);
+ }
+}
+
+static void mesh_cd_calc_active_mloopcol_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
+{
+ const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
+ const CustomData *cd_ldata = &me_final->ldata;
+
int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
if (layer != -1) {
cd_used->vcol |= (1 << layer);
@@ -148,6 +175,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
{
const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
+ const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final);
/* See: DM_vertex_attributes_from_gpu for similar logic */
DRW_MeshCDMask cd_used;
@@ -175,6 +203,11 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name);
type = CD_MCOL;
}
+
+ if (layer == -1) {
+ layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
+ type = CD_PROP_COLOR;
+ }
#if 0 /* Tangents are always from UV's - this will never happen. */
if (layer == -1) {
layer = CustomData_get_named_layer(cd_ldata, CD_TANGENT, name);
@@ -222,7 +255,20 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
}
break;
}
+ case CD_PROP_COLOR: {
+ /* Sculpt Vertex Colors */
+ if (layer == -1) {
+ layer = (name[0] != '\0') ?
+ CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name) :
+ CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR);
+ }
+ if (layer != -1) {
+ cd_used.sculpt_vcol |= (1 << layer);
+ }
+ break;
+ }
case CD_MCOL: {
+ /* Vertex Color Data */
if (layer == -1) {
layer = (name[0] != '\0') ? CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name) :
CustomData_get_render_layer(cd_ldata, CD_MLOOPCOL);
@@ -230,6 +276,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
if (layer != -1) {
cd_used.vcol |= (1 << layer);
}
+
break;
}
case CD_ORCO: {
@@ -679,10 +726,22 @@ static void texpaint_request_active_vcol(MeshBatchCache *cache, Mesh *me)
{
DRW_MeshCDMask cd_needed;
mesh_cd_layers_type_clear(&cd_needed);
- mesh_cd_calc_active_vcol_layer(me, &cd_needed);
+ mesh_cd_calc_active_mloopcol_layer(me, &cd_needed);
BLI_assert(cd_needed.vcol != 0 &&
- "No vcol layer available in vertpaint, but batches requested anyway!");
+ "No MLOOPCOL layer available in vertpaint, but batches requested anyway!");
+
+ mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
+}
+
+static void sculpt_request_active_vcol(MeshBatchCache *cache, Mesh *me)
+{
+ DRW_MeshCDMask cd_needed;
+ mesh_cd_layers_type_clear(&cd_needed);
+ mesh_cd_calc_active_vcol_layer(me, &cd_needed);
+
+ BLI_assert(cd_needed.sculpt_vcol != 0 &&
+ "No MPropCol layer available in Sculpt, but batches requested anyway!");
mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
}
@@ -799,6 +858,14 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Mesh *me)
return DRW_batch_request(&cache->batch.surface);
}
+GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+ sculpt_request_active_vcol(cache, me);
+ mesh_batch_cache_add_request(cache, MBC_SURFACE);
+ return DRW_batch_request(&cache->batch.surface);
+}
+
int DRW_mesh_material_count_get(Mesh *me)
{
return mesh_render_mat_len_get(me);
@@ -1137,7 +1204,9 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
if (cache->cd_used.orco != cache->cd_needed.orco) {
GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.orco);
}
- if ((cache->cd_used.vcol & cache->cd_needed.vcol) != cache->cd_needed.vcol) {
+ if (((cache->cd_used.vcol & cache->cd_needed.vcol) != cache->cd_needed.vcol) ||
+ ((cache->cd_used.sculpt_vcol & cache->cd_needed.sculpt_vcol) !=
+ cache->cd_needed.sculpt_vcol)) {
GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.vcol);
}
}
@@ -1218,7 +1287,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
if (cache->cd_used.uv != 0) {
DRW_vbo_request(cache->batch.surface, &mbufcache->vbo.uv);
}
- if (cache->cd_used.vcol != 0) {
+ if (cache->cd_used.vcol != 0 || cache->cd_used.sculpt_vcol != 0) {
DRW_vbo_request(cache->batch.surface, &mbufcache->vbo.vcol);
}
}
@@ -1286,7 +1355,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
if ((cache->cd_used.tan != 0) || (cache->cd_used.tan_orco != 0)) {
DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.tan);
}
- if (cache->cd_used.vcol != 0) {
+ if (cache->cd_used.vcol != 0 || cache->cd_used.sculpt_vcol != 0) {
DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.vcol);
}
if (cache->cd_used.orco != 0) {