[Bf-blender-cvs] [e441de0792f] sybren-usd: USD: replaced 'xform_only' with 'weak_export'

Sybren A. Stüvel noreply at git.blender.org
Fri Jun 21 16:40:20 CEST 2019


Commit: e441de0792f1ae933a8a4d6ef2a58ed9fa296a6a
Author: Sybren A. Stüvel
Date:   Fri Jun 21 16:38:03 2019 +0200
Branches: sybren-usd
https://developer.blender.org/rBe441de0792f1ae933a8a4d6ef2a58ed9fa296a6a

USD: replaced 'xform_only' with 'weak_export'

An object marked as `weak_export` will only be exported if it has any non-
weak children. When it is exported, it is only written as transform, and
not as full object (so no object data).

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

M	source/blender/usd/intern/abstract_hierarchy_iterator.cc
M	source/blender/usd/intern/abstract_hierarchy_iterator.h
M	source/blender/usd/intern/usd_hierarchy_iterator.cc
M	source/blender/usd/intern/usd_hierarchy_iterator.h

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

diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
index c51aa377e80..bb49da9958d 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
@@ -49,12 +49,15 @@ void AbstractHierarchyIterator::iterate()
       visit_object(object, object->parent, true);
       continue;
     }
-    if (!should_visit_object(object)) {
-      continue;
-    }
 
     // Non-instanced objects always have their object-parent as export-parent.
-    visit_object(object, object->parent, false);
+    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);
@@ -95,13 +98,26 @@ void AbstractHierarchyIterator::iterate()
   DEG_OBJECT_ITER_END;
 
   // For debug: print the export graph.
-  printf("====== Export graph:\n");
+  printf("====== Export graph pre-prune:\n");
   for (auto it : export_graph) {
     printf("    OB %s:\n", it.first == nullptr ? "/" : (it.first->id.name + 2));
     for (auto child_it : it.second) {
-      printf("       - %s (xform_only=%s)\n",
+      printf("       - %s (weak_export=%s)\n",
              child_it.object->id.name + 2,
-             child_it.xform_only ? "true" : "false");
+             child_it.weak_export ? "true" : "false");
+    }
+  }
+
+  prune_export_graph();
+
+  // 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);
+    for (auto child_it : it.second) {
+      printf("       - %s (weak_export=%s)\n",
+             child_it.object->id.name + 2,
+             child_it.weak_export ? "true" : "false");
     }
   }
 
@@ -110,6 +126,43 @@ void AbstractHierarchyIterator::iterate()
   make_writers(nullptr, "", nullptr);
 }
 
+static bool prune_the_weak(const HierarchyContext &context,
+                           AbstractHierarchyIterator::ExportGraph &modify,
+                           const AbstractHierarchyIterator::ExportGraph &iterate)
+{
+  bool all_is_weak = context.weak_export;
+  AbstractHierarchyIterator::ExportGraph::const_iterator child_iterator = iterate.find(
+      context.object);
+
+  if (child_iterator != iterate.end()) {
+    for (const HierarchyContext &child_context : child_iterator->second) {
+      bool child_tree_is_weak = prune_the_weak(child_context, modify, iterate);
+      all_is_weak &= child_tree_is_weak;
+
+      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);
+      }
+    }
+  }
+
+  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);
+  }
+
+  return all_is_weak;
+}
+
+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);
+}
+
 void AbstractHierarchyIterator::make_writers(Object *parent_object,
                                              const std::string &parent_path,
                                              AbstractHierarchyWriter *parent_writer)
@@ -122,11 +175,11 @@ void AbstractHierarchyIterator::make_writers(Object *parent_object,
     context.parent_writer = parent_writer;
     context.export_path = export_path;
 
-    const char *color = context.xform_only ? "31;1" : "30";
+    const char *color = context.weak_export ? "31;1" : "30";
     printf("%s \033[%sm%s\033[0m\n",
            export_path.c_str(),
            color,
-           context.xform_only ? "true" : "false");
+           context.weak_export ? "true" : "false");
 
     // Get or create the transform writer.
     xform_writer = ensure_xform_writer(context);
