Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved obj file parsing efficiency. Make parsing robust against situations where there are more normals than points. Added unit tests. #2450

Merged
merged 7 commits into from
Sep 21, 2018
48 changes: 28 additions & 20 deletions io/src/obj_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ pcl::OBJReader::readHeader (const std::string &file_name, pcl::PCLPointCloud2 &c
// bool material_found = false;
std::vector<std::string> material_files;
std::size_t nr_point = 0;
std::vector<std::string> st;

try
{
Expand All @@ -390,35 +389,40 @@ pcl::OBJReader::readHeader (const std::string &file_name, pcl::PCLPointCloud2 &c
sstream.imbue (std::locale::classic ());
line = sstream.str ();
boost::trim (line);
pherbers marked this conversation as resolved.
Show resolved Hide resolved
boost::split (st, line, boost::is_any_of ("\t\r "), boost::token_compress_on);

// Ignore comments
if (st.at (0) == "#")
if (line.at (0) == '#')
pherbers marked this conversation as resolved.
Show resolved Hide resolved
continue;

// Vertex
if (st.at (0) == "v")
// Vertex, vertex texture or vertex normal
if (line.at (0) == 'v')
{
++nr_point;
continue;
}
// Vertex (v)
if ((line.at(1) == ' ')) {
++nr_point;
continue;
}

// Vertex texture
if ((st.at (0) == "vt") && !vertex_texture_found)
{
vertex_texture_found = true;
continue;
}
// Vertex texture (vt)
else if ((line.at(1) == 't') && !vertex_texture_found)
{
vertex_texture_found = true;
continue;
}

// Vertex normal
if ((st.at (0) == "vn") && !vertex_normal_found)
{
vertex_normal_found = true;
continue;
// Vertex normal (vn)
else if ((line.at(1) == 'n') && !vertex_normal_found)
{
vertex_normal_found = true;
continue;
}
}

// Material library, skip for now!
if (st.at (0) == "mtllib")
if (line.substr (0, 6) == "mtllib")
{
std::vector<std::string> st;
boost::split(st, line, boost::is_any_of("\t\r "), boost::token_compress_on);
material_files.push_back (st.at (1));
continue;
}
Expand Down Expand Up @@ -588,6 +592,10 @@ pcl::OBJReader::read (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
// Vertex normal
if (st[0] == "vn")
{
if (normal_idx >= cloud.width)
{
continue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should print a PCL_WARNING the first time you encounter a normal from a non existing point so that the user knows there are is an unexpected problem, but it's being gracefully handled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 3d34bad.

}
try
{
for (int i = 1, f = normal_x_field; i < 4; ++i, ++f)
Expand Down