Multires: Base Mesh Sculpting

This adds an option to the Multires modifier to sculpt directly on the
base mesh while previewing the displacement of a higher subdivisions
level. What this does it considering Multires as a regular modifier
without exposing the grid displacement to sculpt mode.

This allows to see the propagation happening in real time, which enables
to use complex tools like Cloth or Pose in much higher resolutions and
without surface noise and artifacts.

Reviewed By: sergey, Severin

Differential Revision: https://developer.blender.org/D8555
This commit is contained in:
Pablo Dobarro 2020-08-14 00:23:54 +02:00
parent df495e758d
commit 976f0113e0
5 changed files with 24 additions and 5 deletions

View File

@ -909,8 +909,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
/* Sculpt can skip certain modifiers. */
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
const bool has_multires = (mmd && mmd->sculptlvl != 0);
const bool has_multires = BKE_sculpt_multires_active(scene, ob) != NULL;
bool multires_applied = false;
const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !use_render;
const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !use_render;

View File

@ -1421,7 +1421,7 @@ MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob)
continue;
}
if (mmd->sculptlvl > 0) {
if (mmd->sculptlvl > 0 && !(mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh)) {
return mmd;
}
@ -1458,7 +1458,10 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
continue;
}
if (md->type == eModifierType_Multires && (ob->mode & OB_MODE_SCULPT)) {
continue;
MultiresModifierData *mmd = (MultiresModifierData *)md;
if (!(mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh)) {
continue;
}
}
if (md->type == eModifierType_ShapeKey) {
continue;

View File

@ -1033,6 +1033,7 @@ typedef enum {
eMultiresModifierFlag_PlainUv_DEPRECATED = (1 << 1),
eMultiresModifierFlag_UseCrease = (1 << 2),
eMultiresModifierFlag_UseCustomNormals = (1 << 3),
eMultiresModifierFlag_UseSculptBaseMesh = (1 << 4),
} MultiresModifierFlag;
/* DEPRECATED, only used for versioning. */

View File

@ -2076,6 +2076,14 @@ static void rna_def_modifier_multires(BlenderRNA *brna)
prop, "Use Custom Normals", "Interpolates existing custom normals to resulting mesh");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_sculpt_base_mesh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_UseSculptBaseMesh);
RNA_def_property_ui_text(prop,
"Sculpt Base Mesh",
"Make Sculpt Mode tools deform the base mesh while previewing the "
"displacement of higher subdivision levels");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
RNA_define_lib_overridable(false);
}

View File

@ -238,7 +238,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Needed when rendering or baking will in sculpt mode. */
const bool for_render = (ctx->flag & MOD_APPLY_RENDER) != 0;
if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render) {
const bool sculpt_base_mesh = mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh;
if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render && !sculpt_base_mesh) {
/* NOTE: CCG takes ownership over Subdiv. */
result = multires_as_ccg(mmd, ctx, mesh, subdiv);
result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
@ -341,6 +343,12 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(col, &ptr, "sculpt_levels", 0, IFACE_("Sculpt"), ICON_NONE);
uiItemR(col, &ptr, "render_levels", 0, IFACE_("Render"), ICON_NONE);
const bool is_sculpt_mode = CTX_data_active_object(C)->mode & OB_MODE_SCULPT;
uiBlock *block = uiLayoutGetBlock(panel->layout);
UI_block_lock_set(block, !is_sculpt_mode, IFACE_("Sculpt Base Mesh"));
uiItemR(col, &ptr, "use_sculpt_base_mesh", 0, IFACE_("Sculpt Base Mesh"), ICON_NONE);
UI_block_lock_clear(block);
uiItemR(layout, &ptr, "show_only_control_edges", 0, NULL, ICON_NONE);
modifier_panel_end(layout, &ptr);