Browse Source

+docs
fixed support for MeshBuilders with empty primitives when creating Schema2 meshes.

Vicente Penades 6 years ago
parent
commit
0beb389b9e

+ 13 - 0
src/SharpGLTF.Toolkit/Geometry/MeshBuilderToolkit.cs

@@ -76,5 +76,18 @@ namespace SharpGLTF.Geometry
 
             return posnrm;
         }
+
+        public static bool IsEmpty<TMaterial>(this IPrimitiveReader<TMaterial> primitive)
+        {
+            if (primitive.Points.Count > 0) return false;
+            if (primitive.Lines.Count > 0) return false;
+            if (primitive.Triangles.Count > 0) return false;
+            return true;
+        }
+
+        public static bool IsEmpty<TMaterial>(this IMeshBuilder<TMaterial> mesh)
+        {
+            return mesh.Primitives.All(prim => prim.IsEmpty());
+        }
     }
 }

+ 13 - 11
src/SharpGLTF.Toolkit/Geometry/PackedMeshBuilder.cs

@@ -34,19 +34,19 @@ namespace SharpGLTF.Geometry
                 throw new ArgumentException(ex.Message, nameof(meshBuilders), ex);
             }
 
-            var vertexBlocks = VertexTypes.VertexUtils.CreateVertexMemoryAccessors
-                (
-                meshBuilders
+            var meshPrimitives = meshBuilders
                 .SelectMany(item => item.Primitives)
-                .Select(item => item.Vertices)
-                ).ToList();
+                .Where(item => !item.IsEmpty());
 
-            var indexBlocks = VertexTypes.VertexUtils.CreateIndexMemoryAccessors
-                (
-                meshBuilders
-                .SelectMany(item => item.Primitives)
-                .Select(item => item.Indices)
-                ).ToList();
+            Guard.IsTrue(meshPrimitives.Any(), "No geometry found.");
+
+            var vertexBlocks = VertexTypes.VertexUtils
+                .CreateVertexMemoryAccessors( meshPrimitives.Select(item => item.Vertices) )
+                .ToList();
+
+            var indexBlocks = VertexTypes.VertexUtils
+                .CreateIndexMemoryAccessors( meshPrimitives.Select(item => item.Indices) )
+                .ToList();
 
             int idx = 0;
 
@@ -56,6 +56,8 @@ namespace SharpGLTF.Geometry
 
                 foreach (var primitiveBuilder in meshBuilder.Primitives)
                 {
+                    if (primitiveBuilder.IsEmpty()) continue;
+
                     dstMesh.AddPrimitive(primitiveBuilder.Material, primitiveBuilder.VerticesPerPrimitive, vertexBlocks[idx], indexBlocks[idx]);
 
                     ++idx;

+ 4 - 4
src/SharpGLTF.Toolkit/Geometry/PrimitiveBuilder.cs

@@ -213,7 +213,7 @@ namespace SharpGLTF.Geometry
         /// </summary>
         /// <param name="a">First corner of the line.</param>
         /// <param name="b">Second corner of the line.</param>
-        /// <returns>The indices of the vertices.</returns>
+        /// <returns>The indices of the vertices, or, in case the line is degenerated, (-1,-1).</returns>
         public (int, int) AddLine(IVertexBuilder a, IVertexBuilder b)
         {
             Guard.NotNull(a, nameof(a));
@@ -233,7 +233,7 @@ namespace SharpGLTF.Geometry
         /// </summary>
         /// <param name="a">First corner of the line.</param>
         /// <param name="b">Second corner of the line.</param>
-        /// <returns>The indices of the vertices.</returns>
+        /// <returns>The indices of the vertices, or, in case the line is degenerated, (-1,-1).</returns>
         public (int, int) AddLine(VertexBuilder<TvG, TvM, TvS> a, VertexBuilder<TvG, TvM, TvS> b)
         {
             Guard.IsTrue(_PrimitiveVertexCount == 2, nameof(VerticesPerPrimitive), "Lines are not supported for this primitive");
@@ -264,7 +264,7 @@ namespace SharpGLTF.Geometry
         /// <param name="a">First corner of the triangle.</param>
         /// <param name="b">Second corner of the triangle.</param>
         /// <param name="c">Third corner of the triangle.</param>
-        /// <returns>The indices of the vertices.</returns>
+        /// <returns>The indices of the vertices, or, in case the triangle is degenerated, (-1,-1,-1).</returns>
         public (int, int, int) AddTriangle(IVertexBuilder a, IVertexBuilder b, IVertexBuilder c)
         {
             Guard.NotNull(a, nameof(a));
@@ -288,7 +288,7 @@ namespace SharpGLTF.Geometry
         /// <param name="a">First corner of the triangle.</param>
         /// <param name="b">Second corner of the triangle.</param>
         /// <param name="c">Third corner of the triangle.</param>
-        /// <returns>The indices of the vertices.</returns>
+        /// <returns>The indices of the vertices, or, in case the triangle is degenerated, (-1,-1,-1).</returns>
         public (int, int, int) AddTriangle(VertexBuilder<TvG, TvM, TvS> a, VertexBuilder<TvG, TvM, TvS> b, VertexBuilder<TvG, TvM, TvS> c)
         {
             Guard.IsTrue(_PrimitiveVertexCount == 3, nameof(VerticesPerPrimitive), "Triangles are not supported for this primitive");

+ 33 - 0
tests/SharpGLTF.Tests/Geometry/MeshBuilderTests.cs

@@ -122,5 +122,38 @@ namespace SharpGLTF.Geometry
             NumericsAssert.AreEqual(v1Bis.Skinning.Weights, new Vector4(7, 6, 5, 2) / (7f + 6f + 5f + 2f));
         }
 
+        [Test]
+        public void CreatePartiallyEmptyMesh()
+        {
+            var p0 = new Vector3(4403.12831325084f, 5497.3228336684406f, -451.62756590108586f);
+            var p1 = new Vector3(4403.1283132596873f, 5497.3228336591274f, -451.62756593199413f);
+            var p2 = new Vector3(4392.54991199635f, 5483.549242743291f, -450.72132376581396f);
+
+            Assert.AreEqual(p0, p1);
+
+
+
+            /*
+            var triangle = new Triangle(p0, p1, p2);
+            var normal = triangle.GetNormal();
+            var material1 = new MaterialBuilder().WithDoubleSide(true).WithMetallicRoughnessShader().WithChannelParam("BaseColor", new Vector4(1, 1, 1, 1));
+            var mesh = new MeshBuilder<VertexPositionNormal>("mesh");
+            var prim = mesh.UsePrimitive(material1);
+            prim.AddTriangle(
+            new VertexPositionNormal((float)triangle.GetP0().X, (float)triangle.GetP0().Y, (float)triangle.GetP0().Z, normal.X, normal.Y, normal.Z),
+            new VertexPositionNormal((float)triangle.GetP1().X, (float)triangle.GetP1().Y, (float)triangle.GetP1().Z, normal.X, normal.Y, normal.Z),
+            new VertexPositionNormal((float)triangle.GetP2().X, (float)triangle.GetP2().Y, (float)triangle.GetP2().Z, normal.X, normal.Y, normal.Z));
+
+            var model = ModelRoot.CreateModel();
+            try
+            {
+                model.CreateMeshes(mesh);
+            }
+            catch (ArgumentOutOfRangeException e)
+            {
+                Console.WriteLine(e);
+            }*/
+        }
+
     }
 }