Beispiel #1
0
        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;
            }));
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 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);
        }
Beispiel #7
0
        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;
                }
                }
            }
        }