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:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/alembic/intern/abc_object.cc3
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc7
-rw-r--r--source/blender/blenkernel/BKE_cachefile.h27
-rw-r--r--source/blender/blenkernel/intern/cachefile.c247
-rw-r--r--source/blender/blenkernel/intern/constraint.c24
-rw-r--r--source/blender/blenkernel/intern/scene.c9
-rw-r--r--source/blender/blenloader/intern/readfile.c5
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc11
-rw-r--r--source/blender/editors/interface/interface_templates.c5
-rw-r--r--source/blender/editors/io/io_cache.c14
-rw-r--r--source/blender/makesdna/DNA_cachefile_types.h12
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h5
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_cachefile.c38
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c18
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c15
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c28
18 files changed, 229 insertions, 252 deletions
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index 36daa50e095..e437273c1be 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -364,9 +364,6 @@ void AbcObjectReader::addCacheModifier()
id_us_plus(&mcmd->cache_file->id);
BLI_strncpy(mcmd->object_path, m_iobject.getFullName().c_str(), FILE_MAX);
-
- mcmd->reader = reinterpret_cast<CacheReader *>(this);
- this->incref();
}
chrono_t AbcObjectReader::minTime() const
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 3ff3fbe2001..b502692d0e5 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -627,6 +627,7 @@ struct ImportJobData {
char filename[1024];
ImportSettings settings;
+ ArchiveReader *archive;
std::vector<AbcObjectReader *> readers;
short *stop;
@@ -672,9 +673,9 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
cache_file->is_sequence = data->settings.is_sequence;
cache_file->scale = data->settings.scale;
- cache_file->handle = handle_from_archive(archive);
- BLI_strncpy(cache_file->filepath, data->filename, 1024);
+ STRNCPY(cache_file->filepath, data->filename);
+ data->archive = archive;
data->settings.cache_file = cache_file;
*data->do_update = true;
@@ -855,6 +856,7 @@ static void import_endjob(void *user_data)
static void import_freejob(void *user_data)
{
ImportJobData *data = static_cast<ImportJobData *>(user_data);
+ delete data->archive;
delete data;
}
@@ -886,6 +888,7 @@ bool ABC_import(bContext *C,
job->settings.validate_meshes = validate_meshes;
job->error_code = ABC_NO_ERROR;
job->was_cancelled = false;
+ job->archive = NULL;
G.is_break = false;
diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h
index b991ac24284..257975e3c17 100644
--- a/source/blender/blenkernel/BKE_cachefile.h
+++ b/source/blender/blenkernel/BKE_cachefile.h
@@ -29,8 +29,10 @@ extern "C" {
#endif
struct CacheFile;
+struct CacheReader;
struct Depsgraph;
struct Main;
+struct Object;
struct Scene;
void BKE_cachefiles_init(void);
@@ -52,24 +54,27 @@ void BKE_cachefile_make_local(struct Main *bmain,
struct CacheFile *cache_file,
const bool lib_local);
-void BKE_cachefile_reload(const struct Main *bmain, struct CacheFile *cache_file);
+void BKE_cachefile_reload(struct Depsgraph *depsgraph, struct CacheFile *cache_file);
-void BKE_cachefile_ensure_handle(const struct Main *bmain, struct CacheFile *cache_file);
-
-void BKE_cachefile_update_frame(struct Main *bmain,
- struct Depsgraph *depsgraph,
- struct Scene *scene,
- const float ctime,
- const float fps);
+void BKE_cachefile_eval(struct Main *bmain,
+ struct Depsgraph *depsgraph,
+ struct CacheFile *cache_file);
bool BKE_cachefile_filepath_get(const struct Main *bmain,
+ const struct Depsgraph *depsgrah,
const struct CacheFile *cache_file,
- float frame,
char r_filename[1024]);
-float BKE_cachefile_time_offset(struct CacheFile *cache_file, const float time, const float fps);
+float BKE_cachefile_time_offset(const struct CacheFile *cache_file,
+ const float time,
+ const float fps);
-void BKE_cachefile_clean(struct Main *bmain, struct CacheFile *cache_file);
+/* Modifiers and constraints open and free readers through these. */
+void BKE_cachefile_reader_open(struct CacheFile *cache_file,
+ struct CacheReader **reader,
+ struct Object *object,
+ const char *object_path);
+void BKE_cachefile_reader_free(struct CacheFile *cache_file, struct CacheReader **reader);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index e4fc4706e66..a60b840344c 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -21,18 +21,21 @@
* \ingroup bke
*/
+#include <string.h>
+
#include "DNA_anim_types.h"
#include "DNA_cachefile_types.h"
#include "DNA_constraint_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
+#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_threads.h"
-#include "BLI_utildefines.h"
#include "BKE_animsys.h"
#include "BKE_cachefile.h"
@@ -41,10 +44,13 @@
#include "BKE_modifier.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph_query.h"
+
#ifdef WITH_ALEMBIC
# include "ABC_alembic.h"
#endif
+/* TODO: make this per cache file to avoid global locks. */
static SpinLock spin;
void BKE_cachefiles_init(void)
@@ -57,6 +63,94 @@ void BKE_cachefiles_exit(void)
BLI_spin_end(&spin);
}
+void BKE_cachefile_reader_open(CacheFile *cache_file,
+ struct CacheReader **reader,
+ Object *object,
+ const char *object_path)
+{
+#ifdef WITH_ALEMBIC
+ BLI_assert(cache_file->id.tag & LIB_TAG_COPIED_ON_WRITE);
+
+ if (cache_file->handle == NULL) {
+ return;
+ }
+
+ /* Open Alembic cache reader. */
+ *reader = CacheReader_open_alembic_object(cache_file->handle, *reader, object, object_path);
+
+ /* Multiple modifiers and constraints can call this function concurrently. */
+ BLI_spin_lock(&spin);
+ if (*reader) {
+ /* Register in set so we can free it when the cache file changes. */
+ if (cache_file->handle_readers == NULL) {
+ cache_file->handle_readers = BLI_gset_ptr_new("CacheFile.handle_readers");
+ }
+ BLI_gset_reinsert(cache_file->handle_readers, reader, NULL);
+ }
+ else if (cache_file->handle_readers) {
+ /* Remove in case CacheReader_open_alembic_object free the existing reader. */
+ BLI_gset_remove(cache_file->handle_readers, reader, NULL);
+ }
+ BLI_spin_unlock(&spin);
+#else
+ UNUSED_VARS(reader, object, object_path);
+#endif
+}
+
+void BKE_cachefile_reader_free(CacheFile *cache_file, struct CacheReader **reader)
+{
+#ifdef WITH_ALEMBIC
+ BLI_assert(cache_file->id.tag & LIB_TAG_COPIED_ON_WRITE);
+
+ if (*reader != NULL) {
+ CacheReader_free(*reader);
+ *reader = NULL;
+
+ /* Multiple modifiers and constraints can call this function concurrently. */
+ BLI_spin_lock(&spin);
+ if (cache_file->handle_readers) {
+ BLI_gset_remove(cache_file->handle_readers, reader, NULL);
+ }
+ BLI_spin_unlock(&spin);
+ }
+#else
+ UNUSED_VARS(cache_file, reader);
+#endif
+}
+
+static void cachefile_handle_free(CacheFile *cache_file)
+{
+#ifdef WITH_ALEMBIC
+ /* Free readers in all modifiers and constraints that use the handle, before
+ * we free the handle itself. */
+ BLI_spin_lock(&spin);
+ if (cache_file->handle_readers) {
+ GSetIterator gs_iter;
+ GSET_ITER (gs_iter, cache_file->handle_readers) {
+ struct CacheReader **reader = BLI_gsetIterator_getKey(&gs_iter);
+ if (*reader != NULL) {
+ CacheReader_free(*reader);
+ *reader = NULL;
+ }
+ }
+
+ BLI_gset_free(cache_file->handle_readers, NULL);
+ cache_file->handle_readers = NULL;
+ }
+ BLI_spin_unlock(&spin);
+
+ /* Free handle. */
+ if (cache_file->handle) {
+ ABC_free_handle(cache_file->handle);
+ cache_file->handle = NULL;
+ }
+
+ cache_file->handle_filepath[0] = '\0';
+#else
+ UNUSED_VARS(cache_file);
+#endif
+}
+
void *BKE_cachefile_add(Main *bmain, const char *name)
{
CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, name, 0);
@@ -68,37 +162,23 @@ void *BKE_cachefile_add(Main *bmain, const char *name)
void BKE_cachefile_init(CacheFile *cache_file)
{
- cache_file->handle = NULL;
cache_file->filepath[0] = '\0';
cache_file->override_frame = false;
cache_file->frame = 0.0f;
cache_file->is_sequence = false;
cache_file->scale = 1.0f;
- cache_file->handle_mutex = BLI_mutex_alloc();
BLI_listbase_clear(&cache_file->object_paths);
+
+ cache_file->handle = NULL;
+ cache_file->handle_filepath[0] = '\0';
+ cache_file->handle_readers = NULL;
}
/** Free (or release) any data used by this cachefile (does not free the cachefile itself). */
void BKE_cachefile_free(CacheFile *cache_file)
{
BKE_animdata_free((ID *)cache_file, false);
-
- if (cache_file->id.tag & LIB_TAG_NO_MAIN) {
- /* CoW/no-main copies reuse the existing ArchiveReader and mutex */
- return;
- }
-
- if (cache_file->handle) {
-#ifdef WITH_ALEMBIC
- ABC_free_handle(cache_file->handle);
-#endif
- cache_file->handle = NULL;
- }
- if (cache_file->handle_mutex) {
- BLI_mutex_free(cache_file->handle_mutex);
- cache_file->handle_mutex = NULL;
- }
-
+ cachefile_handle_free(cache_file);
BLI_freelistN(&cache_file->object_paths);
}
@@ -117,13 +197,8 @@ void BKE_cachefile_copy_data(Main *UNUSED(bmain),
const CacheFile *UNUSED(cache_file_src),
const int UNUSED(flag))
{
- if (cache_file_dst->id.tag & LIB_TAG_NO_MAIN) {
- /* CoW/no-main copies reuse the existing ArchiveReader and mutex */
- return;
- }
-
cache_file_dst->handle = NULL;
- cache_file_dst->handle_mutex = NULL;
+ cache_file_dst->handle_readers = NULL;
BLI_duplicatelist(&cache_file_dst->object_paths, &cache_file_dst->object_paths);
}
@@ -139,72 +214,51 @@ void BKE_cachefile_make_local(Main *bmain, CacheFile *cache_file, const bool lib
BKE_id_make_local_generic(bmain, &cache_file->id, true, lib_local);
}
-void BKE_cachefile_reload(const Main *bmain, CacheFile *cache_file)
+void BKE_cachefile_reload(Depsgraph *depsgraph, CacheFile *cache_file)
{
- char filepath[FILE_MAX];
-
- BLI_strncpy(filepath, cache_file->filepath, sizeof(filepath));
- BLI_path_abs(filepath, ID_BLEND_PATH(bmain, &cache_file->id));
-
-#ifdef WITH_ALEMBIC
- if (cache_file->handle) {
- ABC_free_handle(cache_file->handle);
+ /* To force reload, free the handle and tag depsgraph to load it again. */
+ CacheFile *cache_file_eval = (CacheFile *)DEG_get_evaluated_id(depsgraph, &cache_file->id);
+ if (cache_file_eval) {
+ cachefile_handle_free(cache_file_eval);
}
- cache_file->handle = ABC_create_handle(filepath, &cache_file->object_paths);
-#endif
+ DEG_id_tag_update(&cache_file->id, ID_RECALC_COPY_ON_WRITE);
}
-void BKE_cachefile_ensure_handle(const Main *bmain, CacheFile *cache_file)
+void BKE_cachefile_eval(Main *bmain, Depsgraph *depsgraph, CacheFile *cache_file)
{
- BLI_spin_lock(&spin);
- if (cache_file->handle_mutex == NULL) {
- cache_file->handle_mutex = BLI_mutex_alloc();
- }
- BLI_spin_unlock(&spin);
-
- BLI_mutex_lock(cache_file->handle_mutex);
+ BLI_assert(cache_file->id.tag & LIB_TAG_COPIED_ON_WRITE);
- if (cache_file->handle == NULL) {
- /* Assigning to a CoW copy is a bad idea; assign to the original instead. */
- BLI_assert((cache_file->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0);
- BKE_cachefile_reload(bmain, cache_file);
+ /* Compute filepath. */
+ char filepath[FILE_MAX];
+ if (!BKE_cachefile_filepath_get(bmain, depsgraph, cache_file, filepath)) {
+ return;
}
- BLI_mutex_unlock(cache_file->handle_mutex);
-}
-
-void BKE_cachefile_update_frame(
- Main *bmain, struct Depsgraph *depsgraph, Scene *scene, const float ctime, const float fps)
-{
- CacheFile *cache_file;
- char filename[FILE_MAX];
-
- for (cache_file = bmain->cachefiles.first; cache_file; cache_file = cache_file->id.next) {
- /* TODO: dependency graph should be updated to do drivers on cachefile.
- * Execute drivers only, as animation has already been done. */
- BKE_animsys_evaluate_animdata(
- depsgraph, scene, &cache_file->id, cache_file->adt, ctime, ADT_RECALC_DRIVERS);
-
- if (!cache_file->is_sequence) {
- continue;
- }
+ /* Test if filepath change or if we can keep the existing handle. */
+ if (STREQ(cache_file->handle_filepath, filepath)) {
+ return;
+ }
- const float time = BKE_cachefile_time_offset(cache_file, ctime, fps);
+ cachefile_handle_free(cache_file);
+ BLI_freelistN(&cache_file->object_paths);
- if (BKE_cachefile_filepath_get(bmain, cache_file, time, filename)) {
- BKE_cachefile_clean(bmain, cache_file);
#ifdef WITH_ALEMBIC
- ABC_free_handle(cache_file->handle);
- cache_file->handle = ABC_create_handle(filename, NULL);
+ cache_file->handle = ABC_create_handle(filepath, &cache_file->object_paths);
+ BLI_strncpy(cache_file->handle_filepath, filepath, FILE_MAX);
#endif
- }
+
+ if (DEG_is_active(depsgraph)) {
+ /* Flush object paths back to original datablock for UI. */
+ CacheFile *cache_file_orig = (CacheFile *)DEG_get_original_id(&cache_file->id);
+ BLI_freelistN(&cache_file_orig->object_paths);
+ BLI_duplicatelist(&cache_file_orig->object_paths, &cache_file->object_paths);
}
}
bool BKE_cachefile_filepath_get(const Main *bmain,
+ const Depsgraph *depsgraph,
const CacheFile *cache_file,
- float frame,
char r_filepath[FILE_MAX])
{
BLI_strncpy(r_filepath, cache_file->filepath, FILE_MAX);
@@ -214,6 +268,11 @@ bool BKE_cachefile_filepath_get(const Main *bmain,
int frame_len;
if (cache_file->is_sequence && BLI_path_frame_get(r_filepath, &fframe, &frame_len)) {
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ const float ctime = BKE_scene_frame_get(scene);
+ const float fps = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base);
+ const float frame = BKE_cachefile_time_offset(cache_file, ctime, fps);
+
char ext[32];
BLI_path_frame_strip(r_filepath, ext);
BLI_path_frame(r_filepath, frame, frame_len);
@@ -226,47 +285,9 @@ bool BKE_cachefile_filepath_get(const Main *bmain,
return true;
}
-float BKE_cachefile_time_offset(CacheFile *cache_file, const float time, const float fps)
+float BKE_cachefile_time_offset(const CacheFile *cache_file, const float time, const float fps)
{
const float time_offset = cache_file->frame_offset / fps;
const float frame = (cache_file->override_frame ? cache_file->frame : time);
return cache_file->is_sequence ? frame : frame / fps - time_offset;
}
-
-/* TODO(kevin): replace this with some depsgraph mechanism, or something similar. */
-void BKE_cachefile_clean(struct Main *bmain, CacheFile *cache_file)
-{
- for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
- ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache);
-
- if (md) {
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
-
- if (cache_file == mcmd->cache_file) {
-#ifdef WITH_ALEMBIC
- if (mcmd->reader != NULL) {
- CacheReader_free(mcmd->reader);
- }
-#endif
- mcmd->reader = NULL;
- }
- }
-
- for (bConstraint *con = ob->constraints.first; con; con = con->next) {
- if (con->type != CONSTRAINT_TYPE_TRANSFORM_CACHE) {
- continue;
- }
-
- bTransformCacheConstraint *data = con->data;
-
- if (cache_file == data->cache_file) {
-#ifdef WITH_ALEMBIC
- if (data->reader != NULL) {
- CacheReader_free(data->reader);
- }
-#endif
- data->reader = NULL;
- }
- }
- }
-}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index a475a16dd57..0e29f165992 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -4835,13 +4835,9 @@ static void transformcache_evaluate(bConstraint *con, bConstraintOb *cob, ListBa
const float frame = DEG_get_ctime(cob->depsgraph);
const float time = BKE_cachefile_time_offset(cache_file, frame, FPS);
- /* Must always load ABC handle on original. */
- CacheFile *cache_file_orig = (CacheFile *)DEG_get_original_id(&cache_file->id);
- BKE_cachefile_ensure_handle(G.main, cache_file_orig);
-
- if (!data->reader) {
- data->reader = CacheReader_open_alembic_object(
- cache_file_orig->handle, data->reader, cob->ob, data->object_path);
+ if (!data->reader || !STREQ(data->reader_object_path, data->object_path)) {
+ STRNCPY(data->reader_object_path, data->object_path);
+ BKE_cachefile_reader_open(cache_file, &data->reader, cob->ob, data->object_path);
}
ABC_get_transform(data->reader, cob->matrix, time, cache_file->scale);
@@ -4859,12 +4855,8 @@ static void transformcache_copy(bConstraint *con, bConstraint *srccon)
BLI_strncpy(dst->object_path, src->object_path, sizeof(dst->object_path));
dst->cache_file = src->cache_file;
-
-#ifdef WITH_ALEMBIC
- if (dst->reader) {
- CacheReader_incref(dst->reader);
- }
-#endif
+ dst->reader = NULL;
+ dst->reader_object_path[0] = '\0';
}
static void transformcache_free(bConstraint *con)
@@ -4872,10 +4864,8 @@ static void transformcache_free(bConstraint *con)
bTransformCacheConstraint *data = con->data;
if (data->reader) {
-#ifdef WITH_ALEMBIC
- CacheReader_free(data->reader);
-#endif
- data->reader = NULL;
+ BKE_cachefile_reader_free(data->cache_file, &data->reader);
+ data->reader_object_path[0] = '\0';
}
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index e0bf62402d2..58b36aed24f 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1565,15 +1565,6 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
BKE_image_editors_update_frame(bmain, scene->r.cfra);
BKE_sound_set_cfra(scene->r.cfra);
DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
- /* Update animated cache files for modifiers.
- *
- * TODO(sergey): Make this a depsgraph node?
- */
- BKE_cachefile_update_frame(bmain,
- depsgraph,
- scene,
- ctime,
- (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base));
#ifdef POSE_ANIMATION_WORKAROUND
scene_armature_depsgraph_workaround(bmain, depsgraph);
#endif
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 55f02b45854..bf96cc9fa8e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3305,7 +3305,8 @@ static void direct_link_cachefile(FileData *fd, CacheFile *cache_file)
{
BLI_listbase_clear(&cache_file->object_paths);
cache_file->handle = NULL;
- cache_file->handle_mutex = NULL;
+ cache_file->handle_filepath[0] = '\0';
+ cache_file->handle_readers = NULL;
/* relink animdata */
cache_file->adt = newdataadr(fd, cache_file->adt);
@@ -3739,6 +3740,7 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
case CONSTRAINT_TYPE_TRANSFORM_CACHE: {
bTransformCacheConstraint *data = con->data;
data->reader = NULL;
+ data->reader_object_path[0] = '\0';
}
}
}
@@ -5745,6 +5747,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
else if (md->type == eModifierType_MeshSequenceCache) {
MeshSeqCacheModifierData *msmcd = (MeshSeqCacheModifierData *)md;
msmcd->reader = NULL;
+ msmcd->reader_object_path[0] = '\0';
}
else if (md->type == eModifierType_SurfaceDeform) {
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 87bbcef7f01..b6822a89093 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -65,6 +65,7 @@ extern "C" {
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_animsys.h"
+#include "BKE_cachefile.h"
#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
@@ -1469,11 +1470,16 @@ void DepsgraphNodeBuilder::build_cachefile(CacheFile *cache_file)
return;
}
ID *cache_file_id = &cache_file->id;
+ add_id_node(cache_file_id);
+ CacheFile *cache_file_cow = get_cow_datablock(cache_file);
/* Animation, */
build_animdata(cache_file_id);
build_parameters(cache_file_id);
/* Cache evaluation itself. */
- add_operation_node(cache_file_id, NodeType::CACHE, OperationCode::FILE_CACHE_UPDATE);
+ add_operation_node(cache_file_id,
+ NodeType::CACHE,
+ OperationCode::FILE_CACHE_UPDATE,
+ function_bind(BKE_cachefile_eval, bmain_, _1, cache_file_cow));
}
void DepsgraphNodeBuilder::build_mask(Mask *mask)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 147d82c5999..d3fd16d889f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -2222,6 +2222,14 @@ void DepsgraphRelationBuilder::build_cachefile(CacheFile *cache_file)
ComponentKey datablock_key(&cache_file->id, NodeType::CACHE);
add_relation(animation_key, datablock_key, "Datablock Animation");
}
+
+ /* Cache file updates */
+ if (cache_file->is_sequence) {
+ OperationKey cache_update_key(
+ &cache_file->id, NodeType::CACHE, OperationCode::FILE_CACHE_UPDATE);
+ TimeSourceKey time_src_key;
+ add_relation(time_src_key, cache_update_key, "TimeSrc -> Cache File Eval");
+ }
}
void DepsgraphRelationBuilder::build_mask(Mask *mask)
@@ -2329,7 +2337,8 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
continue;
}
int rel_flag = (RELATION_FLAG_NO_FLUSH | RELATION_FLAG_GODMODE);
- if (id_type == ID_ME && comp_node->type == NodeType::GEOMETRY) {
+ if ((id_type == ID_ME && comp_node->type == NodeType::GEOMETRY) ||
+ (id_type == ID_CF && comp_node->type == NodeType::CACHE)) {
rel_flag &= ~RELATION_FLAG_NO_FLUSH;
}
/* Notes on exceptions:
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index f656e917c44..e96141eaa05 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -6711,17 +6711,18 @@ void uiTemplateCacheFile(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
uiItemR(row, &fileptr, "override_frame", 0, "Override Frame", ICON_NONE);
row = uiLayoutRow(layout, false);
- uiLayoutSetEnabled(row, RNA_boolean_get(&fileptr, "override_frame"));
+ uiLayoutSetActive(row, RNA_boolean_get(&fileptr, "override_frame"));
uiItemR(row, &fileptr, "frame", 0, "Frame", ICON_NONE);
row = uiLayoutRow(layout, false);
uiItemR(row, &fileptr, "frame_offset", 0, "Frame Offset", ICON_NONE);
+ uiLayoutSetActive(row, !RNA_boolean_get(&fileptr, "is_sequence"));
row = uiLayoutRow(layout, false);
uiItemL(row, IFACE_("Manual Transform:"), ICON_NONE);
row = uiLayoutRow(layout, false);
- uiLayoutSetEnabled(row, (sbuts->mainb == BCONTEXT_CONSTRAINT));
+ uiLayoutSetActive(row, (sbuts->mainb == BCONTEXT_CONSTRAINT));
uiItemR(row, &fileptr, "scale", 0, "Scale", ICON_NONE);
/* TODO: unused for now, so no need to expose. */
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index 6358c2c1370..3dd3b20bda3 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -38,6 +38,8 @@
#include "RNA_access.h"
+#include "DEG_depsgraph.h"
+
#include "UI_interface.h"
#include "WM_api.h"
@@ -93,7 +95,7 @@ static int cachefile_open_exec(bContext *C, wmOperator *op)
CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, BLI_path_basename(filename), 0);
BLI_strncpy(cache_file->filepath, filename, FILE_MAX);
- BKE_cachefile_reload(bmain, cache_file);
+ DEG_id_tag_update(&cache_file->id, ID_RECALC_COPY_ON_WRITE);
/* Will be set when running invoke, not exec directly. */
if (op->customdata != NULL) {
@@ -137,7 +139,7 @@ void CACHEFILE_OT_open(wmOperatorType *ot)
/* ***************************** Reload Operator **************************** */
-static int cachefile_reload_exec(bContext *C, wmOperator *op)
+static int cachefile_reload_exec(bContext *C, wmOperator *UNUSED(op))
{
CacheFile *cache_file = CTX_data_edit_cachefile(C);
@@ -145,14 +147,10 @@ static int cachefile_reload_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- Main *bmain = CTX_data_main(C);
-
- BLI_freelistN(&cache_file->object_paths);
- BKE_cachefile_reload(bmain, cache_file);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ BKE_cachefile_reload(depsgraph, cache_file);
return OPERATOR_FINISHED;
-
- UNUSED_VARS(op);
}
void CACHEFILE_OT_reload(wmOperatorType *ot)
diff --git a/source/blender/makesdna/DNA_cachefile_types.h b/source/blender/makesdna/DNA_cachefile_types.h
index e5f77f70720..bc57202367c 100644
--- a/source/blender/makesdna/DNA_cachefile_types.h
+++ b/source/blender/makesdna/DNA_cachefile_types.h
@@ -30,10 +30,12 @@
extern "C" {
#endif
+struct GSet;
+
/* CacheFile::flag */
enum {
CACHEFILE_DS_EXPAND = (1 << 0),
- CACHEFILE_DIRTY = (1 << 1),
+ CACHEFILE_UNUSED_0 = (1 << 1),
};
/* CacheFile::draw_flag */
@@ -53,9 +55,6 @@ typedef struct CacheFile {
ID id;
struct AnimData *adt;
- struct AbcArchiveHandle *handle;
- void *handle_mutex;
-
/** Paths of the objects inside of the Alembic archive referenced by this CacheFile. */
ListBase object_paths;
@@ -78,6 +77,11 @@ typedef struct CacheFile {
short draw_flag;
char _pad[4];
+
+ /* Runtime */
+ struct AbcArchiveHandle *handle;
+ char handle_filepath[1024];
+ struct GSet *handle_readers;
} CacheFile;
#ifdef __cplusplus
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 3ca61400e2e..f839f22ec9f 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -593,9 +593,12 @@ typedef struct bObjectSolverConstraint {
/* Transform matrix cache constraint */
typedef struct bTransformCacheConstraint {
struct CacheFile *cache_file;
- struct CacheReader *reader;
/** FILE_MAX. */
char object_path[1024];
+
+ /* Runtime. */
+ struct CacheReader *reader;
+ char reader_object_path[1024];
} bTransformCacheConstraint;
/* ------------------------------------------ */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 1b85fb26c0e..6a524e03b6e 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1852,12 +1852,15 @@ typedef struct MeshSeqCacheModifierData {
ModifierData modifier;
struct CacheFile *cache_file;
- struct CacheReader *reader;
/** 1024 = FILE_MAX. */
char object_path[1024];
char read_flag;
char _pad[7];
+
+ /* Runtime. */
+ struct CacheReader *reader;
+ char reader_object_path[1024];
} MeshSeqCacheModifierData;
/* MeshSeqCacheModifierData.read_flag */
diff --git a/source/blender/makesrna/intern/rna_cachefile.c b/source/blender/makesrna/intern/rna_cachefile.c
index fb61be69ee6..189a4a7de86 100644
--- a/source/blender/makesrna/intern/rna_cachefile.c
+++ b/source/blender/makesrna/intern/rna_cachefile.c
@@ -45,29 +45,12 @@
# include "../../../alembic/ABC_alembic.h"
# endif
-static void rna_CacheFile_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_CacheFile_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
CacheFile *cache_file = (CacheFile *)ptr->data;
- DEG_id_tag_update(&cache_file->id, 0);
+ DEG_id_tag_update(&cache_file->id, ID_RECALC_COPY_ON_WRITE);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
-
- UNUSED_VARS(bmain, scene);
-}
-
-static void rna_CacheFile_update_handle(Main *bmain, Scene *scene, PointerRNA *ptr)
-{
- CacheFile *cache_file = ptr->data;
-
- if ((cache_file->flag & CACHEFILE_DIRTY) != 0) {
- BKE_cachefile_clean(bmain, cache_file);
- BLI_freelistN(&cache_file->object_paths);
- cache_file->flag &= ~CACHEFILE_DIRTY;
- }
-
- BKE_cachefile_reload(bmain, cache_file);
-
- rna_CacheFile_update(bmain, scene, ptr);
}
static void rna_CacheFile_object_paths_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@@ -76,20 +59,6 @@ static void rna_CacheFile_object_paths_begin(CollectionPropertyIterator *iter, P
rna_iterator_listbase_begin(iter, &cache_file->object_paths, NULL);
}
-static void rna_CacheFile_filename_set(PointerRNA *ptr, const char *value)
-{
- CacheFile *cache_file = ptr->data;
-
- if (STREQ(cache_file->filepath, value)) {
- return;
- }
-
- /* Different file is opened, close all readers. */
- cache_file->flag |= CACHEFILE_DIRTY;
-
- BLI_strncpy(cache_file->filepath, value, sizeof(cache_file->filepath));
-}
-
#else
/* cachefile.object_paths */
@@ -122,9 +91,8 @@ static void rna_def_cachefile(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_FILE);
PropertyRNA *prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_CacheFile_filename_set");
RNA_def_property_ui_text(prop, "File Path", "Path to external displacements file");
- RNA_def_property_update(prop, 0, "rna_CacheFile_update_handle");
+ RNA_def_property_update(prop, 0, "rna_CacheFile_update");
prop = RNA_def_property(srna, "is_sequence", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 44445181402..c1c235d497b 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -729,22 +729,6 @@ static void rna_Constraint_objectSolver_camera_set(PointerRNA *ptr, PointerRNA v
}
}
-static void rna_Constraint_transformCache_object_path_update(Main *bmain,
- Scene *scene,
- PointerRNA *ptr)
-{
-# ifdef WITH_ALEMBIC
- bConstraint *con = (bConstraint *)ptr->data;
- bTransformCacheConstraint *data = (bTransformCacheConstraint *)con->data;
- Object *ob = (Object *)ptr->id.data;
-
- data->reader = CacheReader_open_alembic_object(
- data->cache_file->handle, data->reader, ob, data->object_path);
-# endif
-
- rna_Constraint_update(bmain, scene, ptr);
-}
-
#else
static const EnumPropertyItem constraint_distance_items[] = {
@@ -2902,7 +2886,7 @@ static void rna_def_constraint_transform_cache(BlenderRNA *brna)
prop,
"Object Path",
"Path to the object in the Alembic archive used to lookup the transform matrix");
- RNA_def_property_update(prop, 0, "rna_Constraint_transformCache_object_path_update");
+ RNA_def_property_update(prop, 0, "rna_Constraint_update");
}
/* base struct for constraints */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 8a63bf1a619..4f304f97cac 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1300,19 +1300,6 @@ static bool rna_SurfaceDeformModifier_is_bound_get(PointerRNA *ptr)
return (((SurfaceDeformModifierData *)ptr->data)->verts != NULL);
}
-static void rna_MeshSequenceCache_object_path_update(Main *bmain, Scene *scene, PointerRNA *ptr)
-{
-# ifdef WITH_ALEMBIC
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data;
- Object *ob = (Object *)ptr->id.data;
-
- mcmd->reader = CacheReader_open_alembic_object(
- mcmd->cache_file->handle, mcmd->reader, ob, mcmd->object_path);
-# endif
-
- rna_Modifier_update(bmain, scene, ptr);
-}
-
static bool rna_ParticleInstanceModifier_particle_system_poll(PointerRNA *ptr,
const PointerRNA value)
{
@@ -5107,7 +5094,7 @@ static void rna_def_modifier_meshseqcache(BlenderRNA *brna)
prop,
"Object Path",
"Path to the object in the Alembic archive used to lookup geometric data");
- RNA_def_property_update(prop, 0, "rna_MeshSequenceCache_object_path_update");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
static const EnumPropertyItem read_flag_items[] = {
{MOD_MESHSEQ_READ_VERT, "VERT", 0, "Vertex", ""},
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 7710082150b..760830ffb24 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -18,6 +18,11 @@
* \ingroup modifiers
*/
+#include <string.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+
#include "DNA_cachefile_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -47,6 +52,9 @@ static void initData(ModifierData *md)
mcmd->cache_file = NULL;
mcmd->object_path[0] = '\0';
mcmd->read_flag = MOD_MESHSEQ_READ_ALL;
+
+ mcmd->reader = NULL;
+ mcmd->reader_object_path[0] = '\0';
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
@@ -59,6 +67,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
modifier_copyData_generic(md, target, flag);
tmcmd->reader = NULL;
+ tmcmd->reader_object_path[0] = '\0';
}
static void freeData(ModifierData *md)
@@ -66,10 +75,8 @@ static void freeData(ModifierData *md)
MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
if (mcmd->reader) {
-#ifdef WITH_ALEMBIC
- CacheReader_free(mcmd->reader);
-#endif
- mcmd->reader = NULL;
+ mcmd->reader_object_path[0] = '\0';
+ BKE_cachefile_reader_free(mcmd->cache_file, &mcmd->reader);
}
}
@@ -93,17 +100,14 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
Mesh *org_mesh = mesh;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ CacheFile *cache_file = mcmd->cache_file;
const float frame = DEG_get_ctime(ctx->depsgraph);
- const float time = BKE_cachefile_time_offset(mcmd->cache_file, frame, FPS);
+ const float time = BKE_cachefile_time_offset(cache_file, frame, FPS);
const char *err_str = NULL;
- CacheFile *cache_file = (CacheFile *)DEG_get_original_id(&mcmd->cache_file->id);
-
- BKE_cachefile_ensure_handle(G.main, cache_file);
-
- if (!mcmd->reader) {
- mcmd->reader = CacheReader_open_alembic_object(
- cache_file->handle, NULL, ctx->object, mcmd->object_path);
+ if (!mcmd->reader || !STREQ(mcmd->reader_object_path, mcmd->object_path)) {
+ STRNCPY(mcmd->reader_object_path, mcmd->object_path);
+ BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path);
if (!mcmd->reader) {
modifier_setError(md, "Could not create Alembic reader for file %s", cache_file->filepath);
return mesh;