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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/io/usd/intern/abstract_hierarchy_iterator.cc')
-rw-r--r--source/blender/io/usd/intern/abstract_hierarchy_iterator.cc109
1 files changed, 69 insertions, 40 deletions
diff --git a/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc
index 50f81c2ffb1..ab83ea2c3c4 100644
--- a/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc
@@ -21,11 +21,11 @@
#include <iostream>
#include <limits.h>
#include <sstream>
+#include <stdio.h>
#include <string>
-extern "C" {
-#include "BKE_anim.h"
-#include "BKE_animsys.h"
+#include "BKE_anim_data.h"
+#include "BKE_duplilist.h"
#include "BKE_key.h"
#include "BKE_particle.h"
@@ -40,7 +40,6 @@ extern "C" {
#include "DNA_particle_types.h"
#include "DEG_depsgraph_query.h"
-}
namespace USD {
@@ -54,7 +53,7 @@ bool HierarchyContext::operator<(const HierarchyContext &other) const
if (object != other.object) {
return object < other.object;
}
- if (duplicator != NULL && duplicator == other.duplicator) {
+ if (duplicator != nullptr && duplicator == other.duplicator) {
// Only resort to string comparisons when both objects are created by the same duplicator.
return export_name < other.export_name;
}
@@ -259,24 +258,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 <nullptr, nullptr> 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,41 +343,42 @@ void AbstractHierarchyIterator::visit_object(Object *object,
context->original_export_path = "";
copy_m4_m4(context->matrix_world, object->obmat);
- export_graph_[std::make_pair(export_parent, nullptr)].insert(context);
+ ExportGraph::key_type graph_index = determine_graph_index_object(context);
+ context_update_for_graph_index(context, graph_index);
+
+ // Store this HierarchyContext as child of the export parent.
+ export_graph_[graph_index].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();
+ }
+}
+
+AbstractHierarchyIterator::ExportGraph::key_type AbstractHierarchyIterator::
+ determine_graph_index_object(const HierarchyContext *context)
+{
+ return std::make_pair(context->export_parent, nullptr);
}
void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
Object *duplicator,
const std::set<Object *> &dupli_set)
{
- ExportGraph::key_type graph_index;
- bool animation_check_include_parent = false;
-
HierarchyContext *context = new HierarchyContext();
context->object = dupli_object->ob;
context->duplicator = duplicator;
context->weak_export = false;
context->export_path = "";
context->original_export_path = "";
+ context->export_path = "";
+ context->animation_check_include_parent = false;
- /* If the dupli-object's parent is also instanced by this object, use that as the
- * export parent. Otherwise use the dupli-parent as export parent. */
- Object *parent = dupli_object->ob->parent;
- if (parent != nullptr && dupli_set.find(parent) != dupli_set.end()) {
- // The parent object is part of the duplicated collection.
- context->export_parent = parent;
- graph_index = std::make_pair(parent, duplicator);
- }
- else {
- /* The parent object is NOT part of the duplicated collection. This means that the world
- * transform of this dupli-object can be influenced by objects that are not part of its
- * export graph. */
- animation_check_include_parent = true;
- context->export_parent = duplicator;
- graph_index = std::make_pair(duplicator, nullptr);
- }
-
- context->animation_check_include_parent = animation_check_include_parent;
copy_m4_m4(context->matrix_world, dupli_object->mat);
// Construct export name for the dupli-instance.
@@ -391,9 +389,39 @@ void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
}
context->export_name = make_valid_name(get_object_name(context->object) + suffix_stream.str());
+ ExportGraph::key_type graph_index = determine_graph_index_dupli(context, dupli_set);
+ context_update_for_graph_index(context, graph_index);
export_graph_[graph_index].insert(context);
}
+AbstractHierarchyIterator::ExportGraph::key_type AbstractHierarchyIterator::
+ determine_graph_index_dupli(const HierarchyContext *context,
+ const std::set<Object *> &dupli_set)
+{
+ /* If the dupli-object's parent is also instanced by this object, use that as the
+ * export parent. Otherwise use the dupli-parent as export parent. */
+
+ Object *parent = context->object->parent;
+ if (parent != nullptr && dupli_set.find(parent) != dupli_set.end()) {
+ // The parent object is part of the duplicated collection.
+ return std::make_pair(parent, context->duplicator);
+ }
+ return std::make_pair(context->duplicator, nullptr);
+}
+
+void AbstractHierarchyIterator::context_update_for_graph_index(
+ HierarchyContext *context, const ExportGraph::key_type &graph_index) const
+{
+ // Update the HierarchyContext so that it is consistent with the graph index.
+ context->export_parent = graph_index.first;
+ if (context->export_parent != context->object->parent) {
+ /* The parent object in Blender is NOT used as the export parent. This means
+ * that the world transform of this object can be influenced by objects that
+ * are not part of its export graph. */
+ context->animation_check_include_parent = true;
+ }
+}
+
AbstractHierarchyIterator::ExportChildren &AbstractHierarchyIterator::graph_children(
const HierarchyContext *context)
{
@@ -418,8 +446,7 @@ void AbstractHierarchyIterator::determine_export_paths(const HierarchyContext *p
duplisource_export_path_[source_ob] = context->export_path;
if (context->object->data != nullptr) {
- ID *object_data = static_cast<ID *>(context->object->data);
- ID *source_data = object_data;
+ ID *source_data = static_cast<ID *>(context->object->data);
duplisource_export_path_[source_data] = get_object_data_path(context);
}
}
@@ -478,6 +505,7 @@ void AbstractHierarchyIterator::make_writers(const HierarchyContext *parent_cont
}
for (HierarchyContext *context : graph_children(parent_context)) {
+ // Update the context so that it is correct for this parent-child relation.
copy_m4_m4(context->parent_matrix_inv_world, parent_matrix_inv_world);
// Get or create the transform writer.
@@ -546,7 +574,7 @@ void AbstractHierarchyIterator::make_writers_particle_systems(
HierarchyContext hair_context = *transform_context;
hair_context.export_path = path_concatenate(transform_context->export_path,
- get_id_name(&psys->part->id));
+ make_valid_name(psys->name));
hair_context.particle_system = psys;
AbstractHierarchyWriter *writer = nullptr;
@@ -576,9 +604,10 @@ std::string AbstractHierarchyIterator::get_object_data_name(const Object *object
return get_id_name(object_data);
}
-AbstractHierarchyWriter *AbstractHierarchyIterator::get_writer(const std::string &export_path)
+AbstractHierarchyWriter *AbstractHierarchyIterator::get_writer(
+ const std::string &export_path) const
{
- WriterMap::iterator it = writers_.find(export_path);
+ WriterMap::const_iterator it = writers_.find(export_path);
if (it == writers_.end()) {
return nullptr;