Multires: Fix reshape when active level is lower than the total one

This commit is contained in:
2018-08-22 16:07:39 +02:00
parent 9dd279cbdf
commit 6a681981e4
4 changed files with 29 additions and 11 deletions

View File

@@ -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__ */

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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.