mirror of https://github.com/CGAL/cgal
Add stats to the selection_item
This commit is contained in:
parent
bd2b055f1e
commit
bd8b39d162
|
|
@ -2435,7 +2435,10 @@ QString MainWindow::get_item_stats()
|
||||||
QList<QString> classnames;
|
QList<QString> classnames;
|
||||||
Q_FOREACH(int id, scene->selectionIndices())
|
Q_FOREACH(int id, scene->selectionIndices())
|
||||||
{
|
{
|
||||||
QString classname = scene->item(id)->metaObject()->className();
|
Scene_item* item = scene->item(id);
|
||||||
|
QString classname = item->property("classname").toString();
|
||||||
|
if(classname.isEmpty())
|
||||||
|
classname = item->metaObject()->className();
|
||||||
if(!classnames.contains(classname))
|
if(!classnames.contains(classname))
|
||||||
classnames << classname;
|
classnames << classname;
|
||||||
}
|
}
|
||||||
|
|
@ -2446,12 +2449,18 @@ QString MainWindow::get_item_stats()
|
||||||
{
|
{
|
||||||
Scene_item* s_item = scene->item(id);
|
Scene_item* s_item = scene->item(id);
|
||||||
for(int i=0; i<items.size(); i++)
|
for(int i=0; i<items.size(); i++)
|
||||||
if(classnames.at(i).contains(s_item->metaObject()->className()))
|
{
|
||||||
|
Scene_item* item = scene->item(id);
|
||||||
|
QString classname = item->property("classname").toString();
|
||||||
|
if(classname.isEmpty())
|
||||||
|
classname = item->metaObject()->className();
|
||||||
|
if(classnames.at(i).contains(classname))
|
||||||
{
|
{
|
||||||
items[i] << s_item;
|
items[i] << s_item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//last step :: making tables for each type of item
|
//last step :: making tables for each type of item
|
||||||
QString str;
|
QString str;
|
||||||
for(int i=0; i< classnames.size(); i++)
|
for(int i=0; i< classnames.size(); i++)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/Handle_hash_function.h>
|
#include <CGAL/Handle_hash_function.h>
|
||||||
#include <CGAL/Unique_hash_map.h>
|
#include <CGAL/Unique_hash_map.h>
|
||||||
|
#include <CGAL/statistics_helpers.h>
|
||||||
|
|
||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
#include <boost/unordered_set.hpp>
|
#include <boost/unordered_set.hpp>
|
||||||
|
|
@ -21,6 +22,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "triangulate_primitive.h"
|
#include "triangulate_primitive.h"
|
||||||
|
#include <CGAL/boost/graph/Face_filtered_graph.h>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/measure.h>
|
||||||
|
#include <CGAL/boost/graph/properties.h>
|
||||||
|
|
||||||
typedef Scene_surface_mesh_item Scene_face_graph_item;
|
typedef Scene_surface_mesh_item Scene_face_graph_item;
|
||||||
|
|
||||||
|
|
@ -50,7 +54,8 @@ struct Scene_polyhedron_selection_item_priv{
|
||||||
Scene_polyhedron_selection_item_priv(Scene_polyhedron_selection_item* parent):
|
Scene_polyhedron_selection_item_priv(Scene_polyhedron_selection_item* parent):
|
||||||
item(parent)
|
item(parent)
|
||||||
{
|
{
|
||||||
|
filtered_graph = nullptr;
|
||||||
|
item->setProperty("classname", QString("surface_mesh"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const;
|
void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const;
|
||||||
|
|
@ -162,6 +167,7 @@ struct Scene_polyhedron_selection_item_priv{
|
||||||
mutable QOpenGLShaderProgram *program;
|
mutable QOpenGLShaderProgram *program;
|
||||||
mutable bool are_HL_buffers_filled;
|
mutable bool are_HL_buffers_filled;
|
||||||
Scene_polyhedron_selection_item* item;
|
Scene_polyhedron_selection_item* item;
|
||||||
|
CGAL::Face_filtered_graph<SMesh> *filtered_graph;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1970,6 +1976,11 @@ void Scene_polyhedron_selection_item::invalidateOpenGLBuffers() {
|
||||||
d->are_temp_buffers_filled = false;
|
d->are_temp_buffers_filled = false;
|
||||||
d->poly = polyhedron();
|
d->poly = polyhedron();
|
||||||
compute_bbox();
|
compute_bbox();
|
||||||
|
if(d->filtered_graph)
|
||||||
|
{
|
||||||
|
delete d->filtered_graph;
|
||||||
|
d->filtered_graph = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene_polyhedron_selection_item::add_to_selection()
|
void Scene_polyhedron_selection_item::add_to_selection()
|
||||||
|
|
@ -2317,3 +2328,287 @@ Scene_polyhedron_selection_item::toolTip() const
|
||||||
.arg(this->renderingModeName())
|
.arg(this->renderingModeName())
|
||||||
.arg(this->color().name());
|
.arg(this->color().name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Scene_polyhedron_selection_item::computeStats(int type)
|
||||||
|
{
|
||||||
|
if(!d->filtered_graph)
|
||||||
|
{
|
||||||
|
d->filtered_graph = new CGAL::Face_filtered_graph<SMesh>(*d->poly, selected_facets);
|
||||||
|
}
|
||||||
|
double minl, maxl, meanl, midl;
|
||||||
|
unsigned int number_of_null_length_edges;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MIN_LENGTH:
|
||||||
|
case MAX_LENGTH:
|
||||||
|
case MID_LENGTH:
|
||||||
|
case MEAN_LENGTH:
|
||||||
|
case NB_NULL_LENGTH:
|
||||||
|
if(selected_edges.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
else
|
||||||
|
edges_length(d->poly, selected_edges, minl, maxl, meanl, midl, number_of_null_length_edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
double mini, maxi, ave;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MIN_ANGLE:
|
||||||
|
case MAX_ANGLE:
|
||||||
|
case MEAN_ANGLE:
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
else
|
||||||
|
angles(d->poly, selected_facets, mini, maxi, ave);
|
||||||
|
}
|
||||||
|
double min_area, max_area, med_area, mean_area;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MIN_AREA:
|
||||||
|
case MAX_AREA:
|
||||||
|
case MEAN_AREA:
|
||||||
|
case MED_AREA:
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
else{
|
||||||
|
if(!is_triangle_mesh(*d->poly))
|
||||||
|
{
|
||||||
|
return QString("n/a");
|
||||||
|
}
|
||||||
|
faces_area(d->poly, selected_facets, min_area, max_area, mean_area, med_area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double min_altitude, min_ar, max_ar, mean_ar;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MIN_ALTITUDE:
|
||||||
|
case MIN_ASPECT_RATIO:
|
||||||
|
case MAX_ASPECT_RATIO:
|
||||||
|
case MEAN_ASPECT_RATIO:
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!is_triangle_mesh(*d->poly))
|
||||||
|
{
|
||||||
|
return QString("n/a");
|
||||||
|
}
|
||||||
|
faces_aspect_ratio(d->poly, selected_facets,min_altitude, min_ar, max_ar, mean_ar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case NB_VERTICES:
|
||||||
|
{
|
||||||
|
std::set<fg_vertex_descriptor> total_vertices;
|
||||||
|
for(auto v : selected_vertices)
|
||||||
|
{
|
||||||
|
total_vertices.insert(v);
|
||||||
|
}
|
||||||
|
for(auto e : selected_edges)
|
||||||
|
{
|
||||||
|
total_vertices.insert(target(e, *d->poly));
|
||||||
|
total_vertices.insert(source(e, *d->poly));
|
||||||
|
}
|
||||||
|
for(auto f : selected_facets)
|
||||||
|
{
|
||||||
|
for (auto v : CGAL::vertices_around_face(halfedge(f, *d->poly), *d->poly))
|
||||||
|
{
|
||||||
|
total_vertices.insert(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QString::number(total_vertices.size());
|
||||||
|
}
|
||||||
|
case NB_FACETS:
|
||||||
|
return QString::number(selected_facets.size());
|
||||||
|
|
||||||
|
case NB_CONNECTED_COMPOS:
|
||||||
|
{
|
||||||
|
// Extract the part n°0 of the partition into a new, independent mesh
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
boost::vector_property_map<int,
|
||||||
|
boost::property_map<SMesh, boost::face_index_t>::type>
|
||||||
|
fccmap(get(boost::face_index, *d->filtered_graph));
|
||||||
|
|
||||||
|
return QString::number(CGAL::Polygon_mesh_processing::connected_components(*d->filtered_graph, fccmap));
|
||||||
|
}
|
||||||
|
|
||||||
|
case NB_BORDER_EDGES:
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
BOOST_FOREACH(halfedge_descriptor hd, halfedges(*d->poly))
|
||||||
|
{
|
||||||
|
if(is_border(hd, *d->poly)
|
||||||
|
&& selected_edges.find(edge(hd, *d->poly)) != selected_edges.end())
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return QString::number(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
case NB_EDGES:{
|
||||||
|
std::set<fg_edge_descriptor> total_edges;
|
||||||
|
for(auto e : selected_edges)
|
||||||
|
{
|
||||||
|
total_edges.insert(e);
|
||||||
|
}
|
||||||
|
for(auto f : selected_facets)
|
||||||
|
{
|
||||||
|
for (auto e : CGAL::edges_around_face(halfedge(f, *d->poly), *d->poly))
|
||||||
|
{
|
||||||
|
total_edges.insert(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QString::number(total_edges.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
case VOLUME:
|
||||||
|
return QString("n/a");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENUS:
|
||||||
|
return QString("n/a");
|
||||||
|
break;
|
||||||
|
case NB_DEGENERATED_FACES:
|
||||||
|
{
|
||||||
|
if(is_triangle_mesh(*d->poly))
|
||||||
|
{
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
return QString::number(nb_degenerate_faces(d->filtered_graph));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QString("n/a");
|
||||||
|
}
|
||||||
|
case AREA:
|
||||||
|
{
|
||||||
|
if(is_triangle_mesh(*d->poly))
|
||||||
|
{
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
return QString::number(CGAL::Polygon_mesh_processing::area(*d->filtered_graph));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QString("n/a");
|
||||||
|
}
|
||||||
|
|
||||||
|
case SELFINTER:
|
||||||
|
{
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
if(is_triangle_mesh(*d->poly)){
|
||||||
|
bool self_intersect
|
||||||
|
= CGAL::Polygon_mesh_processing::does_self_intersect(*(d->poly));
|
||||||
|
if (self_intersect)
|
||||||
|
return QString("Yes");
|
||||||
|
else
|
||||||
|
return QString("No");
|
||||||
|
}
|
||||||
|
return QString("n/a");
|
||||||
|
}
|
||||||
|
case MIN_LENGTH:
|
||||||
|
return QString::number(minl);
|
||||||
|
case MAX_LENGTH:
|
||||||
|
return QString::number(maxl);
|
||||||
|
case MID_LENGTH:
|
||||||
|
return QString::number(midl);
|
||||||
|
case MEAN_LENGTH:
|
||||||
|
return QString::number(meanl);
|
||||||
|
case NB_NULL_LENGTH:
|
||||||
|
return QString::number(number_of_null_length_edges);
|
||||||
|
|
||||||
|
case MIN_ANGLE:
|
||||||
|
return QString::number(mini);
|
||||||
|
case MAX_ANGLE:
|
||||||
|
return QString::number(maxi);
|
||||||
|
case MEAN_ANGLE:
|
||||||
|
return QString::number(ave);
|
||||||
|
case HOLES:
|
||||||
|
{
|
||||||
|
return QString("n/a");
|
||||||
|
}
|
||||||
|
|
||||||
|
case MIN_AREA:
|
||||||
|
return QString::number(min_area);
|
||||||
|
case MAX_AREA:
|
||||||
|
return QString::number(max_area);
|
||||||
|
case MED_AREA:
|
||||||
|
return QString::number(med_area);
|
||||||
|
case MEAN_AREA:
|
||||||
|
return QString::number(mean_area);
|
||||||
|
case MIN_ALTITUDE:
|
||||||
|
return QString::number(min_altitude);
|
||||||
|
case MIN_ASPECT_RATIO:
|
||||||
|
return QString::number(min_ar);
|
||||||
|
case MAX_ASPECT_RATIO:
|
||||||
|
return QString::number(max_ar);
|
||||||
|
case MEAN_ASPECT_RATIO:
|
||||||
|
return QString::number(mean_ar);
|
||||||
|
case IS_PURE_TRIANGLE:
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(is_triangle_mesh(*d->poly))
|
||||||
|
return QString("yes");
|
||||||
|
else
|
||||||
|
return QString("no");
|
||||||
|
}
|
||||||
|
case IS_PURE_QUAD:
|
||||||
|
{
|
||||||
|
if(selected_facets.size() == 0)
|
||||||
|
return QString("n/a");
|
||||||
|
if (is_quad_mesh(*d->filtered_graph))
|
||||||
|
return QString("yes");
|
||||||
|
else
|
||||||
|
return QString("no");
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end switch
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
CGAL::Three::Scene_item::Header_data Scene_polyhedron_selection_item::header() const
|
||||||
|
{
|
||||||
|
CGAL::Three::Scene_item::Header_data data;
|
||||||
|
//categories
|
||||||
|
|
||||||
|
data.categories.append(std::pair<QString,int>(QString("Properties"),10));
|
||||||
|
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));
|
||||||
|
|
||||||
|
|
||||||
|
//titles
|
||||||
|
data.titles.append(QString("#Vertices"));
|
||||||
|
data.titles.append(QString("#Connected Components"));
|
||||||
|
data.titles.append(QString("#Border Edges"));
|
||||||
|
data.titles.append(QString("Pure Triangle"));
|
||||||
|
data.titles.append(QString("Pure Quad"));
|
||||||
|
data.titles.append(QString("#Degenerate Faces"));
|
||||||
|
data.titles.append(QString("Connected Components of the Boundary"));
|
||||||
|
data.titles.append(QString("Area"));
|
||||||
|
data.titles.append(QString("Volume"));
|
||||||
|
data.titles.append(QString("Self-Intersecting"));
|
||||||
|
data.titles.append(QString("#Faces"));
|
||||||
|
data.titles.append(QString("Min Area"));
|
||||||
|
data.titles.append(QString("Max Area"));
|
||||||
|
data.titles.append(QString("Median Area"));
|
||||||
|
data.titles.append(QString("Mean Area"));
|
||||||
|
data.titles.append(QString("Min Altitude"));
|
||||||
|
data.titles.append(QString("Min Aspect-Ratio"));
|
||||||
|
data.titles.append(QString("Max Aspect-Ratio"));
|
||||||
|
data.titles.append(QString("Mean Aspect-Ratio"));
|
||||||
|
data.titles.append(QString("Genus"));
|
||||||
|
data.titles.append(QString("#Edges"));
|
||||||
|
data.titles.append(QString("Minimum Length"));
|
||||||
|
data.titles.append(QString("Maximum Length"));
|
||||||
|
data.titles.append(QString("Median Length"));
|
||||||
|
data.titles.append(QString("Mean Length"));
|
||||||
|
data.titles.append(QString("#Degenerate Edges"));
|
||||||
|
data.titles.append(QString("Minimum"));
|
||||||
|
data.titles.append(QString("Maximum"));
|
||||||
|
data.titles.append(QString("Average"));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -996,6 +996,44 @@ public:
|
||||||
protected :
|
protected :
|
||||||
friend struct Scene_polyhedron_selection_item_priv;
|
friend struct Scene_polyhedron_selection_item_priv;
|
||||||
Scene_polyhedron_selection_item_priv *d;
|
Scene_polyhedron_selection_item_priv *d;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//statistics
|
||||||
|
enum STATS {
|
||||||
|
NB_VERTICES = 0,
|
||||||
|
NB_CONNECTED_COMPOS,
|
||||||
|
NB_BORDER_EDGES,
|
||||||
|
IS_PURE_TRIANGLE,
|
||||||
|
IS_PURE_QUAD,
|
||||||
|
NB_DEGENERATED_FACES,
|
||||||
|
HOLES,
|
||||||
|
AREA,
|
||||||
|
VOLUME,
|
||||||
|
SELFINTER,
|
||||||
|
NB_FACETS,
|
||||||
|
MIN_AREA,
|
||||||
|
MAX_AREA,
|
||||||
|
MED_AREA,
|
||||||
|
MEAN_AREA,
|
||||||
|
MIN_ALTITUDE,
|
||||||
|
MIN_ASPECT_RATIO,
|
||||||
|
MAX_ASPECT_RATIO,
|
||||||
|
MEAN_ASPECT_RATIO,
|
||||||
|
GENUS,
|
||||||
|
NB_EDGES,
|
||||||
|
MIN_LENGTH,
|
||||||
|
MAX_LENGTH,
|
||||||
|
MID_LENGTH,
|
||||||
|
MEAN_LENGTH,
|
||||||
|
NB_NULL_LENGTH,
|
||||||
|
MIN_ANGLE,
|
||||||
|
MAX_ANGLE,
|
||||||
|
MEAN_ANGLE
|
||||||
|
};
|
||||||
|
|
||||||
|
bool has_stats()const Q_DECL_OVERRIDE{return true;}
|
||||||
|
QString computeStats(int type)Q_DECL_OVERRIDE;
|
||||||
|
CGAL::Three::Scene_item::Header_data header() const Q_DECL_OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ struct Scene_surface_mesh_item_priv{
|
||||||
alphaSlider = NULL;
|
alphaSlider = NULL;
|
||||||
has_vcolors = false;
|
has_vcolors = false;
|
||||||
has_fcolors = false;
|
has_fcolors = false;
|
||||||
|
item->setProperty("classname", QString("surface_mesh"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene_surface_mesh_item_priv(SMesh* sm, Scene_surface_mesh_item *parent):
|
Scene_surface_mesh_item_priv(SMesh* sm, Scene_surface_mesh_item *parent):
|
||||||
|
|
@ -151,6 +152,7 @@ struct Scene_surface_mesh_item_priv{
|
||||||
alphaSlider = NULL;
|
alphaSlider = NULL;
|
||||||
has_vcolors = false;
|
has_vcolors = false;
|
||||||
has_fcolors = false;
|
has_fcolors = false;
|
||||||
|
item->setProperty("classname", QString("surface_mesh"));
|
||||||
}
|
}
|
||||||
|
|
||||||
~Scene_surface_mesh_item_priv()
|
~Scene_surface_mesh_item_priv()
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,35 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
template<typename Mesh>
|
template<typename Set>
|
||||||
void angles(Mesh* poly, double& mini, double& maxi, double& ave)
|
struct Angles_test_with_set
|
||||||
|
{
|
||||||
|
const Set& set;
|
||||||
|
typedef typename Set::value_type value_type;
|
||||||
|
Angles_test_with_set(const Set& set):set(set) {}
|
||||||
|
|
||||||
|
bool operator()(const value_type& f)
|
||||||
|
{
|
||||||
|
return (set.find(f) == set.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Angles_test
|
||||||
|
{
|
||||||
|
Angles_test() {}
|
||||||
|
template<typename T>
|
||||||
|
bool operator()(const T&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Mesh, typename Tester>
|
||||||
|
void compute_angles(Mesh* poly,Tester tester , double& mini, double& maxi, double& ave)
|
||||||
{
|
{
|
||||||
using namespace boost::accumulators;
|
using namespace boost::accumulators;
|
||||||
typedef typename boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
|
typedef typename boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
|
||||||
|
typedef typename boost::graph_traits<Mesh>::face_descriptor face_descriptor;
|
||||||
typedef typename boost::property_map<Mesh, CGAL::vertex_point_t>::type VPMap;
|
typedef typename boost::property_map<Mesh, CGAL::vertex_point_t>::type VPMap;
|
||||||
typedef typename CGAL::Kernel_traits< typename boost::property_traits<VPMap>::value_type >::Kernel Traits;
|
typedef typename CGAL::Kernel_traits< typename boost::property_traits<VPMap>::value_type >::Kernel Traits;
|
||||||
double rad_to_deg = 180. / CGAL_PI;
|
double rad_to_deg = 180. / CGAL_PI;
|
||||||
|
|
@ -33,7 +57,9 @@ void angles(Mesh* poly, double& mini, double& maxi, double& ave)
|
||||||
VPMap vpmap = get(CGAL::vertex_point, *poly);
|
VPMap vpmap = get(CGAL::vertex_point, *poly);
|
||||||
BOOST_FOREACH(halfedge_descriptor h, halfedges(*poly))
|
BOOST_FOREACH(halfedge_descriptor h, halfedges(*poly))
|
||||||
{
|
{
|
||||||
if (face(h, *poly) == boost::graph_traits<Mesh>::null_face())
|
face_descriptor f = face(h, *poly);
|
||||||
|
if (f == boost::graph_traits<Mesh>::null_face()
|
||||||
|
|| tester(f))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
typename Traits::Point_3 a = get(vpmap, source(h, *poly));
|
typename Traits::Point_3 a = get(vpmap, source(h, *poly));
|
||||||
|
|
@ -54,7 +80,22 @@ void angles(Mesh* poly, double& mini, double& maxi, double& ave)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Mesh>
|
template<typename Mesh>
|
||||||
void edges_length(Mesh* poly,
|
void angles(Mesh* poly, double& mini, double& maxi, double& ave)
|
||||||
|
{
|
||||||
|
compute_angles(poly, Angles_test(), mini, maxi, ave);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Mesh, typename Face_set>
|
||||||
|
void angles(Mesh* poly, const Face_set& faces, double& mini, double& maxi, double& ave)
|
||||||
|
{
|
||||||
|
Angles_test_with_set<Face_set> tester(faces);
|
||||||
|
compute_angles(poly, tester, mini, maxi, ave);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Mesh, typename Edge_range>
|
||||||
|
void edges_length(Mesh* poly, const Edge_range& range,
|
||||||
double& mini, double& maxi, double& mean, double& mid,
|
double& mini, double& maxi, double& mean, double& mid,
|
||||||
unsigned int& nb_degen)
|
unsigned int& nb_degen)
|
||||||
{
|
{
|
||||||
|
|
@ -69,7 +110,7 @@ void edges_length(Mesh* poly,
|
||||||
|
|
||||||
VPMap vpmap = get(CGAL::vertex_point, *poly);
|
VPMap vpmap = get(CGAL::vertex_point, *poly);
|
||||||
nb_degen = 0;
|
nb_degen = 0;
|
||||||
BOOST_FOREACH(edge_descriptor e, edges(*poly))
|
BOOST_FOREACH(edge_descriptor e, range)
|
||||||
{
|
{
|
||||||
halfedge_descriptor h = halfedge(e, *poly);
|
halfedge_descriptor h = halfedge(e, *poly);
|
||||||
Point a = get(vpmap, source(h, *poly));
|
Point a = get(vpmap, source(h, *poly));
|
||||||
|
|
@ -85,6 +126,13 @@ void edges_length(Mesh* poly,
|
||||||
mid = extract_result< tag::median >(acc);
|
mid = extract_result< tag::median >(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Mesh>
|
||||||
|
void edges_length(Mesh* poly,
|
||||||
|
double& mini, double& maxi, double& mean, double& mid,
|
||||||
|
unsigned int& nb_degen)
|
||||||
|
{
|
||||||
|
edges_length(poly, edges(*poly), mini, maxi, mean, mid, nb_degen);
|
||||||
|
}
|
||||||
template<typename Mesh>
|
template<typename Mesh>
|
||||||
unsigned int nb_degenerate_faces(Mesh* poly)
|
unsigned int nb_degenerate_faces(Mesh* poly)
|
||||||
{
|
{
|
||||||
|
|
@ -96,11 +144,9 @@ unsigned int nb_degenerate_faces(Mesh* poly)
|
||||||
return static_cast<unsigned int>(degenerate_faces.size());
|
return static_cast<unsigned int>(degenerate_faces.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Mesh>
|
template<typename Mesh, typename IDMap>
|
||||||
unsigned int nb_holes(Mesh* poly)
|
unsigned int nb_holes(Mesh* poly, IDMap idmap)
|
||||||
{
|
{
|
||||||
typedef typename boost::property_map<Mesh, boost::halfedge_index_t>::type IDMap;
|
|
||||||
IDMap idmap = get(boost::halfedge_index, *poly);
|
|
||||||
|
|
||||||
//gets the number of holes
|
//gets the number of holes
|
||||||
//if is_closed is false, then there are borders (= holes)
|
//if is_closed is false, then there are borders (= holes)
|
||||||
|
|
@ -138,9 +184,15 @@ unsigned int nb_holes(Mesh* poly)
|
||||||
//}
|
//}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Mesh>
|
template<typename Mesh>
|
||||||
void faces_area(Mesh* poly,
|
unsigned int nb_holes(Mesh* poly)
|
||||||
|
{
|
||||||
|
typedef typename boost::property_map<Mesh, boost::halfedge_index_t>::type IDMap;
|
||||||
|
IDMap idmap = get(boost::halfedge_index, *poly);
|
||||||
|
return nb_holes(poly, idmap);
|
||||||
|
}
|
||||||
|
template<typename Mesh, typename Face_range>
|
||||||
|
void faces_area(Mesh* poly, const Face_range& range,
|
||||||
double& mini, double& maxi, double& mean, double& mid)
|
double& mini, double& maxi, double& mean, double& mid)
|
||||||
{
|
{
|
||||||
using namespace boost::accumulators;
|
using namespace boost::accumulators;
|
||||||
|
|
@ -153,7 +205,7 @@ void faces_area(Mesh* poly,
|
||||||
features< tag::min, tag::max, tag::mean , tag::median> > acc;
|
features< tag::min, tag::max, tag::mean , tag::median> > acc;
|
||||||
|
|
||||||
VPMap vpmap = get(CGAL::vertex_point, *poly);
|
VPMap vpmap = get(CGAL::vertex_point, *poly);
|
||||||
BOOST_FOREACH(face_descriptor f, faces(*poly))
|
BOOST_FOREACH(face_descriptor f, range)
|
||||||
{
|
{
|
||||||
halfedge_descriptor h = halfedge(f, *poly);
|
halfedge_descriptor h = halfedge(f, *poly);
|
||||||
Point a = get(vpmap, target(h, *poly));
|
Point a = get(vpmap, target(h, *poly));
|
||||||
|
|
@ -169,7 +221,14 @@ void faces_area(Mesh* poly,
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Mesh>
|
template<typename Mesh>
|
||||||
void faces_aspect_ratio(Mesh* poly,
|
void faces_area(Mesh* poly,
|
||||||
|
double& mini, double& maxi, double& mean, double& mid)
|
||||||
|
{
|
||||||
|
faces_area(poly, faces(*poly), mini, maxi, mean, mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Mesh, typename Face_range>
|
||||||
|
void faces_aspect_ratio(Mesh* poly, const Face_range& range,
|
||||||
double& min_altitude, double& mini, double& maxi, double& mean)
|
double& min_altitude, double& mini, double& maxi, double& mean)
|
||||||
{
|
{
|
||||||
using namespace boost::accumulators;
|
using namespace boost::accumulators;
|
||||||
|
|
@ -185,7 +244,7 @@ void faces_aspect_ratio(Mesh* poly,
|
||||||
min_altitude = std::numeric_limits<double>::infinity();
|
min_altitude = std::numeric_limits<double>::infinity();
|
||||||
typename boost::property_map<Mesh, CGAL::vertex_point_t>::type
|
typename boost::property_map<Mesh, CGAL::vertex_point_t>::type
|
||||||
vpmap = get(CGAL::vertex_point, *poly);
|
vpmap = get(CGAL::vertex_point, *poly);
|
||||||
BOOST_FOREACH(face_descriptor f, faces(*poly))
|
BOOST_FOREACH(face_descriptor f, range)
|
||||||
{
|
{
|
||||||
halfedge_descriptor h = halfedge(f, *poly);
|
halfedge_descriptor h = halfedge(f, *poly);
|
||||||
typename Traits::Point_3 points[3];
|
typename Traits::Point_3 points[3];
|
||||||
|
|
@ -212,5 +271,13 @@ void faces_aspect_ratio(Mesh* poly,
|
||||||
maxi = extract_result< tag::max >(acc);
|
maxi = extract_result< tag::max >(acc);
|
||||||
mean = extract_result< tag::mean >(acc);
|
mean = extract_result< tag::mean >(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Mesh>
|
||||||
|
void faces_aspect_ratio(Mesh* poly,
|
||||||
|
double& min_altitude, double& mini, double& maxi, double& mean)
|
||||||
|
{
|
||||||
|
faces_aspect_ratio(poly, faces(*poly), min_altitude, mini, maxi, mean);
|
||||||
|
}
|
||||||
#endif // POLYHEDRON_DEMO_STATISTICS_HELPERS_H
|
#endif // POLYHEDRON_DEMO_STATISTICS_HELPERS_H
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue