diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-08-22 17:07:39 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-08-22 17:07:57 +0300 |
commit | 6a681981e4598f07591a4b99f624f96aea3d2522 (patch) | |
tree | cb0de0efff58dfdba1c22ed61c90794c00fb3470 | |
parent | 9dd279cbdf93b21598267f1860257f0f81837732 (diff) |
Multires: Fix reshape when active level is lower than the total one
-rw-r--r-- | source/blender/blenkernel/BKE_multires.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires_reshape.c | 28 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires_subdiv.c | 5 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_multires.c | 3 |
4 files changed, 29 insertions, 11 deletions
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 5d23f1da289..14559552da7 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -133,11 +133,13 @@ void BKE_multires_subdiv_settings_init( struct SubdivSettings *settings, const struct MultiresModifierData *mmd); +/* TODO(sergey): Replace this set of boolean flags with bitmask. */ void BKE_multires_subdiv_mesh_settings_init( struct SubdivToMeshSettings *mesh_settings, const struct Scene *scene, const struct Object *object, const struct MultiresModifierData *mmd, - const bool use_render_params); + const bool use_render_params, + const bool ignore_simplify); #endif /* __BKE_MULTIRES_H__ */ diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c index b7f53365334..b1d56ffef1f 100644 --- a/source/blender/blenkernel/intern/multires_reshape.c +++ b/source/blender/blenkernel/intern/multires_reshape.c @@ -395,7 +395,7 @@ static bool multires_reshape_from_vertcos(struct Depsgraph *depsgraph, /* Initialize mesh rasterization settings. */ SubdivToMeshSettings mesh_settings; BKE_multires_subdiv_mesh_settings_init( - &mesh_settings, scene_eval, object, mmd, use_render_params); + &mesh_settings, scene_eval, object, mmd, use_render_params, true); /* Run all the callbacks. */ BKE_subdiv_foreach_subdiv_geometry( ctx.subdiv, @@ -434,20 +434,34 @@ bool multiresModifier_reshapeFromDeformModifier( Object *object, ModifierData *md) { + /* It is possible that the current subdivision level of multires is lower + * that it's maximum possible one (i.e., viewport is set to a lower level + * for the performance purposes). But even then, we want all the multires + * levels to be reshaped. Most accurate way to do so is to ignore all + * simplifications and calculate deformation modifier for the highest + * possible multires level. + * Alternative would be propagate displacement from current level to a + * higher ones, but that is likely to cause artifacts. + */ + MultiresModifierData highest_mmd = *mmd; + highest_mmd.lvl = highest_mmd.totlvl; Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); /* Perform sanity checks and early output. */ - if (multires_get_level(scene_eval, object, mmd, false, true) == 0) { + if (multires_get_level( + scene_eval, object, &highest_mmd, false, true) == 0) { return false; } /* Create mesh for the multires, ignoring any further modifiers (leading * deformation modifiers will be applied though). */ - Mesh *multires_mesh = get_multires_mesh(depsgraph, scene_eval, mmd, object); + Mesh *multires_mesh = get_multires_mesh( + depsgraph, scene_eval, &highest_mmd, object); float (*deformed_verts)[3] = BKE_mesh_vertexCos_get(multires_mesh, NULL); /* Apply deformation modifier on the multires, */ - const ModifierEvalContext modifier_ctx = {.depsgraph = depsgraph, - .object = object, - .flag = 0}; + const ModifierEvalContext modifier_ctx = { + .depsgraph = depsgraph, + .object = object, + .flag = MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY}; modifier_deformVerts_ensure_normals( md, &modifier_ctx, multires_mesh, deformed_verts, multires_mesh->totvert); @@ -457,7 +471,7 @@ bool multiresModifier_reshapeFromDeformModifier( bool result = multires_reshape_from_vertcos( depsgraph, object, - mmd, + &highest_mmd, deformed_verts, num_deformed_verts, false); diff --git a/source/blender/blenkernel/intern/multires_subdiv.c b/source/blender/blenkernel/intern/multires_subdiv.c index ef19fdb6f28..2df931328c2 100644 --- a/source/blender/blenkernel/intern/multires_subdiv.c +++ b/source/blender/blenkernel/intern/multires_subdiv.c @@ -56,9 +56,10 @@ void BKE_multires_subdiv_mesh_settings_init( const Scene *scene, const Object *object, const MultiresModifierData *mmd, - const bool use_render_params) + const bool use_render_params, + const bool ignore_simplify) { const int level = multires_get_level( - scene, object, mmd, use_render_params, false); + scene, object, mmd, use_render_params, ignore_simplify); mesh_settings->resolution = (1 << level) + 1; } diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 6e51b229ec5..1298ad63604 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -147,6 +147,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md, Mesh *mesh) { const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); + const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY); const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); Object *object = ctx->object; Mesh *result = mesh; @@ -155,7 +156,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md, BKE_multires_subdiv_settings_init(&subdiv_settings, mmd); SubdivToMeshSettings mesh_settings; BKE_multires_subdiv_mesh_settings_init( - &mesh_settings, scene, object, mmd, use_render_params); + &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify); if (subdiv_settings.level == 0 || mesh_settings.resolution < 3) { /* NOTE: Shouldn't really happen, is supposed to be catched by * isDisabled() callback. |