public override Scene ImportFile(FileStream fileStream, string fileName) { var scene = new Scene(); var mesh = new Mesh(); scene.Meshes.Add(mesh); // Reading materials from PLY files is not supported yet. var material = new Material(); scene.Materials.Add(material); mesh.Material = material; // Create record for this object. var plyFile = new PlyFile(); // Read and parse the file's header. var reader = new StreamReader(fileName); string originalLine; string[] words = GetWords(reader, out originalLine); if (words == null || words[0] != "ply") throw new Exception("Missing header"); ParseHeader(reader, plyFile, words, originalLine); if (plyFile.FileType != PlyFileType.Ascii) throw new Exception("Binary files not currently supported"); // Go through each kind of element that we learned is in the file // and read them. foreach (var element in plyFile.Elements) { for (int i = 0; i < element.Num; i++) { words = GetWords(reader, out originalLine); if (words == null) throw new Exception("Unexpected end of file"); var elementValue = new PlyElementValue(); int whichWord = 0; foreach (var property in element.Properties) { int intVal; uint uintVal; double doubleVal; if (property.IsList) { GetAsciiItem(words[whichWord++], property.CountExternal, out intVal, out uintVal, out doubleVal); var listCount = intVal; for (int j = 0; j < listCount; j++) { var propertyValue = GetAsciiItem(words[whichWord++], property.ExternalType, out intVal, out uintVal, out doubleVal); elementValue.PropertyValues.Add(propertyValue); } } else { var propertyValue = GetAsciiItem(words[whichWord++], property.ExternalType, out intVal, out uintVal, out doubleVal); elementValue.PropertyValues.Add(propertyValue); } } element.ElementValues.Add(elementValue); } } // Now read vertex and face information. foreach (var element in plyFile.Elements) { switch (element.Name) { case "vertex" : int xIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "x")); int yIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "y")); int zIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "z")); int nxIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "nx")); int nyIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "ny")); int nzIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "nz")); int sIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "s")); int tIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "t")); foreach (var elementValue in element.ElementValues) { if (xIndex != -1 && yIndex != -1 && zIndex != -1) mesh.Positions.Add(new Point3D( (float) elementValue.PropertyValues[xIndex], (float) elementValue.PropertyValues[yIndex], (float) elementValue.PropertyValues[zIndex])); if (nxIndex != -1 && nyIndex != -1 && nzIndex != -1) mesh.Normals.Add(new Vector3D( (float) elementValue.PropertyValues[nxIndex], (float) elementValue.PropertyValues[nyIndex], (float) elementValue.PropertyValues[nzIndex])); if (sIndex != -1 && tIndex != -1) mesh.TextureCoordinates.Add(new Point3D( (float)elementValue.PropertyValues[sIndex], (float)elementValue.PropertyValues[tIndex], 0)); } break; case "face" : foreach (var elementValue in element.ElementValues) { if (elementValue.PropertyValues.Count != 3) throw new Exception("Only triangle faces are currently supported"); mesh.Indices.Add(Convert.ToInt32(elementValue.PropertyValues[0])); mesh.Indices.Add(Convert.ToInt32(elementValue.PropertyValues[1])); mesh.Indices.Add(Convert.ToInt32(elementValue.PropertyValues[2])); } break; } } reader.Close(); return scene; }
public override Scene ImportFile(FileStream fileStream, string fileName) { var scene = new Scene(); var mesh = new Mesh(); scene.Meshes.Add(mesh); // Reading materials from PLY files is not supported yet. var material = new Material(); scene.Materials.Add(material); mesh.Material = material; // Create record for this object. var plyFile = new PlyFile(); // Read and parse the file's header. var reader = new StreamReader(fileName); string originalLine; string[] words = GetWords(reader, out originalLine); if (words == null || words[0] != "ply") { throw new Exception("Missing header"); } ParseHeader(reader, plyFile, words, originalLine); if (plyFile.FileType != PlyFileType.Ascii) { throw new Exception("Binary files not currently supported"); } // Go through each kind of element that we learned is in the file // and read them. foreach (var element in plyFile.Elements) { for (int i = 0; i < element.Num; i++) { words = GetWords(reader, out originalLine); if (words == null) { throw new Exception("Unexpected end of file"); } var elementValue = new PlyElementValue(); int whichWord = 0; foreach (var property in element.Properties) { int intVal; uint uintVal; double doubleVal; if (property.IsList) { GetAsciiItem(words[whichWord++], property.CountExternal, out intVal, out uintVal, out doubleVal); var listCount = intVal; for (int j = 0; j < listCount; j++) { var propertyValue = GetAsciiItem(words[whichWord++], property.ExternalType, out intVal, out uintVal, out doubleVal); elementValue.PropertyValues.Add(propertyValue); } } else { var propertyValue = GetAsciiItem(words[whichWord++], property.ExternalType, out intVal, out uintVal, out doubleVal); elementValue.PropertyValues.Add(propertyValue); } } element.ElementValues.Add(elementValue); } } // Now read vertex and face information. foreach (var element in plyFile.Elements) { switch (element.Name) { case "vertex": int xIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "x")); int yIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "y")); int zIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "z")); int nxIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "nx")); int nyIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "ny")); int nzIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "nz")); int sIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "s")); int tIndex = element.Properties.IndexOf(element.Properties.SingleOrDefault(p => p.Name == "t")); foreach (var elementValue in element.ElementValues) { if (xIndex != -1 && yIndex != -1 && zIndex != -1) { mesh.Positions.Add(new Point3D( (float)elementValue.PropertyValues[xIndex], (float)elementValue.PropertyValues[yIndex], (float)elementValue.PropertyValues[zIndex])); } if (nxIndex != -1 && nyIndex != -1 && nzIndex != -1) { mesh.Normals.Add(new Vector3D( (float)elementValue.PropertyValues[nxIndex], (float)elementValue.PropertyValues[nyIndex], (float)elementValue.PropertyValues[nzIndex])); } if (sIndex != -1 && tIndex != -1) { mesh.TextureCoordinates.Add(new Point3D( (float)elementValue.PropertyValues[sIndex], (float)elementValue.PropertyValues[tIndex], 0)); } } break; case "face": foreach (var elementValue in element.ElementValues) { if (elementValue.PropertyValues.Count != 3) { throw new Exception("Only triangle faces are currently supported"); } mesh.Indices.Add(Convert.ToInt32(elementValue.PropertyValues[0])); mesh.Indices.Add(Convert.ToInt32(elementValue.PropertyValues[1])); mesh.Indices.Add(Convert.ToInt32(elementValue.PropertyValues[2])); } break; } } reader.Close(); return(scene); }