| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633 |
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using DATATYPE = SharpGLTF.Schema2.Tiles3D.DataType;
- using ELEMENTTYPE = SharpGLTF.Schema2.Tiles3D.ElementType;
- namespace SharpGLTF.Schema2
- {
- using Collections;
- using Memory;
- using Validation;
- using Tiles3D;
- using System.Numerics;
- using System.Text.Json.Nodes;
- using System.ComponentModel;
- partial class Tiles3DExtensions
- {
- public static EXTStructuralMetadataRoot UseStructuralMetadata(this ModelRoot modelRoot)
- {
- return modelRoot.UseExtension<EXTStructuralMetadataRoot>();
- }
- }
- namespace Tiles3D
- {
- /// <remarks>
- /// Use <see cref="Tiles3DExtensions.UseStructuralMetadata(ModelRoot)"/> to create an instance of this class.
- /// </remarks>
- public partial class EXTStructuralMetadataRoot
- {
- #region lifecycle
- internal EXTStructuralMetadataRoot(ModelRoot modelRoot)
- {
- this.LogicalParent = modelRoot;
- _propertyTables = new ChildrenList<PropertyTable, EXTStructuralMetadataRoot>(this);
- _propertyAttributes = new ChildrenList<PropertyAttribute, EXTStructuralMetadataRoot>(this);
- _propertyTextures = new ChildrenList<PropertyTexture, EXTStructuralMetadataRoot>(this);
- }
- protected override IEnumerable<ExtraProperties> GetLogicalChildren()
- {
- var items = base.GetLogicalChildren()
- .Concat(_propertyTables)
- .Concat(_propertyAttributes)
- .Concat(_propertyTextures);
- if (Schema != null) items = items.Append(Schema);
- return items;
- }
- #endregion
- #region data
- public ModelRoot LogicalParent { get; }
- #endregion
- #region properties
- /**
- internal string SchemaUri
- {
- get => _schemaUri;
- set { _schemaUri = value; }
- }
- */
- internal StructuralMetadataSchema Schema
- {
- get => _schema;
- set { GetChildSetter(this).SetProperty(ref _schema, value); }
- }
- internal IReadOnlyList<PropertyTable> PropertyTables => _propertyTables;
- internal IReadOnlyList<PropertyAttribute> PropertyAttributes => _propertyAttributes;
- internal IReadOnlyList<PropertyTexture> PropertyTextures => _propertyTextures;
- #endregion
- #region API
- public bool TryGetEmbeddedSchema(out StructuralMetadataSchema schema)
- {
- if (_schema != null) { schema = _schema; return true; }
- schema = null;
- return false;
- }
- public StructuralMetadataSchema UseEmbeddedSchema(string id)
- {
- var schema = UseEmbeddedSchema();
- schema.Id = id;
- return schema;
- }
- /**
- // Sets the schema to use an external schema, returns an empty schema to used for adding schema properties
- public StructuralMetadataSchema UseExternalSchema(Uri uri)
- {
- SchemaUri = uri.ToString();
- return new StructuralMetadataSchema();
- }
- */
- public StructuralMetadataSchema UseEmbeddedSchema()
- {
- // SchemaUri = null;
- if (_schema == null) GetChildSetter(this).SetProperty(ref _schema, new StructuralMetadataSchema());
- return _schema;
- }
- public PropertyAttribute AddPropertyAttribute(StructuralMetadataClass schemaClass)
- {
- var prop = AddPropertyAttribute();
- prop.ClassInstance = schemaClass;
- return prop;
- }
- public PropertyAttribute AddPropertyAttribute()
- {
- var prop = new PropertyAttribute();
- _propertyAttributes.Add(prop);
- return prop;
- }
- public PropertyTable AddPropertyTable(StructuralMetadataClass schemaClass, int featureCount, string name = null)
- {
- var table = AddPropertyTable();
- table.ClassInstance = schemaClass;
- table.Count = featureCount;
- table.Name = name;
- return table;
- }
- private PropertyTable AddPropertyTable()
- {
- var prop = new PropertyTable();
- _propertyTables.Add(prop);
- return prop;
- }
- public PropertyTexture AddPropertyTexture(StructuralMetadataClass schemaClass)
- {
- var prop = AddPropertyTexture();
- prop.ClassInstance = schemaClass;
- return prop;
- }
- public PropertyTexture AddPropertyTexture()
- {
- var prop = new PropertyTexture();
- _propertyTextures.Add(prop);
- return prop;
- }
- #endregion
- #region validation
- protected override void OnValidateReferences(ValidationContext validate)
- {
- var root = LogicalParent.GetExtension<EXTStructuralMetadataRoot>();
- Guard.MustBeNull(root._schemaUri, nameof(root._schemaUri),
- "SchemaUri must be null, use embedded achema to set the schema");
- // Guard schema is null
- Guard.NotNull(Schema, nameof(Schema), "Schema must be defined");
- foreach (var propertyTexture in PropertyTextures)
- {
- foreach (var propertyTextureProperty in propertyTexture.Properties)
- {
- var textureId = propertyTextureProperty.Value.LogicalTextureIndex;
- validate.IsNullOrIndex(nameof(propertyTexture), textureId, LogicalParent.LogicalTextures);
- }
- }
- foreach (var propertyTable in PropertyTables)
- {
- Guard.NotNull(Schema.Classes[propertyTable.ClassName], nameof(propertyTable.ClassName), $"Schema must have class {propertyTable.ClassName}");
- foreach (var property in propertyTable.Properties)
- {
- Guard.NotNull(Schema.Classes[propertyTable.ClassName].Properties[property.Key], nameof(property.Key), $"Schema must have property {property.Key}");
- var values = property.Value.Values;
- validate.IsNullOrIndex(nameof(propertyTable), values, LogicalParent.LogicalBufferViews);
- if (property.Value.ArrayOffsets.HasValue)
- {
- var arrayOffsets = property.Value.ArrayOffsets.Value;
- validate.IsNullOrIndex(nameof(propertyTable), arrayOffsets, LogicalParent.LogicalBufferViews);
- }
- if (property.Value.StringOffsets.HasValue)
- {
- var stringOffsets = property.Value.StringOffsets.Value;
- validate.IsNullOrIndex(nameof(propertyTable), stringOffsets, LogicalParent.LogicalBufferViews);
- }
- }
- }
- if (Schema != null)
- {
- foreach (var @class in Schema.Classes)
- {
- foreach (var property in @class.Value.Properties)
- {
- if (property.Value.Type == ELEMENTTYPE.ENUM)
- {
- Guard.IsTrue(Schema.Enums.ContainsKey(property.Value.EnumType), nameof(property.Value.EnumType), $"Enum {property.Value.EnumType} must be defined in schema");
- }
- }
- }
- }
- base.OnValidateReferences(validate);
- }
- protected override void OnValidateContent(ValidationContext result)
- {
- // check schema id is defined and valid
- if (Schema != null && !String.IsNullOrEmpty(Schema.Id))
- {
- var regex = "^[a-zA-Z_][a-zA-Z0-9_]*$";
- Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(Schema.Id, regex), nameof(Schema.Id));
- foreach (var _class in Schema.Classes)
- {
- Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(_class.Key, regex), nameof(_class.Key));
- foreach (var property in _class.Value.Properties)
- {
- if (property.Value.Count.HasValue)
- {
- Guard.MustBeGreaterThanOrEqualTo(property.Value.Count.Value, 2, nameof(property.Value.Count));
- }
- if (property.Value.Required)
- {
- Guard.IsTrue(property.Value.NoData == null, nameof(property.Value.NoData), $"The property '{property.Key}' defines a 'noData' value, but is 'required'");
- }
- if(property.Value.Type == ELEMENTTYPE.SCALAR)
- {
- // check The 'componentType' must be defined for a property with type 'SCALAR'
- Guard.IsTrue(property.Value.ComponentType.HasValue, nameof(property.Value.ComponentType), $"The 'componentType' must be defined for a property '{property.Key}' with type 'SCALAR'");
- }
- }
- }
- }
- foreach (var propertyTexture in PropertyTextures)
- {
- foreach (var propertyTextureProperty in propertyTexture.Properties)
- {
- var texCoord = propertyTextureProperty.Value.TextureCoordinate;
- var channels = propertyTextureProperty.Value.Channels;
- var index = propertyTextureProperty.Value.LogicalTextureIndex;
- Guard.MustBeGreaterThanOrEqualTo(texCoord, 0, nameof(texCoord));
- Guard.IsTrue(channels.Count > 0, nameof(channels), "Channels must be defined");
- Guard.IsTrue(index >= 0, nameof(index), "Index must be defined");
- }
- }
- foreach (var propertyTable in PropertyTables)
- {
- Guard.IsTrue(propertyTable.ClassName != null, nameof(propertyTable.ClassName), "Class must be defined");
- Guard.IsTrue(propertyTable.Count > 0, nameof(propertyTable.Count), "Count must be greater than 0");
- Guard.IsTrue(propertyTable.Properties.Count > 0, nameof(propertyTable.Properties), "Properties must be defined");
- }
- // Check one of schema or schemaUri is defined, but not both
- // Guard.IsFalse(Schema != null && SchemaUri != null, "Schema/SchemaUri", "Schema and SchemaUri cannot both be defined");
- // Guard.IsFalse(Schema == null && SchemaUri == null, "Schema/SchemaUri", "One of Schema and SchemaUri must be defined");
- base.OnValidateContent(result);
- }
- #endregion
- }
- #region structural properties
- /// <remarks>
- /// Use <see cref="EXTStructuralMetadataRoot.AddPropertyTexture"/> to create an instance of this class.
- /// </remarks>
- public partial class PropertyTexture : IChildOfList<EXTStructuralMetadataRoot>
- {
- #region lifecycle
- public PropertyTexture()
- {
- _properties = new ChildrenDictionary<PropertyTextureProperty, PropertyTexture>(this);
- }
- protected override IEnumerable<ExtraProperties> GetLogicalChildren()
- {
- return base.GetLogicalChildren()
- .Concat(_properties.Values);
- }
- #endregion
- #region child properties
- public int LogicalIndex { get; private set; } = -1;
- public EXTStructuralMetadataRoot LogicalParent { get; private set; }
- void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
- {
- LogicalParent = parent;
- LogicalIndex = index;
- }
- #endregion
- #region properties
- public string ClassName
- {
- get => _class;
- set => _class = value;
- }
- public StructuralMetadataClass ClassInstance
- {
- get
- {
- if (string.IsNullOrEmpty(ClassName)) return null;
- var root = _GetModelRoot()?.GetExtension<EXTStructuralMetadataRoot>();
- if (root == null) return null;
- if (root.TryGetEmbeddedSchema(out var schema))
- {
- return schema.Classes[ClassName];
- }
- else return null;
- }
- set
- {
- // Todo: check value is part of this DOM
- ClassName = value?.LogicalKey;
- }
- }
- public IReadOnlyDictionary<string, PropertyTextureProperty> Properties => _properties;
- #endregion
- #region API
- private ModelRoot _GetModelRoot() => LogicalParent.LogicalParent;
- public PropertyTextureProperty CreateProperty(string key, Texture texture, IReadOnlyList<int> channels = null)
- {
- var property = CreateProperty(key);
- property.Texture = texture;
- if (channels != null) property.Channels = channels;
- return property;
- }
- private PropertyTextureProperty CreateProperty(string key)
- {
- var property = new PropertyTextureProperty();
- _properties[key] = property;
- return property;
- }
- #endregion
- }
- /// <remarks>
- /// Use <see cref="PropertyTexture.CreateProperty(string)"/> to create an instance of this class.
- /// </remarks>
- public partial class PropertyTextureProperty : IChildOfDictionary<PropertyTexture>
- {
- #region lifecycle
- public PropertyTextureProperty()
- {
- _channels = new List<int>();
- }
- #endregion
- #region child properties
- public string LogicalKey { get; private set; }
- public PropertyTexture LogicalParent { get; private set; }
- void IChildOfDictionary<PropertyTexture>.SetLogicalParent(PropertyTexture parent, string key)
- {
- LogicalParent = parent;
- LogicalKey = key;
- }
- #endregion
- #region data
- private ModelRoot _GetModelRoot() => LogicalParent.LogicalParent.LogicalParent;
- public IReadOnlyList<int> Channels
- {
- get => _channels;
- set
- {
- _channels.Clear();
- _channels.AddRange(value);
- }
- }
- public Schema2.Texture Texture
- {
- get => _GetModelRoot().LogicalTextures[LogicalTextureIndex];
- set
- {
- Guard.NotNull(value, nameof(value));
- Guard.MustShareLogicalParent(_GetModelRoot(), nameof(MeshExtMeshFeatureIDTexture), value, nameof(value));
- LogicalTextureIndex = value.LogicalIndex;
- }
- }
- #endregion
- }
- /// <remarks>
- /// Use <see cref="EXTStructuralMetadataRoot.AddPropertyAttribute"/> to create an instance of this class.
- /// </remarks>
- public partial class PropertyAttribute : IChildOfList<EXTStructuralMetadataRoot>
- {
- #region lifecycle
- public PropertyAttribute()
- {
- _properties = new ChildrenDictionary<PropertyAttributeProperty, PropertyAttribute>(this);
- }
- protected override IEnumerable<ExtraProperties> GetLogicalChildren()
- {
- return base.GetLogicalChildren()
- .Concat(_properties.Values);
- }
- #endregion
- #region child properties
- /// <summary>
- /// Gets the zero-based index of this <see cref="MeshExtInstanceFeatureID"/> at <see cref="MeshExtInstanceFeatures.FeatureIds"/>.
- /// </summary>
- public int LogicalIndex { get; private set; } = -1;
- /// <summary>
- /// Gets the <see cref="MeshExtInstanceFeatures"/> instance that owns this <see cref="MeshExtInstanceFeatureID"/> instance.
- /// </summary>
- public EXTStructuralMetadataRoot LogicalParent { get; private set; }
- void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
- {
- LogicalParent = parent;
- LogicalIndex = index;
- }
- #endregion
- #region properties
- public string ClassName
- {
- get => _class;
- set => _class = value;
- }
- public StructuralMetadataClass ClassInstance
- {
- get
- {
- if (string.IsNullOrEmpty(ClassName)) return null;
- var root = _GetModelRoot()?.GetExtension<EXTStructuralMetadataRoot>();
- if (root == null) return null;
- if (root.TryGetEmbeddedSchema(out var schema))
- {
- return schema.Classes[ClassName];
- }
- else return null;
- }
- set
- {
- // Todo: check value is part of this DOM
- ClassName = value?.LogicalKey;
- }
- }
- public IReadOnlyDictionary<string, PropertyAttributeProperty> Properties => _properties;
- #endregion
- #region API
- private ModelRoot _GetModelRoot() => LogicalParent.LogicalParent;
- public PropertyAttributeProperty CreateProperty(string key)
- {
- var property = new PropertyAttributeProperty();
- _properties[key] = property;
- return property;
- }
- #endregion
- }
- /// <remarks>
- /// Use <see cref="PropertyAttribute.CreateProperty(string)"/> to create an instance of this class.
- /// </remarks>
- public partial class PropertyAttributeProperty : IChildOfDictionary<PropertyAttribute>
- {
- #region child properties
- public string LogicalKey { get; private set; }
- public PropertyAttribute LogicalParent { get; private set; }
- void IChildOfDictionary<PropertyAttribute>.SetLogicalParent(PropertyAttribute parent, string key)
- {
- LogicalParent = parent;
- LogicalKey = key;
- }
- #endregion
- #region properties
- public string Attribute
- {
- get => _attribute;
- set => _attribute = value;
- }
- /** Commented out for now, as it is not supported
- public JsonNode Min
- {
- get => _min;
- set => _min = value;
- }
- public JsonNode Max
- {
- get => _max;
- set => _max = value;
- }
- public JsonNode Scale
- {
- get => _scale;
- set => _scale = value;
- }
- public JsonNode Offset
- {
- get => _offset;
- set => _offset = value;
- }
- */
- #endregion
- }
- /// <remarks>
- /// Use <see cref="EXTStructuralMetadataRoot.AddPropertyTable"/> to create an instance of this class.
- /// </remarks>
- public partial class PropertyTable : IChildOfList<EXTStructuralMetadataRoot>
- {
- #region lifecycle
- internal PropertyTable()
- {
- _properties = new ChildrenDictionary<PropertyTableProperty, PropertyTable>(this);
- _count = _countMinimum;
- }
- protected override IEnumerable<ExtraProperties> GetLogicalChildren()
- {
- return base.GetLogicalChildren()
- .Concat(_properties.Values);
- }
- #endregion
- #region child properties
- public int LogicalIndex { get; private set; } = -1;
- public EXTStructuralMetadataRoot LogicalParent { get; private set; }
- void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
- {
- LogicalParent = parent;
- LogicalIndex = index;
- }
- #endregion
- #region properties
- public IReadOnlyDictionary<string, PropertyTableProperty> Properties => _properties;
- public string ClassName
- {
- get => _class;
- set => _class = value;
- }
- public StructuralMetadataClass ClassInstance
- {
- get
- {
- if (string.IsNullOrEmpty(ClassName)) return null;
- var root = _GetModelRoot()?.GetExtension<EXTStructuralMetadataRoot>();
- if (root == null) return null;
- if (root.TryGetEmbeddedSchema(out var schema))
- {
- return schema.Classes[ClassName];
- }
- else return null;
- }
- set
- {
- // Todo: check value is part of this DOM
- ClassName = value?.LogicalKey;
- }
- }
- public string Name
- {
- get => _name;
- set => _name = value;
- }
- public int Count
- {
- get => _count;
- set
- {
- Guard.MustBeGreaterThanOrEqualTo(value, _countMinimum, nameof(value));
- _count = value;
- }
- }
- #endregion
- #region API
- private ModelRoot _GetModelRoot() => LogicalParent.LogicalParent;
- public PropertyTableProperty UseProperty(StructuralMetadataClassProperty key)
- {
- return UseProperty(key.LogicalKey);
- }
- public PropertyTableProperty UseProperty(string key)
- {
- if (_properties.TryGetValue(key, out var value)) return value;
- value = new PropertyTableProperty();
- _properties[key] = value;
- return value;
- }
- #endregion
- }
- /// <remarks>
- /// Use <see cref="PropertyTable.UseProperty(string)"/> to create an instance of this class.
- /// </remarks>
- public partial class PropertyTableProperty : IChildOfDictionary<PropertyTable>
- {
- #region child properties
- public string LogicalKey { get; private set; }
- public PropertyTable LogicalParent { get; private set; }
- void IChildOfDictionary<PropertyTable>.SetLogicalParent(PropertyTable parent, string key)
- {
- LogicalParent = parent;
- LogicalKey = key;
- }
- #endregion
- #region properties
- /// <summary>
- /// this is an index to a BufferView
- /// </summary>
- public int Values
- {
- get => _values;
- set => _values = value;
- }
- public int? ArrayOffsets
- {
- get => _arrayOffsets;
- set => _arrayOffsets = value;
- }
- public int? StringOffsets
- {
- get => _stringOffsets;
- set => _stringOffsets = value;
- }
- #endregion
- #region API
- private ModelRoot _GetModelRoot() => LogicalParent.LogicalParent.LogicalParent;
- public void SetArrayValues<T>(List<List<T>> values)
- {
- Guard.IsTrue(values.Count == LogicalParent.Count, nameof(values), $"Values must have length {LogicalParent.Count}");
- var className = LogicalParent.ClassName;
- var metadataProperty = GetProperty<T>(className, LogicalKey);
- metadataProperty.Array = true;
- var root = _GetModelRoot();
- int logicalIndex = GetBufferView(root, values);
- Values = logicalIndex;
- var hasVariableLength = HasVariableLength<T>(values);
- if (HasVariableLength<T>(values) || typeof(T) == typeof(string))
- {
- // if the array has items of variable length, create arraysOffsets bufferview
- var arrayOffsets = BinaryTable.GetArrayOffsets(values);
- int logicalIndexOffsets = GetBufferView(root, arrayOffsets);
- ArrayOffsets = logicalIndexOffsets;
- if (typeof(T) == typeof(string))
- {
- var stringValues = values.ConvertAll(x => x.ConvertAll(y => (string)Convert.ChangeType(y, typeof(string), CultureInfo.InvariantCulture)));
- var stringOffsets = BinaryTable.GetStringOffsets(stringValues);
- int offsets = GetBufferView(root, stringOffsets);
- StringOffsets = offsets;
- }
- }
- else
- {
- metadataProperty.Count = values[0].Count;
- }
- }
- public void SetValues<T>(params T[] values)
- {
- Guard.IsTrue(values.Length == LogicalParent.Count, nameof(values), $"Values must have length {LogicalParent.Count}");
- var className = LogicalParent.ClassName;
- GetProperty<T>(className, LogicalKey);
- var root = _GetModelRoot();
- int logicalIndex = GetBufferView(root, values);
- Values = logicalIndex;
- if (typeof(T) == typeof(string))
- {
- var stringvalues = values
- .Select(x => (string)Convert.ChangeType(x, typeof(string), CultureInfo.InvariantCulture))
- .ToList();
- var stringOffsets = BinaryTable.GetStringOffsets(stringvalues);
- int offsets = GetBufferView(root, stringOffsets);
- StringOffsets = offsets;
- }
- }
- private StructuralMetadataClassProperty GetProperty<T>(string className, string key)
- {
- var metadataClass = LogicalParent.LogicalParent.Schema.Classes[className];
- Guard.IsTrue(metadataClass != null, nameof(className), $"Schema class {className} must be defined");
- metadataClass.Properties.TryGetValue(key, out var metadataProperty);
- Guard.IsTrue(metadataProperty != null, nameof(key), $"Property {key} in {className} must be defined");
- CheckElementTypes<T>(metadataProperty);
- return metadataProperty;
- }
- private bool HasVariableLength<T>(List<List<T>> values)
- {
- int length = values[0].Count;
- for (int i = 1; i < values.Count; i++)
- {
- if (values[i].Count != length) return true;
- }
- return false;
- }
- private void CheckElementTypes<T>(StructuralMetadataClassProperty metadataProperty)
- {
- var elementType = metadataProperty.Type;
- if (elementType == ELEMENTTYPE.ENUM)
- {
- // guard the type of t is an short in case of enum
- Guard.IsTrue(typeof(T) == typeof(short), nameof(T), $"Enum value type of {LogicalKey} must be short");
- }
- else if (elementType == ELEMENTTYPE.SCALAR)
- {
- var componentType = metadataProperty.ComponentType;
- CheckScalarTypes<T>(componentType);
- }
- else if (elementType == ELEMENTTYPE.STRING)
- {
- Guard.IsTrue(typeof(T) == typeof(string), nameof(T), $"String type of property {LogicalKey} must be string");
- }
- else if (elementType == ELEMENTTYPE.BOOLEAN)
- {
- Guard.IsTrue(typeof(T) == typeof(bool), nameof(T), $"Boolean type of property {LogicalKey} must beboolean");
- }
- else if (elementType == ELEMENTTYPE.VEC2)
- {
- Guard.IsTrue(typeof(T) == typeof(Vector2), nameof(T), $"Vector2 type of property {LogicalKey} must be Vector2");
- }
- else if (elementType == ELEMENTTYPE.VEC3)
- {
- Guard.IsTrue(typeof(T) == typeof(Vector3), nameof(T), $"Vector3 type of property {LogicalKey} must be Vector3");
- }
- else if (elementType == ELEMENTTYPE.VEC3)
- {
- Guard.IsTrue(typeof(T) == typeof(Vector4), nameof(T), $"Vector4 type of property {LogicalKey} must be Vector4");
- }
- // todo: add MAT2, MAT3
- else if (elementType == ELEMENTTYPE.MAT4)
- {
- Guard.IsTrue(typeof(T) == typeof(Matrix4x4), nameof(T), $"Matrix4x4 type of property {LogicalKey} must be Matrix4x4");
- }
- }
- private void CheckScalarTypes<T>(DATATYPE? componentType)
- {
- if (componentType == DATATYPE.UINT8)
- {
- Guard.IsTrue(typeof(T) == typeof(byte), nameof(T), $"Scalar value type of property {LogicalKey} must be byte");
- }
- else if (componentType == DATATYPE.INT8)
- {
- Guard.IsTrue(typeof(T) == typeof(sbyte), nameof(T), $"Scalar value type of property {LogicalKey} must be sbyte");
- }
- else if (componentType == DATATYPE.INT16)
- {
- Guard.IsTrue(typeof(T) == typeof(short), nameof(T), $"Scalar value type of property {LogicalKey} must be short");
- }
- else if (componentType == DATATYPE.UINT16)
- {
- Guard.IsTrue(typeof(T) == typeof(ushort), nameof(T), $"Scalar value type of property {LogicalKey} must be ushort");
- }
- else if (componentType == DATATYPE.INT32)
- {
- Guard.IsTrue(typeof(T) == typeof(int), nameof(T), $"Scalar value type of property {LogicalKey} must be int");
- }
- else if (componentType == DATATYPE.UINT32)
- {
- Guard.IsTrue(typeof(T) == typeof(uint), nameof(T), $"Scalar value type of property {LogicalKey} must be uint");
- }
- else if (componentType == DATATYPE.INT64)
- {
- Guard.IsTrue(typeof(T) == typeof(long), nameof(T), $"Scalar value type of property {LogicalKey} must be long");
- }
- else if (componentType == DATATYPE.UINT64)
- {
- Guard.IsTrue(typeof(T) == typeof(ulong), nameof(T), $"Scalar value type of property {LogicalKey} must be ulong");
- }
- else if (componentType == DATATYPE.FLOAT32)
- {
- Guard.IsTrue(typeof(T) == typeof(Single), nameof(T), $"Scalar value type of property {LogicalKey} must be float");
- }
- else if (componentType == DATATYPE.FLOAT64)
- {
- Guard.IsTrue(typeof(T) == typeof(double), nameof(T), $"Scalar value type of property {LogicalKey} must be double");
- }
- }
- private static int GetBufferView<T>(ModelRoot model, IReadOnlyList<T> values)
- {
- var bytes = BinaryTable.GetBytes(values);
- var bufferView = model.UseBufferView(bytes);
- int logicalIndex = bufferView.LogicalIndex;
- return logicalIndex;
- }
- private static int GetBufferView<T>(ModelRoot model, List<List<T>> values)
- {
- List<byte> bytes = BinaryTable.GetBytesForArray(values);
- var bufferView = model.UseBufferView(bytes.ToArray());
- int logicalIndex = bufferView.LogicalIndex;
- return logicalIndex;
- }
- #endregion
- }
- #endregion
- #region structural schema
- /// <remarks>
- /// Use <see cref="EXTStructuralMetadataRoot.UseEmbeddedSchema()"/> to create an instance of this class.
- /// </remarks>
- public partial class StructuralMetadataSchema : IChildOf<EXTStructuralMetadataRoot>
- {
- #region lifecycle
- public StructuralMetadataSchema()
- {
- _classes = new ChildrenDictionary<StructuralMetadataClass, StructuralMetadataSchema>(this);
- _enums = new ChildrenDictionary<StructuralMetadataEnum, StructuralMetadataSchema>(this);
- }
- protected override IEnumerable<ExtraProperties> GetLogicalChildren()
- {
- return base.GetLogicalChildren()
- .Concat(_classes.Values)
- .Concat(_enums.Values);
- }
- #endregion
- #region child properties
- public EXTStructuralMetadataRoot LogicalParent { get; private set; }
- void IChildOf<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent)
- {
- LogicalParent = parent;
- }
- #endregion
- #region properties
- public IReadOnlyDictionary<string, StructuralMetadataClass> Classes => _classes;
- public IReadOnlyDictionary<string, StructuralMetadataEnum> Enums => _enums;
- public string Id
- {
- get => _id;
- set => _id = value;
- }
- public string Version
- {
- get => _version;
- set => _version = value;
- }
- public string Name
- {
- get => _name;
- set => _name = value;
- }
- public string Description
- {
- get => _description;
- set => _description = value;
- }
- #endregion
- #region API
- public StructuralMetadataClass UseClassMetadata(string key)
- {
- if (_classes.TryGetValue(key, out var value)) return value;
- value = new StructuralMetadataClass();
- _classes[key] = value;
- return value;
- }
- public StructuralMetadataEnum UseEnumMetadata(string key, params (string name, int value)[] enumValues)
- {
- var enumType = UseEnumMetadata(key);
- foreach (var (name, value) in enumValues)
- {
- enumType.AddEnum(name, value);
- }
- return enumType;
- }
- public StructuralMetadataEnum UseEnumMetadata(string key)
- {
- if (_enums.TryGetValue(key, out var value)) return value;
- value = new StructuralMetadataEnum();
- _enums[key] = value;
- return value;
- }
- #endregion
- }
- /// <remarks>
- /// Use <see cref="StructuralMetadataSchema.UseEnumMetadata(string)"/> to create an instance of this class.
- /// </remarks>
- public partial class StructuralMetadataEnum : IChildOfDictionary<StructuralMetadataSchema>
- {
- #region lifecycle
- public StructuralMetadataEnum()
- {
- _values = new ChildrenList<StructuralMetadataEnumValue, StructuralMetadataEnum>(this);
- }
- #endregion
- #region child properties
- public string LogicalKey { get; private set; }
- public StructuralMetadataSchema LogicalParent { get; private set; }
- void IChildOfDictionary<StructuralMetadataSchema>.SetLogicalParent(StructuralMetadataSchema parent, string key)
- {
- LogicalParent = parent;
- LogicalKey = key;
- }
- #endregion
- #region properties
- public IReadOnlyList<StructuralMetadataEnumValue> Values => _values;
- public string Name
- {
- get => _name;
- set => _name = value;
- }
- public string Description
- {
- get => _description;
- set => _description = value;
- }
- public IntegerType? ValueType
- {
- get => _valueType;
- }
- #endregion
- #region API
- public StructuralMetadataEnumValue AddEnum(string name, int value, string desc = null)
- {
- var prop = AddEnum();
- prop.Name = name;
- prop.Value = value;
- prop.Description = desc;
- return prop;
- }
- public StructuralMetadataEnumValue AddEnum()
- {
- var prop = new StructuralMetadataEnumValue();
- _values.Add(prop);
- return prop;
- }
- #endregion
- }
- /// <remarks>
- /// Use <see cref="StructuralMetadataEnum.AddEnum()"/> to create an instance of this class.
- /// </remarks>
- public partial class StructuralMetadataEnumValue : IChildOfList<StructuralMetadataEnum>
- {
- #region child properties
- public int LogicalIndex { get; private set; } = -1;
- public StructuralMetadataEnum LogicalParent { get; private set; }
- void IChildOfList<StructuralMetadataEnum>.SetLogicalParent(StructuralMetadataEnum parent, int index)
- {
- LogicalParent = parent;
- LogicalIndex = index;
- }
- #endregion
- #region properties
- public string Description
- {
- get => _description;
- set => _description = value;
- }
- public string Name
- {
- get => _name;
- set => _name = value;
- }
- public int Value
- {
- get => _value;
- set => _value = value;
- }
- #endregion
- }
- /// <remarks>
- /// Use <see cref="StructuralMetadataSchema.UseClassMetadata(string)"/> to create an instance of this class.
- /// </remarks>
- public partial class StructuralMetadataClass : IChildOfDictionary<StructuralMetadataSchema>
- {
- #region lifecycle
- public StructuralMetadataClass()
- {
- _properties = new ChildrenDictionary<StructuralMetadataClassProperty, StructuralMetadataClass>(this);
- }
- protected override IEnumerable<ExtraProperties> GetLogicalChildren()
- {
- return base.GetLogicalChildren()
- .Concat(_properties.Values);
- }
- #endregion
- #region child properties
- public string LogicalKey { get; private set; }
- public StructuralMetadataSchema LogicalParent { get; private set; }
- void IChildOfDictionary<StructuralMetadataSchema>.SetLogicalParent(StructuralMetadataSchema parent, string key)
- {
- LogicalParent = parent;
- LogicalKey = key;
- }
- #endregion
- #region properties
- public IReadOnlyDictionary<string, StructuralMetadataClassProperty> Properties => _properties;
- public string Name
- {
- get => _name;
- set => _name = value;
- }
- public string Description
- {
- get => _description;
- set => _description = value;
- }
- #endregion
- #region API
- public StructuralMetadataClass WithName(string name)
- {
- Name = name;
- return this;
- }
- public StructuralMetadataClass WithDescription(string description)
- {
- Description = description;
- return this;
- }
- public StructuralMetadataClassProperty UseProperty(string key)
- {
- if (_properties.TryGetValue(key, out var value)) return value;
- value = new StructuralMetadataClassProperty();
- _properties[key] = value;
- return value;
- }
- public PropertyTexture AddPropertyTexture()
- {
- return LogicalParent.LogicalParent.AddPropertyTexture(this);
- }
- public PropertyAttribute AddPropertyAttribute()
- {
- return LogicalParent.LogicalParent.AddPropertyAttribute(this);
- }
- public PropertyTable AddPropertyTable(int featureCount, string name = null)
- {
- return LogicalParent.LogicalParent.AddPropertyTable(this, featureCount, name);
- }
- #endregion
- }
- /// <remarks>
- /// Use <see cref="StructuralMetadataClass.UseProperty(string)"/> to create an instance of this class.
- /// </remarks>
- public partial class StructuralMetadataClassProperty : IChildOfDictionary<StructuralMetadataClass>
- {
- #region child properties
- public string LogicalKey { get; private set; }
- public StructuralMetadataClass LogicalParent { get; private set; }
- void IChildOfDictionary<StructuralMetadataClass>.SetLogicalParent(StructuralMetadataClass parent, string key)
- {
- LogicalParent = parent;
- LogicalKey = key;
- }
- #endregion
- #region properties
- public string Name
- {
- get => _name;
- set => _name = value;
- }
- public string Description
- {
- get => _description;
- set => _description = value;
- }
- internal ELEMENTTYPE Type
- {
- get => _type;
- // set => _type = value;
- }
- public string EnumType
- {
- get => _enumType;
- // set => _enumType = value;
- }
- public DATATYPE? ComponentType
- {
- get => _componentType;
- // set => _componentType = value;
- }
- public bool Required
- {
- get => _required ?? _requiredDefault;
- set => _required = value.AsNullable(_requiredDefault);
- }
- public JsonNode NoData
- {
- get => _noData;
- }
- public bool Normalized
- {
- get => _normalized ?? _normalizedDefault;
- set => _normalized = value.AsNullable(_normalizedDefault);
- }
- public bool Array
- {
- get => _array ?? _arrayDefault;
- set => _array = value.AsNullable(_arrayDefault);
- }
- public int? Count
- {
- get => _count;
- set => _count = value;
- }
- /** Commented out for now, as it is not supported
- public JsonNode Min
- {
- get => _min;
- set => _min = value;
- }
- public JsonNode Max
- {
- get => _max;
- set => _max = value;
- }
- public JsonNode Scale
- {
- get => _scale;
- set => _scale = value;
- }
- public JsonNode Offset
- {
- get => _offset;
- set => _offset = value;
- }
- */
- #endregion
- #region API
- public StructuralMetadataClassProperty WithName(string name)
- {
- Name = name;
- return this;
- }
- public StructuralMetadataClassProperty WithDescription(string description)
- {
- Description = description;
- return this;
- }
- public StructuralMetadataClassProperty WithStringType(string noData = null, string defaultValue = null)
- {
- _type = ElementType.STRING;
- if (noData != null) _noData = noData;
- if(defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithBooleanType()
- {
- _type = ElementType.BOOLEAN;
- return this;
- }
- public StructuralMetadataClassProperty WithUInt8Type(byte? noData = null, byte? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.UINT8;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithInt8Type(sbyte? noData = null, sbyte? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.INT8;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithUInt16Type(ushort? noData = null, ushort? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.UINT16;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithInt16Type(short? noData = null, short? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.INT16;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithUInt32Type(uint? noData = null, uint? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.UINT32;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithInt32Type(int? noData = null, int? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.INT32;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithUInt64Type(ulong? noData = null, ulong? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.UINT64;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithInt64Type(long? noData = null, long? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.INT64;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithFloat32Type(float? noData = null, float? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.FLOAT32;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithFloat64Type(double? noData = null, double? defaultValue = null)
- {
- _type = ELEMENTTYPE.SCALAR;
- _componentType = DATATYPE.FLOAT64;
- if (noData != null) _noData = noData;
- if (defaultValue != null) _default = defaultValue;
- return this;
- }
- public StructuralMetadataClassProperty WithVector3Type(Vector3? noData = null, Vector3? defaultValue = null)
- {
- _type = ElementType.VEC3;
- _componentType = DataType.FLOAT32;
- if (noData != null)
- {
- _noData = new JsonArray(noData.Value.X, noData.Value.Y, noData.Value.Z);
- }
- if (defaultValue != null)
- {
- _default = new JsonArray(defaultValue.Value.X, defaultValue.Value.Y, defaultValue.Value.Z);
- }
- return this;
- }
- public StructuralMetadataClassProperty WithMatrix4x4Type(Matrix4x4? noData = null, Matrix4x4? defaultValue = null)
- {
- _type = ElementType.MAT4;
- _componentType = DataType.FLOAT32;
- if (noData != null)
- {
- var m4 = noData.Value;
- _noData = new JsonArray(
- m4.M11, m4.M12, m4.M13, m4.M14,
- m4.M21, m4.M22, m4.M23, m4.M24,
- m4.M31, m4.M32, m4.M33, m4.M34,
- m4.M41, m4.M42, m4.M43, m4.M44);
- }
- if (defaultValue != null)
- {
- var m4 = defaultValue.Value;
- _default = new JsonArray(
- m4.M11, m4.M12, m4.M13, m4.M14,
- m4.M21, m4.M22, m4.M23, m4.M24,
- m4.M31, m4.M32, m4.M33, m4.M34,
- m4.M41, m4.M42, m4.M43, m4.M44);
- }
- return this;
- }
- public StructuralMetadataClassProperty WithCount()
- {
- _type = ElementType.MAT4;
- _componentType = DataType.FLOAT32;
- return this;
- }
- public StructuralMetadataClassProperty WithBooleanArrayType(int? count = null)
- {
- var property = WithArrayType(ELEMENTTYPE.BOOLEAN, null, count);
- return property;
- }
- public StructuralMetadataClassProperty WithUInt8ArrayType(int? count = null, byte? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.UINT8, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithInt8ArrayType(int? count = null, sbyte? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.INT8, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithInt16ArrayType(int? count = null, short? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.INT16, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithUInt16ArrayType(int? count = null, ushort? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.UINT16, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithInt32ArrayType(int? count = null, int? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.INT32, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithUInt32ArrayType(int? count = null, uint? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.UINT32, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithInt64ArrayType(int? count = null, long? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.INT64, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithUInt64ArrayType(int? count = null, ulong? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.UINT64, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithFloat32ArrayType(int? count = null, float? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.FLOAT32, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithFloat64ArrayType(int? count = null, double? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.SCALAR, DATATYPE.FLOAT64, count);
- if (noData != null) property._noData = noData;
- return property;
- }
- public StructuralMetadataClassProperty WithVector3ArrayType(int? count = null, Vector3? noData = null)
- {
- var property = WithArrayType(ELEMENTTYPE.VEC3, DATATYPE.FLOAT32, count);
- return property;
- }
- public StructuralMetadataClassProperty WithMatrix4x4ArrayType(int? count = null)
- {
- return WithArrayType(ELEMENTTYPE.MAT4, DATATYPE.FLOAT32, count);
- }
- public StructuralMetadataClassProperty WithStringArrayType(int? count = null)
- {
- return WithArrayType(ELEMENTTYPE.STRING, null, count);
- }
- private StructuralMetadataClassProperty WithArrayType(ELEMENTTYPE etype, DATATYPE? ctype = null, int? count = null)
- {
- _type = etype;
- _componentType = ctype;
- Array = true;
- Count = count;
- return this;
- }
- public StructuralMetadataClassProperty WithEnumArrayType(StructuralMetadataEnum enumeration, int? count = null, string noData = null)
- {
- _type = ELEMENTTYPE.ENUM;
- _enumType = enumeration.LogicalKey;
- Array = true;
- Count = count;
- if (noData != null) _noData = noData;
- return this;
- }
- public StructuralMetadataClassProperty WithEnumeration(StructuralMetadataEnum enumeration, string noData = null)
- {
- _type = ELEMENTTYPE.ENUM;
- _enumType = enumeration.LogicalKey;
- if (noData != null) _noData = noData;
- return this;
- }
- public StructuralMetadataClassProperty WithRequired(bool required)
- {
- Required = required;
- return this;
- }
- public StructuralMetadataClassProperty WithNormalized(bool normalized)
- {
- Normalized = normalized;
- return this;
- }
- #endregion
- }
- #endregion
- }
- }
|