Jelajahi Sumber

add more validations for EXT_Mesh_Features

Bert Temme 2 tahun lalu
induk
melakukan
523bb831e4

+ 72 - 20
src/SharpGLTF.Cesium/Schema2/MeshExtMeshFeatures.cs

@@ -1,5 +1,5 @@
 using SharpGLTF.Validation;
-using System;
+using System.Text;
 using System.Collections.Generic;
 using System.Linq;
 
@@ -15,17 +15,12 @@ namespace SharpGLTF.Schema2
             _featureIds = new List<MeshExtMeshFeatureID>();
         }
 
-
         public List<MeshExtMeshFeatureID> FeatureIds
         {
-            get
-            {
-                return _featureIds;
-            }
+            get => _featureIds;
             set
             {
                 if (value == null) { _featureIds = null; return; }
-
                 _featureIds = value;
             }
         }
@@ -63,13 +58,37 @@ namespace SharpGLTF.Schema2
             _texture = texture;
         }
 
-        public int? Attribute
-        {
-            get
-            {
-                return _attribute;
-            }
-        }
+        /// <summary>
+        /// The number of unique features in the attribute or texture.
+        /// </summary>
+        public int? FeatureCount { get => _featureCount; }
+
+        /// <summary>
+        /// A value that indicates that no feature is associated with this vertex or texel.
+        /// </summary>
+        public int? NullFeatureId { get => _nullFeatureId; }
+
+        /// <summary>
+        /// An attribute containing feature IDs. When `attribute` and `texture` are omitted the 
+        /// feature IDs are assigned to vertices by their index.
+        /// </summary>
+        public int? Attribute { get => _attribute; }
+
+        /// <summary>
+        /// A label assigned to this feature ID set. Labels must be alphanumeric identifiers 
+        /// matching the regular expression `^[a-zA-Z_][a-zA-Z0-9_]*$`.
+        /// </summary>
+        public string Label { get => _label; }
+
+        /// <summary>
+        /// A texture containing feature IDs.
+        /// </summary>
+        public MeshExtMeshFeatureIDTexture Texture { get => _texture; }
+
+        /// <summary>
+        /// The index of the property table containing per-feature property values. Only applicable when using the `EXT_structural_metadata` extension.
+        /// </summary>
+        public int? PropertyTable { get => _propertyTable; }
     }
 
     public static class ExtMeshFeatures
@@ -78,17 +97,50 @@ namespace SharpGLTF.Schema2
         {
             if (list == null) { primitive.RemoveExtensions<MeshExtMeshFeatures>(); return; }
 
-            // Guard that the custom vertex attribute (_FEATURE_ID_{attribute}) exists when FeatureID has attribute set
-            foreach (var item in list) {
-                if (item.Attribute.HasValue) {
-                    var expectedVertexAttribute = $"_FEATURE_ID_{item.Attribute}";
-                    Guard.NotNull(primitive.GetVertexAccessor(expectedVertexAttribute), expectedVertexAttribute);
-                }
+            Guard.NotNullOrEmpty(list, nameof(list));
+
+            foreach (var item in list)
+            {
+                ValidateFeature(primitive, item);
             };
 
             var ext = primitive.UseExtension<MeshExtMeshFeatures>();
             ext.FeatureIds = list;
         }
+
+        private static void ValidateFeature(MeshPrimitive primitive, MeshExtMeshFeatureID item)
+        {
+            if (item.FeatureCount.HasValue)
+            {
+                Guard.MustBeGreaterThanOrEqualTo((int)item.FeatureCount, 1, nameof(item.FeatureCount));
+            }
+            if (item.NullFeatureId.HasValue)
+            {
+                Guard.MustBeGreaterThanOrEqualTo((int)item.NullFeatureId, 0, nameof(item.NullFeatureId));
+            }
+            if (item.Label != null)
+            {
+                var regex = "^[a-zA-Z_][a-zA-Z0-9_]*$";
+                Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(item.Label, regex), nameof(item.Label));
+            }
+            if (item.Attribute.HasValue)
+            {
+                Guard.MustBeGreaterThanOrEqualTo((int)item.Attribute, 0, nameof(item.Attribute));
+                // Guard that the custom vertex attribute (_FEATURE_ID_{attribute}) exists when FeatureID has attribute set
+                var expectedVertexAttribute = $"_FEATURE_ID_{item.Attribute}";
+                Guard.NotNull(primitive.GetVertexAccessor(expectedVertexAttribute), expectedVertexAttribute);
+            }
+            if (item.Texture != null)
+            {
+                // todo check the texture
+            }
+            if (item.PropertyTable.HasValue)
+            {
+                // The index of the property table containing per-feature property values.
+                // Only applicable when using the `EXT_structural_metadata` extension.
+                Guard.MustBeGreaterThanOrEqualTo((int)item.PropertyTable, 0, nameof(item.PropertyTable));
+            }
+        }
     }
 
 }

+ 1 - 1
tests/SharpGLTF.Cesium.Tests/ExtMeshFeaturesTests.cs

@@ -45,7 +45,7 @@ namespace SharpGLTF.Cesium
             // See sample https://github.com/CesiumGS/glTF/tree/proposal-EXT_mesh_features/extensions/2.0/Vendor/EXT_mesh_features#feature-id-by-vertex
 
             // Method 1: Feature ID by attribute
-            var featureIdAttribute = new MeshExtMeshFeatureID(2, 0);
+            var featureIdAttribute = new MeshExtMeshFeatureID(2, 0, label: "my_label");
 
             // Method 2: Feature ID by Texture coordinates
             var texture = new MeshExtMeshFeatureIDTexture(new List<int>() { 0 }, 0, 0);