[Bf-blender-cvs] [9146dcf] gooseberry: Initial code to support dupli group instancing and overrides through Alembic caches.

Lukas Tönne noreply at git.blender.org
Mon Mar 23 13:03:11 CET 2015


Commit: 9146dcfda718a05a6693fd758bbb535fd0d5c621
Author: Lukas Tönne
Date:   Wed Mar 11 12:46:33 2015 +0100
Branches: gooseberry
https://developer.blender.org/rB9146dcfda718a05a6693fd758bbb535fd0d5c621

Initial code to support dupli group instancing and overrides through
Alembic caches.

This creates representations (Abc::Object) for Blender Object and Group
datablocks in the Alembic files and uses Alembic instancing to define
the dupligroup hierarchy. This leads to a relatively flat hierarchy in
Alembic files:

Top -> Object/Group -> DerivedMesh/Particles/Hair/Cloth/Smoke/...

The dupligroup structure can not be represented by a hierarchical
structure such as the Alembic object nesting, because of the
many-to-many relationship between objects and groups (a group can
contain multiple objects, multiple objects can instance the same group).
Instead we use the instancing feature of Alembic to represent
dupligroups. This is created in 2 stages to ensure all the main ID
blocks have been serialized before creating references.

===================================================================

M	source/blender/blenkernel/BKE_anim.h
M	source/blender/blenkernel/BKE_cache_library.h
M	source/blender/blenkernel/intern/cache_library.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/object_dupli.c
M	source/blender/editors/io/io_cache_library.c
M	source/blender/makesdna/DNA_object_types.h
M	source/blender/pointcache/PTC_api.cpp
M	source/blender/pointcache/PTC_api.h
M	source/blender/pointcache/alembic/CMakeLists.txt
M	source/blender/pointcache/alembic/abc_cloth.cpp
A	source/blender/pointcache/alembic/abc_group.cpp
A	source/blender/pointcache/alembic/abc_group.h
M	source/blender/pointcache/alembic/abc_mesh.cpp
A	source/blender/pointcache/alembic/abc_object.cpp
A	source/blender/pointcache/alembic/abc_object.h
M	source/blender/pointcache/alembic/abc_particles.cpp
M	source/blender/pointcache/alembic/abc_reader.cpp
M	source/blender/pointcache/alembic/abc_reader.h
M	source/blender/pointcache/alembic/abc_writer.cpp
M	source/blender/pointcache/alembic/abc_writer.h
M	source/blender/pointcache/alembic/alembic.cpp
M	source/blender/pointcache/intern/export.cpp
M	source/blender/pointcache/intern/ptc_types.h
M	source/blender/pointcache/intern/writer.cpp
M	source/blender/pointcache/intern/writer.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 0d5078b..a91f4ae 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -42,6 +42,8 @@ struct bAnimVizSettings;
 struct bMotionPath;
 struct bPoseChannel;
 struct ReportList;
+struct GHash;
+struct DupliCache;
 
 /* ---------------------------------------------------- */
 /* Animation Visualization */
@@ -71,6 +73,11 @@ struct ListBase *object_duplilist(struct EvaluationContext *eval_ctx, struct Sce
 void free_object_duplilist(struct ListBase *lb);
 int count_duplilist(struct Object *ob);
 
+void BKE_object_dupli_cache_update(struct Scene *scene, struct Object *ob, struct EvaluationContext *eval_ctx);
+void BKE_object_dupli_cache_clear(struct Object *ob);
+
+void BKE_dupli_cache_add_mesh(struct DupliCache *dupcache, float obmat[4][4], struct DerivedMesh *dm);
+
 typedef struct DupliExtraData {
 	float obmat[4][4];
 	unsigned int lay;
diff --git a/source/blender/blenkernel/BKE_cache_library.h b/source/blender/blenkernel/BKE_cache_library.h
index 4d9673b..4e6c527 100644
--- a/source/blender/blenkernel/BKE_cache_library.h
+++ b/source/blender/blenkernel/BKE_cache_library.h
@@ -40,6 +40,7 @@ struct Object;
 struct Scene;
 struct EvaluationContext;
 struct ParticleSystem;
+struct DupliCache;
 
 struct ClothModifierData;
 
@@ -101,11 +102,12 @@ void BKE_cache_archive_path(const char *path, ID *id, Library *lib, char *result
 typedef struct CacheLibraryWriterLink {
 	struct CacheLibraryWriterLink *next, *prev;
 	
-	struct CacheItem *item;
 	struct PTCWriter *writer;
+	
+	struct Object *ob; /* optional: object to construct render DM */
 } CacheLibraryWriterLink;
 
-void BKE_cache_library_writers(struct CacheLibrary *cachelib, struct Scene *scene, struct DerivedMesh **render_dm_ptr, struct ListBase *writers);
+void BKE_cache_library_writers(struct Main *bmain, struct CacheLibrary *cachelib, struct Scene *scene, struct DerivedMesh **render_dm_ptr, struct ListBase *writers);
 struct PTCWriterArchive *BKE_cache_library_writers_open_archive(struct Scene *scene, struct CacheLibrary *cachelib, struct ListBase *writers);
 void BKE_cache_library_writers_free(struct PTCWriterArchive *archive, struct ListBase *writers);
 
@@ -130,4 +132,6 @@ bool BKE_cache_read_particles_pathcache_parents(struct Main *bmain, struct Scene
 bool BKE_cache_read_particles_pathcache_children(struct Main *bmain, struct Scene *scene, float frame, eCacheLibrary_EvalMode eval_mode,
                                                  struct Object *ob, struct ParticleSystem *psys);
 
+bool BKE_cache_read_dupligroup(struct Main *bmain, struct Scene *scene, float frame, eCacheLibrary_EvalMode eval_mode, struct Group *dupgroup, struct DupliCache *dupcache);
+
 #endif
diff --git a/source/blender/blenkernel/intern/cache_library.c b/source/blender/blenkernel/intern/cache_library.c
index 585c0f0..76008c2 100644
--- a/source/blender/blenkernel/intern/cache_library.c
+++ b/source/blender/blenkernel/intern/cache_library.c
@@ -46,6 +46,7 @@
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 
+#include "BKE_anim.h"
 #include "BKE_cache_library.h"
 #include "BKE_depsgraph.h"
 #include "BKE_DerivedMesh.h"
@@ -647,13 +648,32 @@ void BKE_cache_archive_path(const char *path, ID *id, Library *lib, char *result
 }
 
 
-static void cachelib_add_writer(ListBase *writers, struct CacheItem *item, struct PTCWriter *writer)
+static void tag_dupligroup_recursive(Main *bmain, Group *group)
+{
+	GroupObject *gob;
+	
+	if (!(group->id.flag & LIB_DOIT)) {
+		group->id.flag |= LIB_DOIT;
+		
+		for (gob = group->gobject.first; gob; gob = gob->next) {
+			Object *ob = gob->ob;
+			if (!(ob->id.flag & LIB_DOIT)) {
+				ob->id.flag |= LIB_DOIT;
+				
+				if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group)
+					tag_dupligroup_recursive(bmain, ob->dup_group);
+			}
+		}
+	}
+}
+
+static void cachelib_add_writer(ListBase *writers, struct PTCWriter *writer, struct Object *ob)
 {
 	if (writer) {
 		CacheLibraryWriterLink *link = MEM_callocN(sizeof(CacheLibraryWriterLink), "cachelib writers link");
 		
-		link->item = item;
 		link->writer = writer;
+		link->ob = ob;
 		BLI_addtail(writers, link);
 	}
 }
@@ -661,7 +681,7 @@ static void cachelib_add_writer(ListBase *writers, struct CacheItem *item, struc
 static int cachelib_writers_cmp(const void *a, const void *b)
 {
 	const CacheLibraryWriterLink *la = a, *lb = b;
-	return la->item->ob > lb->item->ob;
+	return la->ob > lb->ob;
 }
 
 BLI_INLINE int cache_required_mode(CacheLibrary *cachelib)
@@ -673,14 +693,44 @@ BLI_INLINE int cache_required_mode(CacheLibrary *cachelib)
 	return 0;
 }
 
-void BKE_cache_library_writers(CacheLibrary *cachelib, Scene *scene, DerivedMesh **render_dm_ptr, ListBase *writers)
+void BKE_cache_library_writers(Main *bmain, CacheLibrary *cachelib, Scene *scene, DerivedMesh **render_dm_ptr, ListBase *writers)
 {
 	const eCacheLibrary_EvalMode eval_mode = cachelib->eval_mode;
 	const int required_mode = cache_required_mode(cachelib);
-	CacheItem *item;
+	Group *cache_group = cachelib->group;
+//	CacheItem *item;
 	
 	BLI_listbase_clear(writers);
 	
+	if (!cache_group)
+		return;
+	
+	/* clear tags */
+	BKE_main_id_tag_idcode(bmain, ID_OB, false);
+	BKE_main_id_tag_idcode(bmain, ID_GR, false);
+	
+	/* tag dupligroups recursively */
+	tag_dupligroup_recursive(bmain, cache_group);
+	
+	/* create object writers */
+	{
+		Object *ob;
+		for (ob = bmain->object.first; ob; ob = ob->id.next) {
+			if (ob->id.flag & LIB_DOIT)
+				cachelib_add_writer(writers, PTC_writer_object(ob->id.name, ob), ob);
+		}
+	}
+	
+	/* create group writers */
+	{
+		Group *group;
+		for (group = bmain->group.first; group; group = group->id.next) {
+			if (group->id.flag & LIB_DOIT)
+				cachelib_add_writer(writers, PTC_writer_group(group->id.name, group), NULL);
+		}
+	}
+	
+#if 0
 	for (item = cachelib->items.first; item; item = item->next) {
 		char name[2*MAX_NAME];
 		
@@ -748,6 +798,7 @@ void BKE_cache_library_writers(CacheLibrary *cachelib, Scene *scene, DerivedMesh
 	 * and all cached items exported, without having to reevaluate the same object multiple times.
 	 */
 	BLI_listbase_sort(writers, cachelib_writers_cmp);
+#endif
 }
 
 struct PTCWriterArchive *BKE_cache_library_writers_open_archive(Scene *scene, CacheLibrary *cachelib, ListBase *writers)
@@ -763,6 +814,10 @@ struct PTCWriterArchive *BKE_cache_library_writers_open_archive(Scene *scene, Ca
 		PTC_writer_set_archive(link->writer, archive);
 	}
 	
+	for (link = writers->first; link; link = link->next) {
+		PTC_writer_create_refs(link->writer);
+	}
+	
 	return archive;
 }
 
@@ -1119,6 +1174,20 @@ bool BKE_cache_read_particles_pathcache_children(Main *bmain, Scene *scene, floa
 	return false;
 }
 
+bool BKE_cache_read_dupligroup(Main *bmain, Scene *scene, float frame, eCacheLibrary_EvalMode eval_mode, struct Group *dupgroup, struct DupliCache *dupcache)
+{
+	CacheLibrary *cachelib;
+	
+	FOREACH_CACHELIB_READ(bmain, cachelib, eval_mode) {
+		if (cachelib->group == dupgroup) {
+			// TODO
+			//	BKE_dupli_cache_add_mesh();
+			return true;
+		}
+	}
+	return false;
+}
+
 
 void BKE_cache_library_dag_recalc_tag(EvaluationContext *eval_ctx, Main *bmain)
 {
@@ -1129,6 +1198,8 @@ void BKE_cache_library_dag_recalc_tag(EvaluationContext *eval_ctx, Main *bmain)
 		if (cachelib->flag & CACHE_LIBRARY_READ) {
 			CacheItem *item;
 			
+			// TODO tag group instance objects or so?
+			
 			for (item = cachelib->items.first; item; item = item->next) {
 				if (item->ob && (item->flag & CACHE_ITEM_ENABLED)) {
 					
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 54faffd..dbc818c 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -3221,6 +3221,8 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
 			}
 			
 			/* quick cache removed */
+			
+			BKE_object_dupli_cache_update(scene, ob, eval_ctx);
 		}
 
 		ob->recalc &= ~OB_RECALC_ALL;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index c77f65f..5f19e5e 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -35,6 +35,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
 #include "BLI_listbase.h"
 #include "BLI_string_utf8.h"
 
@@ -48,6 +50,7 @@
 #include "DNA_vfont_types.h"
 
 #include "BKE_animsys.h"
+#include "BKE_cache_library.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_depsgraph.h"
 #include "BKE_font.h"
@@ -1237,6 +1240,119 @@ int count_duplilist(Object *ob)
 	return 1;
 }
 
+/* ------------------------------------------------------------------------- */
+typedef struct DupliCache {
+#if 0
+	/* XXX ghash implementation later, for now listbase is easier */
+	struct GHash *ghash;
+#else
+	ListBase duplilist;
+#endif
+} DupliCache;
+
+static void dupli_object_free(DupliObject *dob)
+{
+	if (dob->cache_dm)
+		dob->cache_dm->release(dob->cache_dm);
+	
+	MEM_freeN(dob);
+}
+
+#if 0
+static void dupli_cache_clear(DupliCache *dupcache)
+{
+	BLI_ghash_clear(dupcache->ghash, NULL, (GHashValFreeFP)dupli_object_free);
+}
+#else
+static void dupli_cache_clear(DupliCache *dupcache)
+{
+	DupliObject *dob, *dob_next;
+	for (dob = dupcache->duplilist.first; dob; dob = dob_next) {
+		dob_next = dob->next;
+		
+		dupli_object_free(dob);
+	}
+	BLI_listbase_clear(&dupcache->duplilist);
+}
+#endif
+
+static DupliObject *dupli_cache_push(DupliCache *dupcache)
+{
+	DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupli object");
+	
+	unit_m4(dob->mat);
+	
+	BLI_addtail(&dupcache->duplilist, dob);
+	return dob;
+}
+
+void BKE_object_dupli_cache_update(Scene *scene, Object *ob, EvaluationContext *eval_ctx)
+{
+	
+	/* cache is a group duplicator feature only */
+	if (ob->dup_group) {
+		
+		if (ob->dup_cache) {
+			dupli_cache_clear(ob->dup_cache);
+		}
+		else {
+			ob->dup_cache = MEM_callocN(sizeof(DupliCache), "dupli object cache");
+		}
+		
+#if 0
+		/* XXX object_duplilist_ex allocates a ListBase, no need to make it complicated though ... */
+		{
+			ListBase 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list