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/blenkernel/intern/subdiv.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/blenkernel/intern/subdiv.c')
-rw-r--r-- | source/blender/blenkernel/intern/subdiv.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c index 370448d117f..635cb64c772 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.c @@ -66,8 +66,25 @@ BKE_subdiv_fvar_interpolation_from_uv_smooth(int uv_smooth) return SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL; } +/* ================================ SETTINGS ================================ */ + +bool BKE_subdiv_settings_equal(const SubdivSettings *settings_a, + const SubdivSettings *settings_b) +{ + return + (settings_a->is_simple == settings_b->is_simple && + settings_a->is_adaptive == settings_b->is_adaptive && + settings_a->level == settings_b->level && + settings_a->vtx_boundary_interpolation == + settings_b->vtx_boundary_interpolation && + settings_a->fvar_linear_interpolation == + settings_b->fvar_linear_interpolation); +} + /* ============================== CONSTRUCTION ============================== */ +/* Creation from scratch. */ + Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, struct OpenSubdiv_Converter *converter) { @@ -82,7 +99,6 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, osd_topology_refiner = openSubdiv_createTopologyRefinerFromConverter( converter, &topology_refiner_settings); - } else { /* TODO(sergey): Check whether original geometry had any vertices. @@ -112,6 +128,53 @@ Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings, return subdiv; } +/* Creation with cached-aware semantic. */ + +Subdiv *BKE_subdiv_update_from_converter(Subdiv *subdiv, + const SubdivSettings *settings, + OpenSubdiv_Converter *converter) +{ + /* Check if the existing descriptor can be re-used. */ + bool can_reuse_subdiv = true; + if (subdiv != NULL && subdiv->topology_refiner != NULL) { + if (!BKE_subdiv_settings_equal(&subdiv->settings, settings)) { + can_reuse_subdiv = false; + } + else { + BKE_subdiv_stats_begin( + &subdiv->stats, SUBDIV_STATS_TOPOLOGY_COMPARE); + can_reuse_subdiv = openSubdiv_topologyRefinerCompareWithConverter( + subdiv->topology_refiner, converter); + BKE_subdiv_stats_end( + &subdiv->stats, SUBDIV_STATS_TOPOLOGY_COMPARE); + } + } + else { + can_reuse_subdiv = false; + } + if (can_reuse_subdiv) { + return subdiv; + } + /* Create new subdiv. */ + if (subdiv != NULL) { + BKE_subdiv_free(subdiv); + } + return BKE_subdiv_new_from_converter(settings, converter); +} + +Subdiv *BKE_subdiv_update_from_mesh(Subdiv *subdiv, + const SubdivSettings *settings, + const Mesh *mesh) +{ + OpenSubdiv_Converter converter; + BKE_subdiv_converter_init_for_mesh(&converter, settings, mesh); + subdiv = BKE_subdiv_update_from_converter(subdiv, settings, &converter); + BKE_subdiv_converter_free(&converter); + return subdiv; +} + +/* Memory release. */ + void BKE_subdiv_free(Subdiv *subdiv) { if (subdiv->evaluator != NULL) { |