diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-01-17 16:50:47 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-01-17 16:51:04 +0300 |
commit | 0a08ac2528eee972c4dc23554ffd088305e6ae92 (patch) | |
tree | 2ef9014dc16053ce6d249d877110766b0972a2ac /source/blender/blenkernel | |
parent | 9d3f35a0bf1bf5776363bfd61d53a7c85b5827a4 (diff) |
Alembic: add support for reading override layers
Override layers are a standard feature of Alembic, where archives can override
data from other archives, provided that the hierarchies match.
This is useful for modifying a UV map, updating an animation, or even creating
some sort of LOD system where low resolution meshes are swapped by high resolution
versions.
It is possible to add UV maps and vertex colors using this system, however, they
will only appear in the spreadsheet editor when viewing evaluated data, as the UV
map and Vertex color UI only show data present on the original mesh.
Implementation wise, this adds a `CacheFileLayer` data structure to the `CacheFile`
DNA, as well as some operators and UI to present and manage the layers. For both
the Alembic importer and the Cycles procedural, the main change is creating an
archive from a list of filepaths, instead of a single one.
After importing the base file through the regular import operator, layers can be added
to or removed from the `CacheFile` via the UI list under the `Override Layers` panel
located in the Mesh Sequence Cache modifier. Layers can also be moved around or
hidden.
See differential page for tests files and demos.
Reviewed by: brecht, sybren
Differential Revision: https://developer.blender.org/D13603
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_cachefile.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cachefile.c | 47 |
2 files changed, 56 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h index 0ab814c2d94..c6821d88d2a 100644 --- a/source/blender/blenkernel/BKE_cachefile.h +++ b/source/blender/blenkernel/BKE_cachefile.h @@ -28,6 +28,7 @@ extern "C" { #endif struct CacheFile; +struct CacheFileLayer; struct CacheReader; struct Depsgraph; struct Main; @@ -69,6 +70,15 @@ bool BKE_cache_file_uses_render_procedural(const struct CacheFile *cache_file, struct Scene *scene, int dag_eval_mode); +/* Add a layer to the cache_file. Return NULL if the filename is already that of an existing layer + * or if the number of layers exceeds the maximum allowed layer count. */ +struct CacheFileLayer *BKE_cachefile_add_layer(struct CacheFile *cache_file, + const char filename[1024]); + +struct CacheFileLayer *BKE_cachefile_get_active_layer(struct CacheFile *cache_file); + +void BKE_cachefile_remove_layer(struct CacheFile *cache_file, struct CacheFileLayer *layer); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index 8833f3eabe9..75df2e98fcd 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -54,6 +54,8 @@ #include "BLO_read_write.h" +#include "MEM_guardedalloc.h" + #ifdef WITH_ALEMBIC # include "ABC_alembic.h" #endif @@ -86,6 +88,7 @@ static void cache_file_copy_data(Main *UNUSED(bmain), cache_file_dst->handle = NULL; cache_file_dst->handle_readers = NULL; BLI_duplicatelist(&cache_file_dst->object_paths, &cache_file_src->object_paths); + BLI_duplicatelist(&cache_file_dst->layers, &cache_file_src->layers); } static void cache_file_free_data(ID *id) @@ -93,6 +96,7 @@ static void cache_file_free_data(ID *id) CacheFile *cache_file = (CacheFile *)id; cachefile_handle_free(cache_file); BLI_freelistN(&cache_file->object_paths); + BLI_freelistN(&cache_file->layers); } static void cache_file_foreach_path(ID *id, BPathForeachPathData *bpath_data) @@ -117,6 +121,11 @@ static void cache_file_blend_write(BlendWriter *writer, ID *id, const void *id_a if (cache_file->adt) { BKE_animdata_blend_write(writer, cache_file->adt); } + + /* write layers */ + LISTBASE_FOREACH (CacheFileLayer *, layer, &cache_file->layers) { + BLO_write_struct(writer, CacheFileLayer, layer); + } } static void cache_file_blend_read_data(BlendDataReader *reader, ID *id) @@ -130,6 +139,9 @@ static void cache_file_blend_read_data(BlendDataReader *reader, ID *id) /* relink animdata */ BLO_read_data_address(reader, &cache_file->adt); BKE_animdata_blend_read_data(reader, cache_file->adt); + + /* relink layers */ + BLO_read_list(reader, &cache_file->layers); } IDTypeInfo IDType_ID_CF = { @@ -364,7 +376,8 @@ void BKE_cachefile_eval(Main *bmain, Depsgraph *depsgraph, CacheFile *cache_file #ifdef WITH_ALEMBIC if (BLI_path_extension_check_glob(filepath, "*abc")) { cache_file->type = CACHEFILE_TYPE_ALEMBIC; - cache_file->handle = ABC_create_handle(bmain, filepath, &cache_file->object_paths); + cache_file->handle = ABC_create_handle( + bmain, filepath, cache_file->layers.first, &cache_file->object_paths); BLI_strncpy(cache_file->handle_filepath, filepath, FILE_MAX); } #endif @@ -435,3 +448,35 @@ bool BKE_cache_file_uses_render_procedural(const CacheFile *cache_file, const bool is_final_render = (eEvaluationMode)dag_eval_mode == DAG_EVAL_RENDER; return cache_file->use_render_procedural && !is_final_render; } + +CacheFileLayer *BKE_cachefile_add_layer(CacheFile *cache_file, const char filename[1024]) +{ + for (CacheFileLayer *layer = cache_file->layers.first; layer; layer = layer->next) { + if (STREQ(layer->filepath, filename)) { + return NULL; + } + } + + const int num_layers = BLI_listbase_count(&cache_file->layers); + + CacheFileLayer *layer = MEM_callocN(sizeof(CacheFileLayer), "CacheFileLayer"); + BLI_strncpy(layer->filepath, filename, sizeof(layer->filepath)); + + BLI_addtail(&cache_file->layers, layer); + + cache_file->active_layer = (char)(num_layers + 1); + + return layer; +} + +CacheFileLayer *BKE_cachefile_get_active_layer(CacheFile *cache_file) +{ + return BLI_findlink(&cache_file->layers, cache_file->active_layer - 1); +} + +void BKE_cachefile_remove_layer(CacheFile *cache_file, CacheFileLayer *layer) +{ + cache_file->active_layer = 0; + BLI_remlink(&cache_file->layers, layer); + MEM_freeN(layer); +} |