[Bf-blender-cvs] [f1fde1f] gooseberry: Better dupligroup Alembic writer.

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


Commit: f1fde1f4fb0c81a16c0e80b6ec766a32f041b8de
Author: Lukas Tönne
Date:   Fri Mar 13 17:34:24 2015 +0100
Branches: gooseberry
https://developer.blender.org/rBf1fde1f4fb0c81a16c0e80b6ec766a32f041b8de

Better dupligroup Alembic writer.

Uses the duplilist generated by Blender to define instances, instead of
recreating the group layout. This omits some information about actual
structure of the DNA, which might be useful later on. The main problem
is that the duplilist itself does not encode this, so it's a tradeoff
between either including the Group structure or omitting the other
dupli types, like face, vertex, particle duplis.

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

M	source/blender/editors/io/io_cache_library.c
M	source/blender/pointcache/PTC_api.cpp
M	source/blender/pointcache/PTC_api.h
M	source/blender/pointcache/alembic/abc_group.cpp
M	source/blender/pointcache/alembic/abc_group.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/export.h
M	source/blender/pointcache/intern/ptc_types.h

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

diff --git a/source/blender/editors/io/io_cache_library.c b/source/blender/editors/io/io_cache_library.c
index 7d0378f..5a535b0 100644
--- a/source/blender/editors/io/io_cache_library.c
+++ b/source/blender/editors/io/io_cache_library.c
@@ -41,6 +41,7 @@
 #include "BLI_utildefines.h"
 
 #include "DNA_cache_library_types.h"
+#include "DNA_group_types.h"
 #include "DNA_listBase.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
