From 4eb4e232a211e5805ba922750b9915282ff0a198 Mon Sep 17 00:00:00 2001 From: lzwdgc Date: Sun, 1 Mar 2020 21:39:47 +0300 Subject: [PATCH] Refactor. Turn on link faces by default. --- src/mod_converter/mod_converter.cpp | 3 + src/model/model.cpp | 104 +++++++++++++++------------- src/model/model.h | 3 +- 3 files changed, 60 insertions(+), 50 deletions(-) diff --git a/src/mod_converter/mod_converter.cpp b/src/mod_converter/mod_converter.cpp index f030cf5..99be997 100644 --- a/src/mod_converter/mod_converter.cpp +++ b/src/mod_converter/mod_converter.cpp @@ -41,6 +41,7 @@ bool printMaxPolygonBlock = false; cl::opt p(cl::Positional, cl::desc(""), cl::value_desc("file or directory"), cl::Required); cl::opt all_formats("af", cl::desc("All formats (.obj, .fbx)")); +cl::opt link_faces("lf", cl::desc("Link faces (default: true)"), cl::init(true)); yaml root; cl::opt stats("i", cl::desc("Gather information from (models)")); @@ -67,6 +68,8 @@ auto read_model(const path &fn) buffer b(read_file(fn)); model m; m.load(b); + if (link_faces) + m.linkFaces(); if (!b.eof()) { diff --git a/src/model/model.cpp b/src/model/model.cpp index 3356f51..c2c4c52 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -370,51 +370,6 @@ std::string block::printObj(int group_offset, AxisSystem as) const return printObj(group_offset, as, vertices, faces); } -static auto linkFaces(const std::vector &vertices, const std::vector &faces) -{ - // reference implementation by Razum: https://pastebin.com/KewhggDj - - std::vector vertices2; - vertices2.reserve(vertices.size()); - std::unordered_map repl; - repl.reserve(vertices.size()); - - auto sz = vertices.size(); - for (int i = 0; i < sz; i++) - { - auto it = std::find_if(vertices2.begin(), vertices2.end(), [&vertices, i](auto &v1) - { - return (aim_vector3f&)vertices[i].coordinates == (aim_vector3f&)v1.coordinates; - }); - if (it == vertices2.end()) - { - vertices2.push_back(vertices[i]); - repl[i] = vertices2.size() - 1; - } - else - repl[i] = std::distance(vertices2.begin(), it); - } - - std::vector faces2; - faces2.reserve(faces.size()); - for (auto f : faces) - { - for (auto &v : f.vertex_list) - v = repl[v]; - // remove duplicates - if (std::find(faces2.begin(), faces2.end(), f) == faces2.end()) - faces2.push_back(f); - } - - return std::tuple{ vertices2, faces2 }; -} - -std::string block::printObjSlow(int group_offset, AxisSystem as) const -{ - auto [vertices2, faces2] = linkFaces(vertices, faces); - return printObj(group_offset, as, vertices2, faces2); -} - void block::header::texture::load(const buffer &b) { READ_STRING(b, name); @@ -597,6 +552,52 @@ void block::loadPayload(const buffer &data) throw std::logic_error(s); } +static auto linkFaces(const std::vector &vertices, const std::vector &faces) +{ + // reference implementation by Razum: https://pastebin.com/KewhggDj + + std::vector vertices2; + vertices2.reserve(vertices.size()); + std::unordered_map repl; + repl.reserve(vertices.size()); + + auto sz = vertices.size(); + for (int i = 0; i < sz; i++) + { + auto it = std::find_if(vertices2.begin(), vertices2.end(), [&vertices, i](auto &v1) + { + return (aim_vector3f&)vertices[i].coordinates == (aim_vector3f&)v1.coordinates; + }); + if (it == vertices2.end()) + { + vertices2.push_back(vertices[i]); + repl[i] = vertices2.size() - 1; + } + else + repl[i] = std::distance(vertices2.begin(), it); + } + + std::vector faces2; + faces2.reserve(faces.size()); + for (auto f : faces) + { + for (auto &v : f.vertex_list) + v = repl[v]; + // remove duplicates + if (std::find(faces2.begin(), faces2.end(), f) == faces2.end()) + faces2.push_back(f); + } + + return std::tuple{ vertices2, faces2 }; +} + +void block::linkFaces() +{ + auto [v, f] = ::linkFaces(vertices, faces); + vertices = v; + faces = f; +} + bool block::isEngineFx() const { return h.type == BlockType::HelperObject && h.name.find(boost::to_lower_copy(std::string("FIRE"))) == 0; @@ -675,6 +676,12 @@ void model::load(const buffer &b) f.load(b); } +void model::linkFaces() +{ + for (auto &f : blocks) + f.linkFaces(); +} + void model::print(const std::string &fn, AxisSystem as) const { auto title = [](auto &o) @@ -685,7 +692,7 @@ void model::print(const std::string &fn, AxisSystem as) const o << "\n"; }; - auto print_obj = [&](const auto &n, bool patched) + auto print_obj = [&](const auto &n) { std::ofstream o(n); title(o); @@ -697,7 +704,7 @@ void model::print(const std::string &fn, AxisSystem as) const if (!b.canPrint()) continue; - o << (patched ? b.printObjSlow(n_vert, as) : b.printObj(n_vert, as)) << "\n"; + o << b.printObj(n_vert, as) << "\n"; n_vert += b.vertices.size(); } }; @@ -708,8 +715,7 @@ void model::print(const std::string &fn, AxisSystem as) const for (auto &b : blocks) m << b.printMtl() << "\n"; - print_obj(fn + ".obj", false); - print_obj(fn + "_patched.obj", true); + print_obj(fn + ".obj"); } void model::save(yaml &root) const diff --git a/src/model/model.h b/src/model/model.h index 31bf486..de4a203 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -311,10 +311,10 @@ struct block void load(const buffer &b); void loadPayload(const buffer &b); + void linkFaces(); std::string printMtl() const; std::string printObj(int group_offset, AxisSystem as) const; - std::string printObjSlow(int group_offset, AxisSystem as) const; block_info save(yaml &root) const; bool canPrint() const; @@ -330,6 +330,7 @@ struct model std::vector blocks; void load(const buffer &b); + void linkFaces(); void print(const std::string &fn, AxisSystem) const; void printFbx(const std::string &fn, AxisSystem) const;