public SySal.Imaging.Grain3D[] ReadGrains()
 {
     System.IO.StreamReader r = null;
     try
     {
         r = new System.IO.StreamReader(GrainFileName);
         string line;
         System.Collections.ArrayList a = new System.Collections.ArrayList();
         while ((line = r.ReadLine()) != null)
         {
             System.Text.RegularExpressions.Match m = rx_Grains.Match(line);
             if (m.Success && m.Index == 0 && m.Length == line.Length)
             {
                 SySal.Imaging.Grain3D g = new SySal.Imaging.Grain3D();
                 g.Clusters       = new SySal.Imaging.Cluster3D[0];
                 g.Volume         = uint.Parse(m.Groups["VOLUME"].Value);
                 g.FirstLayer     = uint.Parse(m.Groups["FIRSTLAYER"].Value);
                 g.LastLayer      = uint.Parse(m.Groups["LASTLAYER"].Value);
                 g.Position.X     = double.Parse(m.Groups["X"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.Position.Y     = double.Parse(m.Groups["Y"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.Position.Z     = double.Parse(m.Groups["Z"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.Tangent.X      = double.Parse(m.Groups["TANX"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.Tangent.Y      = double.Parse(m.Groups["TANY"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.Tangent.Z      = double.Parse(m.Groups["TANZ"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.TopExtent.X    = double.Parse(m.Groups["TX"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.TopExtent.Y    = double.Parse(m.Groups["TY"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.TopExtent.Z    = double.Parse(m.Groups["TZ"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.BottomExtent.X = double.Parse(m.Groups["BX"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.BottomExtent.Y = double.Parse(m.Groups["BY"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 g.BottomExtent.Z = double.Parse(m.Groups["BZ"].Value, System.Globalization.CultureInfo.InvariantCulture);
                 a.Add(g);
             }
         }
         Grains = (uint)a.Count;
         return((SySal.Imaging.Grain3D[])a.ToArray(typeof(SySal.Imaging.Grain3D)));
     }
     finally
     {
         if (r != null)
         {
             r.Close();
         }
     }
 }
 public void WriteGrains(SySal.Imaging.Grain3D[] grs)
 {
     System.IO.StreamWriter w = null;
     try
     {
         w = new System.IO.StreamWriter(GrainFileName);
         w.WriteLine("SEQUENCE\tFRAME0X\tFRAME0Y\tFRAME0Z\tTOTAL\tID\tVOLUME\tFIRSTLAYER\tLASTLAYER\tX\tY\tZ\tTANX\tTANY\tTANZ\tTX\tTY\tTZ\tBX\tBY\tBZ");
         int i;
         for (i = 0; i < grs.Length; i++)
         {
             SySal.Imaging.Grain3D g = grs[i];
             w.WriteLine(Id + "\t" +
                         Layers[0].Position.X.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         Layers[0].Position.Y.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         Layers[0].Position.Z.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         grs.Length + "\t" + i + "\t" +
                         g.Volume + "\t" + g.FirstLayer + "\t" + g.LastLayer + "\t" +
                         g.Position.X.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.Position.Y.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.Position.Z.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.Tangent.X.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.Tangent.Y.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.Tangent.Z.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.TopExtent.X.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.TopExtent.Y.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.TopExtent.Z.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.BottomExtent.X.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.BottomExtent.Y.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "\t" +
                         g.BottomExtent.Z.ToString("F2", System.Globalization.CultureInfo.InvariantCulture));
         }
         w.Flush();
         w.Close();
         this.Grains = (uint)grs.Length;
     }
     finally
     {
         if (w != null)
         {
             w.Close();
         }
     }
 }