mirror of https://github.com/CGAL/cgal
Merge pull request #4975 from maxGimeno/Demo-Fix_mesh_plane_detection-maxGimeno
Polyhedron Demo: Fix Mesh_plane_detection_plugin
This commit is contained in:
commit
62e8fcb4ce
|
|
@ -201,7 +201,7 @@ private:
|
||||||
const double max_distance_to_plane =
|
const double max_distance_to_plane =
|
||||||
dialog.epsilon();
|
dialog.epsilon();
|
||||||
const double max_accepted_angle =
|
const double max_accepted_angle =
|
||||||
(std::acos(dialog.normal_tolerance()) * 180.0) / CGAL_PI;
|
dialog.normal_tolerance();
|
||||||
const std::size_t min_region_size =
|
const std::size_t min_region_size =
|
||||||
dialog.min_points();
|
dialog.min_points();
|
||||||
|
|
||||||
|
|
@ -248,7 +248,19 @@ private:
|
||||||
64 + rnd.get_int(0, 192),
|
64 + rnd.get_int(0, 192),
|
||||||
64 + rnd.get_int(0, 192)));
|
64 + rnd.get_int(0, 192)));
|
||||||
}
|
}
|
||||||
|
if(color_vector.empty())
|
||||||
|
{
|
||||||
|
for(const auto& f : faces(fg))
|
||||||
|
{
|
||||||
|
fg.property_map<face_descriptor, int>("f:patch_id").first[f] =
|
||||||
|
static_cast<int>(0);
|
||||||
|
}
|
||||||
|
CGAL::Random rnd(static_cast<unsigned int>(0));
|
||||||
|
color_vector.push_back(QColor(
|
||||||
|
64 + rnd.get_int(0, 192),
|
||||||
|
64 + rnd.get_int(0, 192),
|
||||||
|
64 + rnd.get_int(0, 192)));
|
||||||
|
}
|
||||||
colored_item->invalidateOpenGLBuffers();
|
colored_item->invalidateOpenGLBuffers();
|
||||||
scene->addItem(colored_item);
|
scene->addItem(colored_item);
|
||||||
}
|
}
|
||||||
|
|
@ -273,7 +285,7 @@ private:
|
||||||
const double max_distance_to_plane =
|
const double max_distance_to_plane =
|
||||||
dialog.epsilon();
|
dialog.epsilon();
|
||||||
const double max_accepted_angle =
|
const double max_accepted_angle =
|
||||||
(std::acos(dialog.normal_tolerance()) * 180.0) / CGAL_PI;
|
dialog.normal_tolerance();
|
||||||
const std::size_t min_region_size =
|
const std::size_t min_region_size =
|
||||||
dialog.min_points();
|
dialog.min_points();
|
||||||
|
|
||||||
|
|
@ -648,7 +660,7 @@ private:
|
||||||
CGAL::Shape_detection::Plane_map<Traits>(),
|
CGAL::Shape_detection::Plane_map<Traits>(),
|
||||||
CGAL::Shape_detection::Point_to_shape_index_map<Traits>(*points, planes),
|
CGAL::Shape_detection::Point_to_shape_index_map<Traits>(*points, planes),
|
||||||
true, true, true, true,
|
true, true, true, true,
|
||||||
180 * std::acos (op.normal_threshold) / CGAL_PI, op.epsilon);
|
op.normal_threshold, op.epsilon);
|
||||||
|
|
||||||
std::cerr << "done" << std::endl;
|
std::cerr << "done" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
@ -927,8 +939,14 @@ void Polyhedron_demo_point_set_shape_detection_plugin::on_actionDetectShapesSM_t
|
||||||
dialog.label_4->setEnabled(false);
|
dialog.label_4->setEnabled(false);
|
||||||
dialog.m_cluster_epsilon_field->setEnabled(false);
|
dialog.m_cluster_epsilon_field->setEnabled(false);
|
||||||
dialog.groupBox_3->setEnabled(false);
|
dialog.groupBox_3->setEnabled(false);
|
||||||
|
//todo: check default values
|
||||||
|
dialog.m_epsilon_field->setValue(0.01*sm_item->diagonalBbox());
|
||||||
|
std::size_t nb_faces = mesh->number_of_faces();
|
||||||
|
dialog.m_min_pts_field->setValue((std::max)(static_cast<int>(0.01*nb_faces), 1));
|
||||||
if(!dialog.exec()) return;
|
if(!dialog.exec()) return;
|
||||||
|
|
||||||
|
if(dialog.min_points() > static_cast<unsigned int>(nb_faces))
|
||||||
|
dialog.m_min_pts_field->setValue(static_cast<unsigned int>(nb_faces));
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
if (dialog.region_growing()) {
|
if (dialog.region_growing()) {
|
||||||
detect_shapes_with_region_growing_sm(sm_item, dialog);
|
detect_shapes_with_region_growing_sm(sm_item, dialog);
|
||||||
|
|
@ -969,6 +987,8 @@ void Polyhedron_demo_point_set_shape_detection_plugin::on_actionDetect_triggered
|
||||||
Point_set_demo_point_set_shape_detection_dialog dialog;
|
Point_set_demo_point_set_shape_detection_dialog dialog;
|
||||||
if(!dialog.exec())
|
if(!dialog.exec())
|
||||||
return;
|
return;
|
||||||
|
if(dialog.min_points() > static_cast<unsigned int>(points->size()))
|
||||||
|
dialog.m_min_pts_field->setValue(static_cast<unsigned int>(points->size()));
|
||||||
|
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
if (dialog.region_growing())
|
if (dialog.region_growing())
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Normal Tolerance:</string>
|
<string>Normal Tolerance (in degrees):</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -165,7 +165,7 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>0.90</string>
|
<string>30</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,6 @@ qt5_wrap_ui( segmentationUI_FILES Mesh_segmentation_widget.ui)
|
||||||
polyhedron_demo_plugin(mesh_segmentation_plugin Mesh_segmentation_plugin ${segmentationUI_FILES})
|
polyhedron_demo_plugin(mesh_segmentation_plugin Mesh_segmentation_plugin ${segmentationUI_FILES})
|
||||||
target_link_libraries(mesh_segmentation_plugin PUBLIC scene_surface_mesh_item)
|
target_link_libraries(mesh_segmentation_plugin PUBLIC scene_surface_mesh_item)
|
||||||
|
|
||||||
qt5_wrap_ui( mesh_plane_detectionUI_FILES Mesh_plane_detection_dialog.ui)
|
|
||||||
polyhedron_demo_plugin(mesh_plane_detection_plugin Mesh_plane_detection_plugin ${mesh_plane_detectionUI_FILES})
|
|
||||||
target_link_libraries(mesh_plane_detection_plugin PUBLIC scene_surface_mesh_item)
|
|
||||||
|
|
||||||
qt5_wrap_ui( mesh_simplificationUI_FILES Mesh_simplification_dialog.ui)
|
qt5_wrap_ui( mesh_simplificationUI_FILES Mesh_simplification_dialog.ui)
|
||||||
polyhedron_demo_plugin(mesh_simplification_plugin Mesh_simplification_plugin ${mesh_simplificationUI_FILES})
|
polyhedron_demo_plugin(mesh_simplification_plugin Mesh_simplification_plugin ${mesh_simplificationUI_FILES})
|
||||||
target_link_libraries(mesh_simplification_plugin PUBLIC scene_surface_mesh_item scene_selection_item)
|
target_link_libraries(mesh_simplification_plugin PUBLIC scene_surface_mesh_item scene_selection_item)
|
||||||
|
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>Mesh_plane_detection_dialog</class>
|
|
||||||
<widget class="QDialog" name="Mesh_plane_detection_dialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>349</width>
|
|
||||||
<height>117</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Mesh Plane Detection</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QFormLayout" name="formLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="minimumAreaLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Minimum area</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="maximumDeviationFromNormalLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Maximum deviation from normal</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QSpinBox" name="maximumDeviationFromNormalSpinBox">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>°</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>90</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>30</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="DoubleEdit" name="minimumAreaDoubleSpinBox">
|
|
||||||
<property name="text">
|
|
||||||
<string>0.01</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>13</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>DoubleEdit</class>
|
|
||||||
<extends>QLineEdit</extends>
|
|
||||||
<header>CGAL_double_edit.h</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>Mesh_plane_detection_dialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>248</x>
|
|
||||||
<y>254</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>Mesh_plane_detection_dialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>316</x>
|
|
||||||
<y>260</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
||||||
|
|
@ -1,250 +0,0 @@
|
||||||
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
|
|
||||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
|
||||||
|
|
||||||
#include "Scene_surface_mesh_item.h"
|
|
||||||
#include "Scene.h"
|
|
||||||
#include "Color_map.h"
|
|
||||||
|
|
||||||
#include <CGAL/mesh_segmentation.h>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QElapsedTimer>
|
|
||||||
#include <QAction>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QObject>
|
|
||||||
//#include <QtConcurrentRun>
|
|
||||||
#include <map>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <vector>
|
|
||||||
#include <CGAL/property_map.h>
|
|
||||||
#include <CGAL/Polygon_mesh_processing/measure.h>
|
|
||||||
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
|
|
||||||
|
|
||||||
#include "ui_Mesh_plane_detection_dialog.h"
|
|
||||||
|
|
||||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
|
||||||
|
|
||||||
using namespace CGAL::Three;
|
|
||||||
class Polyhedron_demo_mesh_plane_detection_plugin :
|
|
||||||
public QObject,
|
|
||||||
public Polyhedron_demo_plugin_helper
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
|
|
||||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
QList<QAction*> actions() const {
|
|
||||||
return QList<QAction*>() << actionPlaneDetection;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool applicable(QAction*) const {
|
|
||||||
return
|
|
||||||
qobject_cast<Scene_surface_mesh_item*>(scene->item(scene->mainSelectionIndex()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) {
|
|
||||||
this->scene = scene_interface;
|
|
||||||
this->mw = mainWindow;
|
|
||||||
actionPlaneDetection = new QAction("Mesh Plane Detection", mw);
|
|
||||||
actionPlaneDetection->setProperty("subMenuName", "Triangulated Surface Mesh Segmentation");
|
|
||||||
actionPlaneDetection->setObjectName("actionPlaneDetection");
|
|
||||||
|
|
||||||
// adding slot for itemAboutToBeDestroyed signal, aim is removing item from item-functor map.
|
|
||||||
if( Scene* scene = dynamic_cast<Scene*>(scene_interface) ) {
|
|
||||||
connect(scene, SIGNAL(itemAboutToBeDestroyed(CGAL::Three::Scene_item*)), this, SLOT(itemAboutToBeDestroyed(CGAL::Three::Scene_item*)));
|
|
||||||
}
|
|
||||||
|
|
||||||
autoConnectActions();
|
|
||||||
}
|
|
||||||
virtual void closure()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class SegmentPropertyMap>
|
|
||||||
void colorize_segmentation(Scene_surface_mesh_item* item, SegmentPropertyMap& segment_ids, std::vector<QColor>& color_vector);
|
|
||||||
|
|
||||||
void check_and_set_ids(SMesh *sm);
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void on_actionPlaneDetection_triggered();
|
|
||||||
void itemAboutToBeDestroyed(CGAL::Three::Scene_item*);
|
|
||||||
private:
|
|
||||||
QAction* actionPlaneDetection;
|
|
||||||
|
|
||||||
|
|
||||||
template <typename OutputIterator>
|
|
||||||
void detect_planes_in_mesh (SMesh& mesh, const double area_min,
|
|
||||||
const double angle_max,
|
|
||||||
OutputIterator output)
|
|
||||||
{
|
|
||||||
typedef SMesh::size_type size_type;
|
|
||||||
|
|
||||||
std::cerr << "Detecting planes with:" << std::endl
|
|
||||||
<< " * Area min = " << area_min << std::endl
|
|
||||||
<< " * Min cos angle = " << angle_max << std::endl;
|
|
||||||
std::vector<int> label_region(mesh.number_of_faces(), 0);
|
|
||||||
int class_index = 0;
|
|
||||||
|
|
||||||
|
|
||||||
for (typename SMesh::Face_iterator f = mesh.faces_begin(); f != mesh.faces_end(); ++f)
|
|
||||||
{
|
|
||||||
if (label_region[*f] != 0)
|
|
||||||
continue;
|
|
||||||
class_index++;
|
|
||||||
label_region[*f] = class_index;
|
|
||||||
double area = PMP::face_area (*f, mesh, PMP::parameters::geom_traits(EPICK()));
|
|
||||||
|
|
||||||
//characteristics of the seed
|
|
||||||
EPICK::Vector_3 normal_seed = PMP::compute_face_normal (*f, mesh, PMP::parameters::geom_traits(EPICK()));
|
|
||||||
EPICK::Point_3 pt_seed = mesh.point(target(halfedge(*f, mesh), mesh));
|
|
||||||
EPICK::Plane_3 optimal_plane(pt_seed, normal_seed);
|
|
||||||
// Kernel::Plane_3 optimal_plane = f->plane();
|
|
||||||
|
|
||||||
//initialization containers
|
|
||||||
std::vector<size_type> index_container (1,*f);
|
|
||||||
std::vector<size_type> index_container_former_ring (1, *f);
|
|
||||||
std::list<size_type> index_container_current_ring;
|
|
||||||
|
|
||||||
//propagation
|
|
||||||
bool propagation = true;
|
|
||||||
do{
|
|
||||||
|
|
||||||
propagation = false;
|
|
||||||
|
|
||||||
for (size_type k = 0; k < index_container_former_ring.size(); k++)
|
|
||||||
{
|
|
||||||
typename SMesh::Halfedge_around_face_circulator
|
|
||||||
circ( mesh.halfedge(SMesh::Face_index(index_container_former_ring[k])), mesh)
|
|
||||||
, start = circ;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (is_border(*circ, mesh))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
typename SMesh::Face_index
|
|
||||||
neighbor = mesh.face(opposite(*circ, mesh));
|
|
||||||
size_type neighbor_index = neighbor;
|
|
||||||
if (label_region[neighbor_index] == 0)
|
|
||||||
{
|
|
||||||
EPICK::Vector_3 normal
|
|
||||||
= PMP::compute_face_normal (neighbor, mesh, PMP::parameters::geom_traits(EPICK()));
|
|
||||||
|
|
||||||
if (std::fabs(normal * optimal_plane.orthogonal_vector()) > angle_max)
|
|
||||||
{
|
|
||||||
label_region[neighbor_index] = class_index;
|
|
||||||
propagation = true;
|
|
||||||
index_container_current_ring.push_back(neighbor_index);
|
|
||||||
area += PMP::face_area (neighbor, mesh, PMP::parameters::geom_traits(EPICK()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (++ circ != start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//update containers
|
|
||||||
index_container_former_ring.clear();
|
|
||||||
for (std::list<size_type>::iterator it = index_container_current_ring.begin();
|
|
||||||
it != index_container_current_ring.end(); ++it)
|
|
||||||
{
|
|
||||||
index_container_former_ring.push_back(*it);
|
|
||||||
index_container.push_back(*it);
|
|
||||||
}
|
|
||||||
index_container_current_ring.clear();
|
|
||||||
|
|
||||||
} while (propagation);
|
|
||||||
|
|
||||||
//Test the number of inliers -> reject if inferior to Nmin
|
|
||||||
if (area < area_min)
|
|
||||||
{
|
|
||||||
class_index--;
|
|
||||||
label_region[*f] = 0;
|
|
||||||
for (size_type k = 0; k < index_container.size(); k++)
|
|
||||||
label_region[index_container[k]] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cerr << class_index << " planes detected" << std::endl;
|
|
||||||
|
|
||||||
std::copy (label_region.begin(), label_region.end(), output);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void Polyhedron_demo_mesh_plane_detection_plugin::itemAboutToBeDestroyed(CGAL::Three::Scene_item*)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Polyhedron_demo_mesh_plane_detection_plugin::on_actionPlaneDetection_triggered()
|
|
||||||
{
|
|
||||||
const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
|
|
||||||
|
|
||||||
Scene_surface_mesh_item* poly_item =
|
|
||||||
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
|
||||||
|
|
||||||
if (poly_item)
|
|
||||||
{
|
|
||||||
SMesh& pmesh =*poly_item->polyhedron();
|
|
||||||
|
|
||||||
QDialog dialog(mw);
|
|
||||||
Ui::Mesh_plane_detection_dialog ui;
|
|
||||||
ui.setupUi(&dialog);
|
|
||||||
ui.minimumAreaDoubleSpinBox->setMinimum(0.00001);
|
|
||||||
// check user cancellation
|
|
||||||
if(dialog.exec() == QDialog::Rejected)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QElapsedTimer time;
|
|
||||||
time.start();
|
|
||||||
std::cerr << "Detecting planes... ";
|
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
||||||
QApplication::processEvents();
|
|
||||||
|
|
||||||
//check_and_set_ids (&pmesh);
|
|
||||||
std::vector<int> indices;
|
|
||||||
detect_planes_in_mesh (pmesh,
|
|
||||||
ui.minimumAreaDoubleSpinBox->value(),
|
|
||||||
std::fabs(std::cos (CGAL_PI * ui.maximumDeviationFromNormalSpinBox->value() / 180.)),
|
|
||||||
std::back_inserter (indices));
|
|
||||||
|
|
||||||
//poly_item->set_color_vector_read_only(true);
|
|
||||||
colorize_segmentation (poly_item, indices, poly_item->color_vector());
|
|
||||||
|
|
||||||
std::cerr << "ok (" << time.elapsed() << " ms, "
|
|
||||||
<< pmesh.number_of_halfedges() / 2 << " edges)" << std::endl;
|
|
||||||
|
|
||||||
poly_item->invalidateOpenGLBuffers();
|
|
||||||
scene->itemChanged(index);
|
|
||||||
QApplication::restoreOverrideCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class SegmentPropertyMap>
|
|
||||||
void Polyhedron_demo_mesh_plane_detection_plugin::colorize_segmentation(
|
|
||||||
Scene_surface_mesh_item* item,
|
|
||||||
SegmentPropertyMap& segment_ids,
|
|
||||||
std::vector<QColor>& color_vector)
|
|
||||||
{
|
|
||||||
item->setItemIsMulticolor(true);
|
|
||||||
item->computeItemColorVectorAutomatically(true);
|
|
||||||
SMesh* sm = item->face_graph();
|
|
||||||
color_vector.clear();
|
|
||||||
std::size_t max_segment = 0;
|
|
||||||
for(SMesh::Face_iterator facet_it = sm->faces_begin();
|
|
||||||
facet_it != sm->faces_end(); ++facet_it)
|
|
||||||
{
|
|
||||||
std::size_t segment_id = segment_ids[static_cast<std::size_t>(*facet_it)];
|
|
||||||
sm->property_map<face_descriptor, int>("f:patch_id").first[*facet_it] = static_cast<int>(segment_id);
|
|
||||||
max_segment = (std::max)(max_segment, segment_id);
|
|
||||||
}
|
|
||||||
color_vector.push_back(QColor(0, 0, 0));
|
|
||||||
for(std::size_t i = 1; i <= max_segment; ++i)
|
|
||||||
color_vector.push_back (QColor (CGAL::get_default_random().get_int (41, 255),
|
|
||||||
CGAL::get_default_random().get_int (35, 238),
|
|
||||||
CGAL::get_default_random().get_int (35, 255)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "Mesh_plane_detection_plugin.moc"
|
|
||||||
Loading…
Reference in New Issue