[Bf-blender-cvs] [f7431e44cc0] sybren-usd-experiments: Reorganising the USD exporter to be more like the Alembic one

Sybren A. Stüvel noreply at git.blender.org
Wed Jun 19 17:59:01 CEST 2019


Commit: f7431e44cc0296916946a89f6c885012d939295b
Author: Sybren A. Stüvel
Date:   Wed Jun 12 17:10:06 2019 +0200
Branches: sybren-usd-experiments
https://developer.blender.org/rBf7431e44cc0296916946a89f6c885012d939295b

Reorganising the USD exporter to be more like the Alembic one

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

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

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

diff --git a/source/blender/usd/CMakeLists.txt b/source/blender/usd/CMakeLists.txt
index 8ba8ceff587..d96b8cd3953 100644
--- a/source/blender/usd/CMakeLists.txt
+++ b/source/blender/usd/CMakeLists.txt
@@ -43,9 +43,15 @@ set(INC_SYS
 set(SRC
   intern/usd_capi.cc
   intern/usd_exporter.cc
+  intern/usd_writer_abstract.cc
+  intern/usd_writer_mesh.cc
+  intern/usd_writer_transform.cc
 
   usd.h
   intern/usd_exporter.h
+  intern/usd_writer_abstract.h
+  intern/usd_writer_mesh.h
+  intern/usd_writer_transform.h
 )
 
 set(LIB
diff --git a/source/blender/usd/intern/usd_exporter.cc b/source/blender/usd/intern/usd_exporter.cc
index 55e242c63a6..cffe76fabd0 100644
--- a/source/blender/usd/intern/usd_exporter.cc
+++ b/source/blender/usd/intern/usd_exporter.cc
@@ -19,6 +19,8 @@
  */
 
 #include "usd_exporter.h"
+#include "usd_writer_mesh.h"
+#include "usd_writer_transform.h"
 
 #include <pxr/pxr.h>
 #include <pxr/base/gf/matrix4f.h>
@@ -31,6 +33,7 @@
 #include <time.h>
 
 extern "C" {
+#include "BKE_anim.h"
 #include "BKE_mesh_runtime.h"
 #include "BKE_scene.h"
 
@@ -83,21 +86,27 @@ bool USDExporter::export_object(Object *ob_eval, const DEGObjectIterData &data_)
   const pxr::SdfPath root("/");
   Mesh *mesh = ob_eval->runtime.mesh_eval;
   pxr::SdfPath parent_path;
-  float parent_relative_matrix[4][4];
+  USDAbstractWriter *parent_writer = NULL;
 
-  if (mesh == NULL || data_.dupli_object_current != NULL) {
-    printf("USD-\033[34mSKIPPING\033[0m object %s  isinstance=%d type=%d mesh = %p\n",
+  if (mesh == NULL) {
+    printf("USD-\033[34mSKIPPING\033[0m object %s  type=%d mesh = %p\n",
            ob_eval->id.name,
-           data_.dupli_object_current != NULL,
+           ob_eval->type,
+           mesh);
+    return false;
+  }
+  if (data_.dupli_object_current != NULL) {
+    printf("USD-\033[34mSKIPPING\033[0m object %s  instance of %s  type=%d mesh = %p\n",
+           ob_eval->id.name,
+           data_.dupli_object_current->ob->id.name,
            ob_eval->type,
            mesh);
     return false;
   }
 
-  // Compute the parent's SdfPath and get the object matrix relative to the parent.
+  // Compute the parent's SdfPath.
   if (ob_eval->parent == NULL) {
     parent_path = root;
-    copy_m4_m4(parent_relative_matrix, ob_eval->obmat);
   }
   else {
     USDPathMap::iterator path_it = usd_object_paths.find(ob_eval->parent);
@@ -108,59 +117,21 @@ bool USDExporter::export_object(Object *ob_eval, const DEGObjectIterData &data_)
       return false;
     }
     parent_path = path_it->second;
-
-    invert_m4_m4(ob_eval->imat, ob_eval->obmat);
-    mul_m4_m4m4(parent_relative_matrix, ob_eval->parent->imat, ob_eval->obmat);
+    parent_writer = usd_writers[parent_path];
   }
 
-  std::string xform_name = pxr::TfMakeValidIdentifier(ob_eval->id.name + 2);
-  pxr::SdfPath xform_path = parent_path.AppendPath(pxr::SdfPath(xform_name));
-  usd_object_paths[ob_eval] = xform_path;
-
-  printf("USD-\033[32mexporting\033[0m object %s → %s   isinstance=%d type=%d mesh = %p\n",
-         ob_eval->id.name,
-         xform_path.GetString().c_str(),
-         data_.dupli_object_current != NULL,
-         ob_eval->type,
-         mesh);
-
-  // Write the transform relative to the parent.
-  pxr::UsdGeomXform xform = pxr::UsdGeomXform::Define(m_stage, xform_path);
-  xform.AddTransformOp().Set(pxr::GfMatrix4d(parent_relative_matrix));
-
-  // Write the mesh.
-  std::string mesh_name = pxr::TfMakeValidIdentifier(mesh->id.name + 2);
-  pxr::SdfPath mesh_path(xform_path.AppendPath(pxr::SdfPath(mesh_name)));
-  pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define(m_stage, mesh_path);
-
-  const MVert *verts = mesh->mvert;
-
-  // TODO(Sybren): there is probably a more C++-y way to do this, which avoids copying the entire
-  // mesh to a different structure. I haven't seen the approach below in the USD exporters for
-  // Maya/Houdini, but it's simple and it works for now.
-  pxr::VtArray<pxr::GfVec3f> usd_points;
-  usd_points.reserve(mesh->totvert);
-  for (int i = 0; i < mesh->totvert; ++i) {
-    usd_points.push_back(pxr::GfVec3f(verts[i].co));
-  }
-  usd_mesh.CreatePointsAttr().Set(usd_points);
+  USDAbstractWriter *xformWriter = new USDTransformWriter(
+      m_stage, parent_path, ob_eval, data_, parent_writer);
 
-  pxr::VtArray<int> usd_face_vertex_counts, usd_face_indices;
-  usd_face_vertex_counts.reserve(mesh->totpoly);
-  usd_face_indices.reserve(mesh->totloop);
+  USDAbstractWriter *meshWriter = new USDMeshWriter(
+      m_stage, parent_path, ob_eval, data_, parent_writer);
 
-  MLoop *mloop = mesh->mloop;
-  MPoly *mpoly = mesh->mpoly;
+  usd_object_paths[ob_eval] = xformWriter->usd_path();
+  usd_writers[xformWriter->usd_path()] = xformWriter;
+  usd_writers[meshWriter->usd_path()] = meshWriter;
 
-  for (int i = 0; i < mesh->totpoly; ++i, ++mpoly) {
-    MLoop *loop = mloop + mpoly->loopstart;
-    usd_face_vertex_counts.push_back(mpoly->totloop);
-    for (int j = 0; j < mpoly->totloop; ++j, ++loop) {
-      usd_face_indices.push_back(loop->v);
-    }
-  }
-  usd_mesh.CreateFaceVertexCountsAttr().Set(usd_face_vertex_counts);
-  usd_mesh.CreateFaceVertexIndicesAttr().Set(usd_face_indices);
+  xformWriter->write();
+  meshWriter->write();
 
   return true;
 }
diff --git a/source/blender/usd/intern/usd_exporter.h b/source/blender/usd/intern/usd_exporter.h
index 2e77ac2cad5..d1051a879f5 100644
--- a/source/blender/usd/intern/usd_exporter.h
+++ b/source/blender/usd/intern/usd_exporter.h
@@ -30,9 +30,9 @@
 #include <map>
 
 struct Depsgraph;
-struct Main;
 struct Scene;
 struct ViewLayer;
+class USDAbstractWriter;
 
 struct ExportSettings {
   Scene *scene;
@@ -69,7 +69,10 @@ class USDExporter {
   const char *m_filename;
 
   typedef std::map<Object *, pxr::SdfPath> USDPathMap;
+  typedef std::map<pxr::SdfPath, USDAbstractWriter *> USDWriterMap;
+
   USDPathMap usd_object_paths;
+  USDWriterMap usd_writers;
 
   pxr::UsdStageRefPtr m_stage;
 
diff --git a/source/blender/usd/intern/usd_writer_abstract.cc b/source/blender/usd/intern/usd_writer_abstract.cc
new file mode 100644
index 00000000000..02906d649ca
--- /dev/null
+++ b/source/blender/usd/intern/usd_writer_abstract.cc
@@ -0,0 +1,37 @@
+#include "usd_writer_abstract.h"
+
+#include <pxr/base/tf/stringUtils.h>
+
+USDAbstractWriter::USDAbstractWriter(pxr::UsdStageRefPtr stage,
+                                     const pxr::SdfPath &parent_path,
+                                     Object *ob_eval,
+                                     const DEGObjectIterData &degiter_data,
+                                     USDAbstractWriter *parent)
+    : m_stage(stage), m_parent_path(parent_path), m_object(ob_eval), m_degiter_data(degiter_data)
+{
+  std::string usd_name(pxr::TfMakeValidIdentifier(ob_eval->id.name + 2));
+  m_path = m_parent_path.AppendPath(pxr::SdfPath(usd_name));
+
+  if (parent) {
+    parent->add_child(this);
+  }
+}
+
+USDAbstractWriter::~USDAbstractWriter()
+{
+}
+
+const pxr::SdfPath &USDAbstractWriter::usd_path() const
+{
+  return m_path;
+}
+
+void USDAbstractWriter::add_child(USDAbstractWriter *child)
+{
+  m_children.push_back(child);
+}
+
+void USDAbstractWriter::write()
+{
+  do_write();
+}
diff --git a/source/blender/usd/intern/usd_writer_abstract.h b/source/blender/usd/intern/usd_writer_abstract.h
new file mode 100644
index 00000000000..344756ca5b2
--- /dev/null
+++ b/source/blender/usd/intern/usd_writer_abstract.h
@@ -0,0 +1,41 @@
+#ifndef __USD__USD_WRITER_ABSTRACT_H__
+#define __USD__USD_WRITER_ABSTRACT_H__
+
+#include "DEG_depsgraph_query.h"
+
+#include <pxr/usd/sdf/path.h>
+#include <pxr/usd/usd/stage.h>
+
+#include <vector>
+
+struct Main;
+struct Object;
+
+class USDAbstractWriter {
+ protected:
+  pxr::UsdStageRefPtr m_stage;
+  pxr::SdfPath m_parent_path;
+  Object *m_object;
+
+  const DEGObjectIterData &m_degiter_data;
+  std::vector<USDAbstractWriter *> m_children;
+  pxr::SdfPath m_path;
+
+ public:
+  USDAbstractWriter(pxr::UsdStageRefPtr stage,
+                    const pxr::SdfPath &parent_path,
+                    Object *ob_eval,
+                    const DEGObjectIterData &degiter_data,
+                    USDAbstractWriter *parent = NULL);
+  virtual ~USDAbstractWriter();
+
+  void add_child(USDAbstractWriter *child);
+  void write();
+
+  const pxr::SdfPath &usd_path() const;
+
+ protected:
+  virtual void do_write() = 0;
+};
+
+#endif /* __USD__USD_WRITER_ABSTRACT_H__ */
diff --git a/source/blender/usd/intern/usd_writer_mesh.cc b/source/blender/usd/intern/usd_writer_mesh.cc
new file mode 100644
index 00000000000..d16e51ffeb5
--- /dev/null
+++ b/source/blender/usd/intern/usd_writer_mesh.cc
@@ -0,0 +1,100 @@
+#include "usd_writer_mesh.h"
+
+#include <pxr/usd/usdGeom/mesh.h>
+
+extern "C" {
+#include "BKE_library.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+}
+
+USDGenericMeshWriter::USDGenericMeshWriter(pxr::UsdStageRefPtr stage,
+                                           const pxr::SdfPath &parent_path,
+                                           Object *ob_eval,
+                                           const DEGObjectIterData &degiter_data,
+                                           USDAbstractWriter *parent)
+    : USDAbstractWriter(stage, parent_path, ob_eval, degiter_data, parent)
+{
+}
+
+void USDGenericMeshWriter::do_write()
+{
+  bool needsfree = false;
+  struct Mesh *mesh = get_evaluated_mesh(needsfree);
+
+  try {
+    write_mesh(mesh);
+
+    if (needsfree) {
+      free_evaluated_mesh(mesh);
+    }
+  }
+  catch (...) {
+    if (needsfree) {
+      free_evaluated_mesh(mesh);
+    }
+    throw;
+  }
+}
+
+void USDGenericMeshWriter::free_evaluated_mesh(struct Mesh *mesh)
+{
+  BKE_id_free(NULL, mesh);
+}
+
+void USDGenericMeshWriter::write_mesh(struct Mesh *mesh)
+{
+  printf("USD-\033[32mexporting\033[0m object %s → %s   isinstance=%d type=%d mesh = %p\n",
+         m_object->id.name,
+         m_path.GetString().c_str(),
+         m_degiter_data.dupli_object_current != NULL,
+         m_object->type,
+         mesh);
+
+  pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define(m_stage, m_path);
+
+  const MVert *verts = mesh->mvert;
+
+  // TODO(Sybren): there is probably a more C++-y way to do this, which avoid

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list