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 °iter_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 °iter_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 °iter_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 °iter_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 °iter_data); + + USDAbstractWriter *export_object_xform(const pxr::SdfPath &parent_path, + Object *ob_eval, + const DEGObjectIterData °iter_data); + USDAbstractWriter *export_object_data(const pxr::SdfPath &parent_path, + Object *ob_eval, + const DEGObjectIterData °iter_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", _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs