Browse Source

Simplified CesiumPrimitiveOutline API from PR #175

Vicente Penades 2 years ago
parent
commit
70ee77bad6

+ 1 - 1
build/SharpGLTF.CodeGen/Ext.CESIUM_primitive_outline.cs

@@ -10,7 +10,7 @@ namespace SharpGLTF
 
         public override void PrepareTypes(CSharpEmitter newEmitter, SchemaType.Context ctx)
         {
-            newEmitter.SetRuntimeName("Ext.CESIUM_primitive_outline glTF extension", "CesiumPrimitiveOutline");
+            newEmitter.SetRuntimeName("CESIUM_primitive_outline glTF primitive extension", "CesiumPrimitiveOutline");
         }
 
         public override IEnumerable<(string TargetFileName, SchemaType.Context Schema)> Process()

+ 56 - 56
src/SharpGLTF.Core/Schema2/Generated/Ext.CESIUM_primitive_outline.g.cs

@@ -1,56 +1,56 @@
-// <auto-generated/>
-
-//------------------------------------------------------------------------------------------------
-//      This file has been programatically generated; DON´T EDIT!
-//------------------------------------------------------------------------------------------------
-
-#pragma warning disable SA1001
-#pragma warning disable SA1027
-#pragma warning disable SA1028
-#pragma warning disable SA1121
-#pragma warning disable SA1205
-#pragma warning disable SA1309
-#pragma warning disable SA1402
-#pragma warning disable SA1505
-#pragma warning disable SA1507
-#pragma warning disable SA1508
-#pragma warning disable SA1652
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Numerics;
-using System.Text.Json;
-
-namespace SharpGLTF.Schema2
-{
-	using Collections;
-
-	/// <summary>
-	/// glTF extension for indicating that some edges of a primitive's triangles should be outlined.
-	/// </summary>
-	partial class CESIUM_primitive_outlineglTFprimitiveextension : ExtraProperties
-	{
-	
-		private Int32? _indices;
-		
-	
-		protected override void SerializeProperties(Utf8JsonWriter writer)
-		{
-			base.SerializeProperties(writer);
-			SerializeProperty(writer, "indices", _indices);
-		}
-	
-		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
-		{
-			switch (jsonPropertyName)
-			{
-				case "indices": _indices = DeserializePropertyValue<Int32?>(ref reader); break;
-				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
-			}
-		}
-	
-	}
-
-}
+// <auto-generated/>
+
+//------------------------------------------------------------------------------------------------
+//      This file has been programatically generated; DON´T EDIT!
+//------------------------------------------------------------------------------------------------
+
+#pragma warning disable SA1001
+#pragma warning disable SA1027
+#pragma warning disable SA1028
+#pragma warning disable SA1121
+#pragma warning disable SA1205
+#pragma warning disable SA1309
+#pragma warning disable SA1402
+#pragma warning disable SA1505
+#pragma warning disable SA1507
+#pragma warning disable SA1508
+#pragma warning disable SA1652
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Numerics;
+using System.Text.Json;
+
+namespace SharpGLTF.Schema2
+{
+	using Collections;
+
+	/// <summary>
+	/// glTF extension for indicating that some edges of a primitive's triangles should be outlined.
+	/// </summary>
+	partial class CesiumPrimitiveOutline : ExtraProperties
+	{
+	
+		private Int32? _indices;
+		
+	
+		protected override void SerializeProperties(Utf8JsonWriter writer)
+		{
+			base.SerializeProperties(writer);
+			SerializeProperty(writer, "indices", _indices);
+		}
+	
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
+		{
+			switch (jsonPropertyName)
+			{
+				case "indices": _indices = DeserializePropertyValue<Int32?>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
+			}
+		}
+	
+	}
+
+}

+ 1 - 1
src/SharpGLTF.Core/Schema2/gltf.ExtensionsFactory.cs

@@ -50,7 +50,7 @@ namespace SharpGLTF.Schema2
             RegisterExtension<Node, AgiNodeArticulations>("AGI_articulations");
             RegisterExtension<Node, AgiNodeStkMetadata>("AGI_stk_metadata");
 
-            RegisterExtension<MeshPrimitive, CESIUM_primitive_outlineglTFprimitiveextension>("CESIUM_primitive_outline");
+            RegisterExtension<MeshPrimitive, CesiumPrimitiveOutline>("CESIUM_primitive_outline");
         }
 
         #endregion

+ 124 - 98
src/SharpGLTF.Core/Schema2/gltf.MeshPrimitive.CESIUM_primitive_outline.cs

@@ -1,98 +1,124 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace SharpGLTF.Schema2
-{
-    partial class CESIUM_primitive_outlineglTFprimitiveextension
-    {
-        private MeshPrimitive meshPrimitive;
-        internal CESIUM_primitive_outlineglTFprimitiveextension(MeshPrimitive meshPrimitive)
-        {
-            this.meshPrimitive = meshPrimitive;
-        }
-
-        public int? Indices
-        {
-            get => _indices;
-            set => _indices = value;
-        }
-
-        protected override void OnValidateContent(Validation.ValidationContext validate)
-        {
-            var outlineAccessor = meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors[(int)_indices];
-            var isValid = CesiumToolkit.ValidateCesiumOutlineIndices(outlineAccessor, meshPrimitive);
-            validate.IsTrue(nameof(_indices), isValid, "Mismatch between accesor indices and MeshPrimitive indices");
-
-            base.OnValidateContent(validate);
-        }
-    }
-
-    partial class MeshPrimitive
-    {
-        public void SetCesiumOutline(Accessor accessor)
-        {
-            if (accessor == null) { RemoveExtensions<CESIUM_primitive_outlineglTFprimitiveextension>(); return; }
-
-            Guard.NotNull(accessor, nameof(accessor));
-            Guard.MustShareLogicalParent(LogicalParent.LogicalParent, "this", accessor, nameof(accessor));
-            Guard.IsTrue(accessor.Encoding == EncodingType.UNSIGNED_INT, nameof(accessor));
-            Guard.IsTrue(accessor.Dimensions == DimensionType.SCALAR, nameof(accessor));
-
-            var ext = UseExtension<CESIUM_primitive_outlineglTFprimitiveextension>();
-            ext.Indices = accessor.LogicalIndex;
-        }
-    }
-
-    public static class CesiumToolkit
-    {
-        /// <summary>
-        /// Creates an accessor to store Cesium outline vertex indices
-        /// </summary>
-        /// <param name="model"></param>
-        /// <param name="outlines"></param>
-        /// <returns></returns>
-        public static Accessor CreateCesiumOutlineAccessor(ModelRoot model, IReadOnlyList<uint> outlines, string name="Cesium outlines")
-        {
-            var outlineBytes = new List<byte>();
-
-            foreach (var bytes in from outline in outlines
-                                  let bytes = BitConverter.GetBytes(outline).ToList()
-                                  select bytes)
-            {
-                outlineBytes.AddRange(bytes);
-            }
-
-            var buffer = model.UseBufferView(outlineBytes.ToArray());
-            var accessor = model.CreateAccessor(name);
-            accessor.SetData(buffer, 0, outlineBytes.Count / 4, DimensionType.SCALAR, EncodingType.UNSIGNED_INT, false);
-            return 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>
-        internal static bool ValidateCesiumOutlineIndices(Accessor accessor, MeshPrimitive meshPrimitive)
-        {
-            var cesiumOutlineExtension = meshPrimitive.GetExtension<CESIUM_primitive_outlineglTFprimitiveextension>();
-            if (cesiumOutlineExtension != null)
-            {
-                var accessorIndices = accessor.AsIndicesArray();
-                var meshPrimitiveIndices = meshPrimitive.GetIndices();
-                var maxIndice = meshPrimitiveIndices.Max();
-
-                foreach (var _ in from accessorIndice in accessorIndices
-                                  let contains = accessorIndice <= maxIndice
-                                  where !contains
-                                  select new { })
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using SharpGLTF.Validation;
+
+namespace SharpGLTF.Schema2
+{
+    partial class CesiumPrimitiveOutline
+    {
+        private MeshPrimitive meshPrimitive;
+        internal CesiumPrimitiveOutline(MeshPrimitive meshPrimitive)
+        {
+            this.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;
+            }
+        }
+
+        protected override void OnValidateReferences(ValidationContext validate)
+        {
+            validate.IsNullOrIndex(nameof(Indices), this._indices, meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors);
+
+            base.OnValidateReferences(validate);
+        }
+
+        protected override void OnValidateContent(Validation.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;
+        }
+    }
+
+    partial class MeshPrimitive
+    {
+        /// <summary>
+        /// Sets Cesium outline vertex indices
+        /// </summary>
+        /// <param name="outlines">the list of vertex indices.</param>
+        /// <param name="accessorName">the name of the accessor to be created.</param>
+        public void SetCesiumOutline(IReadOnlyList<uint> outlines, string accessorName = "Cesium outlines")
+        {
+            Guard.NotNull(outlines, nameof(outlines));
+
+            // create and fill data
+
+            var dstData = new Byte[outlines.Count * 4];
+            var dstArray = new Memory.IntegerArray(dstData, IndexEncodingType.UNSIGNED_INT);
+            for (int i = 0; i < outlines.Count; ++i) { dstArray[i] = outlines[i]; }
+
+            var model = this.LogicalParent.LogicalParent;
+
+            var bview = model.UseBufferView(dstData);
+            var accessor = model.CreateAccessor(accessorName);
+
+            accessor.SetData(bview, 0, dstArray.Count, DimensionType.SCALAR, EncodingType.UNSIGNED_INT, false);
+
+            SetCesiumOutline(accessor);
+        }
+
+        public void SetCesiumOutline(Accessor accessor)
+        {
+            if (accessor == null) { RemoveExtensions<CesiumPrimitiveOutline>(); return; }
+
+            CesiumPrimitiveOutline._ValidateAccessor(this.LogicalParent.LogicalParent, accessor);
+
+            var ext = UseExtension<CesiumPrimitiveOutline>();
+            ext.Indices = accessor;
+        }
+    }
+}

+ 6 - 5
tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs

@@ -43,12 +43,13 @@ namespace SharpGLTF.Scenes
 
             var model = scene.ToGltf2();
 
-            var outlines = new ReadOnlyCollection<uint>(new List<uint> { 0, 1, 1, 2, 2, 0});
-            var accessor = CesiumToolkit.CreateCesiumOutlineAccessor(model, outlines);
-            model.LogicalMeshes[0].Primitives[0].SetCesiumOutline(accessor);
+            var outlines = new uint[] { 0, 1, 1, 2, 2, 0};            
+            model.LogicalMeshes[0].Primitives[0].SetCesiumOutline(outlines);
+
+            var cesiumOutlineExtension = (CesiumPrimitiveOutline)model.LogicalMeshes[0].Primitives[0].Extensions.FirstOrDefault();
+            Assert.NotNull(cesiumOutlineExtension.Indices);
+            CollectionAssert.AreEqual(outlines, cesiumOutlineExtension.Indices.AsIndicesArray());
 
-            var cesiumOutlineExtension = (CESIUM_primitive_outlineglTFprimitiveextension)model.LogicalMeshes[0].Primitives[0].Extensions.FirstOrDefault();
-            Assert.True(cesiumOutlineExtension.Indices == accessor.LogicalIndex);
             var ctx = new ValidationResult(model, ValidationMode.Strict, true);
             model.ValidateContent(ctx.GetContext());