[Bf-blender-cvs] [3005b71b266] sybren-usd-experiments: Support instanced collections

Sybren A. Stüvel noreply at git.blender.org
Thu Jun 13 11:13:07 CEST 2019


Commit: 3005b71b266386577139ace2a496929a72a360c1
Author: Sybren A. Stüvel
Date:   Thu Jun 13 11:13:00 2019 +0200
Branches: sybren-usd-experiments
https://developer.blender.org/rB3005b71b266386577139ace2a496929a72a360c1

Support instanced collections

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

M	source/blender/usd/CMakeLists.txt
M	source/blender/usd/intern/usd_exporter.cc
M	source/blender/usd/intern/usd_exporter.h
M	source/blender/usd/intern/usd_writer_mesh.cc
M	source/blender/usd/intern/usd_writer_transform.cc

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

diff --git a/source/blender/usd/CMakeLists.txt b/source/blender/usd/CMakeLists.txt
index d96b8cd3953..a77d20366ed 100644
--- a/source/blender/usd/CMakeLists.txt
+++ b/source/blender/usd/CMakeLists.txt
@@ -20,6 +20,12 @@
 
 include(/opt/usd/pxrConfig.cmake)
 
+# This suppresses the warning "This file includes at least one deprecated or antiquated header which
+# may be removed without further notice at a future date", which is caused by the USD library
+# including <ext/hash_set>. Nothing we can do about that until they change what
+# they include, so this just suppresses it.
+add_definitions(-D_GLIBCXX_PERMIT_BACKWARD_HASH)
+
 set(INC
   .
   ../blenkernel
diff --git a/source/blender/usd/intern/usd_exporter.cc b/source/blender/usd/intern/usd_exporter.cc
index 36f690e603e..3feccbe3472 100644
--- a/source/blender/usd/intern/usd_exporter.cc
+++ b/source/blender/usd/intern/usd_exporter.cc
@@ -68,56 +68,97 @@ void USDExporter::operator()(float &r_progress, bool &r_was_canceled)
 
 bool USDExporter::export_object(Object *ob_eval, const DEGObjectIterData &degiter_data)
 {
-  const pxr::SdfPath root("/");
-  pxr::SdfPath parent_path;
-
-  // Compute the parent's SdfPath.
-  if (ob_eval->parent == NULL) {
-    parent_path = root;
+  pxr::SdfPath parent_path = parent_usd_path(ob_eval, degiter_data);
+  if (parent_path.IsEmpty()) {
+    return false;
   }
-  else {
-    USDPathMap::iterator path_it = usd_object_paths.find(ob_eval->parent);
+
+  USDAbstractWriter *xform_writer, *data_writer;
+  xform_writer = export_object_xform(parent_path, ob_eval, degiter_data);
+  data_writer = export_object_data(xform_writer->usd_path(), ob_eval, degiter_data);
+
+  return data_writer != NULL;
+}
+
+pxr::SdfPath USDExporter::parent_usd_path(Object *ob_eval, const DEGObjectIterData &degiter_data)
+{
+  static const pxr::SdfPath root("/");
+  pxr::SdfPath parent_path(root);
+
+  // Prepend any dupli-parent USD path.
+  if (degiter_data.dupli_parent != NULL && degiter_data.dupli_parent != ob_eval) {
+    USDPathMap::iterator path_it = usd_object_paths.find(degiter_data.dupli_parent);
     if (path_it == usd_object_paths.end()) {
-      printf("USD-\033[31mSKIPPING\033[0m object %s because parent %s hasn't been seen yet\n",
-             ob_eval->id.name,
-             ob_eval->parent->id.name);
-      return false;
+      printf(
+          "USD-\033[31mSKIPPING\033[0m object %s because dupli-parent %s hasn't been seen yet\n",
+          ob_eval->id.name,
+          degiter_data.dupli_parent->id.name);
+      return pxr::SdfPath();
     }
     parent_path = path_it->second;
   }
 
-  // Write the transform. This is always done, even when we don't write the data, as it makes it
-  // possible to reference collection-instantiating empties.
+  if (ob_eval->parent == NULL) {
+    return parent_path;
+  }
+
+  // Append the parent object's USD path.
+  USDPathMap::iterator path_it = usd_object_paths.find(ob_eval->parent);
+  if (path_it == usd_object_paths.end()) {
+    printf("USD-\033[31mSKIPPING\033[0m object %s because parent %s hasn't been seen yet\n",
+           ob_eval->id.name,
+           ob_eval->parent->id.name);
+    return pxr::SdfPath();
+  }
+
+  return parent_path.AppendPath(path_it->second.MakeRelativePath(root));
+}
+
+/* Write the transform. This is always done, even when we don't write the data, as it makes it
+ * possible to reference collection-instantiating empties. */
+USDAbstractWriter *USDExporter::export_object_xform(const pxr::SdfPath &parent_path,
+                                                    Object *ob_eval,
+                                                    const DEGObjectIterData &degiter_data)
+{
   USDAbstractWriter *xform_writer = new USDTransformWriter(
       m_stage, parent_path, ob_eval, degiter_data);
+
   const pxr::SdfPath &xform_usd_path = xform_writer->usd_path();
   usd_object_paths[ob_eval] = xform_usd_path;
   usd_writers[xform_usd_path] = xform_writer;
   xform_writer->write();
 
-  // Write the object data, if we know how.
-  // TODO: let the writer determine whether the data is actually supported.
+  return xform_writer;
+}
+
+/* Write the object data, if we know how. */
+USDAbstractWriter *USDExporter::export_object_data(const pxr::SdfPath &parent_path,
+                                                   Object *ob_eval,
+                                                   const DEGObjectIterData &degiter_data)
+{
   USDAbstractWriter *data_writer = NULL;
+
   switch (ob_eval->type) {
     case OB_MESH:
-      data_writer = new USDMeshWriter(m_stage, xform_usd_path, ob_eval, degiter_data);
+      data_writer = new USDMeshWriter(m_stage, parent_path, ob_eval, degiter_data);
       break;
     default:
       printf("USD-\033[34mXFORM-ONLY\033[0m object %s  type=%d (no data writer)\n",
              ob_eval->id.name,
              ob_eval->type);
-      return false;
+      return NULL;
   }
 
   if (!data_writer->is_supported()) {
     printf("USD-\033[34mXFORM-ONLY\033[0m object %s  type=%d (data writer rejects the data)\n",
            ob_eval->id.name,
            ob_eval->type);
+    delete data_writer;
+    return NULL;
   }
-  else {
-    usd_writers[data_writer->usd_path()] = data_writer;
-    data_writer->write();
-  }
 
-  return true;
+  usd_writers[data_writer->usd_path()] = data_writer;
+  data_writer->write();
+
+  return data_writer;
 }
diff --git a/source/blender/usd/intern/usd_exporter.h b/source/blender/usd/intern/usd_exporter.h
index d1051a879f5..92ac3164635 100644
--- a/source/blender/usd/intern/usd_exporter.h
+++ b/source/blender/usd/intern/usd_exporter.h
@@ -76,7 +76,16 @@ class USDExporter {
 
   pxr::UsdStageRefPtr m_stage;
 
+ private:
   bool export_object(Object *ob_eval, const DEGObjectIterData &data_);
+  pxr::SdfPath parent_usd_path(Object *ob_eval, const DEGObjectIterData &degiter_data);
+
+  USDAbstractWriter *export_object_xform(const pxr::SdfPath &parent_path,
+                                         Object *ob_eval,
+                                         const DEGObjectIterData &degiter_data);
+  USDAbstractWriter *export_object_data(const pxr::SdfPath &parent_path,
+                                        Object *ob_eval,
+                                        const DEGObjectIterData &degiter_data);
 
  public:
   USDExporter(const char *filename, ExportSettings &settings);
diff --git a/source/blender/usd/intern/usd_writer_mesh.cc b/source/blender/usd/intern/usd_writer_mesh.cc
index bc721f87f04..dde1cbdf681 100644
--- a/source/blender/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/usd/intern/usd_writer_mesh.cc
@@ -25,6 +25,13 @@ void USDGenericMeshWriter::do_write()
   bool needsfree = false;
   struct Mesh *mesh = get_evaluated_mesh(needsfree);
 
+  if (mesh == NULL) {
+    printf("USD-\033[31mSKIPPING\033[0m object %s  type=%d mesh = NULL\n",
+           m_object->id.name,
+           m_object->type);
+    return;
+  }
+
   try {
     write_mesh(mesh);
 
@@ -96,14 +103,5 @@ USDMeshWriter::USDMeshWriter(pxr::UsdStageRefPtr stage,
 
 Mesh *USDMeshWriter::get_evaluated_mesh(bool &UNUSED(r_needsfree))
 {
-  if (m_degiter_data.dupli_object_current != NULL) {
-    printf("USD-\033[34mSKIPPING\033[0m object %s  instance of %s  type=%d mesh = %p\n",
-           m_object->id.name,
-           m_degiter_data.dupli_object_current->ob->id.name,
-           m_object->type,
-           m_object->runtime.mesh_eval);
-    return NULL;
-  }
-
   return m_object->runtime.mesh_eval;
 }
diff --git a/source/blender/usd/intern/usd_writer_transform.cc b/source/blender/usd/intern/usd_writer_transform.cc
index 0e0b0b9ca25..fb1d079dff3 100644
--- a/source/blender/usd/intern/usd_writer_transform.cc
+++ b/source/blender/usd/intern/usd_writer_transform.cc
@@ -17,15 +17,24 @@ USDTransformWriter::USDTransformWriter(pxr::UsdStageRefPtr stage,
 
 void USDTransformWriter::do_write()
 {
+  float dupliparent_relative_matrix[4][4];
   float parent_relative_matrix[4][4];  // The object matrix relative to the parent.
 
+  if (m_degiter_data.dupli_parent != NULL && m_degiter_data.dupli_parent != m_object) {
+    invert_m4_m4(m_degiter_data.dupli_parent->imat, m_degiter_data.dupli_parent->obmat);
+    mul_m4_m4m4(dupliparent_relative_matrix, m_degiter_data.dupli_parent->imat, m_object->obmat);
+  }
+  else {
+    copy_m4_m4(dupliparent_relative_matrix, m_object->obmat);
+  }
+
   // Get the object matrix relative to the parent.
   if (m_object->parent == NULL) {
-    copy_m4_m4(parent_relative_matrix, m_object->obmat);
+    copy_m4_m4(parent_relative_matrix, dupliparent_relative_matrix);
   }
   else {
     invert_m4_m4(m_object->parent->imat, m_object->parent->obmat);
-    mul_m4_m4m4(parent_relative_matrix, m_object->parent->imat, m_object->obmat);
+    mul_m4_m4m4(parent_relative_matrix, m_object->parent->imat, dupliparent_relative_matrix);
   }
 
   printf("USD-\033[32mexporting\033[0m XForm %s → %s   isinstance=%d type=%d\n",



More information about the Bf-blender-cvs mailing list