Merge pull request #7392 from MaelRL/CGAL_IO-Obj_fixes-GF

Fix issues in OBJ I/O
This commit is contained in:
Laurent Rineau 2023-04-24 14:08:22 +02:00
commit 4d76e06383
3 changed files with 47 additions and 10 deletions

View File

@ -23,18 +23,32 @@ int main(int argc, char* argv[])
Surface_mesh mesh; Surface_mesh mesh;
if(!PMP::IO::read_polygon_mesh(filename, mesh)) if(!PMP::IO::read_polygon_mesh(filename, mesh))
{ {
std::cerr << "Invalid input." << std::endl; std::cerr << "Error: Invalid input." << std::endl;
return 1; return EXIT_FAILURE;
} }
if(is_empty(mesh))
{
std::cerr << "Warning: empty file?" << std::endl;
return EXIT_SUCCESS;
}
if(!CGAL::is_triangle_mesh(mesh))
std::cout << "Input mesh is not triangulated." << std::endl;
else
std::cout << "Input mesh is triangulated." << std::endl;
PMP::triangulate_faces(mesh); PMP::triangulate_faces(mesh);
// Confirm that all faces are triangles. // Confirm that all faces are triangles.
for(boost::graph_traits<Surface_mesh>::face_descriptor f : faces(mesh)) for(boost::graph_traits<Surface_mesh>::face_descriptor f : faces(mesh))
{
if(!CGAL::is_triangle(halfedge(f, mesh), mesh)) if(!CGAL::is_triangle(halfedge(f, mesh), mesh))
std::cerr << "Error: non-triangular face left in mesh." << std::endl; std::cerr << "Error: non-triangular face left in mesh." << std::endl;
}
CGAL::IO::write_polygon_mesh(outfilename, mesh, CGAL::parameters::stream_precision(17)); CGAL::IO::write_polygon_mesh(outfilename, mesh, CGAL::parameters::stream_precision(17));
return 0; return EXIT_SUCCESS;
} }

View File

@ -105,7 +105,7 @@ bool read_polygon_mesh(const std::string& fname,
std::vector<Point> points; std::vector<Point> points;
std::vector<std::vector<std::size_t> > faces; std::vector<std::vector<std::size_t> > faces;
if(!CGAL::IO::read_polygon_soup(fname, points, faces)) if(!CGAL::IO::read_polygon_soup(fname, points, faces, CGAL::parameters::verbose(verbose)))
{ {
if(verbose) if(verbose)
std::cerr << "Warning: cannot read polygon soup" << std::endl; std::cerr << "Warning: cannot read polygon soup" << std::endl;

View File

@ -24,6 +24,7 @@
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
#include <CGAL/Named_function_parameters.h> #include <CGAL/Named_function_parameters.h>
#include <algorithm>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -67,12 +68,30 @@ bool read_OBJ(std::istream& is,
bool tex_found(false), norm_found(false); bool tex_found(false), norm_found(false);
while(getline(is, line)) while(getline(is, line))
{ {
if(line.empty()) // get last non-whitespace, non-null character
continue; auto last = std::find_if(line.rbegin(), line.rend(), [](char c) { return c != '\0' && !std::isspace(c); });
if(last == line.rend())
continue; // line is empty or only whitespace
// keep reading lines as long as the last non-whitespace, non-null character is a backslash
while(last != line.rend() && *last == '\\')
{
// remove everything from the backslash (included)
line = line.substr(0, line.size() - (last - line.rbegin()) - 1);
std::string next_line;
if(!getline(is, next_line))
break;
line += next_line;
last = std::find_if(line.rbegin(), line.rend(), [](char c) { return c != '\0' && !std::isspace(c); });
}
CGAL_assertion(!line.empty());
std::istringstream iss(line); std::istringstream iss(line);
if(!(iss >> s)) if(!(iss >> s))
continue; // can't read anything on the line, whitespace only? continue;
if(s == "v") if(s == "v")
{ {
@ -122,7 +141,11 @@ bool read_OBJ(std::istream& is,
} }
if(iss.bad()) if(iss.bad())
{
if(verbose)
std::cerr << "error while reading OBJ face." << std::endl;
return false; return false;
}
} }
else if(s.front() == '#') else if(s.front() == '#')
{ {
@ -148,15 +171,15 @@ bool read_OBJ(std::istream& is,
else else
{ {
if(verbose) if(verbose)
std::cerr << "error: unrecognized line: " << s << std::endl; std::cerr << "Error: unrecognized line: " << s << std::endl;
return false; return false;
} }
} }
if(norm_found && verbose) if(norm_found && verbose)
std::cout<<"NOTE: normals were found in this file, but were discarded."<<std::endl; std::cout << "NOTE: normals were found in this file, but were discarded." << std::endl;
if(tex_found && verbose) if(tex_found && verbose)
std::cout<<"NOTE: textures were found in this file, but were discarded."<<std::endl; std::cout << "NOTE: textures were found in this file, but were discarded." << std::endl;
if(points.empty() || polygons.empty()) if(points.empty() || polygons.empty())
{ {