Browse Source

starting with complextypes test

Bert Temme 2 years ago
parent
commit
84c7a40f32

+ 36 - 1
src/SharpGLTF.Cesium/Schema2/EXTStructuralMetaDataRoot.cs

@@ -2,7 +2,6 @@
 using SharpGLTF.Validation;
 using SharpGLTF.Validation;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Linq;
 
 
 namespace SharpGLTF.Schema2
 namespace SharpGLTF.Schema2
 {
 {
@@ -51,11 +50,37 @@ namespace SharpGLTF.Schema2
         {
         {
             if (propertyTables == null || propertyTables.Count == 0) { modelRoot.RemoveExtensions<EXTStructuralMetaDataRoot>(); return; }
             if (propertyTables == null || propertyTables.Count == 0) { modelRoot.RemoveExtensions<EXTStructuralMetaDataRoot>(); return; }
 
 
+            // todo add check if propertyTable.Class is in schema.Classes
+            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");
+
+                schema.Switch(
+                    StructuralMetadataSchema =>
+                        CheckConsistency(StructuralMetadataSchema, propertyTable),
+                    Uri =>
+                    {
+                        // do not check here, because schema is not loaded
+                    }
+                    );
+            }
+
             var ext = modelRoot.UseExtension<EXTStructuralMetaDataRoot>();
             var ext = modelRoot.UseExtension<EXTStructuralMetaDataRoot>();
             ext.PropertyTables = propertyTables;
             ext.PropertyTables = propertyTables;
             ext.AddSchema(schema);
             ext.AddSchema(schema);
         }
         }
 
 
+        private static void CheckConsistency(StructuralMetadataSchema StructuralMetadataSchema, PropertyTable propertyTable)
+        {
+            Guard.IsTrue(StructuralMetadataSchema.Classes.ContainsKey(propertyTable.Class), nameof(propertyTable.Class), $"Class {propertyTable.Class} must be defined in schema");
+            foreach (var property in propertyTable.Properties)
+            {
+                Guard.IsTrue(StructuralMetadataSchema.Classes[propertyTable.Class].Properties.ContainsKey(property.Key), nameof(propertyTable.Properties), $"Property {property.Key} must be defined in schema");
+            }
+        }
+
         public static PropertyTableProperty GetPropertyTableProperty<T>(this ModelRoot model, IReadOnlyList<T> values)
         public static PropertyTableProperty GetPropertyTableProperty<T>(this ModelRoot model, IReadOnlyList<T> values)
         {
         {
             var propertyTableProperty = new PropertyTableProperty();
             var propertyTableProperty = new PropertyTableProperty();
@@ -346,6 +371,16 @@ namespace SharpGLTF.Schema2
             get { return _normalized; }
             get { return _normalized; }
             set { _normalized = value; }
             set { _normalized = value; }
         }
         }
+
+        // add array property
+        public bool? Array
+        {
+            get { return _array; }
+            set { _array = value; }
+
+        }
+
+
     }
     }
 
 
     public partial class PropertyTable
     public partial class PropertyTable

+ 6 - 3
src/SharpGLTF.Cesium/Schema2/MeshExtMeshFeatures.cs

@@ -102,6 +102,11 @@ namespace SharpGLTF.Schema2
 
 
     public static class ExtMeshFeatures
     public static class ExtMeshFeatures
     {
     {
+        public static void SetFeatureId(this MeshPrimitive primitive, MeshExtMeshFeatureID featureId)
+        {
+            primitive.SetFeatureIds(new List<MeshExtMeshFeatureID>() { featureId });
+        }
+
         /// <summary>
         /// <summary>
         /// Set the FeatureIds for a MeshPrimitive
         /// Set the FeatureIds for a MeshPrimitive
         /// </summary>
         /// </summary>
@@ -109,9 +114,7 @@ namespace SharpGLTF.Schema2
         /// <param name="featureIds"></param>
         /// <param name="featureIds"></param>
         public static void SetFeatureIds(this MeshPrimitive primitive, List<MeshExtMeshFeatureID> featureIds)
         public static void SetFeatureIds(this MeshPrimitive primitive, List<MeshExtMeshFeatureID> featureIds)
         {
         {
-            if (featureIds == null) { primitive.RemoveExtensions<MeshExtMeshFeatures>(); return; }
-
-            Guard.NotNullOrEmpty(featureIds, nameof(featureIds));
+            if (featureIds == null || featureIds.Count == 0) { primitive.RemoveExtensions<MeshExtMeshFeatures>(); return; }
 
 
             foreach (var featureId in featureIds)
             foreach (var featureId in featureIds)
             {
             {

+ 58 - 0
tests/SharpGLTF.Cesium.Tests/ExtStructuralMetadataTests.cs

@@ -20,6 +20,64 @@ namespace SharpGLTF.Cesium
             CesiumExtensions.RegisterExtensions();
             CesiumExtensions.RegisterExtensions();
         }
         }
 
 
+        [Test(Description = "ext_structural_metadata with complex types")]
+        // sample see https://github.com/CesiumGS/3d-tiles-samples/blob/main/glTF/EXT_structural_metadata/ComplexTypes/ComplexTypes.gltf
+        public void ComplexTypesTest()
+        {
+            TestContext.CurrentContext.AttachGltfValidatorLinks();
+            var material = MaterialBuilder.CreateDefault().WithDoubleSide(true);
+            var mesh = new MeshBuilder<VertexPosition, VertexWithFeatureId, VertexEmpty>("mesh");
+            var prim = mesh.UsePrimitive(material);
+
+            // All the vertices in the triangle have the same feature ID
+            var vt0 = VertexBuilder.GetVertexWithFeatureId(new Vector3(-10, 0, 0), new Vector3(0, 0, 1), 0);
+            var vt1 = VertexBuilder.GetVertexWithFeatureId(new Vector3(10, 0, 0), new Vector3(0, 0, 1), 0);
+            var vt2 = VertexBuilder.GetVertexWithFeatureId(new Vector3(0, 10, 0), new Vector3(0, 0, 1), 0);
+
+            prim.AddTriangle(vt0, vt1, vt2);
+
+            var scene = new SceneBuilder();
+            scene.AddRigidMesh(mesh, Matrix4x4.Identity);
+
+            var model = scene.ToGltf2();
+
+            var featureId = new MeshExtMeshFeatureID(1, 0, 0);
+            model.LogicalMeshes[0].Primitives[0].SetFeatureId(featureId);
+
+            var schema = new StructuralMetadataSchema();
+
+            var exampleMetadataClass = new StructuralMetadataClass();
+            exampleMetadataClass.Name = "Example metadata class A";
+            exampleMetadataClass.Description = "First example metadata class";
+
+            var uint8ArrayProperty = new ClassProperty();
+            uint8ArrayProperty.Name = "Example variable-length ARRAY normalized INT8 property";
+            uint8ArrayProperty.Description = "An example property, with type ARRAY, with component type UINT8, normalized, and variable length";
+            uint8ArrayProperty.Type = ElementType.SCALAR;
+            uint8ArrayProperty.ComponentType = DataType.UINT8;
+            uint8ArrayProperty.Normalized = true;
+            uint8ArrayProperty.Array = true;
+
+            exampleMetadataClass.Properties.Add("example_variable_length_ARRAY_normalized_UINT8", uint8ArrayProperty);
+
+            schema.Classes.Add("exampleMetadataClass", exampleMetadataClass);
+
+            var examplePropertyTable = new PropertyTable("exampleMetadataClass", 1, "Example property table");
+            // todo add the complex type properties
+            var float32Property = model.GetPropertyTableProperty(new List<float>() { 100 });
+            examplePropertyTable.Properties.Add("example_variable_length_ARRAY_normalized_UINT8", float32Property);
+
+            model.SetPropertyTable(examplePropertyTable, schema);
+
+            // create files
+            var ctx = new ValidationResult(model, ValidationMode.Strict, true);
+            model.AttachToCurrentTest("cesium_ext_structural_metadata_complex_types.glb");
+            model.AttachToCurrentTest("cesium_ext_structural_metadata_complex_types.gltf");
+            model.AttachToCurrentTest("cesium_ext_structural_metadata_complex_types.plotly");
+        }
+
+
+
         [Test(Description = "ext_structural_metadata with multiple classes")]
         [Test(Description = "ext_structural_metadata with multiple classes")]
         // Sample see https://github.com/CesiumGS/3d-tiles-samples/blob/main/glTF/EXT_structural_metadata/MultipleClasses/MultipleClasses.gltf
         // Sample see https://github.com/CesiumGS/3d-tiles-samples/blob/main/glTF/EXT_structural_metadata/MultipleClasses/MultipleClasses.gltf
         public void MultipleClassesTest()
         public void MultipleClassesTest()