@@ -140,7 +193,7 @@ void AbstractHierarchyIterator::make_writers(Object *parent_object,
     xform_writer->write(context.object);
 
     // Get or create the object data writer, but only if it is needed.
-    if (!context.xform_only && context.object->data != nullptr) {
+    if (!context.weak_export && context.object->data != nullptr) {
       ID *object_data = static_cast<ID *>(context.object->data);
       std::string data_path = path_concatenate(export_path, get_id_name(object_data));
 
@@ -184,20 +237,19 @@ std::string AbstractHierarchyIterator::path_concatenate(const std::string &paren
   return parent_path + "/" + child_path;
 }
 
-bool AbstractHierarchyIterator::should_visit_object(const Object * /*object*/) const
-{
-  return true;
-}
-
 bool AbstractHierarchyIterator::should_visit_duplilink(const DupliObject *link) const
 {
   // Removing link->no_draw hides things like custom bone shapes.
   return !link->no_draw;
 }
+bool AbstractHierarchyIterator::should_export_object(const Object * /*object*/) const
+{
+  return true;
+}
 
 void AbstractHierarchyIterator::visit_object(Object *object,
                                              Object *export_parent,
-                                             bool xform_only)
+                                             bool weak_export)
 {
   BLI_assert(DEG_is_evaluated_object(object));
   BLI_assert(export_parent == nullptr || DEG_is_evaluated_object(export_parent));
@@ -205,7 +257,7 @@ void AbstractHierarchyIterator::visit_object(Object *object,
   HierarchyContext context = {
       .object = object,
       .export_parent = export_parent,
-      .xform_only = xform_only || object->type == OB_EMPTY,
+      .weak_export = weak_export,
 
       // Will be determined during the writer creation:
       .export_path = "",
@@ -219,7 +271,7 @@ void AbstractHierarchyIterator::visit_object(Object *object,
          object,
          export_parent_name.c_str(),
          export_parent,
-         context.xform_only ? "\033[31;1mtrue\033[0m" : "false",
+         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");
 }
diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.h b/source/blender/usd/intern/abstract_hierarchy_iterator.h
index 187d5a18083..c9cb5844845 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.h
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.h
@@ -23,7 +23,10 @@ struct HierarchyContext {
   /* Determined during hierarchy iteration: */
   Object *object;
   Object *export_parent;
-  bool xform_only;
+
+  // When true, the object will be exported only as transform, and only if is an ancestor of a
+  // non-weak child.
+  bool weak_export;
 
   /* Determined during writer creation: */
   std::string export_path;  // Hierarchical path, such as "/grandparent/parent/objectname".
@@ -39,10 +42,10 @@ struct HierarchyContext {
 class AbstractHierarchyIterator {
  public:
   typedef std::map<std::string, AbstractHierarchyWriter *> WriterMap;
+  typedef std::map<Object *, std::set<HierarchyContext>> ExportGraph;
 
  protected:
-  // Mapping from object to its children, as should be exported.
-  std::map<Object *, std::set<HierarchyContext>> export_graph;
+  ExportGraph export_graph;  // Mapping from object to its children, as should be exported.
 
   Depsgraph *depsgraph;
   WriterMap writers;
@@ -56,7 +59,9 @@ class AbstractHierarchyIterator {
   void release_writers();
 
  private:
-  void visit_object(Object *object, Object *export_parent, bool xform_only);
+  void visit_object(Object *object, Object *export_parent, bool weak_export);
+  void prune_export_graph();
+
   void make_writers(Object *parent_object,
                     const std::string &parent_path,
                     AbstractHierarchyWriter *parent_writer);
@@ -68,8 +73,8 @@ class AbstractHierarchyIterator {
   AbstractHierarchyWriter *ensure_data_writer(const HierarchyContext &context);
 
  protected:
-  virtual bool should_visit_object(const Object *object) const;
   virtual bool should_visit_duplilink(const DupliObject *link) const;
+  virtual bool should_export_object(const Object *object) const;
 
   virtual AbstractHierarchyWriter *create_xform_writer(const HierarchyContext &context) = 0;
   virtual AbstractHierarchyWriter *create_data_writer(const HierarchyContext &context) = 0;
diff --git a/source/blender/usd/intern/usd_hierarchy_iterator.cc b/source/blender/usd/intern/usd_hierarchy_iterator.cc
index 805265bb269..c27cd64d07d 100644
--- a/source/blender/usd/intern/usd_hierarchy_iterator.cc
+++ b/source/blender/usd/intern/usd_hierarchy_iterator.cc
@@ -27,7 +27,7 @@ USDHierarchyIterator::USDHierarchyIterator(Depsgraph *depsgraph,
 {
 }
 
-bool USDHierarchyIterator::should_visit_object(const Object *object) const
+bool USDHierarchyIterator::should_export_object(const Object *object) const
 {
   if (params.selected_objects_only && (object->base_flag & BASE_SELECTED) == 0) {
     return false;
@@ -35,8 +35,7 @@ bool USDHierarchyIterator::should_visit_object(const Object *object) const
   if (params.visible_objects_only && (object->base_flag & BASE_VISIBLE) == 0) {
     return false;
   }
-
-  return AbstractHierarchyIterator::should_visit_object(object);
+  return true;
 }
 
 void USDHierarchyIterator::delete_object_writer(AbstractHierarchyWriter *writer)
diff --git a/source/blender/usd/intern/usd_hierarchy_iterator.h b/source/blender/usd/intern/usd_hierarchy_iterator.h
index 7be659c6081..e2232166d11 100644
--- a/source/blender/usd/intern/usd_hierarchy_iterator.h
+++ b/source/blender/usd/intern/usd_hierarchy_iterator.h
@@ -24,7 +24,7 @@ class USDHierarchyIterator : public AbstractHierarchyIterator {
                        const USDExportParams &params);
 
  protected:
-  virtual b

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list