diff --git a/lib/mayaUsd/fileio/jobs/readJob.cpp b/lib/mayaUsd/fileio/jobs/readJob.cpp index e0b63baeb1..5e30a97b21 100644 --- a/lib/mayaUsd/fileio/jobs/readJob.cpp +++ b/lib/mayaUsd/fileio/jobs/readJob.cpp @@ -115,6 +115,7 @@ bool UsdMaya_ReadJob::Read(std::vector* addedDagPaths) } stage->SetEditTarget(stage->GetSessionLayer()); + _setTimeSampleMultiplierFrom(stage->GetTimeCodesPerSecond()); // XXX Currently all distance values are set directly from USD and will be // interpreted as centimeters (Maya's internal distance unit). Future work @@ -152,11 +153,14 @@ bool UsdMaya_ReadJob::Read(std::vector* addedDagPaths) stageInterval.SetMax(stage->GetEndTimeCode()); } + MTime::Unit timeUnit = MTime::uiUnit(); if (stageInterval.GetMin() < currentMinTime.value()) { - MAnimControl::setMinTime(MTime(stageInterval.GetMin())); + MAnimControl::setMinTime( + MTime(stageInterval.GetMin() * mTimeSampleMultiplier, timeUnit)); } if (stageInterval.GetMax() > currentMaxTime.value()) { - MAnimControl::setMaxTime(MTime(stageInterval.GetMax())); + MAnimControl::setMaxTime( + MTime(stageInterval.GetMax() * mTimeSampleMultiplier, timeUnit)); } } @@ -391,6 +395,7 @@ void UsdMaya_ReadJob::_ImportMaster( for (auto primIt = range.begin(); primIt != range.end(); ++primIt) { const UsdPrim& prim = *primIt; UsdMayaPrimReaderContext readCtx(&mNewNodeRegistry); + readCtx.SetTimeSampleMultiplier(mTimeSampleMultiplier); if (prim.IsInstance()) { _DoImportInstanceIt(primIt, usdRootPrim, readCtx, primReaderMap); } else { @@ -418,6 +423,7 @@ bool UsdMaya_ReadJob::_DoImport(UsdPrimRange& rootRange, const UsdPrim& usdRootP for (auto primIt = range.begin(); primIt != range.end(); ++primIt) { const UsdPrim& prim = *primIt; UsdMayaPrimReaderContext readCtx(&mNewNodeRegistry); + readCtx.SetTimeSampleMultiplier(mTimeSampleMultiplier); if (buildInstances && prim.IsInstance()) { _DoImportInstanceIt(primIt, usdRootPrim, readCtx, primReaderMap); @@ -430,6 +436,8 @@ bool UsdMaya_ReadJob::_DoImport(UsdPrimRange& rootRange, const UsdPrim& usdRootP if (buildInstances) { MDGModifier deleteMasterMod; UsdMayaPrimReaderContext readCtx(&mNewNodeRegistry); + readCtx.SetTimeSampleMultiplier(mTimeSampleMultiplier); + for (const auto& master : usdRootPrim.GetStage()->GetMasters()) { const SdfPath masterPath = master.GetPath(); MObject masterObject = readCtx.GetMayaNode(masterPath, false); @@ -500,4 +508,13 @@ void UsdMaya_ReadJob::SetMayaRootDagPath(const MDagPath& mayaRootDagPath) const MDagPath& UsdMaya_ReadJob::GetMayaRootDagPath() const { return mMayaRootDagPath; } +double UsdMaya_ReadJob::timeSampleMultiplier() const { return mTimeSampleMultiplier; } + +double UsdMaya_ReadJob::_setTimeSampleMultiplierFrom(const double layerFPS) +{ + float sceneFPS = UsdMayaUtil::GetSceneMTimeUnitAsFloat(); + mTimeSampleMultiplier = sceneFPS / layerFPS; + return mTimeSampleMultiplier; +} + PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/mayaUsd/fileio/jobs/readJob.h b/lib/mayaUsd/fileio/jobs/readJob.h index effa634381..afcb5f0a18 100644 --- a/lib/mayaUsd/fileio/jobs/readJob.h +++ b/lib/mayaUsd/fileio/jobs/readJob.h @@ -65,6 +65,9 @@ class UsdMaya_ReadJob MAYAUSD_CORE_PUBLIC const MDagPath& GetMayaRootDagPath() const; + MAYAUSD_CORE_PUBLIC + double timeSampleMultiplier() const; + protected: // Types using _PrimReaderMap = std::unordered_map; @@ -122,9 +125,12 @@ class UsdMaya_ReadJob const UsdPrim& usdRootPrim, UsdMayaPrimReaderContext& readCtx); + double _setTimeSampleMultiplierFrom(const double layerFPS); + // Data MDagModifier mDagModifierUndo; bool mDagModifierSeeded; + double mTimeSampleMultiplier; }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/mayaUsd/fileio/primReaderContext.cpp b/lib/mayaUsd/fileio/primReaderContext.cpp index af3723eace..3793b84034 100644 --- a/lib/mayaUsd/fileio/primReaderContext.cpp +++ b/lib/mayaUsd/fileio/primReaderContext.cpp @@ -19,6 +19,7 @@ PXR_NAMESPACE_OPEN_SCOPE UsdMayaPrimReaderContext::UsdMayaPrimReaderContext(ObjectRegistry* pathNodeMap) : _prune(false) + , _timeSampleMultiplier(1.0) , _pathNodeMap(pathNodeMap) { } @@ -61,4 +62,11 @@ bool UsdMayaPrimReaderContext::GetPruneChildren() const { return _prune; } /// children have already been processed. void UsdMayaPrimReaderContext::SetPruneChildren(bool prune) { _prune = prune; } +double UsdMayaPrimReaderContext::GetTimeSampleMultiplier() const { return _timeSampleMultiplier; }; + +void UsdMayaPrimReaderContext::SetTimeSampleMultiplier(double multiplier) +{ + _timeSampleMultiplier = multiplier; +}; + PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/mayaUsd/fileio/primReaderContext.h b/lib/mayaUsd/fileio/primReaderContext.h index 78b5df5db0..caad00ae12 100644 --- a/lib/mayaUsd/fileio/primReaderContext.h +++ b/lib/mayaUsd/fileio/primReaderContext.h @@ -73,10 +73,19 @@ class UsdMayaPrimReaderContext MAYAUSD_CORE_PUBLIC void SetPruneChildren(bool prune); + /// \brief Return the time sample multiplier to convert from USD time to Maya time + MAYAUSD_CORE_PUBLIC + double GetTimeSampleMultiplier() const; + + /// \brief Set the time sample multiplier to convert from USD time to Maya time + MAYAUSD_CORE_PUBLIC + void SetTimeSampleMultiplier(double multiplier); + ~UsdMayaPrimReaderContext() { } private: - bool _prune; + bool _prune; + double _timeSampleMultiplier; // used to keep track of prims that are created. // for undo/redo diff --git a/lib/mayaUsd/fileio/translators/translatorCamera.cpp b/lib/mayaUsd/fileio/translators/translatorCamera.cpp index 841f279a3a..245464146e 100644 --- a/lib/mayaUsd/fileio/translators/translatorCamera.cpp +++ b/lib/mayaUsd/fileio/translators/translatorCamera.cpp @@ -108,7 +108,8 @@ static bool _GetTimeAndValueArrayForUsdAttribute( const GfInterval& timeInterval, MTimeArray* timeArray, MDoubleArray* valueArray, - const MDistance::Unit convertToUnit = MDistance::kMillimeters) + const MDistance::Unit convertToUnit = MDistance::kMillimeters, + const double timeSampleMultiplier = 1.0) { static const TfType& floatType = TfType::Find(); std::vector timeSamples; @@ -118,8 +119,8 @@ static bool _GetTimeAndValueArrayForUsdAttribute( return false; } - size_t numTimeSamples = timeSamples.size(); - + size_t numTimeSamples = timeSamples.size(); + MTime::Unit timeUnit = MTime::uiUnit(); for (size_t i = 0; i < numTimeSamples; ++i) { const double timeSample = timeSamples[i]; float attrValue; @@ -135,7 +136,7 @@ static bool _GetTimeAndValueArrayForUsdAttribute( break; } - timeArray->set(MTime(timeSample), i); + timeArray->set(MTime(timeSample * timeSampleMultiplier, timeUnit), i); valueArray->set(attrValue, i); } @@ -150,7 +151,8 @@ static bool _GetTimeAndValueArraysForUsdAttribute( const GfInterval& timeInterval, MTimeArray* timeArray, MDoubleArray* valueArray1, - MDoubleArray* valueArray2) + MDoubleArray* valueArray2, + const double timeSampleMultiplier = 1.0) { static const TfType& vec2fType = TfType::Find(); std::vector timeSamples; @@ -162,6 +164,7 @@ static bool _GetTimeAndValueArraysForUsdAttribute( size_t numTimeSamples = timeSamples.size(); valueArray2->setLength(numTimeSamples); + MTime::Unit timeUnit = MTime::uiUnit(); for (size_t i = 0; i < numTimeSamples; ++i) { const double timeSample = timeSamples[i]; @@ -169,7 +172,7 @@ static bool _GetTimeAndValueArraysForUsdAttribute( if (!usdAttr.Get(&attrValue, timeSample)) { return false; } - timeArray->set(MTime(timeSample), i); + timeArray->set(MTime(timeSample * timeSampleMultiplier, timeUnit), i); valueArray1->set(attrValue[0], i); valueArray2->set(attrValue[1], i); } @@ -213,7 +216,12 @@ static bool _TranslateAnimatedUsdAttributeToPlug( MTimeArray timeArray; MDoubleArray valueArray; if (!_GetTimeAndValueArrayForUsdAttribute( - usdAttr, args.GetTimeInterval(), &timeArray, &valueArray, convertToUnit)) { + usdAttr, + args.GetTimeInterval(), + &timeArray, + &valueArray, + convertToUnit, + (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0)) { return false; } @@ -239,7 +247,12 @@ static bool _TranslateAnimatedUsdAttributeToPlugs( MDoubleArray valueArray1; MDoubleArray valueArray2; if (!_GetTimeAndValueArraysForUsdAttribute( - usdAttr, args.GetTimeInterval(), &timeArray, &valueArray1, &valueArray2)) { + usdAttr, + args.GetTimeInterval(), + &timeArray, + &valueArray1, + &valueArray2, + (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0)) { return false; } diff --git a/lib/mayaUsd/fileio/translators/translatorCurves.cpp b/lib/mayaUsd/fileio/translators/translatorCurves.cpp index 3bc0772f55..abcee48ea5 100644 --- a/lib/mayaUsd/fileio/translators/translatorCurves.cpp +++ b/lib/mayaUsd/fileio/translators/translatorCurves.cpp @@ -242,10 +242,11 @@ bool UsdMayaTranslatorCurves::Create( MFnAnimCurve animFn; // Construct the time array to be used for all the keys - MTimeArray timeArray; - timeArray.setLength(numTimeSamples); + MTime::Unit timeUnit = MTime::uiUnit(); + double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0; + MTimeArray timeArray(numTimeSamples, MTime()); for (unsigned int ti = 0; ti < numTimeSamples; ++ti) { - timeArray.set(MTime(pointsTimeSamples[ti]), ti); + timeArray.set(MTime(pointsTimeSamples[ti] * timeSampleMultiplier, timeUnit), ti); } // Key/Animate the weights diff --git a/lib/mayaUsd/fileio/translators/translatorMesh.cpp b/lib/mayaUsd/fileio/translators/translatorMesh.cpp index f7a380043e..602d3d47cf 100644 --- a/lib/mayaUsd/fileio/translators/translatorMesh.cpp +++ b/lib/mayaUsd/fileio/translators/translatorMesh.cpp @@ -48,13 +48,14 @@ namespace MAYAUSD_NS_DEF { TranslatorMeshRead::TranslatorMeshRead( - const UsdGeomMesh& mesh, - const UsdPrim& prim, - const MObject& transformObj, - const MObject& stageNode, - const GfInterval& frameRange, - bool wantCacheAnimation, - MStatus* status) + const UsdGeomMesh& mesh, + const UsdPrim& prim, + const MObject& transformObj, + const MObject& stageNode, + const GfInterval& frameRange, + bool wantCacheAnimation, + UsdMayaPrimReaderContext* context, + MStatus* status) : m_wantCacheAnimation(wantCacheAnimation) , m_pointsNumTimeSamples(0u) { @@ -298,11 +299,15 @@ TranslatorMeshRead::TranslatorMeshRead( // Animate the weights so that mesh0 has a weight of 1 at frame 0, etc. MFnAnimCurve animFn; + // Get the values needed to convert time to the current maya scenes framerate + MTime::Unit timeUnit = MTime::uiUnit(); + double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0; + // Construct the time array to be used for all the keys MTimeArray timeArray; timeArray.setLength(m_pointsNumTimeSamples); for (unsigned int ti = 0u; ti < m_pointsNumTimeSamples; ++ti) { - timeArray.set(MTime(pointsTimeSamples[ti]), ti); + timeArray.set(MTime(pointsTimeSamples[ti] * timeSampleMultiplier, timeUnit), ti); } // Key/Animate the weights diff --git a/lib/mayaUsd/fileio/translators/translatorMesh.h b/lib/mayaUsd/fileio/translators/translatorMesh.h index e2dc6aa847..f47cae0845 100644 --- a/lib/mayaUsd/fileio/translators/translatorMesh.h +++ b/lib/mayaUsd/fileio/translators/translatorMesh.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -36,13 +37,14 @@ class MAYAUSD_CORE_PUBLIC TranslatorMeshRead { public: TranslatorMeshRead( - const UsdGeomMesh& mesh, - const UsdPrim& prim, - const MObject& transformObj, - const MObject& stageNode, - const GfInterval& frameRange, - bool wantCacheAnimation, - MStatus* status = nullptr); + const UsdGeomMesh& mesh, + const UsdPrim& prim, + const MObject& transformObj, + const MObject& stageNode, + const GfInterval& frameRange, + bool wantCacheAnimation, + UsdMayaPrimReaderContext* context, + MStatus* status = nullptr); ~TranslatorMeshRead() = default; diff --git a/lib/mayaUsd/fileio/translators/translatorNurbsPatch.cpp b/lib/mayaUsd/fileio/translators/translatorNurbsPatch.cpp index f4d11e8896..d402aa7e6c 100644 --- a/lib/mayaUsd/fileio/translators/translatorNurbsPatch.cpp +++ b/lib/mayaUsd/fileio/translators/translatorNurbsPatch.cpp @@ -264,10 +264,12 @@ bool UsdMayaTranslatorNurbsPatch::Read( MFnAnimCurve animFn; // Construct the time array to be used for all the keys - MTimeArray timeArray; + MTime::Unit timeUnit = MTime::uiUnit(); + double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0; + MTimeArray timeArray; timeArray.setLength(numTimeSamples); for (unsigned int ti = 0; ti < numTimeSamples; ++ti) { - timeArray.set(MTime(pointsTimeSamples[ti]), ti); + timeArray.set(MTime(pointsTimeSamples[ti] * timeSampleMultiplier, timeUnit), ti); } // Key/Animate the weights diff --git a/lib/mayaUsd/fileio/translators/translatorPrim.cpp b/lib/mayaUsd/fileio/translators/translatorPrim.cpp index 8bfd481b27..12f5fa1bd8 100644 --- a/lib/mayaUsd/fileio/translators/translatorPrim.cpp +++ b/lib/mayaUsd/fileio/translators/translatorPrim.cpp @@ -33,6 +33,8 @@ void UsdMayaTranslatorPrim::Read( UsdMayaPrimReaderContext* context) { UsdGeomImageable primSchema(prim); + MTime::Unit timeUnit = MTime::uiUnit(); + double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0; if (!primSchema) { TF_CODING_ERROR("Prim %s is not UsdGeomImageable.", prim.GetPath().GetText()); return; @@ -81,7 +83,7 @@ void UsdMayaTranslatorPrim::Read( MTimeArray timeArray; timeArray.setLength(numTimeSamples); for (unsigned int ti = 0; ti < numTimeSamples; ++ti) { - timeArray.set(MTime(visTimeSamples[ti]), ti); + timeArray.set(MTime(visTimeSamples[ti] * timeSampleMultiplier, timeUnit), ti); } // Add the keys diff --git a/lib/mayaUsd/fileio/translators/translatorSkel.cpp b/lib/mayaUsd/fileio/translators/translatorSkel.cpp index f916d4c819..3643c38343 100644 --- a/lib/mayaUsd/fileio/translators/translatorSkel.cpp +++ b/lib/mayaUsd/fileio/translators/translatorSkel.cpp @@ -476,8 +476,10 @@ bool _CopyAnimFromSkel( _GetJointAnimTimeSamples(skelQuery, args, &usdTimes); MTimeArray mayaTimes; mayaTimes.setLength(usdTimes.size()); + MTime::Unit timeUnit = MTime::uiUnit(); + double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0; for (size_t i = 0; i < usdTimes.size(); ++i) { - mayaTimes[i] = usdTimes[i]; + mayaTimes[i] = MTime(usdTimes[i] * timeSampleMultiplier, timeUnit); } MStatus status; @@ -622,7 +624,7 @@ bool UsdMayaTranslatorSkel::CreateJointHierarchy( jointContainerPath = skelQuery.GetPrim().GetPath(); jointContainerIsSkeleton = true; - // Create a joint to represent thte Skeleton. + // Create a joint to represent the Skeleton. if (!UsdMayaTranslatorUtil::CreateNode( jointContainerPath, _MayaTokens->jointType, diff --git a/lib/mayaUsd/fileio/translators/translatorXformable.cpp b/lib/mayaUsd/fileio/translators/translatorXformable.cpp index 144557d9a9..8441dd8270 100644 --- a/lib/mayaUsd/fileio/translators/translatorXformable.cpp +++ b/lib/mayaUsd/fileio/translators/translatorXformable.cpp @@ -210,6 +210,9 @@ static bool _pushUSDXformOpToMayaXform( const UsdMayaPrimReaderArgs& args, const UsdMayaPrimReaderContext* context) { + MTime::Unit timeUnit = MTime::uiUnit(); + double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0; + std::vector xValue; std::vector yValue; std::vector zValue; @@ -230,7 +233,7 @@ static bool _pushUSDXformOpToMayaXform( xValue[ti] = value[0]; yValue[ti] = value[1]; zValue[ti] = value[2]; - timeArray.set(MTime(timeSamples[ti]), ti); + timeArray.set(MTime(timeSamples[ti] * timeSampleMultiplier, timeUnit), ti); } else { TF_RUNTIME_ERROR( "Missing sampled data on xformOp: %s", xformop.GetName().GetText()); @@ -380,6 +383,9 @@ static bool _pushUSDXformToMayaXform( std::vector timeCodes; MTimeArray timeArray; + MTime::Unit timeUnit = MTime::uiUnit(); + + double timeSampleMultiplier = (context != nullptr) ? context->GetTimeSampleMultiplier() : 1.0; if (!timeSamples.empty()) { // Convert all the time samples to UsdTimeCodes. @@ -481,7 +487,7 @@ static bool _pushUSDXformToMayaXform( ShearYZVal[ti] = shear[2]; if (!timeCode.IsDefault()) { - timeArray.set(MTime(timeCode.GetValue()), ti); + timeArray.set(MTime(timeCode.GetValue() * timeSampleMultiplier, timeUnit), ti); } } diff --git a/lib/usd/translators/meshReader.cpp b/lib/usd/translators/meshReader.cpp index feacab2abd..f39a56d241 100644 --- a/lib/usd/translators/meshReader.cpp +++ b/lib/usd/translators/meshReader.cpp @@ -103,6 +103,7 @@ bool MayaUsdPrimReaderMesh::Read(UsdMayaPrimReaderContext* context) stageNode, _GetArgs().GetTimeInterval(), _GetArgs().GetUseAsAnimationCache(), + context, &status); CHECK_MSTATUS_AND_RETURN(status, false); diff --git a/lib/usd/translators/skelReader.cpp b/lib/usd/translators/skelReader.cpp index 98bc6a6acf..165b3a5350 100644 --- a/lib/usd/translators/skelReader.cpp +++ b/lib/usd/translators/skelReader.cpp @@ -106,7 +106,7 @@ bool UsdMayaPrimReaderSkeleton::Read(UsdMayaPrimReaderContext* context) skelQuery, parentNode, _GetArgs(), context, &joints)) { // Add a dagPose node to hold the rest pose. - // This is not necessary for skinning to function i Maya, but is not + // This is not necessary for skinning to function in Maya, but is // necessary in order to properly round-trip the Skeleton's // restTransforms, and is a requirement of some exporters. // The dagPose command also will not work without this. diff --git a/plugin/pxr/maya/lib/usdMaya/testenv/testUsdImportNestedAssemblyAnimation.py b/plugin/pxr/maya/lib/usdMaya/testenv/testUsdImportNestedAssemblyAnimation.py index 734a037168..a70dc721cf 100644 --- a/plugin/pxr/maya/lib/usdMaya/testenv/testUsdImportNestedAssemblyAnimation.py +++ b/plugin/pxr/maya/lib/usdMaya/testenv/testUsdImportNestedAssemblyAnimation.py @@ -53,7 +53,8 @@ def setUpClass(cls): # current frame range in Maya to be expanded to include that. We set # it to something inside that range now so we can make sure that that # happens. - OMA.MAnimControl.setAnimationStartEndTime(OM.MTime(121), OM.MTime(130)) + timeUnit = OM.MTime.uiUnit() + OMA.MAnimControl.setAnimationStartEndTime(OM.MTime(121, timeUnit), OM.MTime(130, timeUnit)) cmds.assembly(assemblyNode, edit=True, active='Full') diff --git a/test/lib/mayaUsd/nodes/testPointBasedDeformerNode.py b/test/lib/mayaUsd/nodes/testPointBasedDeformerNode.py index 1aba2323ff..2f40ad9f94 100644 --- a/test/lib/mayaUsd/nodes/testPointBasedDeformerNode.py +++ b/test/lib/mayaUsd/nodes/testPointBasedDeformerNode.py @@ -64,8 +64,9 @@ def testCubeWithDeformer(self): Tests that a native Maya mesh is deformed correctly by a point based deformer node. """ + timeUnit = OM.MTime.uiUnit() OMA.MAnimControl.setAnimationStartEndTime( - OM.MTime(self.START_TIMECODE), OM.MTime(self.END_TIMECODE)) + OM.MTime(self.START_TIMECODE, timeUnit), OM.MTime(self.END_TIMECODE, timeUnit)) # Create the cube that will be affected by the deformer. testCube = cmds.polyCube(depth=1.0, height=1.0, width=1.0)[0] diff --git a/test/lib/usd/translators/CMakeLists.txt b/test/lib/usd/translators/CMakeLists.txt index ad0a737d59..d27eeca913 100644 --- a/test/lib/usd/translators/CMakeLists.txt +++ b/test/lib/usd/translators/CMakeLists.txt @@ -48,6 +48,7 @@ set(TEST_SCRIPT_FILES # To investigate: following test asserts in TDNshapeEditorManager.cpp, but # passes. PPT, 17-Jun-20. testUsdImportFrameRange.py + testUsdImportFramerates.py testUsdImportInstances.py testUsdImportMayaReference.py testUsdImportMesh.py diff --git a/test/lib/usd/translators/UsdImportFramerates/framerate.usda b/test/lib/usd/translators/UsdImportFramerates/framerate.usda new file mode 100644 index 0000000000..fbd9365536 --- /dev/null +++ b/test/lib/usd/translators/UsdImportFramerates/framerate.usda @@ -0,0 +1,233 @@ +#usda 1.0 +( + defaultPrim = "Root" + endTimeCode = 100 + framesPerSecond = 60 + metersPerUnit = 0.01 + startTimeCode = 1 + timeCodesPerSecond = 60 + upAxis = "Y" +) + +def SkelRoot "Root" ( + kind = "component" +) +{ + def Mesh "Mesh" ( + prepend apiSchemas = ["MaterialBindingAPI"] + ) + { + uniform bool doubleSided = 1 + float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)] + int[] faceVertexCounts = [4, 4, 4, 4, 4, 4] + int[] faceVertexIndices = [0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4] + rel material:binding = + point3f[] points = [(-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5)] + texCoord2f[] primvars:map1 = [(0.375, 0), (0.625, 0), (0.625, 0.25), (0.375, 0.25), (0.625, 0.5), (0.375, 0.5), (0.625, 0.75), (0.375, 0.75), (0.625, 1), (0.375, 1), (0.875, 0), (0.875, 0.25), (0.125, 0), (0.125, 0.25)] ( + interpolation = "faceVarying" + ) + int[] primvars:map1:indices = [0, 1, 2, 3, 3, 2, 4, 5, 5, 4, 6, 7, 7, 6, 8, 9, 1, 10, 11, 2, 12, 0, 3, 13] + double3 xformOp:translate.timeSamples = { + 1: (0, 0, 0), + 20: (1.5980701403722433, 4.643729607962522, -0.5855283680443151), + } + uniform token[] xformOpOrder = ["xformOp:translate"] + } + + def Mesh "Skin" ( + prepend apiSchemas = ["MaterialBindingAPI"] + ) + { + uniform bool doubleSided = 1 + float3[] extent.timeSamples = { + 1: [(-0.9995248, -1.8898486, -0.9357536), (0.99803704, 1.4922572, 2.3230896)], + 20: [(-1.0000002, -1.45, -1.0000005), (1, 1.45, 1.0000001)], + } + int[] faceVertexCounts.timeSamples = { + 1: [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], + } + int[] faceVertexIndices.timeSamples = { + 1: [0, 1, 21, 20, 1, 2, 22, 21, 2, 3, 23, 22, 3, 4, 24, 23, 4, 5, 25, 24, 5, 6, 26, 25, 6, 7, 27, 26, 7, 8, 28, 27, 8, 9, 29, 28, 9, 10, 30, 29, 10, 11, 31, 30, 11, 12, 32, 31, 12, 13, 33, 32, 13, 14, 34, 33, 14, 15, 35, 34, 15, 16, 36, 35, 16, 17, 37, 36, 17, 18, 38, 37, 18, 19, 39, 38, 19, 0, 20, 39, 20, 21, 41, 40, 21, 22, 42, 41, 22, 23, 43, 42, 23, 24, 44, 43, 24, 25, 45, 44, 25, 26, 46, 45, 26, 27, 47, 46, 27, 28, 48, 47, 28, 29, 49, 48, 29, 30, 50, 49, 30, 31, 51, 50, 31, 32, 52, 51, 32, 33, 53, 52, 33, 34, 54, 53, 34, 35, 55, 54, 35, 36, 56, 55, 36, 37, 57, 56, 37, 38, 58, 57, 38, 39, 59, 58, 39, 20, 40, 59, 40, 41, 61, 60, 41, 42, 62, 61, 42, 43, 63, 62, 43, 44, 64, 63, 44, 45, 65, 64, 45, 46, 66, 65, 46, 47, 67, 66, 47, 48, 68, 67, 48, 49, 69, 68, 49, 50, 70, 69, 50, 51, 71, 70, 51, 52, 72, 71, 52, 53, 73, 72, 53, 54, 74, 73, 54, 55, 75, 74, 55, 56, 76, 75, 56, 57, 77, 76, 57, 58, 78, 77, 58, 59, 79, 78, 59, 40, 60, 79, 60, 61, 81, 80, 61, 62, 82, 81, 62, 63, 83, 82, 63, 64, 84, 83, 64, 65, 85, 84, 65, 66, 86, 85, 66, 67, 87, 86, 67, 68, 88, 87, 68, 69, 89, 88, 69, 70, 90, 89, 70, 71, 91, 90, 71, 72, 92, 91, 72, 73, 93, 92, 73, 74, 94, 93, 74, 75, 95, 94, 75, 76, 96, 95, 76, 77, 97, 96, 77, 78, 98, 97, 78, 79, 99, 98, 79, 60, 80, 99, 1, 0, 100, 2, 1, 100, 3, 2, 100, 4, 3, 100, 5, 4, 100, 6, 5, 100, 7, 6, 100, 8, 7, 100, 9, 8, 100, 10, 9, 100, 11, 10, 100, 12, 11, 100, 13, 12, 100, 14, 13, 100, 15, 14, 100, 16, 15, 100, 17, 16, 100, 18, 17, 100, 19, 18, 100, 0, 19, 100, 80, 81, 101, 81, 82, 101, 82, 83, 101, 83, 84, 101, 84, 85, 101, 85, 86, 101, 86, 87, 101, 87, 88, 101, 88, 89, 101, 89, 90, 101, 90, 91, 101, 91, 92, 101, 92, 93, 101, 93, 94, 101, 94, 95, 101, 95, 96, 101, 96, 97, 101, 97, 98, 101, 98, 99, 101, 99, 80, 101], + } + rel material:binding = + point3f[] points.timeSamples = { + 1: [(0.95121205, -1.2827566, -0.33868772), (0.8109708, -1.1556907, -0.57971567), (0.5909718, -1.0573795, -0.7712517), (0.31279483, -0.99726266, -0.89416695), (0.0038060471, -0.98050004, -0.9357536), (-0.30557916, -1.0077474, -0.89121836), (-0.58494, -1.0755004, -0.7644283), (-0.8068743, -1.1767787, -0.5677242), (-0.94969255, -1.3019316, -0.32074493), (-0.9995248, -1.439457, -0.04836974), (-0.95164293, -1.5768348, 0.22197643), (-0.810876, -1.7014002, 0.46330944), (-0.5910869, -1.8012894, 0.65195215), (-0.3137774, -1.8664747, 0.7698841), (-0.0059798006, -1.8898486, 0.80631685), (0.3023493, -1.8682077, 0.7584328), (0.58119243, -1.8029126, 0.63136667), (0.8033411, -1.700026, 0.43755013), (0.94702154, -1.5698286, 0.19552164), (0.99803704, -1.4257369, -0.071713924), (0.9513702, -0.59505, -0.034316454), (0.81301236, -0.44570804, -0.26182428), (0.594404, -0.32906672, -0.4439194), (0.31700712, -0.25669068, -0.56235063), (0.008205583, -0.23504949, -0.60471), (-0.30146912, -0.26498678, -0.5658776), (-0.5814453, -0.3421074, -0.4489018), (-0.80419874, -0.45791635, -0.26510227), (-0.9479837, -0.60121, -0.033139773), (-0.99893546, -0.75916094, 0.22306152), (-0.95235324, -0.9179386, 0.47725797), (-0.8130597, -1.0632299, 0.70403814), (-0.5948305, -1.1811414, 0.8815112), (-0.31898606, -1.2595876, 0.99321), (-0.012313621, -1.2898511, 1.0292447), (0.29547366, -1.2678747, 0.9868592), (0.57452494, -1.1949925, 0.87047964), (0.7976638, -1.0779865, 0.6912638), (0.942994, -0.92847985, 0.46614143), (0.99606407, -0.7617455, 0.21636978), (0.951784, -0.0004124162, 0.38286403), (0.81838083, 0.17196903, 0.16715276), (0.6034724, 0.3108376, -0.0065465886), (0.3281802, 0.40220046, -0.12075875), (0.01990182, 0.43696702, -0.16383636), (-0.29053625, 0.41190833, -0.13128743), (-0.57215434, 0.32991064, -0.026331449), (-0.7970911, 0.19952027, 0.14042671), (-0.9434451, 0.033900715, 0.3521676), (-0.9973693, -0.15060961, 0.5876969), (-0.9542424, -0.3361441, 0.8236995), (-0.81886774, -0.50498354, 1.0371237), (-0.60477304, -0.6411186, 1.2074214), (-0.33277562, -0.7316102, 1.3184222), (-0.029006967, -0.7677041, 1.3597142), (0.2774405, -0.7456575, 1.3274878), (0.55711126, -0.6671976, 1.2248309), (0.7828756, -0.53952134, 1.0614636), (0.9325087, -0.37476528, 0.8529157), (0.9909189, -0.18894213, 0.61917126), (0.9538355, 0.4591557, 0.9535357), (0.8464653, 0.65810746, 0.75189996), (0.6543427, 0.8262871, 0.585177), (0.3961656, 0.946698, 0.47008887), (0.097468615, 1.0066881, 0.4180448), (-0.2118607, 0.99946165, 0.43388078), (-0.5006992, 0.925191, 0.51537776), (-0.7401489, 0.79140663, 0.65371484), (-0.9067899, 0.6122742, 0.834778), (-0.9850478, 0.40666747, 1.0409192), (-0.9682997, 0.1955539, 1.2526674), (-0.8589224, -0.00047048926, 1.4502103), (-0.6677338, -0.1630171, 1.6148396), (-0.4130203, -0.2771943, 1.7305505), (-0.11905555, -0.33261362, 1.7856858), (0.18598585, -0.32419583, 1.7743031), (0.47261977, -0.2526685, 1.6969799), (0.71288854, -0.12460869, 1.5609043), (0.8831197, 0.048049252, 1.3792408), (0.96630263, 0.24902812, 1.1698549), (0.9559311, 0.844115, 1.6122084), (0.8757925, 1.0630534, 1.4218118), (0.7090706, 1.253635, 1.2584662), (0.47204223, 1.3972597, 1.1378459), (0.18769544, 1.4796348, 1.0712991), (-0.116440274, 1.4922572, 1.0649198), (-0.41086754, 1.4334162, 1.1191248), (-0.66689986, 1.3085489, 1.2286958), (-0.8594195, 1.1298344, 1.3832488), (-0.9693599, 0.91501826, 1.5681118), (-0.9856558, 0.68558097, 1.7655869), (-0.90644145, 0.4644615, 1.9565346), (-0.73933953, 0.27362055, 2.1221752), (-0.5007685, 0.13176288, 2.2459602), (-0.21430954, 0.052501507, 2.3153243), (0.09169504, 0.043142, 2.3230896), (0.3870342, 0.10414814, 2.2683136), (0.6426793, 0.22926371, 2.1564426), (0.83366406, 0.40622053, 1.9987419), (0.9415041, 0.61793965, 1.811077), (-1.0931747e-7, -1.4693322, -0.008169735), (-0.015418277, 0.7425677, 1.7173107)], + 20: [(0.95105714, -1.45, -0.30901718), (0.80901754, -1.45, -0.5877856), (0.5877856, -1.45, -0.8090175), (0.30901715, -1.45, -0.951057), (1.3422307e-19, -1.45, -1.0000005), (-0.30901715, -1.45, -0.95105696), (-0.5877855, -1.45, -0.8090173), (-0.80901724, -1.45, -0.5877854), (-0.9510568, -1.45, -0.30901706), (-1.0000002, -1.45, 6.887075e-18), (-0.9510568, -1.45, 0.30901706), (-0.8090172, -1.45, 0.58778536), (-0.58778536, -1.45, 0.8090171), (-0.30901706, -1.45, 0.95105666), (-2.9802322e-8, -1.45, 1.0000001), (0.30901697, -1.45, 0.9510566), (0.58778524, -1.45, 0.80901706), (0.809017, -1.45, 0.5877853), (0.95105654, -1.45, 0.309017), (1, -1.45, 6.830225e-18), (0.95105714, -0.725, -0.30901718), (0.80901754, -0.725, -0.5877856), (0.5877856, -0.725, -0.8090175), (0.30901715, -0.725, -0.951057), (2.8937595e-19, -0.725, -1.0000005), (-0.30901715, -0.725, -0.95105696), (-0.5877855, -0.725, -0.8090173), (-0.80901724, -0.725, -0.5877854), (-0.9510568, -0.725, -0.30901706), (-1.0000002, -0.725, 6.8228463e-18), (-0.9510568, -0.725, 0.30901706), (-0.8090172, -0.725, 0.58778536), (-0.58778536, -0.725, 0.8090171), (-0.30901706, -0.725, 0.95105666), (-2.9802322e-8, -0.725, 1.0000001), (0.30901697, -0.725, 0.9510566), (0.58778524, -0.725, 0.80901706), (0.809017, -0.725, 0.5877853), (0.95105654, -0.725, 0.309017), (1, -0.725, 6.7210054e-18), (0.95105714, -1.0329599e-16, -0.30901718), (0.80901754, -1.0373147e-16, -0.5877856), (0.5877856, -1.0426817e-16, -0.8090175), (0.30901715, -1.0485592e-16, -0.951057), (7.018524e-19, -1.05436226e-16, -1.0000005), (-0.30901715, -1.05948846e-16, -0.95105696), (-0.5877855, -1.0633995e-16, -0.8090173), (-0.80901724, -1.06569126e-16, -0.5877854), (-0.9510568, -1.0661339e-16, -0.30901706), (-1.0000002, -1.0646838e-16, 6.652159e-18), (-0.9510568, -1.0614848e-16, 0.30901706), (-0.8090172, -1.0568629e-16, 0.58778536), (-0.58778536, -1.0513014e-16, 0.8090171), (-0.30901706, -1.04538285e-16, 0.95105666), (-2.9802322e-8, -1.03971005e-16, 1.0000001), (0.30901697, -1.03482995e-16, 0.9510566), (0.58778524, -1.0311813e-16, 0.80901706), (0.809017, -1.0290702e-16, 0.5877853), (0.95105654, -1.0286646e-16, 0.309017), (1, -1.029996e-16, 6.4361736e-18), (0.95105714, 0.725, -0.30901718), (0.80901754, 0.725, -0.5877856), (0.5877856, 0.725, -0.8090175), (0.30901715, 0.725, -0.951057), (3.437303e-18, 0.725, -1.0000005), (-0.30901715, 0.725, -0.95105696), (-0.5877855, 0.725, -0.8090173), (-0.80901724, 0.725, -0.5877854), (-0.9510568, 0.725, -0.30901706), (-1.0000002, 0.725, 5.309284e-18), (-0.9510568, 0.725, 0.30901706), (-0.8090172, 0.725, 0.58778536), (-0.58778536, 0.725, 0.8090171), (-0.30901706, 0.725, 0.95105666), (-2.9802322e-8, 0.725, 1.0000001), (0.30901697, 0.725, 0.9510566), (0.58778524, 0.725, 0.80901706), (0.809017, 0.725, 0.5877853), (0.95105654, 0.725, 0.309017), (1, 0.725, 5.073443e-18), (0.95105714, 1.45, -0.30901718), (0.80901754, 1.45, -0.5877856), (0.5877856, 1.45, -0.8090175), (0.30901715, 1.45, -0.951057), (6.6192188e-18, 1.45, -1.0000005), (-0.30901715, 1.45, -0.95105696), (-0.5877855, 1.45, -0.8090173), (-0.80901724, 1.45, -0.5877854), (-0.9510568, 1.45, -0.30901706), (-1.0000002, 1.45, 3.5995145e-18), (-0.9510568, 1.45, 0.30901706), (-0.8090172, 1.45, 0.58778536), (-0.58778536, 1.45, 0.8090171), (-0.30901706, 1.45, 0.95105666), (-2.9802322e-8, 1.45, 1.0000001), (0.30901697, 1.45, 0.9510566), (0.58778524, 1.45, 0.80901706), (0.809017, 1.45, 0.5877853), (0.95105654, 1.45, 0.309017), (1, 1.45, 3.7006224e-18), (4.919527e-23, -1.45, 6.9388695e-18), (6.9385643e-18, 1.45, 3.4696116e-18)], + } + texCoord2f[] primvars:map1 ( + interpolation = "faceVarying" + ) + texCoord2f[] primvars:map1.timeSamples = { + 1: [(0.375, 0.3125), (0.3875, 0.3125), (0.3875, 0.40648496), (0.375, 0.40648496), (0.39999998, 0.3125), (0.39999998, 0.40648496), (0.41249996, 0.3125), (0.41249996, 0.40648496), (0.42499995, 0.3125), (0.42499995, 0.40648496), (0.43749994, 0.3125), (0.43749994, 0.40648496), (0.44999993, 0.3125), (0.44999993, 0.40648496), (0.46249992, 0.3125), (0.46249992, 0.40648496), (0.4749999, 0.3125), (0.4749999, 0.40648496), (0.4874999, 0.3125), (0.4874999, 0.40648496), (0.49999988, 0.3125), (0.49999988, 0.40648496), (0.51249987, 0.3125), (0.51249987, 0.40648496), (0.52499986, 0.3125), (0.52499986, 0.40648496), (0.53749985, 0.3125), (0.53749985, 0.40648496), (0.54999983, 0.3125), (0.54999983, 0.40648496), (0.5624998, 0.3125), (0.5624998, 0.40648496), (0.5749998, 0.3125), (0.5749998, 0.40648496), (0.5874998, 0.3125), (0.5874998, 0.40648496), (0.5999998, 0.3125), (0.5999998, 0.40648496), (0.6124998, 0.3125), (0.6124998, 0.40648496), (0.62499976, 0.3125), (0.62499976, 0.40648496), (0.3875, 0.5004699), (0.375, 0.5004699), (0.39999998, 0.5004699), (0.41249996, 0.5004699), (0.42499995, 0.5004699), (0.43749994, 0.5004699), (0.44999993, 0.5004699), (0.46249992, 0.5004699), (0.4749999, 0.5004699), (0.4874999, 0.5004699), (0.49999988, 0.5004699), (0.51249987, 0.5004699), (0.52499986, 0.5004699), (0.53749985, 0.5004699), (0.54999983, 0.5004699), (0.5624998, 0.5004699), (0.5749998, 0.5004699), (0.5874998, 0.5004699), (0.5999998, 0.5004699), (0.6124998, 0.5004699), (0.62499976, 0.5004699), (0.3875, 0.5944549), (0.375, 0.5944549), (0.39999998, 0.5944549), (0.41249996, 0.5944549), (0.42499995, 0.5944549), (0.43749994, 0.5944549), (0.44999993, 0.5944549), (0.46249992, 0.5944549), (0.4749999, 0.5944549), (0.4874999, 0.5944549), (0.49999988, 0.5944549), (0.51249987, 0.5944549), (0.52499986, 0.5944549), (0.53749985, 0.5944549), (0.54999983, 0.5944549), (0.5624998, 0.5944549), (0.5749998, 0.5944549), (0.5874998, 0.5944549), (0.5999998, 0.5944549), (0.6124998, 0.5944549), (0.62499976, 0.5944549), (0.3875, 0.68843985), (0.375, 0.68843985), (0.39999998, 0.68843985), (0.41249996, 0.68843985), (0.42499995, 0.68843985), (0.43749994, 0.68843985), (0.44999993, 0.68843985), (0.46249992, 0.68843985), (0.4749999, 0.68843985), (0.4874999, 0.68843985), (0.49999988, 0.68843985), (0.51249987, 0.68843985), (0.52499986, 0.68843985), (0.53749985, 0.68843985), (0.54999983, 0.68843985), (0.5624998, 0.68843985), (0.5749998, 0.68843985), (0.5874998, 0.68843985), (0.5999998, 0.68843985), (0.6124998, 0.68843985), (0.62499976, 0.68843985), (0.626409, 0.064408496), (0.64860266, 0.10796607), (0.5, 0.15), (0.5918415, 0.02984102), (0.54828393, 0.0076473355), (0.5, -7.4505806e-8), (0.45171607, 0.0076473504), (0.4081585, 0.02984105), (0.37359107, 0.064408526), (0.3513974, 0.1079661), (0.34374997, 0.15625), (0.3513974, 0.2045339), (0.37359107, 0.24809146), (0.40815854, 0.28265893), (0.4517161, 0.3048526), (0.5, 0.3125), (0.5482839, 0.3048526), (0.59184146, 0.28265893), (0.62640893, 0.24809146), (0.6486026, 0.2045339), (0.65625, 0.15625), (0.6486026, 0.89203393), (0.62640893, 0.93559146), (0.5, 0.8375), (0.59184146, 0.97015893), (0.5482839, 0.9923526), (0.5, 1), (0.4517161, 0.9923526), (0.40815854, 0.97015893), (0.37359107, 0.93559146), (0.3513974, 0.89203393), (0.34374997, 0.84375), (0.3513974, 0.79546607), (0.37359107, 0.75190854), (0.4081585, 0.71734107), (0.45171607, 0.69514734), (0.5, 0.68749994), (0.54828393, 0.69514734), (0.5918415, 0.717341), (0.626409, 0.7519085), (0.64860266, 0.79546607), (0.65625, 0.84375)], + } + int[] primvars:map1:indices.timeSamples = { + 1: [0, 1, 2, 3, 1, 4, 5, 2, 4, 6, 7, 5, 6, 8, 9, 7, 8, 10, 11, 9, 10, 12, 13, 11, 12, 14, 15, 13, 14, 16, 17, 15, 16, 18, 19, 17, 18, 20, 21, 19, 20, 22, 23, 21, 22, 24, 25, 23, 24, 26, 27, 25, 26, 28, 29, 27, 28, 30, 31, 29, 30, 32, 33, 31, 32, 34, 35, 33, 34, 36, 37, 35, 36, 38, 39, 37, 38, 40, 41, 39, 3, 2, 42, 43, 2, 5, 44, 42, 5, 7, 45, 44, 7, 9, 46, 45, 9, 11, 47, 46, 11, 13, 48, 47, 13, 15, 49, 48, 15, 17, 50, 49, 17, 19, 51, 50, 19, 21, 52, 51, 21, 23, 53, 52, 23, 25, 54, 53, 25, 27, 55, 54, 27, 29, 56, 55, 29, 31, 57, 56, 31, 33, 58, 57, 33, 35, 59, 58, 35, 37, 60, 59, 37, 39, 61, 60, 39, 41, 62, 61, 43, 42, 63, 64, 42, 44, 65, 63, 44, 45, 66, 65, 45, 46, 67, 66, 46, 47, 68, 67, 47, 48, 69, 68, 48, 49, 70, 69, 49, 50, 71, 70, 50, 51, 72, 71, 51, 52, 73, 72, 52, 53, 74, 73, 53, 54, 75, 74, 54, 55, 76, 75, 55, 56, 77, 76, 56, 57, 78, 77, 57, 58, 79, 78, 58, 59, 80, 79, 59, 60, 81, 80, 60, 61, 82, 81, 61, 62, 83, 82, 64, 63, 84, 85, 63, 65, 86, 84, 65, 66, 87, 86, 66, 67, 88, 87, 67, 68, 89, 88, 68, 69, 90, 89, 69, 70, 91, 90, 70, 71, 92, 91, 71, 72, 93, 92, 72, 73, 94, 93, 73, 74, 95, 94, 74, 75, 96, 95, 75, 76, 97, 96, 76, 77, 98, 97, 77, 78, 99, 98, 78, 79, 100, 99, 79, 80, 101, 100, 80, 81, 102, 101, 81, 82, 103, 102, 82, 83, 104, 103, 105, 106, 107, 108, 105, 107, 109, 108, 107, 110, 109, 107, 111, 110, 107, 112, 111, 107, 113, 112, 107, 114, 113, 107, 115, 114, 107, 116, 115, 107, 117, 116, 107, 118, 117, 107, 119, 118, 107, 120, 119, 107, 121, 120, 107, 122, 121, 107, 123, 122, 107, 124, 123, 107, 125, 124, 107, 106, 125, 107, 126, 127, 128, 127, 129, 128, 129, 130, 128, 130, 131, 128, 131, 132, 128, 132, 133, 128, 133, 134, 128, 134, 135, 128, 135, 136, 128, 136, 137, 128, 137, 138, 128, 138, 139, 128, 139, 140, 128, 140, 141, 128, 141, 142, 128, 142, 143, 128, 143, 144, 128, 144, 145, 128, 145, 146, 128, 146, 126, 128], + } + } + + def Skeleton "joint1" ( + prepend apiSchemas = ["SkelBindingAPI"] + customData = { + dictionary Maya = { + bool generated = 1 + } + } + ) + { + uniform matrix4d[] bindTransforms = [( (2.220446049250313e-16, 1.0000000000000002, 0, 0), (-1.0000000000000002, 2.220446049250313e-16, 0, 0), (0, 0, 1, 0), (-0.11293683886508588, -1.4413938753959858, -0.04751847940888014, 1) ), ( (2.220446049250313e-16, 1.0000000000000002, 0, 0), (-1.0000000000000002, 2.220446049250313e-16, 0, 0), (0, 0, 1, 0), (-0.11293683886508588, 0.015839493136218685, -0.04751847940888014, 1) ), ( (1.0000000000000004, 0, 0, 0), (0, 1.0000000000000004, 0, 0), (0, 0, 1, 0), (-0.11293683886508588, 1.3780359028511082, -0.04751847940888014, 1) )] + uniform token[] joints = ["joint1", "joint1/joint2", "joint1/joint2/joint3"] + uniform matrix4d[] restTransforms = [( (2.220446049250313e-16, 1.0000000000000002, 0, 0), (-1.0000000000000002, 2.220446049250313e-16, 0, 0), (0, 0, 1, 0), (-0.11293683886508588, -1.4413938753959858, -0.04751847940888014, 1) ), ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (1.4572333685322043, 3.2357080759930576e-16, 0, 1) ), ( (2.220446049250313e-16, -1.0000000000000002, -0, 0), (1.0000000000000002, 2.220446049250313e-16, 0, 0), (0, -0, 1, 0), (1.3621964097148893, 3.0246836362543863e-16, 0, 1) )] + rel skel:animationSource = + + def SkelAnimation "Animation" + { + uniform token[] joints = ["joint1", "joint1/joint2", "joint1/joint2/joint3"] + quatf[] rotations = [(0.70710677, 0, 0, 0.70710677), (1, 0, 0, 0), (0.70710677, 0, 0, -0.70710677)] + quatf[] rotations.timeSamples = { + 1: [(0.69019824, 0.15370882, -0.15370882, 0.69019824), (0.9760877, 9.050139e-18, -0.21737708, 2.0154878e-18), (0.69019824, -0.15370882, -0.15370882, -0.69019824)], + 20: [(0.70710677, 0, 0, 0.70710677), (1, 0, 0, 0), (0.70710677, 0, 0, -0.70710677)], + } + half3[] scales = [(1, 1, 1), (1, 1, 1), (1, 1, 1)] + float3[] translations = [(-0.11293684, -1.4413939, -0.04751848), (1.4572333, 3.1918912e-16, 0), (1.3621964, 3.0531133e-16, 0)] + } + } + + def Camera "Cam" + { + float2 clippingRange.timeSamples = { + 1: (0.1, 10000), + 20: (2, 1000), + } + float focalLength.timeSamples = { + 1: 35, + } + float focusDistance.timeSamples = { + 1: 5, + } + float fStop.timeSamples = { + 1: 5.6, + } + float horizontalAperture.timeSamples = { + 1: 35.999928, + } + float verticalAperture.timeSamples = { + 1: 23.999952, + } + float3 xformOp:rotateXYZ = (-36, -70.4, 9.481412e-15) + double3 xformOp:translate.timeSamples = { + 1: (-8.724161577231872, 6.728331046365596, 3.3837117534027286), + 20: (-4.998428407709971, 4.922573886865677, 2.3579697180289685), + } + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"] + } + + def NurbsPatch "Nurbs" ( + prepend apiSchemas = ["MaterialBindingAPI"] + ) + { + uniform bool doubleSided = 1 + float3[] extent.timeSamples = { + 1: [(-0.5, -3.0416434, -0.5), (0.5, -3.0416434, 0.5)], + 20: [(-0.5, -3.061617e-17, -0.5), (0.5, 3.061617e-17, 0.5)], + } + rel material:binding = + point3f[] points.timeSamples = { + 1: [(-0.5, -3.0416434, 0.5), (-0.16666667, -3.0416434, 0.5), (0.16666667, -3.0416434, 0.5), (0.5, -3.0416434, 0.5), (-0.5, -3.0416434, 0.16666667), (-0.16666667, -3.0416434, 0.16666667), (0.16666667, -3.0416434, 0.16666667), (0.5, -3.0416434, 0.16666667), (-0.5, -3.0416434, -0.16666667), (-0.16666667, -3.0416434, -0.16666667), (0.16666667, -3.0416434, -0.16666667), (0.5, -3.0416434, -0.16666667), (-0.5, -3.0416434, -0.5), (-0.16666667, -3.0416434, -0.5), (0.16666667, -3.0416434, -0.5), (0.5, -3.0416434, -0.5)], + 20: [(-0.5, -3.061617e-17, 0.5), (-0.16666667, -3.061617e-17, 0.5), (0.16666667, -3.061617e-17, 0.5), (0.5, -3.061617e-17, 0.5), (-0.5, -1.020539e-17, 0.16666667), (-0.16666667, -1.020539e-17, 0.16666667), (0.16666667, -1.020539e-17, 0.16666667), (0.5, -1.020539e-17, 0.16666667), (-0.5, 1.020539e-17, -0.16666667), (-0.16666667, 1.020539e-17, -0.16666667), (0.16666667, 1.020539e-17, -0.16666667), (0.5, 1.020539e-17, -0.16666667), (-0.5, 3.061617e-17, -0.5), (-0.16666667, 3.061617e-17, -0.5), (0.16666667, 3.061617e-17, -0.5), (0.5, 3.061617e-17, -0.5)], + } + texCoord2f[] primvars:st = [(0, 0), (0.33333334, 0), (0.6666667, 0), (1, 0), (0, 0.33333334), (0.33333334, 0.33333334), (0.6666667, 0.33333334), (1, 0.33333334), (0, 0.6666667), (0.33333334, 0.6666667), (0.6666667, 0.6666667), (1, 0.6666667), (0, 1), (0.33333334, 1), (0.6666667, 1), (1, 1)] ( + interpolation = "vertex" + ) + double[] uKnots = [0, 0, 0, 0, 1, 1, 1, 1] + int uOrder = 4 + double2 uRange = (0, 1) + int uVertexCount = 4 + double[] vKnots = [0, 0, 0, 0, 1, 1, 1, 1] + int vOrder = 4 + double2 vRange = (0, 1) + int vVertexCount = 4 + double3 xformOp:translate = (0, 0, 2.942409163995654) + uniform token[] xformOpOrder = ["xformOp:translate"] + } + + def Skeleton "joint4" ( + prepend apiSchemas = ["SkelBindingAPI"] + customData = { + dictionary Maya = { + bool generated = 1 + } + } + ) + { + uniform matrix4d[] bindTransforms = [( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0.001663775311510074, 0, 2.9241075361563036, 1) )] + uniform token[] joints = ["joint4"] + uniform matrix4d[] restTransforms = [( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0.001663775311510074, 0, 2.9241075361563036, 1) )] + rel skel:animationSource = + + def SkelAnimation "Animation" + { + uniform token[] joints = ["joint4"] + quatf[] rotations = [(1, 0, 0, 0)] + half3[] scales = [(1, 1, 1)] + float3[] translations = [(0.0016637753, 0, 2.9241076)] + float3[] translations.timeSamples = { + 1: [(0.0016637753, -3.0416434, 2.9241076)], + 20: [(0.0016637753, 0, 2.9241076)], + } + } + } + + def NurbsCurves "Curve" + { + int[] curveVertexCounts = [6] + float3[] extent.timeSamples = { + 1: [(-18.89628, -0.5, -8.25107), (11.195379, 0.5, 16.063616)], + 20: [(-18.89628, -5.3799567, -8.25107), (11.195379, -4.3799567, 16.063616)], + } + double[] knots = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3] + int[] order = [4] + point3f[] points.timeSamples = { + 1: [(7.3439097, 0, -3.6761854), (0.96973777, 0, -5.0344806), (-11.778606, 0, -7.7510705), (-18.39628, 0, 12.4583645), (0.9981591, 0, 14.528532), (10.695379, 0, 15.563616)], + 20: [(7.3439097, -4.8799567, -3.6761854), (0.96973777, -4.8799567, -5.0344806), (-11.778606, -4.8799567, -7.7510705), (-18.39628, -4.8799567, 12.4583645), (0.9981591, -4.8799567, 14.528532), (10.695379, -4.8799567, 15.563616)], + } + double2[] ranges = [(0, 3)] + float[] widths = [1] ( + interpolation = "constant" + ) + } + + def Skeleton "joint5" ( + prepend apiSchemas = ["SkelBindingAPI"] + customData = { + dictionary Maya = { + bool generated = 1 + } + } + ) + { + uniform matrix4d[] bindTransforms = [( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )] + uniform token[] joints = ["joint5"] + uniform matrix4d[] restTransforms = [( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (5.766137682263384, 0, 5.187788877710354, 1) )] + rel skel:animationSource = + + def SkelAnimation "Animation" + { + uniform token[] joints = ["joint5"] + quatf[] rotations = [(1, 0, 0, 0)] + half3[] scales = [(1, 1, 1)] + float3[] translations = [(5.7661376, -4.8799567, 5.187789)] + float3[] translations.timeSamples = { + 1: [(5.7661376, 0, 5.187789)], + 20: [(5.7661376, -4.8799567, 5.187789)], + } + } + } + + def Scope "Looks" + { + def Material "initialShadingGroup" + { + } + } +} + diff --git a/test/lib/usd/translators/testUsdImportCamera.py b/test/lib/usd/translators/testUsdImportCamera.py index 5eb02ccf58..76478f4edc 100644 --- a/test/lib/usd/translators/testUsdImportCamera.py +++ b/test/lib/usd/translators/testUsdImportCamera.py @@ -164,9 +164,10 @@ def _GetAnimCurveFnForPlugName(self, depNodeFn, plugName): return animCurveFn def _ValidateAnimValuesAtTimes(self, animCurveFn, expectedTimesToValues): + timeUnit = OpenMaya.MTime.uiUnit() for time in expectedTimesToValues.keys(): expectedValue = expectedTimesToValues[time] - value = animCurveFn.evaluate(OpenMaya.MTime(time)) + value = animCurveFn.evaluate(OpenMaya.MTime(time, timeUnit)) self.assertTrue(Gf.IsClose(expectedValue, value, 1e-6)) def testImportPerspectiveCameraAnimatedTransform(self): diff --git a/test/lib/usd/translators/testUsdImportFramerates.py b/test/lib/usd/translators/testUsdImportFramerates.py new file mode 100644 index 0000000000..062880f753 --- /dev/null +++ b/test/lib/usd/translators/testUsdImportFramerates.py @@ -0,0 +1,110 @@ +#!/pxrpythonsubst + +# +# Copyright 2020 Apple +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from __future__ import division + +import fixturesUtils +import logging +import os +import unittest +from maya import cmds, standalone +from pxr import Usd + + +class testUsdImportFramerates(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls.temp_dir = fixturesUtils.setUpClass(__file__) + cls.usd_file = os.path.join(cls.temp_dir, "UsdImportFramerates/framerate.usda") + cls.stage = Usd.Stage.Open(cls.usd_file) + cls.base_rate = cls.stage.GetTimeCodesPerSecond() + + @classmethod + def tearDownClass(cls): + standalone.uninitialize() + + @classmethod + def getKeyframes(cls, path): + """Get all keyframe values on a prims attributes""" + frames = set() + prim = cls.stage.GetPrimAtPath(path) + attrs = prim.GetAuthoredAttributes() + + for attr in attrs: + samples = attr.GetTimeSamples() + frames.update(samples) + + return sorted(frames) + + def test_framerate_imports(self): + """Test that the USD's timesamples are appropriately + converted to match the Mayas uiUnits""" + + # Only check a few of these since the logic should + # hold up the same no matter what, but + fps_map = { + "ntsc": 30, + "film": 24, + "ntscf": 60 + } + + base_rate = self.stage.GetTimeCodesPerSecond() + start = self.stage.GetStartTimeCode() + end = self.stage.GetEndTimeCode() + + nodes = { + 'Root|joint1': self.getKeyframes("/Root/Skin"), + 'Root|Mesh': self.getKeyframes("/Root/Mesh"), + "blendShape1": self.getKeyframes("/Root/Skin"), # Mesh Anim + "Cam": self.getKeyframes("/Root/Cam"), + # For some reason the clip planes don't identify keys on the Cam Shape directly + "CamShape_nearClipPlane": self.getKeyframes("/Root/Cam"), + "blendShape2": self.getKeyframes("/Root/Nurbs") # Patch anim + } + + # TODO: Add NurbsCurves to the nodes list when the importer supports it + + for name, fps in fps_map.items(): + cmds.file(new=True, force=True) + cmds.currentUnit(time=name) + cmds.playbackOptions(minTime=10) + cmds.playbackOptions(maxTime=20) + + time_scale = (fps / base_rate) + + cmds.mayaUSDImport(f=self.usd_file, readAnimData=True) + + # First make sure the playback slider is set correctly + self.assertAlmostEquals(start * time_scale, cmds.playbackOptions(query=True, minTime=True)) + self.assertAlmostEquals(end * time_scale, cmds.playbackOptions(query=True, maxTime=True)) + + for node, frames in nodes.items(): + mframes = sorted(set(cmds.keyframe(node, query=True))) + + numMFrames = len(mframes) + numFrames = len(frames) + self.assertTrue(numFrames == numMFrames, + "A mismatched number of frames was found {}:{}".format(numFrames, numMFrames)) + + for idx, frame in enumerate(frames): + self.assertAlmostEquals(frame * time_scale, mframes[idx]) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/test/lib/usd/translators/testUsdImportRfMLight.py b/test/lib/usd/translators/testUsdImportRfMLight.py index 140620bd6a..52aaa42261 100644 --- a/test/lib/usd/translators/testUsdImportRfMLight.py +++ b/test/lib/usd/translators/testUsdImportRfMLight.py @@ -169,9 +169,9 @@ def _ValidatePxrDiskLightTransformAnimation(self): self.assertEqual(animObjs.length(), 1) animCurveFn = OpenMayaAnim.MFnAnimCurve(animObjs[0]) - + timeUnit = OpenMaya.MTime.uiUnit() for frame in range(int(self.START_TIMECODE), int(self.END_TIMECODE + 1.0)): - value = animCurveFn.evaluate(OpenMaya.MTime(frame)) + value = animCurveFn.evaluate(OpenMaya.MTime(frame, timeUnit)) self.assertTrue(Gf.IsClose(float(frame), value, 1e-6)) def _ValidatePxrDistantLightAngle(self):