/// <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 );
            }
        }