I'm trying to write a 3D geometry into a binary STL file. Here is how the main program works:
ParseSTL stl();
//generate the 3D model
std::string outfname = "test.stl";
std::ofstream outf(outfname, std::ios_base::out & std::ios_base::binary);
stl.writeBinarySTL(outf);
and the STL writer is:
void writeBinarySTL(std::ofstream &outf)
{
char attr[2] = { 0 };
char header[80] = { 0 };
int count = 0;
outf.write(header, 80);
//count += 80;
//std::cout << "after header: file position: " << outf.tellp() << " bytes written: " << count << "\n";
//if ((int)outf.tellp() != count)
// std::cout << "something is wrong!\n";
outf.write(reinterpret_cast<char *>(&facecount), sizeof(int));
//count += sizeof(int);
//std::cout << "after number of faces: file position: " << outf.tellp() << " bytes written: " << count << "\n";
//if ((int)outf.tellp() != count)
// std::cout << "something is wrong!\n";
for (int i = 0; i < facecount; i++)
{
struct face{
float n[3];
float v[3][3];
} f;
for (int j = 0; j < 3; ++j)
f.n[j] = (float) normals[i][j];
for (int j = 0; j < 3; ++j)
for (int k = 0; k < 3; ++k)
f.v[j][k] = (float)vertices[faces[i][j]][k];
outf.write(reinterpret_cast<char *>(&f), sizeof(f));
//count += sizeof(f);
//std::cout << "after struct: file position: " << outf.tellp() << " bytes written: " << count << "\n";
//if ((int)outf.tellp() != count)
//{
// std::cout << "something is wrong!\n";
// break;
//}
outf.write(attr, 2);
//count += 2;
//std::cout << "after attributes: file position: " << outf.tellp() << " bytes written: " << count << "\n";
//if ((int)outf.tellp() != count)
//{
// std::cout << "something is wrong!\n";
// break;
//}
}
//std::cout << "Bytes written: " << count << "\n";
}
The commented parts are just for debugging, and facecount
is a member of the class ParseSTL
that stores number of triangles, normals
is a vector of 3D vectors that stores normals for all faces, vertices
is a vector of 3D vectors that stores coordinates for all vertices, and faces
is a vector of 3 integers that stores the index of vrtices that belong to a triangle. Now, if I run the program, here is the output that I get:
Vertex count = 4243
Face count = 3168
Edge count = 0
after header: file position: 80 bytes written: 80
after number of faces: file position: 84 bytes written: 84
after struct: file position: 132 bytes written: 132
after attributes: file position: 134 bytes written: 134
...
after struct: file position: 532 bytes written: 532
after attributes: file position: 534 bytes written: 534
after struct: file position: 583 bytes written: 582
something is wrong!
So, it seems that the line outf.write(reinterpret_cast<char *>(&f), sizeof(f));
is writing 1 more byte than it should. This drifting happens once in a while, and at the end, instead of a file that is 158,484
Bytes, I'm getting a file that is 158,896
Bytes. If I add a outf.seekp(count)
after writing the struct, the final file size is correct, but some of the floats are not written correctly (so the drift is not always at the end of the struct).
I was wondering what I'm doing wrong that causes this extra Bytes to be written into the file. Oh, and I'm using Microsoft Visual Stusio Express 2013.
This line
std::ofstream outf(outfname, std::ios_base::out & std::ios_base::binary);
needs to be
std::ofstream outf(outfname, std::ios_base::out | std::ios_base::binary);
^^^^^ The difference
It can be simplified by omitting the std::ios_base::out
flag (Thanks @Blastfurnace for the hint). It also reduces the chances of such errors creeping in.
std::ofstream outf(outfname, std::ios_base::binary);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.