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;
|
||||
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))
|
||||
classnames << classname;
|
||||
}
|
||||
|
|
@ -2446,12 +2449,18 @@ QString MainWindow::get_item_stats()
|
|||
{
|
||||
Scene_item* s_item = scene->item(id);
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//last step :: making tables for each type of item
|
||||
QString str;
|
||||
for(int i=0; i< classnames.size(); i++)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/Handle_hash_function.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
#include <CGAL/statistics_helpers.h>
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
|
@ -21,6 +22,9 @@
|
|||
#include <vector>
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -50,7 +54,8 @@ struct Scene_polyhedron_selection_item_priv{
|
|||
Scene_polyhedron_selection_item_priv(Scene_polyhedron_selection_item* parent):
|
||||
item(parent)
|
||||
{
|
||||
|
||||
filtered_graph = nullptr;
|
||||
item->setProperty("classname", QString("surface_mesh"));
|
||||
}
|
||||
|
||||
void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const;
|
||||
|
|
@ -162,6 +167,7 @@ struct Scene_polyhedron_selection_item_priv{
|
|||
mutable QOpenGLShaderProgram *program;
|
||||
mutable bool are_HL_buffers_filled;
|
||||
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->poly = polyhedron();
|
||||
compute_bbox();
|
||||
if(d->filtered_graph)
|
||||
{
|
||||
delete d->filtered_graph;
|
||||
d->filtered_graph = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Scene_polyhedron_selection_item::add_to_selection()
|
||||
|
|
@ -2317,3 +2328,287 @@ Scene_polyhedron_selection_item::toolTip() const
|
|||
.arg(this->renderingModeName())
|
||||
.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 :
|
||||
friend struct Scene_polyhedron_selection_item_priv;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ struct Scene_surface_mesh_item_priv{
|
|||
alphaSlider = NULL;
|
||||
has_vcolors = false;
|
||||
has_fcolors = false;
|
||||
item->setProperty("classname", QString("surface_mesh"));
|
||||
}
|
||||
|
||||
Scene_surface_mesh_item_priv(SMesh* sm, Scene_surface_mesh_item *parent):
|
||||
|
|
@ -151,6 +152,7 @@ struct Scene_surface_mesh_item_priv{
|
|||
alphaSlider = NULL;
|
||||
has_vcolors = false;
|
||||
has_fcolors = false;
|
||||
item->setProperty("classname", QString("surface_mesh"));
|
||||
}
|
||||
|
||||
~Scene_surface_mesh_item_priv()
|
||||
|
|
|
|||
|
|
@ -18,11 +18,35 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
template<typename Mesh>
|
||||
void angles(Mesh* poly, double& mini, double& maxi, double& ave)
|
||||
template<typename Set>
|
||||
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;
|
||||
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 CGAL::Kernel_traits< typename boost::property_traits<VPMap>::value_type >::Kernel Traits;
|
||||
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);
|
||||
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;
|
||||
|
||||
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>
|
||||
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,
|
||||
unsigned int& nb_degen)
|
||||
{
|
||||
|
|
@ -69,7 +110,7 @@ void edges_length(Mesh* poly,
|
|||
|
||||
VPMap vpmap = get(CGAL::vertex_point, *poly);
|
||||
nb_degen = 0;
|
||||
BOOST_FOREACH(edge_descriptor e, edges(*poly))
|
||||
BOOST_FOREACH(edge_descriptor e, range)
|
||||
{
|
||||
halfedge_descriptor h = halfedge(e, *poly);
|
||||
Point a = get(vpmap, source(h, *poly));
|
||||
|
|
@ -85,6 +126,13 @@ void edges_length(Mesh* poly,
|
|||
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>
|
||||
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());
|
||||
}
|
||||
|
||||
template<typename Mesh>
|
||||
unsigned int nb_holes(Mesh* poly)
|
||||
template<typename Mesh, typename IDMap>
|
||||
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
|
||||
//if is_closed is false, then there are borders (= holes)
|
||||
|
|
@ -138,9 +184,15 @@ unsigned int nb_holes(Mesh* poly)
|
|||
//}
|
||||
return n;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
using namespace boost::accumulators;
|
||||
|
|
@ -153,7 +205,7 @@ void faces_area(Mesh* poly,
|
|||
features< tag::min, tag::max, tag::mean , tag::median> > acc;
|
||||
|
||||
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);
|
||||
Point a = get(vpmap, target(h, *poly));
|
||||
|
|
@ -169,7 +221,14 @@ void faces_area(Mesh* poly,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
using namespace boost::accumulators;
|
||||
|
|
@ -185,7 +244,7 @@ void faces_aspect_ratio(Mesh* poly,
|
|||
min_altitude = std::numeric_limits<double>::infinity();
|
||||
typename boost::property_map<Mesh, CGAL::vertex_point_t>::type
|
||||
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);
|
||||
typename Traits::Point_3 points[3];
|
||||
|
|
@ -212,5 +271,13 @@ void faces_aspect_ratio(Mesh* poly,
|
|||
maxi = extract_result< tag::max >(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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue