Browse Source

namespace adjustments

vpenades 2 years ago
parent
commit
8e9b80da99

+ 2 - 0
build/SharpGLTF.CodeGen/Constants.cs

@@ -81,6 +81,8 @@ namespace SharpGLTF
 
 
         public static string CesiumNameSpace => "SharpGLTF.Schema2.Tiles3D";
         public static string CesiumNameSpace => "SharpGLTF.Schema2.Tiles3D";
 
 
+        public static string AgiNameSpace => "SharpGLTF.Schema2.AGI";
+
         #endregion
         #endregion
     }
     }
 }
 }

+ 10 - 23
build/SharpGLTF.CodeGen/Ext.AGI_Articulations.cs

@@ -43,29 +43,16 @@ namespace SharpGLTF
 
 
         public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
         public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
         {
         {
-            newEmitter.SetRuntimeName("AGI_articulations glTF extension", "AgiRootArticulations");
-            newEmitter.SetRuntimeName("AGI_articulations glTF Node extension", "AgiNodeArticulations");
-            newEmitter.SetRuntimeName("Articulation", "AgiArticulation");
-            newEmitter.SetRuntimeName("Articulation Stage", "AgiArticulationStage");
-            newEmitter.SetRuntimeName("uniformScale-xRotate-xScale-xTranslate-yRotate-yScale-yTranslate-zRotate-zScale-zTranslate", "AgiArticulationTransformType");            
-
-            var agiArticulationRootClass = ctx.FindClass("AGI_articulations glTF extension");
-            if (agiArticulationRootClass != null)
-            {
-                newEmitter.SetCollectionContainer(agiArticulationRootClass.UseField("articulations"), "ChildrenList<TItem,AgiRootArticulations>");
-            }
-
-            var agiArticulationClass = ctx.FindClass("Articulation");
-            if (agiArticulationClass != null)
-            {
-                newEmitter.SetCollectionContainer(agiArticulationClass.UseField("stages"), "ChildrenList<TItem,AgiArticulation>");
-            }
-
-            var agiStkMetadataRootClass = ctx.FindClass("AGI_stk_metadata glTF extension");
-            if (agiStkMetadataRootClass != null)
-            {
-                newEmitter.SetCollectionContainer(agiStkMetadataRootClass.UseField("solarPanelGroups"), "ChildrenList<TItem,AgiRootStkMetadata>");
-            }
+            newEmitter.SetRuntimeName("AGI_stk_metadata glTF extension", "AgiRootStkMetadata", Constants.AgiNameSpace);
+            newEmitter.SetRuntimeName("AGI_articulations glTF extension", "AgiRootArticulations", Constants.AgiNameSpace);
+            newEmitter.SetRuntimeName("AGI_articulations glTF Node extension", "AgiNodeArticulations", Constants.AgiNameSpace);
+            newEmitter.SetRuntimeName("Articulation", "AgiArticulation", Constants.AgiNameSpace);
+            newEmitter.SetRuntimeName("Articulation Stage", "AgiArticulationStage", Constants.AgiNameSpace);
+            newEmitter.SetRuntimeName("uniformScale-xRotate-xScale-xTranslate-yRotate-yScale-yTranslate-zRotate-zScale-zTranslate", "AgiArticulationTransformType", Constants.AgiNameSpace);
+
+            newEmitter.SetFieldToChildrenList(ctx, "AGI_articulations glTF extension", "articulations");
+            newEmitter.SetFieldToChildrenList(ctx, "Articulation", "stages");
+            newEmitter.SetFieldToChildrenList(ctx, "AGI_stk_metadata glTF extension", "solarPanelGroups");
         }
         }
     }
     }
 }
 }

+ 3 - 3
build/SharpGLTF.CodeGen/Ext.AGI_RootStkMetadata.cs

@@ -36,9 +36,9 @@ namespace SharpGLTF
 
 
         public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
         public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
         {
         {
-            newEmitter.SetRuntimeName("AGI_stk_metadata glTF extension", "AgiRootStkMetadata");
-            newEmitter.SetRuntimeName("AGI_stk_metadata glTF Node extension", "AgiNodeStkMetadata");
-            newEmitter.SetRuntimeName("Solar Panel Group", "AgiStkSolarPanelGroup");
+            newEmitter.SetRuntimeName("AGI_stk_metadata glTF extension", "AgiRootStkMetadata", Constants.AgiNameSpace);
+            newEmitter.SetRuntimeName("AGI_stk_metadata glTF Node extension", "AgiNodeStkMetadata", Constants.AgiNameSpace);
+            newEmitter.SetRuntimeName("Solar Panel Group", "AgiStkSolarPanelGroup", Constants.AgiNameSpace);
         }        
         }        
     }
     }
 }
 }

+ 99 - 95
src/SharpGLTF.Ext.3DTiles/Schema2/Ext.CESIUM_primitive_outline.cs

@@ -4,102 +4,9 @@ using System.Linq;
 
 
 using SharpGLTF.Validation;
 using SharpGLTF.Validation;
 
 
