diff --git a/apps/texrecon/arguments.cpp b/apps/texrecon/arguments.cpp index b0a4de40..e8938fe7 100644 --- a/apps/texrecon/arguments.cpp +++ b/apps/texrecon/arguments.cpp @@ -17,6 +17,7 @@ #define WRITE_TIMINGS "write_timings" #define SKIP_HOLE_FILLING "skip_hole_filling" #define KEEP_UNSEEN_FACES "keep_unseen_faces" +#define SAVE_UNTEXTURED_FACES_MESH "write_untextured_faces_mesh" Arguments parse_args(int argc, char **argv) { util::Arguments args; @@ -82,6 +83,8 @@ Arguments parse_args(int argc, char **argv) { "Skip hole filling [false]"); args.add_option('\0', KEEP_UNSEEN_FACES, false, "Keep unseen faces [false]"); + args.add_option('\0', SAVE_UNTEXTURED_FACES_MESH, false, + "Save untextured faces to seperate mesh file [false]"); args.add_option('\0', WRITE_TIMINGS, false, "Write out timings for each algorithm step (OUT_PREFIX + _timings.csv)"); args.add_option('\0', NO_INTERMEDIATE_RESULTS, false, @@ -137,6 +140,8 @@ Arguments parse_args(int argc, char **argv) { conf.settings.hole_filling = false; } else if (i->opt->lopt == KEEP_UNSEEN_FACES) { conf.settings.keep_unseen_faces = true; + } else if (i->opt->lopt == SAVE_UNTEXTURED_FACES_MESH) { + conf.settings.save_untextured_faces_mesh = true; } else if (i->opt->lopt == WRITE_TIMINGS) { conf.write_timings = true; } else if (i->opt->lopt == NO_INTERMEDIATE_RESULTS) { diff --git a/apps/texrecon/texrecon.cpp b/apps/texrecon/texrecon.cpp index 58692e82..835525bf 100644 --- a/apps/texrecon/texrecon.cpp +++ b/apps/texrecon/texrecon.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -186,6 +187,40 @@ int main(int argc, char **argv) { timer.measure("Saving"); } + if (conf.settings.save_untextured_faces_mesh) { + std::vector face_textured(mesh->get_faces().size() / 3, false); + + for (TextureAtlas::Ptr texture_atlas : texture_atlases) { + for (std::size_t face_id : texture_atlas->get_faces()) { + face_textured[face_id] = true; + } + } + + std::vector untextured_faces; + std::unordered_map vertices_index_remap; + for (std::size_t face_id = 0; face_id < face_textured.size(); ++face_id) { + if (face_textured[face_id]) { + continue; + } + std::size_t const face_pos = face_id * 3; + for (std::size_t j = 0; j < 3; ++j) { + std::size_t const vertex_id = mesh->get_faces()[face_pos + j]; + if (vertices_index_remap.find(vertex_id) == vertices_index_remap.end()) { + int rempaed_vertex_id = vertices_index_remap.size(); + vertices_index_remap[vertex_id] = rempaed_vertex_id; + } + untextured_faces.push_back(vertices_index_remap[vertex_id]); + } + } + std::vector untextured_vertices(vertices_index_remap.size()); + for (const auto & entry : vertices_index_remap) { + untextured_vertices[entry.second] = mesh->get_vertices()[entry.first]; + } + std::cout << "\tSaving separate mesh with " << (untextured_faces.size() / 3) << " untextured faces... "; + ObjModel::saveSimpleTriangles(untextured_vertices, untextured_faces, conf.out_prefix + "_untextured"); + std::cout << "done." << std::endl; + } + std::cout << "Whole texturing procedure took: " << wtimer.get_elapsed_sec() << "s" << std::endl; timer.measure("Total"); if (conf.write_timings) { diff --git a/libs/tex/obj_model.cpp b/libs/tex/obj_model.cpp index 1a9c2aec..41dfca1d 100644 --- a/libs/tex/obj_model.cpp +++ b/libs/tex/obj_model.cpp @@ -69,3 +69,24 @@ ObjModel::save_to_files(std::string const & prefix) const { } out.close(); } + +void +ObjModel::saveSimpleTriangles(std::vector const & vertices, std::vector const & faces, std::string const & prefix) +{ + std::ofstream out((prefix + ".obj").c_str()); + + out << std::fixed << std::setprecision(6); + for (const auto & vertex : vertices) { + out << "v " << vertex[0] << " " + << vertex[1] << " " + << vertex[2] << std::endl; + } + + for (std::size_t j = 0; j < faces.size(); j += 3) { + out << "f " << faces[j] + 1 << " " + << faces[j + 1] + 1 << " " + << faces[j + 2] + 1 << std::endl; + } + out.close(); + +} diff --git a/libs/tex/obj_model.h b/libs/tex/obj_model.h index e3615f10..98afe281 100644 --- a/libs/tex/obj_model.h +++ b/libs/tex/obj_model.h @@ -51,6 +51,7 @@ class ObjModel { Groups & get_groups(void); static void save(ObjModel const & model, std::string const & prefix); + static void saveSimpleTriangles(std::vector const & vertices, std::vector const & faces, std::string const & prefix); }; inline diff --git a/libs/tex/settings.h b/libs/tex/settings.h index f2cc5632..a90e8a8e 100644 --- a/libs/tex/settings.h +++ b/libs/tex/settings.h @@ -92,6 +92,7 @@ struct Settings { bool local_seam_leveling = true; bool hole_filling = true; bool keep_unseen_faces = false; + bool save_untextured_faces_mesh = false; }; TEX_NAMESPACE_END