Exemplo n.º 1
0
    def read_usd_material(cls, material, texture_path, time=None):
        r"""Read USD material and return a Material object.
        The shader used must have a corresponding registered reader function. If no available reader is found,
        the material parameters will be returned as a dictionary.

        Args:
            material (UsdShade.Material): Valid USD Material prim
            texture_path (str, optional): Path to textures directory. If the USD has absolute paths
                to textures, set to an empty string. By default, the textures will be assumed to be
                under the same directory as the USD specified by `file_path`.
            time (convertible to float, optional): Positive integer indicating the time at which to retrieve parameters.

        Returns:
            (Material): Material object determined by the corresponding reader function.
        """
        if time is None:
            time = Usd.TimeCode.Default()

        if not UsdShade.Material(material):
            raise MaterialLoadError(
                f'The material `{material}` is not a valid UsdShade.Material object.'
            )

        for surface_output in material.GetSurfaceOutputs():
            if not surface_output.HasConnectedSource():
                continue
            surface_shader = surface_output.GetConnectedSource()[0]
            shader = UsdShade.Shader(surface_shader)
            if not UsdShade.Shader(shader):
                raise MaterialLoadError(
                    f'The shader `{shader}` is not a valid UsdShade.Shader object.'
                )

            if shader.GetImplementationSourceAttr().Get(time=time) == 'id':
                shader_name = UsdShade.Shader(surface_shader).GetShaderId()
            elif shader.GetPrim().HasAttribute('info:mdl:sourceAsset'):
                # source_asset = shader.GetPrim().GetAttribute('info:mdl:sourceAsset').Get(time=time)
                shader_name = shader.GetPrim().GetAttribute(
                    'info:mdl:sourceAsset:subIdentifier').Get(time=time)
            else:
                shader_name = ''
                warnings.warn(
                    f'A reader for the material defined by `{material}` is not yet implemented.'
                )

            params = _get_shader_parameters(surface_shader, time)

            if shader_name not in cls._usd_readers:
                warnings.warn(
                    'No registered readers were able to process the material '
                    f'`{material}` with shader `{shader_name}`.')
                return params

            reader = cls._usd_readers[shader_name]
            return reader(params, texture_path, time)
        raise MaterialError(f'Error processing material {material}')
Exemplo n.º 2
0
    def IsConverter(self):
        mtlxShaderReaderTest.IsConverterCalled = True
        self._refinedOutputToken = ''
        prim = self._GetArgs().GetUsdPrim()
        shaderSchema = UsdShade.Shader(prim)
        if (not shaderSchema):
            return None

        shaderId = shaderSchema.GetIdAttr().Get()

        input = shaderSchema.GetInput('in')
        if (not input):
            return None

        (source, sourceOutputName, sourceType) = input.GetConnectedSource()
        if (not source):
            return None

        downstreamSchema = UsdShade.Shader(source.GetPrim())
        if (not downstreamSchema):
            return None

        # No refinement necessary for ND_convert_color3_vector3 and ND_normalmap.

        if ("ND_luminance_" in shaderId):
            # Luminance is an alpha output.
            self._setAlphaIsLuminance = True
            self._refinedOutputToken = 'outAlpha'
        elif ("ND_swizzle_" in shaderId):
            channelsAttr = shaderSchema.GetInput('channels')
            val = channelsAttr.Get(Usd.TimeCode.Default())
            if (val == 'r' or val == 'x'):
                self._refinedOutputToken = 'outColorR'
            elif (val == 'g'):
                self._refinedOutputToken = 'outColorG'
            elif (val == 'y'):
                if (shaderSchema.GetOutput('out').GetTypeName() == 'Float'):
                    self._refinedOutputToken = 'outAlpha'
                else:
                    self._refinedOutputToken = 'outColorG'
            elif (val == 'b' or val == 'z'):
                self._refinedOutputToken = 'outColorB'
            elif (val == 'a' or val == 'w'):
                self._refinedOutputToken = 'outAlpha'
            else:
                print("Unsupported swizzle" + val)
                # TF_CODING_ERROR("Unsupported swizzle");


