C# 用C语言读取二进制PLY文件的面索引#
我正在使用此项目读取.ply二进制文件: 它适用于读取点及其颜色。 但我不知道如何检索网格面索引列表 在函数ReadDataHeaders中,我成功地检索了面数: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") {
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)。完成后,它返回,而面索引未读。