【发布时间】:2017-12-13 00:42:34
【问题描述】:
解析 .STL 文件最有效的策略是什么?
我的代码的一个关键部分是导入 .STL 文件(一种常见的 CAD 文件格式),这会限制整体性能。
这里总结了.STL文件格式-https://en.wikipedia.org/wiki/STL_(file_format)
此应用程序需要使用 ASCII 格式。
通用格式为:
solid name
facet normal ni nj nk
outer loop
vertex v1x v1y v1z
vertex v2x v2y v2z
vertex v3x v3y v3z
endloop
endfacet
endsolid
但是,我注意到没有严格的格式要求。而且,导入功能必须进行最少的错误检查。我已经完成了一些性能测量(使用 chrono),对于 43,000 行文件给出了:
stl_import() - 1.177568 秒
解析循环 - 3.894250 s
解析循环:
cout << "Importing " << stl_path << "... ";
auto file_vec = import_stl(stl_path);
for (auto& l : file_vec) {
trim(l);
if (solid_state) {
if (facet_state) {
if (starts_with(l, "vertex")) {
//---------ADD FACE----------//
l.erase(0, 6);
trim(l);
vector<string> strs;
split(strs, l, is_any_of(" "));
point p = { stod(strs[0]), stod(strs[1]), stod(strs[2]) };
facet_points.push_back(p);
//---------------------------//
}
else {
if (starts_with(l, "endfacet")) {
facet_state = false;
}
}
}
else {
if (starts_with(l, "facet")) {
facet_state = true;
//assert(facet_points.size() == 0);
//---------------------------//
// Normals can be ignored //
//---------------------------//
}
if (starts_with(l, "endsolid")) {
solid_state = false;
}
}
}
else {
if (starts_with(l, "solid")) {
solid_state = true;
}
}
if (facet_points.size() == 3) {
triangle facet(facet_points[0], facet_points[1], facet_points[2]);
stl_solid.add_facet(facet);
facet_points.clear();
//check normal
facet.normal();
}
}
stl_import 函数是:
std::vector<std::string> import_stl(const std::string& file_path)
{
std::ifstream infile(file_path);
SkipBOM(infile);
std::vector<std::string> file_vec;
std::string line;
while (std::getline(infile, line))
{
file_vec.push_back(line);
}
return file_vec;
}
我已经搜索了优化文件读取等的方法。并且,我发现使用 mmap 可以提高文件读取速度。
这个问题是询问 .STL 文件的最佳解析策略是什么?
【问题讨论】:
-
最好的方法无疑是找到合适的库。与尝试加快对文件数据的读取访问速度相比,一个好的解析例程可能会产生更好的结果。
-
我已经进行了这些修改,尽管它们不会影响性能。
-
为什么要在解析之前导入整个文件?这样做会浪费大量内存,而且可能还会浪费一些时间。
标签: c++ string file parsing cad