USD Export: Armature export improvements.

Now including the root prim in the skinned mesh
skeleton relationship path.  Also, added logic to
avoid nesting SkelRoot prims in the USD, as such
nesting causes skeleton binding to fail as well
as crashes in Create.

Now iterating over the deform groups of the
evaluated mesh when setting joint weights
and indices, to ensure the vertex group
data is valid.
This commit is contained in:
Michael Kowalski 2021-11-08 16:38:11 -05:00
parent e2a783f8eb
commit 85172cb5e1
3 changed files with 47 additions and 4 deletions

View File

@ -22,12 +22,47 @@
namespace blender::io::usd {
bool USDSkelRootWriter::is_under_skel_root() const
{
pxr::SdfPath parent_path(usd_export_context_.usd_path);
parent_path = parent_path.GetParentPath();
if (parent_path.IsEmpty()) {
return false;
}
pxr::UsdPrim prim = usd_export_context_.stage->GetPrimAtPath(parent_path);
while (prim.IsValid()) {
if (prim.IsA<pxr::UsdSkelRoot>()) {
return true;
}
prim = prim.GetParent();
}
return false;
}
pxr::UsdGeomXformable USDSkelRootWriter::create_xformable() const
{
pxr::UsdSkelRoot root =
/* Create a UsdSkelRoot primitive, unless this prim is already
beneath a UsdSkelRoot, in which case create an Xform. */
pxr::UsdGeomXformable root;
if (is_under_skel_root()) {
root =
(usd_export_context_.export_params.export_as_overs) ?
pxr::UsdSkelRoot(usd_export_context_.stage->OverridePrim(usd_export_context_.usd_path)) :
pxr::UsdSkelRoot::Define(usd_export_context_.stage, usd_export_context_.usd_path);
pxr::UsdGeomXform(usd_export_context_.stage->OverridePrim(usd_export_context_.usd_path)) :
pxr::UsdGeomXform::Define(usd_export_context_.stage, usd_export_context_.usd_path);
}
else {
root =
(usd_export_context_.export_params.export_as_overs) ?
pxr::UsdSkelRoot(usd_export_context_.stage->OverridePrim(usd_export_context_.usd_path)) :
pxr::UsdSkelRoot::Define(usd_export_context_.stage, usd_export_context_.usd_path);
}
return root;
}

View File

@ -34,6 +34,10 @@ class USDSkelRootWriter : public USDTransformWriter {
protected:
/* Override to create UsdSkelRoot prim. */
pxr::UsdGeomXformable create_xformable() const override;
/* Rturns true if the prim to be created is
* already unde a USD SkeRoot. */
bool is_under_skel_root() const;
};
} // namespace blender::io::usd

View File

@ -136,6 +136,10 @@ void USDSkinnedMeshWriter::do_write(HierarchyContext &context)
return;
}
if (strlen(usd_export_context_.export_params.root_prim_path) != 0) {
skel_path = std::string(usd_export_context_.export_params.root_prim_path) + skel_path;
}
usd_skel_api.CreateSkeletonRel().SetTargets(pxr::SdfPathVector({pxr::SdfPath(skel_path)}));
if (pxr::UsdAttribute geom_bind_attr = usd_skel_api.CreateGeomBindTransformAttr()) {
@ -186,7 +190,7 @@ void USDSkinnedMeshWriter::write_weights(const Object *ob,
std::vector<int> group_to_bone_idx;
for (bDeformGroup *def = (bDeformGroup *)ob->defbase.first; def; def = def->next) {
for (const bDeformGroup *def = (const bDeformGroup *)mesh->vertex_group_names.first; def; def = def->next) {
int bone_idx = -1;
/* For now, n-squared search is acceptable. */