Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support duplicate blendshape target names #1179

Merged
1 change: 1 addition & 0 deletions lib/mayaUsd/fileio/writeJobContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <maya/MDagPath.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MObjectHandle.h>
#include <maya/MPlugArray.h>

#include <memory>
#include <vector>
Expand Down
2 changes: 1 addition & 1 deletion lib/mayaUsd/utils/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ std::string UsdMayaUtil::GetMayaNodeName(const MObject& mayaNode)
return nodeName.asChar();
}

MString UsdMayaUtil::GetUniqueNameOfDAGNode(const MObject& node)
MString UsdMayaUtil::GetUniqueNameOfDagNode(const MObject& node)
{
if (!TF_VERIFY(!node.isNull() && node.hasFn(MFn::kDagNode))) {
return MString();
Expand Down
2 changes: 1 addition & 1 deletion lib/mayaUsd/utils/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ std::string GetMayaNodeName(const MObject& mayaNode);
* @return The name as a Maya string.
*/
MAYAUSD_CORE_PUBLIC
MString GetUniqueNameOfDAGNode(const MObject& node);
MString GetUniqueNameOfDagNode(const MObject& node);

/// Gets the Maya MObject for the node named \p nodeName.
MAYAUSD_CORE_PUBLIC
Expand Down
23 changes: 22 additions & 1 deletion lib/usd/translators/meshWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ TF_DEFINE_PRIVATE_TOKENS(
);
// clang-format on

MPlugArray PxrUsdTranslators_MeshWriter::mBlendShapesAnimWeightPlugs;

PxrUsdTranslators_MeshWriter::PxrUsdTranslators_MeshWriter(
const MFnDependencyNode& depNodeFn,
const SdfPath& usdPath,
Expand All @@ -291,7 +293,16 @@ PxrUsdTranslators_MeshWriter::PxrUsdTranslators_MeshWriter(
}
}

void PxrUsdTranslators_MeshWriter::PostExport() { cleanupPrimvars(); }
void PxrUsdTranslators_MeshWriter::PostExport()
{
cleanupPrimvars();
if (this->mBlendShapesAnimWeightPlugs.length() != 0) {
// NOTE: (yliangsiew) Really, clearing it once is enough, but due to the constraints on what
// should go in the WriteJobContext, there's not really a better place to put this cache for
// now.
this->mBlendShapesAnimWeightPlugs.clear();
}
}

bool PxrUsdTranslators_MeshWriter::writeAnimatedMeshExtents(
const MObject& deformedMesh,
Expand Down Expand Up @@ -463,6 +474,13 @@ bool PxrUsdTranslators_MeshWriter::writeMeshAttrs(
}
} else {
// NOTE: (yliangsiew) This is going to get called once for each time sampled.
// Why do we do this later? Currently, it's because the block above needs to
// run across _all_ meshes first, so that we build the entire array of
// blendshapes being exported ahead of time (the above block is run for each
// prim at the default time sample before running it on each anim. time
// sample) and the plugs that they're associated with. Then here, now knowing
// the entirety of the shapes that are meant to be exported, we can go ahead
// and write the animation for each of them.
if (!_skelInputMesh.isNull()) {
bStat = this->writeBlendShapeAnimation(usdTime);
if (!bStat) {
Expand All @@ -473,6 +491,9 @@ bool PxrUsdTranslators_MeshWriter::writeMeshAttrs(
return bStat;
}
}
// NOTE: (yliangsiew) Also write out the "default" weights for the blendshapes,
// to cover static blendshapes (i.e. non-animated targets.)
bStat = this->writeBlendShapeAnimation(UsdTimeCode::Default());
}
}
}
Expand Down
13 changes: 9 additions & 4 deletions lib/usd/translators/meshWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include <maya/MBoundingBox.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnMesh.h>
#include <maya/MPlugArray.h>
#include <maya/MString.h>

#include <set>
Expand Down Expand Up @@ -75,12 +74,18 @@ class PxrUsdTranslators_MeshWriter : public UsdMayaPrimWriter
bool writeBlendShapeAnimation(const UsdTimeCode& usdTime);
bool writeAnimatedMeshExtents(const MObject& deformedMesh, const UsdTimeCode& usdTime);

/// Used to cache the animated blend shape weight plugs that need to be
/// sampled per-frame. Becuase UsdSkelBlendShape stores animation in an
/// array that encompasses _all_ targets at the SkelRoot level, we cache out
/// blendshape weight plugs across repeated invocations of the meshWriter,
/// so that we know which plugs to sample when we start writing out the
/// animation. This shared cache is eventually cleared in PostExport() of
/// each meshWriter.
static MPlugArray mBlendShapesAnimWeightPlugs;

/// Input mesh before any skeletal deformations, cached between iterations.
MObject _skelInputMesh;

/// The animated plugs of any blendshape nodes involved in mesh deformation.
MPlugArray _animBlendShapeWeightPlugs;

/// The previous sample for the mesh extents. Cached between iterations.
VtVec3fArray _prevMeshExtentsSample;

Expand Down
Loading