@@ -238,10 +239,9 @@ typedef struct CacheLibraryBakeJob {
 	struct Scene *scene;
 	EvaluationContext eval_ctx;
 	struct CacheLibrary *cachelib;
-	struct DerivedMesh *render_dm; /* temporary render_dm pointer, not stored in Object */
 	
 	struct PTCWriterArchive *archive;
-	ListBase writers;
+	struct PTCWriter *writer;
 	
 	int origfra;                            /* original frame to reset scene after export */
 	float origframelen;                     /* original frame length to reset scene after export */
@@ -258,6 +258,7 @@ static void cache_library_bake_startjob(void *customdata, short *stop, short *do
 	CacheLibraryBakeJob *data= (CacheLibraryBakeJob *)customdata;
 	Scene *scene = data->scene;
 	int start_frame, end_frame;
+	char filename[FILE_MAX];
 	
 	data->stop = stop;
 	data->do_update = do_update;
@@ -277,15 +278,18 @@ static void cache_library_bake_startjob(void *customdata, short *stop, short *do
 	/* disable reading for the duration of the bake process */
 	data->cachelib->flag &= ~CACHE_LIBRARY_READ;
 	
-	BKE_cache_library_writers(G.main, data->cachelib, scene, &data->render_dm, &data->writers);
-	data->archive = BKE_cache_library_writers_open_archive(scene, data->cachelib, &data->writers);
+	BKE_cache_archive_path(data->cachelib->filepath, (ID *)data->cachelib, data->cachelib->id.lib, filename, sizeof(filename));
+	data->archive = PTC_open_writer_archive(scene, filename);
+	
+	data->writer = PTC_writer_dupligroup(data->cachelib->group->id.name, &data->eval_ctx, scene, data->cachelib->group);
+	PTC_writer_set_archive(data->writer, data->archive);
 	
 	G.is_break = false;
 	
 	/* XXX where to get this from? */
 	start_frame = scene->r.sfra;
 	end_frame = scene->r.efra;
-	PTC_bake(data->bmain, scene, &data->eval_ctx, &data->writers, &data->render_dm, start_frame, end_frame, stop, do_update, progress);
+	PTC_bake(data->bmain, scene, &data->eval_ctx, data->writer, start_frame, end_frame, stop, do_update, progress);
 	
 	*do_update = true;
 	*stop = 0;
@@ -299,7 +303,10 @@ static void cache_library_bake_endjob(void *customdata)
 	G.is_rendering = false;
 	BKE_spacedata_draw_locks(false);
 	
-	BKE_cache_library_writers_free(data->archive, &data->writers);
+	if (data->writer)
+		PTC_writer_free(data->writer);
+	if (data->archive)
+		PTC_close_writer_archive(data->archive);
 	
 	/* enable reading */
 	data->cachelib->flag |= CACHE_LIBRARY_READ;
diff --git a/source/blender/pointcache/PTC_api.cpp b/source/blender/pointcache/PTC_api.cpp
index cbb94c7..810bb32 100644
--- a/source/blender/pointcache/PTC_api.cpp
+++ b/source/blender/pointcache/PTC_api.cpp
@@ -151,6 +151,15 @@ void PTC_write_sample(struct PTCWriter *_writer)
 	writer->write_sample();
 }
 
+#if 1
+void PTC_bake(struct Main *bmain, struct Scene *scene, struct EvaluationContext *evalctx,
+              PTCWriter *writer, int start_frame, int end_frame,
+              short *stop, short *do_update, float *progress)
+{
+	PTC::Exporter exporter(bmain, scene, evalctx, stop, do_update, progress);
+	exporter.bake(writer, start_frame, end_frame);
+}
+#else
 void PTC_bake(struct Main *bmain, struct Scene *scene, struct EvaluationContext *evalctx,
               struct ListBase *writers, DerivedMesh **render_dm_ptr, int start_frame, int end_frame,
               short *stop, short *do_update, float *progress)
@@ -158,6 +167,7 @@ void PTC_bake(struct Main *bmain, struct Scene *scene, struct EvaluationContext
 	PTC::Exporter exporter(bmain, scene, evalctx, stop, do_update, progress);
 	exporter.bake(writers, render_dm_ptr, start_frame, end_frame);
 }
+#endif
 
 
 void PTC_reader_free(PTCReader *_reader)
@@ -201,6 +211,11 @@ char *PTC_get_archive_info(PTCReaderArchive *_archive)
 }
 
 
+PTCWriter *PTC_writer_dupligroup(const char *name, struct EvaluationContext *eval_ctx, struct Scene *scene, struct Group *group)
+{
+	return (PTCWriter *)PTC::Factory::alembic->create_writer_dupligroup(name, eval_ctx, scene, group);
+}
+
 PTCReadSampleResult PTC_read_dupligroup(PTCReaderArchive *archive, float frame, Group *dupgroup, DupliCache *dupcache)
 {
 	return PTC::Factory::alembic->read_dupligroup((PTC::ReaderArchive *)archive, frame, dupgroup, dupcache);
diff --git a/source/blender/pointcache/PTC_api.h b/source/blender/pointcache/PTC_api.h
index cb7e048..18c975a 100644
--- a/source/blender/pointcache/PTC_api.h
+++ b/source/blender/pointcache/PTC_api.h
@@ -56,7 +56,7 @@ void PTC_error_handler_reports(struct ReportList *reports);
 void PTC_error_handler_modifier(struct ModifierData *md);
 
 void PTC_bake(struct Main *bmain, struct Scene *scene, struct EvaluationContext *evalctx,
-              struct ListBase *writers, struct DerivedMesh **render_dm_ptr, int start_frame, int end_frame,
+              struct PTCWriter *writer, int start_frame, int end_frame,
               short *stop, short *do_update, float *progress);
 
 /*** Archive ***/
@@ -85,6 +85,7 @@ PTCReadSampleResult PTC_test_sample(struct PTCReader *reader, float frame);
 
 char *PTC_get_archive_info(struct PTCReaderArchive *archive);
 
+struct PTCWriter *PTC_writer_dupligroup(const char *name, struct EvaluationContext *eval_ctx, struct Scene *scene, struct Group *group);
 PTCReadSampleResult PTC_read_dupligroup(struct PTCReaderArchive *archive, float frame, struct Group *dupgroup, struct DupliCache *dupcache);
 
 /* get writer/reader from RNA type */
diff --git a/source/blender/pointcache/alembic/abc_group.cpp b/source/blender/pointcache/alembic/abc_group.cpp
index 80b319f..4bb24d9 100644
--- a/source/blender/pointcache/alembic/abc_group.cpp
+++ b/source/blender/pointcache/alembic/abc_group.cpp
@@ -103,6 +103,86 @@ PTCReadSampleResult AbcGroupReader::read_sample(float frame)
 
 /* ========================================================================= */
 
+AbcDupligroupWriter::AbcDupligroupWriter(const std::string &name, EvaluationContext *eval_ctx, Scene *scene, Group *group) :
+    GroupWriter(group, name),
+    m_eval_ctx(eval_ctx),
+    m_scene(scene)
+{
+}
+
+void AbcDupligroupWriter::open_archive(WriterArchive *archive)
+{
+	BLI_assert(dynamic_cast<AbcWriterArchive*>(archive));
+	AbcWriter::abc_archive(static_cast<AbcWriterArchive*>(archive));
+	
+	if (abc_archive()->archive) {
+		m_abc_group = abc_archive()->add_id_object<OObject>((ID *)m_group);
+	}
+}
+
+void AbcDupligroupWriter::write_sample_object(Object *ob)
+{
+	OObject abc_object = abc_archive()->add_id_object<OObject>((ID *)ob);
+	m_writers.push_back(abc_object.getPtr());
+	
+	// TODO mesh, modifiers, sims ...
+}
+
+void AbcDupligroupWriter::write_sample_dupli(DupliObject *dob, int index)
+{
+	OObject abc_object = abc_archive()->get_id_object((ID *)dob->ob);
+	if (!abc_object)
+		return;
+	
+	std::stringstream ss;
+	ss << "DupliObject" << index;
+	std::string name = ss.str();
+	
+	OObject abc_dupli = m_abc_group.getChild(name);
+	if (!abc_dupli) {
+		abc_dupli = OObject(m_abc_group, name, 0);
+		m_writers.push_back(abc_dupli.getPtr());
+		
+		abc_dupli.addChildInstance(abc_object, "object");
+		
+		// TODO dupli offset, layers, etc.
+	}
+}
+
+void AbcDupligroupWriter::write_sample()
+{
+	if (!m_abc_group)
+		return;
+	
+	ListBase *duplilist = group_duplilist_ex(m_eval_ctx, m_scene, m_group, true);
+	DupliObject *dob;
+	int i;
+	
+	/* LIB_DOIT is used to mark handled objects, clear first */
+	for (dob = (DupliObject *)duplilist->first; dob; dob = dob->next) {
+		if (dob->ob)
+			dob->ob->id.flag &= ~LIB_DOIT;
+	}
+	
+	/* write actual object data: duplicator itself + all instanced objects */
+	for (dob = (DupliObject *)duplilist->first; dob; dob = dob->next) {
+		if (dob->ob->id.flag & LIB_DOIT)
+			continue;
+		dob->ob->id.flag |= LIB_DOIT;
+		
+		write_sample_object(dob->ob);
+	}
+	
+	/* write dupli instances */
+	for (dob = (DupliObject *)duplilist->first, i = 0; dob; dob = dob->next, ++i) {
+		write_sample_dupli(dob, i);
+	}
+	
+	free_object_duplilist(duplilist);
+}
+
+/* ------------------------------------------------------------------------- */
+
 typedef float Matrix[4][4];
 
 typedef float (*MatrixPtr)[4];
diff --git a/source/blender/pointcache/alembic/abc_group.h b/source/blender/pointcache/alembic/abc_group.h
index a11ea7a..9dfa9eb 100644
--- a/source/blender/pointcache/alembic/abc_group.h
+++ b/source/blender/pointcache/alembic/abc_group.h
@@ -30,6 +30,8 @@
 
 struct DupliCache;
 struct Group;
+struct Object;
+struct Scene;
 
 namespace PTC {
 
@@ -58,6 +60,28 @@ private:
 	Abc::IObject m_abc_object;
 };
 
+/* ========================================================================= */
+
+class AbcDupligroupWriter : public GroupWriter, public AbcWriter {
+public:
+	typedef std::vector<Abc::ObjectWriterPtr> WriterList;
+	
+	AbcDupligroupWriter(const std::string &name, EvaluationContext *eval_ctx, Scene *scene, Group *group);
+	
+	void open_archive(WriterArchive *archive);
+	
+	void write_sample();
+	void write_sample_object(Object *ob);
+	void write_sample_dupli(DupliObject *dob, int index);
+	
+private:
+	EvaluationContext *m_eval_ctx;
+	Scene *m_scene;
+	
+	Abc::OObject m_abc_group;
+	WriterList m_writers;
+};
+
 PTCReadSampleResult abc_read_dupligroup(ReaderArchive *archive, float frame, Group *dupgroup, DupliCache *dupcache);
 
 } /* namespace PTC */
diff --git a/source/blender/pointcache/alembic/abc_writer.cpp b/source/blender/pointcache/alembic/abc_writer.cpp
index fd2a098..c69e997 100644
--- a/source/blender/pointcache/alembic/abc_writer.cpp
+++ b/source/blender/pointcache/alembic/abc_writer.cpp
@@ -71,8 +71,19 @@ OObject AbcWriterArchive::get_id_object(ID *id)
 	if (!archive)
 		return OObject();
 	
-	OObject root = archive.getTop();
-	return root.getChild(id->name);
+	ObjectWriterPtr root = archive.getTop().getPtr();
+	
+	ObjectWriterPtr child = root->getChild(id->name);
+	if (child)
+		return OObject(child, kWrapExist

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list