/// <summary> /// Get a binding from a USD type /// </summary> /// <remarks> /// Used the C# type needs to be derived from the USD type. /// Example: UVs can be of type float2, float3, texcoord2f, texcoord2f /// </remarks> public bool GetReverseBinding(pxr.SdfValueTypeName key, out UsdTypeBinding binding) { // Check if the given sdf type name is an alias // https://graphics.pixar.com/usd/docs/api/_usd__page__datatypes.html#Usd_Roles string name; bool match = true; if (!typeAliases.TryGetValue(key.GetAsToken(), out name)) { name = key.GetAsToken(); match = false; } // TODO: we could keep a reverse mapping, but waiting for deeper performance analysis first. foreach (var kvp in bindings) { if (kvp.Value.sdfTypeName.GetAsToken() == name) { binding = kvp.Value; return(true); } } binding = new UsdTypeBinding(); return(false); }
public bool GetBinding(Type key, out UsdTypeBinding binding) { lock (UsdIo.Bindings) { if (bindings.TryGetValue(key, out binding)) { return(true); } if (!key.IsEnum) { return(false); } // // Enumerations. // To reduce special cases of client code, all enums are special cased into a single // converter. This converter is only selected if no specific type has been registered. // binding = BindEnum(key); // Memoize the binding so it doesn't get regenerated on every call. bindings.Add(key, binding); } return(true); }
public bool GetReverseBinding(Type key, out UsdTypeBinding binding) { // TODO: we could keep a reverse mapping, but waiting for deeper performance analysis first. foreach (var kvp in bindings) { if (kvp.Value.toCsObject.Method.GetParameters()[0].ParameterType == key) { binding = kvp.Value; return(true); } } binding = new UsdTypeBinding(); return(false); }
public bool GetReverseBinding(pxr.SdfValueTypeName key, out UsdTypeBinding binding) { // TODO: we could keep a reverse mapping, but waiting for deeper performance analysis first. foreach (var kvp in bindings) { if (kvp.Value.sdfTypeName == key) { binding = kvp.Value; return(true); } } binding = new UsdTypeBinding(); return(false); }
public void BindNativeType(Type csType, pxr.SdfValueTypeName sdfName) { string name; if (!typeNameMapping.TryGetValue(csType.Name, out name)) { name = csType.Name; } var converter = typeof(pxr.UsdCs).GetMethod("VtValueTo" + name, new Type[] { typeof(pxr.VtValue) }); if (converter == null) { throw new ArgumentException(string.Format("No VtValueTo... converter found for type {0}, VtValueTo{1}", csType.ToString(), name)); } bindings[csType] = new UsdTypeBinding(DefaultConversions.ToVtValue, (x) => converter.Invoke(null, new object[] { x }), sdfName); }
/// <summary> /// Binds the specified C# type to the given USD array and scene description (Sdf) types, /// looking for ConverterT.ToVtArray(csType) and ConverterT.FromVtArray(vtArrayType). /// </summary> /// /// <typeparam name="ConverterT"> /// The C# class type providing type conversion rules ToVtArray and FromVtArray. /// </typeparam> /// /// <param name="csType">The C# type to be mapped to USD</param> /// <param name="vtArrayType">The USD C++ value type (Vt)</param> /// <param name="sdfName">The USD scene description (Sdf) type</param> /// /// TODO: The C++ type can be inferred from the Sdf type, so vtArrayType is not needed. /// public void BindArrayType <ConverterT>(Type csType, Type vtArrayType, pxr.SdfValueTypeName sdfName, string methodNamePrefix = "") { var csToVtArray = typeof(ConverterT) .GetMethod(methodNamePrefix + "ToVtArray", new Type[] { csType }); if (csToVtArray == null) { throw new ArgumentException(string.Format("No ToVtArray overload found for type {0}", csType.ToString())); } var vtToCsArray = typeof(ConverterT) .GetMethod(methodNamePrefix + "FromVtArray", new Type[] { vtArrayType }); if (vtToCsArray == null) { throw new ArgumentException(string.Format("No FromVtArray overload found for type {0}", vtArrayType.ToString())); } var valToVtArray = typeof(pxr.UsdCs).GetMethod("VtValueTo" + vtArrayType.Name, new Type[] { typeof(pxr.VtValue), vtArrayType }); if (valToVtArray == null) { throw new ArgumentException(string.Format("No VtValueTo{...} converter found for type {0}", vtArrayType.ToString())); } var copyConverter = (ToCsCopyConverter)CodeGen.EmitToCs <ToCsCopyConverter>(valToVtArray, vtToCsArray); ToCsConverter toCs = (vtValue) => ToCsConvertHelper(vtValue, vtArrayType, copyConverter); ToVtConverter toVt = (ToVtConverter)CodeGen.EmitToVt <ToVtConverter>(csToVtArray, csType, vtArrayType); bindings[csType] = new UsdTypeBinding(toVt, toCs, sdfName); }
public bool GetBinding(Type key, out UsdTypeBinding binding) { lock (UsdIo.Bindings) { // First try the exact type requested. if (bindings.TryGetValue(key, out binding)) { return(true); } // If the first lookup failed, perhaps this is a nullable type? if (key.IsGenericType && key.GetGenericTypeDefinition() == typeof(Nullable <>) && bindings.TryGetValue(key.GetGenericArguments()[0], out binding)) { return(true); } // If this is an Enum type, then use the generic Enum handler. if (!key.IsEnum) { return(false); } // // Enumerations. // To reduce special cases of client code, all enums are special cased into a single // converter. This converter is only selected if no specific type has been registered. // binding = BindEnum(key); // Memoize the binding so it doesn't get regenerated on every call. bindings.Add(key, binding); } return(true); }
private void RegisterIntrinsicTypes() { // --------------------------------------------------------------------------------------- // // Establish bindings from intrinsic C# type -> USD C++ type -> USD Type // --------------------------------------------------------------------------------------- // // TODO: The C++ -> USD type could probably be discovered at runtime. // Note that multiple USD types map to a single C++ type, so the mapping // needs to be discovered from USD type -> C++ type. The C++ type is known // by the TfType system, but it's unclear how to go from C++ type to C# type. // --------------------------------------------------------------------------------------- // // // Custom C# conversions // // The bytes version of Guid, which generates less garbage, can't be used until versioning is // more fully supported. //bindings[typeof(Guid)] = new UsdTypeBinding(GuidToVt_Bytes, GuidToCs_Bytes, SdfValueTypeNames.UCharArray); bindings[typeof(Guid)] = new UsdTypeBinding(GuidToVt_String, GuidToCs_String, SdfValueTypeNames.String); /* * These throw exceptions because there is no VtValueTo...ListOp, because those types are not declared in * SdfValueTypeNames. Bug filed: https://github.com/PixarAnimationStudios/USD/issues/639 * * BindNativeType(typeof(pxr.SdfInt64ListOp), SdfValueTypeNames.Int64); * BindNativeType(typeof(pxr.SdfUInt64ListOp), SdfValueTypeNames.UInt64); * BindNativeType(typeof(pxr.SdfIntListOp), SdfValueTypeNames.Int); * BindNativeType(typeof(pxr.SdfUIntListOp), SdfValueTypeNames.UInt); * BindNativeType(typeof(pxr.SdfStringListOp), SdfValueTypeNames.String); * BindNativeType(typeof(pxr.SdfTokenListOp), SdfValueTypeNames.Token); * BindNativeType(typeof(pxr.SdfReferenceListOp), SdfValueTypeNames.Asset); * BindNativeType(typeof(pxr.SdfPathListOp), SdfValueTypeNames.String); */ // // Bool // BindNativeType(typeof(bool), SdfValueTypeNames.Bool); BindNativeType(typeof(pxr.VtBoolArray), SdfValueTypeNames.BoolArray); BindArrayType <IntrinsicTypeConverter>(typeof(bool[]), typeof(pxr.VtBoolArray), SdfValueTypeNames.BoolArray); BindArrayType <IntrinsicTypeConverter>(typeof(List <bool>), typeof(pxr.VtBoolArray), SdfValueTypeNames.BoolArray, "List"); // // UChar/byte // BindNativeType(typeof(byte), SdfValueTypeNames.UChar); BindNativeType(typeof(pxr.VtUCharArray), SdfValueTypeNames.UCharArray); BindArrayType <IntrinsicTypeConverter>(typeof(byte[]), typeof(pxr.VtUCharArray), SdfValueTypeNames.UCharArray); BindArrayType <IntrinsicTypeConverter>(typeof(List <byte>), typeof(pxr.VtUCharArray), SdfValueTypeNames.UCharArray, "List"); // // String // BindNativeType(typeof(string), SdfValueTypeNames.String); BindNativeType(typeof(pxr.TfToken), SdfValueTypeNames.Token); BindNativeType(typeof(pxr.VtStringArray), SdfValueTypeNames.StringArray); BindNativeType(typeof(pxr.VtTokenArray), SdfValueTypeNames.TokenArray); BindArrayType <IntrinsicTypeConverter>(typeof(string[]), typeof(pxr.VtTokenArray), SdfValueTypeNames.TokenArray); BindArrayType <IntrinsicTypeConverter>(typeof(List <string>), typeof(pxr.VtTokenArray), SdfValueTypeNames.TokenArray, "List"); // // SdfAssetPath // //BindType(typeof(pxr.SdfAssetPath), new UsdTypeBinding((obj) => new pxr.VtValue((pxr.SdfAssetPath)obj), (obj) => (pxr.SdfAssetPath)obj, SdfValueTypeNames.Asset)); BindNativeType(typeof(pxr.SdfAssetPath), SdfValueTypeNames.Asset); BindArrayType <IntrinsicTypeConverter>(typeof(pxr.SdfAssetPath[]), typeof(pxr.SdfAssetPathArray), SdfValueTypeNames.AssetArray); BindArrayType <IntrinsicTypeConverter>(typeof(List <pxr.SdfAssetPath>), typeof(pxr.SdfAssetPathArray), SdfValueTypeNames.AssetArray, "List"); // // Int // BindNativeType(typeof(int), SdfValueTypeNames.Int); BindNativeType(typeof(pxr.VtIntArray), SdfValueTypeNames.IntArray); BindArrayType <IntrinsicTypeConverter>(typeof(int[]), typeof(pxr.VtIntArray), SdfValueTypeNames.IntArray); BindArrayType <IntrinsicTypeConverter>(typeof(List <int>), typeof(pxr.VtIntArray), SdfValueTypeNames.IntArray, "List"); // // UInt // BindNativeType(typeof(uint), SdfValueTypeNames.UInt); BindNativeType(typeof(pxr.VtUIntArray), SdfValueTypeNames.UIntArray); BindArrayType <IntrinsicTypeConverter>(typeof(uint[]), typeof(pxr.VtUIntArray), SdfValueTypeNames.UIntArray); BindArrayType <IntrinsicTypeConverter>(typeof(List <uint>), typeof(pxr.VtUIntArray), SdfValueTypeNames.UIntArray, "List"); // // Long // BindNativeType(typeof(long), SdfValueTypeNames.Int64); BindNativeType(typeof(pxr.VtInt64Array), SdfValueTypeNames.Int64Array); BindArrayType <IntrinsicTypeConverter>(typeof(long[]), typeof(pxr.VtInt64Array), SdfValueTypeNames.Int64Array); BindArrayType <IntrinsicTypeConverter>(typeof(List <long>), typeof(pxr.VtInt64Array), SdfValueTypeNames.Int64Array, "List"); // // ULong // BindNativeType(typeof(ulong), SdfValueTypeNames.UInt64); BindNativeType(typeof(pxr.VtUInt64Array), SdfValueTypeNames.UInt64Array); BindArrayType <IntrinsicTypeConverter>(typeof(ulong[]), typeof(pxr.VtUInt64Array), SdfValueTypeNames.UInt64Array); BindArrayType <IntrinsicTypeConverter>(typeof(List <ulong>), typeof(pxr.VtUInt64Array), SdfValueTypeNames.UInt64Array, "List"); // // Half // BindNativeType(typeof(pxr.GfHalf), SdfValueTypeNames.Half); BindNativeType(typeof(pxr.VtHalfArray), SdfValueTypeNames.HalfArray); BindNativeType(typeof(pxr.VtVec2hArray), SdfValueTypeNames.Half2Array); BindNativeType(typeof(pxr.VtVec3hArray), SdfValueTypeNames.Half3Array); BindNativeType(typeof(pxr.VtVec4hArray), SdfValueTypeNames.Half4Array); // // Float // BindNativeType(typeof(float), SdfValueTypeNames.Float); BindNativeType(typeof(pxr.VtFloatArray), SdfValueTypeNames.FloatArray); BindArrayType <IntrinsicTypeConverter>(typeof(float[]), typeof(pxr.VtFloatArray), SdfValueTypeNames.FloatArray); BindArrayType <IntrinsicTypeConverter>(typeof(List <float>), typeof(pxr.VtFloatArray), SdfValueTypeNames.FloatArray, "List"); // // Double // BindNativeType(typeof(double), SdfValueTypeNames.Double); BindNativeType(typeof(pxr.VtDoubleArray), SdfValueTypeNames.DoubleArray); BindArrayType <IntrinsicTypeConverter>(typeof(double[]), typeof(pxr.VtDoubleArray), SdfValueTypeNames.DoubleArray); BindArrayType <IntrinsicTypeConverter>(typeof(List <double>), typeof(pxr.VtDoubleArray), SdfValueTypeNames.DoubleArray, "List"); // // Quaternion // BindNativeType(typeof(pxr.GfQuath), SdfValueTypeNames.Quath); BindNativeType(typeof(pxr.VtQuathArray), SdfValueTypeNames.QuathArray); BindNativeType(typeof(pxr.GfQuatf), SdfValueTypeNames.Quatf); BindNativeType(typeof(pxr.VtQuatfArray), SdfValueTypeNames.QuatfArray); BindNativeType(typeof(pxr.GfQuatd), SdfValueTypeNames.Quatd); BindNativeType(typeof(pxr.VtQuatdArray), SdfValueTypeNames.QuatdArray); // Below the Vt array types are commented out, because they will be found in reverse // binding searches, which we don't want. Still, it is desireable to be able to // serialize these types, though not a primary use case. // // Vec2 // BindNativeType(typeof(pxr.GfVec2i), SdfValueTypeNames.Int2); BindNativeType(typeof(pxr.GfVec2h), SdfValueTypeNames.Half2); //BindNativeType(typeof(pxr.VtVec2hArray), SdfValueTypeNames.Half2Array); BindNativeType(typeof(pxr.GfVec2f), SdfValueTypeNames.Float2); //BindNativeType(typeof(pxr.VtVec2fArray), SdfValueTypeNames.Float2Array); // // Vec3 // BindNativeType(typeof(pxr.GfVec3i), SdfValueTypeNames.Int3); //BindNativeType(typeof(pxr.VtVec3iArray), SdfValueTypeNames.Int3Array); BindNativeType(typeof(pxr.GfVec3h), SdfValueTypeNames.Half3); //BindNativeType(typeof(pxr.VtVec3hArray), SdfValueTypeNames.Half3Array); BindNativeType(typeof(pxr.GfVec3f), SdfValueTypeNames.Float3); //BindNativeType(typeof(pxr.VtVec3fArray), SdfValueTypeNames.Float3Array); // // Vec4 // BindNativeType(typeof(pxr.GfVec4i), SdfValueTypeNames.Int4); //BindNativeType(typeof(pxr.VtVec4iArray), SdfValueTypeNames.Int4Array); BindNativeType(typeof(pxr.GfVec4h), SdfValueTypeNames.Half4); //BindNativeType(typeof(pxr.VtVec4hArray), SdfValueTypeNames.Half4Array); BindNativeType(typeof(pxr.GfVec4f), SdfValueTypeNames.Float4); //BindNativeType(typeof(pxr.VtVec4fArray), SdfValueTypeNames.Float4Array); // --------------------------------------------------------------------------------------- // }
/// <summary> /// Binds the specified C# type to the given USD array and scene description (Sdf) types, /// looking for ConverterT.ToVtArray(csType) and ConverterT.FromVtArray(vtArrayType). /// </summary> /// /// <typeparam name="ConverterT"> /// The C# class type providing type conversion rules ToVtArray and FromVtArray. /// </typeparam> /// /// <param name="csType">The C# type to be mapped to USD</param> /// <param name="vtArrayType">The USD C++ value type (Vt)</param> /// <param name="sdfName">The USD scene description (Sdf) type</param> /// /// TODO: The C++ type can be inferred from the Sdf type, so vtArrayType is not needed. /// public void BindArrayType <ConverterT>(Type csType, Type vtArrayType, pxr.SdfValueTypeName sdfName, string methodNamePrefix = "") { // ConverterT and the function being found will be something like: // class IntrinsicTypeConverter { // static public VtTokenArray ToVtArray(string[] input); // var csToVtArray = typeof(ConverterT) .GetMethod(methodNamePrefix + "ToVtArray", new Type[] { csType }); if (csToVtArray == null) { throw new ArgumentException(string.Format("No ToVtArray overload found for type {0}", csType.ToString())); } // ConverterT and the function being found will be something like: // class IntrinsicTypeConverter { // static public string[] FromVtArray(VtTokenArray input); // var vtToCsArray = typeof(ConverterT) .GetMethod(methodNamePrefix + "FromVtArray", new Type[] { vtArrayType }); if (vtToCsArray == null) { throw new ArgumentException(string.Format("No FromVtArray overload found for type {0}", vtArrayType.ToString())); } // The specific UsdCs method being located here will be somthing like: // class UsdCs { // public static void VtValueToVtTokenArray(VtValue value, VtTokenArray output); // var valToVtArray = typeof(pxr.UsdCs).GetMethod("VtValueTo" + vtArrayType.Name, new Type[] { typeof(pxr.VtValue), vtArrayType }); if (valToVtArray == null) { throw new ArgumentException(string.Format("No VtValueTo{...} converter found for type {0}", vtArrayType.ToString())); } // The following code constructs functions to: // // 1) Convert the VtValue (type-erased container) to a specific VtArray<T> type and then // convert the VtArray<T> to a native C# type. // // 2) Convert a strongly typed C# array to a strongly typed VtArray<T> and then // convert the VtArray<T> to a type-erased VtValue. // // For example, to will convert: // // 1) VtValue -> VtArray<TfToken> -> string[] // 2) string[] -> VtArray<TfToken> -> VtValue // ToCsConverter toCs = null; ToVtConverter toVt = null; if (IsCodeGenEnabled()) { // EmitToCs and EmitToVt are not defined when not using NET_4_6 #if NET_4_6 var copyConverter = (ToCsCopyConverter)CodeGen.EmitToCs <ToCsCopyConverter>(valToVtArray, vtToCsArray); toCs = (vtValue) => ToCsConvertHelper(vtValue, vtArrayType, copyConverter); toVt = (ToVtConverter)CodeGen.EmitToVt <ToVtConverter>(csToVtArray, csType, vtArrayType); #endif } else { // In .NET2 or when IL2CPP is enabled , we cannot dynamically emit code. // Instead, we use late binding, which is slower, but also doesn't crash. // In the future, we should generate code to do these conversions, rather than using late binding. toCs = (vtValue) => ToCsDynamicConvertHelper(vtValue, vtArrayType, valToVtArray, vtToCsArray); toVt = CsArrayToVtValue(csToVtArray, csType, vtArrayType); } bindings[csType] = new UsdTypeBinding(toVt, toCs, sdfName); }
public void BindType(Type csType, UsdTypeBinding binding) { bindings[csType] = binding; }