Merge pull request #4203 from maxGimeno/Demo-Fix_detect_boundaries-GF

Polyhedron Demo: Fix  stitching plugin
This commit is contained in:
Laurent Rineau 2019-10-15 16:34:14 +02:00
commit 8d7932cdc2
5 changed files with 68 additions and 74 deletions

View File

@ -2,6 +2,7 @@
#include "Scene_polygon_soup_item.h"
#include "Scene_points_with_normal_item.h"
#include <CGAL/Three/Three.h>
#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
@ -181,6 +182,19 @@ Polyhedron_demo_off_plugin::load_off(QFileInfo fileinfo) {
tr("%1 isolated vertices found")
.arg(item->getNbIsolatedvertices()));
}
typedef boost::function_output_iterator<CGAL::internal::Throw_at_output> OutputIterator;
try{
CGAL::Polygon_mesh_processing::non_manifold_vertices(*surface_mesh, OutputIterator());
}
catch( CGAL::internal::Throw_at_output::Throw_at_output_exception& )
{
QApplication::restoreOverrideCursor();
QMessageBox::warning((QWidget*)NULL,
tr("Non Manifold Vertices"),
tr("Non-manifold vertices have been found"));
}
if(item->isItemMulticolor())
item->computeItemColorVectorAutomatically(true);
return item;

View File

@ -14,25 +14,6 @@
#include <CGAL/boost/graph/helpers.h>
#include <boost/graph/filtered_graph.hpp>
template <typename G>
struct Is_border {
const G& g;
Is_border(const G& g)
: g(g)
{}
template <typename Descriptor>
bool operator()(const Descriptor& d) const {
return is_border(d,g);
}
bool operator()(typename boost::graph_traits<G>::vertex_descriptor d) const {
return is_border(d,g) != boost::none;
}
};
using namespace CGAL::Three;
class Polyhedron_demo_polyhedron_stitching_plugin :
public QObject,
@ -90,30 +71,6 @@ public Q_SLOTS:
}; // end Polyhedron_demo_polyhedron_stitching_plugin
template <typename Poly>
struct Polyline_visitor
{
Scene_polylines_item* new_item;
typename boost::property_map<Poly, CGAL::vertex_point_t>::const_type vpm;
Polyline_visitor(const Poly& poly, Scene_polylines_item* new_item)
: new_item(new_item), vpm(get(CGAL::vertex_point,poly))
{}
void start_new_polyline()
{
new_item->polylines.push_back( Scene_polylines_item::Polyline() );
}
void add_node(typename boost::graph_traits<Poly>::vertex_descriptor vd)
{
new_item->polylines.back().push_back(get(vpm,vd));
}
void end_polyline(){}
};
template <typename Item>
void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_triggered(Scene_interface::Item_id index)
@ -127,17 +84,15 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_trigger
FaceGraph* pMesh = item->polyhedron();
normalize_border(*pMesh);
typedef boost::filtered_graph<FaceGraph,Is_border<FaceGraph>, Is_border<FaceGraph> > BorderGraph;
Is_border<FaceGraph> ib(*pMesh);
BorderGraph bg(*pMesh,ib,ib);
Polyline_visitor<FaceGraph> polyline_visitor(*pMesh, new_item);
CGAL::split_graph_into_polylines( bg,
polyline_visitor,
CGAL::internal::IsTerminalDefault() );
for(auto ed : edges(*pMesh))
{
if(pMesh->is_border(ed))
{
new_item->polylines.push_back(Scene_polylines_item::Polyline());
new_item->polylines.back().push_back(pMesh->point(pMesh->source(pMesh->halfedge(ed))));
new_item->polylines.back().push_back(pMesh->point(pMesh->target(pMesh->halfedge(ed))));
}
}
if (new_item->polylines.empty())
{

View File

@ -260,6 +260,7 @@ struct Scene_surface_mesh_item_priv{
double volume, area;
unsigned int number_of_null_length_edges;
unsigned int number_of_degenerated_faces;
bool has_nm_vertices;
int genus;
bool self_intersect;
mutable QSlider* alphaSlider;
@ -1515,6 +1516,7 @@ invalidate_stats()
{
number_of_degenerated_faces = (unsigned int)(-1);
number_of_null_length_edges = (unsigned int)(-1);
has_nm_vertices = false;
volume = -std::numeric_limits<double>::infinity();
area = -std::numeric_limits<double>::infinity();
self_intersect = false;
@ -1568,11 +1570,30 @@ QString Scene_surface_mesh_item::computeStats(int type)
}
faces_aspect_ratio(d->smesh_, min_altitude, min_ar, max_ar, mean_ar);
}
if(type == HAS_NM_VERTICES)
{
d->has_nm_vertices = false;
typedef boost::function_output_iterator<CGAL::internal::Throw_at_output> OutputIterator;
try{
CGAL::Polygon_mesh_processing::non_manifold_vertices(*d->smesh_, OutputIterator());
}
catch( CGAL::internal::Throw_at_output::Throw_at_output_exception& )
{
d->has_nm_vertices = true;
}
}
switch(type)
{
case NB_VERTICES:
return QString::number(num_vertices(*d->smesh_));
case HAS_NM_VERTICES:
{
if(d->has_nm_vertices)
return QString("Yes");
return QString("No");
}
case NB_FACETS:
return QString::number(num_faces(*d->smesh_));
@ -1721,14 +1742,15 @@ CGAL::Three::Scene_item::Header_data Scene_surface_mesh_item::header() const
CGAL::Three::Scene_item::Header_data data;
//categories
data.categories.append(std::pair<QString,int>(QString("Properties"),9));
data.categories.append(std::pair<QString,int>(QString("Properties"),11));
data.categories.append(std::pair<QString,int>(QString("Faces"),10));
data.categories.append(std::pair<QString,int>(QString("Edges"),7));
data.categories.append(std::pair<QString,int>(QString("Angles"),2));
data.categories.append(std::pair<QString,int>(QString("Edges"),6));
data.categories.append(std::pair<QString,int>(QString("Angles"),3));
//titles
data.titles.append(QString("#Vertices"));
data.titles.append(QString("Has Non-manifold Vertices"));
data.titles.append(QString("#Connected Components"));
data.titles.append(QString("#Border Edges"));
data.titles.append(QString("Pure Triangle"));

View File

@ -106,6 +106,7 @@ public:
//statistics
enum STATS {
NB_VERTICES = 0,
HAS_NM_VERTICES,
NB_CONNECTED_COMPOS,
NB_BORDER_EDGES,
IS_PURE_TRIANGLE,

View File

@ -1758,6 +1758,8 @@ public:
/// With `check_all_incident_halfedges == false` the function returns `true`, if the incident
/// halfedge associated to vertex `v` is a border halfedge, or if the vertex is isolated.
/// \cgalAdvancedEnd
/// \attention If the data contained in the `Surface_mesh` is not a 2-manifold, then
/// this operation is not guaranteed to return the right result.
bool is_border(Vertex_index v, bool check_all_incident_halfedges = true) const
{
Halfedge_index h(halfedge(v));