diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_multires.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_multires.c | 78 |
1 files changed, 54 insertions, 24 deletions
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index fc8a376d2d7..7cd9dfa05aa 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -1,6 +1,4 @@ /* - * ***** BEGIN GPL LICENSE BLOCK ***** - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -17,35 +15,26 @@ * * The Original Code is Copyright (C) 2005 by the Blender Foundation. * All rights reserved. - * - * Contributor(s): Daniel Dunbar - * Ton Roosendaal, - * Ben Batt, - * Brecht Van Lommel, - * Campbell Barton - * - * ***** END GPL LICENSE BLOCK ***** - * */ -/** \file blender/modifiers/intern/MOD_multires.c - * \ingroup modifiers +/** \file + * \ingroup modifiers */ #include <stddef.h> +#include "BLI_utildefines.h" + #include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BLI_utildefines.h" - #include "BKE_cdderivedmesh.h" -#include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_modifier.h" +#include "BKE_paint.h" #include "BKE_subdiv.h" #include "BKE_subdiv_ccg.h" #include "BKE_subdiv_mesh.h" @@ -67,6 +56,35 @@ static void initData(ModifierData *md) mmd->quality = 3; } +static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag) +{ + MultiresModifierData *mmd_dst = (MultiresModifierData *)md_dst; + + modifier_copyData_generic(md_src, md_dst, flag); + + mmd_dst->subdiv = NULL; +} + +static void freeData(ModifierData *md) +{ + MultiresModifierData *mmd = (MultiresModifierData *) md; + if (mmd->subdiv != NULL) { + BKE_subdiv_free(mmd->subdiv); + } +} + +/* Main goal of this function is to give usable subdivision surface descriptor + * which matches settings and topology. */ +static Subdiv *subdiv_descriptor_ensure(MultiresModifierData *mmd, + const SubdivSettings *subdiv_settings, + const Mesh *mesh) +{ + Subdiv *subdiv = BKE_subdiv_update_from_mesh( + mmd->subdiv, subdiv_settings, mesh); + mmd->subdiv = subdiv; + return subdiv; +} + /* Subdivide into fully qualified mesh. */ static Mesh *multires_as_mesh(MultiresModifierData *mmd, @@ -137,28 +155,40 @@ static Mesh *applyModifier(ModifierData *md, if (subdiv_settings.level == 0) { return result; } - /* TODO(sergey): Try to re-use subdiv when possible. */ - Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, mesh); + BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh); + Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh); if (subdiv == NULL) { /* Happens on bad topology, ut also on empty input mesh. */ return result; } /* NOTE: Orco needs final coordinates on CPU side, which are expected to be * accessible via MVert. For this reason we do not evaluate multires to - * grids when orco is requested. - */ + * grids when orco is requested. */ const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0; if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) { /* NOTE: CCG takes ownership over Subdiv. */ result = multires_as_ccg(mmd, ctx, mesh, subdiv); result->runtime.subdiv_ccg_tot_level = mmd->totlvl; + /* TODO(sergey): Usually it is sculpt stroke's update variants which + * takes care of this, but is possible that we need this before the + * stroke: i.e. when exiting blender right after stroke is done. + * Annoying and not so much black-boxed as far as sculpting goes, and + * surely there is a better way of solving this. */ + if (ctx->object->sculpt != NULL) { + ctx->object->sculpt->subdiv_ccg = result->runtime.subdiv_ccg; + } + /* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share + * this pointer. Not sure if it's needed, but might have a second look + * on the ownership model here. */ + mmd->subdiv = NULL; // BKE_subdiv_stats_print(&subdiv->stats); } else { result = multires_as_mesh(mmd, ctx, mesh, subdiv); - /* TODO(sergey): Cache subdiv somehow. */ // BKE_subdiv_stats_print(&subdiv->stats); - BKE_subdiv_free(subdiv); + if (subdiv != mmd->subdiv) { + BKE_subdiv_free(subdiv); + } } return result; } @@ -172,7 +202,7 @@ ModifierTypeInfo modifierType_Multires = { eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_RequiresOriginalData, - /* copyData */ modifier_copyData_generic, + /* copyData */ copyData, /* deformVerts_DM */ NULL, /* deformMatrices_DM */ NULL, @@ -188,7 +218,7 @@ ModifierTypeInfo modifierType_Multires = { /* initData */ initData, /* requiredDataMask */ NULL, - /* freeData */ NULL, + /* freeData */ freeData, /* isDisabled */ NULL, /* updateDepsgraph */ NULL, /* dependsOnTime */ NULL, |