I am trying to create a binary PLY file, with the following header:
ply
format binary_little_endian 1.0
element vertex 43000
property float x
property float y
property float z
property float nx
property float ny
property float nz
property uchar red
property uchar green
property uchar blue
end_header
I have the following overloaded functions to write as binary (validated with another example):
inline void write_fbin(std::ofstream &out, float val) {
out.write(reinterpret_cast<char*>(&val), sizeof(float));
}
inline void write_fbin(std::ofstream &out, unsigned char val) {
out.write(reinterpret_cast<char*>(&val), sizeof(unsigned char));
}
I write the vertices info as follows:
write_fbin(ofstr, static_cast<float>(point.x));
write_fbin(ofstr, static_cast<float>(point.y));
write_fbin(ofstr, static_cast<float>(point.z));
write_fbin(ofstr, static_cast<float>(point.n_x));
write_fbin(ofstr, static_cast<float>(point.n_y));
write_fbin(ofstr, static_cast<float>(point.n_z));
write_fbin(ofstr, static_cast<unsigned char>(point.r));
write_fbin(ofstr, static_cast<unsigned char>(point.g));
write_fbin(ofstr, static_cast<unsigned char>(point.b));
where point
is a struct of type
struct DensePoint {
float x, y, z;
float n_x, n_y, n_z;
unsigned char r, g, b;
};
This does not work and produces an invalid ply file. However, if I use the same code (changing the header) to produce an ASCII version,
ofstr
<< point.x << ' '
<< point.y << ' '
<< point.z << ' '
<< point.n_x << ' '
<< point.n_y << ' '
<< point.n_z << ' '
<< static_cast<int>(point.r) << ' '
<< static_cast<int>(point.g) << ' '
<< static_cast<int>(point.b) <<
'\n';
this works perfectly. What could be wrong?
Maybe I need to introduce a newline at the end of each vertex in the binary format?
When writing / reading binary data to / from a file that seem don't match the expected format, chances are that there is a character translation in place at OS level that replaces certain bytes combinations with other (es 0x0C becoming 0x0C 0x0A).
You have most likely opened the file in text mode (the default for C++ stream) when it should have been binary, to let the OS behavior neutral.