#            } else if (channels.size() == 3) {
#                // Triple channel swizzles must go to outColor:
#                self._refinedOutputToken = 'outColor';
#            }
        self._downstreamPrim = source.GetPrim()
        return downstreamSchema, sourceOutputName
    def testExportPxrRisShading(self):
        """
        Tests that exporting a Maya mesh with a simple Maya shading setup
        results in the correct shading on the USD mesh.
        """
        cubePrim = self._stage.GetPrimAtPath('/MarbleCube/Geom/Cube')
        self.assertTrue(cubePrim)

        # Validate the Material prim bound to the Mesh prim.
        materialBindingAPI = UsdShade.MaterialBindingAPI(cubePrim)
        material = materialBindingAPI.ComputeBoundMaterial()[0]
        self.assertTrue(material)
        materialPath = material.GetPath().pathString
        self.assertEqual(materialPath, '/MarbleCube/Materials/MarbleCubeSG')

        if Usd.GetVersion() >= (0, 21, 5):
            # For USD 21.05 and later, GetInputs() and GetOutputs() take an
            # "onlyAuthored" argument that is True by default, so in that case
            # we expect only one output on the material for the "surface"
            # terminal in the "ri" renderContext that the export should have
            # authored.
            expectedNumOutputs = 1
        else:
            # Otherwise prior to USD 21.05, GetInputs() and GetOutputs() did
            # not take any arguments and always included the built-in
            # terminals for the universal renderContext as well as any other
            # authored terminals.
            expectedNumOutputs = 4

        # Validate the surface shader that is connected to the material.
        materialOutputs = material.GetOutputs()
        self.assertEqual(len(materialOutputs), expectedNumOutputs)
        print(self._stage.ExportToString())
        materialOutput = material.GetOutput('ri:surface')
        (connectableAPI, outputName, outputType) = materialOutput.GetConnectedSource()
        self.assertEqual(outputName, 'out')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaMarble')

        # Validate the connected input on the surface shader.
        shaderInput = shader.GetInput('placementMatrix')
        self.assertTrue(shaderInput)

        (connectableAPI, outputName, outputType) = shaderInput.GetConnectedSource()
        self.assertEqual(outputName, 'worldInverseMatrix')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaPlacement3d')
    def testExportPxrRisShading(self):
        """
        Tests that exporting a Maya mesh with a simple Maya shading setup
        results in the correct shading on the USD mesh.
        """
        cubePrim = self._stage.GetPrimAtPath('/MarbleCube/Geom/Cube')
        self.assertTrue(cubePrim)

        # Validate the Material prim bound to the Mesh prim.
        material = UsdShade.Material.GetBoundMaterial(cubePrim)
        self.assertTrue(material)
        materialPath = material.GetPath().pathString
        self.assertEqual(materialPath, '/MarbleCube/Looks/MarbleCubeSG')

        # Validate the surface shader that is connected to the material.
        # XXX: Note that the expected number of outputs here is two rather than
        # one, since we are still authoring the UsdRi Bxdf source in addition
        # to the surface terminal for backwards compatibility. When consumers
        # are updated to use the surface terminal instead, this test will have
        # to be updated.
        materialOutputs = material.GetOutputs()
        self.assertEqual(len(materialOutputs), 2)
        materialOutput = material.GetOutput('surface')
        (connectableAPI, outputName,
         outputType) = materialOutput.GetConnectedSource()
        self.assertEqual(outputName, 'out')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)

        # XXX: Validate the UsdRi Bxdf. This must also be removed when we no
        # longer author it.
        from pxr import UsdRi
        usdRiMaterialAPI = UsdRi.MaterialAPI(material.GetPrim())
        self.assertTrue(usdRiMaterialAPI)
        bxdf = usdRiMaterialAPI.GetBxdf()
        self.assertEqual(bxdf.GetPrim(), shader.GetPrim())

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaMarble')

        # Validate the connected input on the surface shader.
        shaderInput = shader.GetInput('placementMatrix')
        self.assertTrue(shaderInput)

        (connectableAPI, outputName,
         outputType) = shaderInput.GetConnectedSource()
        self.assertEqual(outputName, 'worldInverseMatrix')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaPlacement3d')
    def testExportRfMShaders(self):
        '''
        Tests that exporting a Maya mesh with a simple Maya shading setup
        results in the correct shading on the USD mesh.
        '''
        cubePrim = self._stage.GetPrimAtPath('/MarbleCube/Geom/Cube')
        self.assertTrue(cubePrim)

        # Validate the Material prim bound to the Mesh prim.
        self.assertTrue(cubePrim.HasAPI(UsdShade.MaterialBindingAPI))
        materialBindingAPI = UsdShade.MaterialBindingAPI(cubePrim)
        material = materialBindingAPI.ComputeBoundMaterial()[0]
        self.assertTrue(material)
        materialPath = material.GetPath().pathString
        self.assertEqual(materialPath, '/MarbleCube/Materials/MarbleCubeSG')

        # We expect four outputs on the material, the three built-in terminals
        # for the universal renderContext, and a fourth for the "surface"
        # terminal in the "ri" renderContext that the export should have
        # authored.
        materialOutputs = material.GetOutputs()
        self.assertEqual(len(materialOutputs), 4)

        # Validate the lambert surface shader that is connected to the material.
        materialOutput = material.GetOutput('ri:surface')
        (connectableAPI, outputName, outputType) = materialOutput.GetConnectedSource()
        self.assertEqual(outputName, UsdShade.Tokens.surface)
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)
        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaLambert')

        # Validate the connected input on the lambert surface shader.
        shaderInput = shader.GetInput('color')
        self.assertTrue(shaderInput)
        (connectableAPI, outputName, outputType) = shaderInput.GetConnectedSource()
        self.assertEqual(outputName, 'outColor')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)
        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaMarble')

        # Validate the connected input on the marble shader.
        shaderInput = shader.GetInput('placementMatrix')
        self.assertTrue(shaderInput)
        (connectableAPI, outputName, outputType) = shaderInput.GetConnectedSource()
        self.assertEqual(outputName, 'worldInverseMatrix')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)
        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaPlacement3d')
    def testExportDisplacementShaders(self):
        '''
        Tests that exporting multiple Maya planes with varying displacement
        setups results in the expected USD data:
        '''

        textures = ["RGBA", "RGB", "MonoA", "Mono"]
        channels = ["r", "g", "b", "a", "a"]

        for suffix in range(1, 21):
            image = textures[int((suffix - 1) / 5)]
            channel = channels[(suffix - 1) % 5]

            mesh_prim = self._stage.GetPrimAtPath('/pPlane%i' % suffix)
            self.assertTrue(mesh_prim)

            # Validate the Material prim bound to the Mesh prim.
            self.assertTrue(mesh_prim.HasAPI(UsdShade.MaterialBindingAPI))
            mat_binding = UsdShade.MaterialBindingAPI(mesh_prim)
            material = mat_binding.ComputeBoundMaterial()[0]
            self.assertTrue(material)
            material_path = material.GetPath().pathString
            self.assertEqual(
                material_path,
                '/pPlane%i/Materials/blinn%iSG' % (suffix, suffix))

            self.assertTrue(material.ComputeSurfaceSource())
            self.assertTrue(material.ComputeDisplacementSource())

            # Validate the shader that is connected to the material.
            mat_out = material.GetOutput(UsdShade.Tokens.displacement)
            (connect_api, out_name, _) = mat_out.GetConnectedSource()
            self.assertEqual(out_name, UsdShade.Tokens.displacement)
            shader = UsdShade.Shader(connect_api)
            self.assertTrue(shader)
            shader_id = shader.GetIdAttr().Get()
            self.assertEqual(shader_id, 'UsdPreviewSurface')

            # Validate the connected input on the displacement shader.
            in_displacement = shader.GetInput('displacement')
            self.assertTrue(in_displacement)
            (connect_api, out_name, _) = in_displacement.GetConnectedSource()
            self.assertEqual(out_name, channel)
            shader = UsdShade.Shader(connect_api)
            self.assertTrue(shader)
            shader_id = shader.GetIdAttr().Get()
            self.assertEqual(shader_id, 'UsdUVTexture')
            filename = shader.GetInput("file")
            self.assertTrue(filename.Get().path.endswith("/%s.png" % image))
Exemplo n.º 7
0
    def _TestShading(self, stage, materialsPath):

        ConnAPI = UsdShade.ConnectableAPI
        # Create parent material
        parentMaterialPath = materialsPath.AppendChild('ParentMaterial')
        parentMaterial = UsdShade.Material.Define(stage, parentMaterialPath)
        floatInterfaceInput = parentMaterial.CreateInput(
            'floatVal', Sdf.ValueTypeNames.Float)
        parentShader1 = UsdShade.Shader.Define(
            stage, parentMaterialPath.AppendChild("Shader_1"))
        floatShaderInput = parentShader1.CreateInput('floatInput',
                                                     Sdf.ValueTypeNames.Float)
        floatShaderInput.Set(1.0)

        parentShader2 = UsdShade.Shader.Define(
            stage, parentMaterialPath.AppendChild("Shader_2"))
        floatShaderOutput = parentShader2.CreateOutput(
            'floatOutput', Sdf.ValueTypeNames.Float)

        self.assertTrue(
            ConnAPI.ConnectToSource(floatShaderInput, floatShaderOutput))

        print(stage.GetRootLayer().ExportToString())
        print(ConnAPI.GetConnectedSources(floatShaderInput))
        self.assertTrue(ConnAPI.HasConnectedSource(floatShaderInput))
        self.assertFalse(
            ConnAPI.IsSourceConnectionFromBaseMaterial(floatShaderInput))
        self.assertTrue(not parentMaterial.HasBaseMaterial())

        # Create child materials
        # one with SetBaseMaterial
        childMaterials = []
        childMaterialPath = materialsPath.AppendChild('ChildMaterial_1')
        childMaterial = UsdShade.Material.Define(stage, childMaterialPath)
        childMaterial.SetBaseMaterial(parentMaterial)
        childMaterials.append(childMaterial)

        # one with SetBaseMaterialPath
        childMaterialPath = materialsPath.AppendChild('ChildMaterial_2')
        childMaterial = UsdShade.Material.Define(stage, childMaterialPath)
        childMaterial.SetBaseMaterialPath(parentMaterialPath)
        childMaterials.append(childMaterial)

        # verify that material is found
        for childMaterial in childMaterials:
            self.assertTrue(childMaterial.HasBaseMaterial())
            self.assertEqual(childMaterial.GetBaseMaterialPath(),
                             parentMaterialPath)
            childShaderPath = childMaterial.GetPrim().GetPath().AppendChild(
                "Shader_1")
            childShaderPrim = stage.GetPrimAtPath(childShaderPath)

            # verify that inheritance is found and resolved
            self.assertEqual(bool(childShaderPrim), True)
            childShader = UsdShade.Shader(childShaderPrim)
            self.assertTrue(childShader)
            childShaderInput = childShader.GetInput('floatInput')
            self.assertEqual(childShaderInput.GetAttr().Get(), 1.0)
            self.assertTrue(
                ConnAPI.IsSourceConnectionFromBaseMaterial(childShaderInput))
