diff options
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 20 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_materials.c | 12 | ||||
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_deferred.c | 24 | ||||
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_forward.c | 29 | ||||
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_materials.c | 4 | ||||
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_private.h | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 22 | ||||
-rw-r--r-- | source/blender/draw/modes/overlay_mode.c | 13 | ||||
-rw-r--r-- | source/blender/draw/modes/sculpt_mode.c | 4 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 100 |
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); } |