public IOWriteResult Write(BinaryWriter writer, List <WriteMesh> vMeshes, WriteOptions options) { string header = "g3sharp_stl "; byte[] header_bytes = ASCIIEncoding.ASCII.GetBytes(header); byte[] stl_header = new byte[80]; Array.Clear(stl_header, 0, stl_header.Length); Array.Copy(header_bytes, stl_header, header_bytes.Length); writer.Write(stl_header); int total_tris = 0; foreach (WriteMesh mesh in vMeshes) { total_tris += mesh.Mesh.TriangleCount; } writer.Write(total_tris); for (int mi = 0; mi < vMeshes.Count; ++mi) { IMesh mesh = vMeshes[mi].Mesh; if (options.ProgressFunc != null) { options.ProgressFunc(mi, vMeshes.Count - 1); } Func <int, stl_triangle> producerF = (ti) => { var tri = new stl_triangle(); Index3i t = mesh.GetTriangle(ti); Vector3d a = mesh.GetVertex(t.a), b = mesh.GetVertex(t.b), c = mesh.GetVertex(t.c); Vector3d n = MathUtil.Normal(a, b, c); tri.nx = (float)n.x; tri.ny = (float)n.y; tri.nz = (float)n.z; tri.ax = (float)a.x; tri.ay = (float)a.y; tri.az = (float)a.z; tri.bx = (float)b.x; tri.by = (float)b.y; tri.bz = (float)b.z; tri.cx = (float)c.x; tri.cy = (float)c.y; tri.cz = (float)c.z; tri.attrib = 0; return(tri); }; Action <stl_triangle> consumerF = (tri) => { byte[] tri_bytes = Util.StructureToByteArray(tri); writer.Write(tri_bytes); }; var stream = new ParallelStream <int, stl_triangle>(); stream.ProducerF = producerF; stream.ConsumerF = consumerF; // parallel version is slower =\ //stream.Run_Thread(mesh.TriangleIndices()); stream.Run(mesh.TriangleIndices()); } return(new IOWriteResult(IOCode.Ok, "")); }