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;
if(!PMP::IO::read_polygon_mesh(filename, mesh))
{
std::cerr << "Invalid input." << std::endl;
return 1;
std::cerr << "Error: Invalid input." << std::endl;
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);
// Confirm that all faces are triangles.
for(boost::graph_traits<Surface_mesh>::face_descriptor f : faces(mesh))
{
if(!CGAL::is_triangle(halfedge(f, mesh), mesh))
std::cerr << "Error: non-triangular face left in mesh." << std::endl;
}
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<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)
std::cerr << "Warning: cannot read polygon soup" << std::endl;

View File

@ -24,6 +24,7 @@
#include <boost/range/value_type.hpp>
#include <CGAL/Named_function_parameters.h>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
@ -67,12 +68,30 @@ bool read_OBJ(std::istream& is,
bool tex_found(false), norm_found(false);
while(getline(is, line))
{
if(line.empty())
continue;
// get last non-whitespace, non-null character
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);
if(!(iss >> s))
continue; // can't read anything on the line, whitespace only?
continue;
if(s == "v")
{
@ -122,8 +141,12 @@ bool read_OBJ(std::istream& is,
}
if(iss.bad())
{
if(verbose)
std::cerr << "error while reading OBJ face." << std::endl;
return false;
}
}
else if(s.front() == '#')
{
// this is a commented line, ignored
@ -148,15 +171,15 @@ bool read_OBJ(std::istream& is,
else
{
if(verbose)
std::cerr << "error: unrecognized line: " << s << std::endl;
std::cerr << "Error: unrecognized line: " << s << std::endl;
return false;
}
}
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)
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())
{