Browse Source

Added KHR_XmpJsonLd bare bones support.

vpenades 2 years ago
parent
commit
c348ba5804

+ 51 - 0
build/SharpGLTF.CodeGen/Ext.KHR_XmpJsonLD.cs

@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Microsoft.VisualBasic.FileIO;
+
+using SharpGLTF.SchemaReflection;
+
+namespace SharpGLTF
+{
+    class XmpJsonLdExtension : SchemaProcessor
+    {
+        private static string RootSchemaUri => Constants.KhronosExtensionPath("KHR_xmp_json_ld", "glTF.KHR_xmp_json_ld.schema.json");
+
+        private static string PropSchemaUri => Constants.KhronosExtensionPath("KHR_xmp_json_ld", "KHR_xmp_json_ld.schema.json");
+
+        private const string ExtensionRootClassName = "KHR_xmp_json_ld glTF Document Extension";
+        private const string ExtensionPropClassName = "KHR_xmp_json_ld glTF Extension";
+
+        public override IEnumerable<(string, SchemaType.Context)> Process()
+        {
+            yield return ("ext.XmpJsonLinkedData.Root.g", ProcessModel());
+            yield return ("ext.XmpJsonLinkedData.Prop.g", ProcessProps());
+        }
+
+        private static SchemaType.Context ProcessModel()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(RootSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+
+            var packets = ctx.FindClass(ExtensionRootClassName).GetField("packets");
+
+            return ctx;
+        }
+
+        private static SchemaType.Context ProcessProps()
+        {
+            var ctx = SchemaProcessing.LoadSchemaContext(PropSchemaUri);
+            ctx.IgnoredByCodeEmitter("glTF Property");
+            ctx.IgnoredByCodeEmitter("glTF Child of Root Property");
+            return ctx;
+        }
+
+        public override void PrepareTypes(CodeGen.CSharpEmitter newEmitter, SchemaType.Context ctx)
+        {
+            newEmitter.SetRuntimeName(ExtensionRootClassName, "XmpPackets");
+            newEmitter.SetRuntimeName(ExtensionPropClassName, "XmpPacketReference");
+        }
+    }
+}

+ 4 - 1
build/SharpGLTF.CodeGen/Program.cs

@@ -53,9 +53,12 @@ namespace SharpGLTF
             processors.Add(new AgiArticulationsExtension());
             processors.Add(new AgiArticulationsExtension());
             processors.Add(new AgiStkMetadataExtension());
             processors.Add(new AgiStkMetadataExtension());
 
 
+            // other
+            processors.Add(new XmpJsonLdExtension());
+
             // ----------------------------------------------  process all files
             // ----------------------------------------------  process all files
 
 
