我正在尝试使用Boost Spirit库编写基本的OBJ文件加载器。虽然我使用标准的std :: ifstreams工作,但我想知道是否可以使用内存映射文件对整个文件执行phrase_parse,因为它似乎提供了发布here的最佳性能。
我有以下代码,它似乎运行良好,但在文件中有注释时会中断。所以,我的问题是你如何忽略使用Spririt在OBJ文件中以'#'开头的注释?
struct vertex {
double x, y, z;
};
BOOST_FUSION_ADAPT_STRUCT(
vertex,
(double, x)
(double, y)
(double, z)
)
std::vector<vertex> b_vertices
boost::iostreams::mapped_file mmap(
path,
boost::iostreams::mapped_file::readonly);
const char* f = mmap.const_data();
const char* l = f + mmap.size();
using namespace boost::spirit::qi;
bool ok = phrase_parse(f,l,(("v" >> double_ >> double_ >> double_) |
("vn" >> double_ >> double_>> double_)) % eol ,
blank, b_vertices);
当没有注释或除顶点/法线之外的任何其他数据时,上述代码运行良好。但是当有一种不同类型的数据时,解析器失败(应该如此),我想知道是否有办法让它工作而不回去解析每一行,因为它更慢(在我的测试中几乎是2.5倍) 。谢谢!
答案 0 :(得分:3)
最简单的想法是简单地使评论可以跳过:
bool ok = qi::phrase_parse(
f,l,
(
("v" >> qi::double_ >> qi::double_ >> qi::double_) |
("vn" >> qi::double_ >> qi::double_ >> qi::double_)
)
% qi::eol,
('#' >> *(qi::char_ - qi::eol) >> qi::eol | qi::blank), b_vertices);
请注意,如果#
出现在该行的某个位置,这也会“识别”评论。这可能很好(因为它会使解析失败,除非它是一个在其他有效输入行上尾随的注释)。
或者,使用一些凤凰魔术来处理“注释行”,就像处理“vn”或“v”行一样。
答案 1 :(得分:0)
我意识到我的评论/帖子不是直接相关的代码,但我不是为了重新发明轮子,如果可能的话我想知道这个库。我正在使用手写的OBJ / Wavefront加载器,但在我的研究中,我找到了这个库Tiny Obj Loader。这个库是用C ++编写的,除了C ++ STL之外没有任何依赖。它可以很好地处理Wavefront规范的边缘情况,而且速度非常快。用户必须做的事情是将Tiny OBJ对象转换为他们的代码。 TinyObjLoader也被许多项目采用。我为没有直接回答这个问题而道歉,我的愿望是了解这个伟大的图书馆。