[Bf-blender-cvs] [1294eb47b30] sybren-usd: USD: Better detection of whether transforms are animated

Sybren A. Stüvel noreply at git.blender.org
Thu Jun 27 17:10:49 CEST 2019


Commit: 1294eb47b30555ef83f833f39cef3cf521e3541c
Author: Sybren A. Stüvel
Date:   Thu Jun 27 13:45:46 2019 +0200
Branches: sybren-usd
https://developer.blender.org/rB1294eb47b30555ef83f833f39cef3cf521e3541c

USD: Better detection of whether transforms are animated

When an object in a duplicated collection has a parent that's not in that
collection, it needs to check its entire parent chain for animatedness
(because those parents aren't going to be in the USD hierarchy for that
duplicated object).

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

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_abstract.cc
M	source/blender/usd/intern/usd_writer_abstract.h
M	source/blender/usd/intern/usd_writer_transform.cc
M	source/blender/usd/intern/usd_writer_transform.h

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

diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
index dec7e78f38b..65647e93abe 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
@@ -45,67 +45,7 @@ void AbstractHierarchyIterator::release_writers()
 
 void AbstractHierarchyIterator::iterate()
 {
-  Scene *scene = DEG_get_evaluated_scene(depsgraph);
-
-  // printf("====== Visiting objects:\n");
-  DEG_OBJECT_ITER_BEGIN (depsgraph,
-                         object,
-                         DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
-                             DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) {
-    if (object->base_flag & BASE_HOLDOUT) {
-      visit_object(object, object->parent, true);
-      continue;
-    }
-
-    // Non-instanced objects always have their object-parent as export-parent.
-    bool weak_export = !should_export_object(object);
-    visit_object(object, object->parent, weak_export);
-
-    if (weak_export) {
-      // If a duplicator shouldn't be exported, its duplilist also shouldn't be.
-      continue;
-    }
-
-    // Export the duplicated objects instanced by this object.
-    ListBase *lb = object_duplilist(depsgraph, scene, object);
-    if (lb) {
-      DupliObject *link = nullptr;
-
-      // Construct the set of duplicated objects, so that later we can determine whether a parent
-      // is also duplicated itself.
-      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.
-        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, graph_index, object, export_parent, false);
-      }
-    }
-
-    free_object_duplilist(lb);
-  }
-  DEG_OBJECT_ITER_END;
+  construct_export_graph();
 
   // // For debug: print the export graph.
   // printf("====== Export graph pre-prune:\n");
@@ -180,6 +120,58 @@ void AbstractHierarchyIterator::iterate()
   export_graph.clear();
 }
 
+void AbstractHierarchyIterator::construct_export_graph()
+{
+  Scene *scene = DEG_get_evaluated_scene(depsgraph);
+
+  // printf("====== Visiting objects:\n");
+  DEG_OBJECT_ITER_BEGIN (depsgraph,
+                         object,
+                         DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+                             DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) {
+    if (object->base_flag & BASE_HOLDOUT) {
+      visit_object(object, object->parent, true);
+      continue;
+    }
+
+    // Non-instanced objects always have their object-parent as export-parent.
+    bool weak_export = !should_export_object(object);
+    visit_object(object, object->parent, weak_export);
+
+    if (weak_export) {
+      // If a duplicator shouldn't be exported, its duplilist also shouldn't be.
+      continue;
+    }
+
+    // Export the duplicated objects instanced by this object.
+    ListBase *lb = object_duplilist(depsgraph, scene, object);
+    if (lb) {
+      DupliObject *link = nullptr;
+
+      // Construct the set of duplicated objects, so that later we can determine whether a parent
+      // is also duplicated itself.
+      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);
+      }
+
+      for (link = static_cast<DupliObject *>(lb->first); link; link = link->next) {
+        if (!should_visit_duplilink(link)) {
+          continue;
+        }
+
+        visit_dupli_object(link, object, dupli_set);
+      }
+    }
+
+    free_object_duplilist(lb);
+  }
+  DEG_OBJECT_ITER_END;
+}
+
 void AbstractHierarchyIterator::visit_object(Object *object,
                                              Object *export_parent,
                                              bool weak_export)
@@ -189,6 +181,7 @@ void AbstractHierarchyIterator::visit_object(Object *object,
   context.export_parent = export_parent;
   context.duplicator = nullptr;
   context.weak_export = weak_export;
+  context.animation_check_include_parent = false;
   context.export_path = "";
   context.parent_writer = nullptr;
   copy_m4_m4(context.matrix_world, object->obmat);
@@ -204,18 +197,37 @@ void AbstractHierarchyIterator::visit_object(Object *object,
 }
 
 void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
-                                                   const ExportGraph::key_type &graph_index,
                                                    Object *duplicator,
-                                                   Object *export_parent,
-                                                   bool weak_export)
+                                                   const std::set<Object *> &dupli_set)
 {
+  ExportGraph::key_type graph_index;
+  bool animation_check_include_parent = false;
+
   HierarchyContext context;
   context.object = dupli_object->ob;
-  context.export_parent = export_parent;
   context.duplicator = duplicator;
-  context.weak_export = weak_export;
+  context.weak_export = false;
   context.export_path = "";
   context.parent_writer = nullptr;
+
+  /* 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. */
+  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 dupliobject 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);
 
   export_graph[graph_index].insert(context);
diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.h b/source/blender/usd/intern/abstract_hierarchy_iterator.h
index cc09b1628ac..4d39778b0bd 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.h
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.h
@@ -21,10 +21,14 @@ struct HierarchyContext {
   Object *duplicator;
   float matrix_world[4][4];
 
-  // When true, the object will be exported only as transform, and only if is an ancestor of a
-  // non-weak child:
+  /* When true, the object will be exported only as transform, and only if is an ancestor of a
+   * non-weak child: */
   bool weak_export;
 
+  /* When true, this object should check its parents for animation data when determining whether
+   * it's animated. */
+  bool animation_check_include_parent;
+
   /* Determined during writer creation: */
   float parent_matrix_inv_world[4][4]; /* Inverse of the parent's world matrix. */
   std::string export_path;  // Hierarchical path, such as "/grandparent/parent/objectname".
@@ -50,7 +54,7 @@ class AbstractHierarchyWriter {
 class AbstractHierarchyIterator {
  public:
   typedef std::map<std::string, AbstractHierarchyWriter *> WriterMap;
-  // Mapping from <object, duplicator> to its export-children.
+  // Mapping from <object, duplicator> to the object's export-children.
   typedef std::map<std::pair<Object *, Object *>, std::set<HierarchyContext>> ExportGraph;
 
  protected:
@@ -67,12 +71,11 @@ class AbstractHierarchyIterator {
   void release_writers();
 
  private:
+  void construct_export_graph();
   void visit_object(Object *object, Object *export_parent, bool weak_export);
   void visit_dupli_object(DupliObject *dupli_object,
-                          const ExportGraph::key_type &graph_index,
                           Object *duplicator,
-                          Object *export_parent,
-                          bool weak_export);
+                          const std::set<Object *> &dupli_set);
   void prune_export_graph();
 
   void make_writers(const HierarchyContext &parent_context,
diff --git a/source/blender/usd/intern/usd_writer_abstract.cc b/source/blender/usd/intern/usd_writer_abstract.cc
index 4d5b20d07fb..59e3a34d6ef 100644
--- a/source/blender/usd/intern/usd_writer_abstract.cc
+++ b/source/blender/usd/intern/usd_writer_abstract.cc
@@ -49,7 +49,7 @@ void USDAbstractWriter::write(HierarchyContext &context)
     }
   }
   else {
-    is_animated_ = export_params.do_animation && check_is_animated(context.object);
+    is_animated_ = export_params.do_animation && check_is_animated(context);
     // printf("%sANIMATION\033[0m: %20s: %s\n",
     //        is_animated_ ? "\033[32;1m" : "\033[31;1m",
     //        context.export_path.c_str(),
@@ -61,8 +61,10 @@ void USDAbstractWriter::write(HierarchyContext &context)
   frame_has_been_written_ = true;
 }
 
-bool USDAbstractWriter::check_is_animated(Object *object) const
+bool USDAbstractWriter::check_is_animated(const HierarchyContext &context) const
 {
+  const Object *object = context.object;
+
   if (object->data != nullptr) {
     AnimData *adt = BKE_animdata_from_id(static_cast<ID *>(object->data));
     /* TODO(Sybren): make 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list