示例#1
0
        // ------------------------------------------------------------------------------------------ //
        // Helper functions.
        // ------------------------------------------------------------------------------------------ //

        /// <summary>
        /// Reads the material associated with the geometry at the target path. If a valid material is
        /// bound, the "surface" shader is inspected, if valid, the shader ID is queried and returned
        /// via the shaderId output parameter. Returns true when shaderId is set.
        /// </summary>
        static public bool ReadMaterial(Scene scene,
                                        string geometryPath,
                                        MaterialSample materialSample,
                                        out string shaderId)
        {
            // Discover the material bound to the geometry.
            // Note that with this structure, the geometry type does not matter.
            var geomMaterialBinding = new MaterialBindingSample();

            // Discover the binding for the geometry.
            // Note that the details of how to import geometry is handled in a different example.
            scene.Read(geometryPath, geomMaterialBinding);

            // In general, there is no guarantee that any prim is bound, so this null check is always
            // required.
            if (geomMaterialBinding.binding.targetPaths == null)
            {
                // In this example, exceptions are thrown on invalid data, but in practice invalid bindings
                // should probably be collected into a summary report and emitted as a single warning.
                throw new System.Exception("Expected bound material");
            }

            // Similarly, there is no guarantee the source file is well formed, so an invalid number of
            // target paths must also be handled.
            if (geomMaterialBinding.binding.targetPaths.Length != 1)
            {
                throw new System.Exception("Expected exactly one target path for material binding");
            }

            // Read the material, which will provide the shader binding.
            scene.Read(geomMaterialBinding.binding.targetPaths[0], materialSample);

            // Again, the surface may be invalid, so protect against broken scene description.
            if (materialSample.surface == null || string.IsNullOrEmpty(materialSample.surface.connectedPath))
            {
                throw new System.Exception("Material had no surface bound");
            }

            string shaderPath = materialSample.surface.connectedPath.Replace(".outputs:out", "");
            var    prim       = scene.Stage.GetPrimAtPath(new pxr.SdfPath(shaderPath));

            if (prim == null || !prim.IsValid())
            {
                throw new System.Exception("Invalid shader prim");
            }

            var val = new VtValue();

            if (!prim.GetAttributeValue(new TfToken("info:id"), val, scene.Time ?? UsdTimeCode.Default()))
            {
                throw new System.Exception("Shader prim had no identifier");
            }

            shaderId = pxr.UsdCs.VtValueToTfToken(val).ToString();
            return(true);
        }
        /// <summary>
        /// Serializes the attribute value to USD-ASCII and writes it to Debug.Log.
        /// </summary>
        void DebugPrintAttr(Scene srcScene, UsdAttribute attr, UsdTimeCode time)
        {
            // Copy the desired attribute into a temp scene, with nothing other than this one attr.
            var tmpScene = Scene.Create();

            // Up-Axis is unrelated to the attribute, but it makes the generated USDA look more correct,
            // since it will include an up-axis.
            tmpScene.UpAxis = srcScene.UpAxis;

            // Define the owning prim for the attribute.
            var tmpPrim = tmpScene.Stage.DefinePrim(attr.GetPath().GetPrimPath(), attr.GetPrim().GetTypeName());

            // Define the attribute itself.
            var tmpAttr = tmpPrim.CreateAttribute(attr.GetName(), attr.GetTypeName());

            // Gather the default value and the value at the current time.
            var defaultVal = attr.Get(UsdTimeCode.Default());
            var valAtTime  = attr.Get(time);

            // Copy them to the new attribute.
            if (!defaultVal.IsEmpty())
            {
                tmpAttr.Set(defaultVal);
            }

            if (attr.ValueMightBeTimeVarying())
            {
                tmpAttr.Set(valAtTime, time);
            }

            // If this is an array, get the size.
            var arraySize = -1;

            if (valAtTime.IsArrayValued())
            {
                arraySize = (int)valAtTime.GetArraySize();
            }

            // Metadata cannot be time-varying.
            UsdMetadataValueMap metaData = attr.GetAllMetadata();

            foreach (var key in metaData.GetKeys())
            {
                tmpAttr.SetMetadata(key, metaData.GetValue(key));
            }

            // Export the single attribute to a string.
            var stringified = "";

            tmpScene.Stage.ExportToString(out stringified, addSourceFileComment: false);

            // Dispose the tmp scene.
            tmpScene.Close();
            tmpScene = null;

            // Print.
            if (arraySize > -1)
            {
                stringified = "Array Size: " + arraySize + "\n" + stringified;
            }

            Debug.Log("Path: <" + attr.GetPath().ToString() + ">\n" + stringified);
        }