// ------------------------------------------------------------------------------------------ // // 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); }