static void WritePlyExample(string filename) { Geometry cube = MakeCubeGeometry(); { PlyFile cubeFile = new PlyFile(); byte[] verticesbytes = new byte[cube.vertices.Count * sizeof(float)]; System.Buffer.BlockCopy(cube.vertices.ToArray(), 0, verticesbytes, 0, verticesbytes.Length); cubeFile.AddPropertiesToElement("vertex", new List <string> { "x", "y", "z" }, TinyplyCSharp.Type.FLOAT32, cube.vertices.Count / 3, verticesbytes, TinyplyCSharp.Type.INVALID, 0); byte[] normalbytes = new byte[cube.normals.Count * sizeof(float)]; System.Buffer.BlockCopy(cube.normals.ToArray(), 0, normalbytes, 0, normalbytes.Length); cubeFile.AddPropertiesToElement("vertex", new List <string> { "nx", "ny", "nz" }, TinyplyCSharp.Type.FLOAT32, cube.normals.Count / 3, normalbytes, TinyplyCSharp.Type.INVALID, 0); byte[] trianglebytes = new byte[cube.triangles.Count * sizeof(int)]; System.Buffer.BlockCopy(cube.triangles.ToArray(), 0, trianglebytes, 0, trianglebytes.Length); cubeFile.AddPropertiesToElement("face", new List <string> { "vertex_indices" }, TinyplyCSharp.Type.UINT32, cube.triangles.Count / 3, trianglebytes, TinyplyCSharp.Type.UINT8, 3); cubeFile.GetComments().Add("generated by tinyply 2.3"); using (FileStream outStream = File.Open(filename + "-ascii.ply", FileMode.Create)) { cubeFile.Write(outStream, false); } using (FileStream outStream = File.Open(filename + "-binary.ply", FileMode.Create)) { cubeFile.Write(outStream, true); } } }
private void AddVertexElement(PlyFile plyFile, Mesh mesh) { int index = 0; var vertexElements = new PlyElement(PlyKeywords.Vertex, mesh.Points.Count); foreach (var name in new List <string>() { PlyKeywords.X, PlyKeywords.Y, PlyKeywords.Z }) { AddVertexProperty(vertexElements, name, index++); } if (mesh.ContainsNormals) { foreach (var name in new List <string>() { PlyKeywords.NormalX, PlyKeywords.NormalY, PlyKeywords.NormalZ }) { AddVertexProperty(vertexElements, name, index++); } } if (mesh.ContainsColors) { foreach (var name in new List <string>() { PlyKeywords.Red, PlyKeywords.Green, PlyKeywords.Blue, PlyKeywords.Alpha }) { AddColorProperty(vertexElements, name, index++); } } plyFile.Elements.Add(vertexElements); }
public override Task <Scene> ImportFileImpl(string filePath) { return(Task.Run(() => { var mesh = new Mesh(); var scene = new Scene(); scene.Meshes.Add(mesh); var headerParser = new PlyHeaderReaderWriter(); PlyFile plyFile = headerParser.ReadFileStructure(filePath); if (plyFile.Header.PlyFileFormat == PlyFileFormat.BinaryBigEndian) { throw new Exception($"{nameof(PlyFileFormat.BinaryBigEndian)} format is not currently supported"); } using var elementReadWriter = PlyReaderWriterFactory.GetReaderWriter(plyFile, OperationType.Import); BuildElements(elementReadWriter, plyFile); BuildMeshStructure(mesh, plyFile); return scene; })); }
public PlyFile ReadFileStructure(string filePath) { var plyFile = new PlyFile(filePath); var header = new PlyHeader(File.ReadLines(filePath).TakeUntilIncluding(x => x == PlyKeywords.EndHeader).ToList()); plyFile.Header = header; foreach (var line in header.HeaderLines) { var tokens = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); switch (tokens[0]) { case PlyKeywords.Format: { if (tokens.Length != 3) { throw new Exception("Invalid header - format is invalid"); } plyFile.Header.PlyFileFormat = (tokens[1]) switch { PlyKeywords.Ascii => PlyFileFormat.Ascii, PlyKeywords.BinaryLittleEndian => PlyFileFormat.BinaryLittleEndian, PlyKeywords.BinaryBigEndian => PlyFileFormat.BinaryBigEndian, _ => throw new Exception("Invalid header - format is invalid"), }; plyFile.Header.Version = Convert.ToSingle(tokens[2]); break; } case PlyKeywords.Element: { AddElement(plyFile, tokens); break; } case PlyKeywords.Property: { AddProperty(plyFile, tokens); break; } case PlyKeywords.Comment: { AddComment(plyFile, line); break; } case PlyKeywords.ObjectInfo: { AddObjectInfo(plyFile, line); break; } case PlyKeywords.EndHeader: { return(plyFile); } } } return(plyFile); }
private void AddElement(PlyFile plyFile, string[] tokens) { plyFile.Elements.Add(new PlyElement(tokens[1], Convert.ToInt32(tokens[2]))); }
public void Import(string filename) { PlyFile ply = LoadPly(filename); CreateTextures(ply.body.vertices, ply.body.colors); }
private bool ParsePlyFile(string filepath) { var contents = File.ReadAllBytes(filepath); var sizemb = contents.Length * 1e-6; PlyFile file = new PlyFile(); var ms = new MemoryStream(contents); bool headerResult = file.ParseHeader(ms); // All ply files are required to have a vertex element Dictionary <string, PlyData> vertexElement = new Dictionary <string, PlyData>(); Console.WriteLine("Testing: " + filepath + " - filetype: " + (file.IsBinaryFile() ? "binary" : "ascii")); Assert.IsTrue(file.GetElements().Count > 0); string likelyFacePropertyName = null; // Extract a fat vertex structure (will likely include more than xyz) foreach (var e in file.GetElements()) { if (e.Name == "vertex") { Assert.IsTrue(e.Properties.Count > 0); foreach (var p in e.Properties) { try { vertexElement.Add(p.Name, file.RequestPropertiesFromElement(e.Name, new List <string> { p.Name })); } catch { } } } // Heuristic... if (e.Name == "face" || e.Name == "tristrips") { for (int i = 0; i < 1; ++i) { likelyFacePropertyName = e.Properties[i].Name; } } } PlyData faces, tripstrip; if (!string.IsNullOrEmpty(likelyFacePropertyName)) { try { faces = file.RequestPropertiesFromElement("face", new List <string> { likelyFacePropertyName }, 0); } catch { } try { tripstrip = file.RequestPropertiesFromElement("tristrips", new List <string> { likelyFacePropertyName }, 0); } catch { } } Stopwatch sw = new Stopwatch(); sw.Start(); file.Read(ms); sw.Stop(); Console.WriteLine("\tparsing " + sizemb + "mb in " + sw.ElapsedMilliseconds + " ms"); foreach (var p in vertexElement) { Assert.IsTrue(p.Value.Count > 0); foreach (var e in file.GetElements()) { foreach (var prop in e.Properties) { if (e.Name == "vertex" && prop.Name == p.Key) { Assert.IsTrue(e.Size == p.Value.Count); } } } } sw.Restart(); TranscodePlyFile(file, filepath); sw.Stop(); Console.WriteLine("\ttranscoded in " + sw.ElapsedMilliseconds + " ms"); return(headerResult); }
private void AddComments(PlyFile plyFile, Mesh mesh) { plyFile.Comments = GetBanner(mesh); }
private void BuildMeshStructure(Mesh mesh, PlyFile plyFile) { foreach (var element in plyFile.Elements) { var indexes = PropertyIndexRetreiver.GetPropertyIndexes(element.Properties); switch (element.Name) { case PlyKeywords.Vertex: { foreach (var elementValue in element.ElementValues) { if (indexes.X != -1 && indexes.Y != -1 && indexes.Z != -1) { mesh.Points.Add(new Vector3( Convert.ToSingle(elementValue.PropertyValues[indexes.X]), Convert.ToSingle(elementValue.PropertyValues[indexes.Y]), Convert.ToSingle(elementValue.PropertyValues[indexes.Z]))); } if (indexes.Nx != -1 && indexes.Ny != -1 && indexes.Nz != -1) { mesh.Normals.Add(new Vector3( Convert.ToSingle(elementValue.PropertyValues[indexes.Nx]), Convert.ToSingle(elementValue.PropertyValues[indexes.Ny]), Convert.ToSingle(elementValue.PropertyValues[indexes.Nz]))); } if (indexes.Red != -1 && indexes.Green != -1 && indexes.Blue != -1) { mesh.Colors.Add(new Color( Convert.ToByte(elementValue.PropertyValues[indexes.Red]), Convert.ToByte(elementValue.PropertyValues[indexes.Green]), Convert.ToByte(elementValue.PropertyValues[indexes.Blue]), indexes.Alpha != -1 ? Convert.ToByte(elementValue.PropertyValues[indexes.Alpha]) : byte.MaxValue)); } if (indexes.S != -1 && indexes.T != -1) { mesh.TextureCoordinates.Add(new Vector3( Convert.ToSingle(elementValue.PropertyValues[indexes.S]), Convert.ToSingle(elementValue.PropertyValues[indexes.T]), 0.0f)); } } break; } case PlyKeywords.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; } case PlyKeywords.Edge: { foreach (var elementValue in element.ElementValues) { if (indexes.Vertex1 != -1 && indexes.Vertex2 != -1 && indexes.Red != -1 && indexes.Green != -1 && indexes.Blue != -1) { mesh.Edges.Add(new Edge( Convert.ToInt32(elementValue.PropertyValues[indexes.Vertex1]), Convert.ToInt32(elementValue.PropertyValues[indexes.Vertex2]), new Color( Convert.ToByte(elementValue.PropertyValues[indexes.Red]), Convert.ToByte(elementValue.PropertyValues[indexes.Green]), Convert.ToByte(elementValue.PropertyValues[indexes.Blue]), byte.MaxValue)) ); } } break; } } } }