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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-31 15:04:16 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-31 18:17:03 +0300
commit692891f69ea42af0ba890f5f92cbd1a3260442c9 (patch)
tree1aeb9469b7a2b26a8a25a09c6045faa51d34944b /source/blender
parent9899999e944c0d954dbe5a7aa96c8e1680e7b3f8 (diff)
Fix sculpt mode drawing with modifiers still being wrong in some cases
Centralize logic for when to use the PBVH for drawing, fix missing tests in mask drawing, fix missing tests for multiple windows, only do more expensive update for all viewports at end of the stroke.
Diffstat (limited to 'source/blender')
-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);
}