title: Reading binary PLY file face indices using C#
body: <p>I am reading .ply binary file using this project:
  <a href="https://github.com/Zarbuz/FileToVox/blob/2064dcf99532e9c22748afb8e1a3755c1e5dfb81/SchematicToVoxCore/Converter/PLYToSchematic.cs" rel="nofollow noreferrer">https://github.com/Zarbuz/FileToVox/blob/2064dcf99532e9c22748afb8e1a3755c1e5dfb81/SchematicToVoxCore/Converter/PLYToSchematic.cs</a></p>
  
  <p>It works for reading points and their colors.
  But I do not understand how to retrieve the list of mesh faces indices.</p>
  
  <p>In the function ReadDataHeaders I successuflly retrieve the number of faces:</p>
  
  <pre><code> private static DataHeader ReadDataHeader(StreamReader reader) {
   ...
                  if (col[0] == "element") {
                      if (col[1] == "vertex") {
                          data.vertexCount = Convert.ToInt32(col[2]);
                          skip = false;
                      } else if (col[1] == "face") {
                          data.faceCount = Convert.ToInt32(col[2]);
                          skip = false;
                      } else {
                          // Don't read elements other than vertices.
                          skip = true;
                      }
                  }
  
  ...
  }
  </code></pre>
  
  <p>But what I do not understand is how retrieve the mesh face indices in the function ReadDataBodyBoundary.
  I do not also understand how the BinaryReader works in this function, how does it reads the each line of binary form for mesh faces vertex indices.</p>
  
  <pre><code> private static DataBody ReadDataBodyBinary(DataHeader header, BinaryReader reader) {
              DataBody data = new DataBody(header.vertexCount,header.faceCount);
  
              float x = 0, y = 0, z = 0;
              byte r = 255, g = 255, b = 255, a = 255;
              int f0 = 0, f1 = 0, f2 = 0;
  
              //for(int i = 0; i &lt; header.faceCount; i++) {
              //    //foreach(var face in )
              //    int faceVertex = reader.ReadInt32();
              //    Console.WriteLine();
              //}
              //reader.BaseStream.Position = readCount;
              Console.WriteLine("Number of properties:   " + header.properties.Count().ToString());
              for (int i = 0; i &lt; header.vertexCount; i++) {
                  foreach (DataProperty prop in header.properties) {//iterate six properties
                      //Console.WriteLine(prop.ToString());
                      switch (prop) {
                          case DataProperty.R8:
                          r = reader.ReadByte();
                          break;
                          case DataProperty.G8:
                          g = reader.ReadByte();
                          break;
                          case DataProperty.B8:
                          b = reader.ReadByte();
                          break;
                          case DataProperty.A8:
                          a = reader.ReadByte();
                          break;
  
                          case DataProperty.R16:
                          r = (byte)(reader.ReadUInt16() &gt;&gt; 8);
                          break;
                          case DataProperty.G16:
                          g = (byte)(reader.ReadUInt16() &gt;&gt; 8);
                          break;
                          case DataProperty.B16:
                          b = (byte)(reader.ReadUInt16() &gt;&gt; 8);
                          break;
                          case DataProperty.A16:
                          a = (byte)(reader.ReadUInt16() &gt;&gt; 8);
                          break;
  
                          case DataProperty.SingleX:
                          x = reader.ReadSingle();
                          break;
                          case DataProperty.SingleY:
                          y = reader.ReadSingle();
                          break;
                          case DataProperty.SingleZ:
                          z = reader.ReadSingle();
                          break;
  
                          case DataProperty.DoubleX:
                          x = (float)reader.ReadDouble();
                          break;
                          case DataProperty.DoubleY:
                          y = (float)reader.ReadDouble();
                          break;
                          case DataProperty.DoubleZ:
                          z = (float)reader.ReadDouble();
                          break;
  
                          case DataProperty.Data8:
                          reader.ReadByte();
                          break;
                          case DataProperty.Data16:
                          reader.BaseStream.Position += 2;
                          break;
                          case DataProperty.Data32:
                          reader.BaseStream.Position += 4;
                          break;
                          case DataProperty.Data64:
                          reader.BaseStream.Position += 8;
                          break;
                      }
                  }
  
                  data.AddPoint(x, y, z, r, g, b);
              }
  
              return data;
          }
  </code></pre>