Commit: ee392718633525a0b884f28cc6456fec43b4c543 Author: Sybren A. Stüvel Date: Tue Jun 18 14:31:12 2019 +0200 Branches: sybren-usd-experiments https://developer.blender.org/rBee392718633525a0b884f28cc6456fec43b4c543
Working on a smarter way to construct the USD object hierarchy This includes delayed writing to USD, which breaks things for now. =================================================================== M source/blender/usd/intern/abstract_hierarchy_iterator.cc M source/blender/usd/intern/abstract_hierarchy_iterator.h M source/blender/usd/intern/usd_exporter.cc M source/blender/usd/intern/usd_exporter_context.h M source/blender/usd/intern/usd_hierarchy_iterator.cc M source/blender/usd/intern/usd_writer_abstract.cc M source/blender/usd/intern/usd_writer_abstract.h M source/blender/usd/intern/usd_writer_mesh.cc M source/blender/usd/intern/usd_writer_transform.cc =================================================================== diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/usd/intern/abstract_hierarchy_iterator.cc index b108f38accc..4f2c1f7246b 100644 --- a/source/blender/usd/intern/abstract_hierarchy_iterator.cc +++ b/source/blender/usd/intern/abstract_hierarchy_iterator.cc @@ -23,6 +23,11 @@ AbstractHierarchyIterator::~AbstractHierarchyIterator() { } +const AbstractHierarchyIterator::WriterMap &AbstractHierarchyIterator::writer_map() const +{ + return writers; +} + void AbstractHierarchyIterator::release_writers() { for (WriterMap::value_type it : writers) { @@ -34,9 +39,85 @@ void AbstractHierarchyIterator::release_writers() void AbstractHierarchyIterator::iterate() { ViewLayer *view_layer = DEG_get_input_view_layer(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) { - Object *ob = base->object; - visit_object(base, ob, ob->parent, nullptr); + if (base->flag & BASE_HOLDOUT) { + continue; + } + + // Non-instanced objects always have their object-parent as export-parent. + visit_object(base, base->object, base->object->parent, false); + + // Object *evaluated_ob = DEG_get_evaluated_object(depsgraph, object); + // export_object_and_parents(ob, parent, dupliObParent); + + ListBase *lb = object_duplilist(depsgraph, scene, base->object); + if (lb) { + DupliObject *link = nullptr; + + std::set<Object *> dupli_set; + for (link = static_cast<DupliObject *>(lb->first); link; link = link->next) { + if (!should_visit_duplilink(link)) { + continue; + } + dupli_set.insert(link->ob); + } + + Object *export_parent = nullptr; + for (link = static_cast<DupliObject *>(lb->first); link; link = link->next) { + if (!should_visit_duplilink(link)) { + continue; + } + // If the dupli-object's scene parent is also instanced by this object, use that as the + // export parent. Otherwise use the dupli-parent as export parent. + if (link->ob->parent != nullptr && dupli_set.find(link->ob->parent) != dupli_set.end()) { + export_parent = link->ob->parent; + } + else { + export_parent = base->object; + } + visit_object(base, link->ob, export_parent, false); + } + } + + free_object_duplilist(lb); + } + + 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); + } + + printf("====== Export graph:\n"); + for (auto it : export_graph) { + printf(" OB %s:\n", it.first == nullptr ? "/" : (it.first->id.name + 2)); + for (auto child_it : it.second) { + printf(" - %s (xform_only=%s)\n", + child_it.object->id.name + 2, + child_it.xform_only ? "true" : "false"); + } + } + + printf("====== Export paths:\n"); + make_paths(nullptr, ""); +} + +void AbstractHierarchyIterator::make_paths(Object *for_object, const std::string &at_path) +{ + for (auto it : export_graph[for_object]) { + std::string usd_path = at_path + "/" + get_object_name(it.object); + + const char *colour = it.xform_only ? "31;1" : "30"; + printf("%s \033[%sm%s\033[0m\n", usd_path.c_str(), colour, it.xform_only ? "true" : "false"); + + make_paths(it.object, usd_path); } } @@ -98,37 +179,56 @@ bool AbstractHierarchyIterator::should_visit_duplilink(const DupliObject *const void AbstractHierarchyIterator::visit_object(Base *base, Object *object, - Object *parent, - Object *dupliObParent) + 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, dupliObParent != nullptr)) { + if (!should_visit_object(base, false)) { return; } - Object *ob = DEG_get_evaluated_object(depsgraph, object); - export_object_and_parents(ob, parent, dupliObParent); - - ListBase *lb = object_duplilist(depsgraph, DEG_get_input_scene(depsgraph), ob); - - if (lb) { - DupliObject *link = static_cast<DupliObject *>(lb->first); - Object *dupli_ob = nullptr; - Object *dupli_parent = nullptr; - - for (; link; link = link->next) { - if (!should_visit_duplilink(link)) { - continue; - } - - dupli_ob = link->ob; - dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob; - visit_object(base, dupli_ob, dupli_parent, ob); - } - - free_object_duplilist(lb); + BLI_assert(DEG_is_original_object(export_parent)); + if (export_parent != NULL && export_graph.find(export_parent) == export_graph.end()) { + // If the export-parent is not an exportable object, it should be exported as XForm-only. + xform_onlies.insert(export_parent); } + xform_onlies.erase(object); + + ExportInfo export_info = { + .object = object, + .xform_only = xform_only || object->type == OB_EMPTY, + }; + export_graph[export_parent].insert(export_info); + + std::string export_parent_name = export_parent ? get_object_name(export_parent) : "/"; + printf(" OB %20s (parent=%s; xform-only=%s)\n", + get_object_name(object).c_str(), + export_parent_name.c_str(), + export_info.xform_only ? "true" : "false"); + + // Object *evaluated_ob = DEG_get_evaluated_object(depsgraph, object); + // export_object_and_parents(ob, parent, dupliObParent); + + // ListBase *lb = object_duplilist(depsgraph, DEG_get_input_scene(depsgraph), ob); + + // if (lb) { + // DupliObject *link = static_cast<DupliObject *>(lb->first); + // Object *dupli_ob = nullptr; + // Object *dupli_parent = nullptr; + + // for (; link; link = link->next) { + // if (!should_visit_duplilink(link)) { + // continue; + // } + + // dupli_ob = link->ob; + // dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob; + // visit_object(base, dupli_ob, dupli_parent, ob); + // } + + // free_object_duplilist(lb); + // } } TEMP_WRITER_TYPE *AbstractHierarchyIterator::export_object_and_parents(Object *ob, diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.h b/source/blender/usd/intern/abstract_hierarchy_iterator.h index d4ff4491903..bc35356a0a1 100644 --- a/source/blender/usd/intern/abstract_hierarchy_iterator.h +++ b/source/blender/usd/intern/abstract_hierarchy_iterator.h @@ -3,6 +3,7 @@ #include <map> #include <string> +#include <set> struct Base; struct Depsgraph; @@ -13,10 +14,24 @@ struct ViewLayer; typedef void TEMP_WRITER_TYPE; +struct ExportInfo { + Object *object; + bool xform_only; + + bool operator<(const ExportInfo &other) const + { + return object < other.object; + } +}; + class AbstractHierarchyIterator { public: typedef std::map<std::string, TEMP_WRITER_TYPE *> WriterMap; + // Mapping from object to its children, as should be exported. + std::map<Object *, std::set<ExportInfo>> export_graph; + std::set<Object *> xform_onlies; + protected: Depsgraph *depsgraph; WriterMap writers; @@ -30,7 +45,8 @@ class AbstractHierarchyIterator { void release_writers(); private: - void visit_object(Base *base, Object *object, Object *parent, Object *dupliObParent); + void visit_object(Base *base, Object *object, Object *export_parent, bool xform_only); + void make_paths(Object *for_object, const std::string &at_path); std::string get_object_name(const Object *const object) const; std::string get_object_dag_path_name(const Object *const ob, diff --git a/source/blender/usd/intern/usd_exporter.cc b/source/blender/usd/intern/usd_exporter.cc index 2908f5a892b..f12b07b7c91 100644 --- a/source/blender/usd/intern/usd_exporter.cc +++ b/source/blender/usd/intern/usd_exporter.cc @@ -60,6 +60,13 @@ void USDExporter::operator()(float &r_progress, bool &r_was_canceled) USDHierarchyIterator iter(m_settings.depsgraph, m_stage); iter.iterate(); - m_stage->GetRootLayer()->Save(); + // for (AbstractHierarchyIterator::WriterMap::value_type it : iter.writer_map()) { + // USDAbstractWriter *writer = static_cast<USDAbstractWriter *>(it.second); + // printf(" ==> %s\n", it.first.c_str()); + // writer->write(); + // } + // iter.release_writers(); + + // m_stage->GetRootLayer()->Save(); r_progress = 1.0; } diff --git a/source/blender/usd/intern/usd_exporter_context.h b/source/blender/usd/intern/usd_exporter_context.h index 9c738cd8433..b8b0a746028 100644 --- a/source/blender/usd/intern/usd_exporter_context.h +++ b/source/blender/usd/intern/usd_exporter_context.h @@ -4,9 +4,11 @@ #include <pxr/usd/sdf/path.h> #include <pxr/usd/usd/common.h> +struct Depsgraph; struct Object; struct USDExporterContext { + Depsgraph *depsgraph; pxr::UsdStageRefPtr stage; pxr::SdfPath usd_path; Object *ob_eval; diff --git a/source/blender/usd/intern/usd_hierarchy_iterator.cc b/source/blender/usd/intern/usd_hierarchy_iterator.cc index 5c64f42f939..d8a0a9c35f2 100644 --- a/source/blender/usd/intern/usd_hierarchy_iterator.cc +++ b/source/blender/usd/intern/usd_hierarchy_iterator.cc @@ -44,10 +44,8 @@ TEMP_WRITER_TYPE *USDHierarchyIterator::create_xform_writer(const std::string &n printf("\033[32;1mCREATE\033[0m %s at %s\n", object->id.name, name.c_str()); pxr::SdfPath usd_path("/" + name); - USDExporterContext ctx = {stage, usd_path, object, NULL}; - USDAbstractWriter *xform_writer = new USDTransformWriter(ctx); - xform_writer->write(); - return xform_writer; + USDExporterContext ctx = {depsgraph, stage, usd_path, object, nullptr}; + return new USDTransformWriter(ctx); } TEMP_WRITER_TYPE *USDHierarchyIterator::create_data_writer(const std::string &name, @@ -57,8 +55,9 @@ TEMP_WRITER_TYPE *USDHierarchyIterator::c @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs