/// <summary> /// Save mesh in binary .STL file /// </summary> /// <param name="mesh">Calculated mesh object</param> /// <param name="writer">Binary file writer</param> /// <param name="flipYZ">Flag to determine whether the Y and Z values are flipped on save</param> private static void SaveBinarySTLMesh( Mesh mesh, BinaryWriter writer, bool flipYZ = true ) { var vertices = mesh.GetVertices(); var normals = mesh.GetNormals(); var indices = mesh.GetTriangleIndexes(); // Check mesh arguments if ( 0 == vertices.Count || 0 != vertices.Count % 3 || vertices.Count != indices.Count ) { throw new ArgumentException( "不正なメッシュです" ); } char[] header = new char[80]; writer.Write( header ); // Write number of triangles int triangles = vertices.Count / 3; writer.Write( triangles ); // Sequentially write the normal, 3 vertices of the triangle and attribute, for each triangle for ( int i = 0; i < triangles; i++ ) { // Write normal var normal = normals[i * 3]; writer.Write( normal.X ); writer.Write( flipYZ ? -normal.Y : normal.Y ); writer.Write( flipYZ ? -normal.Z : normal.Z ); // Write vertices for ( int j = 0; j < 3; j++ ) { var vertex = vertices[(i * 3) + j]; writer.Write( vertex.X ); writer.Write( flipYZ ? -vertex.Y : vertex.Y ); writer.Write( flipYZ ? -vertex.Z : vertex.Z ); } ushort attribute = 0; writer.Write( attribute ); } }
/// <summary> /// Save mesh in ASCII Wavefront .OBJ file /// </summary> /// <param name="mesh">Calculated mesh object</param> /// <param name="writer">Stream writer</param> /// <param name="flipYZ">Flag to determine whether the Y and Z values are flipped on save</param> private static void SaveAsciiObjMesh( Mesh mesh, StreamWriter writer, bool flipYZ = true ) { var vertices = mesh.GetVertices(); var normals = mesh.GetNormals(); var indices = mesh.GetTriangleIndexes(); // Check mesh arguments if ( 0 == vertices.Count || 0 != vertices.Count % 3 || vertices.Count != indices.Count ) { throw new ArgumentException( "不正なメッシュです" ); } // Write the header lines writer.WriteLine( "#" ); writer.WriteLine( "# OBJ file created by Microsoft Kinect Fusion" ); writer.WriteLine( "#" ); // Sequentially write the 3 vertices of the triangle, for each triangle for ( int i = 0; i < vertices.Count; i++ ) { var vertex = vertices[i]; string vertexString = "v " + vertex.X.ToString( CultureInfo.CurrentCulture ) + " "; if ( flipYZ ) { vertexString += (-vertex.Y).ToString( CultureInfo.CurrentCulture ) + " " + (-vertex.Z).ToString( CultureInfo.CurrentCulture ); } else { vertexString += vertex.Y.ToString( CultureInfo.CurrentCulture ) + " " + vertex.Z.ToString( CultureInfo.CurrentCulture ); } writer.WriteLine( vertexString ); } // Sequentially write the 3 normals of the triangle, for each triangle for ( int i = 0; i < normals.Count; i++ ) { var normal = normals[i]; string normalString = "vn " + normal.X.ToString( CultureInfo.CurrentCulture ) + " "; if ( flipYZ ) { normalString += (-normal.Y).ToString( CultureInfo.CurrentCulture ) + " " + (-normal.Z).ToString( CultureInfo.CurrentCulture ); } else { normalString += normal.Y.ToString( CultureInfo.CurrentCulture ) + " " + normal.Z.ToString( CultureInfo.CurrentCulture ); } writer.WriteLine( normalString ); } // Sequentially write the 3 vertex indices of the triangle face, for each triangle // Note this is typically 1-indexed in an OBJ file when using absolute referencing! for ( int i = 0; i < vertices.Count / 3; i++ ) { string baseIndex0 = ((i * 3) + 1).ToString( CultureInfo.CurrentCulture ); string baseIndex1 = ((i * 3) + 2).ToString( CultureInfo.CurrentCulture ); string baseIndex2 = ((i * 3) + 3).ToString( CultureInfo.CurrentCulture ); string faceString = "f " + baseIndex0 + "//" + baseIndex0 + " " + baseIndex1 + "//" + baseIndex1 + " " + baseIndex2 + "//" + baseIndex2; writer.WriteLine( faceString ); } }