[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 °iter_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 °iter_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 °iter_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