def setUp(self):
        if not hasattr(self, 'setupComplete'):
            self.layerFileNames = [
                'src/Particles_Splash.101.usd', 'src/Particles_Splash.102.usd',
                'src/Particles_Splash.103.usd', 'src/Particles_Splash.104.usd',
                'src/Particles_Splash.105.usd', 'src/Particles_Splash.106.usd',
                'src/Particles_Splash.107.usd', 'src/Particles_Splash.108.usd',
                'src/PTS_dev.1.usd', 'src/PTS_dev.2.usd', 'src/PTS_dev.3.usd',
                'src/PTS_dev.4.usd', 'src/PTS_dev.5.usd', 'src/PTS_dev.6.usd',
                'src/PTS_dev.7.usd', 'src/PTS_dev.8.usd', 'src/PTS_dev.9.usd',
                'src/PTS_dev.10.usd', 'src/PTS_dev.11.usd',
                'src/PTS_dev.12.usd', 'src/PTS_dev.13.usd',
                'src/PTS_dev.14.usd', 'src/PTS_dev.15.usd',
                'src/PTS_dev.16.usd', 'src/PTS_dev.17.usd',
                'src/PTS_dev.18.usd', 'src/PTS_dev.19.usd',
                'src/PTS_dev.20.usd', 'src/PTS_dev.21.usd',
                'src/PTS_dev.22.usd', 'src/PTS_dev.23.usd',
                'src/PTS_dev.24.usd'
            ]

            self.clipPath = Sdf.Path('/World/fx/Particles_Splash')
            self.baseName = 'testModelClips.usd'
            self.startTimeCode = 101
            self.endTimeCode = 108
            rootLayer = Sdf.Layer.FindOrOpen(self.baseName)
            self.rootLayer = rootLayer if rootLayer else Sdf.Layer.CreateNew(
                self.baseName)
            UsdUtils.StitchClips(self.rootLayer, self.layerFileNames[0:7],
                                 self.clipPath, self.startTimeCode,
                                 self.endTimeCode)

        self.setupComplete = True
    def test_ExplicitEndCodes(self):
        start = 104
        end = 105
        resultLayer = Sdf.Layer.CreateNew('explicitEndCodes.usd')
        UsdUtils.StitchClips(resultLayer, self.layerFileNames[:7],
                             self.clipPath, start, end)

        self.assertEqual(resultLayer.startTimeCode, start)
        self.assertEqual(resultLayer.endTimeCode, end)
 def test_NumericalPrecisionLoss(self):
     rootLayerFile = 'numericalPrecision.usd'
     clipPath = Sdf.Path("/World/fx/points")
     rootLayer = Sdf.Layer.CreateNew(rootLayerFile)
     UsdUtils.StitchClips(rootLayer, self.layerFileNames[8:], clipPath)
     self.assertTrue(rootLayer)
     self.assertEqual(rootLayer.startTimeCode, 1.00000)
     # previously, the precision error was causing
     # us to end up with an end frame of 24.0006
     self.assertEqual(rootLayer.endTimeCode, 24.000000)
Example #4
0
    def test_TopologySublayerAuthoring(self):
        resultLayer = Sdf.Layer.CreateNew('sublayerTopology.usd')
        UsdUtils.StitchClips(resultLayer, self.layerFileNames[:7], self.clipPath)

        self.assertEqual(list(resultLayer.subLayerPaths), 
                         ['./sublayerTopology.topology.usd'])
        
        resultLayer = Sdf.Layer.CreateNew('foo.usd')
        topLayer = Sdf.Layer.CreateNew('foo.topology.usd')
        UsdUtils.StitchClipsTemplate(resultLayer, topLayer, self.clipPath,
                                     'asset.#.usd', 101, 120, 1)
        self.assertEqual(list(resultLayer.subLayerPaths), 
                         ['./foo.topology.usd'])
Example #5
0
 def test_FilePermissions(self):
     import os
     from pxr import Tf
     rootLayerFile = 'permissions.usd'
     clipPath = Sdf.Path('/World/fx/points')
     rootLayer = Sdf.Layer.CreateNew(rootLayerFile)
     os.system('chmod -w ' + rootLayerFile)
     try:
         UsdUtils.StitchClips(rootLayer, self.layerFileNames, clipPath)
     except Tf.ErrorException as tfError:
         print "Caught expected exception %s" % tfError
     else:
         self.assertTrue(
             False, "Failed to raise runtime error on unwritable file.")
     finally:
         os.system('chmod +w ' + rootLayerFile)
Example #6
0
 def test_FilePermissions(self):
     import os, stat
     from pxr import Tf
     rootLayerFile = 'permissions.usd'
     clipPath = Sdf.Path('/World/fx/points')
     rootLayer = Sdf.Layer.CreateNew(rootLayerFile)
     mode = stat.S_IMODE(os.stat(rootLayerFile).st_mode)
     os.chmod(rootLayerFile,
              mode & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
     try:
         UsdUtils.StitchClips(rootLayer, self.layerFileNames, clipPath)
     except Tf.ErrorException as tfError:
         print "Caught expected exception %s" %tfError
     else:
         self.assertTrue(False, "Failed to raise runtime error on unwritable file." )
     finally:
         os.chmod(rootLayerFile, mode)
Example #7
0
    def test_RelativeAssetPaths(self):
        import os
        rootLayerFile = 'relativePaths.usd'
        if os.path.isfile(rootLayerFile):
            os.remove(rootLayerFile)

        rootLayer = Sdf.Layer.CreateNew(rootLayerFile)
        self.assertTrue(rootLayer)

        localLayerNames = [os.path.relpath(i, os.getcwd()) 
                           for i in self.layerFileNames]

        UsdUtils.StitchClips(rootLayer, localLayerNames, self.clipPath)
        assetPaths = (
            rootLayer.GetPrimAtPath(self.clipPath).GetInfo('clipAssetPaths'))

        # ensure all paths are relative
        import itertools
        self.assertTrue(not any([os.path.isabs(i.path) for i in assetPaths]))
Example #8
0
        def _checkMissingTemplateArg(argName, argValue):
            if not argValue:
                raise Tf.ErrorException('Error: %s must be specified '
                                        'when --templateMetadata is' % argName)

        _checkMissingTemplateArg('templatePath', results.templatePath)
        _checkMissingTemplateArg('endTimeCode', results.endTimeCode)
        _checkMissingTemplateArg('startTimeCode', results.startTimeCode)
        _checkMissingTemplateArg('stride', results.stride)

        UsdUtils.StitchClipsTopology(topologyLayer, results.usdFiles)
        UsdUtils.StitchClipsTemplate(outLayer, topologyLayer, results.clipPath,
                                     results.templatePath,
                                     results.startTimeCode,
                                     results.endTimeCode, results.stride)
    else:
        UsdUtils.StitchClips(outLayer, results.usdFiles, results.clipPath,
                             results.startTimeCode, results.endTimeCode)

    if not results.noComment:
        outLayer.comment = 'Generated with ' + ' '.join(sys.argv)
        outLayer.Save()

except Tf.ErrorException as e:
    # if something in the authoring fails, remove the output file
    if outLayerGenerated and os.path.isfile(results.out):
        os.remove(results.out)
    if topologyLayerGenerated and os.path.isfile(topologyLayerName):
        os.remove(topologyLayerName)
    sys.exit(e)
    def test_CustomSetName(self):
        """ Test authoring with a custom set name 'bob' """
        # template case
        resultLayer = Sdf.Layer.CreateNew('customSetName.usd')
        topLayer = Sdf.Layer.CreateNew('customSetName.topology.usd')
        UsdUtils.StitchClipsTemplate(resultLayer, topLayer, self.clipPath,
                                     'asset.#.usd', 101, 120, 1, 0.3, 'bob')
        self.assertEqual(list(resultLayer.subLayerPaths),
                         ['./customSetName.topology.usd'])
        self.assertEqual(resultLayer.endTimeCode, 120)
        self.assertEqual(resultLayer.startTimeCode, 101)

        prim = resultLayer.GetPrimAtPath('/World/fx/Particles_Splash')
        self.assertTrue('clips' in prim.GetMetaDataInfoKeys())
        expectedValues = {
            'templateStartTime': 101.0,
            'templateStride': 1.0,
            'templateActiveOffset': 0.3,
            'primPath': '/World/fx/Particles_Splash',
            'templateAssetPath': 'asset.#.usd',
            'templateEndTime': 120.0
        }

        # Ensure that our custom set name applied
        actualValues = prim.GetInfo('clips')['bob']
        self.assertTrue(actualValues is not None)

        # Ensure all of our values were written out
        for k in [
                'templateStartTime', 'templateStride', 'templateEndTime',
                'primPath', 'templateAssetPath'
        ]:
            self.assertEqual(expectedValues[k], actualValues[k])

        # non template case
        resultLayer = Sdf.Layer.CreateNew('customSetNameNonTemplate.usd')
        UsdUtils.StitchClips(resultLayer,
                             self.layerFileNames[:7],
                             self.clipPath,
                             clipSet='bob')

        self.assertEqual(resultLayer.startTimeCode, 101)
        self.assertEqual(resultLayer.endTimeCode, 107)
        self.assertEqual(list(resultLayer.subLayerPaths),
                         ['./customSetNameNonTemplate.topology.usd'])

        prim = resultLayer.GetPrimAtPath('/World/fx/Particles_Splash')
        expectedValues = {
            'active':
            Vt.Vec2dArray([(101.0, 0.0), (102.0, 1.0), (103.0, 2.0),
                           (104.0, 3.0), (105.0, 4.0), (106.0, 5.0),
                           (107.0, 6.0)]),
            'times':
            Vt.Vec2dArray([(101.0, 101.0), (102.0, 102.0), (103.0, 103.0),
                           (104.0, 104.0), (105.0, 105.0), (106.0, 106.0),
                           (107.0, 107.0)]),
            'manifestAssetPath':
            Sdf.AssetPath('./customSetNameNonTemplate.topology.usd'),
            'assetPaths':
            Sdf.AssetPathArray([
                Sdf.AssetPath('./src/Particles_Splash.101.usd'),
                Sdf.AssetPath('./src/Particles_Splash.102.usd'),
                Sdf.AssetPath('./src/Particles_Splash.103.usd'),
                Sdf.AssetPath('./src/Particles_Splash.104.usd'),
                Sdf.AssetPath('./src/Particles_Splash.105.usd'),
                Sdf.AssetPath('./src/Particles_Splash.106.usd'),
                Sdf.AssetPath('./src/Particles_Splash.107.usd')
            ]),
            'primPath':
            '/World/fx/Particles_Splash'
        }

        # Ensure that our custom set name applied
        actualValues = prim.GetInfo('clips')['bob']
        self.assertTrue(actualValues is not None)

        # Ensure all of our values were written out
        for k in [
                'active', 'times', 'manifestAssetPath', 'primPath',
                'assetPaths'
        ]:
            self.assertEqual(expectedValues[k], actualValues[k])
Example #10
0
            results.startTimeCode, results.endTimeCode, results.stride,
            results.activeOffset, results.interpolateMissingClipValues,
            results.clipSet)
    else:
        if results.templatePath:
            raise Tf.ErrorException('Error: templatePath cannot be specified '
                                    'without --templateMetadata')
        if results.activeOffset:
            raise Tf.ErrorException('Error: activeOffset cannot be specified '
                                    'without --templateMetadata')
        if results.stride:
            raise Tf.ErrorException('Error: stride cannot be specified '
                                    'without --templateMetadata')

        UsdUtils.StitchClips(outLayer, results.usdFiles, results.clipPath,
                             results.startTimeCode, results.endTimeCode,
                             results.interpolateMissingClipValues,
                             results.clipSet)

    if not results.noComment:
        outLayer.comment = 'Generated with ' + ' '.join(sys.argv)
        outLayer.Save()

except Tf.ErrorException as e:
    # if something in the authoring fails, remove the output file
    if outLayerGenerated and os.path.isfile(results.out):
        os.remove(results.out)
    if topologyLayerGenerated and os.path.isfile(topologyLayerName):
        os.remove(topologyLayerName)
    sys.exit(e)
Example #11
0
    def testExportAsClip(self):
        """
        Test that a maya scene exports to usd the same way if it is exported
        all at once, or in 5 frame clips and then stitched back together.
        """
        # generate clip files and validate num samples on points attribute
        clipFiles = []
        # first 5 frames have no animation
        usdFile = os.path.abspath('UsdExportAsClip_cube.001.usda')
        clipFiles.append(usdFile)
        cmds.usdExport(mergeTransformAndShape=True,
                       file=usdFile,
                       frameRange=(1, 5))
        stage = Usd.Stage.Open(usdFile)
        self._ValidateNumSamples(stage, '/world/pCube1', 'points', 1)

        # next 5 frames have no animation
        usdFile = os.path.abspath('UsdExportAsClip_cube.005.usda')
        clipFiles.append(usdFile)
        cmds.usdExport(mergeTransformAndShape=True,
                       file=usdFile,
                       frameRange=(5, 10))
        stage = Usd.Stage.Open(usdFile)
        self._ValidateNumSamples(stage, '/world/pCube1', 'points', 1)

        # next 5 frames have deformation animation
        usdFile = os.path.abspath('UsdExportAsClip_cube.010.usda')
        clipFiles.append(usdFile)
        frames = (10, 15)
        cmds.usdExport(mergeTransformAndShape=True,
                       file=usdFile,
                       frameRange=frames)
        stage = Usd.Stage.Open(usdFile)
        self._ValidateNumSamples(stage, '/world/pCube1', 'points',
                                 frames[1] + 1 - frames[0])

        # next 5 frames have no animation
        usdFile = os.path.abspath('UsdExportAsClip_cube.015.usda')
        clipFiles.append(usdFile)
        cmds.usdExport(mergeTransformAndShape=True,
                       file=usdFile,
                       frameRange=(15, 20))
        stage = Usd.Stage.Open(usdFile)
        self._ValidateNumSamples(stage, '/world/pCube1', 'points', 1)

        stitchedPath = os.path.abspath('result.usda')
        stitchedLayer = Sdf.Layer.CreateNew(stitchedPath)
        UsdUtils.StitchClips(stitchedLayer, clipFiles, '/world', 1, 20,
                             'default')

        # export a non clip version for comparison
        canonicalUsdFile = os.path.abspath('canonical.usda')
        cmds.usdExport(mergeTransformAndShape=True,
                       file=canonicalUsdFile,
                       frameRange=(1, 20))

        print 'comparing: \nnormal: {}\nstitched: {}'.format(
            canonicalUsdFile, stitchedPath)
        canonicalStage = Usd.Stage.Open(canonicalUsdFile)
        clipsStage = Usd.Stage.Open(stitchedPath)
        # visible
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube1',
                              'visibility', (0, 21))
        # animated visibility
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube2',
                              'visibility', (0, 21))
        # hidden, non animated:
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube4',
                              'visibility', (0, 21))
        # constant points:
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube2',
                              'points', (0, 21))
        # blend shape driven animated points:
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube3',
                              'points', (0, 21))
        # animated points:
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube1',
                              'points', (0, 21))
Example #12
0
                         usd file was generated''')
results = parser.parse_args()

# verify the integrity of the inputs
assert results.out is not None, "must specify output file(--out)"
assert results.clipPath is not None, "must specify a clip path(--clipPath)"
assert results.usdFiles is not None, "must specify clip files"

if os.path.isfile(results.out):
    print "Warning: merging with current result layer"

try:
    outLayer = Sdf.Layer.FindOrOpen(results.out)
    if not outLayer:
        outLayer = Sdf.Layer.CreateNew(results.out)

    if results.startTimeCode:
        results.startTimeCode = float(results.startTimeCode)

    UsdUtils.StitchClips(outLayer, results.usdFiles, results.clipPath,
                         results.reuseExistingTopology, results.startTimeCode)

    if not results.noComment:
        outLayer.comment = 'Generated with ' + ' '.join(sys.argv)
        outLayer.Save()

# if something in the authoring fails, remove the output file
except Tf.ErrorException as e:
    print e
    sys.exit(1)
    def testExportAsClip(self):
        """
        Test that a maya scene exports to usd the same way if it is exported
        all at once, or in 5 frame clips and then stitched back together.
        """
        # generate clip files and validate num samples on points attribute
        clipFiles = []
        # first 5 frames have no animation
        usdFile = os.path.abspath('UsdExportAsClip_cube.001.usda')
        clipFiles.append(usdFile)
        cmds.usdExport(mergeTransformAndShape=True,
                       file=usdFile,
                       frameRange=(1, 5),
                       sss=False)
        stage = Usd.Stage.Open(usdFile)
        self._ValidateNumSamples(stage, '/world/pCube1', 'points', 1)

        # next 5 frames have no animation
        usdFile = os.path.abspath('UsdExportAsClip_cube.005.usda')
        clipFiles.append(usdFile)
        cmds.usdExport(mergeTransformAndShape=True,
                       file=usdFile,
                       frameRange=(5, 10),
                       sss=False)
        stage = Usd.Stage.Open(usdFile)
        self._ValidateNumSamples(stage, '/world/pCube1', 'points', 1)

        # next 5 frames have deformation animation
        usdFile = os.path.abspath('UsdExportAsClip_cube.010.usda')
        clipFiles.append(usdFile)
        frames = (10, 15)
        cmds.usdExport(mergeTransformAndShape=True,
                       file=usdFile,
                       frameRange=frames,
                       sss=False)
        stage = Usd.Stage.Open(usdFile)
        self._ValidateNumSamples(stage, '/world/pCube1', 'points',
                                 frames[1] + 1 - frames[0])

        # next 5 frames have no animation
        usdFile = os.path.abspath('UsdExportAsClip_cube.015.usda')
        clipFiles.append(usdFile)
        cmds.usdExport(mergeTransformAndShape=True,
                       file=usdFile,
                       frameRange=(15, 20),
                       sss=False)
        stage = Usd.Stage.Open(usdFile)
        self._ValidateNumSamples(stage, '/world/pCube1', 'points', 1)

        stitchedPath = os.path.abspath('result.usda')
        stitchedLayer = Sdf.Layer.CreateNew(stitchedPath)

        # Clip stitching behavior changed significantly between core USD 20.05
        # and 20.08. Beginning with 20.08, we need to pass an additional option
        # to ensure that authored time samples are held across gaps in value
        # clips.
        if Usd.GetVersion() > (0, 20, 5):
            self.assertTrue(
                UsdUtils.StitchClips(stitchedLayer,
                                     clipFiles,
                                     '/world',
                                     startFrame=1,
                                     endFrame=20,
                                     interpolateMissingClipValues=True,
                                     clipSet='default'))
        else:
            self.assertTrue(
                UsdUtils.StitchClips(stitchedLayer,
                                     clipFiles,
                                     '/world',
                                     startFrame=1,
                                     endFrame=20,
                                     clipSet='default'))

        # export a non clip version for comparison
        canonicalUsdFile = os.path.abspath('canonical.usda')
        cmds.usdExport(mergeTransformAndShape=True,
                       file=canonicalUsdFile,
                       frameRange=(1, 20),
                       sss=False)

        print('comparing: \nnormal: {}\nstitched: {}'.format(
            canonicalUsdFile, stitchedPath))
        canonicalStage = Usd.Stage.Open(canonicalUsdFile)
        clipsStage = Usd.Stage.Open(stitchedPath)
        # visible
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube1',
                              'visibility', (0, 21))
        # animated visibility
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube2',
                              'visibility', (0, 21))
        # hidden, non animated:
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube4',
                              'visibility', (0, 21))
        # constant points:
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube2',
                              'points', (0, 21))
        # blend shape driven animated points:
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube3',
                              'points', (0, 21))
        # animated points:
        self._ValidateSamples(canonicalStage, clipsStage, '/world/pCube1',
                              'points', (0, 21))