diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-01-15 17:34:11 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-01-16 13:00:43 +0300 |
commit | b0c6c65e7b45bf66f2f9e0aa3718be7eb0f72f81 (patch) | |
tree | 74f3aeb53634bd80bdca4d5626ee9e8fe09b5caf /source/blender/modifiers/intern/MOD_subsurf.c | |
parent | e064777cac02a065e20a9453f6d2a03651250d56 (diff) |
Subdiv: Initial implementation of topology cache
This commit makes it so OpenSubdiv's topology refiner is kept
in memory and reused for until topology changes. There are the
following modifications which causes topology refiner to become
invalid:
- Change in a mesh topology (for example, vertices, edges, and
faces connectivity).
- Change in UV islands (adding new islands, merging them and
so on),
- Change in UV smoothing options.
- Change in creases.
- Change in Catmull-Clark / Simple subdivisions.
The following limitations are known:
- CPU evaluator is not yet cached.
- UV islands topology is not checked.
The UV limitation is currently a stopper for making this cache
enabled by default.
Diffstat (limited to 'source/blender/modifiers/intern/MOD_subsurf.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_subsurf.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index e66b3fdbafb..6394ab458e7 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -89,6 +89,9 @@ static void freeData(ModifierData *md) ccgSubSurf_free(smd->emCache); smd->emCache = NULL; } + if (smd->subdiv != NULL) { + BKE_subdiv_free(smd->subdiv); + } } static bool isDisabled(const Scene *scene, ModifierData *md, bool useRenderParams) @@ -122,6 +125,20 @@ static void subdiv_settings_init(SubdivSettings *settings, BKE_subdiv_fvar_interpolation_from_uv_smooth(smd->uv_smooth); } +/* Main goal of this function is to give usable subdivision surface descriptor + * which matches settings and topology. */ +static Subdiv *subdiv_descriptor_ensure(SubsurfModifierData *smd, + const SubdivSettings *subdiv_settings, + const Mesh *mesh) +{ + Subdiv *subdiv = BKE_subdiv_update_from_mesh( + smd->subdiv, subdiv_settings, mesh); + if (false) { + smd->subdiv = subdiv; + } + return subdiv; +} + /* Subdivide into fully qualified mesh. */ static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, @@ -189,24 +206,23 @@ 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(smd, &subdiv_settings, mesh); if (subdiv == NULL) { - /* Happens on bad topology, ut also on empty input mesh. */ + /* Happens on bad topology, but also on empty input mesh. */ return result; } /* TODO(sergey): Decide whether we ever want to use CCG for subsurf, - * maybe when it is a last modifier in the stack? - */ + * maybe when it is a last modifier in the stack? */ if (true) { result = subdiv_as_mesh(smd, ctx, mesh, subdiv); } else { result = subdiv_as_ccg(smd, ctx, mesh, subdiv); } - /* TODO(sergey): Cache subdiv somehow. */ // BKE_subdiv_stats_print(&subdiv->stats); - BKE_subdiv_free(subdiv); + if (subdiv != smd->subdiv) { + BKE_subdiv_free(subdiv); + } return result; } |