[Bf-blender-cvs] [9c26924] alembic: Added writers for DupliCache data to allow truely successive cache modification.

Lukas Tönne noreply at git.blender.org
Wed Apr 1 11:35:42 CEST 2015


Commit: 9c269243dbbc270a71119996a969ed25303caf8a
Author: Lukas Tönne
Date:   Wed Apr 1 11:31:41 2015 +0200
Branches: alembic
https://developer.blender.org/rB9c269243dbbc270a71119996a969ed25303caf8a

Added writers for DupliCache data to allow truely successive cache
modification.

The bake operator will now generate output based on the 'source_mode'
setting:
* When the source is SCENE it uses the basic object data as stored in
  the Object ID datablocks (DerivedMesh, particle hair strands etc.)
* When the source is CACHE it fills a temporary DupliCache with data
  from the cache archive (like it would for the display dupli_cache,
  but also supporting render data). This dupli cache is carried over
  between frames during baking, which allows modifiers to act as
  simulations and sequentially advance motion states.

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

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_particles.cpp
M	source/blender/pointcache/alembic/alembic.cpp
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 7d94e6c..9a39b06 100644
--- a/source/blender/editors/io/io_cache_library.c
+++ b/source/blender/editors/io/io_cache_library.c
@@ -242,9 +242,19 @@ static void cache_library_bake_do(CacheLibraryBakeJob *data)
 	if (cache_library_bake_stop(data))
 		return;
 	
+	switch (data->cachelib->source_mode) {
+		case CACHE_LIBRARY_SOURCE_SCENE:
+			data->writer = PTC_writer_dupligroup(data->group->id.name, &data->eval_ctx, scene, data->group, data->cachelib);
+			break;
+		case CACHE_LIBRARY_SOURCE_CACHE:
+			data->writer = PTC_writer_duplicache(data->group->id.name, data->group, write_dupcache, data->cachelib->data_types);
+			break;
+	}
+	if (!data->writer)
+		return;
+	
 	data->cachelib->flag |= CACHE_LIBRARY_BAKING;
 	
-	data->writer = PTC_writer_dupligroup(data->group->id.name, &data->eval_ctx, scene, data->group, data->cachelib);
 	PTC_writer_init(data->writer, data->archive);
 	
 	/* XXX where to get this from? */
diff --git a/source/blender/pointcache/PTC_api.cpp b/source/blender/pointcache/PTC_api.cpp
index 1196da2..1b9a3f0 100644
--- a/source/blender/pointcache/PTC_api.cpp
+++ b/source/blender/pointcache/PTC_api.cpp
@@ -248,6 +248,11 @@ PTCWriter *PTC_writer_dupligroup(const char *name, struct EvaluationContext *eva
 	return (PTCWriter *)PTC::Factory::alembic->create_writer_dupligroup(name, eval_ctx, scene, group, cachelib);
 }
 
+PTCWriter *PTC_writer_duplicache(const char *name, struct Group *group, struct DupliCache *dupcache, int datatypes)
+{
+	return (PTCWriter *)PTC::Factory::alembic->create_writer_duplicache(name, group, dupcache, datatypes);
+}
+
 PTCReader *PTC_reader_duplicache(const char *name, struct Group *group, struct DupliCache *dupcache)
 {
 	return (PTCReader *)PTC::Factory::alembic->create_reader_duplicache(name, group, dupcache);
diff --git a/source/blender/pointcache/PTC_api.h b/source/blender/pointcache/PTC_api.h
index bf883d2..0bb5889 100644
--- a/source/blender/pointcache/PTC_api.h
+++ b/source/blender/pointcache/PTC_api.h
@@ -83,6 +83,8 @@ 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, struct CacheLibrary *cachelib);
+struct PTCWriter *PTC_writer_duplicache(const char *name, struct Group *group, struct DupliCache *dupcache, int datatypes);
+
 struct PTCReader *PTC_reader_duplicache(const char *name, struct Group *group, struct DupliCache *dupcache);
 struct PTCReader *PTC_reader_duplicache_object(const char *name, struct Object *ob, struct DupliObjectData *data);
 
diff --git a/source/blender/pointcache/alembic/abc_group.cpp b/source/blender/pointcache/alembic/abc_group.cpp
index c319058..5509a12 100644
--- a/source/blender/pointcache/alembic/abc_group.cpp
+++ b/source/blender/pointcache/alembic/abc_group.cpp
@@ -217,6 +217,109 @@ AbcWriter *AbcDupligroupWriter::find_id_writer(ID *id) const
 
 /* ------------------------------------------------------------------------- */
 
+AbcDupliCacheWriter::AbcDupliCacheWriter(const std::string &name, Group *group, DupliCache *dupcache, int data_types) :
+    GroupWriter(group, name),
+    m_dupcache(dupcache),
+    m_data_types(data_types)
+{
+}
+
+AbcDupliCacheWriter::~AbcDupliCacheWriter()
+{
+	for (IDWriterMap::iterator it = m_id_writers.begin(); it != m_id_writers.end(); ++it) {
+		if (it->second)
+			delete it->second;
+	}
+}
+
+void AbcDupliCacheWriter::init_abc()
+{
+	if (m_abc_group)
+		return;
+	
+	m_abc_group = abc_archive()->add_id_object<OObject>((ID *)m_group);
+}
+
+void AbcDupliCacheWriter::write_sample_object_data(DupliObjectData *data)
+{
+	AbcWriter *ob_writer = find_id_writer((ID *)data->ob);
+	if (!ob_writer) {
+		bool do_mesh = (m_data_types & CACHE_TYPE_DERIVED_MESH);
+		bool do_hair = (m_data_types & CACHE_TYPE_HAIR);
+		
+		ob_writer = new AbcDupliObjectWriter(data->ob->id.name, data, do_mesh, do_hair);
+		ob_writer->init(abc_archive());
+		m_id_writers.insert(IDWriterPair((ID *)data->ob, ob_writer));
+	}
+	
+	ob_writer->write_sample();
+}
+
+void AbcDupliCacheWriter::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);
+	OCompoundProperty props;
+	OM44fProperty prop_matrix;
+	if (!abc_dupli) {
+		abc_dupli = OObject(m_abc_group, name, 0);
+		m_object_writers.push_back(abc_dupli.getPtr());
+		props = abc_dupli.getProperties();
+		
+		abc_dupli.addChildInstance(abc_object, "object");
+		
+		prop_matrix = OM44fProperty(props, "matrix", 0);
+		m_property_writers.push_back(prop_matrix.getPtr());
+	}
+	else {
+		props = abc_dupli.getProperties();
+		
+		prop_matrix = OM44fProperty(props.getProperty("matrix").getPtr()->asScalarPtr(), kWrapExisting);
+	}
+	
+	prop_matrix.set(M44f(dob->mat));
+}
+
+void AbcDupliCacheWriter::write_sample()
+{
+	if (!m_abc_group)
+		return;
+	
+	DupliObject *dob;
+	int i;
+	
+	struct DupliCacheIterator *iter = BKE_dupli_cache_iter_new(m_dupcache);
+	for (; BKE_dupli_cache_iter_valid(iter); BKE_dupli_cache_iter_next(iter)) {
+		DupliObjectData *data = BKE_dupli_cache_iter_get(iter);
+		
+		write_sample_object_data(data);
+	}
+	BKE_dupli_cache_iter_free(iter);
+	
+	/* write dupli instances */
+	for (dob = (DupliObject *)m_dupcache->duplilist.first, i = 0; dob; dob = dob->next, ++i) {
+		write_sample_dupli(dob, i);
+	}
+}
+
+AbcWriter *AbcDupliCacheWriter::find_id_writer(ID *id) const
+{
+	IDWriterMap::const_iterator it = m_id_writers.find(id);
+	if (it == m_id_writers.end())
+		return NULL;
+	else
+		return it->second;
+}
+
+/* ------------------------------------------------------------------------- */
+
 AbcDupliCacheReader::AbcDupliCacheReader(const std::string &name, Group *group, DupliCache *dupli_cache) :
     GroupReader(group, name),
     dupli_cache(dupli_cache)
@@ -387,6 +490,82 @@ void AbcDupliCacheReader::build_object_map_add_group(Group *group)
 
 /* ------------------------------------------------------------------------- */
 
