C# 用C语言读取二进制PLY文件的面索引#

C# 用C语言读取二进制PLY文件的面索引#,c#,mesh,ply-file-format,C#,Mesh,Ply File Format,我正在使用此项目读取.ply二进制文件: 它适用于读取点及其颜色。 但我不知道如何检索网格面索引列表 在函数ReadDataHeaders中,我成功地检索了面数: private static DataHeader ReadDataHeader(StreamReader reader) { ... if (col[0] == "element") { if (col[1] == "vertex") {

我正在使用此项目读取.ply二进制文件:

它适用于读取点及其颜色。 但我不知道如何检索网格面索引列表

在函数ReadDataHeaders中,我成功地检索了面数:

 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;
                    }
                }

...
}
但我不明白的是如何在函数ReadDataBodyBoundary中检索网格面索引。 我也不明白BinaryReader在这个函数中是如何工作的,它是如何读取网格面顶点索引的每一行二进制形式的

 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 < 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 < 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() >> 8);
                        break;
                        case DataProperty.G16:
                        g = (byte)(reader.ReadUInt16() >> 8);
                        break;
                        case DataProperty.B16:
                        b = (byte)(reader.ReadUInt16() >> 8);
                        break;
                        case DataProperty.A16:
                        a = (byte)(reader.ReadUInt16() >> 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;
        }
private static DataBody ReadDataBodyBinary(DataHeader头,BinaryReader){
数据体数据=新数据体(header.vertexCount,header.faceCount);
浮动x=0,y=0,z=0;
字节r=255,g=255,b=255,a=255;
int f0=0,f1=0,f2=0;
//对于(int i=0;i>8);
打破
案例DataProperty.G16:
g=(字节)(reader.ReadUInt16()>>8);
打破
案例DataProperty.B16:
b=(字节)(reader.ReadUInt16()>>8);
打破
案例DataProperty.A16:
a=(字节)(reader.ReadUInt16()>>8);
打破
case DataProperty.SingleX:
x=reader.ReadSingle();
打破
case DataProperty.SingleY:
y=reader.ReadSingle();
打破
case DataProperty.SingleZ:
z=reader.ReadSingle();
打破
case DataProperty.DoubleX:
x=(float)reader.ReadDouble();
打破
case DataProperty.DoubleY:
y=(float)reader.ReadDouble();
打破
case DataProperty.DoubleZ:
z=(float)reader.ReadDouble();
打破
案例DataProperty.Data8:
reader.ReadByte();
打破
案例DataProperty.Data16:
reader.BaseStream.Position+=2;
打破
案例DataProperty.Data32:
reader.BaseStream.Position+=4;
打破
案例DataProperty.Data64:
reader.BaseStream.Position+=8;
打破
}
}
数据添加点(x,y,z,r,g,b);
}
返回数据;
}

问题在于,您提供的示例只需要颜色点云(而不需要面三角形)

在代码中注释的那段代码中似乎包含了“读取面”的键

我假设您的ply文件的头是这样的:

ply
format binary_little_endian 1.0
element vertex 326
property float x
property float y
property float z
property uchar r
property uchar g
property uchar b
property uchar a
element face 595
property list uchar int vertex_indices
end_header
重要的一行是
属性列表uchar int vertex\u index
意味着您有一个包含面中顶点数(通常为3)的uchar,以及一个包含顶点索引的有符号int列表

 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 < 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 < 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() >> 8);
                        break;
                        case DataProperty.G16:
                        g = (byte)(reader.ReadUInt16() >> 8);
                        break;
                        case DataProperty.B16:
                        b = (byte)(reader.ReadUInt16() >> 8);
                        break;
                        case DataProperty.A16:
                        a = (byte)(reader.ReadUInt16() >> 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;
        }
因此,您需要更改数据结构,以使用类似于
公共列表面的内容来存储面
并添加类似于此的内容,其中包含
返回数据

for(int i=0;i
解析器没有读取面索引,它只是读取顶点信息(x、y、z、r、g、b)。完成后,它返回,而面索引未读。