Exemplo n.º 8
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)
Exemplo n.º 9
0
    def _CheckShader(self, prim):
        from pxr import Sdf, UsdShade
        self._Msg("Checking shader <%s>." % prim.GetPath())
        shader = UsdShade.Shader(prim)
        if not shader:
            self._AddError("Prim <%s> with typename 'Shader' is not a valid "
                           "shader." % prim.GetPath(),
                           ruleNum=8)
            return

        implSource = shader.GetImplementationSource()
        if implSource != UsdShade.Tokens.id:
            self._AddFailedCheck("Shader <%s> has non-id implementation "
                                 "source '%s'." % (prim.GetPath(), implSource),
                                 ruleNum=8)

        shaderId = shader.GetShaderId()
        if not shaderId or not shaderId.startswith('Usd'):
            self._AddFailedCheck("Shader <%s> has unsupported info:id '%s'." %
                                 (prim.GetPath(), shaderId),
                                 ruleNum=8)

        shaderInputs = shader.GetInputs()
        for ip in shaderInputs:
            if ip.GetTypeName() == Sdf.ValueTypeNames.Asset:
                texFilePath = str(ip.Get()).strip('@')
                self._CheckTexture(texFilePath)
            elif ip.GetTypeName() == Sdf.ValueTypeNames.AssetArray:
                texPathArray = ip.Get()
                texPathArray = [str(i).strip('@') for i in texPathArray]
                for texPath in texPathArray:
                    self._CheckTexture(texFilePath)
    def testShaderAttrsAuthoredSparsely(self):
        """
        Tests that only the attributes authored in Maya are exported to USD.
        """
        shaderPrimPath = '/MarbleCube/Looks/MarbleCubeSG/MarbleShader'
        shaderPrim = self._stage.GetPrimAtPath(shaderPrimPath)
        self.assertTrue(shaderPrim)

        shader = UsdShade.Shader(shaderPrim)
        self.assertTrue(shader)

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaMarble')

        shaderInputs = shader.GetInputs()
        self.assertEqual(len(shaderInputs), 3)

        inputOutAlpha = shader.GetInput('outAlpha').Get()
        self.assertTrue(Gf.IsClose(inputOutAlpha, 0.0894, 1e-6))

        inputOutColor = shader.GetInput('outColor').Get()
        self.assertTrue(Gf.IsClose(inputOutColor, Gf.Vec3f(0.298, 0.0, 0.0), 1e-6))

        inputPlacementMatrix = shader.GetInput('placementMatrix')
        (connectableAPI, outputName, outputType) = inputPlacementMatrix.GetConnectedSource()
        self.assertEqual(connectableAPI.GetPath().pathString,
            '/MarbleCube/Looks/MarbleCubeSG/MarbleCubePlace3dTexture')

        shaderOutputs = shader.GetOutputs()
        self.assertEqual(len(shaderOutputs), 1)
Exemplo n.º 11
0
    def testExportedUsdShadeNodeTypes(self):
        '''
        Tests that all node ids are what we expect:
        '''

        base_path = "/pCube{0}/Materials/{1}SG/{2}/{1}"
        to_test = [
            # pCube1 has standard_surface, known to UsdPreviewSurface and MaterialX
            (1, "standardSurface2", "UsdPreviewSurface", "UsdPreviewSurface"),
            (1, "standardSurface2", "MaterialX", "ND_standard_surface_surfaceshader"),
            # pCube2 has lambert, known to UsdPreviewSurface and RfM
            (2, "lambert2", "UsdPreviewSurface", "UsdPreviewSurface"),
            (2, "lambert2", "rendermanForMaya", "PxrMayaLambert"),
            # pCube3 has UsdPreviewSurface, known to UsdPreviewSurface and MaterialX
            (3, "usdPreviewSurface1", "UsdPreviewSurface", "UsdPreviewSurface"),
            (3, "usdPreviewSurface1", "MaterialX", "ND_UsdPreviewSurface_surfaceshader"),
        ]

        for prim_idx, shd_name, shd_scope, id_attr in to_test:
            prim_path = base_path.format(prim_idx, shd_name, shd_scope)

            prim = self._stage.GetPrimAtPath(prim_path)
            self.assertTrue(prim, prim_path)
            shader = UsdShade.Shader(prim)
            self.assertTrue(shader, prim_path)
            self.assertEqual(shader.GetIdAttr().Get(), id_attr)
Exemplo n.º 12
0
    def testUsdExportCustomConverter(self):
        """
        Tests a custom exporter for a conversion that exists in an unloaded
        plugin.
        """
        # Load test scene:
        file_path = os.path.join(self.input_path,
                                 "UsdExportCustomConverterTest",
                                 "testScene.ma")
        cmds.file(file_path, force=True, open=True)

        # Export to USD:
        usd_path = os.path.abspath('UsdExportCustomConverterTest.usda')

        # Using the "maya" material conversion, which only exists in the test
        # plugin
        options = ["shadingMode=useRegistry",
                   "convertMaterialsTo=maya",
                   "mergeTransformAndShape=1"]

        default_ext_setting = cmds.file(q=True, defaultExtensions=True)
        cmds.file(defaultExtensions=False)
        cmds.file(usd_path, force=True,
                  options=";".join(options),
                  typ="USD Export", pr=True, ea=True)
        cmds.file(defaultExtensions=default_ext_setting)

        # Make sure we have a Maya standardSurface material in the USD file:
        stage = Usd.Stage.Open(usd_path)
        material = stage.GetPrimAtPath(
            "/pCube1/Looks/standardSurface2SG/standardSurface2")
        shader = UsdShade.Shader(material)
        self.assertEqual(shader.GetIdAttr().Get(), "standardSurface")
