Beispiel #1
0
        private static void AddLines(long id, Vector3[] vertices, Gltf gltf,
                                     int material, List <byte> buffer, List <BufferView> bufferViews, List <Accessor> accessors, Transform t = null)
        {
            var floatSize  = sizeof(float);
            var ushortSize = sizeof(ushort);
            var vBuff      = new byte[vertices.Length * 3 * floatSize];
            var indices    = new byte[vertices.Length / 2 * 2 * ushortSize];

            var vi = 0;
            var ii = 0;

            for (var i = 0; i < vertices.Length; i++)
            {
                var v = vertices[i];
                System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.X), 0, vBuff, vi, floatSize);
                System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.Y), 0, vBuff, vi + floatSize, floatSize);
                System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.Z), 0, vBuff, vi + 2 * floatSize, floatSize);
                vi += 3 * floatSize;

                // On every even index, write a line segment.
                if (i % 2 == 0 && i < vertices.Length - 1)
                {
                    System.Buffer.BlockCopy(BitConverter.GetBytes((ushort)i), 0, indices, ii, ushortSize);
                    System.Buffer.BlockCopy(BitConverter.GetBytes((ushort)(i + 1)), 0, indices, ii + ushortSize, ushortSize);
                    ii += 2 * ushortSize;
                }
            }
            // Console.WriteLine($"{vBuff.Count / sizeof(float)/3} vertices, {indices.Count / sizeof(ushort)} indices");

            var bbox = new BBox3(vertices);

            gltf.AddLineLoop($"{id}_curve", buffer, bufferViews, accessors, vBuff.ToArray(), indices.ToArray(), bbox.Min.ToArray(),
                             bbox.Max.ToArray(), 0, (ushort)(vertices.Length - 1), material, MeshPrimitive.ModeEnum.LINES, t);
        }
Beispiel #2
0
        private void AddLines(long id, Vector3[] vertices, Gltf gltf, int material, Transform t = null)
        {
            var vBuff   = vertices.ToArray();
            var vCount  = vertices.Length;
            var indices = new List <ushort>();

            for (ushort i = 0; i < vertices.Length; i += 2)
            {
                indices.Add(i);
                indices.Add((ushort)(i + 1));
            }
            // var indices = Enumerable.Range(0, vCount).Select(i => (ushort)i).ToArray();
            var bbox = new BBox3(vertices);

            gltf.AddLineLoop($"{id}_curve", _buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(),
                             bbox.Max.ToArray(), 0, (ushort)(vCount - 1), material, MeshPrimitive.ModeEnum.LINES, t);
        }
Beispiel #3
0
        private void AddArrow(long id, Vector3 origin, Vector3 direction, Gltf gltf, int material, Transform t)
        {
            var scale = 0.5;
            var end   = origin + direction * scale;
            var up    = direction.IsParallelTo(Vector3.ZAxis) ? Vector3.YAxis : Vector3.ZAxis;
            var tr    = new Transform(Vector3.Origin, direction.Cross(up), direction);

            tr.Rotate(up, -45.0);
            var arrow1  = tr.OfPoint(Vector3.XAxis * 0.1);
            var pts     = new[] { origin, end, end + arrow1 };
            var vBuff   = pts.ToArray();
            var vCount  = 3;
            var indices = Enumerable.Range(0, vCount).Select(i => (ushort)i).ToArray();
            var bbox    = new BBox3(pts);

            gltf.AddLineLoop($"{id}_curve", _buffer, vBuff, indices, bbox.Min.ToArray(),
                             bbox.Max.ToArray(), 0, (ushort)(vCount - 1), material, MeshPrimitive.ModeEnum.LINE_STRIP, t);
        }
Beispiel #4
0
        private static void AddLines(long id,
                                     IList <Vector3> vertices,
                                     Gltf gltf,
                                     int material,
                                     List <byte> buffer,
                                     List <BufferView> bufferViews,
                                     List <Accessor> accessors,
                                     List <glTFLoader.Schema.Mesh> meshes,
                                     List <glTFLoader.Schema.Node> nodes,
                                     bool lineLoop,
                                     Transform t = null)
        {
            var floatSize  = sizeof(float);
            var ushortSize = sizeof(ushort);
            var vBuff      = new byte[vertices.Count * 3 * floatSize];
            var indices    = new byte[vertices.Count * 2 * ushortSize];

            var vi = 0;
            var ii = 0;

            for (var i = 0; i < vertices.Count; i++)
            {
                var v = vertices[i];
                System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.X), 0, vBuff, vi, floatSize);
                System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.Y), 0, vBuff, vi + floatSize, floatSize);
                System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.Z), 0, vBuff, vi + 2 * floatSize, floatSize);
                vi += 3 * floatSize;

                var write = lineLoop ? (i < vertices.Count - 1) : (i % 2 == 0 && i < vertices.Count - 1);
                if (write)
                {
                    System.Buffer.BlockCopy(BitConverter.GetBytes((ushort)i), 0, indices, ii, ushortSize);
                    System.Buffer.BlockCopy(BitConverter.GetBytes((ushort)(i + 1)), 0, indices, ii + ushortSize, ushortSize);
                    ii += 2 * ushortSize;
                }
            }

            var bbox = new BBox3(vertices);

            gltf.AddLineLoop($"{id}_curve", buffer, bufferViews, accessors, vBuff, indices, bbox.Min.ToArray(),
                             bbox.Max.ToArray(), 0, (ushort)(vertices.Count - 1), material, MeshPrimitive.ModeEnum.LINES, meshes, nodes, t);
        }
Beispiel #5
0
        private void GetRenderDataForElement(Element e, Gltf gltf, Dictionary <string, int> materials)
        {
            if (e is ITessellateMesh)
            {
                var       mp        = e as ITessellateMesh;
                var       mesh      = mp.Mesh();
                Transform transform = null;
                if (e.Transform != null)
                {
                    transform = e.Transform;
                }
                gltf.AddTriangleMesh(e.Id + "_mesh", _buffer, mesh.Vertices.ToArray(), mesh.Normals.ToArray(),
                                     mesh.Indices.ToArray(), mesh.VertexColors.ToArray(),
                                     mesh.VMin, mesh.VMax, mesh.NMin, mesh.NMax, mesh.CMin, mesh.CMax,
                                     mesh.IMin, mesh.IMax, materials[e.Material.Name], null, transform);
            }

            if (e is ITessellateCurves)
            {
                var cp      = e as ITessellateCurves;
                var curves  = cp.Curves();
                var counter = 0;
                foreach (var c in curves)
                {
                    var vBuff   = c.ToArray();
                    var indices = Enumerable.Range(0, c.Count).Select(i => (ushort)i).ToArray();
                    var bbox    = new BBox3(c);
                    gltf.AddLineLoop($"{e.Id}_curve_{counter}", _buffer, vBuff, indices, bbox.Min.ToArray(),
                                     bbox.Max.ToArray(), 0, (ushort)(c.Count - 1), materials[BuiltInMaterials.Black.Name], e.Transform);
                }
            }

            if (e.SubElements.Count > 0)
            {
                foreach (var esub in e.SubElements)
                {
                    GetRenderDataForElement(esub, gltf, materials);
                }
            }
        }
Beispiel #6
0
        internal static void ToGlb(this Solid solid, string path)
        {
            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            root.Translation = new[] { 0.0f, 0.0f, 0.0f };
            root.Scale       = new[] { 1.0f, 1.0f, 1.0f };

            // Set Z up by rotating -90d around the X Axis
            var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2);

            root.Rotation = new[] {
                (float)q.X, (float)q.Y, (float)q.Z, (float)q.W
            };

            gltf.Nodes = new[] { root };

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" };

            var materials = gltf.AddMaterials(new[] { BuiltInMaterials.Default, BuiltInMaterials.Edges, BuiltInMaterials.EdgesHighlighted });

            var buffer = new List <byte>();
            var mesh   = new Elements.Geometry.Mesh();

            solid.Tessellate(ref mesh);

            gltf.AddTriangleMesh("mesh", buffer, mesh.Vertices.ToArray(), mesh.Normals.ToArray(),
                                 mesh.Indices.ToArray(), mesh.VertexColors.ToArray(),
                                 mesh.VMin, mesh.VMax, mesh.NMin, mesh.NMax, mesh.CMin, mesh.CMax,
                                 mesh.IMin, mesh.IMax, materials[BuiltInMaterials.Default.Name], null, null);

            var edgeCount           = 0;
            var vertices            = new List <Vector3>();
            var verticesHighlighted = new List <Vector3>();

            foreach (var e in solid.Edges.Values)
            {
                if (e.Left.Loop == null || e.Right.Loop == null)
                {
                    verticesHighlighted.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }
                else
                {
                    vertices.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }

                edgeCount++;
            }

            if (vertices.Count > 0)
            {
                // Draw standard edges
                var vBuff  = vertices.ToArray().ToArray();
                var vCount = vertices.Count;
                // var indices = Enumerable.Range(0, vCount).Select(i => (ushort)i).ToArray();
                var indices = new List <ushort>();
                for (var i = 0; i < vertices.Count; i += 2)
                {
                    indices.Add((ushort)i);
                    indices.Add((ushort)(i + 1));
                }
                var bbox = new BBox3(vertices.ToArray());
                gltf.AddLineLoop($"edge_{edgeCount}", buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), materials[BuiltInMaterials.Edges.Name], MeshPrimitive.ModeEnum.LINES, null);
            }

            if (verticesHighlighted.Count > 0)
            {
                // Draw highlighted edges
                var vBuff   = vertices.ToArray().ToArray();
                var vCount  = vertices.Count;
                var indices = new List <ushort>();
                for (var i = 0; i < vertices.Count; i += 2)
                {
                    indices.Add((ushort)i);
                    indices.Add((ushort)(i + 1));
                }
                var bbox = new BBox3(vertices.ToArray());
                gltf.AddLineLoop($"edge_{edgeCount}", buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), materials[BuiltInMaterials.EdgesHighlighted.Name], MeshPrimitive.ModeEnum.LINES, null);
            }

            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength = buffer.Count;
            gltf.Buffers    = new[] { buff };

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            gltf.SaveBinaryModel(buffer.ToArray(), path);
        }