Example #1
0
        public static void WriteFast(string path, StlModel model)
        {
            StringBuilder sb = new StringBuilder();

            var vertices = model.vertices;
            var normals  = model.normals;
            int tris     = model.normals.Count;

            sb.Append("solid ").Append(model.name);

            for (int i = 0; i < tris; i++)
            {
                var n = normals[i];
                sb.Append("\r\n").Append("   facet normal ").Append(n.x).Append(" ").Append(n.y).Append(" ").Append(n.z);
                sb.Append("\r\n").Append("      outer loop");
                for (int j = 0; j < 3; j++)
                {
                    var v = vertices[i * 3 + j];
                    sb.Append("\r\n").Append("         vertex ").Append(v.x).Append(" ").Append(v.y).Append(" ")
                    .Append(v.z);
                }
                sb.Append("\r\n").Append("      endloop");
                sb.Append("\r\n").Append("   endfacet");
            }

            sb.Append("\r\n endsolid");

            File.WriteAllText(path, sb.ToString());
        }
Example #2
0
        public static void Write(string path, StlModel model)
        {
            List <string> lines = new List <string>(1024);

            var vertices = model.vertices;
            var normals  = model.normals;
            int tris     = model.normals.Count;

            lines.Add($"solid {model.name}");

            for (int i = 0; i < tris; i++)
            {
                var n = normals[i].ToStringFull();
                lines.Add($"   facet normal {n}");
                lines.Add("      outer loop");
                for (int j = 0; j < 3; j++)
                {
                    lines.Add($"         vertex {vertices[i*3 + j].ToStringFull()}");
                }
                lines.Add("      endloop");
                lines.Add("   endfacet");
            }

            lines.Add("endsolid");

            File.WriteAllLines(path, lines);
        }
Example #3
0
        public static StlModel Read(string path)
        {
            var lines = File.ReadAllLines(path).Select(line => line.Trim()).ToArray();
            var name  = lines[0].Replace("solid ", "").Trim();

            List <Vector> vertices = new List <Vector>(1024);
            List <Vector> normals  = new List <Vector>(512);

            for (int i = 1; i < lines.Length; i += 7)
            {
                var line = lines[i].Replace("facet normal", "").Trim();

                if (line.Contains("endsolid"))
                {
                    // end of file
                    break;
                }

                var normal = Vector.Parse(line);
                normals.Add(normal);

                for (int j = i + 2; j < i + 5; j++)
                {
                    line = lines[j].Replace("vertex ", "").Trim();
                    var vertex = Vector.Parse(line);
                    vertices.Add(vertex);
                }
            }

            var model = new StlModel(name, vertices, normals);

            return(model);
        }
Example #4
0
        // Convert geometry from STL format to mesh format.
        public static Mesh StlModelToMesh(StlModel model)
        {
            var verts = model.vertices;
            var norms = model.normals;

            int triCount = model.TriangleCount;

            // Hashmap used to keep track of overlapping vertices and share them between triangles.
            Dictionary <Vector, int> hash = new Dictionary <Vector, int>();

            List <Vector> vertices = new List <Vector>();
            List <Vector> normals  = new List <Vector>();

            List <int> indices = new List <int>();

            for (int i = 0; i < triCount; i++)
            {
                var norm = norms[i].Normalized;
                for (int j = 0; j < 3; j++)
                {
                    var v = verts[i * 3 + j];
                    if (hash.TryGetValue(v, out var sharedIndex))
                    {
                        // An overlapping vertex had already been seen, use shared index.
                        indices.Add(sharedIndex);
                        // Accumulate normals of triangles using the same vertex
                        normals[sharedIndex] += norm;
                    }
                    else
                    {
                        // New vertex
                        int index = vertices.Count;
                        vertices.Add(v);
                        normals.Add(norm);
                        indices.Add(index);
                        hash.Add(v, index);
                    }
                }
            }

            // Normalize the accumulated normal for each vertex, not the most accurate solution but okay in this case.
            for (int i = 0; i < normals.Count; i++)
            {
                normals[i] = normals[i].Normalized;
            }

            var mesh = new Mesh(model.name, vertices, normals, indices);

            return(mesh);
        }
Example #5
0
        // Convert geometry from mesh format to STL format.
        public static StlModel MeshToStlModel(Mesh mesh)
        {
            var triCount = mesh.TriangleCount;

            List <Vector> vertices = new List <Vector>();
            List <Vector> normals  = new List <Vector>();

            for (int i = 0; i < triCount; i++)
            {
                var i0 = mesh.indices[i * 3 + 0];
                var i1 = mesh.indices[i * 3 + 1];
                var i2 = mesh.indices[i * 3 + 2];

                var v0 = mesh.vertices[i0];
                var v1 = mesh.vertices[i1];
                var v2 = mesh.vertices[i2];

                var n0 = mesh.normals[i0];
                var n1 = mesh.normals[i1];
                var n2 = mesh.normals[i2];

                vertices.Add(v0);
                vertices.Add(v1);
                vertices.Add(v2);

                var nMean = (n0 + n1 + n2).Normalized;

                var r1 = (v1 - v0).Normalized;
                var r2 = (v2 - v0).Normalized;

                // Normal of the triangle is either nCross or -nCross but we are not sure about the r1 and r2 direction
                // at this point. Compare with the mean normal of corner vertices to deduce the direction.
                var nCross = Vector.Cross(r1, r2);

                var dot = Vector.Dot(nCross, nMean);

                var n = dot > 0 ? nCross : -nCross;

                normals.Add(n.Normalized);
            }

            var stlModel = new StlModel(mesh.name, vertices, normals);

            return(stlModel);
        }