diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-01-09 17:42:06 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-01-09 17:47:05 +0300 |
commit | 9f5f91d6bd934b70174a9ddb4ea47503d87d4b14 (patch) | |
tree | 2a86ebc0c8025136c623610362e7d3d17d1668f7 /source | |
parent | cf0f066c2d62234cb0ed228c25a496c2ecab142e (diff) |
USD Exporter: properly export objects whose parents are not exported
The exporter constructs an export hierarchy, and then traverses that
hierarchy from the root to the children. When an object is to be exported,
but its parent is not, it meant that this traversal from (great)parent to
children would skip these objects. This commit fixes that by inserting the
missing parents as 'transform only' into the hierarchy.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/usd/intern/abstract_hierarchy_iterator.cc | 43 | ||||
-rw-r--r-- | source/blender/usd/intern/abstract_hierarchy_iterator.h | 1 |
2 files changed, 44 insertions, 0 deletions
diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/usd/intern/abstract_hierarchy_iterator.cc index 957db1a25ef..fae41c1bbd0 100644 --- a/source/blender/usd/intern/abstract_hierarchy_iterator.cc +++ b/source/blender/usd/intern/abstract_hierarchy_iterator.cc @@ -88,6 +88,7 @@ AbstractHierarchyIterator::~AbstractHierarchyIterator() void AbstractHierarchyIterator::iterate_and_write() { export_graph_construct(); + connect_loose_objects(); export_graph_prune(); determine_export_paths(HierarchyContext::root()); determine_duplication_references(HierarchyContext::root(), ""); @@ -210,6 +211,48 @@ void AbstractHierarchyIterator::export_graph_construct() DEG_OBJECT_ITER_END; } +void AbstractHierarchyIterator::connect_loose_objects() +{ + // Find those objects whose parent is not part of the export graph; these + // objects would be skipped when traversing the graph as a hierarchy. + // These objects will have to be re-attached to some parent object in order to + // fit into the hierarchy. + ExportGraph loose_objects_graph = export_graph_; + for (const ExportGraph::value_type &map_iter : export_graph_) { + for (const HierarchyContext *child : map_iter.second) { + // An object that is marked as a child of another object is not considered 'loose'. + loose_objects_graph.erase(std::make_pair(child->object, child->duplicator)); + } + } + // The root of the hierarchy is always found, so it's never considered 'loose'. + loose_objects_graph.erase(std::make_pair(nullptr, nullptr)); + + // Iterate over the loose objects and connect them to their export parent. + for (const ExportGraph::value_type &map_iter : loose_objects_graph) { + const DupliAndDuplicator &export_info = map_iter.first; + Object *object = export_info.first; + Object *export_parent = object->parent; + + while (true) { + // Loose objects will all be real objects, as duplicated objects always have + // their duplicator or other exported duplicated object as ancestor. + ExportGraph::iterator found_parent_iter = export_graph_.find( + std::make_pair(export_parent, nullptr)); + + visit_object(object, export_parent, true); + if (found_parent_iter != export_graph_.end()) { + break; + } + // 'export_parent' will never be nullptr here, as the export graph contains the + // tuple <nullptr, nullptr> as root and thus will cause a break. + BLI_assert(export_parent != nullptr); + + object = export_parent; + export_parent = export_parent->parent; + } + } +} + static bool remove_weak_subtrees(const HierarchyContext *context, AbstractHierarchyIterator::ExportGraph &clean_graph, const AbstractHierarchyIterator::ExportGraph &input_graph) diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.h b/source/blender/usd/intern/abstract_hierarchy_iterator.h index ea31e94cf9b..10408401797 100644 --- a/source/blender/usd/intern/abstract_hierarchy_iterator.h +++ b/source/blender/usd/intern/abstract_hierarchy_iterator.h @@ -174,6 +174,7 @@ class AbstractHierarchyIterator { void debug_print_export_graph() const; void export_graph_construct(); + void connect_loose_objects(); void export_graph_prune(); void export_graph_clear(); |