From ea54cbe1b42efb3107285c89685f555c06997062 Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Tue, 3 Aug 2021 11:55:53 +0200 Subject: USD: add USD importer This is an initial implementation of a USD importer. This work is comprised of Tangent Animation's open source USD importer, combined with features @makowalski had implemented. The design is very similar to the approach taken in the Alembic importer. The core functionality resides in a collection of "reader" classes, each of which is responsible for converting an instance of a USD prim to the corresponding Blender Object representation. The flow of control for the conversion can be followed in the `import_startjob()` and `import_endjob()` functions in `usd_capi.cc`. The `USDStageReader` class is responsible for traversing the USD stage and instantiating the appropriate readers. Reviewed By: sybren, HooglyBoogly Differential Revision: https://developer.blender.org/D10700 --- source/blender/modifiers/CMakeLists.txt | 10 ++++ .../modifiers/intern/MOD_meshsequencecache.c | 63 ++++++++++++++++++---- 2 files changed, 63 insertions(+), 10 deletions(-) (limited to 'source/blender/modifiers') diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 0138dd0c3ad..d9b9fa96d04 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -141,6 +141,16 @@ if(WITH_ALEMBIC) ) endif() +if(WITH_USD) + add_definitions(-DWITH_USD) + list(APPEND INC + ../io/usd + ) + list(APPEND LIB + bf_usd + ) +endif() + if(WITH_MOD_REMESH) list(APPEND INC ../../../intern/dualcon diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c index c2f9cd8c867..3e6081e0a18 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.c +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c @@ -55,18 +55,29 @@ #include "MOD_modifiertypes.h" #include "MOD_ui_common.h" -#ifdef WITH_ALEMBIC -# include "ABC_alembic.h" +#if defined(WITH_USD) || defined(WITH_ALEMBIC) # include "BKE_global.h" # include "BKE_lib_id.h" #endif +#ifdef WITH_ALEMBIC +# include "ABC_alembic.h" +#endif + +#ifdef WITH_USD +# include "usd.h" +#endif + static void initData(ModifierData *md) { MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md; BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(mcmd, modifier)); + mcmd->cache_file = NULL; + mcmd->object_path[0] = '\0'; + mcmd->read_flag = MOD_MESHSEQ_READ_ALL; + MEMCPY_STRUCT_AFTER(mcmd, DNA_struct_default_get(MeshSeqCacheModifierData), modifier); } @@ -109,7 +120,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { -#ifdef WITH_ALEMBIC +#if defined(WITH_USD) || defined(WITH_ALEMBIC) MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md; /* Only used to check whether we are operating on org data or not... */ @@ -127,16 +138,32 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path); if (!mcmd->reader) { BKE_modifier_set_error( - ctx->object, md, "Could not create Alembic reader for file %s", cache_file->filepath); + ctx->object, md, "Could not create reader for file %s", cache_file->filepath); return mesh; } } - /* If this invocation is for the ORCO mesh, and the mesh in Alembic hasn't changed topology, we + /* If this invocation is for the ORCO mesh, and the mesh hasn't changed topology, we * must return the mesh as-is instead of deforming it. */ - if (ctx->flag & MOD_APPLY_ORCO && - !ABC_mesh_topology_changed(mcmd->reader, ctx->object, mesh, time, &err_str)) { - return mesh; + if (ctx->flag & MOD_APPLY_ORCO) { + switch (cache_file->type) { + case CACHEFILE_TYPE_ALEMBIC: +# ifdef WITH_ALEMBIC + if (!ABC_mesh_topology_changed(mcmd->reader, ctx->object, mesh, time, &err_str)) { + return mesh; + } +# endif + break; + case CACHEFILE_TYPE_USD: +# ifdef WITH_USD + if (!USD_mesh_topology_changed(mcmd->reader, ctx->object, mesh, time, &err_str)) { + return mesh; + } +# endif + break; + case CACHE_FILE_TYPE_INVALID: + break; + } } if (me != NULL) { @@ -156,7 +183,23 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } } - Mesh *result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag); + Mesh *result = NULL; + + switch (cache_file->type) { + case CACHEFILE_TYPE_ALEMBIC: +# ifdef WITH_ALEMBIC + result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag); +# endif + break; + case CACHEFILE_TYPE_USD: +# ifdef WITH_USD + result = USD_read_mesh( + mcmd->reader, ctx->object, mesh, time * FPS, &err_str, mcmd->read_flag); +# endif + break; + case CACHE_FILE_TYPE_INVALID: + break; + } mcmd->velocity_delta = 1.0f; if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_SECOND) { @@ -187,7 +230,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * static bool dependsOnTime(ModifierData *md) { -#ifdef WITH_ALEMBIC +#if defined(WITH_USD) || defined(WITH_ALEMBIC) MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md; return (mcmd->cache_file != NULL); #else -- cgit v1.2.3