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
path: root/source
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2015-03-14 19:39:57 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2015-03-26 16:13:37 +0300
commitad2a8e7fd81614110d3ad8ac5555e6b2ace4d7cc (patch)
tree521412a68143aad84c4009a74cc1d14590dcb83e /source
parent401b7205311be65ee4b9ff80cb21985c37dde4c9 (diff)
Moved the dupli cache reading code into a AbcDupligroupReader class.
This is more in line with how readers work in the Blender Alembic implementation elsewhere. Generally, readers are less persistent than writers: they are created whenever cache results need to be updated (e.g. on frame changes) and discarded afterward. Writers OTOH stay alive during the whole baking job, since they keep the references to Alembic Writer instances and can only be deleted once the writing for that part is done.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/cache_library.c7
-rw-r--r--source/blender/pointcache/PTC_api.cpp4
-rw-r--r--source/blender/pointcache/PTC_api.h2
-rw-r--r--source/blender/pointcache/alembic/abc_group.cpp198
-rw-r--r--source/blender/pointcache/alembic/abc_group.h36
-rw-r--r--source/blender/pointcache/alembic/alembic.cpp4
-rw-r--r--source/blender/pointcache/intern/ptc_types.h2
7 files changed, 130 insertions, 123 deletions
diff --git a/source/blender/blenkernel/intern/cache_library.c b/source/blender/blenkernel/intern/cache_library.c
index 1f4ed637c8d..0b63ad5e3f0 100644
--- a/source/blender/blenkernel/intern/cache_library.c
+++ b/source/blender/blenkernel/intern/cache_library.c
@@ -1229,13 +1229,18 @@ bool BKE_cache_read_dupligroup(Main *bmain, Scene *scene, float frame, eCacheLib
if (cachelib->group == dupgroup) {
char filename[FILE_MAX];
struct PTCReaderArchive *archive;
+ struct PTCReader *reader;
eCacheReadSampleResult result;
BKE_cache_archive_path(cachelib->filepath, (ID *)cachelib, cachelib->id.lib, filename, sizeof(filename));
archive = PTC_open_reader_archive(scene, filename);
- result = BKE_cache_read_result(PTC_read_dupligroup(archive, frame, dupgroup, dupcache));
+ reader = PTC_reader_dupligroup(dupgroup->id.name, dupgroup, dupcache);
+ PTC_reader_set_archive(reader, archive);
+ result = BKE_cache_read_result(PTC_read_sample(reader, frame));
+
+ PTC_reader_free(reader);
PTC_close_reader_archive(archive);
return true;
diff --git a/source/blender/pointcache/PTC_api.cpp b/source/blender/pointcache/PTC_api.cpp
index 810bb32be68..b2a9a56f68e 100644
--- a/source/blender/pointcache/PTC_api.cpp
+++ b/source/blender/pointcache/PTC_api.cpp
@@ -216,9 +216,9 @@ PTCWriter *PTC_writer_dupligroup(const char *name, struct EvaluationContext *eva
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)
+PTCReader *PTC_reader_dupligroup(const char *name, struct Group *group, struct DupliCache *dupcache)
{
- return PTC::Factory::alembic->read_dupligroup((PTC::ReaderArchive *)archive, frame, dupgroup, dupcache);
+ return (PTCReader *)PTC::Factory::alembic->create_reader_dupligroup(name, group, dupcache);
}
diff --git a/source/blender/pointcache/PTC_api.h b/source/blender/pointcache/PTC_api.h
index 18c975a93a9..105dabb1e94 100644
--- a/source/blender/pointcache/PTC_api.h
+++ b/source/blender/pointcache/PTC_api.h
@@ -86,7 +86,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);
+struct PTCReader *PTC_reader_dupligroup(const char *name, struct Group *group, struct DupliCache *dupcache);
/* get writer/reader from RNA type */
struct PTCWriter *PTC_writer_from_rna(struct Scene *scene, struct PointerRNA *ptr);
diff --git a/source/blender/pointcache/alembic/abc_group.cpp b/source/blender/pointcache/alembic/abc_group.cpp
index 142e3c9ee8d..b2be67296f2 100644
--- a/source/blender/pointcache/alembic/abc_group.cpp
+++ b/source/blender/pointcache/alembic/abc_group.cpp
@@ -217,120 +217,46 @@ Writer *AbcDupligroupWriter::find_id_writer(ID *id) const
/* ------------------------------------------------------------------------- */
-typedef float Matrix[4][4];
-
-typedef float (*MatrixPtr)[4];
+AbcDupligroupReader::AbcDupligroupReader(const std::string &name, Group *group, DupliCache *dupli_cache) :
+ GroupReader(group, name),
+ dupli_cache(dupli_cache)
+{
+ /* XXX this mapping allows fast lookup of existing objects in Blender data
+ * to associate with duplis. Later i may be possible to create instances of
+ * non-DNA data, but for the time being this is a requirement due to other code parts (drawing, rendering)
+ */
+ build_object_map(G.main, group);
+}
-static Matrix I = {{1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}};
+AbcDupligroupReader::~AbcDupligroupReader()
+{
+}
-struct DupliGroupContext {
- typedef std::map<ObjectReaderPtr, DupliObjectData*> DupliMap;
- typedef std::pair<ObjectReaderPtr, DupliObjectData*> DupliPair;
-
- struct Transform {
- Transform() {}
- Transform(float (*value)[4]) { copy_m4_m4(matrix, value); }
- Transform(const Transform &tfm) { memcpy(matrix, tfm.matrix, sizeof(Matrix)); }
-
- Matrix matrix;
- };
- typedef std::vector<Transform> TransformStack;
-
- typedef std::map<std::string, Object*> ObjectMap;
- typedef std::pair<std::string, Object*> ObjectPair;
-
- /* constructor */
- DupliGroupContext(DupliCache *dupli_cache) :
- dupli_cache(dupli_cache)
- {
- tfm_stack.push_back(Transform(I));
- }
-
-
- DupliObjectData *find_dupli_data(ObjectReaderPtr ptr) const
- {
- DupliMap::const_iterator it = dupli_map.find(ptr);
- if (it == dupli_map.end())
- return NULL;
- else
- return it->second;
- }
-
- void insert_dupli_data(ObjectReaderPtr ptr, DupliObjectData *data)
- {
- dupli_map.insert(DupliPair(ptr, data));
- }
-
-
- MatrixPtr get_transform() { return tfm_stack.back().matrix; }
-// void push_transform(float mat[4][4])
-
-
- void build_object_map(Main *bmain, Group *group)
- {
- BKE_main_id_tag_idcode(bmain, ID_OB, false);
- BKE_main_id_tag_idcode(bmain, ID_GR, false);
- object_map.clear();
-
- build_object_map_add_group(group);
- }
-
- Object *find_object(const std::string &name) const
- {
- ObjectMap::const_iterator it = object_map.find(name);
- if (it == object_map.end())
- return NULL;
- else
- return it->second;
- }
-
- DupliMap dupli_map;
- DupliCache *dupli_cache;
-
- TransformStack tfm_stack;
-
- ObjectMap object_map;
-
-protected:
- void build_object_map_add_group(Group *group)
- {
- if (group->id.flag & LIB_DOIT)
- return;
- group->id.flag |= LIB_DOIT;
-
- for (GroupObject *gob = (GroupObject *)group->gobject.first; gob; gob = gob->next) {
- Object *ob = gob->ob;
- if (ob->id.flag & LIB_DOIT)
- continue;
- ob->id.flag |= LIB_DOIT;
- object_map.insert(ObjectPair(ob->id.name, ob));
-
- if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
- build_object_map_add_group(ob->dup_group);
- }
- }
- }
-};
+void AbcDupligroupReader::open_archive(ReaderArchive *archive)
+{
+ BLI_assert(dynamic_cast<AbcReaderArchive*>(archive));
+ AbcReader::abc_archive(static_cast<AbcReaderArchive*>(archive));
+}
-static void read_dupligroup_object(DupliGroupContext &ctx, IObject object, const ISampleSelector &ss)
+void AbcDupligroupReader::read_dupligroup_object(IObject object, const ISampleSelector &ss)
{
if (GS(object.getName().c_str()) == ID_OB) {
/* instances are handled later, we create true object data here */
if (object.isInstanceDescendant())
return;
- Object *b_ob = ctx.find_object(object.getName());
+ Object *b_ob = find_object(object.getName());
if (!b_ob)
return;
/* TODO load DM, from subobjects for IPolyMesh etc. */
DerivedMesh *dm = NULL;
- DupliObjectData *data = BKE_dupli_cache_add_mesh(ctx.dupli_cache, b_ob, dm);
- ctx.insert_dupli_data(object.getPtr(), data);
+ DupliObjectData *data = BKE_dupli_cache_add_mesh(dupli_cache, b_ob, dm);
+ insert_dupli_data(object.getPtr(), data);
}
}
-static void read_dupligroup_group(DupliGroupContext &ctx, IObject abc_group, const ISampleSelector &ss)
+void AbcDupligroupReader::read_dupligroup_group(IObject abc_group, const ISampleSelector &ss)
{
if (GS(abc_group.getName().c_str()) == ID_GR) {
size_t num_child = abc_group.getNumChildren();
@@ -346,42 +272,84 @@ static void read_dupligroup_group(DupliGroupContext &ctx, IObject abc_group, con
IObject abc_dupli_object = abc_dupli.getChild("object");
if (abc_dupli_object.isInstanceRoot()) {
- DupliObjectData *dupli_data = ctx.find_dupli_data(abc_dupli_object.getPtr());
+ DupliObjectData *dupli_data = find_dupli_data(abc_dupli_object.getPtr());
if (dupli_data) {
- BKE_dupli_cache_add_instance(ctx.dupli_cache, matrix, dupli_data);
+ BKE_dupli_cache_add_instance(dupli_cache, matrix, dupli_data);
}
}
}
}
}
-PTCReadSampleResult abc_read_dupligroup(ReaderArchive *_archive, float frame, Group *dupgroup, DupliCache *dupcache)
+PTCReadSampleResult AbcDupligroupReader::read_sample(float frame)
{
- AbcReaderArchive *archive = (AbcReaderArchive *)_archive;
- DupliGroupContext ctx(dupcache);
-
- /* XXX this mapping allows fast lookup of existing objects in Blender data
- * to associate with duplis. Later i may be possible to create instances of
- * non-DNA data, but for the time being this is a requirement due to other code parts (drawing, rendering)
- */
- ctx.build_object_map(G.main, dupgroup);
+ ISampleSelector ss = abc_archive()->get_frame_sample_selector(frame);
- ISampleSelector ss = archive->get_frame_sample_selector(frame);
-
- IObject abc_top = archive->archive.getTop();
- IObject abc_group = archive->get_id_object((ID *)dupgroup);
+ IObject abc_top = abc_archive()->archive.getTop();
+ IObject abc_group = abc_archive()->get_id_object((ID *)m_group);
if (!abc_group)
return PTC_READ_SAMPLE_INVALID;
/* first create shared object data */
for (size_t i = 0; i < abc_top.getNumChildren(); ++i) {
- read_dupligroup_object(ctx, abc_top.getChild(i), ss);
+ read_dupligroup_object(abc_top.getChild(i), ss);
}
- /* now generate dupli instances for the dupgroup */
- read_dupligroup_group(ctx, abc_group, ss);
+ /* now generate dupli instances for the group */
+ read_dupligroup_group(abc_group, ss);
return PTC_READ_SAMPLE_EXACT;
}
+DupliObjectData *AbcDupligroupReader::find_dupli_data(ObjectReaderPtr ptr) const
+{
+ DupliMap::const_iterator it = dupli_map.find(ptr);
+ if (it == dupli_map.end())
+ return NULL;
+ else
+ return it->second;
+}
+
+void AbcDupligroupReader::insert_dupli_data(ObjectReaderPtr ptr, DupliObjectData *data)
+{
+ dupli_map.insert(DupliPair(ptr, data));
+}
+
+void AbcDupligroupReader::build_object_map(Main *bmain, Group *group)
+{
+ BKE_main_id_tag_idcode(bmain, ID_OB, false);
+ BKE_main_id_tag_idcode(bmain, ID_GR, false);
+ object_map.clear();
+
+ build_object_map_add_group(group);
+}
+
+Object *AbcDupligroupReader::find_object(const std::string &name) const
+{
+ ObjectMap::const_iterator it = object_map.find(name);
+ if (it == object_map.end())
+ return NULL;
+ else
+ return it->second;
+}
+
+void AbcDupligroupReader::build_object_map_add_group(Group *group)
+{
+ if (group->id.flag & LIB_DOIT)
+ return;
+ group->id.flag |= LIB_DOIT;
+
+ for (GroupObject *gob = (GroupObject *)group->gobject.first; gob; gob = gob->next) {
+ Object *ob = gob->ob;
+ if (ob->id.flag & LIB_DOIT)
+ continue;
+ ob->id.flag |= LIB_DOIT;
+ object_map.insert(ObjectPair(ob->id.name, ob));
+
+ if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
+ build_object_map_add_group(ob->dup_group);
+ }
+ }
+}
+
} /* namespace PTC */
diff --git a/source/blender/pointcache/alembic/abc_group.h b/source/blender/pointcache/alembic/abc_group.h
index 92f28a3b5d6..771a65cddf6 100644
--- a/source/blender/pointcache/alembic/abc_group.h
+++ b/source/blender/pointcache/alembic/abc_group.h
@@ -26,6 +26,8 @@
#include "abc_writer.h"
struct DupliCache;
+struct DupliObject;
+struct DupliObjectData;
struct Group;
struct Object;
struct Scene;
@@ -88,7 +90,39 @@ private:
IDWriterMap m_id_writers;
};
-PTCReadSampleResult abc_read_dupligroup(ReaderArchive *archive, float frame, Group *dupgroup, DupliCache *dupcache);
+class AbcDupligroupReader : public GroupReader, public AbcReader {
+public:
+ typedef std::map<Abc::ObjectReaderPtr, DupliObjectData*> DupliMap;
+ typedef std::pair<Abc::ObjectReaderPtr, DupliObjectData*> DupliPair;
+
+ typedef std::map<std::string, Object*> ObjectMap;
+ typedef std::pair<std::string, Object*> ObjectPair;
+
+public:
+ AbcDupligroupReader(const std::string &name, Group *group, DupliCache *dupcache);
+ ~AbcDupligroupReader();
+
+ void open_archive(ReaderArchive *archive);
+
+ PTCReadSampleResult read_sample(float frame);
+
+protected:
+ void read_dupligroup_object(Abc::IObject object, const Abc::ISampleSelector &ss);
+ void read_dupligroup_group(Abc::IObject abc_group, const Abc::ISampleSelector &ss);
+
+ DupliObjectData *find_dupli_data(Abc::ObjectReaderPtr ptr) const;
+ void insert_dupli_data(Abc::ObjectReaderPtr ptr, DupliObjectData *data);
+
+ void build_object_map(Main *bmain, Group *group);
+ void build_object_map_add_group(Group *group);
+ Object *find_object(const std::string &name) const;
+
+private:
+ DupliMap dupli_map;
+ DupliCache *dupli_cache;
+
+ ObjectMap object_map;
+};
} /* namespace PTC */
diff --git a/source/blender/pointcache/alembic/alembic.cpp b/source/blender/pointcache/alembic/alembic.cpp
index 4b7ee24a29f..e928fe0c62a 100644
--- a/source/blender/pointcache/alembic/alembic.cpp
+++ b/source/blender/pointcache/alembic/alembic.cpp
@@ -157,9 +157,9 @@ class AbcFactory : public Factory {
return new AbcDupligroupWriter(name, eval_ctx, scene, group);
}
- PTCReadSampleResult read_dupligroup(ReaderArchive *archive, float frame, Group *dupgroup, DupliCache *dupcache)
+ Reader *create_reader_dupligroup(const std::string &name, Group *group, DupliCache *dupcache)
{
- return abc_read_dupligroup(archive, frame, dupgroup, dupcache);
+ return new AbcDupligroupReader(name, group, dupcache);
}
};
diff --git a/source/blender/pointcache/intern/ptc_types.h b/source/blender/pointcache/intern/ptc_types.h
index c217708a0f5..dc278f9ed1c 100644
--- a/source/blender/pointcache/intern/ptc_types.h
+++ b/source/blender/pointcache/intern/ptc_types.h
@@ -217,7 +217,7 @@ struct Factory {
virtual Writer *create_writer_cache_modifier_render(const std::string &name, Scene *scene, Object *ob, CacheModifierData *cmd) = 0;
virtual Writer *create_writer_dupligroup(const std::string &name, EvaluationContext *eval_ctx, Scene *scene, Group *group) = 0;
- virtual PTCReadSampleResult read_dupligroup(ReaderArchive *archive, float frame, Group *dupgroup, DupliCache *dupcache) = 0;
+ virtual Reader *create_reader_dupligroup(const std::string &name, Group *group, DupliCache *dupcache) = 0;
static Factory *alembic;
};