From a8bd385a5dcabbc55f69d885e64ccf6dc386a2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 9 Apr 2020 12:18:45 +0200 Subject: Fix T75491: ctest: usd_test fails in a debug configuration There was a bug in the `connect_loose_objects()` function, which caused some objects to be exported twice (once for real, and once transform-only). This is now resolved. --- .../io/usd/intern/abstract_hierarchy_iterator.cc | 26 +++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'source/blender/io') diff --git a/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc index 71cab020e57..d837d3d8dd3 100644 --- a/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc +++ b/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include extern "C" { @@ -259,24 +260,22 @@ void AbstractHierarchyIterator::connect_loose_objects() 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); + ExportGraph::iterator found_parent_iter = export_graph_.find( + std::make_pair(object->parent, nullptr)); + visit_object(object, object->parent, true); if (found_parent_iter != export_graph_.end()) { break; } - // 'export_parent' will never be nullptr here, as the export graph contains the + // 'object->parent' will never be nullptr here, as the export graph contains the // tuple as root and thus will cause a break. - BLI_assert(export_parent != nullptr); + BLI_assert(object->parent != nullptr); - object = export_parent; - export_parent = export_parent->parent; + object = object->parent; } } } @@ -346,7 +345,18 @@ void AbstractHierarchyIterator::visit_object(Object *object, context->original_export_path = ""; copy_m4_m4(context->matrix_world, object->obmat); + // Store this HierarchyContext as child of the export parent. export_graph_[std::make_pair(export_parent, nullptr)].insert(context); + + // Create an empty entry for this object to indicate it is part of the export. This will be used + // by connect_loose_objects(). Having such an "indicator" will make it possible to do an O(log n) + // check on whether an object is part of the export, rather than having to check all objects in + // the map. Note that it's not possible to simply search for (object->parent, nullptr), as the + // object's parent in Blender may not be the same as its export-parent. + ExportGraph::key_type object_key = std::make_pair(object, nullptr); + if (export_graph_.find(object_key) == export_graph_.end()) { + export_graph_[object_key] = ExportChildren(); + } } void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object, -- cgit v1.2.3