Exemplo n.º 13
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")
Exemplo n.º 14
0
    def testExportStandaloneTransform2dTransformed(self):
        """
        Test that a material with transform 2D values exports with a UsdTransform2D shader and the
        correct values
        """

        root = self.stage.GetPrimAtPath(
            "/PxrUsdTransform2dExportTest/Looks/pxrUsdPreviewSurface_TransformedSG"
        )
        transform = findTransformPrim(root)
        self.assertTrue(transform, "Missing UsdTransform2D shader")

        shader = UsdShade.Shader(transform)
        translation_input = shader.GetInput('translation')
        rotation_input = shader.GetInput('rotation')
        scale_input = shader.GetInput('scale')

        expected_translation_value = (0.10104963, 0.19860554)
        expected_rotation_value = 0.2
        expected_scale_value = (0.8, 1)

        self.assertAlmostEqual(translation_input.Get(),
                               expected_translation_value)

        self.assertAlmostEqual(rotation_input.Get(), expected_rotation_value)

        self.assertEqual(scale_input.Get(), expected_scale_value)
Exemplo n.º 15
0
    def CheckPrim(self, prim):
        # Right now, we find texture referenced by looking at the asset-valued 
        # shader inputs. However, it is entirely legal to feed the "fileName" 
        # input of a UsdUVTexture shader from a UsdPrimvarReader_string. 
        # Hence, ideally we would also check "the right" primvars on 
        # geometry prims here.  However, identifying the right primvars is 
        # non-trivial. We probably need to pre-analyze all the materials. 
        # Not going to try to do this yet, but it raises an interesting 
        # validation pattern -
        from pxr import Sdf, UsdShade

        # Check if the prim is a shader. 
        if not prim.IsA(UsdShade.Shader):
            return

        shader = UsdShade.Shader(prim)
        shaderInputs = shader.GetInputs()
        for ip in shaderInputs:
            if ip.GetTypeName() == Sdf.ValueTypeNames.Asset:
                texFilePath = str(ip.Get()).strip('@')
                self._CheckTexture(texFilePath)
            elif ip.GetTypeName() == Sdf.ValueTypeNames.AssetArray:
                texPathArray = ip.Get()
                texPathArray = [str(i).strip('@') for i in texPathArray]
                for texPath in texPathArray:
                    self._CheckTexture(texFilePath)
Exemplo n.º 16
0
    def testShaderAttrsAuthoredSparsely(self):
        """
        Tests that only the attributes authored in Maya are exported to USD.
        """
        shaderPrimPath = '/MarbleCube/Materials/MarbleCubeSG/MarbleShader'
        shaderPrim = self._stage.GetPrimAtPath(shaderPrimPath)
        self.assertTrue(shaderPrim)

        shader = UsdShade.Shader(shaderPrim)
        self.assertTrue(shader)

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaMarble')

        shaderInputs = shader.GetInputs()
        self.assertEqual(len(shaderInputs), 1)

        inputPlacementMatrix = shader.GetInput('placementMatrix')
        (connectableAPI, outputName,
         outputType) = inputPlacementMatrix.GetConnectedSource()
        self.assertEqual(
            connectableAPI.GetPath().pathString,
            '/MarbleCube/Materials/MarbleCubeSG/MarbleCubePlace3dTexture')

        shaderOutputs = shader.GetOutputs()
        self.assertEqual(len(shaderOutputs), 1)
Exemplo n.º 17
0
def _AddShadingToBall(stage):
    from pxr import Sdf, UsdShade
    model = stage.OverridePrim('/Ball')
    texDir = os.path.join(ASSET_BASE, 'Ball/tex')
    mesh = stage.OverridePrim('/Ball/mesh')

    ballTexture = UsdShade.Shader(
        stage.OverridePrim(
            model.GetPath().AppendPath('Looks/BallMaterial/BallTexture')))

    # now we'll show adding some shading variants to the ball as well.
    shadingVariantsInfo = [
        ('Cue', '', _Color(0.996, 0.992, 0.874)),  # white
        ('Ball_1', '', _Color(1.000, 0.929, 0.184)),  # yellow
        ('Ball_2', '', _Color(0.157, 0.243, 0.631)),  # blue
        ('Ball_3', '', _Color(0.976, 0.212, 0.141)),  # red
        ('Ball_4', '', _Color(0.250, 0.156, 0.400)),  # purple
        ('Ball_5', '', _Color(0.980, 0.498, 0.184)),  # orange
        ('Ball_6', '', _Color(0.050, 0.255, 0.239)),  # green
        ('Ball_7', '', _Color(0.607, 0.059, 0.094)),  # darkred
        ('Ball_8', '', _Color(0.122, 0.118, 0.110)),  # black
        ('Ball_9', 'striped', _Color(1.000, 0.929, 0.184)),  # yellow
        ('Ball_10', 'striped', _Color(0.157, 0.243, 0.631)),  # blue
        ('Ball_11', 'striped', _Color(0.976, 0.212, 0.141)),  # red
        ('Ball_12', 'striped', _Color(0.250, 0.156, 0.400)),  # purple
        ('Ball_13', 'striped', _Color(0.980, 0.498, 0.184)),  # orange
        ('Ball_14', 'striped', _Color(0.050, 0.255, 0.239)),  # green
        ('Ball_15', 'striped', _Color(0.607, 0.059, 0.094)),  # darkred
    ]

    # create the shadingVariant variantSet
    shadingVariant = model.GetVariantSets().AddVariantSet('shadingVariant')
    for variantName, decoration, color in shadingVariantsInfo:
        # creates a variant inside 'shadingVariant'
        shadingVariant.AddVariant(variantName)

        # switch to that variant
        shadingVariant.SetVariantSelection(variantName)

        # this 'with' construct here tells Usd that authoring operations should
        # write to the shadingVariant.
        with shadingVariant.GetVariantEditContext():
            whichBall = variantName.split('_')[-1]
            texPath = os.path.join(texDir, 'ball%s.tex' % whichBall)
            # in the current variant, modify the color
            _SetParameters(ballTexture, [
                ('filename', Sdf.ValueTypeNames.String, texPath),
            ])

            # set the display color for hydra
            _SetDisplayColor(mesh, color)

            # currently not doing anything with decoration, but we could maybe
            # use this to make the solid vs. stripes.

    # now make the variant selection 'Cue' instead of the last variant that we
    # created above.
    shadingVariant.SetVariantSelection('Cue')
    def _GetSourceShader(self, inputOrOutput):
        (connectableAPI, _, _) = inputOrOutput.GetConnectedSource()
        self.assertTrue(connectableAPI.IsShader())
        shaderPrim = connectableAPI.GetPrim()
        self.assertTrue(shaderPrim)

        shader = UsdShade.Shader(shaderPrim)
        self.assertTrue(shader)

        return shader
