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:
-rw-r--r--source/blender/blenkernel/BKE_paint.h6
-rw-r--r--source/blender/blenkernel/intern/paint.c20
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c12
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c24
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c29
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h4
-rw-r--r--source/blender/draw/intern/DRW_render.h1
-rw-r--r--source/blender/draw/intern/draw_manager.c22
-rw-r--r--source/blender/draw/modes/overlay_mode.c13
-rw-r--r--source/blender/draw/modes/sculpt_mode.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c100
13 files changed, 121 insertions, 120 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 56c92b731b7..b92ce8a001f 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -54,6 +54,7 @@ struct SubdivCCG;
struct Tex;
struct ToolSettings;
struct UnifiedPaintSettings;
+struct View3D;
struct ViewLayer;
struct bContext;
struct bToolRef;
@@ -250,9 +251,6 @@ typedef struct SculptSession {
float (*deform_cos)[3]; /* coords of deformed mesh but without stroke displacement */
float (*deform_imats)[3][3]; /* crazyspace deformation matrices */
- /* Partial redraw */
- bool partial_redraw;
-
/* Used to cache the render of the active texture */
unsigned int texcache_side, *texcache, texcache_actual;
struct ImagePool *tex_pool;
@@ -308,6 +306,8 @@ struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct O
void BKE_sculpt_bvh_update_from_ccg(struct PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
+bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d);
+
enum {
SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1),
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 5849d691b03..4de425acfc0 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1512,3 +1512,23 @@ void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg)
subdiv_ccg->grid_flag_mats,
subdiv_ccg->grid_hidden);
}
+
+/* Test if PBVH can be used directly for drawing, which is faster than
+ * drawing the mesh and all updates that come with it. */
+bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *v3d)
+{
+ SculptSession *ss = ob->sculpt;
+ if (ss == NULL || ss->pbvh == NULL || ss->mode_type != OB_MODE_SCULPT) {
+ return false;
+ }
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
+ /* Regular mesh only draws from PBVH without modifiers and shape keys. */
+ const bool full_shading = (v3d && (v3d->shading.type > OB_SOLID));
+ return !(ss->kb || ss->modifiers_active || full_shading);
+ }
+ else {
+ /* Multires and dyntopo always draw directly from the PBVH. */
+ return true;
+ }
+}
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 3b78d8718ef..2b8673e2f53 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -28,9 +28,8 @@
#include "BLI_rand.h"
#include "BLI_string_utils.h"
-#include "BKE_particle.h"
#include "BKE_paint.h"
-#include "BKE_pbvh.h"
+#include "BKE_particle.h"
#include "DNA_world_types.h"
#include "DNA_modifier_types.h"
@@ -1535,10 +1534,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
Scene *scene = draw_ctx->scene;
GHash *material_hash = stl->g_data->material_hash;
- bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob);
- /* For now just force fully shaded with eevee when supported. */
- is_sculpt_mode = is_sculpt_mode &&
- !(ob->sculpt->pbvh && BKE_pbvh_type(ob->sculpt->pbvh) == PBVH_FACES);
+ bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
/* First get materials for this mesh. */
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
@@ -1606,7 +1602,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
int auto_layer_count;
struct GPUBatch **mat_geom = NULL;
- if (!is_sculpt_mode) {
+ if (!use_sculpt_pbvh) {
mat_geom = DRW_cache_object_surface_material_get(ob,
gpumat_array,
materials_len,
@@ -1615,7 +1611,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
&auto_layer_count);
}
- if (is_sculpt_mode) {
+ if (use_sculpt_pbvh) {
/* Vcol is not supported in the modes that require PBVH drawing. */
bool use_vcol = false;
DRW_shgroup_call_sculpt_with_materials(shgrp_array, ob, use_vcol);
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 516d4de897f..3dbdd1cce61 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -30,6 +30,7 @@
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_paint.h"
#include "BKE_particle.h"
#include "DNA_image_types.h"
@@ -965,13 +966,13 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
WORKBENCH_MaterialData *material;
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob);
+ const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
const int materials_len = MAX2(1, ob->totcol);
const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
bool has_transp_mat = false;
- if (!is_sculpt_mode && TEXTURE_DRAWING_ENABLED(wpd) && me && me->mloopuv) {
+ if (!use_sculpt_pbvh && TEXTURE_DRAWING_ENABLED(wpd) && me && me->mloopuv) {
/* Draw textured */
struct GPUBatch **geom_array = DRW_cache_mesh_surface_texpaint_get(ob);
for (int i = 0; i < materials_len; i++) {
@@ -981,12 +982,13 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
ImageUser *iuser;
int interp;
workbench_material_get_image_and_mat(ob, i + 1, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob, is_sculpt_mode);
+ int color_type = workbench_material_determine_color_type(
+ wpd, image, ob, use_sculpt_pbvh);
if (color_type == V3D_SHADING_MATERIAL_COLOR && mat && mat->a < 1.0) {
/* Hack */
wpd->shading.xray_alpha = mat->a;
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, image, iuser, color_type, 0, is_sculpt_mode);
+ vedata, ob, mat, image, iuser, color_type, 0, use_sculpt_pbvh);
has_transp_mat = true;
}
else {
@@ -1002,13 +1004,13 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
V3D_SHADING_OBJECT_COLOR,
V3D_SHADING_RANDOM_COLOR,
V3D_SHADING_VERTEX_COLOR)) {
- int color_type = workbench_material_determine_color_type(wpd, NULL, ob, is_sculpt_mode);
+ int color_type = workbench_material_determine_color_type(wpd, NULL, ob, use_sculpt_pbvh);
if ((ob->color[3] < 1.0f) && (color_type == V3D_SHADING_OBJECT_COLOR)) {
/* Hack */
wpd->shading.xray_alpha = ob->color[3];
material = workbench_forward_get_or_create_material_data(
- vedata, ob, NULL, NULL, NULL, color_type, 0, is_sculpt_mode);
+ vedata, ob, NULL, NULL, NULL, color_type, 0, use_sculpt_pbvh);
has_transp_mat = true;
}
else {
@@ -1016,7 +1018,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
material = get_or_create_material_data(vedata, ob, NULL, NULL, NULL, color_type, 0);
}
- if (is_sculpt_mode) {
+ if (use_sculpt_pbvh) {
bool use_vcol = (color_type == V3D_SHADING_VERTEX_COLOR);
DRW_shgroup_call_sculpt(material->shgrp, ob, false, false, use_vcol);
}
@@ -1036,7 +1038,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
}
else {
/* Draw material color */
- if (is_sculpt_mode) {
+ if (use_sculpt_pbvh) {
struct DRWShadingGroup **shgrps = BLI_array_alloca(shgrps, materials_len);
for (int i = 0; i < materials_len; ++i) {
@@ -1045,7 +1047,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
/* Hack */
wpd->shading.xray_alpha = mat->a;
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, use_sculpt_pbvh);
has_transp_mat = true;
}
else {
@@ -1070,7 +1072,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
/* Hack */
wpd->shading.xray_alpha = mat->a;
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, use_sculpt_pbvh);
has_transp_mat = true;
}
else {
@@ -1087,7 +1089,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
bool is_manifold;
struct GPUBatch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold);
if (geom_shadow) {
- if (is_sculpt_mode || use_hide) {
+ if (use_sculpt_pbvh || use_hide) {
/* Currently unsupported in sculpt mode. We could revert to the slow
* method in this case but I'm not sure if it's a good idea given that
* sculpted meshes are heavy to begin with. */
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 26c4b920382..eccf2b1a0f0 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -29,9 +29,10 @@
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
-#include "BKE_particle.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_particle.h"
#include "DNA_image_types.h"
#include "DNA_mesh_types.h"
@@ -141,7 +142,7 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
ImageUser *iuser,
int color_type,
int interp,
- bool is_sculpt_mode)
+ bool use_sculpt_pbvh)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
@@ -198,7 +199,7 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
material->shgrp = grp;
/* Depth */
- if (workbench_material_determine_color_type(wpd, material->ima, ob, is_sculpt_mode) ==
+ if (workbench_material_determine_color_type(wpd, material->ima, ob, use_sculpt_pbvh) ==
V3D_SHADING_TEXTURE_COLOR) {
material->shgrp_object_outline = DRW_shgroup_create(sh_data->object_outline_texture_sh,
psl->object_outline_pass);
@@ -567,11 +568,11 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
WORKBENCH_MaterialData *material;
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
- const bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob);
+ const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
const int materials_len = MAX2(1, ob->totcol);
const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
- if (!is_sculpt_mode && TEXTURE_DRAWING_ENABLED(wpd) && me && me->mloopuv) {
+ if (!use_sculpt_pbvh && TEXTURE_DRAWING_ENABLED(wpd) && me && me->mloopuv) {
struct GPUBatch **geom_array = DRW_cache_mesh_surface_texpaint_get(ob);
for (int i = 0; i < materials_len; i++) {
Material *mat;
@@ -579,9 +580,9 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
ImageUser *iuser;
int interp;
workbench_material_get_image_and_mat(ob, i + 1, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob, is_sculpt_mode);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob, use_sculpt_pbvh);
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, image, iuser, color_type, interp, is_sculpt_mode);
+ vedata, ob, mat, image, iuser, color_type, interp, use_sculpt_pbvh);
DRW_shgroup_call(material->shgrp_object_outline, geom_array[i], ob);
DRW_shgroup_call(material->shgrp, geom_array[i], ob);
}
@@ -592,11 +593,11 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
V3D_SHADING_RANDOM_COLOR,
V3D_SHADING_VERTEX_COLOR)) {
/* No material split needed */
- int color_type = workbench_material_determine_color_type(wpd, NULL, ob, is_sculpt_mode);
+ int color_type = workbench_material_determine_color_type(wpd, NULL, ob, use_sculpt_pbvh);
- if (is_sculpt_mode) {
+ if (use_sculpt_pbvh) {
material = workbench_forward_get_or_create_material_data(
- vedata, ob, NULL, NULL, NULL, color_type, 0, is_sculpt_mode);
+ vedata, ob, NULL, NULL, NULL, color_type, 0, use_sculpt_pbvh);
bool use_vcol = (color_type == V3D_SHADING_VERTEX_COLOR);
/* TODO(fclem) make this call optional */
DRW_shgroup_call_sculpt(material->shgrp_object_outline, ob, false, false, false);
@@ -610,7 +611,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
DRW_cache_object_surface_get(ob);
if (geom) {
material = workbench_forward_get_or_create_material_data(
- vedata, ob, NULL, NULL, NULL, color_type, 0, is_sculpt_mode);
+ vedata, ob, NULL, NULL, NULL, color_type, 0, use_sculpt_pbvh);
/* TODO(fclem) make this call optional */
DRW_shgroup_call(material->shgrp_object_outline, geom, ob);
if (!is_wire) {
@@ -621,13 +622,13 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
}
else {
/* Draw material color */
- if (is_sculpt_mode) {
+ if (use_sculpt_pbvh) {
struct DRWShadingGroup **shgrps = BLI_array_alloca(shgrps, materials_len);
for (int i = 0; i < materials_len; ++i) {
struct Material *mat = give_current_material(ob, i + 1);
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, use_sculpt_pbvh);
shgrps[i] = material->shgrp;
}
/* TODO(fclem) make this call optional */
@@ -650,7 +651,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
Material *mat = give_current_material(ob, i + 1);
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, use_sculpt_pbvh);
/* TODO(fclem) make this call optional */
DRW_shgroup_call(material->shgrp_object_outline, mat_geom[i], ob);
if (!is_wire) {
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 02fbbe0b042..6ca55d48681 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -237,12 +237,12 @@ int workbench_material_get_accum_shader_index(WORKBENCH_PrivateData *wpd,
int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd,
Image *ima,
Object *ob,
- bool is_sculpt_mode)
+ bool use_sculpt_pbvh)
{
int color_type = wpd->shading.color_type;
const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
- if ((color_type == V3D_SHADING_TEXTURE_COLOR && (ima == NULL || is_sculpt_mode)) ||
+ if ((color_type == V3D_SHADING_TEXTURE_COLOR && (ima == NULL || use_sculpt_pbvh)) ||
(ob->dt < OB_TEXTURE)) {
color_type = V3D_SHADING_MATERIAL_COLOR;
}
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 240d06c1e79..34196c6aa04 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -383,7 +383,7 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
ImageUser *iuser,
int color_type,
int interp,
- bool is_sculpt_mode);
+ bool use_sculpt_pbvh);
/* workbench_effect_aa.c */
void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx);
@@ -416,7 +416,7 @@ void workbench_dof_draw_pass(WORKBENCH_Data *vedata);
int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd,
Image *ima,
Object *ob,
- bool is_sculpt_mode);
+ bool use_sculpt_pbvh);
void workbench_material_get_image_and_mat(
Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, int *r_interp, Material **r_mat);
char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd,
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 315b3ee8b30..e8283d2a359 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -635,7 +635,6 @@ bool DRW_object_is_renderable(const struct Object *ob);
int DRW_object_visibility_in_active_context(const struct Object *ob);
bool DRW_object_is_flat_normal(const struct Object *ob);
bool DRW_object_use_hide_faces(const struct Object *ob);
-bool DRW_object_use_pbvh_drawing(const struct Object *ob);
bool DRW_object_is_visible_psys_in_active_context(const struct Object *object,
const struct ParticleSystem *psys);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 6428eb77ddb..9e69cfa7ea4 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -217,28 +217,6 @@ bool DRW_object_use_hide_faces(const struct Object *ob)
return false;
}
-/* Should we use PBVH drawing or regular mesh drawing
- * PBVH drawing should be used for
- * - Multires
- * - Dyntopo
- * - Normal sculpt without any active modifiers
- */
-bool DRW_object_use_pbvh_drawing(const struct Object *ob)
-{
- SculptSession *ss = ob->sculpt;
- if (ss == NULL || ss->pbvh == NULL || ob->sculpt->mode_type != OB_MODE_SCULPT) {
- return false;
- }
-
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- return !(ss->kb || ss->modifiers_active);
- }
- else {
- /* Multires/Dyntopo */
- return true;
- }
-}
-
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
{
const bool for_render = DRW_state_is_image_render();
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 667f2c9e70a..3c5cb7cb5aa 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -26,8 +26,9 @@
#include "BIF_glutil.h"
#include "BKE_editmesh.h"
-#include "BKE_object.h"
#include "BKE_global.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
#include "BLI_hash.h"
@@ -391,10 +392,10 @@ static void overlay_cache_populate(void *vedata, Object *ob)
if ((!pd->show_overlays) ||
(((ob != draw_ctx->object_edit) && !is_edit_mode) || has_edit_mesh_cage) ||
ob->type != OB_MESH) {
- const bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob);
+ const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES);
const bool is_wire = (ob->dt < OB_SOLID);
- const bool use_coloring = (pd->show_overlays && !is_edit_mode && !is_sculpt_mode &&
+ const bool use_coloring = (pd->show_overlays && !is_edit_mode && !use_sculpt_pbvh &&
!has_edit_mesh_cage);
const int stencil_mask = (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF;
float *rim_col, *wire_col;
@@ -405,11 +406,11 @@ static void overlay_cache_populate(void *vedata, Object *ob)
struct GPUBatch *geom;
geom = DRW_cache_object_face_wireframe_get(ob);
- if (geom || is_sculpt_mode) {
+ if (geom || use_sculpt_pbvh) {
shgrp = DRW_shgroup_create_sub(pd->face_wires_shgrp);
float wire_step_param = 10.0f;
- if (!is_sculpt_mode) {
+ if (!use_sculpt_pbvh) {
wire_step_param = (all_wires) ? 1.0f : pd->wire_step_param;
}
DRW_shgroup_uniform_float_copy(shgrp, "wireStepParam", wire_step_param);
@@ -420,7 +421,7 @@ static void overlay_cache_populate(void *vedata, Object *ob)
DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
}
- if (is_sculpt_mode) {
+ if (use_sculpt_pbvh) {
DRW_shgroup_call_sculpt(shgrp, ob, true, false, false);
}
else {
diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c
index cc3435014d3..42a2333f305 100644
--- a/source/blender/draw/modes/sculpt_mode.c
+++ b/source/blender/draw/modes/sculpt_mode.c
@@ -152,10 +152,10 @@ static void SCULPT_cache_populate(void *vedata, Object *ob)
UNUSED_VARS(psl, stl);
- if (ob->type == OB_MESH) {
+ if (ob->sculpt) {
const DRWContextState *draw_ctx = DRW_context_state_get();
- if (ob->sculpt && (ob == draw_ctx->obact)) {
+ if ((ob == draw_ctx->obact) && BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d)) {
PBVH *pbvh = ob->sculpt->pbvh;
if (pbvh && pbvh_has_mask(pbvh)) {
DRW_shgroup_call_sculpt(stl->g_data->mask_overlay_grp, ob, false, true, false);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 7852cd61ae1..f9db589405e 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2336,8 +2336,6 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
r.xmax += vc->ar->winrct.xmin + 2;
r.ymin += vc->ar->winrct.ymin - 2;
r.ymax += vc->ar->winrct.ymin + 2;
-
- ss->partial_redraw = 1;
}
ED_region_tag_redraw_partial(vc->ar, &r);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 2dc1e53af89..7b8461f5011 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5180,15 +5180,15 @@ void sculpt_update_object_bounding_box(Object *ob)
}
}
-static void sculpt_flush_update(bContext *C)
+static void sculpt_flush_update_step(bContext *C)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Object *ob = CTX_data_active_object(C);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
SculptSession *ss = ob->sculpt;
ARegion *ar = CTX_wm_region(C);
- bScreen *screen = CTX_wm_screen(C);
MultiresModifierData *mmd = ss->multires;
+ View3D *v3d = CTX_wm_view3d(C);
if (mmd != NULL) {
/* NOTE: SubdivCCG is living in the evaluated object. */
@@ -5197,32 +5197,17 @@ static void sculpt_flush_update(bContext *C)
DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
- bool use_shaded_mode = false;
- if (mmd || (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH)) {
- /* Multres or dyntopo are drawn directly by EEVEE,
- * no need for hacks in this case. */
- }
- else {
- /* We search if an area of the current window is in lookdev/rendered
- * display mode. In this case, for changes to show up, we need to
- * tag for ID_RECALC_GEOMETRY. */
- for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
- for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *)sl;
- if (v3d->shading.type > OB_SOLID) {
- use_shaded_mode = true;
- }
- }
- }
- }
- }
-
- if (ss->kb || ss->modifiers_active || use_shaded_mode) {
+ /* Only current viewport matters, slower update for all viewports will
+ * be done in sculpt_flush_update_done. */
+ if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) {
+ /* Slow update with full dependency graph update and all that comes with it.
+ * Needed when there are modifiers or full shading in the 3D viewport. */
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
ED_region_tag_redraw(ar);
}
else {
+ /* Fast path where we just update the BVH nodes that changed, and redraw
+ * only the part of the 3D viewport where changes happened. */
rcti r;
BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL);
@@ -5244,13 +5229,52 @@ static void sculpt_flush_update(bContext *C)
r.xmax += ar->winrct.xmin + 2;
r.ymin += ar->winrct.ymin - 2;
r.ymax += ar->winrct.ymin + 2;
-
- ss->partial_redraw = 1;
ED_region_tag_redraw_partial(ar, &r);
}
}
}
+static void sculpt_flush_update_done(const bContext *C, Object *ob)
+{
+ /* After we are done drawing the stroke, check if we need to do a more
+ * expensive depsgraph tag to update geometry. */
+ wmWindowManager *wm = CTX_wm_manager(C);
+ View3D *current_v3d = CTX_wm_view3d(C);
+ SculptSession *ss = ob->sculpt;
+ Mesh *mesh = ob->data;
+ bool need_tag = (mesh->id.us > 1); /* Always needed for linked duplicates. */
+
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ bScreen *screen = WM_window_get_active_screen(win);
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl = sa->spacedata.first;
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ if (v3d != current_v3d) {
+ need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, v3d);
+ }
+ }
+ }
+ }
+
+ BKE_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_bmesh_after_stroke(ss->pbvh);
+ }
+
+ /* optimization: if there is locked key and active modifiers present in */
+ /* the stack, keyblock is updating at each step. otherwise we could update */
+ /* keyblock only when stroke is finished */
+ if (ss->kb && !ss->modifiers_active) {
+ sculpt_update_keyblock(ob);
+ }
+
+ if (need_tag) {
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+}
+
/* Returns whether the mouse/stylus is over the mesh (1)
* or over the background (0) */
static bool over_mesh(bContext *C, struct wmOperator *UNUSED(op), float x, float y)
@@ -5334,7 +5358,7 @@ static void sculpt_stroke_update_step(bContext *C,
* much common scenario.
*
* Same applies to the DEG_id_tag_update() invoked from
- * sculpt_flush_update().
+ * sculpt_flush_update_step().
*/
if (ss->modifiers_active) {
sculpt_flush_stroke_deform(sd, ob);
@@ -5346,7 +5370,7 @@ static void sculpt_stroke_update_step(bContext *C,
ss->cache->first_time = false;
/* Cleanup */
- sculpt_flush_update(C);
+ sculpt_flush_update_step(C);
}
static void sculpt_brush_exit_tex(Sculpt *sd)
@@ -5395,25 +5419,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
sculpt_undo_push_end();
- BKE_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
-
- if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- BKE_pbvh_bmesh_after_stroke(ss->pbvh);
- }
-
- /* optimization: if there is locked key and active modifiers present in */
- /* the stack, keyblock is updating at each step. otherwise we could update */
- /* keyblock only when stroke is finished */
- if (ss->kb && !ss->modifiers_active) {
- sculpt_update_keyblock(ob);
- }
-
- ss->partial_redraw = 0;
-
- /* try to avoid calling this, only for e.g. linked duplicates now */
- if (((Mesh *)ob->data)->id.us > 1) {
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- }
+ sculpt_flush_update_done(C, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}