public override void Import(ref MeshModel mesh) { using (BufferedStream sr = new BufferedStream(File.OpenRead(mesh.FilePath))) { int byteCount; PlyObjectHeader headerObj = this.GetPlyObjectHeader(sr, out byteCount); sr.Position = byteCount; switch (headerObj.Format) { case PlyFormat.ascii: this.ParserASCII(headerObj, sr, ref mesh); break; case PlyFormat.binary_big_endian: using (EndianessBinaryReader br = new EndianessBinaryReader(sr, Endianess.BigEndian)) { this.ParserBinary(headerObj, br, ref mesh); } break; case PlyFormat.binary_little_endian: using (EndianessBinaryReader br = new EndianessBinaryReader(sr, Endianess.LittleEndian)) { this.ParserBinary(headerObj, br, ref mesh); } break; default: throw new FormatException("Invalid File format!"); break; } } }
private PlyObjectHeader GetPlyObjectHeader(Stream sr, out int byteCount) { PlyObjectHeader headerObj = new PlyObjectHeader(); int lineByteCount; string line = Extensions.ReadLine(sr, out lineByteCount); byteCount = lineByteCount; if (line.ToLower() != "ply") { throw new ArgumentException("Invalid file format. PLY indentifier expected in header file."); } String[] lineSplits; while (line.ToLower() != "end_header") { line = Extensions.ReadLine(sr, out lineByteCount); byteCount += lineByteCount; lineSplits = line.Trim().Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries); switch (lineSplits[0]) { case "format": lineSplits = lineSplits[1].Split(' '); headerObj.Format = (PlyFormat)Enum.Parse(typeof(PlyFormat), lineSplits[0]); NumberFormatInfo nfi = new NumberFormatInfo(); nfi.NumberDecimalSeparator = "."; nfi.NumberGroupSeparator = ","; headerObj.Vesion = float.Parse(lineSplits[1], nfi); break; case "comment": headerObj.Comments.Add(lineSplits[1]); break; case "element": lineSplits = lineSplits[1].Split(' '); ElementDescription element = new ElementDescription(lineSplits[0].ToLower(), Convert.ToInt32(lineSplits[1])); headerObj.Elements.Add(element); break; case "property": lineSplits = lineSplits[1].Split(' '); PropertyType pType = (PropertyType)Enum.Parse(typeof(PropertyType), lineSplits[0]); String pName = lineSplits[lineSplits.Length - 1]; PropertyDescription property = new PropertyDescription(pType, pName); if (pType == PropertyType.list) { property.CountType = (PropertyType)Enum.Parse(typeof(PropertyType), lineSplits[1]); property.TypeOfList = (PropertyType)Enum.Parse(typeof(PropertyType), lineSplits[2]); } headerObj.Elements[headerObj.Elements.Count - 1].Properties.Add(property); break; } } return(headerObj); }
private MeshModel ParserBinary(PlyObjectHeader header, BinaryReader ebr, ref MeshModel mesh) { //MeshModel mesh = new MeshModel(header.Elements["face"].Count * 3, header.Elements["vertex"].Count); //for (int i = 0; i < header.Elements.Count; i++) //{ // ElementDescription element = header.Elements[i]; // for (int e = 0; e < element.Count; e++) // { // for (int p = 0; p < element.Properties.Count; p++) // { // PropertyDescription property = element.Properties[p]; // if (property.IsList) // { // int listCount = 0; // if (property.CountType == PropertyType.uchar || property.CountType == PropertyType.uint8) // { // listCount = ebr.ReadByte(); // } // else // { // throw new ArgumentException("The type expected for List Count is 'uchar'. Type in file: '" + property.CountType + "'"); // } // if (property.TypeOfList == PropertyType.@int || property.TypeOfList == PropertyType.int32) // { // if (element.Name == "face") // { // for (int j = 0; j < listCount; j += 3) // { // mesh.Indices[e] = ebr.ReadInt32(); // mesh.Indices[e + 1] = ebr.ReadInt32(); // mesh.Indices[e + 2] = ebr.ReadInt32(); // int percent = (int)(((float)e / mesh.Indices.Length) * 100.0f); // if ((percent % 20) == 0) // { // this.OnElementLoaded(percent, ElementMesh.VextexIndice); // } // } // } // else if (element.Name == "vertex") // { // #region Ignore other properties for vertex // for (int j = 0; j < listCount; j += 3) // { // ebr.ReadInt32(); // ebr.ReadInt32(); // ebr.ReadInt32(); // } // #endregion // } // } // else // { // throw new ArgumentException("The type expected for List elements is 'int'. Type in file: '" + property.TypeOfList + "'"); // } // } // else // { // if (element.Name == "face") // { // #region Ignore other properties for face // switch (property.Type) // { // case PropertyType.@char: // case PropertyType.int8: // ebr.ReadSByte(); // break; // case PropertyType.uchar: // case PropertyType.uint8: // ebr.ReadByte(); // break; // case PropertyType.@short: // case PropertyType.int16: // ebr.ReadInt16(); // break; // case PropertyType.@ushort: // case PropertyType.uint16: // ebr.ReadUInt16(); // break; // case PropertyType.@int: // case PropertyType.int32: // ebr.ReadInt32(); // break; // case PropertyType.@uint: // case PropertyType.uint32: // ebr.ReadUInt32(); // break; // case PropertyType.@float: // case PropertyType.float32: // ebr.ReadSingle(); // break; // case PropertyType.@double: // case PropertyType.float64: // ebr.ReadDouble(); // break; // default: // break; // } // #endregion // } // else if (element.Name == "vertex") // { // switch (property.Type) // { // case PropertyType.@char: // case PropertyType.int8: // ebr.ReadSByte(); // break; // case PropertyType.uchar: // case PropertyType.uint8: // ebr.ReadByte(); // break; // case PropertyType.@short: // case PropertyType.int16: // ebr.ReadInt16(); // break; // case PropertyType.@ushort: // case PropertyType.uint16: // ebr.ReadUInt16(); // break; // case PropertyType.@int: // case PropertyType.int32: // ebr.ReadInt32(); // break; // case PropertyType.@uint: // case PropertyType.uint32: // ebr.ReadUInt32(); // break; // case PropertyType.@float: // case PropertyType.float32: // mesh.Vertices[e].Position.X = ebr.ReadSingle(); // mesh.Vertices[e].Position.Y = ebr.ReadSingle(); // mesh.Vertices[e].Position.Z = ebr.ReadSingle(); // p += 2; // //Adjusting BoundBox... // mesh.BoundBox.Include(mesh.Vertices[e].Position); // //Reporting progress // int percent = (int)(((float)e / mesh.Vertices.Length) * 100.0f); // if ((percent % 20) == 0) // { // this.OnElementLoaded(percent, ElementMesh.Vertex); // } // break; // case PropertyType.@double: // case PropertyType.float64: // ebr.ReadDouble(); // break; // default: // break; // } // } // } // } // } //} //GC.Collect(); //ForceGenerateNormals(mesh); //return mesh; return(null); }
private void ParserASCII(PlyObjectHeader header, Stream sr, ref MeshModel mesh) { MeshVertex[] vertices = new MeshVertex[header.Elements["vertex"].Count]; int[] indices = new int[header.Elements["face"].Count * 3]; NumberFormatInfo nfi = new NumberFormatInfo(); nfi.NumberDecimalSeparator = "."; nfi.NumberGroupSeparator = ","; //Initialize bound box calculation String[] str; //for number of vertices readed in header do... BoundBox boundBox = new BoundBox(); for (int i = 0; i < vertices.Length; i++) { str = sr.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); vertices[i].Position = new Point3D(float.Parse(str[0], nfi), float.Parse(str[1], nfi), float.Parse(str[2], nfi)); //Adjusting BoundBox... boundBox.Include(vertices[i].Position); //Reporting progress int percent = (int)(((float)i / vertices.Length) * 100.0f); if ((percent % 20) == 0) { this.OnElementLoaded(percent, ElementMesh.Vertex); } } //MeshModel mesh = new MeshModel(header.Elements["face"].Count); mesh.Triangles = new MeshTriangle[header.Elements["face"].Count]; mesh.BoundBox = boundBox; for (int i = 0, ptr = 0; i < mesh.Triangles.Length; i++) { str = sr.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); indices[ptr++] = Int32.Parse(str[1], nfi); mesh.Triangles[i].Vertex1 = vertices[indices[ptr - 1]]; indices[ptr++] = Int32.Parse(str[2], nfi); mesh.Triangles[i].Vertex2 = vertices[indices[ptr - 1]]; indices[ptr++] = Int32.Parse(str[3], nfi); mesh.Triangles[i].Vertex3 = vertices[indices[ptr - 1]]; int percent = (int)(((float)i / indices.Length) * 100.0f); if ((percent % 20) == 0) { this.OnElementLoaded(percent, ElementMesh.VextexIndice); } } int verticesCount = vertices.Length; vertices = null; GC.Collect(); GC.WaitForPendingFinalizers(); ProcessNormalsPerVertex(indices, ref mesh, verticesCount); indices = null; GC.Collect(); GC.WaitForPendingFinalizers(); }