[Bf-blender-cvs] [861e553] alembic_pointcache: BKE functions for managing cache content based on a group.
Lukas Tönne
noreply at git.blender.org
Mon Feb 23 14:06:39 CET 2015
Commit: 861e553f1db6ee28d909143265528acf8ce5bf52
Author: Lukas Tönne
Date: Sat Feb 21 12:28:51 2015 +0100
Branches: alembic_pointcache
https://developer.blender.org/rB861e553f1db6ee28d909143265528acf8ce5bf52
BKE functions for managing cache content based on a group.
This uses a complete hierarchy of group instances, based on a path
hierarchy (object names).
Putting
===================================================================
M source/blender/blenkernel/BKE_cache_library.h
M source/blender/blenkernel/intern/cache_library.c
M source/blender/makesdna/DNA_cache_library_types.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_cache_library.h b/source/blender/blenkernel/BKE_cache_library.h
index 92a1f9d..53dd131 100644
--- a/source/blender/blenkernel/BKE_cache_library.h
+++ b/source/blender/blenkernel/BKE_cache_library.h
@@ -32,11 +32,28 @@
* \ingroup bke
*/
-struct CacheLibrary;
struct Main;
+struct CacheLibrary;
+struct CacheItem;
+struct CacheItemPath;
struct CacheLibrary *BKE_cache_library_add(struct Main *bmain, const char *name);
struct CacheLibrary *BKE_cache_library_copy(struct CacheLibrary *cachelib);
-void BKE_cache_library_free(struct CacheLibrary *cache);
+void BKE_cache_library_free(struct CacheLibrary *cachelib);
+
+bool BKE_cache_item_path_cmp(const struct CacheItemPath *a, const struct CacheItemPath *b);
+int BKE_cache_item_path_len(const struct CacheItemPath *path);
+bool BKE_cache_item_path_append(struct CacheItemPath *path, const char *name);
+void BKE_cache_item_path_replace(struct CacheItemPath *path, const char *name, int index);
+void BKE_cache_item_path_clear(struct CacheItemPath *path);
+void BKE_cache_item_path_truncate(struct CacheItemPath *path, int len);
+void BKE_cache_item_path_copy(struct CacheItemPath *dst, const struct CacheItemPath *src);
+
+typedef void (*CacheGroupWalkFunc)(void *userdata, struct CacheLibrary *cachelib, const struct CacheItemPath *path);
+void BKE_cache_library_walk(struct CacheLibrary *cachelib, CacheGroupWalkFunc walk, void *userdata);
+
+struct CacheItem *BKE_cache_library_find_item(struct CacheLibrary *cachelib, const struct CacheItemPath *path);
+struct CacheItem *BKE_cache_library_add_item(struct CacheLibrary *cachelib, const struct CacheItemPath *path);
+bool BKE_cache_library_remove_item(struct CacheLibrary *cachelib, const struct CacheItemPath *path);
#endif
diff --git a/source/blender/blenkernel/intern/cache_library.c b/source/blender/blenkernel/intern/cache_library.c
index cbfed7c..0ab19ba 100644
--- a/source/blender/blenkernel/intern/cache_library.c
+++ b/source/blender/blenkernel/intern/cache_library.c
@@ -27,18 +27,83 @@
* \ingroup bke
*/
+#include <string.h>
+
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "DNA_cache_library_types.h"
+#include "DNA_group_types.h"
+#include "DNA_object_types.h"
#include "BKE_cache_library.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
+bool BKE_cache_item_path_cmp(const CacheItemPath *a, const CacheItemPath *b)
+{
+ int i, cmp;
+ for (i = 0; i < MAX_CACHE_GROUP_LEVEL; ++i) {
+ if (a->value[i][0] == '\0' && b->value[i][0] == '\0')
+ break;
+ cmp = strcmp(a->value[i], b->value[i]);
+ if (cmp != 0)
+ return cmp;
+ }
+ return 0;
+}
+
+int BKE_cache_item_path_len(const CacheItemPath *path)
+{
+ int i;
+ for (i = 0; i < MAX_CACHE_GROUP_LEVEL; ++i) {
+ if (path->value[i][0] == '\0')
+ break;
+ }
+ return i;
+}
+
+bool BKE_cache_item_path_append(CacheItemPath *path, const char *name)
+{
+ int i;
+ for (i = 0; i < MAX_CACHE_GROUP_LEVEL; ++i) {
+ if (path->value[i][0] == '\0') {
+ BLI_strncpy(path->value[i], name, sizeof(path->value[i]));
+ return true;
+ }
+ }
+ return false;
+}
+
+void BKE_cache_item_path_replace(CacheItemPath *path, const char *name, int index)
+{
+ BLI_assert(index < MAX_CACHE_GROUP_LEVEL);
+ BLI_strncpy(path->value[index], name, sizeof(path->value[index]));
+}
+
+void BKE_cache_item_path_clear(CacheItemPath *path)
+{
+ path->value[0][0] = '\0';
+}
+
+void BKE_cache_item_path_truncate(CacheItemPath *path, int len)
+{
+ BLI_assert(len < MAX_CACHE_GROUP_LEVEL);
+ path->value[len][0] = '\0';
+}
+
+void BKE_cache_item_path_copy(CacheItemPath *dst, const CacheItemPath *src)
+{
+ memcpy(dst->value, src->value, sizeof(CacheItemPath));
+}
+
+/* ========================================================================= */
+
CacheLibrary *BKE_cache_library_add(Main *bmain, const char *name)
{
CacheLibrary *cachelib;
@@ -56,6 +121,8 @@ CacheLibrary *BKE_cache_library_copy(CacheLibrary *cachelib)
cachelibn = BKE_libblock_copy(&cachelib->id);
+ BLI_duplicatelist(&cachelibn->items, &cachelib->items);
+
if (cachelib->id.lib) {
BKE_id_lib_local_paths(G.main, cachelib->id.lib, &cachelibn->id);
}
@@ -63,6 +130,188 @@ CacheLibrary *BKE_cache_library_copy(CacheLibrary *cachelib)
return cachelibn;
}
-void BKE_cache_library_free(CacheLibrary *UNUSED(cache))
+void BKE_cache_library_free(CacheLibrary *cachelib)
+{
+ BLI_freelistN(&cachelib->items);
+}
+
+/* ========================================================================= */
+
+static void cache_library_walk_recursive(CacheLibrary *cachelib, CacheGroupWalkFunc walk, void *userdata, const CacheItemPath *path, int level, Object *ob)
+{
+ /* object dm */
+ walk(userdata, cachelib, path);
+
+ /* dupli group recursion */
+ if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
+ GroupObject *gob;
+
+ for (gob = ob->dup_group->gobject.first; gob; gob = gob->next) {
+ CacheItemPath gpath;
+ BKE_cache_item_path_copy(&gpath, path);
+ BKE_cache_item_path_append(&gpath, ob->id.name+2);
+ cache_library_walk_recursive(cachelib, walk, userdata, &gpath, level + 1, gob->ob);
+ }
+ }
+}
+
+void BKE_cache_library_walk(CacheLibrary *cachelib, CacheGroupWalkFunc walk, void *userdata)
+{
+ CacheItemPath path;
+ BKE_cache_item_path_clear(&path);
+
+ if (cachelib && cachelib->group) {
+ GroupObject *gob;
+
+ for (gob = cachelib->group->gobject.first; gob; gob = gob->next) {
+ cache_library_walk_recursive(cachelib, walk, userdata, &path, 0, gob->ob);
+ }
+ }
+}
+
+/* ========================================================================= */
+
+BLI_INLINE unsigned int hash_int_2d(unsigned int kx, unsigned int ky)
+{
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+ uint a, b, c;
+
+ a = b = c = 0xdeadbeef + (2 << 2) + 13;
+ a += kx;
+ b += ky;
+
+ c ^= b; c -= rot(b,14);
+ a ^= c; a -= rot(c,11);
+ b ^= a; b -= rot(a,25);
+ c ^= b; c -= rot(b,16);
+ a ^= c; a -= rot(c,4);
+ b ^= a; b -= rot(a,14);
+ c ^= b; c -= rot(b,24);
+
+ return c;
+
+#undef rot
+}
+
+static unsigned int cache_item_hash(const void *key)
+{
+ const CacheItemPath *path = key;
+ int i;
+ unsigned int hash = 0;
+
+ for (i = 0; i < MAX_CACHE_GROUP_LEVEL; ++i) {
+ hash = hash_int_2d(hash, BLI_ghashutil_strhash(path->value[i]));
+ }
+ return hash;
+}
+
+static bool cache_item_cmp(const void *key_a, const void *key_b)
+{
+ return BKE_cache_item_path_cmp(key_a, key_b) != 0;
+}
+
+static void cache_library_insert_item_hash(CacheLibrary *cachelib, CacheItem *item, bool replace)
+{
+ CacheItemPath *path = &item->path;
+ CacheItem *exist = BLI_ghash_lookup(cachelib->items_hash, path);
+ if (exist && replace) {
+ BLI_remlink(&cachelib->items, exist);
+ BLI_ghash_remove(cachelib->items_hash, path, NULL, NULL);
+ MEM_freeN(exist);
+ }
+ if (!exist || replace)
+ BLI_ghash_insert(cachelib->items_hash, path, item);
+}
+
+static void cache_library_ensure_items_hash(CacheLibrary *cachelib)
+{
+ CacheItem *item;
+
+ if (cachelib->items_hash) {
+ BLI_ghash_clear(cachelib->items_hash, NULL, NULL);
+ }
+ else {
+ cachelib->items_hash = BLI_ghash_new(cache_item_hash, cache_item_cmp, "cache item hash");
+ }
+
+ for (item = cachelib->items.first; item; item = item->next) {
+ cache_library_insert_item_hash(cachelib, item, true);
+ }
+}
+
+CacheItem *BKE_cache_library_find_item(CacheLibrary *cachelib, const CacheItemPath *path)
{
+ return BLI_ghash_lookup(cachelib->items_hash, path);
+}
+
+CacheItem *BKE_cache_library_add_item(CacheLibrary *cachelib, const CacheItemPath *path)
+{
+ CacheItem *item = BLI_ghash_lookup(cachelib->items_hash, path);
+
+ if (!item) {
+ item = MEM_callocN(sizeof(CacheItem), "cache library item");
+ BKE_cache_item_path_copy(&item->path, path);
+
+ BLI_addtail(&cachelib->items, item);
+ cache_library_insert_item_hash(cachelib, item, false);
+ }
+
+ return item;
+}
+
+bool BKE_cache_library_remove_item(CacheLibrary *cachelib, const CacheItemPath *path)
+{
+ CacheItem *item = BLI_ghash_lookup(cachelib->items_hash, path);
+ if (item) {
+ BLI_ghash_remove(cachelib->items_hash, (CacheItemPath *)path, NULL, NULL);
+ BLI_remlink(&cachelib->items, item);
+ MEM_freeN(item);
+ return true;
+ }
+ else
+ return false;
+}
+
+/* ========================================================================= */
+
+#if 0
+typedef struct UpdateItemsData {
+ CacheItem *cur;
+} UpdateItemsData;
+
+static void cache_library_update_items_walk(void *userdata, CacheLibrary *cachelib)
+{
+ UpdateItemsData *data = userdata;
+ CacheItem *item;
+
+ if (data->cur) {
+ item = data->cur;
+ data->cur = data->cur->next;
+ }
+ else {
+ item = MEM_callocN(sizeof(CacheItem), "cache library item");
+ BLI_addtail(&cachelib->items, item);
+ }
+}
+
+void BKE_cache_library_update_items(CacheLibrary *cachelib)
+{
+ UpdateItemsData data;
+
+ data.cur = cachelib->items.first;
+ BKE_cache_library_walk(cachelib, cache_library_update_items_walk, &data);
+
+ /* truncate items list */
+ if (data.cur) {
+ cachelib->items.last = data.cur->prev;
+ while (data.cur) {
+ CacheItem *item = data.cur;
+ data.cur = data.cur->next;
+
+ BLI_remlink(&cachelib->items, item);
+ MEM_freeN(item);
+ }
+ }
}
+#endif
diff --git a/source/blender/makesdna/DNA_cache_library_types.h b/source/blender/makesdna/DNA_cache_library_types.h
index 223cde1..36b60d7 100644
--- a/source/blender/makesdna/DNA_cache_library_types.h
+++ b/source/blender/makesdna/DNA_cache_library_types.h
@@ -34,12 +34,28 @@
#include "DNA_defs.h"
#include "DNA_ID.h"
+#include "DNA_listBase.h"
+
+#define MAX_CACHE_GROUP_LEVEL 8
+
+typedef struct CacheItemPath {
+ char value[8][64]; /* MAX_CACHE_GROUP_LEVEL, MAX_NAME */
+} CacheItemPath;
+
+typedef struct CacheItem {
+ struct CacheItem *next, *prev;
+
+ CacheItemPath path;
+} CacheItem;
typedef struct CacheLibrary {
ID id;
char filepath[1024]; /* 1024 = FILE_MAX */
struct Group *group;
+
+ ListBase items; /* cached items */
+ struct GHash *items_hash; /* runtime: cached items hash for fast lookup */
} CacheLibrary;
#endif
More information about the Bf-blender-cvs
mailing list