/// <summary>
        /// Returns a single TiltBrushMesh instance created from all passed in
        /// </summary>
        /// <param name="meshes">Instances to merge</param>
        /// <returns></returns>
        public static TiltBrushMesh FromMeshes(TiltBrushMesh[] meshes)
        {
            TiltBrushMesh destinationMesh = new TiltBrushMesh();

            if (meshes.Length > 0)
            {
                destinationMesh.Name      = meshes[0].Name;
                destinationMesh.BrushName = meshes[0].BrushName;
                destinationMesh.BrushGuid = meshes[0].BrushGuid;
                for (int i = 0; i < meshes.Length; i++)
                {
                    var mesh = meshes[i];
                    if (i == 0)
                    {
                        //if the first item in the list, instantiate the destination object properties with mesh properties
                        destinationMesh.v   = mesh.v;
                        destinationMesh.n   = mesh.n;
                        destinationMesh.uv0 = mesh.uv0;
                        destinationMesh.uv1 = mesh.uv1;
                        destinationMesh.c   = mesh.c;
                        destinationMesh.t   = mesh.t;
                        destinationMesh.tri = mesh.tri;
                    }
                    else
                    {
                        int offset = destinationMesh.v.Length;
                        destinationMesh.v   = destinationMesh.v.ExtendArray(mesh.v);
                        destinationMesh.n   = destinationMesh.n.ExtendArray(mesh.n);
                        destinationMesh.uv0 = destinationMesh.uv0.ExtendArray(mesh.uv0);
                        if (destinationMesh.uv1 != null)
                        {
                            destinationMesh.uv1 = destinationMesh.uv1.ExtendArray(mesh.uv1);
                        }
                        destinationMesh.c   = destinationMesh.c.ExtendArray(mesh.c);
                        destinationMesh.t   = destinationMesh.t.ExtendArray(mesh.t);
                        destinationMesh.tri = destinationMesh.tri.ExtendArray(mesh.tri.Select(t => new Tuple <int, int, int>(t.Item1 + offset, t.Item2 + offset, t.Item3 + offset)).ToArray());
                    }
                }
            }
            else
            {
                throw new ArgumentException("Empty array passed");
            }
            return(destinationMesh);
        }
 /// <summary>
 /// returns an array of TiltBrushMesh instances, parsed from the .json export from Tilt Brush
 /// </summary>
 /// <param name="filePath">Path to .json file</param>
 /// <returns></returns>
 public static TiltBrushMesh[] FromFile(string filePath)
 {
     TiltBrushMesh[] meshes = null;
     if (File.Exists(filePath))
     {
         string json = File.ReadAllText(filePath);
         JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
         jsonSerializer.MaxJsonLength = Int32.MaxValue;
         JsonHolder items = jsonSerializer.Deserialize <JsonHolder>(json);
         meshes = new TiltBrushMesh[items.strokes.Length];
         int count = 0;
         foreach (var stroke in items.strokes)
         {
             TiltBrushMesh mesh  = new TiltBrushMesh();
             var           brush = items.brushes[stroke.brush];
             mesh.BrushName = brush.name;
             mesh.BrushGuid = brush.guid;
             //num verts gets set when parsing the vertices information and is then used to parse the remainder of the information
             int numVerts = 0;
             mesh.v        = GetInfo("v", stroke.v, ref numVerts);
             mesh.n        = GetInfo("n", stroke.n, ref numVerts);
             mesh.uv0      = Get4TupleInfo("uv0", stroke.uv0, ref numVerts);
             mesh.uv1      = Get4TupleInfo("uv1", stroke.uv1, ref numVerts);
             mesh.c        = GetIntInfo("c", stroke.c, ref numVerts);
             mesh.t        = Get4TupleInfo("t", stroke.t, ref numVerts);
             mesh.tri      = GetIntTupleInfo("tri", stroke.tri, ref numVerts);
             meshes[count] = mesh;
             count++;
         }
     }
     else
     {
         throw new FileNotFoundException("No file found at " + filePath);
     }
     return(meshes);
 }