Closed kingui1106 closed 1 year ago
Based on my own understanding, the following simple code works.But obviously, exporting obj takes up a lot of time and space
/**
* Write to file with Obj format.
*/
void Voxelizer::WriteObj() {
if (option_.Verbose()) std::cout << "writing voxels to file..." << std::endl;
int lx = 0, ux = size_x_ - 1, ly = 0, uy = size_y_ - 1, lz = 0, uz = size_z_ - 1;
std::ofstream* output = new std::ofstream(option_.OutFilePath().c_str(), std::ios::out);
if (option_.Verbose())
std::cout << "dim : " << size_x_ << " x " << size_y_ << " x " << size_z_ << std::endl;
if (option_.Verbose()) std::cout << "lower bound : " << (*lb_) << std::endl;
if (option_.Verbose()) std::cout << "voxel size : " << (*unit_)[0] << " " << (*unit_)[1] << " " << (*unit_)[2] << std::endl;
Vec3f minP((double)(*lb_)[0], (double)(*lb_)[1], (double)(*lb_)[2]);
Vec3f size((double)(*unit_)[0], (double)(*unit_)[1], (double)(*unit_)[2]);
//
// write data
//
//The obj index starts at 1
int idx = 1;
//trigulate faces
bool trigulate = false;
VoxelIndex count = 0;
for (int x = lx; x <= ux; ++x) {
for (int y = ly; y <= uy; ++y) {
for (int z = lz; z <= uz; ++z) {
if (Filled(x, y, z)) {
auto _write_vertex = [&](const Vec3f& _p)->void
{
*output << "v " << _p[0] << ' ' << _p[1] << ' ' << _p[2] << std::endl;
};
Vec3f p0 = Vec3f(x * size[0], y * size[1], z * size[2]) + minP;
Vec3f p1 = Vec3f(p0[0] + size[0], p0[1], p0[2]);
Vec3f p2 = Vec3f(p0[0] , p0[1], p0[2]+ size[2]);
Vec3f p3 = Vec3f(p0[0] + size[0], p0[1], p0[2] + size[2]);
Vec3f p4 = Vec3f(p0[0] , p0[1] + size[1], p0[2]);
Vec3f p5 = Vec3f(p0[0] + size[0], p0[1] + size[1], p0[2]);
Vec3f p6 = Vec3f(p0[0] , p0[1] + size[1], p0[2] + size[2]);
Vec3f p7 = Vec3f(p0[0] + size[0], p0[1] + size[1], p0[2] + size[2]);
_write_vertex(p0);
_write_vertex(p1);
_write_vertex(p2);
_write_vertex(p3);
_write_vertex(p4);
_write_vertex(p5);
_write_vertex(p6);
_write_vertex(p7);
int idx0 = idx + 0;
int idx1 = idx + 1;
int idx2 = idx + 2;
int idx3 = idx + 3;
int idx4 = idx + 4;
int idx5 = idx + 5;
int idx6 = idx + 6;
int idx7 = idx + 7;
/*
6 ----- 7
/| /|
2 ----- 3 |
| | | |
| 4 ----- 5
|/ |/
0 ----- 1
*/
if(!trigulate){
*output << "f " << idx0 << " " << idx1 << " " << idx3 << " " << idx2 << std::endl;
*output << "f " << idx5 << " " << idx4 << " " << idx6 << " " << idx7 << std::endl;
*output << "f " << idx2 << " " << idx3 << " " << idx7 << " " << idx6 << std::endl;
*output << "f " << idx4 << " " << idx5 << " " << idx1 << " " << idx0 << std::endl;
*output << "f " << idx0 << " " << idx2 << " " << idx6 << " " << idx4 << std::endl;
*output << "f " << idx3 << " " << idx1 << " " << idx5 << " " << idx7 << std::endl;
}
else
{
*output << "f " << idx0 << " " << idx1 << " " << idx3 << std::endl;
*output << "f " << idx0 << " " << idx3 << " " << idx2 << std::endl;
*output << "f " << idx5 << " " << idx4 << " " << idx6 << std::endl;
*output << "f " << idx5 << " " << idx6 << " " << idx7 << std::endl;
*output << "f " << idx2 << " " << idx3 << " " << idx7 << std::endl;
*output << "f " << idx2 << " " << idx7 << " " << idx6 << std::endl;
*output << "f " << idx4 << " " << idx5 << " " << idx1 << std::endl;
*output << "f " << idx4 << " " << idx1 << " " << idx0 << std::endl;
*output << "f " << idx0 << " " << idx2 << " " << idx6 << std::endl;
*output << "f " << idx0 << " " << idx6 << " " << idx4 << std::endl;
*output << "f " << idx3 << " " << idx1 << " " << idx5 << std::endl;
*output << "f " << idx3 << " " << idx5 << " " << idx7 << std::endl;
}
idx += 8;
++count;
}
}
}
}
output->close();
if (option_.Verbose()) std::cout << "wrote " << count << " voxels" << std::endl;
}
Yes, this is one correct way to export obj technically. To save some time and space, you may 1) use the surface mode in voxelization 2) instead generating 8 vertex, you may use the center point as the only vertex (assume your voxel is not too large), and the model should look similar
Btw, may I ask what is motivation to export the voxels as an obj? since the input of the voxelizer is already an obj. if it is for simplification, an alternative is mesh simplification method.
Yes, this is one correct way to export obj technically. To save some time and space, you may 1) use the surface mode in voxelization 2) instead generating 8 vertex, you may use the center point as the only vertex (assume your voxel is not too large), and the model should look similar
Btw, may I ask what is motivation to export the voxels as an obj? since the input of the voxelizer is already an obj. if it is for simplification, an alternative is mesh simplification method.
Yes, this is one correct way to export obj technically. To save some time and space, you may
- use the surface mode in voxelization
- instead generating 8 vertex, you may use the center point as the only vertex (assume your voxel is not too large), and the model should look similar
Btw, may I ask what is motivation to export the voxels as an obj? since the input of the voxelizer is already an obj. if it is for simplification, an alternative is mesh simplification method.
Just want to get the expression of the voxel, and obj easy visualization.
I try to understand binvox or Rawvox. How do I convert it to the representation of the surface model?Like obj, or other common 3D formats.