Skip to content

Commit c253197

Browse files
committed
Fix write_obj and write_textured_obj to correctly write out tti if present
The two `write_obj` functions previously didn't write out the texture triangle indices (tti) at all, causing weird artefacts on the top of the head when using them and then opening a textured obj in e.g. MeshLab. This fixes it and writes out tti's into the obj if they're present. Also added appropriate asserts.
1 parent 7ce2918 commit c253197

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

include/eos/core/write_obj.hpp

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ namespace core {
4343
inline void write_obj(Mesh mesh, std::string filename)
4444
{
4545
assert(mesh.vertices.size() == mesh.colors.size() || mesh.colors.empty());
46+
assert(mesh.tvi.size() == mesh.tti.size() || mesh.tti.empty());
4647

4748
std::ofstream obj_file(filename);
4849

@@ -72,10 +73,29 @@ inline void write_obj(Mesh mesh, std::string filename)
7273
}
7374
}
7475

75-
for (auto&& v : mesh.tvi)
76+
for (std::size_t i = 0; i < mesh.tvi.size(); ++i)
7677
{
77-
// Add one because obj starts counting triangle indices at 1
78-
obj_file << "f " << v[0] + 1 << " " << v[1] + 1 << " " << v[2] + 1 << std::endl;
78+
const auto& vi = mesh.tvi[i];
79+
// We add one to the indices because obj starts counting triangle indices at 1
80+
if (mesh.texcoords.empty())
81+
{
82+
obj_file << "f " << vi[0] + 1 << " " << vi[1] + 1 << " " << vi[2] + 1 << std::endl;
83+
} else
84+
{
85+
if (mesh.tti.empty())
86+
{
87+
assert(mesh.texcoords.size() == mesh.vertices.size());
88+
// Using the mesh triangulation as uv triangle indices:
89+
obj_file << "f " << vi[0] + 1 << "/" << vi[0] + 1 << " " << vi[1] + 1 << "/" << vi[1] + 1
90+
<< " " << vi[2] + 1 << "/" << vi[2] + 1 << std::endl;
91+
} else
92+
{
93+
// Separate triangle indices for the uv coordinates:
94+
const auto& ti = mesh.tti[i];
95+
obj_file << "f " << vi[0] + 1 << "/" << ti[0] + 1 << " " << vi[1] + 1 << "/" << ti[1] + 1
96+
<< " " << vi[2] + 1 << "/" << ti[2] + 1 << std::endl;
97+
}
98+
}
7999
}
80100

81101
return;
@@ -94,7 +114,9 @@ inline void write_obj(Mesh mesh, std::string filename)
94114
*/
95115
inline void write_textured_obj(Mesh mesh, std::string filename)
96116
{
97-
assert((mesh.vertices.size() == mesh.colors.size() || mesh.colors.empty()) && !mesh.texcoords.empty());
117+
assert(mesh.vertices.size() == mesh.colors.size() || mesh.colors.empty());
118+
assert(!mesh.texcoords.empty());
119+
assert(mesh.tvi.size() == mesh.tti.size() || mesh.tti.empty());
98120

99121
if (filename.at(filename.size() - 4) != '.')
100122
{
@@ -143,17 +165,29 @@ inline void write_textured_obj(Mesh mesh, std::string filename)
143165
for (std::size_t i = 0; i < mesh.texcoords.size(); ++i)
144166
{
145167
obj_file << "vt " << mesh.texcoords[i][0] << " " << 1.0f - mesh.texcoords[i][1] << std::endl;
146-
// We invert y because Meshlab's uv origin (0, 0) is on the bottom-left
168+
// We invert y because MeshLab's uv origin (0, 0) is on the bottom-left
147169
}
148170

171+
// Note: This can't be at the top, otherwise MeshLab displays the mesh in all-black.
149172
obj_file << "usemtl FaceTexture" << std::endl; // the name of our texture (material) will be 'FaceTexture'
150173

151-
for (auto&& v : mesh.tvi)
174+
for (std::size_t i = 0; i < mesh.tvi.size(); ++i)
152175
{
153-
// This assumes mesh.texcoords.size() == mesh.vertices.size(). The texture indices could theoretically be different (for example in the cube-mapped 3D scan).
154-
// Add one because obj starts counting triangle indices at 1
155-
obj_file << "f " << v[0] + 1 << "/" << v[0] + 1 << " " << v[1] + 1 << "/" << v[1] + 1 << " "
156-
<< v[2] + 1 << "/" << v[2] + 1 << std::endl;
176+
const auto& vi = mesh.tvi[i];
177+
// We add one to the indices because obj starts counting triangle indices at 1
178+
if (mesh.tti.empty())
179+
{
180+
assert(mesh.texcoords.size() == mesh.vertices.size());
181+
// Using the mesh triangulation as uv triangle indices:
182+
obj_file << "f " << vi[0] + 1 << "/" << vi[0] + 1 << " " << vi[1] + 1 << "/" << vi[1] + 1 << " "
183+
<< vi[2] + 1 << "/" << vi[2] + 1 << std::endl;
184+
} else
185+
{
186+
// Separate triangle indices for the uv coordinates:
187+
const auto& ti = mesh.tti[i];
188+
obj_file << "f " << vi[0] + 1 << "/" << ti[0] + 1 << " " << vi[1] + 1 << "/" << ti[1] + 1 << " "
189+
<< vi[2] + 1 << "/" << ti[2] + 1 << std::endl;
190+
}
157191
}
158192

159193
std::ofstream mtl_file(mtl_filename);

0 commit comments

Comments
 (0)