+AbcDupliObjectWriter::AbcDupliObjectWriter(const std::string &name, DupliObjectData *dupdata, bool do_mesh, bool do_strands) :
+    ObjectWriter(dupdata->ob, name),
+    m_dupdata(dupdata),
+    m_dm_writer(0)
+{
+	if (do_mesh) {
+		if (m_ob && m_ob->type == OB_MESH) {
+			m_dm_writer = new AbcDerivedMeshWriter("mesh", dupdata->ob, &dupdata->dm);
+		}
+	}
+	
+	if (do_strands) {
+		int index = 0;
+		for (LinkData *link = (LinkData *)dupdata->strands.first; link; link = link->next) {
+			Strands *strands = (Strands *)link->data;
+			if (strands) {
+				std::stringstream ss;
+				ss << "strands" << index;
+				m_strands_writers.push_back(new AbcStrandsWriter(ss.str(), strands));
+				
+				++index;
+			}
+		}
+	}
+}
+
+AbcDupliObjectWriter::~AbcDupliObjectWriter()
+{
+	if (m_dm_writer)
+		delete m_dm_writer;
+	for (int i = 0; i < m_strands_writers.size(); ++i)
+		if (m_strands_writers[i])
+			delete m_strands_writers[i];
+}
+
+void AbcDupliObjectWriter::init_abc()
+{
+	if (m_abc_object)
+		return;
+	
+	m_abc_object = abc_archive()->add_id_object<OObject>((ID *)m_ob);
+	
+	if (m_dm_writer) {
+		/* XXX not nice */
+		m_dm_writer->init(abc_archive());
+		m_dm_writer->init_abc(m_abc_object);
+	}
+	
+	for (int i = 0; i < m_strands_writers.size(); ++i) {
+		AbcStrandsWriter *strands_writer = m_strands_writers[i];
+		if (strands_writer) {
+			strands_writer->init(abc_archive());
+			strands_writer->init_abc(m_abc_object);
+		}
+	}
+}
+
+void AbcDupliObjectWriter::write_sample()
+{
+	if (!m_abc_object)
+		return;
+	
+	if (m_dm_writer) {
+		m_dm_writer->write_sample();
+	}
+	
+	for (int i = 0; i < m_strands_writers.size(); ++i) {
+		AbcStrandsWriter *strands_writer = m_strands_writers[i];
+		if (strands_writer) {
+			strands_writer->write_sample();
+		}
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
 AbcDupliObjectReader::AbcDupliObjectReader(const std::string &name, Object *ob, DupliObjectData *dupli_data) :
     ObjectReader(ob, name),
     dupli_data(dupli_data)
diff --git a/source/blender/pointcache/alembic/abc_group.h b/source/blender/pointcache/alembic/abc_group.h
index 4284be2..a2d0338 100644
--- a/source/blender/pointcache/alembic/abc_group.h
+++ b/source/blender/pointcache/alembic/abc_group.h
@@ -35,6 +35,9 @@ struct Scene;
 
 namespace PTC {
 
+class AbcDerivedMeshWriter;
+class AbcStrandsWriter;
+
 class AbcGroupWriter : public GroupWriter, public AbcWriter {
 public:
 	AbcGroupWriter(const std::string &name, Group *group);
@@ -92,6 +95,35 @@ private:
 	IDWriterMap m_id_writers;
 };
 
+class AbcDupliCacheWriter : public GroupWriter, public AbcWriter {
+public:
+	typedef std::vector<Abc::ObjectWriterPtr> ObjectWriterList;
+	typedef std::vector<Abc::BasePropertyWriterPtr> PropertyWriterList;
+	
+	typedef std::map<ID *, AbcWriter *> IDWriterMap;
+	typedef std::pair<ID *, AbcWriter *> IDWriterPair;
+	
+	AbcDupliCacheWriter(const std::string &name, Group *group, DupliCache *dupcache, int data_types);
+	~AbcDupliCacheWriter();
+	
+	void init_abc();
+	
+	void write_sample();
+	void write_sample_object_data(DupliObjectData *data);
+	void write_sample_dupli(DupliObject *dob, int index);
+	
+	AbcWriter *find_id_writer(ID *id) const;
+	
+private:
+	DupliCache *m_dupcache;
+	int m_data_types;
+	
+	Abc::OObject m_abc_group;
+	ObjectWriterList m_object_writers;
+	PropertyWriterList m_property_writers;
+	IDWriterMap m_id_writers;
+};
+
 class AbcDupliCacheReader : public GroupReader, public AbcReader {
 public:
 	typedef std::map<Abc::ObjectReaderPtr, DupliObjectData*> DupliMap;
@@ -126,6 +158,26 @@ private:
 	ObjectMap object_map;
 };
 
+
+class AbcDupliObjectWriter : public ObjectWriter, public AbcWriter {
+public:
+	typedef std::vector<AbcStrandsWriter *> StrandsWriters;
+	
+	AbcDupliObjectWriter(const std::string &name, DupliObjectData *dupdata, bool do_mesh, bool do_strands);
+	~AbcDupliObjectWr

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list