public SparkViewDescriptor AddAccessor(string property, string getValue) { Accessors.Add(new Accessor { Property = property, GetValue = getValue }); return(this); }
/// <summary> /// Some reflection and lambda wizardry to make this type safe... /// </summary> /// <typeparam name="TProperty"></typeparam> /// <param name="property"></param> /// <param name="rule"></param> /// <param name="message"></param> protected void AddPropertyRule <TProperty>(Expression <Func <T, TProperty> > property, Func <T, TProperty, bool> rule, string message) { MemberExpression memberExp = property.Body as MemberExpression; var info = memberExp.Member; var pd = TypeDescriptor.CreateProperty(typeof(T), info.Name, typeof(TProperty)); Func <T, object, bool> func = (entity, o) => rule(entity, (TProperty)pd.GetValue(entity)); Accessors.Add(info.Name, e => pd.GetValue(e)); PropertyRules.Add(info.Name, new PropertyRule <T>(func, message)); }
// Put initializtion code here. public TestObjectAccessors() { myobject = new MyObject(); PropertyInfo[] oProps; Type oType = typeof(MyObject); oProps = oType.GetProperties(); for (int i = 0; i < oProps.Length; i++) { Accessors.Add(new PropertyAccessor(oType, oProps[i].Name)); } }
private PropertyDeclarationSyntax AddAttribute(PropertyDeclarationSyntax property) { var dictionaryType = property.Type; if (dictionaryType is QualifiedNameSyntax qualifiedName) { dictionaryType = qualifiedName.Right; } if (dictionaryType is not GenericNameSyntax genericName) { // Don't mutate return(property); } var nullableObject = NullableType(PredefinedType(Token(SyntaxKind.ObjectKeyword))); // System.Text.Json requires dictionary values be JsonElement or object, so replace the types with object. // We don't want to use JsonElement because it's very difficult to build those dynamically. // We could use JsonObject instead of a dictionary, but there is currently an issue in System.Text.Json which prevents this // https://github.com/dotnet/runtime/issues/60560 var newDictionaryType = WellKnownTypes.System.Collections.Generic.DictionaryT.Name( genericName.TypeArgumentList.Arguments[0], nullableObject); var interfaceType = WellKnownTypes.System.Collections.Generic.IDictionaryT.Name( genericName.TypeArgumentList.Arguments[0], nullableObject); return(property .WithType(interfaceType) .WithInitializer(EqualsValueClause(ObjectCreationExpression(newDictionaryType))) // We must have a setter for JsonExtensionData to work with System.Text.Json .WithAccessorList(AccessorList(property.AccessorList !.Accessors.Add(AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)))) // Add the JsonExtensionData attribute .AddAttributeLists(AttributeList(SingletonSeparatedList( Attribute(SystemTextJsonTypes.Serialization.JsonExtensionDataAttributeName))))); }
/* * public byte[] GetBuffer(int bufferIndex) * { * return FileChunks[bufferIndex + 1].Data; * } */ public void ParseJSON(string JSONstring) { var json = JsonConvert.DeserializeObject <dynamic>(JSONstring); foreach (var bufferViewJSON in json.bufferViews) { GLBBufferView bufferView = new GLBBufferView(); bufferView.Buffer = FileChunks[(int)bufferViewJSON.buffer + 1].Data; bufferView.ByteOffset = bufferViewJSON.byteOffset; bufferView.ByteLength = bufferViewJSON.byteLength; bufferView.Target = bufferViewJSON.target; BufferViews.Add(bufferView); } foreach (var accessorJSON in json.accessors) { GLBAccessor accessor = new GLBAccessor(); accessor.BufferView = BufferViews[(int)accessorJSON.bufferView]; accessor.ComponentType = accessorJSON.componentType; accessor.Count = accessorJSON.count; accessor.Type = accessorJSON.type; Accessors.Add(accessor); } foreach (var imageJSON in json.images) { GLBImage image = new GLBImage(); image.BufferView = BufferViews[(int)imageJSON.bufferView]; image.MimeType = imageJSON.mimeType; Images.Add(image); } foreach (var samplerJSON in json.samplers) { GLBSampler sampler = new GLBSampler(); sampler.MinFilter = samplerJSON.minFilter; sampler.MagFilter = samplerJSON.magFilter; sampler.WrapS = samplerJSON.wrapS; sampler.WrapT = samplerJSON.wrapT; Samplers.Add(sampler); } foreach (var textureJSON in json.textures) { GLBTexture texture = new GLBTexture(); texture.Source = Images[(int)textureJSON.source]; texture.Sampler = Samplers[(int)textureJSON.sampler]; Textures.Add(texture); } foreach (var materialJSON in json.materials) { GLBMaterial material = new GLBMaterial(); material.Name = materialJSON.name; Materials.Add(material); } foreach (var meshJSON in json.meshes) { GLBMesh mesh = new GLBMesh(); mesh.Name = meshJSON.name; foreach (var primitiveJSON in meshJSON.primitives) { GLBPrimitive primitive = new GLBPrimitive(); GLBAttributes attributes = new GLBAttributes(); attributes.Position = Accessors[(int)primitiveJSON.attributes.POSITION]; attributes.Normal = Accessors[(int)primitiveJSON.attributes.NORMAL]; primitive.Attributes = attributes; primitive.Indices = Accessors[(int)primitiveJSON.indices]; primitive.Material = Materials[(int)primitiveJSON.material]; mesh.Primitives.Add(primitive); } Meshes.Add(mesh); } }
private void RegisterMember(Type type, System.Reflection.MemberInfo m, Type mType, Func <object, object> get, Action <object, object> set) { // struct that holds access method for property/field MemberInfo accessor = new MemberInfo(); accessor.Type = mType; accessor.Get = get; accessor.Set = set; if (set != null) // writeable ? { accessor.SerializeMethod = YamlSerializeMethod.Assign; } else { accessor.SerializeMethod = YamlSerializeMethod.Never; if (mType.IsClass) { accessor.SerializeMethod = YamlSerializeMethod.Content; } } var attr1 = m.GetAttribute <YamlSerializeAttribute>(); if (attr1 != null) // specified { if (set == null) // read only member { if (attr1.SerializeMethod == YamlSerializeMethod.Assign || (mType.IsValueType && accessor.SerializeMethod == YamlSerializeMethod.Content)) { throw new ArgumentException("{0} {1} is not writeable by {2}." .DoFormat(mType.FullName, m.Name, attr1.SerializeMethod.ToString())); } } accessor.SerializeMethod = attr1.SerializeMethod; } if (accessor.SerializeMethod == YamlSerializeMethod.Never) { return; // no need to register } if (accessor.SerializeMethod == YamlSerializeMethod.Binary) { if (!mType.IsArray) { throw new InvalidOperationException("{0} {1} of {2} is not an array. Can not be serialized as binary." .DoFormat(mType.FullName, m.Name, type.FullName)); } if (!TypeUtils.IsPureValueType(mType.GetElementType())) { throw new InvalidOperationException( "{0} is not a pure ValueType. {1} {2} of {3} can not serialize as binary." .DoFormat(mType.GetElementType(), mType.FullName, m.Name, type.FullName)); } } // ShouldSerialize // YamlSerializeAttribute(Never) => false // ShouldSerializeSomeProperty => call it // DefaultValueAttribute(default) => compare to it // otherwise => true var shouldSerialize = type.GetMethod("ShouldSerialize" + m.Name, BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, new ParameterModifier[0]); if (shouldSerialize != null && shouldSerialize.ReturnType == typeof(bool) && accessor.ShouldSeriealize == null) { accessor.ShouldSeriealize = obj => (bool)shouldSerialize.Invoke(obj, EmptyObjectArray); } var attr2 = m.GetAttribute <DefaultValueAttribute>(); if (attr2 != null && accessor.ShouldSeriealize == null) { var defaultValue = attr2.Value; if (TypeUtils.IsNumeric(defaultValue) && defaultValue.GetType() != mType) { defaultValue = TypeUtils.CastToNumericType(defaultValue, mType); } accessor.ShouldSeriealize = obj => !TypeUtils.AreEqual(defaultValue, accessor.Get(obj)); } if (accessor.ShouldSeriealize == null) { accessor.ShouldSeriealize = obj => true; } Accessors.Add(m.Name, accessor); }
/// <summary> /// Takes the intermediate geometry data and performs the calculations /// to convert that into glTF buffers, views, and accessors. /// </summary> /// <param name="geomData"></param> /// <param name="name">Unique name for the .bin file that will be produced.</param> /// <param name="elementId">Revit element's Element ID that will be used as the batchId value.</param> /// <returns></returns> public glTFBinaryData AddGeometryMeta(GeometryData geomData, string name, int elementId) { // add a buffer glTFBuffer buffer = new glTFBuffer(); buffer.uri = name + ".bin"; Buffers.Add(buffer); int bufferIdx = Buffers.Count - 1; /** * Buffer Data **/ glTFBinaryData bufferData = new glTFBinaryData(); bufferData.name = buffer.uri; foreach (var coord in geomData.vertices) { float vFloat = Convert.ToSingle(coord); bufferData.vertexBuffer.Add(vFloat); } //foreach (var normal in geomData.normals) //{ // bufferData.normalBuffer.Add((float)normal); //} foreach (var index in geomData.faces) { bufferData.indexBuffer.Add(index); } foreach (var coord in geomData.vertices) { bufferData.batchIdBuffer.Add(elementId); } // Get max and min for vertex data float[] vertexMinMax = Util.GetVec3MinMax(bufferData.vertexBuffer); // Get max and min for normal data //float[] normalMinMax = Util.GetVec3MinMax(bufferData.normalBuffer); // Get max and min for index data int[] faceMinMax = Util.GetScalarMinMax(bufferData.indexBuffer); // Get max and min for batchId data float[] batchIdMinMax = Util.GetVec3MinMax(bufferData.batchIdBuffer); /** * BufferViews **/ // Add a vec3 buffer view int elementsPerVertex = 3; int bytesPerElement = 4; int bytesPerVertex = elementsPerVertex * bytesPerElement; int numVec3 = (geomData.vertices.Count) / elementsPerVertex; int sizeOfVec3View = numVec3 * bytesPerVertex; glTFBufferView vec3View = new glTFBufferView(); vec3View.buffer = bufferIdx; vec3View.byteOffset = 0; vec3View.byteLength = sizeOfVec3View; vec3View.target = Targets.ARRAY_BUFFER; BufferViews.Add(vec3View); int vec3ViewIdx = BufferViews.Count - 1; // Add a normals (vec3) buffer view //int elementsPerNormal = 3; //int bytesPerNormalElement = 4; //int bytesPerNormal = elementsPerNormal * bytesPerNormalElement; //int numVec3Normals = (geomData.normals.Count) / elementsPerNormal; //int sizeOfVec3ViewNormals = numVec3Normals * bytesPerNormal; //glTFBufferView vec3ViewNormals = new glTFBufferView(); //vec3ViewNormals.buffer = bufferIdx; //vec3ViewNormals.byteOffset = vec3View.byteLength; //vec3ViewNormals.byteLength = sizeOfVec3ViewNormals; //vec3ViewNormals.target = Targets.ELEMENT_ARRAY_BUFFER; //BufferViews.Add(vec3ViewNormals); //int vec3ViewNormalsIdx = BufferViews.Count - 1; // Add a faces / indexes buffer view int elementsPerIndex = 1; int bytesPerIndexElement = 4; int bytesPerIndex = elementsPerIndex * bytesPerIndexElement; int numIndexes = geomData.faces.Count; int sizeOfIndexView = numIndexes * bytesPerIndex; glTFBufferView facesView = new glTFBufferView(); facesView.buffer = bufferIdx; facesView.byteOffset = vec3View.byteLength; //facesView.byteOffset = vec3ViewNormals.byteOffset + vec3ViewNormals.byteLength; facesView.byteLength = sizeOfIndexView; facesView.target = Targets.ELEMENT_ARRAY_BUFFER; BufferViews.Add(facesView); int facesViewIdx = BufferViews.Count - 1; // Add a batchId buffer view glTFBufferView batchIdsView = new glTFBufferView(); batchIdsView.buffer = bufferIdx; batchIdsView.byteOffset = facesView.byteOffset + facesView.byteLength; batchIdsView.byteLength = sizeOfVec3View; batchIdsView.target = Targets.ARRAY_BUFFER; BufferViews.Add(batchIdsView); int batchIdsViewIdx = BufferViews.Count - 1; //Buffers[bufferIdx].byteLength = vec3View.byteLength + vec3ViewNormals.byteLength + facesView.byteLength + batchIdsView.byteLength; Buffers[bufferIdx].byteLength = vec3View.byteLength + facesView.byteLength + batchIdsView.byteLength; /** * Accessors **/ // add a position accessor glTFAccessor positionAccessor = new glTFAccessor(); positionAccessor.bufferView = vec3ViewIdx; positionAccessor.byteOffset = 0; positionAccessor.componentType = ComponentType.FLOAT; positionAccessor.count = geomData.vertices.Count / elementsPerVertex; positionAccessor.type = "VEC3"; positionAccessor.max = new List <float>() { vertexMinMax[1], vertexMinMax[3], vertexMinMax[5] }; positionAccessor.min = new List <float>() { vertexMinMax[0], vertexMinMax[2], vertexMinMax[4] }; positionAccessor.name = "POSITION"; Accessors.Add(positionAccessor); bufferData.vertexAccessorIndex = Accessors.Count - 1; //add a normals accessor //glTFAccessor normalsAccessor = new glTFAccessor(); //normalsAccessor.bufferView = vec3ViewNormalsIdx; //normalsAccessor.byteOffset = 0; //normalsAccessor.componentType = ComponentType.FLOAT; //normalsAccessor.count = geomData.normals.Count / elementsPerNormal; //normalsAccessor.type = "VEC3"; //normalsAccessor.max = new List<float>() { normalMinMax[1], normalMinMax[3], normalMinMax[5] }; //normalsAccessor.min = new List<float>() { normalMinMax[0], normalMinMax[2], normalMinMax[4] }; //normalsAccessor.name = "NORMALS"; //Accessors.Add(normalsAccessor); //bufferData.normalsAccessorIndex = Accessors.Count - 1; // add a face accessor glTFAccessor faceAccessor = new glTFAccessor(); faceAccessor.bufferView = facesViewIdx; faceAccessor.byteOffset = 0; faceAccessor.componentType = ComponentType.UNSIGNED_INT; //faceAccessor.count = numIndexes; faceAccessor.count = geomData.faces.Count / elementsPerIndex; faceAccessor.type = "SCALAR"; faceAccessor.max = new List <float>() { faceMinMax[1] }; faceAccessor.min = new List <float>() { faceMinMax[0] }; faceAccessor.name = "FACE"; Accessors.Add(faceAccessor); bufferData.indexAccessorIndex = Accessors.Count - 1; // add a batchId accessor glTFAccessor batchIdAccessor = new glTFAccessor(); batchIdAccessor.bufferView = batchIdsViewIdx; batchIdAccessor.byteOffset = 0; batchIdAccessor.componentType = ComponentType.FLOAT; //batchIdAccessor.count = numIndexes; batchIdAccessor.count = geomData.vertices.Count / elementsPerVertex; batchIdAccessor.type = "VEC3"; //batchIdAccessor.max = new List<float>() { batchIdMinMax[1] }; //batchIdAccessor.min = new List<float>() { batchIdMinMax[0] }; batchIdAccessor.max = new List <float>() { batchIdMinMax[1], batchIdMinMax[3], batchIdMinMax[5] }; batchIdAccessor.min = new List <float>() { batchIdMinMax[0], batchIdMinMax[2], batchIdMinMax[4] }; batchIdAccessor.name = "BATCH_ID"; Accessors.Add(batchIdAccessor); bufferData.batchIdAccessorIndex = Accessors.Count - 1; return(bufferData); }