Browse Source

Updated gltf validator to 2.0.0-dev.3.3 (still WIP)

Vicente Penades 5 years ago
parent
commit
07e775eee8

+ 11 - 18
src/SharpGLTF.Toolkit/Scenes/SceneBuilder.Schema2.cs

@@ -177,12 +177,12 @@ namespace SharpGLTF.Scenes
         #region from SceneBuilder to Schema2
 
         /// <summary>
-        /// Convertes a collection of <see cref="SceneBuilder"/> instances to a single <see cref="ModelRoot"/> instance.
+        /// Converts a collection of <see cref="SceneBuilder"/> instances to a single <see cref="ModelRoot"/> instance.
         /// </summary>
         /// <param name="srcScenes">A collection of scenes</param>
         /// <param name="settings">Conversion settings.</param>
         /// <returns>A new <see cref="ModelRoot"/> instance.</returns>
-        public static ModelRoot ToSchema2(IEnumerable<SceneBuilder> srcScenes, SceneBuilderSchema2Settings settings)
+        public static ModelRoot ToGltf2(IEnumerable<SceneBuilder> srcScenes, SceneBuilderSchema2Settings settings)
         {
             Guard.NotNull(srcScenes, nameof(srcScenes));
 
@@ -196,10 +196,13 @@ namespace SharpGLTF.Scenes
                 var dstScene = dstModel.UseScene(dstModel.LogicalScenes.Count);
 
                 dstScene.Name = srcScene.Name;
+                dstScene.Extras = srcScene.Extras.DeepClone();
 
                 context.AddScene(dstScene, srcScene);
             }
 
+            dstModel.DefaultScene = dstModel.LogicalScenes[0];
+
             return dstModel;
         }
 
@@ -210,26 +213,16 @@ namespace SharpGLTF.Scenes
         /// <returns>A new <see cref="ModelRoot"/> instance.</returns>
         public ModelRoot ToGltf2(SceneBuilderSchema2Settings settings)
         {
-            var context = new Schema2SceneBuilder();
-
-            var dstModel = ModelRoot.CreateModel();
-            context.AddGeometryResources(dstModel, new[] { this }, settings);
-
-            var dstScene = dstModel.UseScene(0);
-
-            dstScene.Name = this.Name;
-            dstScene.Extras = this.Extras.DeepClone();
-
-            context.AddScene(dstScene, this);
-
-            dstModel.DefaultScene = dstScene;
-
-            return dstModel;
+            return ToGltf2(new[] { this }, settings);
         }
 
+        /// <summary>
+        /// Converts this <see cref="SceneBuilder"/> instance into a <see cref="ModelRoot"/> instance.
+        /// </summary>
+        /// <returns>A new <see cref="ModelRoot"/> instance.</returns>
         public ModelRoot ToGltf2()
         {
-            return ToGltf2(SceneBuilderSchema2Settings.Default);
+            return ToGltf2(new[] { this }, SceneBuilderSchema2Settings.Default);
         }
 
         #endregion

+ 14 - 9
tests/SharpGLTF.NUnit/NUnitGltfUtils.cs

@@ -60,15 +60,19 @@ namespace SharpGLTF
             // find the output path for the current test
             fileName = TestContext.CurrentContext.GetAttachmentPath(fileName, true);
 
+            string validationPath = null;
+
             if (fileName.ToLower().EndsWith(".glb"))
             {
                 model.SaveGLB(fileName, settings);
+                validationPath = fileName;
             }
             else if (fileName.ToLower().EndsWith(".gltf"))
             {
                 if (settings == null) settings = new WriteSettings { JsonIndented = true };
 
                 model.Save(fileName, settings);
+                validationPath = fileName;
             }
             else if (fileName.ToLower().EndsWith(".obj"))
             {
@@ -87,20 +91,21 @@ namespace SharpGLTF
             }
 
             // Attach the saved file to the current test
-            TestContext.AddTestAttachment(fileName);
+            TestContext.AddTestAttachment(fileName);            
 
-            if (fileName.ToLower().EndsWith(".obj")) return fileName;
+            if (validationPath != null)
+            {
+                var report = gltf_validator.ValidateFile(fileName);
+                if (report == null) return fileName;
 
-            var report = gltf_validator.ValidateFile(fileName);
-            if (report == null) return fileName;
+                if (report.HasErrors || report.HasWarnings)
+                {
+                    TestContext.WriteLine(report.ToString());
+                }
 
-            if (report.HasErrors || report.HasWarnings)
-            {
-                TestContext.WriteLine(report.ToString());
+                Assert.IsFalse(report.HasErrors);
             }
 
-            Assert.IsFalse(report.HasErrors);
-
             return fileName;
         }
     }

+ 108 - 48
tests/SharpGLTF.NUnit/gltf_validator.cs

@@ -1,7 +1,9 @@
 using System;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
+using System.Linq;
 using System.Text;
+using System.Text.Json;
 
 namespace SharpGLTF
 {
@@ -42,83 +44,141 @@ namespace SharpGLTF
             if (!System.IO.Path.IsPathRooted(gltfFilePath)) gltfFilePath = System.IO.Path.GetFullPath(gltfFilePath);
 
             var psi = new System.Diagnostics.ProcessStartInfo(ValidatorExePath);
-            psi.Arguments = $"-p -r -a \"{gltfFilePath}\"";
-            psi.UseShellExecute = false;            
-            psi.RedirectStandardError = true;
+            psi.Arguments = $"-p -r -a --stdout \"{gltfFilePath}\"";
+            psi.UseShellExecute = false;
+            psi.RedirectStandardOutput = true;            
 
             using (var p = System.Diagnostics.Process.Start(psi))
             {
-                if (!p.WaitForExit(1000 * 10))
+                if (!p.WaitForExit(1000 * 10)) // wait for a reasonable timeout
                 {
-                    try { p.Kill(); } catch { }
+                    try { p.Kill(); } catch { return null; }
                 }
 
-                var rawReport = p.StandardError.ReadToEnd();
+                var mainReport = p.StandardOutput.ReadToEnd();
+                if (string.IsNullOrWhiteSpace(mainReport)) return null;
+                var report = ValidationReport.Parse(mainReport);
+                
+                if (report.Messages.Any(item => item.Code == "UNSUPPORTED_EXTENSION")) return null;
 
-                if (string.IsNullOrWhiteSpace(rawReport)) return null;
-
-                return new ValidationReport(gltfFilePath, rawReport);
+                return report;
             }
         }
 
+        /// <summary>
+        /// Represents the report generated by glTF validator
+        /// </summary>
+        /// <see href="https://github.com/KhronosGroup/glTF-Validator/blob/898f53944b40650aacef550c4977de04c46990ab/docs/validation.schema.json"/>
         public sealed class ValidationReport
         {
-            internal ValidationReport(string srcPath, string rawReport)
+            public static ValidationReport Parse(string json)
             {
-                var lines = rawReport.Split('\n');
-
-                var status = 0;
+                var options = new JsonSerializerOptions();
+                options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
 
-                var www = new List<string>();
-                var eee = new List<string>();
+                return JsonSerializer.Deserialize<ValidationReport>(json, options);
+            }
 
-                foreach (var l in lines)
-                {
-                    if (l == "\tWarnings:") { status = 1; continue; }
-                    if (l == "\tErrors:") { status = 2; continue; }
+            public string Uri { get; set; }
+            public string MimeType { get; set; }
+            public string ValidatorVersion { get; set; }
+            public string ValidatedAt { get; set; }
+            public ValidationIssues Issues { get; set; }
+            public ValidationInfo Info { get; set; }
 
-                    if (status == 1) www.Add(l.Trim());
-                    if (status == 2) eee.Add(l.Trim());
-                }
+            public bool HasWarnings => Issues.NumWarnings > 0;
+            public bool HasErrors => Issues.NumErrors > 0;
 
-                FilePath = srcPath;
-                RawReport = rawReport;
-                Warnings = www;
-                Errors = eee;
-            }
+            public IEnumerable<ValidationMessage> Messages => Issues.Messages == null
+                ? Enumerable.Empty<ValidationMessage>()
+                : Issues.Messages;
 
-            public string RawReport { get; private set; }
+            public IEnumerable<String> Hints => Messages
+                .Where(item => item.Severity == 3)
+                .Select(item => item.Message);
 
-            public readonly IReadOnlyList<String> Warnings;
-            public readonly IReadOnlyList<String> Errors;
+            public IEnumerable<String> Infos => Messages
+                .Where(item => item.Severity == 2)
+                .Select(item => item.Message);
 
-            public string FilePath { get; private set; }
+            public IEnumerable<String> Warnings => Messages
+                .Where(item => item.Severity == 1)
+                .Select(item => item.Message);
 
-            public bool HasWarnings => Warnings.Count > 0;
-            public bool HasErrors => Errors.Count > 0;
+            public IEnumerable<String> Errors => Messages
+                .Where(item => item.Severity == 0)
+                .Select(item => item.Message);
 
             public override string ToString()
             {
-                return RawReport;
+                var options = new JsonSerializerOptions();
+                options.WriteIndented = true;
+                options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
+                return JsonSerializer.Serialize(this, options);
+            }
+        }
 
-                var sb = new StringBuilder();
+        public sealed class ValidationIssues
+        {
+            public int NumErrors { get; set; }
+            public int NumWarnings { get; set; }
+            public int NumInfos { get; set; }
+            public int NumHints { get; set; }
+            public ValidationMessage[] Messages { get; set; }
+            public bool Truncated { get; set; }
+        }
 
-                sb.AppendLine(FilePath);
+        public sealed class ValidationMessage
+        {
+            public string Code { get; set; }
+            public string Message { get; set; }
+            public int Severity { get; set; }
+            public string Pointer { get; set; }
+            public int? Offset { get; set; }
+        }
 
-                if (HasWarnings)
-                {
-                    sb.AppendLine("\tWarnings:");
-                    foreach (var w in Warnings) sb.AppendLine($"\t\t{w}");
-                }
+        public sealed class ValidationInfo
+        {
+            public string Version { get; set; }
+            public string MinVersion { get; set; }
+            public string Generator { get; set; }
+            public string[] ExtensionsUsed { get; set; }
+            public string[] ExtensionsRequired { get; set; }
+            public ValidationResources[] Resources { get; set; }
+            public int AnimationCount { get; set; }
+            public int MaterialCount { get; set; }
+            public bool HasMorphTargets { get; set; }
+            public bool HasSkins { get; set; }
+            public bool HasTextures { get; set; }
+            public bool HasDefaultScene { get; set; }
+            public int DrawCallCount { get; set; }
+            public int TotalVertexCount { get; set; }
+            public int TotalTriangleCount { get; set; }
+            public int MaxUVs { get; set; }
+            public int  MaxInfluences { get; set; }
+            public int  MaxAttributes { get; set; }
+        }
 
-                if (HasErrors)
-                {
-                    sb.AppendLine("\tErrors:");
-                    foreach (var e in Errors) sb.AppendLine($"\t\t{e}");
-                }
+        public sealed class ValidationResources
+        {
+            public string Pointer { get; set; }
+            public string Storage { get; set; }
+            public string MimeType { get; set; }            
+            public string Uri { get; set; }
+            public int ByteLength { get; set; }
+            public ValidationImage Image { get; set; }
+        }
 
-                return sb.ToString();
-            }
+        public sealed class ValidationImage
+        {
+            public int Width { get; set; }
+            public int Height { get; set; }
+            public string Format { get; set; }
+            public string Primaries { get; set; }
+            public string Transfer { get; set; }
+            public int Bits { get; set; }
         }
+
+        
     }
 }

BIN
tools/linux64/gltf_validator


BIN
tools/win64/gltf_validator.exe