-namespace SharpGLTF.Schema2.Tiles3D
+namespace SharpGLTF.Schema2
 {
 {
-    /// <remarks>
-    /// This extension is attached to a <see cref="Schema2.MeshPrimitive"/> using <see cref="Tiles3DExtensions.SetCesiumOutline"/>
-    /// </remarks>    
-    partial class CesiumPrimitiveOutline
-    {
-        #region lifecycle
-
-        internal CesiumPrimitiveOutline(MeshPrimitive meshPrimitive)
-        {
-            this.meshPrimitive = meshPrimitive;
-        }
-
-        #endregion
-
-        #region properties
-
-        private MeshPrimitive meshPrimitive;
-
-        public Accessor Indices
-        {
-            get
-            {
-                return _indices.HasValue
-                    ? meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors[_indices.Value]
-                    : null;
-            }
-            set
-            {
-                if (value == null) { _indices = null; return; }
-
-                _ValidateAccessor(meshPrimitive.LogicalParent.LogicalParent, value);
-
-                _indices = value.LogicalIndex;
-            }
-        }
-
-        #endregion
-
-        #region validation
-
-        protected override void OnValidateReferences(ValidationContext validate)
-        {
-            validate.IsNullOrIndex(nameof(Indices), this._indices, meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors);
-
-            base.OnValidateReferences(validate);
-        }
-
-        protected override void OnValidateContent(ValidationContext validate)
-        {
-            var outlineAccessor = meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors[(int)_indices];
-            var isValid = _ValidateCesiumOutlineIndices(outlineAccessor, meshPrimitive);
-            validate.IsTrue(nameof(_indices), isValid, "Mismatch between accesor indices and MeshPrimitive indices");
-
-            base.OnValidateContent(validate);
-        }
-
-        internal static void _ValidateAccessor(ModelRoot model, Accessor accessor)
-        {
-            Guard.NotNull(accessor, nameof(accessor));
-            Guard.MustShareLogicalParent(model, "this", accessor, nameof(accessor));
-            Guard.IsTrue(accessor.Encoding == EncodingType.UNSIGNED_INT, nameof(accessor));
-            Guard.IsTrue(accessor.Dimensions == DimensionType.SCALAR, nameof(accessor));
-            Guard.IsFalse(accessor.Normalized, nameof(accessor));
-        }
-
-        /// <summary>
-        /// Checks if all the indices of the Cesium outline accessor are within the range of in the MeshPrimitive indices
-        /// </summary>
-        /// <param name="accessor">Cesium outline accessor</param>
-        /// <param name="meshPrimitive">MeshPrimitive with the CESIUM_primitive_outline extension</param>
-        /// <returns>true all indices are available, false indices are missing </returns>
-        private static bool _ValidateCesiumOutlineIndices(Accessor accessor, MeshPrimitive meshPrimitive)
-        {
-            var cesiumOutlineExtension = meshPrimitive.GetExtension<CesiumPrimitiveOutline>();
-            if (cesiumOutlineExtension != null)
-            {
-                var accessorIndices = accessor.AsIndicesArray();
-                var meshPrimitiveIndices = meshPrimitive.GetIndices();
-                var maxIndex = meshPrimitiveIndices.Max();
-
-                foreach (var _ in from accessorIndice in accessorIndices
-                                  let contains = accessorIndice <= maxIndex
-                                  where !contains
-                                  select new { })
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        #endregion
-    }
-
+    using Tiles3D;
     partial class Tiles3DExtensions
     partial class Tiles3DExtensions
     {
     {
         /// <summary>
         /// <summary>
@@ -137,4 +44,101 @@ namespace SharpGLTF.Schema2.Tiles3D
             ext.Indices = accessor;
             ext.Indices = accessor;
         }
         }
     }
     }
+
+    namespace Tiles3D
+    {
+        /// <remarks>
+        /// This extension is attached to a <see cref="Schema2.MeshPrimitive"/> using <see cref="Tiles3DExtensions.SetCesiumOutline"/>
+        /// </remarks>    
+        partial class CesiumPrimitiveOutline
+        {
+            #region lifecycle
+
+            internal CesiumPrimitiveOutline(MeshPrimitive meshPrimitive)
+            {
+                this.meshPrimitive = meshPrimitive;
+            }
+
+            #endregion
+
+            #region properties
+
+            private MeshPrimitive meshPrimitive;
+
+            public Accessor Indices
+            {
+                get
+                {
+                    return _indices.HasValue
+                        ? meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors[_indices.Value]
+                        : null;
+                }
+                set
+                {
+                    if (value == null) { _indices = null; return; }
+
+                    _ValidateAccessor(meshPrimitive.LogicalParent.LogicalParent, value);
+
+                    _indices = value.LogicalIndex;
+                }
+            }
+
+            #endregion
+
+            #region validation
+
+            protected override void OnValidateReferences(ValidationContext validate)
+            {
+                validate.IsNullOrIndex(nameof(Indices), this._indices, meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors);
+
+                base.OnValidateReferences(validate);
+            }
+
+            protected override void OnValidateContent(ValidationContext validate)
+            {
+                var outlineAccessor = meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors[(int)_indices];
+                var isValid = _ValidateCesiumOutlineIndices(outlineAccessor, meshPrimitive);
+                validate.IsTrue(nameof(_indices), isValid, "Mismatch between accesor indices and MeshPrimitive indices");
+
+                base.OnValidateContent(validate);
+            }
+
+            internal static void _ValidateAccessor(ModelRoot model, Accessor accessor)
+            {
+                Guard.NotNull(accessor, nameof(accessor));
+                Guard.MustShareLogicalParent(model, "this", accessor, nameof(accessor));
+                Guard.IsTrue(accessor.Encoding == EncodingType.UNSIGNED_INT, nameof(accessor));
+                Guard.IsTrue(accessor.Dimensions == DimensionType.SCALAR, nameof(accessor));
+                Guard.IsFalse(accessor.Normalized, nameof(accessor));
+            }
+
+            /// <summary>
+            /// Checks if all the indices of the Cesium outline accessor are within the range of in the MeshPrimitive indices
+            /// </summary>
+            /// <param name="accessor">Cesium outline accessor</param>
+            /// <param name="meshPrimitive">MeshPrimitive with the CESIUM_primitive_outline extension</param>
+            /// <returns>true all indices are available, false indices are missing </returns>
+            private static bool _ValidateCesiumOutlineIndices(Accessor accessor, MeshPrimitive meshPrimitive)
+            {
+                var cesiumOutlineExtension = meshPrimitive.GetExtension<CesiumPrimitiveOutline>();
+                if (cesiumOutlineExtension != null)
+                {
+                    var accessorIndices = accessor.AsIndicesArray();
+                    var meshPrimitiveIndices = meshPrimitive.GetIndices();
+                    var maxIndex = meshPrimitiveIndices.Max();
+
+                    foreach (var _ in from accessorIndice in accessorIndices
+                                      let contains = accessorIndice <= maxIndex
+                                      where !contains
+                                      select new { })
+                    {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            #endregion
+        }
+    }
 }
 }

+ 212 - 205
src/SharpGLTF.Ext.3DTiles/Schema2/Ext.Features.cs

@@ -6,294 +6,301 @@ using System.Linq;
 using SharpGLTF.Collections;
 using SharpGLTF.Collections;
 using SharpGLTF.Validation;
 using SharpGLTF.Validation;
 
 
-namespace SharpGLTF.Schema2.Tiles3D
+namespace SharpGLTF.Schema2
 {
 {
-    /// <remarks>
-    /// This extension is attached to a <see cref="Schema2.Node"/> using <see cref="ExtraProperties.UseExtension{T}"/>
-    /// </remarks>
-    public partial class MeshExtInstanceFeatures
-    {
-        #region lifecycle
-
-        internal MeshExtInstanceFeatures() { }
-
-        internal MeshExtInstanceFeatures(Node node)
-        {
-            _node = node;
-            _featureIds = new ChildrenList<MeshExtInstanceFeatureID, MeshExtInstanceFeatures>(this);            
-        }
+    using Tiles3D;
 
 
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+    partial class Tiles3DExtensions
+    {
+        internal static void ValidateFeatureIdReferences(this IMeshFeatureIDInfo featureId, ModelRoot root)
         {
         {
-            return base.GetLogicalChildren().Concat(_featureIds);
+            if (featureId.PropertyTable.HasValue)
+            {
+                var metadataExtension = root.GetExtension<EXTStructuralMetadataRoot>();
+                Guard.NotNull(metadataExtension, nameof(metadataExtension), "EXT_Structural_Metadata extension is not found.");
+                Guard.NotNull(metadataExtension.PropertyTables[featureId.PropertyTable.Value], nameof(featureId.PropertyTable), $"Property table index {featureId.PropertyTable.Value} does not exist");
+            }
         }
         }
 
 
-        #endregion
-
-        #region data
-
-        private Node _node;
-
-        #endregion
-
-        #region properties
-
-        public Node LogicalParent => _node;
-        public IReadOnlyList<MeshExtInstanceFeatureID> FeatureIds => _featureIds;
-
-        #endregion
-
-        #region API
-
-        public MeshExtInstanceFeatureID CreateFeatureID(IMeshFeatureIDInfo properties)
+        internal static void ValidateFeatureIdContent(this IMeshFeatureIDInfo featureId)
         {
         {
-            var instance = CreateFeatureID();
+            Guard.MustBeGreaterThanOrEqualTo((int)featureId.FeatureCount, 1, nameof(featureId.FeatureCount));
 
 
-            instance.FeatureCount = properties.FeatureCount;
-            instance.NullFeatureId = properties.NullFeatureId;
-            instance.Label = properties.Label;
-            instance.Attribute = properties.Attribute;
-            instance.PropertyTable = properties.PropertyTable;
+            if (featureId.NullFeatureId.HasValue)
+            {
+                Guard.MustBeGreaterThanOrEqualTo((int)featureId.NullFeatureId, 0, nameof(featureId.NullFeatureId));
+            }
+            if (featureId.Label != null)
+            {
+                var regex = "^[a-zA-Z_][a-zA-Z0-9_]*$";
+                Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(featureId.Label, regex), nameof(featureId.Label));
+            }
 
 
-            return instance;
+            if (featureId.Attribute.HasValue)
+            {
+                Guard.MustBeGreaterThanOrEqualTo((int)featureId.Attribute, 0, nameof(featureId.Attribute));
+            }
+            if (featureId.PropertyTable.HasValue)
+            {
+                Guard.MustBeGreaterThanOrEqualTo((int)featureId.PropertyTable, 0, nameof(featureId.PropertyTable));
+            }
         }
         }
 
 
-        public MeshExtInstanceFeatureID CreateFeatureID()
+        /// <summary>
+        /// Set the FeatureIds for a MeshPrimitive
+        /// </summary>        
+        public static MeshExtInstanceFeatureID[] SetInstanceFeatureIds(this Node node, params IMeshFeatureIDInfo[] featureIds)
         {
         {
-            var featureId = new MeshExtInstanceFeatureID();
-            _featureIds.Add(featureId);
-            return featureId;
-        }
-
-        #endregion
+            if (featureIds == null || featureIds.Length == 0) { node.RemoveExtensions<MeshExtInstanceFeatures>(); return Array.Empty<MeshExtInstanceFeatureID>(); }
 
 
-        #region validation
+            var ext = node.UseExtension<MeshExtInstanceFeatures>();
 
 
-        protected override void OnValidateReferences(ValidationContext validate)
-        {
-            var extInstanceFeatures = _node.GetExtension<MeshExtInstanceFeatures>();
-            validate.NotNull(nameof(extInstanceFeatures), extInstanceFeatures);
-            var extMeshGpInstancing = _node.GetExtension<MeshGpuInstancing>();
-            validate.NotNull(nameof(extMeshGpInstancing), extMeshGpInstancing);
+            var result = new MeshExtInstanceFeatureID[featureIds.Length];
 
 
-            foreach (var instanceFeatureId in FeatureIds)
+            for (int i = 0; i < result.Length; ++i)
             {
             {
-                if (instanceFeatureId.Attribute.HasValue)
-                {
-                    var expectedVertexAttribute = $"_FEATURE_ID_{instanceFeatureId.Attribute}";
-                    var gpuInstancing = _node.GetGpuInstancing();
-                    var featureIdAccessors = gpuInstancing.GetAccessor(expectedVertexAttribute);
-                    Guard.NotNull(featureIdAccessors, expectedVertexAttribute);
-                }
-
-                instanceFeatureId.ValidateFeatureIdReferences(_node.LogicalParent);
+                result[i] = ext.CreateFeatureID(featureIds[i]);
             }
             }
 
 
-            base.OnValidateReferences(validate);
+            return result;
         }
         }
 
 
-        protected override void OnValidateContent(ValidationContext validate)
+        /// <summary>
+        /// Set the FeatureIds for a MeshPrimitive
+        /// </summary>        
+        public static MeshExtMeshFeatureID[] SetMeshFeatureIds(this MeshPrimitive primitive, params (IMeshFeatureIDInfo fid, Texture tex, IReadOnlyList<int> channels)[] featureIds)
         {
         {
-            var extInstanceFeatures = _node.GetExtension<MeshExtInstanceFeatures>();
-            validate.NotNull(nameof(FeatureIds), extInstanceFeatures.FeatureIds);
-            validate.IsTrue(nameof(FeatureIds), extInstanceFeatures.FeatureIds.Count > 0, "Instance FeatureIds has items");
+            if (featureIds == null || featureIds.Length == 0) { primitive.RemoveExtensions<MeshExtMeshFeatures>(); return Array.Empty<MeshExtMeshFeatureID>(); }
+
+            var ext = primitive.UseExtension<MeshExtMeshFeatures>();
+
+            var result = new MeshExtMeshFeatureID[featureIds.Length];
 
 
-            foreach (var instanceFeatureId in FeatureIds)
+            for (int i = 0; i < result.Length; ++i)
             {
             {
-                instanceFeatureId.ValidateFeatureIdContent();
+                var (fid, tex, channels) = featureIds[i];
+                result[i] = ext.CreateFeatureID(fid, tex, channels);
             }
             }
 
 
-            base.OnValidateContent(validate);
+            return result;
         }
         }
-
-        #endregion
     }
     }
 
 
-    /// <remarks>
-    /// This extension is attached to a <see cref="Schema2.MeshPrimitive"/>
-    /// </remarks>    
-    public partial class MeshExtMeshFeatures
-    {
-        #region lifecycle
 
 
-        internal MeshExtMeshFeatures(MeshPrimitive meshPrimitive)
-        {
-            _meshPrimitive = meshPrimitive;
-            _featureIds = new ChildrenList<MeshExtMeshFeatureID, MeshExtMeshFeatures>(this);
-        }
-
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+    namespace Tiles3D
+    {
+        /// <remarks>
+        /// This extension is attached to a <see cref="Schema2.Node"/> using <see cref="ExtraProperties.UseExtension{T}"/>
+        /// </remarks>
+        public partial class MeshExtInstanceFeatures
         {
         {
-            return base.GetLogicalChildren().Concat(_featureIds);
-        }
+            #region lifecycle
 
 
-        #endregion
+            internal MeshExtInstanceFeatures() { }
 
 
-        #region data
+            internal MeshExtInstanceFeatures(Node node)
+            {
+                _node = node;
+                _featureIds = new ChildrenList<MeshExtInstanceFeatureID, MeshExtInstanceFeatures>(this);
+            }
 
 
-        private MeshPrimitive _meshPrimitive;
+            protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+            {
+                return base.GetLogicalChildren().Concat(_featureIds);
+            }
 
 
-        #endregion
+            #endregion
 
 
-        #region properties
+            #region data
 
 
-        public MeshPrimitive LogicalParent => _meshPrimitive;
+            private Node _node;
 
 
-        public IReadOnlyList<MeshExtMeshFeatureID> FeatureIds => _featureIds;
+            #endregion
 
 
-        #endregion
+            #region properties
 
 
-        #region API
+            public Node LogicalParent => _node;
+            public IReadOnlyList<MeshExtInstanceFeatureID> FeatureIds => _featureIds;
 
 
-        public MeshExtMeshFeatureID CreateFeatureID(IMeshFeatureIDInfo properties, Texture texture = null, IReadOnlyList<int> texChannels = null)
-        {
-            var instance = CreateFeatureID();
+            #endregion
 
 
-            instance.FeatureCount = properties.FeatureCount;
-            instance.NullFeatureId = properties.NullFeatureId;
-            instance.Label = properties.Label;
-            instance.Attribute = properties.Attribute;
-            instance.PropertyTable = properties.PropertyTable;
+            #region API
 
 
-            if (texture != null)
+            public MeshExtInstanceFeatureID CreateFeatureID(IMeshFeatureIDInfo properties)
             {
             {
-                var texInfo = instance.UseTexture();
-                texInfo.Texture = texture;
-                if (texChannels != null) texInfo.SetChannels(texChannels);
-            }            
+                var instance = CreateFeatureID();
 
 
-            return instance;
-        }
+                instance.FeatureCount = properties.FeatureCount;
+                instance.NullFeatureId = properties.NullFeatureId;
+                instance.Label = properties.Label;
+                instance.Attribute = properties.Attribute;
+                instance.PropertyTable = properties.PropertyTable;
 
 
-        public MeshExtMeshFeatureID CreateFeatureID()
-        {
-            var featureId = new MeshExtMeshFeatureID();
-            _featureIds.Add(featureId);
-            return featureId;
-        }
+                return instance;
+            }
 
 
-        #endregion
+            public MeshExtInstanceFeatureID CreateFeatureID()
+            {
+                var featureId = new MeshExtInstanceFeatureID();
+                _featureIds.Add(featureId);
+                return featureId;
+            }
 
 
-        #region validation
+            #endregion
 
 
-        protected override void OnValidateReferences(ValidationContext validate)
-        {
-            foreach (var featureId in _featureIds)
+            #region validation
+
+            protected override void OnValidateReferences(ValidationContext validate)
             {
             {
-                if (featureId.Attribute.HasValue)
+                var extInstanceFeatures = _node.GetExtension<MeshExtInstanceFeatures>();
+                validate.NotNull(nameof(extInstanceFeatures), extInstanceFeatures);
+                var extMeshGpInstancing = _node.GetExtension<MeshGpuInstancing>();
+                validate.NotNull(nameof(extMeshGpInstancing), extMeshGpInstancing);
+
+                foreach (var instanceFeatureId in FeatureIds)
                 {
                 {
-                    var expectedVertexAttribute = $"_FEATURE_ID_{featureId.Attribute}";
-                    Guard.NotNull(_meshPrimitive.GetVertexAccessor(expectedVertexAttribute), expectedVertexAttribute);
+                    if (instanceFeatureId.Attribute.HasValue)
+                    {
+                        var expectedVertexAttribute = $"_FEATURE_ID_{instanceFeatureId.Attribute}";
+                        var gpuInstancing = _node.GetGpuInstancing();
+                        var featureIdAccessors = gpuInstancing.GetAccessor(expectedVertexAttribute);
+                        Guard.NotNull(featureIdAccessors, expectedVertexAttribute);
+                    }
+
+                    instanceFeatureId.ValidateFeatureIdReferences(_node.LogicalParent);
                 }
                 }
 
 
-                featureId.ValidateFeatureIdReferences(_meshPrimitive.LogicalParent.LogicalParent);
+                base.OnValidateReferences(validate);
+            }
 
 
-                var texture = featureId.GetTexture();
+            protected override void OnValidateContent(ValidationContext validate)
+            {
+                var extInstanceFeatures = _node.GetExtension<MeshExtInstanceFeatures>();
+                validate.NotNull(nameof(FeatureIds), extInstanceFeatures.FeatureIds);
+                validate.IsTrue(nameof(FeatureIds), extInstanceFeatures.FeatureIds.Count > 0, "Instance FeatureIds has items");
 
 
-                if (texture != null)
+                foreach (var instanceFeatureId in FeatureIds)
                 {
                 {
-                    var expectedTexCoordAttribute = $"TEXCOORD_{texture.TextureCoordinate}";
-                    Guard.NotNull(_meshPrimitive.GetVertexAccessor(expectedTexCoordAttribute), expectedTexCoordAttribute);
-
-                    var modelRoot = _meshPrimitive.LogicalParent.LogicalParent;
-                    validate.IsNullOrIndex(nameof(texture), texture.TextureCoordinate, modelRoot.LogicalTextures);
+                    instanceFeatureId.ValidateFeatureIdContent();
                 }
                 }
+
+                base.OnValidateContent(validate);
             }
             }
 
 
-            base.OnValidateReferences(validate);
+            #endregion
         }
         }
 
 
-        protected override void OnValidateContent(ValidationContext validate)
+        /// <remarks>
+        /// This extension is attached to a <see cref="Schema2.MeshPrimitive"/>
+        /// </remarks>    
+        public partial class MeshExtMeshFeatures
         {
         {
-            var extMeshFeatures = _meshPrimitive.Extensions.Where(item => item is MeshExtMeshFeatures).FirstOrDefault();
-            validate.NotNull(nameof(extMeshFeatures), extMeshFeatures);
-            validate.NotNull(nameof(FeatureIds), _featureIds);
-            validate.IsTrue(nameof(FeatureIds), _featureIds.Count > 0, "FeatureIds has items");
+            #region lifecycle
 
 
-            foreach (var featureId in _featureIds)
+            internal MeshExtMeshFeatures(MeshPrimitive meshPrimitive)
             {
             {
-                featureId.ValidateFeatureIdContent();                
+                _meshPrimitive = meshPrimitive;
+                _featureIds = new ChildrenList<MeshExtMeshFeatureID, MeshExtMeshFeatures>(this);
             }
             }
 
 
-            base.OnValidateContent(validate);
-        }
-
-        #endregion
-    }
-
-    partial class Tiles3DExtensions
-    {
-        internal static void ValidateFeatureIdReferences(this IMeshFeatureIDInfo featureId, ModelRoot root)
-        {
-            if (featureId.PropertyTable.HasValue)
+            protected override IEnumerable<ExtraProperties> GetLogicalChildren()
             {
             {
-                var metadataExtension = root.GetExtension<EXTStructuralMetadataRoot>();
-                Guard.NotNull(metadataExtension, nameof(metadataExtension), "EXT_Structural_Metadata extension is not found.");
-                Guard.NotNull(metadataExtension.PropertyTables[featureId.PropertyTable.Value], nameof(featureId.PropertyTable), $"Property table index {featureId.PropertyTable.Value} does not exist");
+                return base.GetLogicalChildren().Concat(_featureIds);
             }
             }
-        }
-        
-        internal static void ValidateFeatureIdContent(this IMeshFeatureIDInfo featureId)
-        {
-            Guard.MustBeGreaterThanOrEqualTo((int)featureId.FeatureCount, 1, nameof(featureId.FeatureCount));
 
 
-            if (featureId.NullFeatureId.HasValue)
-            {
-                Guard.MustBeGreaterThanOrEqualTo((int)featureId.NullFeatureId, 0, nameof(featureId.NullFeatureId));
-            }
-            if (featureId.Label != null)
-            {
-                var regex = "^[a-zA-Z_][a-zA-Z0-9_]*$";
-                Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(featureId.Label, regex), nameof(featureId.Label));
-            }
+            #endregion
 
 
-            if (featureId.Attribute.HasValue)
+            #region data
+
+            private MeshPrimitive _meshPrimitive;
+
+            #endregion
+
+            #region properties
+
+            public MeshPrimitive LogicalParent => _meshPrimitive;
+
+            public IReadOnlyList<MeshExtMeshFeatureID> FeatureIds => _featureIds;
+
+            #endregion
+
+            #region API
+
+            public MeshExtMeshFeatureID CreateFeatureID(IMeshFeatureIDInfo properties, Texture texture = null, IReadOnlyList<int> texChannels = null)
             {
             {
-                Guard.MustBeGreaterThanOrEqualTo((int)featureId.Attribute, 0, nameof(featureId.Attribute));
+                var instance = CreateFeatureID();
+
+                instance.FeatureCount = properties.FeatureCount;
+                instance.NullFeatureId = properties.NullFeatureId;
+                instance.Label = properties.Label;
+                instance.Attribute = properties.Attribute;
+                instance.PropertyTable = properties.PropertyTable;
+
+                if (texture != null)
+                {
+                    var texInfo = instance.UseTexture();
+                    texInfo.Texture = texture;
+                    if (texChannels != null) texInfo.SetChannels(texChannels);
+                }
+
+                return instance;
             }
             }
-            if (featureId.PropertyTable.HasValue)
+
+            public MeshExtMeshFeatureID CreateFeatureID()
             {
             {
-                Guard.MustBeGreaterThanOrEqualTo((int)featureId.PropertyTable, 0, nameof(featureId.PropertyTable));
+                var featureId = new MeshExtMeshFeatureID();
+                _featureIds.Add(featureId);
+                return featureId;
             }
             }
-        }
 
 
-        /// <summary>
-        /// Set the FeatureIds for a MeshPrimitive
-        /// </summary>        
-        public static MeshExtInstanceFeatureID[] SetInstanceFeatureIds(this Node node, params IMeshFeatureIDInfo[] featureIds)
-        {
-            if (featureIds == null || featureIds.Length == 0) { node.RemoveExtensions<MeshExtInstanceFeatures>(); return Array.Empty<MeshExtInstanceFeatureID>(); }
+            #endregion
 
 
-            var ext = node.UseExtension<MeshExtInstanceFeatures>();
+            #region validation
 
 
-            var result = new MeshExtInstanceFeatureID[featureIds.Length];
+            protected override void OnValidateReferences(ValidationContext validate)
+            {
+                foreach (var featureId in _featureIds)
+                {
+                    if (featureId.Attribute.HasValue)
+                    {
+                        var expectedVertexAttribute = $"_FEATURE_ID_{featureId.Attribute}";
+                        Guard.NotNull(_meshPrimitive.GetVertexAccessor(expectedVertexAttribute), expectedVertexAttribute);
+                    }
 
 
-            for (int i = 0; i < result.Length; ++i)
-            {                
-                result[i] = ext.CreateFeatureID(featureIds[i]);
-            }
+                    featureId.ValidateFeatureIdReferences(_meshPrimitive.LogicalParent.LogicalParent);
 
 
-            return result;
-        }
+                    var texture = featureId.GetTexture();
 
 
-        /// <summary>
-        /// Set the FeatureIds for a MeshPrimitive
-        /// </summary>        
-        public static MeshExtMeshFeatureID[] SetMeshFeatureIds(this MeshPrimitive primitive, params (IMeshFeatureIDInfo fid, Texture tex, IReadOnlyList<int> channels)[] featureIds)
-        {
-            if (featureIds == null || featureIds.Length == 0) { primitive.RemoveExtensions<MeshExtMeshFeatures>(); return Array.Empty<MeshExtMeshFeatureID>(); }
+                    if (texture != null)
+                    {
+                        var expectedTexCoordAttribute = $"TEXCOORD_{texture.TextureCoordinate}";
+                        Guard.NotNull(_meshPrimitive.GetVertexAccessor(expectedTexCoordAttribute), expectedTexCoordAttribute);
 
 
-            var ext = primitive.UseExtension<MeshExtMeshFeatures>();
+                        var modelRoot = _meshPrimitive.LogicalParent.LogicalParent;
+                        validate.IsNullOrIndex(nameof(texture), texture.TextureCoordinate, modelRoot.LogicalTextures);
+                    }
+                }
 
 
-            var result = new MeshExtMeshFeatureID[featureIds.Length];
+                base.OnValidateReferences(validate);
+            }
 
 
-            for(int i=0; i < result.Length; ++i)
+            protected override void OnValidateContent(ValidationContext validate)
             {
             {
-                var (fid, tex, channels) = featureIds[i];
-                result[i] = ext.CreateFeatureID(fid, tex, channels);
+                var extMeshFeatures = _meshPrimitive.Extensions.Where(item => item is MeshExtMeshFeatures).FirstOrDefault();
+                validate.NotNull(nameof(extMeshFeatures), extMeshFeatures);
+                validate.NotNull(nameof(FeatureIds), _featureIds);
+                validate.IsTrue(nameof(FeatureIds), _featureIds.Count > 0, "FeatureIds has items");
+
+                foreach (var featureId in _featureIds)
+                {
+                    featureId.ValidateFeatureIdContent();
+                }
+
+                base.OnValidateContent(validate);
             }
             }
 
 
-            return result;
+            #endregion
         }
         }
-    }
+
+    }    
 }
 }

+ 49 - 44
src/SharpGLTF.Ext.3DTiles/Schema2/Ext.StructuralMetadataPrimitive.cs

@@ -2,70 +2,75 @@
 
 
 using SharpGLTF.Validation;
 using SharpGLTF.Validation;
 
 
-namespace SharpGLTF.Schema2.Tiles3D
+namespace SharpGLTF.Schema2
 {
 {
-    partial class ExtStructuralMetadataMeshPrimitive
+    using Tiles3D;
+
+    partial class Tiles3DExtensions
     {
     {
-        internal ExtStructuralMetadataMeshPrimitive(MeshPrimitive meshPrimitive)
+        public static void SetPropertyTextures(this MeshPrimitive primitive, List<int> propertyTextures)
         {
         {
-            this.meshPrimitive = meshPrimitive;
-            _propertyTextures = new List<int>();
-            _propertyAttributes = new List<int>();
-        }
-
-        private MeshPrimitive meshPrimitive;
+            if (propertyTextures == null) { primitive.RemoveExtensions<ExtStructuralMetadataMeshPrimitive>(); return; }
 
 
-        public List<int> PropertyTextures
-        {
-            get => _propertyTextures;
-            set => _propertyTextures = value;
+            var ext = primitive.UseExtension<ExtStructuralMetadataMeshPrimitive>();
+            ext.PropertyTextures = propertyTextures;
         }
         }
 
 
-        public List<int> PropertyAttributes
+        public static void SetPropertyAttributes(this MeshPrimitive primitive, List<int> propertyAttributes)
         {
         {
-            get => _propertyAttributes;
-            set => _propertyAttributes = value;
+            if (propertyAttributes == null) { primitive.RemoveExtensions<ExtStructuralMetadataMeshPrimitive>(); return; }
+
+            var ext = primitive.UseExtension<ExtStructuralMetadataMeshPrimitive>();
+            ext.PropertyAttributes = propertyAttributes;
         }
         }
+    }
 
 
-        protected override void OnValidateReferences(ValidationContext validate)
+    namespace Tiles3D
+    {
+        partial class ExtStructuralMetadataMeshPrimitive
         {
         {
-            foreach (var propertyTexture in PropertyTextures)
+            internal ExtStructuralMetadataMeshPrimitive(MeshPrimitive meshPrimitive)
             {
             {
-                var propertyTextures = meshPrimitive.LogicalParent.LogicalParent.GetExtension<EXTStructuralMetadataRoot>().PropertyTextures;
-                validate.IsNullOrIndex(nameof(propertyTexture), propertyTexture, propertyTextures);
+                this.meshPrimitive = meshPrimitive;
+                _propertyTextures = new List<int>();
+                _propertyAttributes = new List<int>();
             }
             }
 
 
-            foreach (var propertyAttribute in PropertyAttributes)
+            private MeshPrimitive meshPrimitive;
+
+            public List<int> PropertyTextures
             {
             {
-                var propertyAttributes = meshPrimitive.LogicalParent.LogicalParent.GetExtension<EXTStructuralMetadataRoot>().PropertyAttributes;
-                validate.IsNullOrIndex(nameof(propertyAttribute), propertyAttribute, propertyAttributes);
+                get => _propertyTextures;
+                set => _propertyTextures = value;
             }
             }
 
 
-            base.OnValidateReferences(validate);
-        }
-
-        protected override void OnValidateContent(ValidationContext result)
-        {
-            base.OnValidateContent(result);
-        }
-    }
+            public List<int> PropertyAttributes
+            {
+                get => _propertyAttributes;
+                set => _propertyAttributes = value;
+            }
 
 
-    partial class Tiles3DExtensions
-    {
-        public static void SetPropertyTextures(this MeshPrimitive primitive, List<int> propertyTextures)
-        {
-            if (propertyTextures == null) { primitive.RemoveExtensions<ExtStructuralMetadataMeshPrimitive>(); return; }
+            protected override void OnValidateReferences(ValidationContext validate)
+            {
+                foreach (var propertyTexture in PropertyTextures)
+                {
+                    var propertyTextures = meshPrimitive.LogicalParent.LogicalParent.GetExtension<EXTStructuralMetadataRoot>().PropertyTextures;
+                    validate.IsNullOrIndex(nameof(propertyTexture), propertyTexture, propertyTextures);
+                }
 
 
-            var ext = primitive.UseExtension<ExtStructuralMetadataMeshPrimitive>();
-            ext.PropertyTextures = propertyTextures;
-        }
+                foreach (var propertyAttribute in PropertyAttributes)
+                {
+                    var propertyAttributes = meshPrimitive.LogicalParent.LogicalParent.GetExtension<EXTStructuralMetadataRoot>().PropertyAttributes;
+                    validate.IsNullOrIndex(nameof(propertyAttribute), propertyAttribute, propertyAttributes);
+                }
 
 
-        public static void SetPropertyAttributes(this MeshPrimitive primitive, List<int> propertyAttributes)
-        {
-            if (propertyAttributes == null) { primitive.RemoveExtensions<ExtStructuralMetadataMeshPrimitive>(); return; }
+                base.OnValidateReferences(validate);
+            }
 
 
-            var ext = primitive.UseExtension<ExtStructuralMetadataMeshPrimitive>();
-            ext.PropertyAttributes = propertyAttributes;
+            protected override void OnValidateContent(ValidationContext result)
+            {
+                base.OnValidateContent(result);
+            }
         }
         }
     }
     }
 }
 }

+ 499 - 495
src/SharpGLTF.Ext.3DTiles/Schema2/Ext.StructuralMetadataRoot.cs

@@ -6,13 +6,14 @@ using System.Reflection;
 
 
 using OneOf;
 using OneOf;
 
 
-namespace SharpGLTF.Schema2.Tiles3D
+namespace SharpGLTF.Schema2
 {
 {
     using Collections;
     using Collections;
     using Memory;
     using Memory;
     using Validation;
     using Validation;
+    using Tiles3D;
 
 
-    using METADATAORURI = OneOf<StructuralMetadataSchema, Uri>;
+    using METADATAORURI = OneOf<Tiles3D.StructuralMetadataSchema, Uri>;
 
 
     partial class Tiles3DExtensions
     partial class Tiles3DExtensions
     {
     {
@@ -138,686 +139,689 @@ METADATAORURI schema)
         }
         }
     }
     }
 
 
-    public partial class EXTStructuralMetadataRoot
+    namespace Tiles3D
     {
     {
-        #region lifecycle
-
-        internal EXTStructuralMetadataRoot(ModelRoot modelRoot)
+        public partial class EXTStructuralMetadataRoot
         {
         {
-            this.modelRoot = modelRoot;
-            _propertyTables = new ChildrenList<PropertyTable, EXTStructuralMetadataRoot>(this);
-            _propertyAttributes = new ChildrenList<PropertyAttribute, EXTStructuralMetadataRoot>(this);
-            _propertyTextures = new ChildrenList<PropertyTexture, EXTStructuralMetadataRoot>(this);
-        }
+            #region lifecycle
 
 
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
-        {
-            var items = base.GetLogicalChildren()
-                .Concat(_propertyTables)
-                .Concat(_propertyAttributes)
-                .Concat(_propertyTextures);
+            internal EXTStructuralMetadataRoot(ModelRoot modelRoot)
+            {
+                this.modelRoot = modelRoot;
+                _propertyTables = new ChildrenList<PropertyTable, EXTStructuralMetadataRoot>(this);
+                _propertyAttributes = new ChildrenList<PropertyAttribute, EXTStructuralMetadataRoot>(this);
+                _propertyTextures = new ChildrenList<PropertyTexture, EXTStructuralMetadataRoot>(this);
+            }
 
 
-            if (Schema != null) items = items.Append(Schema);
+            protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+            {
+                var items = base.GetLogicalChildren()
+                    .Concat(_propertyTables)
+                    .Concat(_propertyAttributes)
+                    .Concat(_propertyTextures);
 
 
-            return items;
-        }
+                if (Schema != null) items = items.Append(Schema);
 
 
-        #endregion
+                return items;
+            }
 
 
-        #region data
+            #endregion
 
 
-        private ModelRoot modelRoot;
+            #region data
 
 
-        #endregion
+            private ModelRoot modelRoot;
 
 
-        #region properties
+            #endregion
 
 
-        internal string SchemaUri
-        {
-            get => _schemaUri;
-            set { _schemaUri = value; }
-        }
+            #region properties
 
 
-        internal StructuralMetadataSchema Schema
-        {
-            get => _schema;
-            set { GetChildSetter(this).SetListProperty(ref _schema, value); }
-        }
+            internal string SchemaUri
+            {
+                get => _schemaUri;
+                set { _schemaUri = value; }
+            }
 
 
-        internal IReadOnlyList<PropertyTable> PropertyTables => _propertyTables;
-        internal IReadOnlyList<PropertyAttribute> PropertyAttributes => _propertyAttributes;
-        internal IReadOnlyList<PropertyTexture> PropertyTextures => _propertyTextures;
+            internal StructuralMetadataSchema Schema
+            {
+                get => _schema;
+                set { GetChildSetter(this).SetListProperty(ref _schema, value); }
+            }
 
 
-        #endregion
+            internal IReadOnlyList<PropertyTable> PropertyTables => _propertyTables;
+            internal IReadOnlyList<PropertyAttribute> PropertyAttributes => _propertyAttributes;
+            internal IReadOnlyList<PropertyTexture> PropertyTextures => _propertyTextures;
 
 
-        #region API
+            #endregion
 
 
-        internal void AddSchema(METADATAORURI schema)
-        {
-            schema.Switch(
-                StructuralMetadataSchema => _schema = StructuralMetadataSchema,
-                Uri => this.SchemaUri = Uri.ToString()
-                );
-        }
+            #region API
 
 
-        #endregion
+            internal void AddSchema(METADATAORURI schema)
+            {
+                schema.Switch(
+                    StructuralMetadataSchema => _schema = StructuralMetadataSchema,
+                    Uri => this.SchemaUri = Uri.ToString()
+                    );
+            }
 
 
-        #region validation
+            #endregion
 
 
-        protected override void OnValidateReferences(ValidationContext validate)
-        {
-            foreach (var propertyTexture in PropertyTextures)
+            #region validation
+
+            protected override void OnValidateReferences(ValidationContext validate)
             {
             {
-                foreach (var propertyTextureProperty in propertyTexture.Properties)
+                foreach (var propertyTexture in PropertyTextures)
                 {
                 {
-                    var textureId = propertyTextureProperty.Value.LogicalTextureIndex;
-                    validate.IsNullOrIndex(nameof(propertyTexture), textureId, modelRoot.LogicalTextures);
+                    foreach (var propertyTextureProperty in propertyTexture.Properties)
+                    {
+                        var textureId = propertyTextureProperty.Value.LogicalTextureIndex;
+                        validate.IsNullOrIndex(nameof(propertyTexture), textureId, modelRoot.LogicalTextures);
+                    }
                 }
                 }
-            }
-
-            foreach (var propertyTable in PropertyTables)
-            {
-                Guard.NotNull(Schema.Classes[propertyTable.Class], nameof(propertyTable.Class), $"Schema must have class {propertyTable.Class}");
 
 
-                foreach (var property in propertyTable.Properties)
+                foreach (var propertyTable in PropertyTables)
                 {
                 {
-                    Guard.NotNull(Schema.Classes[propertyTable.Class].Properties[property.Key], nameof(property.Key), $"Schema must have property {property.Key}");
+                    Guard.NotNull(Schema.Classes[propertyTable.Class], nameof(propertyTable.Class), $"Schema must have class {propertyTable.Class}");
 
 
-                    var values = property.Value.Values;
-                    validate.IsNullOrIndex(nameof(propertyTable), values, modelRoot.LogicalBufferViews);
-
-                    if (property.Value.ArrayOffsets.HasValue)
+                    foreach (var property in propertyTable.Properties)
                     {
                     {
-                        var arrayOffsets = property.Value.ArrayOffsets.Value;
-                        validate.IsNullOrIndex(nameof(propertyTable), arrayOffsets, modelRoot.LogicalBufferViews);
-                    }
+                        Guard.NotNull(Schema.Classes[propertyTable.Class].Properties[property.Key], nameof(property.Key), $"Schema must have property {property.Key}");
 
 
-                    if (property.Value.StringOffsets.HasValue)
-                    {
-                        var stringOffsets = property.Value.StringOffsets.Value;
-                        validate.IsNullOrIndex(nameof(propertyTable), stringOffsets, modelRoot.LogicalBufferViews);
+                        var values = property.Value.Values;
+                        validate.IsNullOrIndex(nameof(propertyTable), values, modelRoot.LogicalBufferViews);
+
+                        if (property.Value.ArrayOffsets.HasValue)
+                        {
+                            var arrayOffsets = property.Value.ArrayOffsets.Value;
+                            validate.IsNullOrIndex(nameof(propertyTable), arrayOffsets, modelRoot.LogicalBufferViews);
+                        }
+
+                        if (property.Value.StringOffsets.HasValue)
+                        {
+                            var stringOffsets = property.Value.StringOffsets.Value;
+                            validate.IsNullOrIndex(nameof(propertyTable), stringOffsets, modelRoot.LogicalBufferViews);
+                        }
                     }
                     }
                 }
                 }
-            }
 
 
-            if (Schema != null)
-            {
-                foreach (var @class in Schema.Classes)
+                if (Schema != null)
                 {
                 {
-                    foreach (var property in @class.Value.Properties)
+                    foreach (var @class in Schema.Classes)
                     {
                     {
-                        if (property.Value.Type == ElementType.ENUM)
+                        foreach (var property in @class.Value.Properties)
                         {
                         {
-                            Guard.IsTrue(Schema.Enums.ContainsKey(property.Value.EnumType), nameof(property.Value.EnumType), $"Enum {property.Value.EnumType} must be defined in schema");
+                            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);
-        }
+                base.OnValidateReferences(validate);
+            }
 
 
-        protected override void OnValidateContent(ValidationContext result)
-        {
-            // check schema id is defined and valid
-            if (Schema != null && !String.IsNullOrEmpty(Schema.Id))
+            protected override void OnValidateContent(ValidationContext result)
             {
             {
-                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)
+                // check schema id is defined and valid
+                if (Schema != null && !String.IsNullOrEmpty(Schema.Id))
                 {
                 {
-                    Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(_class.Key, regex), nameof(_class.Key));
+                    var regex = "^[a-zA-Z_][a-zA-Z0-9_]*$";
+                    Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(Schema.Id, regex), nameof(Schema.Id));
+
 
 
-                    foreach(var property in _class.Value.Properties)
+                    foreach (var _class in Schema.Classes)
                     {
                     {
-                        if (property.Value.Count.HasValue)
+                        Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(_class.Key, regex), nameof(_class.Key));
+
+                        foreach (var property in _class.Value.Properties)
                         {
                         {
-                            Guard.MustBeGreaterThanOrEqualTo(property.Value.Count.Value, 2, nameof(property.Value.Count));
+                            if (property.Value.Count.HasValue)
+                            {
+                                Guard.MustBeGreaterThanOrEqualTo(property.Value.Count.Value, 2, nameof(property.Value.Count));
+                            }
                         }
                         }
                     }
                     }
                 }
                 }
-            }
 
 
-            foreach (var propertyTexture in PropertyTextures)
-            {
-                foreach (var propertyTextureProperty in propertyTexture.Properties)
+                foreach (var propertyTexture in PropertyTextures)
                 {
                 {
-                    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 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.Class != null, nameof(propertyTable.Class), "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");
+                foreach (var propertyTable in PropertyTables)
+                {
+                    Guard.IsTrue(propertyTable.Class != null, nameof(propertyTable.Class), "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");
+                }
 
 
-            base.OnValidateContent(result);
-        }
+                // 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");
 
 
-        #endregion
-    }
+                base.OnValidateContent(result);
+            }
 
 
-    public partial class PropertyTexture : IChildOfList<EXTStructuralMetadataRoot>
-    {
-        #region lifecycle
-        public PropertyTexture()
-        {
-            _properties = new ChildrenDictionary<PropertyTextureProperty, PropertyTexture>(this);
+            #endregion
         }
         }
 
 
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+        public partial class PropertyTexture : IChildOfList<EXTStructuralMetadataRoot>
         {
         {
-            return base.GetLogicalChildren()
-                .Concat(_properties.Values);
-        }
+            #region lifecycle
+            public PropertyTexture()
+            {
+                _properties = new ChildrenDictionary<PropertyTextureProperty, PropertyTexture>(this);
+            }
 
 
-        #endregion
+            protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+            {
+                return base.GetLogicalChildren()
+                    .Concat(_properties.Values);
+            }
 
 
-        #region child properties
+            #endregion
 
 
-        public int LogicalIndex { get; private set; } = -1;
-        
-        public EXTStructuralMetadataRoot LogicalParent { get; private set; }
+            #region child properties
 
 
-        void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
-        {
-            LogicalParent = parent;
-            LogicalIndex = index;
-        }
+            public int LogicalIndex { get; private set; } = -1;
 
 
-        #endregion
+            public EXTStructuralMetadataRoot LogicalParent { get; private set; }
 
 
-        #region properties
+            void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
+            {
+                LogicalParent = parent;
+                LogicalIndex = index;
+            }
 
 
-        public string ClassName
-        {
-            get => _class;
-            set => _class = value;
-        }
+            #endregion
 
 
-        public IReadOnlyDictionary<string, PropertyTextureProperty> Properties => _properties;
+            #region properties
 
 
-        #endregion
-    }
+            public string ClassName
+            {
+                get => _class;
+                set => _class = value;
+            }
 
 
-    public partial class PropertyTextureProperty : IChildOfDictionary<PropertyTexture>
-    {
-        #region lifecycle
-        public PropertyTextureProperty()
-        {
-            _channels = new List<int>();
+            public IReadOnlyDictionary<string, PropertyTextureProperty> Properties => _properties;
+
+            #endregion
         }
         }
 
 
-        #endregion
+        public partial class PropertyTextureProperty : IChildOfDictionary<PropertyTexture>
+        {
+            #region lifecycle
+            public PropertyTextureProperty()
+            {
+                _channels = new List<int>();
+            }
 
 
-        #region child properties
+            #endregion
 
 
-        public string LogicalKey { get; private set; }
+            #region child properties
 
 
-        public PropertyTexture LogicalParent { get; private set; }
+            public string LogicalKey { get; private set; }
 
 
-        void IChildOfDictionary<PropertyTexture>.SetLogicalParent(PropertyTexture parent, string key)
-        {
-            LogicalParent = parent;
-            LogicalKey = key;
-        }
+            public PropertyTexture LogicalParent { get; private set; }
 
 
-        #endregion
+            void IChildOfDictionary<PropertyTexture>.SetLogicalParent(PropertyTexture parent, string key)
+            {
+                LogicalParent = parent;
+                LogicalKey = key;
+            }
 
 
-        #region data
+            #endregion
 
 
-        public List<int> Channels => _channels;
+            #region data
 
 
-        #endregion
-    }
+            public List<int> Channels => _channels;
 
 
-    public partial class PropertyAttribute : IChildOfList<EXTStructuralMetadataRoot>
-    {
-        #region lifecycle
-        public PropertyAttribute()
-        {
-            _properties = new ChildrenDictionary<PropertyAttributeProperty, PropertyAttribute>(this);
+            #endregion
         }
         }
 
 
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+        public partial class PropertyAttribute : IChildOfList<EXTStructuralMetadataRoot>
         {
         {
-            return base.GetLogicalChildren()
-                .Concat(_properties.Values);
-        }
+            #region lifecycle
+            public PropertyAttribute()
+            {
+                _properties = new ChildrenDictionary<PropertyAttributeProperty, PropertyAttribute>(this);
+            }
 
 
-        #endregion
+            protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+            {
+                return base.GetLogicalChildren()
+                    .Concat(_properties.Values);
+            }
 
 
-        #region child properties
+            #endregion
 
 
-        /// <summary>
-        /// Gets the zero-based index of this <see cref="MeshExtInstanceFeatureID"/> at <see cref="MeshExtInstanceFeatures.FeatureIds"/>.
-        /// </summary>
-        public int LogicalIndex { get; private set; } = -1;
+            #region child properties
 
 
-        /// <summary>
-        /// Gets the <see cref="MeshExtInstanceFeatures"/> instance that owns this <see cref="MeshExtInstanceFeatureID"/> instance.
-        /// </summary>
-        public EXTStructuralMetadataRoot LogicalParent { get; private set; }
+            /// <summary>
+            /// Gets the zero-based index of this <see cref="MeshExtInstanceFeatureID"/> at <see cref="MeshExtInstanceFeatures.FeatureIds"/>.
+            /// </summary>
+            public int LogicalIndex { get; private set; } = -1;
 
 
-        void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
-        {
-            LogicalParent = parent;
-            LogicalIndex = index;
-        }
+            /// <summary>
+            /// Gets the <see cref="MeshExtInstanceFeatures"/> instance that owns this <see cref="MeshExtInstanceFeatureID"/> instance.
+            /// </summary>
+            public EXTStructuralMetadataRoot LogicalParent { get; private set; }
 
 
-        #endregion
+            void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
+            {
+                LogicalParent = parent;
+                LogicalIndex = index;
+            }
 
 
-        #region properties
-        public string Class
-        {
-            get => _class;
-            set => _class = value;
-        }
+            #endregion
 
 
-        public IReadOnlyDictionary<string, PropertyAttributeProperty> Properties => _properties;
+            #region properties
+            public string Class
+            {
+                get => _class;
+                set => _class = value;
+            }
 
 
-        #endregion
+            public IReadOnlyDictionary<string, PropertyAttributeProperty> Properties => _properties;
 
 
-    }
+            #endregion
 
 
-    public partial class PropertyAttributeProperty : IChildOfDictionary<PropertyAttribute>
-    {
-        #region child properties
+        }
 
 
-        public string LogicalKey { get; private set; }
+        public partial class PropertyAttributeProperty : IChildOfDictionary<PropertyAttribute>
+        {
+            #region child properties
 
 
-        public PropertyAttribute LogicalParent { get; private set; }
+            public string LogicalKey { get; private set; }
 
 
-        void IChildOfDictionary<PropertyAttribute>.SetLogicalParent(PropertyAttribute parent, string key)
-        {
-            LogicalParent = parent;
-            LogicalKey = key;
-        }
+            public PropertyAttribute LogicalParent { get; private set; }
 
 
-        #endregion
+            void IChildOfDictionary<PropertyAttribute>.SetLogicalParent(PropertyAttribute parent, string key)
+            {
+                LogicalParent = parent;
+                LogicalKey = key;
+            }
 
 
-        #region properties
+            #endregion
 
 
-        public string Attribute
-        {
-            get => _attribute;
-            set => _attribute = value;
-        }
+            #region properties
 
 
-        #endregion
-    }
+            public string Attribute
+            {
+                get => _attribute;
+                set => _attribute = value;
+            }
 
 
-    public partial class StructuralMetadataSchema : IChildOfList<EXTStructuralMetadataRoot>
-    {
-        #region lifecycle
-        public StructuralMetadataSchema()
-        {
-            _classes = new ChildrenDictionary<StructuralMetadataClass, StructuralMetadataSchema>(this);
-            _enums = new ChildrenDictionary<StructuralMetadataEnum, StructuralMetadataSchema>(this);
+            #endregion
         }
         }
 
 
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+        public partial class StructuralMetadataSchema : IChildOfList<EXTStructuralMetadataRoot>
         {
         {
-            return base.GetLogicalChildren()
-                .Concat(_classes.Values)
-                .Concat(_enums.Values);
-        }
+            #region lifecycle
+            public StructuralMetadataSchema()
+            {
+                _classes = new ChildrenDictionary<StructuralMetadataClass, StructuralMetadataSchema>(this);
+                _enums = new ChildrenDictionary<StructuralMetadataEnum, StructuralMetadataSchema>(this);
+            }
 
 
-        #endregion
+            protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+            {
+                return base.GetLogicalChildren()
+                    .Concat(_classes.Values)
+                    .Concat(_enums.Values);
+            }
 
 
-        #region child properties
+            #endregion
 
 
-        public int LogicalIndex { get; private set; } = -1;
+            #region child properties
 
 
-        public EXTStructuralMetadataRoot LogicalParent { get; private set; }
+            public int LogicalIndex { get; private set; } = -1;
 
 
-        void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
-        {
-            LogicalParent = parent;
-            LogicalIndex = index;
-        }
+            public EXTStructuralMetadataRoot LogicalParent { get; private set; }
 
 
-        #endregion
+            void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
+            {
+                LogicalParent = parent;
+                LogicalIndex = index;
+            }
 
 
-        #region properties        
+            #endregion
 
 
-        public IReadOnlyDictionary<string, StructuralMetadataClass> Classes => _classes;
-        public IReadOnlyDictionary<string, StructuralMetadataEnum> Enums => _enums;
+            #region properties        
 
 
-        public string Id
-        {
-            get => _id;
-            set => _id = value;
-        }
+            public IReadOnlyDictionary<string, StructuralMetadataClass> Classes => _classes;
+            public IReadOnlyDictionary<string, StructuralMetadataEnum> Enums => _enums;
 
 
-        public string Version
-        {
-            get => _version;
-            set => _version = value;
-        }
+            public string Id
+            {
+                get => _id;
+                set => _id = value;
+            }
 
 
-        public string Name
-        {
-            get => _name;
-            set => _name = value;
-        }
+            public string Version
+            {
+                get => _version;
+                set => _version = value;
+            }
 
 
-        public string Description
-        {
-            get => _description;
-            set => _description = value;
-        }        
+            public string Name
+            {
+                get => _name;
+                set => _name = value;
+            }
 
 
-        #endregion
-    }
+            public string Description
+            {
+                get => _description;
+                set => _description = value;
+            }
 
 
-    public partial class StructuralMetadataEnum : IChildOfDictionary<StructuralMetadataSchema>
-    {
-        #region lifecycle
-        public StructuralMetadataEnum()
-        {
-            _values = new List<EnumValue>();
+            #endregion
         }
         }
 
 
-        #endregion
+        public partial class StructuralMetadataEnum : IChildOfDictionary<StructuralMetadataSchema>
+        {
+            #region lifecycle
+            public StructuralMetadataEnum()
+            {
+                _values = new List<EnumValue>();
+            }
 
 
-        #region child properties
+            #endregion
 
 
-        public string LogicalKey { get; private set; }
+            #region child properties
 
 
-        public StructuralMetadataSchema LogicalParent { get; private set; }
+            public string LogicalKey { get; private set; }
 
 
-        void IChildOfDictionary<StructuralMetadataSchema>.SetLogicalParent(StructuralMetadataSchema parent, string key)
-        {
-            LogicalParent = parent;
-            LogicalKey = key;
-        }
+            public StructuralMetadataSchema LogicalParent { get; private set; }
 
 
-        #endregion
+            void IChildOfDictionary<StructuralMetadataSchema>.SetLogicalParent(StructuralMetadataSchema parent, string key)
+            {
+                LogicalParent = parent;
+                LogicalKey = key;
+            }
 
 
-        #region properties
+            #endregion
 
 
-        public string Name
-        {
-            get => _name;
-            set => _name = value;
-        }
-        public string Description
-        {
-            get => _description;
-            set => _description = value;
-        }
-        public List<EnumValue> Values
-        {
-            get => _values;
-            set => _values = value;
-        }
+            #region properties
 
 
-        #endregion
-    }
+            public string Name
+            {
+                get => _name;
+                set => _name = value;
+            }
+            public string Description
+            {
+                get => _description;
+                set => _description = value;
+            }
+            public List<EnumValue> Values
+            {
+                get => _values;
+                set => _values = value;
+            }
 
 
-    public partial class EnumValue
-    {
-        public string Description
-        {
-            get => _description;
-            set => _description = value;
+            #endregion
         }
         }
-        public string Name
+
+        public partial class EnumValue
         {
         {
-            get => _name;
-            set => _name = value;
+            public string Description
+            {
+                get => _description;
+                set => _description = value;
+            }
+            public string Name
+            {
+                get => _name;
+                set => _name = value;
+            }
+            public int Value
+            {
+                get => _value;
+                set => _value = value;
+            }
         }
         }
-        public int Value
+
+        public partial class StructuralMetadataClass : IChildOfDictionary<StructuralMetadataSchema>
         {
         {
-            get => _value;
-            set => _value = value;
-        }
-    }
+            #region lifecycle
 
 
-    public partial class StructuralMetadataClass : IChildOfDictionary<StructuralMetadataSchema>
-    {
-        #region lifecycle
+            public StructuralMetadataClass()
+            {
+                _properties = new ChildrenDictionary<ClassProperty, StructuralMetadataClass>(this);
+            }
 
 
-        public StructuralMetadataClass()
-        {
-            _properties = new ChildrenDictionary<ClassProperty, StructuralMetadataClass>(this);
-        }
+            protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+            {
+                return base.GetLogicalChildren()
+                    .Concat(_properties.Values);
+            }
 
 
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
-        {
-            return base.GetLogicalChildren()
-                .Concat(_properties.Values);
-        }
+            #endregion
 
 
-        #endregion
+            #region child properties
 
 
-        #region child properties
+            public string LogicalKey { get; private set; }
 
 
-        public string LogicalKey { get; private set; }
+            public StructuralMetadataSchema LogicalParent { get; private set; }
 
 
-        public StructuralMetadataSchema LogicalParent { get; private set; }
+            void IChildOfDictionary<StructuralMetadataSchema>.SetLogicalParent(StructuralMetadataSchema parent, string key)
+            {
+                LogicalParent = parent;
+                LogicalKey = key;
+            }
 
 
-        void IChildOfDictionary<StructuralMetadataSchema>.SetLogicalParent(StructuralMetadataSchema parent, string key)
-        {
-            LogicalParent = parent;
-            LogicalKey = key;
-        }
+            #endregion
 
 
-        #endregion
+            #region properties
 
 
-        #region properties
+            public IReadOnlyDictionary<string, ClassProperty> Properties => _properties;
 
 
-        public IReadOnlyDictionary<string, ClassProperty> Properties => _properties;
+            public string Name
+            {
+                get => _name;
+                set => _name = value;
+            }
 
 
-        public string Name
-        {
-            get => _name;
-            set => _name = value;
-        }
+            public string Description
+            {
+                get => _description;
+                set => _description = value;
+            }
+
+            #endregion
 
 
-        public string Description
-        {
-            get => _description;
-            set => _description = value;
         }
         }
 
 
-        #endregion
+        public partial class ClassProperty : IChildOfDictionary<StructuralMetadataClass>
+        {
+            #region child properties
 
 
-    }
+            public string LogicalKey { get; private set; }
 
 
-    public partial class ClassProperty : IChildOfDictionary<StructuralMetadataClass>
-    {
-        #region child properties
+            public StructuralMetadataClass LogicalParent { get; private set; }
 
 
-        public string LogicalKey { get; private set; }
+            void IChildOfDictionary<StructuralMetadataClass>.SetLogicalParent(StructuralMetadataClass parent, string key)
+            {
+                LogicalParent = parent;
+                LogicalKey = key;
+            }
 
 
-        public StructuralMetadataClass LogicalParent { get; private set; }
+            #endregion
 
 
-        void IChildOfDictionary<StructuralMetadataClass>.SetLogicalParent(StructuralMetadataClass parent, string key)
-        {
-            LogicalParent = parent;
-            LogicalKey = key;
-        }
+            #region properties
+            public string Name
+            {
+                get => _name;
+                set => _name = value;
+            }
 
 
-        #endregion
+            public string Description
+            {
+                get => _description;
+                set => _description = value;
+            }
 
 
-        #region properties
-        public string Name
-        {
-            get => _name;
-            set => _name = value;
-        }
+            public ElementType Type
+            {
+                get => _type;
+                set => _type = value;
+            }
 
 
-        public string Description
-        {
-            get => _description;
-            set => _description = value;
-        }
+            public string EnumType
+            {
+                get => _enumType;
+                set => _enumType = value;
+            }
 
 
-        public ElementType Type
-        {
-            get => _type;
-            set => _type = value;
-        }
+            public DataType? ComponentType
+            {
+                get => _componentType;
+                set => _componentType = value;
+            }
 
 
-        public string EnumType
-        {
-            get => _enumType;
-            set => _enumType = value;
-        }
+            public bool? Required
+            {
+                get => _required;
+                set => _required = value;
+            }
 
 
-        public DataType? ComponentType
-        {
-            get => _componentType;
-            set => _componentType = value;
-        }
+            public bool? Normalized
+            {
+                get => _normalized;
+                set => _normalized = value;
+            }
 
 
-        public bool? Required
-        {
-            get => _required;
-            set => _required = value;
-        }
+            public bool? Array
+            {
+                get => _array;
+                set => _array = value;
+            }
 
 
-        public bool? Normalized
-        {
-            get => _normalized;
-            set => _normalized = value;
-        }
+            public int? Count
+            {
+                get => _count;
+                set => _count = value;
+            }
 
 
-        public bool? Array
-        {
-            get => _array;
-            set => _array = value;
+            #endregion
         }
         }
 
 
-        public int? Count
+        /// <remarks>
+        /// Represents a Propery table of <see cref="EXTStructuralMetadataRoot"/>
+        /// </remarks> 
+        public partial class PropertyTable : IChildOfList<EXTStructuralMetadataRoot>
         {
         {
-            get => _count;
-            set => _count = value;
-        }
+            #region lifecycle
+            public PropertyTable()
+            {
+                _properties = new ChildrenDictionary<PropertyTableProperty, PropertyTable>(this);
+            }
+            public PropertyTable(string Class, int Count, string Name = "") : this()
+            {
+                _class = Class;
+                _count = Count;
+                _name = Name;
+            }
 
 
-        #endregion
-    }
+            protected override IEnumerable<ExtraProperties> GetLogicalChildren()
+            {
+                return base.GetLogicalChildren()
+                    .Concat(_properties.Values);
+            }
 
 
-    /// <remarks>
-    /// Represents a Propery table of <see cref="EXTStructuralMetadataRoot"/>
-    /// </remarks> 
-    public partial class PropertyTable : IChildOfList<EXTStructuralMetadataRoot>
-    {
-        #region lifecycle
-        public PropertyTable()
-        {
-            _properties = new ChildrenDictionary<PropertyTableProperty, PropertyTable>(this);
-        }
-        public PropertyTable(string Class, int Count, string Name = "") : this()
-        {
-            _class = Class;
-            _count = Count;
-            _name = Name;
-        }
+            #endregion
 
 
-        protected override IEnumerable<ExtraProperties> GetLogicalChildren()
-        {
-            return base.GetLogicalChildren()
-                .Concat(_properties.Values);
-        }
+            #region child properties
 
 
-        #endregion
+            public int LogicalIndex { get; private set; } = -1;
+            public EXTStructuralMetadataRoot LogicalParent { get; private set; }
 
 
-        #region child properties
+            void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
+            {
+                LogicalParent = parent;
+                LogicalIndex = index;
+            }
 
 
-        public int LogicalIndex { get; private set; } = -1;        
-        public EXTStructuralMetadataRoot LogicalParent { get; private set; }
+            #endregion
 
 
-        void IChildOfList<EXTStructuralMetadataRoot>.SetLogicalParent(EXTStructuralMetadataRoot parent, int index)
-        {
-            LogicalParent = parent;
-            LogicalIndex = index;
-        }
+            #region properties
 
 
-        #endregion
+            public IReadOnlyDictionary<string, PropertyTableProperty> Properties => _properties;
 
 
-        #region properties
+            public string Name
+            {
+                get => _name;
+                set => _name = value;
+            }
 
 
-        public IReadOnlyDictionary<string, PropertyTableProperty> Properties => _properties;
+            public string Class
+            {
+                get => _class;
+                set => _class = value;
+            }
 
 
-        public string Name
-        {
-            get => _name;
-            set => _name = value;
-        }
+            public int Count
+            {
+                get => _count;
+                set => _count = value;
+            }
 
 
-        public string Class
-        {
-            get => _class;
-            set => _class = value;
+            #endregion
         }
         }
 
 
-        public int Count
+        /// <remarks>
+        /// Represents a Property of <see cref="PropertyTable"/>
+        /// </remarks>    
+        public partial class PropertyTableProperty : IChildOfDictionary<PropertyTable>
         {
         {
-            get => _count;
-            set => _count = value;
-        }        
+            #region child properties
 
 
-        #endregion
-    }
+            public string LogicalKey { get; private set; }
 
 
-    /// <remarks>
-    /// Represents a Property of <see cref="PropertyTable"/>
-    /// </remarks>    
-    public partial class PropertyTableProperty : IChildOfDictionary<PropertyTable>
-    {
-        #region child properties
+            public PropertyTable LogicalParent { get; private set; }
 
 
-        public string LogicalKey { get; private set; }
-
-        public PropertyTable LogicalParent { get; private set; }
+            void IChildOfDictionary<PropertyTable>.SetLogicalParent(PropertyTable parent, string key)
+            {
+                LogicalParent = parent;
+                LogicalKey = key;
+            }
 
 
-        void IChildOfDictionary<PropertyTable>.SetLogicalParent(PropertyTable parent, string key)
-        {
-            LogicalParent = parent;
-            LogicalKey = key;
-        }
+            #endregion
 
 
-        #endregion
+            #region properties
+            /// <summary>
+            /// this is an index to a BufferView
+            /// </summary>
+            public int Values
+            {
+                get => _values;
+                set => _values = value;
+            }
 
 
-        #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? ArrayOffsets
-        {
-            get => _arrayOffsets;
-            set => _arrayOffsets = value;
-        }
+            public int? StringOffsets
+            {
+                get => _stringOffsets;
+                set => _stringOffsets = value;
+            }
 
 
-        public int? StringOffsets
-        {
-            get => _stringOffsets;
-            set => _stringOffsets = value;
+            #endregion
         }
         }
-
-        #endregion
     }
     }
 }
 }
 
 

+ 3 - 1
src/SharpGLTF.Ext.3DTiles/Schema2/Tiles3DExtensions.cs

@@ -1,5 +1,7 @@
-namespace SharpGLTF.Schema2.Tiles3D
+namespace SharpGLTF.Schema2
 {
 {
+    using Tiles3D;
+
     /// <summary>
     /// <summary>
     /// Extension methods for 3DTiles glTF Extensions
     /// Extension methods for 3DTiles glTF Extensions
     /// </summary>
     /// </summary>

+ 2 - 0
src/SharpGLTF.Ext.Agi/schema2/AgiExtensions.cs

@@ -4,6 +4,8 @@ using System.Text;
 
 
 namespace SharpGLTF.Schema2
 namespace SharpGLTF.Schema2
 {
 {
+    using AGI;
+
     /// <summary>
     /// <summary>
     /// Extension methods for AGI glTF Extensions
     /// Extension methods for AGI glTF Extensions
     /// </summary>
     /// </summary>

+ 1 - 1
src/SharpGLTF.Ext.Agi/schema2/agi.Articulations.cs

@@ -5,7 +5,7 @@ using System.Numerics;
 using System.Linq;
 using System.Linq;
 using SharpGLTF.Collections;
 using SharpGLTF.Collections;
 
 
-namespace SharpGLTF.Schema2
+namespace SharpGLTF.Schema2.AGI
 {    
 {    
     public sealed partial class AgiRootArticulations
     public sealed partial class AgiRootArticulations
     {
     {

+ 1 - 1
src/SharpGLTF.Ext.Agi/schema2/agi.StkMetadata.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using SharpGLTF.Collections;
 using SharpGLTF.Collections;
 
 
-namespace SharpGLTF.Schema2
+namespace SharpGLTF.Schema2.AGI
 {
 {
     public sealed partial class AgiRootStkMetadata
     public sealed partial class AgiRootStkMetadata
     {
     {

+ 1 - 1
src/SharpGLTF.Ext.Agi/schema2/generated/ext.AgiNodeArticulations.g.cs

@@ -23,7 +23,7 @@ using System.Text;
 using System.Numerics;
 using System.Numerics;
 using System.Text.Json;
 using System.Text.Json;
 
 
-namespace SharpGLTF.Schema2
+namespace SharpGLTF.Schema2.AGI
 {
 {
 	using Collections;
 	using Collections;
 
 

+ 1 - 1
src/SharpGLTF.Ext.Agi/schema2/generated/ext.AgiNodeStkMetadata.g.cs

@@ -23,7 +23,7 @@ using System.Text;
 using System.Numerics;
 using System.Numerics;
 using System.Text.Json;
 using System.Text.Json;
 
 
-namespace SharpGLTF.Schema2
+namespace SharpGLTF.Schema2.AGI
 {
 {
 	using Collections;
 	using Collections;
 
 

+ 1 - 1
src/SharpGLTF.Ext.Agi/schema2/generated/ext.AgiRootArticulations.g.cs

@@ -23,7 +23,7 @@ using System.Text;
 using System.Numerics;
 using System.Numerics;
 using System.Text.Json;
 using System.Text.Json;
 
 
-namespace SharpGLTF.Schema2
+namespace SharpGLTF.Schema2.AGI
 {
 {
 	using Collections;
 	using Collections;
 
 

+ 1 - 1
src/SharpGLTF.Ext.Agi/schema2/generated/ext.AgiRootStkMetadata.g.cs

@@ -23,7 +23,7 @@ using System.Text;
 using System.Numerics;
 using System.Numerics;
 using System.Text.Json;
 using System.Text.Json;
 
 
-namespace SharpGLTF.Schema2
+namespace SharpGLTF.Schema2.AGI
 {
 {
 	using Collections;
 	using Collections;