コード例 #1
0
    def testSkelBindPoseSparseIndices(self):
        """
        Check that if a dagPose has sparse indices on some of it's attributes,
        with differing number of created indices, that things still work.
        """
        mayaFile = os.path.join(self.inputPath, "UsdExportSkeletonTest", "UsdExportSkeletonBindPoseSparseIndices.ma")
        cmds.file(mayaFile, force=True, open=True)

        usdFile = os.path.abspath('UsdExportBindPoseSparseIndicesTest.usda')

        cmds.select('joint_grp')
        cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFile, shadingMode='none',
                           exportSkels='auto', selection=True)

        stage = Usd.Stage.Open(usdFile)

        skeleton = UsdSkel.Skeleton.Get(stage, '/joint_grp/joint1')
        self.assertEqual(skeleton.GetRestTransformsAttr().Get(),
            Vt.Matrix4dArray(
                # If we're not correlating using logical indices correctly, we may get this
                # matrix in here somehwere (which we shouldn't):
                # Gf.Matrix4d( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (777, 888, 999, 1) ),
                [Gf.Matrix4d( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 2, 1) ),
                 Gf.Matrix4d( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3, 0, 1) ),
                 Gf.Matrix4d( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (5, 0, 0, 1) )]))
コード例 #2
0
    def testReexport(self):
        cmds.mayaUSDImport(file=self._usdFile, primPath='/')

        exportedUsdFile = os.path.abspath('ExoticTypeNames.reexported.usda')
        cmds.mayaUSDExport(file=exportedUsdFile)

        stage = Usd.Stage.Open(exportedUsdFile)
        self.assertTrue(stage)

        self.assertTrue(stage.GetPrimAtPath('/A'))
        self.assertEqual(stage.GetPrimAtPath('/A').GetTypeName(), 'Xform')
        self.assertTrue(stage.GetPrimAtPath('/A/A_1'))
        self.assertEqual(stage.GetPrimAtPath('/A/A_1').GetTypeName(), '')
        self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_I'))
        self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_I').GetTypeName(),
                '')
        self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_II'))
        self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_II').GetTypeName(),
                '') # Originally Cube, but not on re-export!
        self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_III'))
        self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_III').GetTypeName(),
                'Scope')
        self.assertTrue(stage.GetPrimAtPath('/A/A_2'))
        self.assertEqual(stage.GetPrimAtPath('/A/A_2').GetTypeName(), 'Scope')
        self.assertTrue(stage.GetPrimAtPath('/B'))
        self.assertEqual(stage.GetPrimAtPath('/B').GetTypeName(), '')
        self.assertTrue(stage.GetPrimAtPath('/B/B_1'))
        self.assertEqual(stage.GetPrimAtPath('/B/B_1').GetTypeName(), 'Xform')
コード例 #3
0
    def testExportSelfContainedPackage(self):
        """
        Tests that the exported usdz file is self contained, such that it's valid for AR QuickLook on iOS
        """

        maya_file = os.path.join(self.temp_dir, "UsdExportPackage", "asset.ma")
        cmds.file(maya_file, force=True, open=True)

        # Write the file out
        path = os.path.join(self.temp_dir,
                            'testExportSelfContainedPackage.usdz')
        cmds.mayaUSDExport(f=path, compatibility='appleArKit')

        # Check with USD what the path to the texture is
        stage = Usd.Stage.Open(path)
        prim = stage.GetPrimAtPath(
            "/AssetGroup/Looks/pxrUsdPreviewSurface1SG/file1")
        shader = UsdShade.Shader(prim)
        tex = shader.GetInput("file").Get().path

        # Check to see if the zipfile contains the texture
        with zipfile.ZipFile(path) as zf:
            for zfile in zf.filelist:
                if zfile.filename == tex:
                    break
            else:
                self.fail("Could not find texture inside zip file")
コード例 #4
0
    def testSkelMissingJointFromDagPose(self):
        """
        Check that dagPoses that don't contain all desired joints issue an
        appropriate warning
        """
        mayaFile = os.path.join(self.inputPath, "UsdExportSkeletonTest", "UsdExportSkeletonBindPoseMissingJoints.ma")
        cmds.file(mayaFile, force=True, open=True)

        usdFile = os.path.abspath('UsdExportBindPoseMissingJointsTest.usda')

        joints = cmds.listRelatives('joint_grp', allDescendents=True, type='joint')
        bindMembers = cmds.dagPose('dagPose1', q=1, members=1)
        nonBindJoints = [j for j in joints if j not in bindMembers]
        self.assertEqual(nonBindJoints, [u'joint4'])

        delegate = UsdUtils.CoalescingDiagnosticDelegate()

        cmds.select('joint_grp')
        cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFile, shadingMode='none',
                           exportSkels='auto', selection=True)

        messages = delegate.TakeUncoalescedDiagnostics()
        warnings = [x.commentary for x in messages if x.diagnosticCode == Tf.TF_DIAGNOSTIC_WARNING_TYPE]
        missingJointWarnings = [x for x in warnings if 'is not a member of dagPose' in x]
        self.assertEqual(len(missingJointWarnings), 1)
        self.assertIn("Node 'joint4' is not a member of dagPose 'dagPose1'",
                      missingJointWarnings[0])
コード例 #5
0
    def testExportUDIM(self):
        '''
        Tests that exporting a UDIM texture works:
        '''

        maya_file = os.path.join(self.test_dir, 'UsdExportUDIMTest.ma')
        cmds.file(maya_file, force=True, open=True)

        # Export to USD.
        usd_file = os.path.abspath('UsdExportUDIMTest.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usd_file,
                           shadingMode='useRegistry',
                           convertMaterialsTo=['UsdPreviewSurface'],
                           materialsScopeName='Materials')

        stage = Usd.Stage.Open(usd_file)
        self.assertTrue(stage)

        shader_prim = stage.GetPrimAtPath(
            '/pPlane1/Materials/lambert2SG/file1')
        self.assertTrue(shader_prim)

        shader = UsdShade.Shader(shader_prim)
        shader_id = shader.GetIdAttr().Get()
        self.assertEqual(shader_id, 'UsdUVTexture')
        filename = shader.GetInput("file")
        self.assertTrue("<UDIM>" in filename.Get().path)
コード例 #6
0
    def testExportStaticSingleSampleOn(self):
        for state in (True, False):
            # Set up the scene in here to prevent having to maintain a Maya file
            cmds.file(new=True, force=True)
            root = cmds.group(empty=True, name="root")
            cube, _ = cmds.polyCube(name="Cube")
            joint = cmds.joint()
            cmds.parent(cube, joint, root)
            cmds.skinCluster(joint, cube)


            cmds.setKeyframe(joint, v=0, at='translateY', time=1)
            cmds.setKeyframe(root, v=0, at='translateY', time=1)
            cmds.setKeyframe(joint, v=0, at='translateY', time=10)

            # Okay now do the export
            path = os.path.join(self.temp_dir, "staticSingleFrame{}.usda".format("On" if state else "Off"))

            cmds.mayaUSDExport(f=path, exportSkels="auto", frameRange=(1, 10), sss=state)

            stage = Usd.Stage.Open(path)

            # Check to see if the flag is working
            prim = stage.GetPrimAtPath("/root")
            attr = prim.GetAttribute("xformOp:translate")
            num_samples = attr.GetNumTimeSamples()
            self.assertEqual(num_samples, int(not state))
コード例 #7
0
    def testBindTransformExport(self):
        temp_export_file = os.path.join(self.temp_dir, 'test_output.usda')
        cmds.select('a', r=True)
        cmds.mayaUSDExport(v=True,
                           sl=True,
                           f=temp_export_file,
                           skl='auto',
                           skn='auto',
                           defaultMeshScheme='catmullClark')

        stage = Usd.Stage.Open(temp_export_file)
        prim = stage.GetPrimAtPath('/a/b/c')
        bindTransforms = prim.GetAttribute('bindTransforms').Get()
        bindTransform = bindTransforms[
            3]  # NOTE: (yliangsiew) The 4th joint is the rt_joint that we're interested in.
        self.assertNotEqual(
            bindTransform,
            Gf.Matrix4d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))

        self.assertEqual(
            bindTransform,
            Gf.Matrix4d(-0.002290224357008666, -0.0056947280722030105,
                        0.9999807051930374, 0.0, 0.01567493647243696,
                        0.9998602653154095, 0.005729941968379492, 0.0,
                        -0.9998745177471474, 0.01568775712160303,
                        -0.0022006397844859227, 0.0, -4.625417221923634,
                        16.113398996722644, 5.401075137997586, 1.0))
コード例 #8
0
    def testSidedness(self):
        for sidedness in ('single', 'double', 'derived'):
            for doubleSided in (False, True):
                output = os.path.join(
                    self.temp_dir,
                    'sidedness_{}_{}.usda'.format(sidedness, doubleSided))
                cmds.file(new=True, force=True)

                xform, _ = cmds.polyCube()
                shape = cmds.listRelatives(xform)[0]

                cmds.setAttr("{}.doubleSided".format(shape), doubleSided)
                cmds.mayaUSDExport(file=output,
                                   selection=True,
                                   geomSidedness=sidedness)

                stage = Usd.Stage.Open(output)
                prim = stage.GetPrimAtPath("/pCube1")

                value = UsdGeom.Mesh(prim).GetDoubleSidedAttr().Get()
                if sidedness == 'derived':
                    self.assertEqual(value, doubleSided,
                                     "Incorrect derived sidedness value")
                elif sidedness == 'single':
                    self.assertFalse(value, "Incorrect single sidedness value")
                elif sidedness == 'double':
                    self.assertTrue(value, "Incorrect double sidedness value")
コード例 #9
0
    def testRotateScalePivotCompensationAfterExport(self):
        '''Rotate and scale pivots must match after export.'''

        cmds.file(new=True, force=True)
        mayaSphere = cmds.polySphere()[0]

        cmds.rotate(0, 0, -45, r=True, os=True, fo=True)
        cmds.scale(4, 3, 2, r=True)
        cmds.move(-2, -3, -4, "pSphere1.rotatePivot", r=True)
        cmds.move(7, 6, 5, "pSphere1.scalePivot", r=True)

        # Export out, reference back in using proxy shape.
        usdFilePath = os.path.abspath('UsdExportMayaXformStack.usda')
        cmds.mayaUSDExport(file=usdFilePath)

        # Reference it back in.
        proxyShape = cmds.createNode('mayaUsdProxyShape')
        cmds.setAttr('mayaUsdProxyShape1.filePath', usdFilePath, type='string')

        # MAYA-101766: awkward plug access for non-interactive stage loading.
        outStageData = nameToPlug('mayaUsdProxyShape1.outStageData')
        outStageData.asMDataHandle()

        proxyShapeMayaPath = cmds.ls(proxyShape, long=True)[0]
        proxyShapePathSegment = mayaUtils.createUfePathSegment(
            proxyShapeMayaPath)

        spherePathSegment = usdUtils.createUfePathSegment('/pSphere1')
        spherePath = ufe.Path([proxyShapePathSegment, spherePathSegment])
        sphereItem = ufe.Hierarchy.createItem(spherePath)
        usdSphereT3d = ufe.Transform3d.transform3d(sphereItem)

        # If the Transform3d interface can't handle rotate or scale pivot
        # compensation, skip this test.
        if usdSphereT3d.translateRotatePivotCmd() is None or \
           usdSphereT3d.translateScalePivotCmd() is None:
            raise unittest.SkipTest(
                "Rotate or scale pivot compensation unsupported.")

        # Maya object and its exported USD object twin should have the
        # same pivots and pivot compensations.
        checkPivotsAndCompensations(self, "pSphere1", usdSphereT3d)

        sn = ufe.GlobalSelection.get()
        sn.clear()
        sn.append(sphereItem)

        # Move only the rotate pivot.
        cmds.move(-1, -2, -3, r=True, urp=True)
        cmds.move(-1, -2, -3, "pSphere1.rotatePivot", r=True)

        checkPivotsAndCompensations(self, "pSphere1", usdSphereT3d)

        # Move only the scale pivot.
        cmds.move(-4, -3, -2, r=True, usp=True)
        cmds.move(-4, -3, -2, "pSphere1.scalePivot", r=True)

        checkPivotsAndCompensations(self, "pSphere1", usdSphereT3d)
コード例 #10
0
    def testExportWithSelection(self):

        mayaFilePath = os.path.join(self.inputPath,
                                    "UsdExportSelectionHierarchy",
                                    "UsdExportSelectionHierarchy.ma")
        cmds.file(mayaFilePath, force=True, open=True)

        selectionInput = [
            '|pSphere1|pSphere3|pSphere9|pSphere19',
            '|pSphere1|pSphere3|pSphere7', '|pSphere1|pSphere3|pSphere9',
            '|pSphere1|pSphere2|pSphere4|pSphereShape4', '|pSphere1|pSphere2',
            '|pSphere1|pSphere3|pSphereShape3'
        ]

        cmds.select(selectionInput, af=True)

        selectionResult = cmds.ls(long=True, sl=True)

        # Want to make sure the order is maintatined
        self.assertTrue(selectionResult == selectionInput)

        usdFilePath = os.path.abspath(
            'UsdExportSelectionHierarchy_EXPORTED.usda')
        cmds.mayaUSDExport(selection=True,
                           file=usdFilePath,
                           shadingMode='none')

        stage = Usd.Stage.Open(usdFilePath)
        self.assertTrue(stage)

        expectedExportedPrims = [
            '/pSphere1',
            '/pSphere1/pSphere2',
            '/pSphere1/pSphere2/pSphereShape2',
            '/pSphere1/pSphere2/pSphere4',
            '/pSphere1/pSphere2/pSphere5',
            '/pSphere1/pSphere2/pSphere6',
            '/pSphere1/pSphere2/pSphere4/pSphere10',
            '/pSphere1/pSphere2/pSphere4/pSphere11',
            '/pSphere1/pSphere2/pSphere4/pSphere12',
            '/pSphere1/pSphere2/pSphere4/pSphere13',
            '/pSphere1/pSphere2/pSphere4/pSphere14',
            '/pSphere1/pSphere2/pSphere4/pSphere15',
        ]

        expectedNonExportedPrims = [
            '/pSphere1/pSphereShape1',
            '/pSphere1/pSphere3/pSphere8',
        ]

        for primPath in expectedExportedPrims:
            prim = stage.GetPrimAtPath(primPath)
            self.assertTrue(prim.IsValid())

        for primPath in expectedNonExportedPrims:
            prim = stage.GetPrimAtPath(primPath)
            self.assertFalse(prim.IsValid())
コード例 #11
0
    def testExportStandaloneUsdPreviewSurface(self):
        """
        Tests that a usdPreviewSurface with attribute values but no
        connections authored exports correctly.
        """
        expectedInputTuples = [
            ("clearcoat", 0.1),
            ("clearcoatRoughness", 0.2),
            ("diffuseColor", Gf.Vec3f(0.3, 0.4, 0.5)),
            ("displacement", 0.6),
            ("emissiveColor", Gf.Vec3f(0.07, 0.08, 0.09)),
            ("ior", 1.1),
            ("metallic", 0.11),
            ("normal", Gf.Vec3f(0.12, 0.13, 0.14)),
            ("occlusion", 0.9),
            ("opacity", 0.8),
            ("roughness", 0.7),
            ("specularColor", Gf.Vec3f(0.3, 0.2, 0.1)),
            ("useSpecularWorkflow", 1),
        ]
        maya_file = self.generateStandaloneTestScene(expectedInputTuples)
        cmds.file(maya_file, force=True, open=True)
        usd_file_path = os.path.join(self.temp_dir,
                                     "UsdPreviewSurfaceExportTest.usda")
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usd_file_path,
                           shadingMode="useRegistry")

        stage = Usd.Stage.Open(usd_file_path)

        standaloneMaterial = self._GetUsdMaterial(
            stage, "usdPreviewSurface_StandaloneSG")

        surfaceOutput = standaloneMaterial.GetOutput(UsdShade.Tokens.surface)
        previewSurfaceShader = self._GetSourceShader(surfaceOutput)

        expectedShaderPrimPath = standaloneMaterial.GetPath().AppendChild(
            "usdPreviewSurface_Standalone")

        self.assertEqual(previewSurfaceShader.GetPath(),
                         expectedShaderPrimPath)

        self.assertEqual(previewSurfaceShader.GetShaderId(),
                         "UsdPreviewSurface")

        expectedOutputs = {
            "surface": Sdf.ValueTypeNames.Token,
            "displacement": Sdf.ValueTypeNames.Token,
        }

        self._ValidateUsdShader(previewSurfaceShader, expectedInputTuples,
                                expectedOutputs)

        # There should not be any additional inputs.
        self.assertEqual(len(previewSurfaceShader.GetInputs()),
                         len(expectedInputTuples))
コード例 #12
0
    def testUsdExportFileFormat_cmd_usda(self):
        name = 'ascii.usd'
        usdFile = os.path.abspath(name)

        args = ()
        kwargs = {'file': usdFile, 'defaultUSDFormat': 'usda'}
        cmds.mayaUSDExport(*args, **kwargs)

        layer = Sdf.Layer.FindOrOpen(usdFile)
        format = self.GetUnderlyingUsdFileFormat(layer)
        self.assertEqual(format, 'usda')
コード例 #13
0
    def setUpClass(cls):
        cls.temp_dir = fixturesUtils.setUpClass(__file__)
        cls.maya_file = os.path.join(cls.temp_dir, "UsdExportUVTransforms",
                                     "UsdExportUVTransforms.ma")
        cmds.file(cls.maya_file, force=True, open=True)

        usd_file_path = os.path.join(cls.temp_dir,
                                     "UsdExportUVTransforms.usda")
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usd_file_path,
                           shadingMode='useRegistry')

        cls.stage = Usd.Stage.Open(usd_file_path)
コード例 #14
0
    def testExportJobContextConflicts(self):
        """Testing that merging incompatible contexts generates errors"""
        mark = Tf.Error.Mark()
        mark.SetMark()
        self.assertTrue(mark.IsClean())

        cmds.polySphere(r=1)
        usdFilePath = os.path.abspath('UsdExportSchemaApiTestBasic.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usdFilePath,
                           jobContext=["Larry", "Curly", "Moe"])

        self.assertFalse(mark.IsClean())

        errors = mark.GetErrors()
        messages = set()
        for e in errors:
            messages.add(e.commentary)

        expected = set([
            "Arguments for job context 'Larry' can not include extra contexts.",
            "Context 'Curly' and context 'Larry' do not agree on type of argument 'apiSchema'.",
            "Context 'Moe' and context 'Larry' do not agree on argument 'geomSidedness'."
        ])
        self.assertEqual(messages, expected)

        cmds.file(f=True, new=True)

        mark = Tf.Error.Mark()
        mark.SetMark()
        self.assertTrue(mark.IsClean())

        cmds.polySphere(r=1)
        usdFilePath = os.path.abspath('UsdExportSchemaApiTestBasic.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usdFilePath,
                           jobContext=["NullAPI", "Moe"])

        self.assertFalse(mark.IsClean())

        errors = mark.GetErrors()
        messages = set()
        for e in errors:
            messages.add(e.commentary)

        expected = set(
            ["Missing implementation for NullAPIChaser::ExportDefault"])
        self.assertEqual(messages, expected)

        cmds.file(f=True, new=True)
コード例 #15
0
    def setUpClass(cls):
        inputPath = fixturesUtils.setUpClass(__file__)

        mayaFile = os.path.join(inputPath, 'UsdExportRfMShadersTest',
            'MarbleCube.ma')
        cmds.file(mayaFile, force=True, open=True)

        # Export to USD.
        usdFilePath = os.path.abspath('MarbleCube.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFilePath,
            shadingMode='useRegistry', convertMaterialsTo='rendermanForMaya',
            materialsScopeName='Materials')

        cls._stage = Usd.Stage.Open(usdFilePath)
コード例 #16
0
    def setUpClass(cls):
        inputPath = fixturesUtils.setUpClass(__file__)

        mayaFile = os.path.join(inputPath, 'UsdExportDisplacementTest',
            'SimpleDisplacement.ma')
        cmds.file(mayaFile, force=True, open=True)

        # Export to USD.
        usdFilePath = os.path.abspath('SimpleDisplacement.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFilePath,
            shadingMode='useRegistry', convertMaterialsTo=['UsdPreviewSurface'],
            materialsScopeName='Materials')

        cls._stage = Usd.Stage.Open(usdFilePath)
コード例 #17
0
    def testSkelForSegfault(self):
        """
        Certain skeletons cause heap corruption and segfaulting when exported multiple times.
        Because this can happen anywhere from the first to last time, we run this test multiple times.
        """
        mayaFile = os.path.join(self.inputPath, "UsdExportSkeletonTest", "UsdExportSkeletonSegfaultTest.ma")
        cmds.file(mayaFile, force=True, open=True)

        usdFile = os.path.abspath('UsdExportSkeletonSegfaultTest.usda')
        cmds.select('skinned_mesh')

        # Run 5 times because the crash only happens every few runs.
        for _ in range(5):
            cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFile,
                         shadingMode='none', exportSkels='auto', selection=True)
コード例 #18
0
    def testImagingShapeDoesNotExport(self):
        """
        Tests that the USD exported from a scene that uses the
        pxrHdImagingShape does *not* include any prims for the
        pxrHdImagingShape itself.

        The pxrHdImagingShape and its parent transform are set so that they do
        not write to the Maya scene file and are not exported to USD.
        """
        usdFilePath = os.path.abspath('ProxyShapeBaseExportTest.usda')
        cmds.mayaUSDExport(file=usdFilePath)

        usdStage = Usd.Stage.Open(usdFilePath)
        prim = usdStage.GetPrimAtPath('/HdImaging')
        self.assertFalse(prim)
        prim = usdStage.GetPrimAtPath('/HdImaging/HdImagingShape')
        self.assertFalse(prim)
コード例 #19
0
    def setUpClass(cls):
        inputPath = fixturesUtils.setUpClass(__file__)

        mayaSceneFilePath = os.path.join(inputPath,
            'UsdExportUserTaggedAttributesTest', 'UserTaggedAttributesTest.ma')

        cmds.file(mayaSceneFilePath, open=True, force=True)

        usdFilePathFormat = 'UserTaggedAttributesTest_EXPORTED_%s.usda'
        
        cls._mergedUsdFilePath = os.path.abspath(usdFilePathFormat % 'MERGED')
        cls._unmergedUsdFilePath = os.path.abspath(usdFilePathFormat % 'UNMERGED')

        cmds.mayaUSDExport(file=cls._mergedUsdFilePath,
            mergeTransformAndShape=True)
        cmds.mayaUSDExport(file=cls._unmergedUsdFilePath,
            mergeTransformAndShape=False)
コード例 #20
0
    def testMeshNextToProxyShapeAndImported(self):
        """
        Tests the colors between a mesh with (0.55, 0.55, 0.55)
        exporting that file and then re-importing it, and also referencing
        it back into the same scene through a proxy shape.

        While this is a bit more than just "GL" testing, it's a useful place to
        centralize all this.  If we don't like that this is testing usdImport
        functionality, we can remove

        This will render as follows:


        blank    |  usdImport
                 |
        ---------+-----------
        modeled  |  ref'd
                 |

        """
        x = self._PlaneWithColor((0.55, 0.55, 0.55))
        cmds.select(x)
        usdFile = os.path.join(self._testDir, 'plane.usd')
        cmds.mayaUSDExport(file=usdFile,
                           selection=True,
                           shadingMode='none',
                           exportDisplayColor=True)
        proxyShape = cmds.createNode('mayaUsdProxyShape', name='usdProxyShape')
        proxyTransform = cmds.listRelatives(proxyShape,
                                            parent=True,
                                            fullPath=True)[0]
        cmds.xform(proxyTransform, translation=(30.48, 0, 0))
        cmds.setAttr('%s.filePath' % proxyShape, usdFile, type='string')
        cmds.setAttr('%s.primPath' % proxyShape, '/pPlane1', type='string')

        x = cmds.mayaUSDImport(file=usdFile)
        cmds.xform(x, translation=(30.48, 30.48, 0))

        cmds.setAttr("hardwareRenderingGlobals.floatingPointRTEnable", 0)
        cmds.setAttr('defaultColorMgtGlobals.outputTransformEnabled', 0)
        self._Snapshot('default')
        cmds.setAttr("hardwareRenderingGlobals.floatingPointRTEnable", 1)
        cmds.setAttr('defaultColorMgtGlobals.outputTransformEnabled', 1)
        self._Snapshot('colorMgt')
コード例 #21
0
    def testSkelRestXformsWithNoDagPose(self):
        """
        Tests export of rest xforms when there is no dagPose node at all.
        """
        mayaFile = os.path.join(self.inputPath, "UsdExportSkeletonTest",
            "UsdExportSkeletonNoDagPose.ma")
        cmds.file(mayaFile, force=True, open=True)

        usdFile = os.path.abspath('UsdExportSkeletonRestXformsWithNoDagPose.usda')
        cmds.select('skel_root')
        cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFile,
                           shadingMode='none', exportSkels='auto', selection=True)

        stage = Usd.Stage.Open(usdFile)

        skeleton = UsdSkel.Skeleton.Get(stage, '/skel_root/joint1')

        self.assertEqual(skeleton.GetJointsAttr().Get(),
            Vt.TokenArray(['joint1',
                           'joint1/joint2',
                           'joint1/joint2/joint3',
                           'joint1/joint2/joint3/joint4']))

        self.assertEqual(
            skeleton.GetBindTransformsAttr().Get(),
            Vt.Matrix4dArray([
                Gf.Matrix4d( (-1, 0, 0, 0), (0, 1, 0, 0), (0, 0, -1, 0), (0, 0, 0, 1) ),
                Gf.Matrix4d( (0, -1, 0, 0), (-1, 0, 0, 0), (0, 0, -1, 0), (3, 0, 0, 1) ),
                Gf.Matrix4d( (0, -1, 0, 0), (0, 0, -1, 0), (1, 0, 0, 0), (3, 0, -2, 1) ),
                Gf.Matrix4d( (0, -1, 0, 0), (1, 0, 0, 0), (0, 0, 1, 0), (3, 0, -4, 1) ),
            ])
        )

        self.assertEqual(
            skeleton.GetRestTransformsAttr().Get(),
            Vt.Matrix4dArray([
                Gf.Matrix4d( (-1, 0, 0, 0), (0, 1, 0, 0), (0, 0, -1, 0), (0, 0, 0, 1) ),
                Gf.Matrix4d( (0, -1, 0, 0), (1, 0, 0, 0), (0, 0, 1, 0), (-3, 0, 0, 1) ),
                Gf.Matrix4d( (1, 0, 0, 0), (0, 0, 1, 0), (0, -1, 0, 0), (0, 0, 2, 1) ),
                Gf.Matrix4d( (1, 0, 0, 0), (0, 0, 1, 0), (0, -1, 0, 0), (0, 2, 0, 1) ),
            ])
        )        
コード例 #22
0
    def setUpClass(cls):
        suffix = ""
        if mayaUsdLib.WriteUtil.WriteMap1AsST():
            suffix += "ST"

        inputPath = fixturesUtils.setUpClass(__file__, suffix)

        mayaFile = os.path.join(inputPath, 'UsdExportUVSetMappingsTest',
                                'UsdExportUVSetMappingsTest.ma')
        cmds.file(mayaFile, force=True, open=True)

        # Export to USD.
        usdFilePath = os.path.abspath('UsdExportUVSetMappingsTest.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usdFilePath,
                           shadingMode='useRegistry',
                           convertMaterialsTo='UsdPreviewSurface',
                           materialsScopeName='Materials')

        cls._stage = Usd.Stage.Open(usdFilePath)
コード例 #23
0
    def test_fps(self):
        fps_map = {
            "ntsc": 30,
            "game": 15,
            "film": 24,
            "pal": 25,
            "show": 48,
            "palf": 50,
            "ntscf": 60
        }

        for name, fps in fps_map.items():
            cmds.currentUnit(time=name)
            temp_file = os.path.join(self.temp_dir,
                                     'test_{}.usda'.format(name))
            cmds.mayaUSDExport(f=temp_file, frameRange=(1, 5))

            stage = Usd.Stage.Open(temp_file)
            self.assertEqual(stage.GetTimeCodesPerSecond(), fps)
            self.assertEqual(stage.GetFramesPerSecond(), fps)
コード例 #24
0
    def testExportAnimatedCompundValue(self):
        """MayaUSD Issue #1712: Test that animated custom compound attributes
           on a mesh are exported."""
        cmds.file(new=True, force=True)
        cubeShape = "MyCubeShape"
        cmds.polyCube(name="MyCube")
        cmds.addAttr(cubeShape, sn="tf2", ln="TestFloatTwo", at="float2")
        cmds.addAttr(cubeShape, sn="tf2u", ln="TestFloatTwoU", at="float", p="TestFloatTwo")
        cmds.addAttr(cubeShape, sn="tf2v", ln="TestFloatTwoV", at="float", p="TestFloatTwo")
        cmds.setAttr(cubeShape + ".TestFloatTwoU", e=True, keyable=True)
        cmds.setAttr(cubeShape + ".TestFloatTwoV", e=True, keyable=True)
        cmds.setKeyframe(cubeShape, attribute="tf2")
        cmds.currentTime(10)
        cmds.setAttr(cubeShape + ".TestFloatTwoU", 20.0)
        cmds.setAttr(cubeShape + ".TestFloatTwoV", 40.0)
        cmds.setKeyframe(cubeShape, attribute="tf2")
        cmds.addAttr(cubeShape, ci=True, sn="USD_UserExportedAttributesJson", ln="USD_UserExportedAttributesJson", dt="string")
        cmds.setAttr(cubeShape + ".USD_UserExportedAttributesJson", '{"TestFloatTwo": {}}', type="string")

        # Exporting with a time range results in time samples:
        path = os.path.join(self.temp_dir, "animatedCompoundValue.usda")
        cmds.mayaUSDExport(f=path, exportSkels="auto", frameRange=(1, 10), sss=True)

        stage = Usd.Stage.Open(path)

        prim = stage.GetPrimAtPath("/MyCube")
        attr = prim.GetAttribute("userProperties:TestFloatTwo")
        self.assertGreater(attr.GetNumTimeSamples(), 1)

        # Exporting without time range results in a single authored value:
        path = os.path.join(self.temp_dir, "animatedCompoundValueStatic.usda")
        cmds.mayaUSDExport(f=path)

        stage = Usd.Stage.Open(path)

        prim = stage.GetPrimAtPath("/MyCube")
        attr = prim.GetAttribute("userProperties:TestFloatTwo")
        self.assertEqual(attr.GetNumTimeSamples(), 0)
        # Make sure value is there because previous code did not write any:
        self.assertEqual(attr.Get(), [20.0, 40.0])
コード例 #25
0
    def testPythonCustomShaderExporter(self):
        '''
        Add a custom exporter to the mix and see if it can export a compositing node.
        '''
        cmds.file(f=True, new=True)

        # Register our new exporter:
        mayaUsdLib.ShaderWriter.Register(mxCompositeExportTest, "colorComposite")

        mayaFile = os.path.join(self._inputPath, 'UsdExportMaterialXTest',
            'MaterialX_decal.ma')
        cmds.file(mayaFile, force=True, open=True)

        # Export to USD.
        usdFilePath = os.path.abspath('MaterialX_decal.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFilePath,
            shadingMode='useRegistry', convertMaterialsTo=['MaterialX'],
            materialsScopeName='Materials')

        stage = Usd.Stage.Open(usdFilePath)
        self.assertTrue(stage)

        # We should have a nice colorComposite1 node in the graph curtesy of the custom exporter:
        prim = stage.GetPrimAtPath("/pPlane1/Materials/standardSurface2SG/MayaNG_standardSurface2SG/colorComposite1")
        self.assertTrue(prim)
        shader = UsdShade.Shader(prim)
        self.assertTrue(shader)
        self.assertEqual(shader.GetIdAttr().Get(), "ND_mix_color3")
        input = shader.GetInput("fg")
        self.assertEqual(input.Get(), (1,1,0))
        input = shader.GetInput("bg")
        cnxTuple = input.GetConnectedSource()
        self.assertTrue(cnxTuple)
        self.assertEqual(cnxTuple[0].GetPrim().GetName(), "file1")
        input = shader.GetInput("mix")
        cnxTuple = input.GetConnectedSource()
        self.assertTrue(cnxTuple)
        self.assertEqual(cnxTuple[0].GetPrim().GetName(), "MayaSwizzle_file2_a")
        self.assertTrue("MaterialX" in mxCompositeExportTest._AllMaterialConversions)
コード例 #26
0
    def _StartTest(self, testName):
        cmds.file(force=True, new=True)
        mayaUtils.loadPlugin("mayaUsdPlugin")

        self._testName = testName
        testFile = testUtils.getTestScene("displayColors",
                                          self._testName + ".ma")

        cmds.file(testFile, o=True)

        exportedFile = os.path.join(self._testDir, "ColorTest.usda")
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=exportedFile,
                           shadingMode='none',
                           exportDisplayColor=True)

        shapeNode = mayaUtils.createProxyFromFile(exportedFile)[0]
        cmds.move(0, 0, -1, shapeNode)

        globalSelection = ufe.GlobalSelection.get()
        globalSelection.clear()
        self.assertSnapshotClose('%s_unselected.png' % self._testName)
コード例 #27
0
    def testComponentTags(self):
        """
        Test that component tags can round-trip through USD.
        """
        geo = cmds.polySphere(sx=6, sy=6)[0]
        geo_name = geo
        geo = geo_utils.extendToShape(geo)
        ctag_utils.createTag(geo, 'top', ['f[18:23]', 'f[30:35]'])
        ctag_utils.createTag(geo, 'bottom', ['f[0:5]', 'f[24:29]'])

        usdFilePath = os.path.join(os.environ.get('MAYA_APP_DIR'),
                                   'testComponentTags.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usdFilePath,
                           shadingMode='none')

        cmds.file(new=True, force=True)
        rootPaths = cmds.mayaUSDImport(v=True, f=usdFilePath)
        self.assertEqual(len(rootPaths), 1)

        indices = cmds.getAttr('{0}.componentTags'.format(geo_name),
                               multiIndices=True) or []
        self.assertEqual(len(indices), 2)
コード例 #28
0
    def testBlendShapesExport(self):
        # NOTE: (yliangsiew) Basic blendshape export test.
        om.MFileIO.newFile(True)
        parent = cmds.group(name="root", empty=True)
        base, _ = cmds.polyCube(name="base")
        cmds.parent(base, parent)
        target, _ = cmds.polyCube(name="blend")
        cmds.parent(target, parent)
        cmds.polyMoveVertex('{}.vtx[0:2]'.format(target), s=(1.0, 1.5, 1.0))

        cmds.blendShape(target, base, automatic=True)

        cmds.select(base, replace=True)
        temp_file = os.path.join(self.temp_dir, 'blendshape.usda')
        cmds.mayaUSDExport(f=temp_file, v=True, sl=True, ebs=True, skl="auto")

        stage = Usd.Stage.Open(temp_file)
        prim = stage.GetPrimAtPath("/root/base/blendShape")
        offsets = prim.GetAttribute("offsets").Get()

        for i, coords in enumerate(offsets):
            coords = list(coords)  # convert from GfVec3
            self.assertEqual(coords, [0, -0.25 if i < 2 else 0.25, 0])

        """
        Sample BlendShape prim:

        def BlendShape "blendShape"
        {
            uniform vector3f[] normalOffsets = [(0, 0, 0), (0, 0, 0), (0, 0, 0)]
            uniform vector3f[] offsets = [(0, -0.25, 0), (0, -0.25, 0), (0, 0.25, 0)]
            uniform int[] pointIndices = [0, 1, 2]
        }
        """

        # NOTE: (yliangsiew) Test simple inbetween setup.
        om.MFileIO.open(self.scene_path, None, True)
        cmds.select("basic_cube_2_inbetweens_no_anim|base", r=True)
        cmds.mayaUSDExport(f=temp_file, v=True, sl=True, ebs=True, skl="auto", skn="auto")
        stage = Usd.Stage.Open(temp_file)
        prim = stage.GetPrimAtPath("/basic_cube_2_inbetweens_no_anim/base/pCube2")
        blendShape = UsdSkel.BlendShape(prim)
        inbetweens = blendShape.GetInbetweens()
        self.assertEqual(len(inbetweens), 2)  # NOTE: (yliangsiew) This particular setup has two additional inbetweens.

        # NOTE: (yliangsiew) Test simple multiple targets setup.
        om.MFileIO.open(self.scene_path, None, True)
        cmds.select("basic_cube_4_blendshapes_no_anim|base", r=True)
        cmds.mayaUSDExport(f=temp_file, v=True, sl=True, ebs=True, skl="auto", skn="auto")
        stage = Usd.Stage.Open(temp_file)
        prim = stage.GetPrimAtPath("/basic_cube_4_blendshapes_no_anim/base")
        blendShapes = prim.GetChildren()
        for bs in blendShapes:
            self.assertEqual(bs.GetTypeName(), 'BlendShape')
コード例 #29
0
    def testComplexAdaptation(self):
        """Test that we can adapt a bullet simulation"""

        mayaUsdLib.SchemaApiAdaptor.Register(TestBulletMassShemaAdaptor,
                                             "shape", "PhysicsMassAPI")
        mayaUsdLib.SchemaApiAdaptor.Register(TestBulletRigidBodyShemaAdaptor,
                                             "shape", "PhysicsRigidBodyAPI")

        # Build a scene (and exercise the adaptor in a freeform context)
        cmds.file(f=True, new=True)

        s1T = cmds.polySphere()[0]
        cmds.loadPlugin("bullet")
        if not BulletUtils.checkPluginLoaded():
            return

        rbT, rbShape = RigidBody.CreateRigidBody().command(
            autoFit=True,
            colliderShapeType=RigidBody.eShapeType.kColliderSphere,
            meshes=[s1T],
            radius=1.0,
            mass=5.0,
            centerOfMass=(0.9, 0.8, 0.7))

        # See if the plugin adaptor can read the bullet shape under the mesh:
        sl = om.MSelectionList()
        sl.add(s1T)
        dagPath = sl.getDagPath(0)
        dagPath.extendToShape()

        adaptor = mayaUsdLib.Adaptor(dagPath.fullPathName())
        self.assertEqual(adaptor.GetUsdType(),
                         Tf.Type.FindByName('UsdGeomMesh'))
        # NOTICE: PhysicsRigidBodyAPI is not in the list because that API is
        # supported only on export!!!
        self.assertEqual(adaptor.GetAppliedSchemas(), ['PhysicsMassAPI'])
        physicsMass = adaptor.GetSchemaByName("PhysicsMassAPI")
        self.assertEqual(physicsMass.GetName(), "PhysicsMassAPI")
        massAttributes = set([
            'physics:centerOfMass', 'physics:density',
            'physics:diagonalInertia', 'physics:mass', 'physics:principalAxes'
        ])
        self.assertEqual(set(physicsMass.GetAttributeNames()), massAttributes)
        bulletAttributes = set(['physics:centerOfMass', 'physics:mass'])
        self.assertEqual(set(physicsMass.GetAuthoredAttributeNames()),
                         bulletAttributes)
        bulletMass = physicsMass.GetAttribute('physics:mass')
        self.assertAlmostEqual(bulletMass.Get(), 5.0)
        bulletMass.Set(12.0)

        bulletCenter = physicsMass.GetAttribute('physics:centerOfMass')
        bulletCenter.Set(Gf.Vec3f(3, 4, 5))

        sl = om.MSelectionList()
        sl.add(s1T)
        bulletPath = sl.getDagPath(0)
        bulletPath.extendToShape(1)
        massDepFn = om.MFnDependencyNode(bulletPath.node())
        plug = om.MPlug(bulletPath.node(), massDepFn.attribute("mass"))
        self.assertAlmostEqual(plug.asFloat(), 12.0)

        # Create an untranslated attribute:
        usdDensity = physicsMass.CreateAttribute('physics:density')
        usdDensity.Set(33.0)
        self.assertAlmostEqual(usdDensity.Get(), 33.0)

        # This will result in a dynamic attribute on the bulletShape:
        plug = massDepFn.findPlug("USD_ATTR_physics_density", True)
        self.assertAlmostEqual(plug.asFloat(), 33.0)
        bulletAttributes.add('physics:density')
        self.assertEqual(set(physicsMass.GetAuthoredAttributeNames()),
                         bulletAttributes)

        physicsMass.RemoveAttribute('physics:density')
        bulletAttributes.remove('physics:density')
        self.assertEqual(set(physicsMass.GetAuthoredAttributeNames()),
                         bulletAttributes)

        # Add some animation:
        cmds.setKeyframe(bulletPath, at="mass", t=0, v=3.0)
        cmds.setKeyframe(bulletPath, at="mass", t=10, v=30.0)

        # Modify the velocity so it can be exported to the RBD Physics schema.
        cmds.setKeyframe(bulletPath, at="initialVelocityX", t=0, v=5.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityX", t=10, v=50.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityY", t=0, v=6.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityY", t=10, v=60.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityZ", t=0, v=7.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityZ", t=10, v=70.0)

        # Try applying the schema on a new sphere:
        s2T = cmds.polySphere()[0]
        sl.add(s2T)
        dagPath = sl.getDagPath(1)
        dagPath.extendToShape()
        adaptor = UsdMaya.Adaptor(dagPath.fullPathName())
        physicsMass = adaptor.ApplySchemaByName("PhysicsMassAPI")
        self.assertEqual(physicsMass.GetName(), "PhysicsMassAPI")
        self.assertEqual(adaptor.GetUsdType(),
                         Tf.Type.FindByName('UsdGeomMesh'))
        self.assertEqual(adaptor.GetAppliedSchemas(), ['PhysicsMassAPI'])

        usdDensity = physicsMass.CreateAttribute('physics:density')
        usdDensity.Set(33.0)

        # Export, but without enabling Bullet:
        usdFilePath = os.path.abspath('UsdExportSchemaApiTest_NoBullet.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFilePath)

        # Check that there are no Physics API schemas exported:
        stage = Usd.Stage.Open(usdFilePath)
        for i in (1, 2):
            spherePrim = stage.GetPrimAtPath(
                '/pSphere{0}/pSphereShape{0}'.format(i))
            self.assertFalse(
                "PhysicsMassAPI" in spherePrim.GetAppliedSchemas())

        schemasToExport = ["PhysicsMassAPI", "PhysicsRigidBodyAPI"]
        # Export, with Bullet:
        usdFilePath = os.path.abspath('UsdExportSchemaApiTest_WithBullet.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usdFilePath,
                           apiSchema=schemasToExport,
                           frameRange=(1, 10))

        # Check that Physics API schemas did get exported:
        stage = Usd.Stage.Open(usdFilePath)
        values = [
            ("physics:centerOfMass", (Gf.Vec3f(3, 4, 5), Gf.Vec3f(0, 0, 0))),
            ("physics:mass", (3.0, 1.0)),
            ("physics:density", (None, 33.0)),
        ]
        for i in (1, 2):
            spherePrim = stage.GetPrimAtPath(
                '/pSphere{0}/pSphereShape{0}'.format(i))
            self.assertTrue("PhysicsMassAPI" in spherePrim.GetAppliedSchemas())
            for n, v in values:
                if v[i - 1]:
                    a = spherePrim.GetAttribute(n)
                    self.assertEqual(a.Get(), v[i - 1])
            if i == 1:
                # Is mass animated?
                a = spherePrim.GetAttribute("physics:mass")
                self.assertEqual(a.Get(10), 30)
            # This got exported even though invisible in interactive:
            self.assertTrue(
                "PhysicsRigidBodyAPI" in spherePrim.GetAppliedSchemas())
            a = spherePrim.GetAttribute("physics:velocity")
            if i == 1:
                self.assertEqual(a.Get(0), (5, 6, 7))
                self.assertEqual(a.Get(10), (50, 60, 70))
                numberOfExportedKeys = len(a.GetTimeSamples())

        # Try unapplying the schema:
        adaptor.UnapplySchemaByName("PhysicsMassAPI")
        self.assertEqual(adaptor.GetAppliedSchemas(), [])

        # Test import of USDPhysics without job context:
        cmds.file(new=True, force=True)
        cmds.mayaUSDImport(f=usdFilePath)

        sl = om.MSelectionList()
        # pSphereShape1 is a transform, since the bullet shape prevented merging the mesh and the
        # transform. The shape will be pSphereShape1Shape...
        sl.add("pSphereShape1")
        bulletPath = sl.getDagPath(0)
        # No bullet shape since we did not put Bullet as jobContext
        self.assertEqual(bulletPath.numberOfShapesDirectlyBelow(), 1)

        cmds.file(new=True, force=True)
        cmds.mayaUSDImport(f=usdFilePath,
                           apiSchema=schemasToExport,
                           readAnimData=True)

        sl = om.MSelectionList()
        sl.add("pSphereShape1")
        bulletPath = sl.getDagPath(0)
        # Finds bullet shape since we did put Bullet as jobContext

        self.assertEqual(bulletPath.numberOfShapesDirectlyBelow(), 2)

        # The bullet shape has animated mass and initial velocity since we read the animation.
        bulletPath.extendToShape(1)
        massDepFn = om.MFnDependencyNode(bulletPath.node())
        for attrName in ("mass", "initialVelocityX", "initialVelocityY",
                         "initialVelocityZ"):
            plug = om.MPlug(bulletPath.node(), massDepFn.attribute(attrName))
            self.assertTrue(plug.isConnected)
            fcurve = oma.MFnAnimCurve(plug.source().node())
            self.assertEqual(fcurve.numKeys, numberOfExportedKeys)
コード例 #30
0
    def testSimpleShaderWriter(self):
        mayaUsdLib.ShaderWriter.Register(shaderWriterTest, "lambert")

        cmds.file(f=True, new=True)

        sphere_xform = cmds.polySphere()[0]

        # Need a lambert, with something connected to exercise the
        # full API. The code will survive the test writer not even
        # creating a UsdShade node for the lambert.
        material_node = cmds.shadingNode("lambert",
                                         asShader=True,
                                         name="Lanbert42")

        material_sg = cmds.sets(renderable=True,
                                noSurfaceShader=True,
                                empty=True,
                                name=material_node + "SG")
        cmds.connectAttr(material_node + ".outColor",
                         material_sg + ".surfaceShader",
                         force=True)
        cmds.sets(sphere_xform, e=True, forceElement=material_sg)

        file_node = cmds.shadingNode("file",
                                     asTexture=True,
                                     isColorManaged=True)
        uv_node = cmds.shadingNode("place2dTexture", asUtility=True)

        for att_name in (".coverage", ".translateFrame", ".rotateFrame",
                         ".mirrorU", ".mirrorV", ".stagger", ".wrapU",
                         ".wrapV", ".repeatUV", ".offset", ".rotateUV",
                         ".noiseUV", ".vertexUvOne", ".vertexUvTwo",
                         ".vertexUvThree", ".vertexCameraOne"):
            cmds.connectAttr(uv_node + att_name, file_node + att_name, f=True)
        cmds.connectAttr(uv_node + ".outUV", file_node + ".uvCoord", f=True)
        cmds.connectAttr(uv_node + ".outUvFilterSize",
                         file_node + ".uvFilterSize",
                         f=True)

        cmds.connectAttr(file_node + ".outColor",
                         material_node + ".color",
                         f=True)

        cmds.setAttr(file_node + ".fileTextureName",
                     "unknown.png",
                     type="string")

        # Export to USD. We select MaterialX because all the writer
        # there are reporting "Fallback", which allows our CanExport
        # to always win with "Supported" (also helps that the current
        # version of the MaterialX export does not support lambert).
        usdFilePath = os.path.join(self.temp_dir, 'testShaderWriter.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usdFilePath,
                           shadingMode='useRegistry',
                           convertMaterialsTo=['MaterialX'],
                           materialsScopeName='Materials')

        self.assertTrue(shaderWriterTest.CanExportCalled)
        self.assertEqual(shaderWriterTest.WriteCalledCount, 1)
        self.assertTrue(
            shaderWriterTest.GetShadingAttributeForMayaAttrNameCalled)
        self.assertEqual(
            shaderWriterTest.GetShadingAttributeNameForMayaAttrNameCalledWith,
            'color')
        self.assertFalse(shaderWriterTest.NotCalled)