Browse Source

Added a check for meshes without primitives, fixes #31
Models are now fully validated before saving.

Vicente Penades 5 years ago
parent
commit
cf494d835e

+ 24 - 6
src/SharpGLTF.Core/IO/WriteContext.cs

@@ -154,16 +154,12 @@ namespace SharpGLTF.IO
 
             model._PrepareImagesForWriting(this, baseName, ResourceWriteMode.SatelliteFile);
 
+            _ValidateBeforeWriting(model);
+
             using (var m = new MemoryStream())
             {
                 model._WriteJSON(m, this.JsonIndented);
 
-                /*
-                using (var w = new StreamWriter(m))
-                {
-                    model._WriteJSON(w, this.JsonFormatting);
-                }*/
-
                 WriteAllBytesToEnd($"{baseName}.gltf", m.ToArraySegment());
             }
 
@@ -190,6 +186,8 @@ namespace SharpGLTF.IO
 
             model._PrepareImagesForWriting(this, baseName, ResourceWriteMode.Embedded);
 
+            _ValidateBeforeWriting(model);
+
             using (var m = new MemoryStream())
             {
                 using (var w = new BinaryWriter(m))
@@ -207,6 +205,26 @@ namespace SharpGLTF.IO
 
         #region core
 
+        /// <summary>
+        /// This needs to be called immediately before writing to json,
+        /// but immediately after preprocessing and buffer setup, so we have a valid model.
+        /// </summary>
+        /// <param name="model"></param>
+        private void _ValidateBeforeWriting(SCHEMA2 model)
+        {
+            if (_NoCloneWatchdog) return;
+
+            var vcontext = new Validation.ValidationResult(model, Validation.ValidationMode.Strict);
+
+            model.ValidateReferences(vcontext.GetContext());
+            var ex = vcontext.Errors.FirstOrDefault();
+            if (ex != null) throw ex;
+
+            model.Validate(vcontext.GetContext());
+            ex = vcontext.Errors.FirstOrDefault();
+            if (ex != null) throw ex;
+        }
+
         /// <summary>
         /// Prepares the model for writing with the appropiate settings, creating a defensive copy if neccesary.
         /// </summary>

+ 6 - 0
src/SharpGLTF.Core/Schema2/gltf.Mesh.cs

@@ -96,6 +96,12 @@ namespace SharpGLTF.Schema2
         protected override void OnValidateReferences(Validation.ValidationContext result)
         {
             base.OnValidateReferences(result);
+            
+            if (this.Primitives.Count == 0)
+            {
+                result.AddSchemaError("Primitives must be defined");
+                return;
+            }
 
             result.CheckLinksInCollection("Primitives", _primitives);
 

+ 18 - 0
tests/SharpGLTF.Tests/Scenes/SceneBuilderTests.cs

@@ -587,5 +587,23 @@ namespace SharpGLTF.Scenes
             }
         }
 
+
+        [Test]
+        public void TestCreateEmptyMesh()
+        {
+            var sb = new SceneBuilder();
+            sb.AddMesh(VPOSNRM.CreateCompatibleMesh("Empty"), Matrix4x4.Identity);
+
+            var schema = sb.ToGltf2();
+
+            Assert.AreEqual(0, schema.LogicalMeshes.Count,"SceneBuilder should detect empty meshes and remove them.");
+
+            schema.CreateMesh("Empty2");
+
+            var fileName = TestContext.CurrentContext.GetAttachmentPath("empty.glb", true);
+
+            Assert.Throws<SharpGLTF.Validation.SchemaException>(() => schema.SaveGLB(fileName));
+        }
+
     }
 }