Exemplo n.º 19
0
    def CheckPrim(self, prim):
        from pxr import UsdShade

        if not prim.IsA(UsdShade.Shader):
            return

        shader = UsdShade.Shader(prim)
        if not shader:
            # Error has already been issued by a Base-level checker
            return

        self._Msg("Checking shader <%s>." % prim.GetPath())

        implSource = shader.GetImplementationSource()
        if implSource != UsdShade.Tokens.id:
            self._AddFailedCheck("Shader <%s> has non-id implementation "
                                 "source '%s'." % (prim.GetPath(), implSource))

        shaderId = shader.GetShaderId()
        if not shaderId or \
           not (shaderId in [NodeTypes.UsdPreviewSurface,
                             NodeTypes.UsdUVTexture,
                             NodeTypes.UsdTransform2d] or
                shaderId.startswith(NodeTypes.UsdPrimvarReader)) :
            self._AddFailedCheck("Shader <%s> has unsupported info:id '%s'." %
                                 (prim.GetPath(), shaderId))

        # Check shader input connections
        shaderInputs = shader.GetInputs()
        for shdInput in shaderInputs:
            connections = shdInput.GetAttr().GetConnections()
            # If an input has one or more connections, ensure that the
            # connections are valid.
            if len(connections) > 0:
                if len(connections) > 1:
                    self._AddFailedCheck(
                        "Shader input <%s> has %s connection "
                        "sources, but only one is allowed." %
                        (shdInput.GetAttr.GetPath(), len(connections)))
                connectedSource = shdInput.GetConnectedSource()
                if connectedSource is None:
                    self._AddFailedCheck(
                        "Connection source <%s> for shader "
                        "input <%s> is missing." %
                        (connections[0], shdInput.GetAttr().GetPath()))
                else:
                    # The source must be a valid shader or material prim.
                    source = connectedSource[0]
                    if not source.GetPrim().IsA(UsdShade.Shader) and \
                       not source.GetPrim().IsA(UsdShade.Material):
                        self._AddFailedCheck(
                            "Shader input <%s> has an invalid "
                            "connection source prim of type '%s'." %
                            (shdInput.GetAttr().GetPath(),
                             source.GetPrim().GetTypeName()))
Exemplo n.º 20
0
    def testExportPxrRisShading(self):
        """
        Tests that exporting a Maya mesh with a simple Maya shading setup
        results in the correct shading on the USD mesh.
        """
        cubePrim = self._stage.GetPrimAtPath('/MarbleCube/Geom/Cube')
        self.assertTrue(cubePrim)

        # Validate the Material prim bound to the Mesh prim.
        materialBindingAPI = UsdShade.MaterialBindingAPI(cubePrim)
        material = materialBindingAPI.ComputeBoundMaterial()[0]
        self.assertTrue(material)
        materialPath = material.GetPath().pathString
        self.assertEqual(materialPath, '/MarbleCube/Materials/MarbleCubeSG')

        # Validate the surface shader that is connected to the material.
        materialOutputs = material.GetOutputs()
        self.assertEqual(len(materialOutputs), 4)
        print self._stage.ExportToString()
        materialOutput = material.GetOutput('ri:surface')
        (connectableAPI, outputName,
         outputType) = materialOutput.GetConnectedSource()
        self.assertEqual(outputName, 'out')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaMarble')

        # Validate the connected input on the surface shader.
        shaderInput = shader.GetInput('placementMatrix')
        self.assertTrue(shaderInput)

        (connectableAPI, outputName,
         outputType) = shaderInput.GetConnectedSource()
        self.assertEqual(outputName, 'worldInverseMatrix')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaPlacement3d')
Exemplo n.º 21
0
    def testShaderAttrsAuthoredSparsely(self):
        '''
        Tests that only the attributes authored in Maya are exported to USD.
        '''
        shaderPrimPath = '/MarbleCube/Materials/MarbleCubeSG/MarbleLambert'
        shaderPrim = self._stage.GetPrimAtPath(shaderPrimPath)
        self.assertTrue(shaderPrim)
        shader = UsdShade.Shader(shaderPrim)
        self.assertTrue(shader)
        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaLambert')
        shaderInputs = shader.GetInputs()
        self.assertEqual(len(shaderInputs), 1)

        # We actually expect two outputs on the "top-level" shader. The Maya
        # node this shader came from would have had an "outColor" output that
        # should have been translated, and then a "surface" output should have
        # been created when the shader was bound into the Material.
        shaderOutputs = shader.GetOutputs()
        self.assertEqual(len(shaderOutputs), 2)
        outputNames = {o.GetBaseName() for o in shaderOutputs}
        self.assertEqual(outputNames, set(['outColor', 'surface']))

        # Traverse the network down to the marble shader
        shaderInput = shader.GetInput('color')
        self.assertTrue(shaderInput)
        (connectableAPI, outputName,
         outputType) = shaderInput.GetConnectedSource()
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)

        inputPlacementMatrix = shader.GetInput('placementMatrix')
        (connectableAPI, outputName,
         outputType) = inputPlacementMatrix.GetConnectedSource()
        self.assertEqual(
            connectableAPI.GetPath().pathString,
            '/MarbleCube/Materials/MarbleCubeSG/MarbleCubePlace3dTexture')
        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrMayaMarble')
        shaderOutputs = shader.GetOutputs()
        self.assertEqual(len(shaderOutputs), 1)
Exemplo n.º 22
0
def findTransformPrim(root):
    for prim in root.GetAllChildren():
        if not prim.IsA(UsdShade.Shader):
            continue

        shader = UsdShade.Shader(prim)
        shader_type = shader.GetIdAttr().Get()
        if shader_type == "UsdTransform2d":
            return prim

        transform = findTransformPrim(prim)
        if transform:
            return transform
Exemplo n.º 23
0
    def read_from_usd(self,
                      file_path,
                      scene_path,
                      texture_path=None,
                      time=None):
        r"""Read material from USD.

        Args:
            file_path (str): Path to usd file (\*.usd, \*.usda).
            scene_path (str): Absolute path of UsdShade.Material prim within the USD file scene.
                Must be a valid ``Sdf.Path``.
            texture_path (str, optional): Path to textures directory. If the USD has absolute paths
                to textures, set to an empty string. By default, the textures will be assumed to be
                under the same directory as the USD specified by `file_path`.
            time (convertible to float, optional): Positive integer indicating the time at which to retrieve parameters.
        """
        if time is None:
            time = Usd.TimeCode.Default()
        if texture_path is None:
            texture_file_path = os.path.dirname(file_path)
        else:
            usd_dir = os.path.dirname(file_path)
            texture_file_path = posixpath.join(usd_dir, texture_path)
        stage = Usd.Stage.Open(file_path)
        material = UsdShade.Material(stage.GetPrimAtPath(scene_path))
        assert material

        surface_shader = material.GetSurfaceOutput().GetConnectedSource()[0]
        shader = UsdShade.Shader(surface_shader)
        if shader.GetImplementationSourceAttr().Get(time=time) == 'id':
            shader_name = UsdShade.Shader(surface_shader).GetShaderId()
        else:
            raise NotImplementedError

        material_params = _get_shader_parameters(surface_shader, time)

        reader = self.shaders[shader_name]['reader']
        return reader(material_params, texture_file_path, time)
Exemplo n.º 24
0
    def _SetupStage(self):
        stage = Usd.Stage.CreateInMemory()

        UsdGeom.Scope.Define(stage, "/Model")
        UsdGeom.Scope.Define(stage, "/Model/Materials")
        UsdShade.Material.Define(stage, "/Model/Materials/MaterialSharp")

        pale = UsdShade.Shader.Define(stage, palePath)
        self.assertTrue(pale)
        whiterPale = UsdShade.Shader.Define(stage, whiterPalePath)
        self.assertTrue(whiterPale)

        # Make a class for pale so we can test that disconnecting/blocking works
        classPale = stage.CreateClassPrim(classPalePath)
        self.assertTrue(classPale)
        pale.GetPrim().GetInherits().AppendInherit(classPalePath)
        shaderClass = UsdShade.Shader(classPale)
        # it's not valid because it's not defined, but we can still author using it
        self.assertTrue(not shaderClass)

        return stage
Exemplo n.º 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)
Exemplo n.º 26
0
    def testExportTexturedMaterialXpPlane1(self):
        '''
        Tests that pPlane1 exported as planned:

        this plane is a basic RGB texture without any customizations.
        '''
        cmds.file(f=True, new=True)

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

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

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

        # Exploring this path:
        base_path = "/pPlane1/Materials/standardSurface2SG"

        mesh_prim = stage.GetPrimAtPath('/pPlane1')
        self.assertTrue(mesh_prim)

        # Validate the Material prim bound to the Mesh prim.
        self.assertTrue(mesh_prim.HasAPI(UsdShade.MaterialBindingAPI))
        mat_binding = UsdShade.MaterialBindingAPI(mesh_prim)
        mat = mat_binding.ComputeBoundMaterial("mtlx")[0]
        self.assertTrue(mat)
        material_path = mat.GetPath().pathString
        self.assertEqual(material_path, base_path)

        # Needs a resolved inputs:file1:varnameStr attribute:
        self.assertEqual(mat.GetInput("file1:varnameStr").GetAttr().Get(), "st")

        # Needs a MaterialX surface source:
        shader = mat.ComputeSurfaceSource("mtlx")[0]
        self.assertTrue(shader)

        # Which is a standard surface:
        self.assertEqual(shader.GetIdAttr().Get(),
                         "ND_standard_surface_surfaceshader")

        # With a connected file texture on base_color going to baseColor on the
        # nodegraph:
        attr = shader.GetInput('base_color')
        self.assertTrue(attr)
        cnxTuple = attr.GetConnectedSource()
        self.assertTrue(cnxTuple)

        ng_path = base_path + '/MayaNG_standardSurface2SG'
        ng = UsdShade.NodeGraph(cnxTuple[0])
        self.assertEqual(ng.GetPath(), ng_path)
        self.assertEqual(cnxTuple[1], "baseColor")

        # Should have an outputs connected to a file node:
        attr = ng.GetOutput('baseColor')
        self.assertTrue(attr)
        cnxTuple = attr.GetConnectedSource()
        self.assertTrue(cnxTuple)

        # Which is a color3 image:
        shader = UsdShade.Shader(cnxTuple[0])
        self.assertEqual(shader.GetIdAttr().Get(), "ND_image_color3")
        self.assertEqual(shader.GetPath(), ng_path + "/file1")

        # Check a few values:
        self.assertTrue(self.compareValue(shader, "uaddressmode", "periodic"))
        self.assertTrue(self.compareValue(shader, "default", (0.5, 0.5, 0.5)))

        # Which is itself connected to a primvar reader:
        attr = shader.GetInput('texcoord')
        self.assertTrue(attr)
        cnxTuple = attr.GetConnectedSource()
        self.assertTrue(cnxTuple)

        # Which is a geompropvalue node:
        shader = UsdShade.Shader(cnxTuple[0])
        self.assertEqual(shader.GetIdAttr().Get(), "ND_geompropvalue_vector2")
        self.assertEqual(shader.GetPath(),
                         ng_path + "/place2dTexture1")

        base_path = "/pPlane{0}/Materials/standardSurface{1}SG/MayaNG_standardSurface{1}SG/{2}"
        to_test = [
            (7, 8, "file7", "ND_image_float"),
            (6, 7, "file6", "ND_image_vector2"),
            (1, 2, "file1", "ND_image_color3"),
            (4, 5, "file4", "ND_image_color4"),

            (1, 2, "place2dTexture1", "ND_geompropvalue_vector2"),

            (4, 5, "MayaSwizzle_file4_rgb", "ND_swizzle_color4_color3"),
            (6, 7, "MayaSwizzle_file6_xxx", "ND_swizzle_vector2_color3"),
            (19, 21, "MayaSwizzle_file20_x", "ND_swizzle_vector2_float"),
            (7, 8, "MayaSwizzle_file7_rrr", "ND_swizzle_float_color3"),
            (8, 9, "MayaSwizzle_file8_r", "ND_swizzle_color4_float"),
            (13, 14, "MayaSwizzle_file13_g", "ND_swizzle_color3_float"),

            (27, 20, "MayaLuminance_file27", "ND_luminance_color3"),
            (12, 13, "MayaLuminance_file12", "ND_luminance_color4"),

            (14, 15, "MayaConvert_file14_color3f_float3", 
             "ND_convert_color3_vector3"),
            (15, 16, "MayaNormalMap_standardSurface16_normalCamera",
             "ND_normalmap"),
        ]

        for prim_idx, sg_idx, node_name, id_attr in to_test:
            prim_path = base_path.format(prim_idx, sg_idx, node_name)

            prim = stage.GetPrimAtPath(prim_path)
            self.assertTrue(prim, prim_path)
            shader = UsdShade.Shader(prim)
            self.assertTrue(shader, prim_path)
            self.assertEqual(shader.GetIdAttr().Get(), id_attr, id_attr)
