[Bf-blender-cvs] [820be7f6879] sybren-usd: USD: Export graph now is indexed by (export parent, duplicator)

Sybren A. Stüvel noreply at git.blender.org
Thu Jun 27 12:25:22 CEST 2019


Commit: 820be7f6879919acb6c607bb3ad063d93e635969
Author: Sybren A. Stüvel
Date:   Thu Jun 27 12:24:33 2019 +0200
Branches: sybren-usd
https://developer.blender.org/rB820be7f6879919acb6c607bb3ad063d93e635969

USD: Export graph now is indexed by (export parent, duplicator)

By including the duplicator into the export graph, each duplicated object
now has a unique entry in the graph. This solves a problem with the
transform matrices.

===================================================================

M	source/blender/usd/intern/abstract_hierarchy_iterator.cc
M	source/blender/usd/intern/abstract_hierarchy_iterator.h
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 11565b5fd41..dec7e78f38b 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
@@ -15,6 +15,12 @@ extern "C" {
 #include "DEG_depsgraph_query.h"
 }
 
+const HierarchyContext &HierarchyContext::root()
+{
+  static const HierarchyContext root_hierarchy_context = {.object = nullptr};
+  return root_hierarchy_context;
+}
+
 AbstractHierarchyIterator::AbstractHierarchyIterator(Depsgraph *depsgraph)
     : depsgraph(depsgraph), writers()
 {
@@ -83,14 +89,17 @@ void AbstractHierarchyIterator::iterate()
 
         // 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.
+        ExportGraph::key_type graph_index;
         if (link->ob->parent != nullptr && dupli_set.find(link->ob->parent) != dupli_set.end()) {
           export_parent = link->ob->parent;
+          graph_index = std::make_pair(export_parent, object);
         }
         else {
           export_parent = object;
+          graph_index = std::make_pair(export_parent, nullptr);
         }
 
-        visit_dupli_object(link, export_parent, false);
+        visit_dupli_object(link, graph_index, object, export_parent, false);
       }
     }
 
@@ -101,11 +110,32 @@ void AbstractHierarchyIterator::iterate()
   // // For debug: print the export graph.
   // printf("====== Export graph pre-prune:\n");
   // for (auto it : export_graph) {
-  //   printf("    OB %s:\n", it.first == nullptr ? "/" : (it.first->id.name + 2));
+  //   const std::pair<Object *, Object *> &parent_info = it.first;
+  //   Object *const export_parent = parent_info.first;
+  //   Object *const duplicator = parent_info.second;
+
+  //   if (duplicator != nullptr) {
+  //     printf("    DU %s (as dupped by %s):\n",
+  //            export_parent == nullptr ? "-null-" : (export_parent->id.name + 2),
+  //            duplicator->id.name + 2);
+  //   }
+  //   else {
+  //     printf("    OB %s:\n", export_parent == nullptr ? "-null-" : (export_parent->id.name +
+  //     2));
+  //   }
+
   //   for (auto child_it : it.second) {
-  //     printf("       - %s (weak_export=%s)\n",
-  //            child_it.object->id.name + 2,
-  //            child_it.weak_export ? "true" : "false");
+  //     if (child_it.duplicator == nullptr) {
+  //       printf("       - %s%s\n",
+  //              child_it.object->id.name + 2,
+  //              child_it.weak_export ? " (weak)" : "");
+  //     }
+  //     else {
+  //       printf("       - %s (dup by %s%s)\n",
+  //              child_it.object->id.name + 2,
+  //              child_it.duplicator->id.name + 2,
+  //              child_it.weak_export ? ", weak" : "");
+  //     }
   //   }
   // }
 
@@ -114,17 +144,38 @@ void AbstractHierarchyIterator::iterate()
   // // For debug: print the export graph.
   // printf("====== Export graph post-prune:\n");
   // for (auto it : export_graph) {
-  //   printf("    OB %s (%p):\n", it.first == nullptr ? "/" : (it.first->id.name + 2), it.first);
+  //   const std::pair<Object *, Object *> &parent_info = it.first;
+  //   Object *const export_parent = parent_info.first;
+  //   Object *const duplicator = parent_info.second;
+
+  //   if (duplicator != nullptr) {
+  //     printf("    DU %s (as dupped by %s):\n",
+  //            export_parent == nullptr ? "-null-" : (export_parent->id.name + 2),
+  //            duplicator->id.name + 2);
+  //   }
+  //   else {
+  //     printf("    OB %s:\n", export_parent == nullptr ? "-null-" : (export_parent->id.name +
+  //     2));
+  //   }
+
   //   for (auto child_it : it.second) {
-  //     printf("       - %s (weak_export=%s)\n",
-  //            child_it.object->id.name + 2,
-  //            child_it.weak_export ? "true" : "false");
+  //     if (child_it.duplicator == nullptr) {
+  //       printf("       - %s%s\n",
+  //              child_it.object->id.name + 2,
+  //              child_it.weak_export ? " (weak)" : "");
+  //     }
+  //     else {
+  //       printf("       - %s (dup by %s%s)\n",
+  //              child_it.object->id.name + 2,
+  //              child_it.duplicator->id.name + 2,
+  //              child_it.weak_export ? ", weak" : "");
+  //     }
   //   }
   // }
 
   // For debug: print the export paths.
   // printf("====== Export paths:\n");
-  make_writers(nullptr, "", nullptr);
+  make_writers(HierarchyContext::root(), nullptr);
 
   export_graph.clear();
 }
