[Bf-blender-cvs] [cbe1d5ccea4] sybren-usd: USD: Iterate depsgraph, rather than view layer bases
Sybren A. Stüvel
noreply at git.blender.org
Fri Jun 21 16:40:13 CEST 2019
Commit: cbe1d5ccea45642b889edd80a2772c3fa7dd857e
Author: Sybren A. Stüvel
Date: Thu Jun 20 17:10:25 2019 +0200
Branches: sybren-usd
https://developer.blender.org/rBcbe1d5ccea45642b889edd80a2772c3fa7dd857e
USD: Iterate depsgraph, rather than view layer bases
The depsgraph contains all info we need, and iterating it is more
future-proof than iterating the view layer. This also removes any use of
original data and makes the USD exporter work 100% on evaluated data.
Also contains some other cleanups.
===================================================================
M source/blender/usd/intern/abstract_hierarchy_iterator.cc
M source/blender/usd/intern/abstract_hierarchy_iterator.h
===================================================================
diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
index c0dc1e3ad75..c51aa377e80 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
@@ -7,11 +7,11 @@ extern "C" {
#include "BLI_assert.h"
-#include "DEG_depsgraph_query.h"
-
#include "DNA_ID.h"
#include "DNA_layer_types.h"
#include "DNA_object_types.h"
+
+#include "DEG_depsgraph_query.h"
}
AbstractHierarchyIterator::AbstractHierarchyIterator(Depsgraph *depsgraph)
@@ -38,20 +38,26 @@ void AbstractHierarchyIterator::release_writers()
void AbstractHierarchyIterator::iterate()
{
- ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
printf("====== Visiting objects:\n");
- Scene *scene = DEG_get_input_scene(depsgraph);
- for (Base *base = static_cast<Base *>(view_layer->object_bases.first); base; base = base->next) {
- if (base->flag & BASE_HOLDOUT) {
+ DEG_OBJECT_ITER_BEGIN (depsgraph,
+ object,
+ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) {
+ if (object->base_flag & BASE_HOLDOUT) {
+ visit_object(object, object->parent, true);
+ continue;
+ }
+ if (!should_visit_object(object)) {
continue;
}
// Non-instanced objects always have their object-parent as export-parent.
- visit_object(base, base->object, base->object->parent, false);
+ visit_object(object, object->parent, false);
// Export the duplicated objects instanced by this object.
- ListBase *lb = object_duplilist(depsgraph, scene, base->object);
+ ListBase *lb = object_duplilist(depsgraph, scene, object);
if (lb) {
DupliObject *link = nullptr;
@@ -77,27 +83,16 @@ void AbstractHierarchyIterator::iterate()
export_parent = link->ob->parent;
}
else {
- export_parent = base->object;
+ export_parent = object;
}
- visit_object(base, link->ob, export_parent, false);
+ visit_object(link->ob, export_parent, false);
}
}
free_object_duplilist(lb);
}
-
- // Add the parent objects that weren't included in this view layer as transform-only objects.
- // This ensures that the object hierarchy in Blender is reflected in the exported file.
- printf("====== adding xform-onlies:\n");
- while (!xform_onlies.empty()) {
- std::set<Object *>::iterator first = xform_onlies.begin();
-
- Object *xform_only = *first;
- visit_object(nullptr, xform_only, xform_only->parent, true);
-
- xform_onlies.erase(xform_only);
- }
+ DEG_OBJECT_ITER_END;
// For debug: print the export graph.
printf("====== Export graph:\n");
@@ -134,21 +129,15 @@ void AbstractHierarchyIterator::make_writers(Object *parent_object,
context.xform_only ? "true" : "false");
// Get or create the transform writer.
- xform_writer = get_writer(export_path);
- if (xform_writer == nullptr) {
- xform_writer = create_xform_writer(context);
- if (xform_writer != nullptr) {
- writers[export_path] = xform_writer;
- }
- }
+ xform_writer = ensure_xform_writer(context);
if (xform_writer == nullptr) {
// Unable to export, so there is nothing to attach any children to; just abort this entire
// branch of the export hierarchy.
return;
}
- Object *object_eval = DEG_get_evaluated_object(depsgraph, context.object);
- xform_writer->write(object_eval);
+ BLI_assert(DEG_is_evaluated_object(context.object));
+ xform_writer->write(context.object);
// Get or create the object data writer, but only if it is needed.
if (!context.xform_only && context.object->data != nullptr) {
@@ -159,16 +148,9 @@ void AbstractHierarchyIterator::make_writers(Object *parent_object,
context.export_path = data_path;
context.parent_writer = xform_writer;
- data_writer = get_writer(data_path);
- if (data_writer == nullptr) {
- data_writer = create_data_writer(context);
- if (data_writer != nullptr) {
- writers[data_path] = data_writer;
- }
- }
-
+ data_writer = ensure_data_writer(context);
if (data_writer != nullptr) {
- data_writer->write(object_eval);
+ data_writer->write(context.object);
}
}
@@ -178,7 +160,7 @@ void AbstractHierarchyIterator::make_writers(Object *parent_object,
// TODO(Sybren): iterate over all unused writers and call unused_during_iteration() or something.
}
-std::string AbstractHierarchyIterator::get_object_name(const Object *const object) const
+std::string AbstractHierarchyIterator::get_object_name(const Object *object) const
{
if (object == nullptr) {
return "";
@@ -187,7 +169,7 @@ std::string AbstractHierarchyIterator::get_object_name(const Object *const objec
return get_id_name(&object->id);
}
-std::string AbstractHierarchyIterator::get_id_name(const ID *const id) const
+std::string AbstractHierarchyIterator::get_id_name(const ID *id) const
{
if (id == nullptr) {
return "";
@@ -202,37 +184,23 @@ std::string AbstractHierarchyIterator::path_concatenate(const std::string &paren
return parent_path + "/" + child_path;
}
-bool AbstractHierarchyIterator::should_visit_object(const Base * /*base*/,
- bool /*is_duplicated*/) const
+bool AbstractHierarchyIterator::should_visit_object(const Object * /*object*/) const
{
return true;
}
-bool AbstractHierarchyIterator::should_visit_duplilink(const DupliObject *const link) const
+bool AbstractHierarchyIterator::should_visit_duplilink(const DupliObject *link) const
{
// Removing link->no_draw hides things like custom bone shapes.
- return !link->no_draw && link->type == OB_DUPLICOLLECTION;
+ return !link->no_draw;
}
-void AbstractHierarchyIterator::visit_object(Base *base,
- Object *object,
+void AbstractHierarchyIterator::visit_object(Object *object,
Object *export_parent,
bool xform_only)
{
- /* If an object isn't exported itself, its duplilist shouldn't be
- * exported either. */
- if (!should_visit_object(base, false)) {
- return;
- }
-
- BLI_assert(export_parent == nullptr || DEG_is_original_object(export_parent));
- if (export_parent != NULL && export_graph.find(export_parent) == export_graph.end()) {
- // The parent is not (yet) exported, to remember to export it as transform-only.
- xform_onlies.insert(export_parent);
- }
-
- // This object is exported for real (so not "transform-only").
- xform_onlies.erase(object);
+ BLI_assert(DEG_is_evaluated_object(object));
+ BLI_assert(export_parent == nullptr || DEG_is_evaluated_object(export_parent));
HierarchyContext context = {
.object = object,
@@ -246,10 +214,14 @@ void AbstractHierarchyIterator::visit_object(Base *base,
export_graph[export_parent].insert(context);
std::string export_parent_name = export_parent ? get_object_name(export_parent) : "/";
- printf(" OB %20s (parent=%s; xform-only=%s)\n",
+ printf(" OB %30s %p (parent=%s %p; xform-only=%s; instance=%s)\n",
get_object_name(object).c_str(),
+ object,
export_parent_name.c_str(),
- context.xform_only ? "true" : "false");
+ export_parent,
+ context.xform_only ? "\033[31;1mtrue\033[0m" : "false",
+ context.object->base_flag & BASE_FROM_DUPLI ? "\033[35;1mtrue\033[0m" :
+ "\033[30;1mfalse\033[0m");
}
AbstractHierarchyWriter *AbstractHierarchyIterator::get_writer(const std::string &name)
@@ -261,3 +233,33 @@ AbstractHierarchyWriter *AbstractHierarchyIterator::get_writer(const std::string
}
return it->second;
}
+
+AbstractHierarchyWriter *AbstractHierarchyIterator::ensure_xform_writer(
+ const HierarchyContext &context)
+{
+ AbstractHierarchyWriter *xform_writer = get_writer(context.export_path);
+ if (xform_writer != nullptr) {
+ return xform_writer;
+ }
+
+ xform_writer = create_xform_writer(context);
+ if (xform_writer != nullptr) {
+ writers[context.export_path] = xform_writer;
+ }
+ return xform_writer;
+}
+
+AbstractHierarchyWriter *AbstractHierarchyIterator::ensure_data_writer(
+ const HierarchyContext &context)
+{
+ AbstractHierarchyWriter *data_writer = get_writer(context.export_path);
+ if (data_writer != nullptr) {
+ return data_writer;
+ }
+
+ data_writer = create_data_writer(context);
+ if (data_writer != nullptr) {
+ writers[context.export_path] = data_writer;
+ }
+ return data_writer;
+}
diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.h b/source/blender/usd/intern/abstract_hierarchy_iterator.h
index aaf1ba84d8d..187d5a18083 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.h
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.h
@@ -43,7 +43,6 @@ class AbstractHierarchyIterator {
protected:
// Mapping from object to its children, as should be exported.
std::map<Object *, std::set<HierarchyContext>> export_graph;
- std::set<Object *> xform_onlies;
Depsgraph *depsgraph;
WriterMap writers;
@@ -57,26 +56,27 @@ class AbstractHierarchyIterator {
void release_writers();
private:
- void visit_object(Base *base, Object *object, Object *export_parent, bool xform_only);
+ void visit_object(Object *object, Object *export_parent, bool xform_only);
void make_writers(Object *parent_object,
const std::string &parent_path,
AbstractHierarchyWriter *parent_writer);
- std::string get_object_name(const Object *const object) const;
+ std::string get_object_name(const Object *object) const;
AbstractHierarchyWriter *get_writer(const std::string &name);
+ AbstractHierarchyWriter *ensure_xform_writer(const HierarchyContext &context);
+ AbstractHierarchyWriter *ensure_data_writer(const Hierarchy
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list