Merge pull request #2071 from janetournois/Polyhedron_demo-improve_surf_reader-GF

Polyhedron demo : improve .surf reader
This commit is contained in:
Laurent Rineau 2017-05-19 10:28:22 +02:00
commit a07cd292d9
4 changed files with 67 additions and 16 deletions

View File

@ -29,6 +29,7 @@
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h> #include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
#include <CGAL/algorithm.h> #include <CGAL/algorithm.h>
#include <set> #include <set>
#include <boost/dynamic_bitset.hpp>
#include <boost/range/size.hpp> #include <boost/range/size.hpp>
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
@ -67,13 +68,29 @@ public:
_polygons(polygons) _polygons(polygons)
{ } { }
void operator()(PM& pmesh) void operator()(PM& pmesh, const bool insert_isolated_vertices = true)
{ {
Vpmap vpmap = get(CGAL::vertex_point, pmesh); Vpmap vpmap = get(CGAL::vertex_point, pmesh);
boost::dynamic_bitset<> not_isolated;
if (!insert_isolated_vertices)
{
not_isolated.resize(_points.size());
for (std::size_t i = 0, end = _polygons.size(); i < end; ++i)
{
const Polygon& polygon = _polygons[i];
const std::size_t size = polygon.size();
for (std::size_t j = 0; j < size; ++j)
not_isolated.set(polygon[j], true);
}
}
std::vector<vertex_descriptor> vertices(_points.size()); std::vector<vertex_descriptor> vertices(_points.size());
for (std::size_t i = 0, end = _points.size(); i < end; ++i) for (std::size_t i = 0, end = _points.size(); i < end; ++i)
{ {
if (!insert_isolated_vertices && !not_isolated.test(i))
continue;
Point_3 pi(_points[i][0], _points[i][1], _points[i][2]); Point_3 pi(_points[i][0], _points[i][1], _points[i][2]);
vertices[i] = add_vertex(pmesh); vertices[i] = add_vertex(pmesh);
put(vpmap, vertices[i], pi); put(vpmap, vertices[i], pi);
@ -162,6 +179,8 @@ public:
typename Orienter::Marked_edges marked_edges; typename Orienter::Marked_edges marked_edges;
Orienter::fill_edge_map(edges, marked_edges, polygons); Orienter::fill_edge_map(edges, marked_edges, polygons);
//returns false if duplication is necessary //returns false if duplication is necessary
if (!marked_edges.empty())
return false;
return Orienter::has_singular_vertices(static_cast<std::size_t>(max_id+1),polygons,edges,marked_edges); return Orienter::has_singular_vertices(static_cast<std::size_t>(max_id+1),polygons,edges,marked_edges);
} }

View File

@ -15,6 +15,7 @@
#include "Color_map.h" #include "Color_map.h"
#include <fstream> #include <fstream>
#include <boost/container/flat_set.hpp>
using namespace CGAL::Three; using namespace CGAL::Three;
class Surf_io_plugin: class Surf_io_plugin:
@ -62,13 +63,19 @@ CGAL::Three::Scene_item* Surf_io_plugin::load(QFileInfo fileinfo)
std::vector<MaterialData> material_data; std::vector<MaterialData> material_data;
CGAL::Bbox_3 grid_box; CGAL::Bbox_3 grid_box;
CGAL::cpp11::array<unsigned int, 3> grid_size = {{1, 1, 1}}; CGAL::cpp11::array<unsigned int, 3> grid_size = {{1, 1, 1}};
read_surf(in, patches, material_data, grid_box, grid_size); boost::container::flat_set<Polyhedron::Point_3> duplicated_points;
read_surf(in, patches, material_data, grid_box, grid_size
, std::inserter(duplicated_points, duplicated_points.end()));
for(std::size_t i=0; i<material_data.size(); ++i) for(std::size_t i=0; i<material_data.size(); ++i)
{ {
std::cout<<"The patch #"<<i<<":\n -inner region : material's id = "<<material_data[i].innerRegion.first<<" material's name = " std::cout<<"The patch #"<<i<<":\n -inner region : material's id = "<<material_data[i].innerRegion.first<<" material's name = "
<<material_data[i].innerRegion.second<<"\n -outer region: material's id = "<<material_data[i].outerRegion.first<<" material's name = " <<material_data[i].innerRegion.second<<"\n -outer region: material's id = "<<material_data[i].outerRegion.first<<" material's name = "
<<material_data[i].outerRegion.second<<std::endl; <<material_data[i].outerRegion.second<<std::endl;
} }
if (!duplicated_points.empty())
std::cout << duplicated_points.size() << " points have been duplicated." << std::endl;
std::vector<QColor> colors_; std::vector<QColor> colors_;
compute_color_map(QColor(100, 100, 255), static_cast<unsigned>(patches.size()), compute_color_map(QColor(100, 100, 255), static_cast<unsigned>(patches.size()),
std::back_inserter(colors_)); std::back_inserter(colors_));

View File

@ -14,6 +14,7 @@
#include "Color_map.h" #include "Color_map.h"
#include <fstream> #include <fstream>
#include <boost/container/flat_set.hpp>
using namespace CGAL::Three; using namespace CGAL::Three;
class Surf_io_plugin: class Surf_io_plugin:
@ -51,6 +52,7 @@ public:
CGAL::Three::Scene_item* Surf_io_plugin::load(QFileInfo fileinfo) CGAL::Three::Scene_item* Surf_io_plugin::load(QFileInfo fileinfo)
{ {
typedef Scene_surface_mesh_item::SMesh SMesh; typedef Scene_surface_mesh_item::SMesh SMesh;
typedef Scene_surface_mesh_item::Point Point;
// Open file // Open file
std::ifstream in(fileinfo.filePath().toUtf8()); std::ifstream in(fileinfo.filePath().toUtf8());
if(!in) { if(!in) {
@ -62,13 +64,19 @@ CGAL::Three::Scene_item* Surf_io_plugin::load(QFileInfo fileinfo)
std::vector<MaterialData> material_data; std::vector<MaterialData> material_data;
CGAL::Bbox_3 grid_box; CGAL::Bbox_3 grid_box;
CGAL::cpp11::array<unsigned int, 3> grid_size = {{1, 1, 1}}; CGAL::cpp11::array<unsigned int, 3> grid_size = {{1, 1, 1}};
read_surf(in, patches, material_data, grid_box, grid_size); boost::container::flat_set<Point> duplicated_points;
for(std::size_t i=0; i<material_data.size(); ++i) read_surf(in, patches, material_data, grid_box, grid_size
, std::inserter(duplicated_points, duplicated_points.end()));
for (std::size_t i = 0; i<material_data.size(); ++i)
{ {
std::cout<<"The patch #"<<i<<":\n -inner region : material's id = "<<material_data[i].innerRegion.first<<" material's name = " std::cout<<"The patch #"<<i<<":\n -inner region : material's id = "<<material_data[i].innerRegion.first<<" material's name = "
<<material_data[i].innerRegion.second<<"\n -outer region: material's id = "<<material_data[i].outerRegion.first<<" material's name = " <<material_data[i].innerRegion.second<<"\n -outer region: material's id = "<<material_data[i].outerRegion.first<<" material's name = "
<<material_data[i].outerRegion.second<<std::endl; <<material_data[i].outerRegion.second<<std::endl;
} }
if (!duplicated_points.empty())
std::cout << duplicated_points.size() << " points have been duplicated." << std::endl;
std::vector<QColor> colors_; std::vector<QColor> colors_;
compute_color_map(QColor(100, 100, 255), static_cast<unsigned>(patches.size()), compute_color_map(QColor(100, 100, 255), static_cast<unsigned>(patches.size()),
std::back_inserter(colors_)); std::back_inserter(colors_));

View File

@ -36,6 +36,7 @@ bool get_material_metadata(std::istream& input,
iss >> _material.second;//name iss >> _material.second;//name
static int material_id = 0;
while (std::getline(input, line)) while (std::getline(input, line))
{ {
std::string prop; //property std::string prop; //property
@ -45,7 +46,9 @@ bool get_material_metadata(std::istream& input,
if (prop.compare("Id") == 0) if (prop.compare("Id") == 0)
{ {
iss >> _material.first; int tmp_id;
iss >> tmp_id;
_material.first = material_id++;
if ((0 == to_lower_case(_material.second).compare("exterior")) if ((0 == to_lower_case(_material.second).compare("exterior"))
&& _material.first != 0) && _material.first != 0)
@ -74,11 +77,12 @@ bool line_starts_with(const std::string& line, const char* cstr)
* read_surf reads a file which extension is .surf and fills `output` with one `Mesh` per patch. * read_surf reads a file which extension is .surf and fills `output` with one `Mesh` per patch.
* Mesh is a model of FaceListGraph. * Mesh is a model of FaceListGraph.
*/ */
template<class Mesh, class NamedParameters> template<class Mesh, typename DuplicatedPointsOutIterator, class NamedParameters>
bool read_surf(std::istream& input, std::vector<Mesh>& output, bool read_surf(std::istream& input, std::vector<Mesh>& output,
std::vector<MaterialData>& metadata, std::vector<MaterialData>& metadata,
CGAL::Bbox_3& grid_box, CGAL::Bbox_3& grid_box,
CGAL::cpp11::array<unsigned int, 3>& grid_size, CGAL::cpp11::array<unsigned int, 3>& grid_size,
DuplicatedPointsOutIterator out,
const NamedParameters&) const NamedParameters&)
{ {
typedef typename CGAL::GetGeomTraits<Mesh, typedef typename CGAL::GetGeomTraits<Mesh,
@ -230,7 +234,8 @@ bool read_surf(std::istream& input, std::vector<Mesh>& output,
} }
//connect triangles //connect triangles
std::vector<std::vector<std::size_t> > polygons; typedef CGAL::cpp11::array<std::size_t, 3> Triangle_ind;
std::vector<Triangle_ind> polygons;
polygons.reserve(nb_triangles); polygons.reserve(nb_triangles);
while(std::getline(input, line)) while(std::getline(input, line))
{ {
@ -246,7 +251,7 @@ bool read_surf(std::istream& input, std::vector<Mesh>& output,
iss.str(line); iss.str(line);
iss >> index[0] >> index[1] >> index[2]; iss >> index[0] >> index[1] >> index[2];
std::vector<std::size_t> polygon(3); Triangle_ind polygon;
polygon[0] = index[0] - 1; polygon[0] = index[0] - 1;
polygon[1] = index[1] - 1; polygon[1] = index[1] - 1;
polygon[2] = index[2] - 1; polygon[2] = index[2] - 1;
@ -260,33 +265,45 @@ bool read_surf(std::istream& input, std::vector<Mesh>& output,
{ {
std::cout << "Orientation of patch #" << (i + 1) << "..."; std::cout << "Orientation of patch #" << (i + 1) << "...";
std::cout.flush(); std::cout.flush();
const std::size_t nbp_init = points.size();
bool no_duplicates = bool no_duplicates =
PMP::orient_polygon_soup(points, polygons);//returns false if some points PMP::orient_polygon_soup(points, polygons);//returns false if some points
//were duplicated //were duplicated
std::cout << "\rOrientation of patch #" << (i + 1) << " done"; std::cout << "\rOrientation of patch #" << (i + 1) << " done";
if (!no_duplicates)
std::cout << " (non manifold -> duplicated vertices)"; if(!no_duplicates) //collect duplicates
{
for (std::size_t i = nbp_init; i < points.size(); ++i)
*out++ = points[i];
std::cout << " (non manifold -> "
<< (points.size() - nbp_init) << " duplicated vertices)";
}
std::cout << "." << std::endl; std::cout << "." << std::endl;
} }
Mesh& mesh = output[i]; Mesh& mesh = output[i];
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh( PMP::internal::Polygon_soup_to_polygon_mesh<Mesh, Point_3, Triangle_ind>
points, polygons, mesh); converter(points, polygons);
CGAL::Polygon_mesh_processing::remove_isolated_vertices(mesh); converter(mesh, false/*insert_isolated_vertices*/);
CGAL_assertion(PMP::remove_isolated_vertices(mesh) == 0);
CGAL_assertion(is_valid(mesh)); CGAL_assertion(is_valid(mesh));
} // end loop on patches } // end loop on patches
return true; return true;
} }
template<class Mesh> template<class Mesh, typename DuplicatedPointsOutIterator>
bool read_surf(std::istream& input, std::vector<Mesh>& output, bool read_surf(std::istream& input, std::vector<Mesh>& output,
std::vector<MaterialData>& metadata, std::vector<MaterialData>& metadata,
CGAL::Bbox_3& grid_box, CGAL::Bbox_3& grid_box,
CGAL::cpp11::array<unsigned int, 3>& grid_size) CGAL::cpp11::array<unsigned int, 3>& grid_size,
DuplicatedPointsOutIterator out)
{ {
return read_surf(input, output, metadata, grid_box, grid_size, return read_surf(input, output, metadata, grid_box, grid_size, out,
CGAL::Polygon_mesh_processing::parameters::all_default()); CGAL::Polygon_mesh_processing::parameters::all_default());
} }