Exemplo n.º 27
0
def convert_to_usd(gltf_file,
                   usd_file,
                   fps,
                   scale,
                   arkit=False,
                   verbose=False,
                   use_euler_rotation=False,
                   optimize_textures=False,
                   generate_texture_transform_texture=True,
                   scale_texture=False):
    """Converts a glTF file to USD

    Arguments:
        gltf_file {str} -- path to glTF file
        usd_file {str} -- path to write USD file

    Keyword Arguments:
        verbose {bool} -- [description] (default: {False})
    """
    temp_dir = tempfile.mkdtemp()
    temp_usd_file = os.path.join(temp_dir, ntpath.basename(usd_file))
    try:
        usd = GLTF2USD(gltf_file=gltf_file,
                       usd_file=temp_usd_file,
                       fps=fps,
                       scale=scale,
                       verbose=verbose,
                       use_euler_rotation=use_euler_rotation,
                       optimize_textures=optimize_textures,
                       generate_texture_transform_texture=
                       generate_texture_transform_texture,
                       scale_texture=scale_texture)
        if usd.stage:
            asset = usd.stage.GetRootLayer()
            gltf_asset = usd.gltf_loader.get_asset()
            if gltf_asset:
                gltf_metadata = {'creator': 'gltf2usd v{}'.format(__version__)}
                if gltf_asset.generator:
                    gltf_metadata['gltf_generator'] = gltf_asset.generator
                if gltf_asset.version:
                    gltf_metadata['gltf_version'] = gltf_asset.version
                if gltf_asset.minversion:
                    gltf_metadata['gltf_minversion'] = gltf_asset.minversion
                if gltf_asset.copyright:
                    gltf_metadata['gltf_copyright'] = gltf_asset.copyright
                if gltf_asset.extras:
                    for key, value in gltf_asset.extras.items():
                        gltf_metadata['gltf_extras_{}'.format(key)] = value
                asset.customLayerData = gltf_metadata

            usd.logger.info('Conversion complete!')

            asset.Save()
            usd.logger.info('created {}'.format(asset.realPath))
            if not os.path.isdir(os.path.dirname(usd_file)):
                os.makedirs(os.path.dirname(usd_file))

            if temp_usd_file.endswith('.usdz') or temp_usd_file.endswith(
                    '.usdc'):
                usdc_file = '%s.%s' % (os.path.splitext(temp_usd_file)[0],
                                       'usdc')
                asset.Export(usdc_file, args=dict(format='usdc'))
                usd.logger.info('created {}'.format(usdc_file))

            if temp_usd_file.endswith('.usdz'):
                #change to directory of the generated usd files to avoid issues with
                # relative paths with CreateNewUsdzPackage
                os.chdir(os.path.dirname(usdc_file))
                temp_usd_file = ntpath.basename(temp_usd_file)
                r = Ar.GetResolver()
                resolved_asset = r.Resolve(ntpath.basename(usdc_file))
                context = r.CreateDefaultContextForAsset(resolved_asset)

                success = check_usd_compliance(resolved_asset,
                                               arkit=args.arkit)
                with Ar.ResolverContextBinder(context):
                    if arkit and not success:
                        usd.logger.warning('USD is not ARKit compliant')
                        return

                    success = UsdUtils.CreateNewUsdzPackage(
                        resolved_asset, temp_usd_file) and success
                    if success:
                        shutil.copyfile(temp_usd_file, usd_file)
                        usd.logger.info(
                            'created package {} with contents:'.format(
                                usd_file))
                        zip_file = Usd.ZipFile.Open(usd_file)
                        file_names = zip_file.GetFileNames()
                        for file_name in file_names:
                            usd.logger.info('\t{}'.format(file_name))
                    else:
                        usd.logger.error(
                            'could not create {}'.format(usd_file))
            else:
                # Copy textures referenced in the Usda/Usdc files from the temp directory to the target directory
                temp_stage = Usd.Stage.Open(temp_usd_file)
                usd_uv_textures = [
                    x for x in temp_stage.Traverse() if x.IsA(UsdShade.Shader)
                    and UsdShade.Shader(x).GetShaderId() == 'UsdUVTexture'
                ]

                for usd_uv_texture in usd_uv_textures:
                    file_name = usd_uv_texture.GetAttribute(
                        'inputs:file').Get()
                    if file_name:
                        file_name = str(file_name).replace('@', '')

                        if os.path.isfile(os.path.join(temp_dir, file_name)):
                            shutil.copyfile(
                                os.path.join(temp_dir, file_name),
                                os.path.join(os.path.dirname(usd_file),
                                             file_name))
                shutil.copyfile(temp_usd_file, usd_file)
    finally:
        shutil.rmtree(temp_dir)
Exemplo n.º 28
0
    def CheckPrim(self, prim):
        from pxr import UsdShade, Gf
        from pxr.UsdShade import Utils as ShadeUtils

        if not prim.IsA(UsdShade.Shader):
            return

        shader = UsdShade.Shader(prim)
        if not shader:
            self._AddError("Invalid shader prim <%s>." % prim.GetPath())
            return

        shaderId = self._GetShaderId(shader)

        # We may have failed to fetch an identifier for asset/source-based
        # nodes. We are only interested in UsdPreviewSurface nodes identified via
        # info:id, so it's not an error
        if not shaderId or shaderId != NodeTypes.UsdPreviewSurface:
            return

        normalInput = shader.GetInput(ShaderProps.Normal)
        if not normalInput:
            return
        valueProducingAttrs = ShadeUtils.GetValueProducingAttributes(
            normalInput)
        if not valueProducingAttrs or valueProducingAttrs[0].GetPrim() == prim:
            return

        sourcePrim = valueProducingAttrs[0].GetPrim()

        sourceShader = UsdShade.Shader(sourcePrim)
        if not sourceShader:
            # In theory, could be connected to an interface attribute of a
            # parent connectable... not useful, but not an error
            if UsdShade.ConnectableAPI(sourcePrim):
                return
            self._AddFailedCheck("%s.%s on prim <%s> is connected to a"
                                 " non-Shader prim." % \
                                 (NodeTypes.UsdPreviewSurface,
                                  ShaderProps.Normal))
            return

        sourceId = self._GetShaderId(sourceShader)

        # We may have failed to fetch an identifier for asset/source-based
        # nodes. OR, we could potentially be driven by a UsdPrimvarReader,
        # in which case we'd have nothing to validate
        if not sourceId or sourceId != NodeTypes.UsdUVTexture:
            return

        texAsset = self._GetInputValue(sourceShader, ShaderProps.File)

        if not texAsset or not texAsset.resolvedPath:
            self._AddFailedCheck("%s prim <%s> has invalid or unresolvable "
                                 "inputs:file of @%s@" % \
                                 (NodeTypes.UsdUVTexture,
                                  sourcePrim.GetPath(),
                                  texAsset.path if texAsset else ""))
            return

        if not self._TextureIs8Bit(texAsset):
            # really nothing more is required for image depths > 8 bits,
            # which we assume FOR NOW, are floating point
            return

        if not self._GetInputValue(sourceShader, ShaderProps.SourceColorSpace):
            self._AddWarning("%s prim <%s> that reads Normal Map @%s@ may need "
                             "to set inputs:sourceColorSpace to 'raw' as some "
                             "8-bit image writers always indicate an SRGB "
                             "encoding." % \
                             (NodeTypes.UsdUVTexture,
                              sourcePrim.GetPath(),
                              texAsset.path))

        bias = self._GetInputValue(sourceShader, ShaderProps.Bias)

        scale = self._GetInputValue(sourceShader, ShaderProps.Scale)

        if not (bias and scale and isinstance(bias, Gf.Vec4f)
                and isinstance(scale, Gf.Vec4f)):
            # XXX This should be a failure, as it results in broken normal
            # maps in Storm and hdPrman, at least.  But for the same reason
            # as the shader-under-shader check, we cannot fail until at least
            # the major authoring tools have been updated.
            self._AddWarning("%s prim <%s> reads 8 bit Normal Map @%s@, "
                             "which requires that inputs:scale be set to "
                             "[2, 2, 2, 1] and inputs:bias be set to "
                             "[-1, -1, -1, 0] for proper interpretation." %\
                             (NodeTypes.UsdUVTexture,
                              sourcePrim.GetPath(),
                              texAsset.path))
            return

        # don't really care about fourth components...
        if (bias[0] != -1 or bias[1] != -1 or bias[2] != -1 or scale[0] != 2
                or scale[1] != 2 or scale[2] != 2):
            self._AddWarning("%s prim <%s> reads an 8 bit Normal Map, "
                             "but has non-standard inputs:scale and "
                             "inputs:bias values of %s and %s" %\
                             (NodeTypes.UsdUVTexture,
                              sourcePrim.GetPath(),
                              str(scale), str(bias)))
Exemplo n.º 29
0
    def testExportDisplayColorShading(self):
        """
        Tests that exporting a Maya mesh with a simple Maya shading setup
        results in the correct shading on the USD mesh.
        """
        # Validate the displayColor on the mesh prim.
        cubePrim = self._stage.GetPrimAtPath('/RedCube/Geom/Cube')
        self.assertTrue(cubePrim)

        cubeMesh = UsdGeom.Mesh(cubePrim)
        self.assertTrue(cubeMesh)

        meshDisplayColors = cubeMesh.GetDisplayColorPrimvar().Get()
        self.assertEqual(len(meshDisplayColors), 1)
        self.assertTrue(Gf.IsClose(meshDisplayColors[0], self.RED_COLOR, 1e-6))

        # Validate the Material prim bound to the Mesh prim.
        material = UsdShade.Material.GetBoundMaterial(cubePrim)
        self.assertTrue(material)
        materialPath = material.GetPath().pathString
        self.assertEqual(materialPath, '/RedCube/Looks/RedLambertSG')

        materialInputs = material.GetInputs()
        self.assertEqual(len(materialInputs), 3)

        materialInput = material.GetInput('displayColor')
        matDisplayColor = materialInput.Get()
        self.assertTrue(Gf.IsClose(matDisplayColor, self.RED_COLOR, 1e-6))

        # Just verify that displayOpacity and transparency exist.
        materialInput = material.GetInput('displayOpacity')
        self.assertTrue(materialInput)

        materialInput = material.GetInput('transparency')
        self.assertTrue(materialInput)

        # Validate the surface shader that is connected to the material.
        materialOutputs = material.GetOutputs()
        self.assertEqual(len(materialOutputs), 4)
        print(self._stage.ExportToString())
        materialOutput = material.GetOutput('ri:surface')
        (connectableAPI, outputName,
         outputType) = materialOutput.GetConnectedSource()
        self.assertEqual(outputName, 'out')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)
        self.assertEqual(shader.GetPrim().GetName(), 'RedLambertSG_lambert')

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrDiffuse')

        shaderInputs = shader.GetInputs()
        self.assertEqual(len(shaderInputs), 2)

        diffuseInput = shader.GetInput('diffuseColor')
        self.assertTrue(diffuseInput)
        (connectableAPI, outputName,
         outputType) = diffuseInput.GetConnectedSource()
        self.assertEqual(outputName, 'displayColor')
        self.assertTrue(connectableAPI)
        self.assertEqual(connectableAPI.GetPath().pathString, materialPath)

        transmissionInput = shader.GetInput('transmissionColor')
        self.assertTrue(transmissionInput)
        (connectableAPI, outputName,
         outputType) = transmissionInput.GetConnectedSource()
        self.assertEqual(outputName, 'transparency')
        self.assertTrue(connectableAPI)
        self.assertEqual(connectableAPI.GetPath().pathString, materialPath)
Exemplo n.º 30
0
    def testExportDisplayColorShading(self):
        """
        Tests that exporting a Maya mesh with a simple Maya shading setup
        results in the correct shading on the USD mesh.
        """
        # Validate the displayColor on the mesh prim.
        cubePrim = self._stage.GetPrimAtPath('/RedCube/Geom/Cube')
        self.assertTrue(cubePrim)

        cubeMesh = UsdGeom.Mesh(cubePrim)
        self.assertTrue(cubeMesh)

        meshDisplayColors = cubeMesh.GetDisplayColorPrimvar().Get()
        self.assertEqual(len(meshDisplayColors), 1)
        self.assertTrue(Gf.IsClose(meshDisplayColors[0], self.RED_COLOR, 1e-6))

        # Validate the Material prim bound to the Mesh prim.
        material = UsdShade.Material.GetBoundMaterial(cubePrim)
        self.assertTrue(material)
        materialPath = material.GetPath().pathString
        self.assertEqual(materialPath, '/RedCube/Looks/RedLambertSG')

        materialInputs = material.GetInputs()
        self.assertEqual(len(materialInputs), 3)

        materialInput = material.GetInput('displayColor')
        matDisplayColor = materialInput.Get()
        self.assertTrue(Gf.IsClose(matDisplayColor, self.RED_COLOR, 1e-6))

        # Just verify that displayOpacity and transparency exist.
        materialInput = material.GetInput('displayOpacity')
        self.assertTrue(materialInput)

        materialInput = material.GetInput('transparency')
        self.assertTrue(materialInput)

        # Validate the surface shader that is connected to the material.
        # XXX: Note that the expected number of outputs here is two rather than
        # one, since we are still authoring the UsdRi Bxdf source in addition
        # to the surface terminal for backwards compatibility. When consumers
        # are updated to use the surface terminal instead, this test will have
        # to be updated.
        materialOutputs = material.GetOutputs()
        self.assertEqual(len(materialOutputs), 2)
        materialOutput = material.GetOutput('surface')
        (connectableAPI, outputName,
         outputType) = materialOutput.GetConnectedSource()
        self.assertEqual(outputName, 'out')
        shader = UsdShade.Shader(connectableAPI)
        self.assertTrue(shader)
        self.assertEqual(shader.GetPrim().GetName(), 'RedLambertSG_lambert')

        # XXX: Validate the UsdRi Bxdf. This must also be removed when we no
        # longer author it.
        from pxr import UsdRi
        usdRiMaterialAPI = UsdRi.MaterialAPI(material.GetPrim())
        self.assertTrue(usdRiMaterialAPI)
        bxdf = usdRiMaterialAPI.GetBxdf()
        self.assertEqual(bxdf.GetPrim(), shader.GetPrim())

        shaderId = shader.GetIdAttr().Get()
        self.assertEqual(shaderId, 'PxrDiffuse')

        shaderInputs = shader.GetInputs()
        self.assertEqual(len(shaderInputs), 2)

        diffuseInput = shader.GetInput('diffuseColor')
        self.assertTrue(diffuseInput)
        (connectableAPI, outputName,
         outputType) = diffuseInput.GetConnectedSource()
        self.assertEqual(outputName, 'displayColor')
        self.assertTrue(connectableAPI)
        self.assertEqual(connectableAPI.GetPath().pathString, materialPath)

        transmissionInput = shader.GetInput('transmissionColor')
        self.assertTrue(transmissionInput)
        (connectableAPI, outputName,
         outputType) = transmissionInput.GetConnectedSource()
        self.assertEqual(outputName, 'transparency')
        self.assertTrue(connectableAPI)
        self.assertEqual(connectableAPI.GetPath().pathString, materialPath)