-            foreach(var processor in processors)
+            foreach (var processor in processors)
             {
             {
                 foreach(var (targetFileName, schema) in processor.Process())
                 foreach(var (targetFileName, schema) in processor.Process())
                 {
                 {

+ 2 - 2
src/SharpGLTF.Core/README.md

@@ -74,9 +74,10 @@ It also handles the way a mesh is brought from its local space to world space, i
 - [x] [CESIUM_primitive_outline](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor/CESIUM_primitive_outline)
 - [x] [CESIUM_primitive_outline](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor/CESIUM_primitive_outline)
   - Extension provided by [@bertt](https://github.com/bertt)
   - Extension provided by [@bertt](https://github.com/bertt)
 - [x] [AGI_articulations](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/AGI_articulations)
 - [x] [AGI_articulations](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/AGI_articulations)
+- [x] [AGI_stk_metadata](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/AGI_stk_metadata)
   - Extension provided by [@emackey](https://github.com/emackey)
   - Extension provided by [@emackey](https://github.com/emackey)
 
 
-- [ ] [KHR_xmp_json_ld](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_xmp_json_ld)
+- [x] [KHR_xmp_json_ld](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_xmp_json_ld)
 - [ ] [KHR_techniques_webgl](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_techniques_webgl)
 - [ ] [KHR_techniques_webgl](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_techniques_webgl)
   - This extension has been declared _obsolete_ by Khronos 
   - This extension has been declared _obsolete_ by Khronos 
 
 
@@ -90,7 +91,6 @@ It also handles the way a mesh is brought from its local space to world space, i
 - [ ] [MSFT_packing_normalRoughnessMetallic](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_packing_normalRoughnessMetallic)
 - [ ] [MSFT_packing_normalRoughnessMetallic](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_packing_normalRoughnessMetallic)
 - [ ] [MSFT_packing_occlusionRoughnessMetallic](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_packing_occlusionRoughnessMetallic)
 - [ ] [MSFT_packing_occlusionRoughnessMetallic](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_packing_occlusionRoughnessMetallic)
 
 
-- [ ] [AGI_stk_metadata](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/AGI_stk_metadata)
 - [ ] [EXT_lights_image_based](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_lights_image_based)
 - [ ] [EXT_lights_image_based](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_lights_image_based)
 
 
 - [ ] [ADOBE_materials_thin_transparency](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/ADOBE_materials_thin_transparency)
 - [ ] [ADOBE_materials_thin_transparency](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/ADOBE_materials_thin_transparency)

+ 56 - 0
src/SharpGLTF.Core/Schema2/Generated/ext.XmpJsonLinkedData.Prop.g.cs

@@ -0,0 +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>
+	/// References an XMP packet listed in `KHR_xmp_json_ld glTF extension`
+	/// </summary>
+	partial class XmpPacketReference : ExtraProperties
+	{
+	
+		private Int32 _packet;
+		
+	
+		protected override void SerializeProperties(Utf8JsonWriter writer)
+		{
+			base.SerializeProperties(writer);
+			SerializeProperty(writer, "packet", _packet);
+		}
+	
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
+		{
+			switch (jsonPropertyName)
+			{
+				case "packet": _packet = DeserializePropertyValue<Int32>(ref reader); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
+			}
+		}
+	
+	}
+
+}

+ 57 - 0
src/SharpGLTF.Core/Schema2/Generated/ext.XmpJsonLinkedData.Root.g.cs

@@ -0,0 +1,57 @@
+// <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>
+	/// Metadata about the glTF asset.
+	/// </summary>
+	partial class XmpPackets : ExtraProperties
+	{
+	
+		private const int _packetsMinItems = 1;
+		private List<System.Text.Json.Nodes.JsonNode> _packets;
+		
+	
+		protected override void SerializeProperties(Utf8JsonWriter writer)
+		{
+			base.SerializeProperties(writer);
+			SerializeProperty(writer, "packets", _packets, _packetsMinItems);
+		}
+	
+		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
+		{
+			switch (jsonPropertyName)
+			{
+				case "packets": DeserializePropertyList<System.Text.Json.Nodes.JsonNode>(ref reader, _packets); break;
+				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
+			}
+		}
+	
+	}
+
+}

+ 64 - 0
src/SharpGLTF.Core/Schema2/ext.XmpJsonLinkedData.cs

@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using SharpGLTF.Collections;
+
+using XMPJSONLD = System.Text.Json.Nodes.JsonNode;
+
+namespace SharpGLTF.Schema2
+{
+    public partial class XmpPackets
+    {
+        internal XmpPackets(ModelRoot root)
+        {
+            _packets = new List<XMPJSONLD>();
+        }
+
+        public IReadOnlyList<XMPJSONLD> JsonPackets => _packets;
+
+        public int AddPacket(XMPJSONLD packet)
+        {
+            if (_packets.Contains(packet)) throw new ArgumentException("Already exists", nameof(packet));
+            _packets.Add(packet);
+            return _packets.Count -1;
+        }
+    }
+
+    public partial class XmpPacketReference
+    {
+        internal XmpPacketReference(ExtraProperties owner)
+        {
+            _Owner = owner;
+        }
+
+        private ExtraProperties _Owner;
+
+        private ModelRoot _FindRoot()
+        {
+            if (_Owner is LogicalChildOfRoot logicalChild) return logicalChild.LogicalParent;
+            return null;
+        }
+
+        private XmpPackets _GetPackets()
+        {
+            return _FindRoot()?.GetExtension<XmpPackets>();
+        }
+
+        public int PacketLogicalIndex => _packet;
+
+        public XMPJSONLD JsonPacket => _GetPackets()?.JsonPackets[_packet];
+
+        public void SetPacket(int logicalIndex)
+        {
+            if (logicalIndex < 0) throw new ArgumentOutOfRangeException(nameof(logicalIndex));
+
+            var packets = _GetPackets();
+            if (packets != null && logicalIndex >= packets.JsonPackets.Count) throw new ArgumentOutOfRangeException(nameof(logicalIndex));
+
+            _packet = logicalIndex;
+        }
+    }
+
+    
+}

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

@@ -24,8 +24,8 @@ namespace SharpGLTF.Schema2
         static ExtensionsFactory()
         static ExtensionsFactory()
         {
         {
             RegisterExtension<ModelRoot, _ModelPunctualLights>("KHR_lights_punctual");
             RegisterExtension<ModelRoot, _ModelPunctualLights>("KHR_lights_punctual");
-
             RegisterExtension<Node, _NodePunctualLight>("KHR_lights_punctual");
             RegisterExtension<Node, _NodePunctualLight>("KHR_lights_punctual");
+
             RegisterExtension<Node, MeshGpuInstancing>("EXT_mesh_gpu_instancing");
             RegisterExtension<Node, MeshGpuInstancing>("EXT_mesh_gpu_instancing");
 
 
             RegisterExtension<Material, MaterialUnlit>("KHR_materials_unlit");
             RegisterExtension<Material, MaterialUnlit>("KHR_materials_unlit");
@@ -45,6 +45,9 @@ namespace SharpGLTF.Schema2
             RegisterExtension<Texture, TextureWEBP>("EXT_texture_webp");
             RegisterExtension<Texture, TextureWEBP>("EXT_texture_webp");
             RegisterExtension<Texture, TextureKTX2>("KHR_texture_basisu");
             RegisterExtension<Texture, TextureKTX2>("KHR_texture_basisu");
 
 
+            RegisterExtension<ModelRoot, XmpPackets>("KHR_xmp_json_ld");
+            RegisterExtension<ExtraProperties, XmpPacketReference>("KHR_xmp_json_ld");            
+
             RegisterExtension<ModelRoot, AgiRootArticulations>("AGI_articulations");
             RegisterExtension<ModelRoot, AgiRootArticulations>("AGI_articulations");
             RegisterExtension<ModelRoot, AgiRootStkMetadata>("AGI_stk_metadata");
             RegisterExtension<ModelRoot, AgiRootStkMetadata>("AGI_stk_metadata");
             RegisterExtension<Node, AgiNodeArticulations>("AGI_articulations");
             RegisterExtension<Node, AgiNodeArticulations>("AGI_articulations");

+ 91 - 0
tests/Assets/XmpJsonLd.gltf

@@ -0,0 +1,91 @@
+{
+  "extensionsUsed": ["KHR_xmp_json_ld"],
+  "extensions": {
+    "KHR_xmp_json_ld": {
+      "packets": [
+        {
+          "@context": {
+            "dc": "http://purl.org/dc/elements/1.1/",
+            "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+          },
+          "@id": "",
+          "dc:contributor": {
+            "@set": [
+              "Creator1Name",
+              "[email protected]",
+              "Creator3Name<[email protected]>"
+            ]
+          },
+          "dc:coverage": "Bay Area, California, United States",
+          "dc:creator": {
+            "@list": [ "CreatorName", "[email protected]" ]
+          },
+          "dc:date": {
+            "@list": [ "1997-07-16T19:20:30+01:00" ]
+          },
+          "dc:description": {
+            "@type": "rdf:Alt",
+            "rdf:_1": {
+              "@language": "en-us",
+              "@value": "text"
+            }
+          },
+          "dc:format": "model/gltf-binary",
+          "dc:identifier": "urn:stock-id:292930",
+          "dc:language": {
+            "@set": [ "en" ]
+          },
+          "dc:publisher": {
+            "@set": [ "Company" ]
+          },
+          "dc:relation": {
+            "@set": [ "https://www.khronos.org/" ]
+          },
+          "dc:rights": {
+            "@type": "rdf:Alt",
+            "rdf:_1": {
+              "@language": "en-us",
+              "@value": "BSD"
+            }
+          },
+          "dc:source": "http://related_resource.org/derived_from_this.gltf",
+          "dc:subject": {
+            "@set": [ "architecture" ]
+          },
+          "dc:title": {
+            "@type": "rdf:Alt",
+            "rdf:_1": {
+              "@language": "en-us",
+              "@value": "MyModel"
+            },
+            "rdf:_2": {
+              "@language": "it-it",
+              "@value": "Mio Modello"
+            }
+          },
+          "dc:type": {
+            "@set": [ "Physical Object" ]
+          }
+        }
+      ]
+    }
+  },
+  "asset": {
+    "version": "2.0",
+    "extensions": {
+      "KHR_xmp_json_ld": {
+        "packet": 0
+      }
+    }
+  },
+  "images": [
+    {
+      "uri": "texture.png",
+      "extensions": {
+        "KHR_xmp_json_ld": {
+          "packet": 0
+        }
+      }
+    }
+  ]
+}

+ 42 - 0
tests/SharpGLTF.Core.Tests/Schema2/LoadAndSave/XmpJsonTests.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+
+using NUnit.Framework;
+
+namespace SharpGLTF.Schema2.LoadAndSave
+{
+    /// <summary>
+    /// Test cases for models found in <see href="https://github.com/KhronosGroup/glTF-Blender-Exporter"/>
+    /// </summary>
+    [TestFixture]
+    [AttachmentPathFormat("*/TestResults/LoadAndSave/?", true)]
+    [Category("XMP Json tests")]
+    public class XmpJsonTests
+    {
+        [Test]
+        public void LoadXmpModel()
+        {
+            var path = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, "Assets\\XmpJsonLd.gltf");
+
+            var model = ModelRoot.Load(path);
+            Assert.NotNull(model);
+
+            var packets = model.GetExtension<XmpPackets>();
+            Assert.NotNull(packets);
+            Assert.AreEqual(1, packets.JsonPackets.Count);
+
+            var packet = packets.JsonPackets[0];
+
+            model.AttachToCurrentTest("result.gltf");
+
+            var model2 = ModelRoot.CreateModel();
+            model2.UseExtension<XmpPackets>().AddPacket(packet);
+            model2.Asset.UseExtension<XmpPacketReference>().SetPacket(0);
+            model2.AttachToCurrentTest("result2.gltf");
+
+        }
+    }
+}