mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Refactor. Turn on link faces by default.
This commit is contained in:
parent
e262989492
commit
4eb4e232a2
3 changed files with 60 additions and 50 deletions
|
|
@ -41,6 +41,7 @@ bool printMaxPolygonBlock = false;
|
||||||
|
|
||||||
cl::opt<path> p(cl::Positional, cl::desc("<MOD_ file or directory with MOD_ files>"), cl::value_desc("file or directory"), cl::Required);
|
cl::opt<path> p(cl::Positional, cl::desc("<MOD_ file or directory with MOD_ files>"), cl::value_desc("file or directory"), cl::Required);
|
||||||
cl::opt<bool> all_formats("af", cl::desc("All formats (.obj, .fbx)"));
|
cl::opt<bool> all_formats("af", cl::desc("All formats (.obj, .fbx)"));
|
||||||
|
cl::opt<bool> link_faces("lf", cl::desc("Link faces (default: true)"), cl::init(true));
|
||||||
|
|
||||||
yaml root;
|
yaml root;
|
||||||
cl::opt<bool> stats("i", cl::desc("Gather information from (models)"));
|
cl::opt<bool> stats("i", cl::desc("Gather information from (models)"));
|
||||||
|
|
@ -67,6 +68,8 @@ auto read_model(const path &fn)
|
||||||
buffer b(read_file(fn));
|
buffer b(read_file(fn));
|
||||||
model m;
|
model m;
|
||||||
m.load(b);
|
m.load(b);
|
||||||
|
if (link_faces)
|
||||||
|
m.linkFaces();
|
||||||
|
|
||||||
if (!b.eof())
|
if (!b.eof())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -370,51 +370,6 @@ std::string block::printObj(int group_offset, AxisSystem as) const
|
||||||
return printObj(group_offset, as, vertices, faces);
|
return printObj(group_offset, as, vertices, faces);
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto linkFaces(const std::vector<vertex> &vertices, const std::vector<face> &faces)
|
|
||||||
{
|
|
||||||
// reference implementation by Razum: https://pastebin.com/KewhggDj
|
|
||||||
|
|
||||||
std::vector<vertex> vertices2;
|
|
||||||
vertices2.reserve(vertices.size());
|
|
||||||
std::unordered_map<short, short> 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<face> 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)
|
void block::header::texture::load(const buffer &b)
|
||||||
{
|
{
|
||||||
READ_STRING(b, name);
|
READ_STRING(b, name);
|
||||||
|
|
@ -597,6 +552,52 @@ void block::loadPayload(const buffer &data)
|
||||||
throw std::logic_error(s);
|
throw std::logic_error(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static auto linkFaces(const std::vector<vertex> &vertices, const std::vector<face> &faces)
|
||||||
|
{
|
||||||
|
// reference implementation by Razum: https://pastebin.com/KewhggDj
|
||||||
|
|
||||||
|
std::vector<vertex> vertices2;
|
||||||
|
vertices2.reserve(vertices.size());
|
||||||
|
std::unordered_map<short, short> 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<face> 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
|
bool block::isEngineFx() const
|
||||||
{
|
{
|
||||||
return h.type == BlockType::HelperObject && h.name.find(boost::to_lower_copy(std::string("FIRE"))) == 0;
|
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);
|
f.load(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void model::linkFaces()
|
||||||
|
{
|
||||||
|
for (auto &f : blocks)
|
||||||
|
f.linkFaces();
|
||||||
|
}
|
||||||
|
|
||||||
void model::print(const std::string &fn, AxisSystem as) const
|
void model::print(const std::string &fn, AxisSystem as) const
|
||||||
{
|
{
|
||||||
auto title = [](auto &o)
|
auto title = [](auto &o)
|
||||||
|
|
@ -685,7 +692,7 @@ void model::print(const std::string &fn, AxisSystem as) const
|
||||||
o << "\n";
|
o << "\n";
|
||||||
};
|
};
|
||||||
|
|
||||||
auto print_obj = [&](const auto &n, bool patched)
|
auto print_obj = [&](const auto &n)
|
||||||
{
|
{
|
||||||
std::ofstream o(n);
|
std::ofstream o(n);
|
||||||
title(o);
|
title(o);
|
||||||
|
|
@ -697,7 +704,7 @@ void model::print(const std::string &fn, AxisSystem as) const
|
||||||
if (!b.canPrint())
|
if (!b.canPrint())
|
||||||
continue;
|
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();
|
n_vert += b.vertices.size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -708,8 +715,7 @@ void model::print(const std::string &fn, AxisSystem as) const
|
||||||
for (auto &b : blocks)
|
for (auto &b : blocks)
|
||||||
m << b.printMtl() << "\n";
|
m << b.printMtl() << "\n";
|
||||||
|
|
||||||
print_obj(fn + ".obj", false);
|
print_obj(fn + ".obj");
|
||||||
print_obj(fn + "_patched.obj", true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void model::save(yaml &root) const
|
void model::save(yaml &root) const
|
||||||
|
|
|
||||||
|
|
@ -311,10 +311,10 @@ struct block
|
||||||
|
|
||||||
void load(const buffer &b);
|
void load(const buffer &b);
|
||||||
void loadPayload(const buffer &b);
|
void loadPayload(const buffer &b);
|
||||||
|
void linkFaces();
|
||||||
|
|
||||||
std::string printMtl() const;
|
std::string printMtl() const;
|
||||||
std::string printObj(int group_offset, AxisSystem as) 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;
|
block_info save(yaml &root) const;
|
||||||
|
|
||||||
bool canPrint() const;
|
bool canPrint() const;
|
||||||
|
|
@ -330,6 +330,7 @@ struct model
|
||||||
std::vector<block> blocks;
|
std::vector<block> blocks;
|
||||||
|
|
||||||
void load(const buffer &b);
|
void load(const buffer &b);
|
||||||
|
void linkFaces();
|
||||||
|
|
||||||
void print(const std::string &fn, AxisSystem) const;
|
void print(const std::string &fn, AxisSystem) const;
|
||||||
void printFbx(const std::string &fn, AxisSystem) const;
|
void printFbx(const std::string &fn, AxisSystem) const;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue