Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在c+;中导入.STL文件最有效的方法是什么+;?_C++_String_File_Parsing_Cad - Fatal编程技术网

C++ 在c+;中导入.STL文件最有效的方法是什么+;?

C++ 在c+;中导入.STL文件最有效的方法是什么+;?,c++,string,file,parsing,cad,C++,String,File,Parsing,Cad,解析.STL文件最有效的策略是什么 我的代码的一个关键部分是导入一个.STL文件(一种常见的CAD文件格式),这限制了整体性能 .STL文件格式总结如下: 此应用程序需要使用ASCII格式 通用格式为: solid name facet normal ni nj nk outer loop vertex v1x v1y v1z vertex v2x v2y v2z vertex v3x v3y v3z

解析.STL文件最有效的策略是什么

我的代码的一个关键部分是导入一个.STL文件(一种常见的CAD文件格式),这限制了整体性能

.STL文件格式总结如下:

此应用程序需要使用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),对于43000行文件,它给出:

stl_导入()-1.177568 s

解析循环-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();
        }
    }

cout如果没有可用于测量时间花在何处的数据,则很难确定实际改善性能的因素。一个已经做好这项工作的体面的图书馆可能是最简单的方法。然而,当前的代码使用了一些方法,这些方法可能很容易提高性能。我发现了一些东西:

  • streams库非常擅长跳过前导空格。您可能希望使用
    std::getline(infle>>std::ws,line)
    :std::ws
  • 操纵器跳过前导空格,而不是先读取空格,然后再修剪它们
  • 我宁愿将每一行读入一个“命令”和行尾,并将命令与
    std::string const
    对象进行比较,而不是进行字符比较,比较大小可能就足够了
  • 与其在空白处将
    std::string
    转换成
    std::vector
    ,我宁愿重置一个合适的流(可能是
    std::istringstream
    ,但为了防止复制自定义内存流),并直接从中读取:

    std::istringstream in; // declared outside the reading loop
    // ...
    point p;
    in.clear(); // get rid of potentially existing errors
    in.str(line);
    if (in >> p.x >> p.y >> p.z) {
        facet_points.push_back(p);
    }
    
    这种方法还有一个额外的优点,就是允许进行格式检查:我总是不相信收到的任何输入,即使它来自可信的来源

  • 如果您坚持使用调整字符序列和/或将其拆分为子序列,我强烈建议使用
    std::string_view
    (或者,如果此C++17类不可用,则使用类似的类),以避免移动字符
  • 假设文件的大小很大,我建议不要将文件读入
    std::vector
    ,然后对其进行解析。相反,我会动态解析文件:这样热内存会立即被重用,而不是将其移出缓存进行后期处理。这种处理辅助流的方式(见上文第3点)可以避免。为了避免过于复杂的读取循环,我将嵌套的部分拆分为适当的函数,并在结束标记上从它们返回。此外,我还为
    point
    等结构定义了输入函数,以便从流中简单地读取它们
  • 根据您正在使用的系统的不同,您可能希望在读取文件之前调用
    std::ios\u base::sync\u with\u stdio(false)
    :以前至少有一种常用的streams实现,可以从该调用中获益

  • 毫无疑问,最好的办法是找到一个合适的图书馆。一个好的解析例程可能会比尝试加快对文件数据的读取速度产生更好的结果。我已经进行了这些编辑,尽管它们不会影响性能。为什么在解析之前要导入整个文件?你这样做浪费了很多内存,可能也浪费了一些时间。
    std::istringstream in; // declared outside the reading loop
    // ...
    point p;
    in.clear(); // get rid of potentially existing errors
    in.str(line);
    if (in >> p.x >> p.y >> p.z) {
        facet_points.push_back(p);
    }