Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c35
3 files changed, 34 insertions, 7 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 0094a6a2f57..ff79ba056e1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5393,6 +5393,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
BevelModifierData *bmd = (BevelModifierData *)md;
bmd->clnordata.faceHash = NULL;
}
+ else if (md->type == eModifierType_Multires) {
+ MultiresModifierData *mmd = (MultiresModifierData *)md;
+ mmd->subdiv = NULL;
+ }
}
}
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 30c093ab3a8..101d655ded5 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -949,6 +949,8 @@ typedef struct MultiresModifierData {
short quality;
short uv_smooth;
short pad2[2];
+ struct Subdiv *subdiv;
+ void *pad3;
} MultiresModifierData;
typedef enum {
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index fc8a376d2d7..9775a536e99 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -67,6 +67,28 @@ static void initData(ModifierData *md)
mmd->quality = 3;
}
+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);
+ if (false) {
+ mmd->subdiv = subdiv;
+ }
+ return subdiv;
+}
+
/* Subdivide into fully qualified mesh. */
static Mesh *multires_as_mesh(MultiresModifierData *mmd,
@@ -137,16 +159,14 @@ 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);
+ 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. */
@@ -156,9 +176,10 @@ static Mesh *applyModifier(ModifierData *md,
}
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;
}
@@ -188,7 +209,7 @@ ModifierTypeInfo modifierType_Multires = {
/* initData */ initData,
/* requiredDataMask */ NULL,
- /* freeData */ NULL,
+ /* freeData */ freeData,
/* isDisabled */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,