@@ -136,40 +187,46 @@ void AbstractHierarchyIterator::visit_object(Object *object,
   HierarchyContext context;
   context.object = object;
   context.export_parent = export_parent;
+  context.duplicator = nullptr;
   context.weak_export = weak_export;
   context.export_path = "";
   context.parent_writer = nullptr;
-  // TODO(Sybren): avoid creating too many copies of the matrix.
   copy_m4_m4(context.matrix_world, object->obmat);
 
-  export_graph[export_parent].insert(context);
+  export_graph[std::make_pair(export_parent, nullptr)].insert(context);
 
   // std::string export_parent_name = export_parent ? get_object_name(export_parent) : "/";
-  // printf("    OB %30s %p (parent=%s %p; xform-only=%s; instance=%s; world x = %f)\n",
-  //        get_object_name(object).c_str(),
-  //        object,
+  // printf("    OB %30s %p (export-parent=%s; world x = %f)\n",
+  //        get_object_name(context.object).c_str(),
+  //        context.object,
   //        export_parent_name.c_str(),
-  //        export_parent,
-  //        context.weak_export ? "\033[31;1mtrue\033[0m" : "false",
-  //        context.object->base_flag & BASE_FROM_DUPLI ? "\033[35;1mtrue\033[0m" :
-  //                                                      "\033[30;1mfalse\033[0m",
   //        context.matrix_world[3][0]);
 }
 
 void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
+                                                   const ExportGraph::key_type &graph_index,
+                                                   Object *duplicator,
                                                    Object *export_parent,
                                                    bool weak_export)
 {
   HierarchyContext context;
   context.object = dupli_object->ob;
   context.export_parent = export_parent;
+  context.duplicator = duplicator;
   context.weak_export = weak_export;
   context.export_path = "";
   context.parent_writer = nullptr;
-  // TODO(Sybren): avoid creating too many copies of the matrix.
   copy_m4_m4(context.matrix_world, dupli_object->mat);
 
-  export_graph[export_parent].insert(context);
+  export_graph[graph_index].insert(context);
+
+  // std::string export_parent_name = export_parent ? get_object_name(export_parent) : "/";
+  // printf("    DU %30s %p (export-parent=%s; duplicator = %s; world x = %f)\n",
+  //        get_object_name(context.object).c_str(),
+  //        context.object,
+  //        export_parent_name.c_str(),
+  //        duplicator->id.name + 2,
+  //        context.matrix_world[3][0]);
 }
 
 static bool prune_the_weak(const HierarchyContext &context,
@@ -177,8 +234,8 @@ static bool prune_the_weak(const HierarchyContext &context,
                            const AbstractHierarchyIterator::ExportGraph &iterate)
 {
   bool all_is_weak = context.weak_export;
-  AbstractHierarchyIterator::ExportGraph::const_iterator child_iterator = iterate.find(
-      context.object);
+  const auto map_index = std::make_pair(context.object, context.duplicator);
+  AbstractHierarchyIterator::ExportGraph::const_iterator child_iterator = iterate.find(map_index);
 
   if (child_iterator != iterate.end()) {
     for (const HierarchyContext &child_context : child_iterator->second) {
@@ -187,14 +244,14 @@ static bool prune_the_weak(const HierarchyContext &context,
 
       if (child_tree_is_weak) {
         // This subtree is all weak, so we can remove it from the current object's children.
-        modify[context.object].erase(child_context);
+        modify[map_index].erase(child_context);
       }
     }
   }
 
   if (all_is_weak) {
     // This node and all its children are weak, so it can be removed from the export graph.
-    modify.erase(context.object);
+    modify.erase(map_index);
   }
 
   return all_is_weak;
@@ -204,28 +261,36 @@ void AbstractHierarchyIterator::prune_export_graph()
 {
   // Take a copy of the map so that we can modify while recursing.
   ExportGraph unpruned_export_graph = export_graph;
-  const HierarchyContext root = {.object = nullptr};
-
-  prune_the_weak(root, export_graph, unpruned_export_graph);
+  prune_the_weak(HierarchyContext::root(), export_graph, unpruned_export_graph);
 }
 
-void AbstractHierarchyIterator::make_writers(Object *parent_object,
-                                             const std::string &parent_path,
+void AbstractHierarchyIterator::make_writers(const HierarchyContext &parent_context,
                                              AbstractHierarchyWriter *parent_writer)
 {
   AbstractHierarchyWriter *xform_writer = nullptr;
   AbstractHierarchyWriter *data_writer = nullptr;
+  float parent_matrix_inv_world[4][4];
+
+  if (parent_context.object == nullptr) {
+    unit_m4(parent_matrix_inv_world);
+  }
+  else {
+    invert_m4_m4(parent_matrix_inv_world, parent_context.matrix_world);
+  }
 
-  for (HierarchyContext context : export_graph[parent_object]) {
-    std::string export_path = path_concatenate(parent_path, get_object_name(context.object));
+  for (HierarchyContext context :
+       export_graph[std::make_pair(parent_context.object, parent_context.duplicator)]) {
+    std::string export_path = path_concatenate(parent_context.export_path,
+                                               get_object_name(context.object));
     context.parent_writer = parent_writer;
     context.export_path = export_path;
+    copy_m4_m4(context.parent_matrix_inv_world, parent_matrix_inv_world);
 
-    // const char *color = context.weak_export ? "31;1" : "30";
+    // const char *color = context.duplicator ? "32;1" : "30";
     // printf("%s \033[%sm%s\0

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list