mirror of https://github.com/CGAL/cgal
surface mesh sd plugin + test fixes
This commit is contained in:
parent
c82199c012
commit
28bdc838b1
|
|
@ -18,6 +18,10 @@ if(EIGEN3_FOUND)
|
||||||
polyhedron_demo_plugin(point_set_average_spacing_plugin Point_set_average_spacing_plugin KEYWORDS PointSetProcessing Classification)
|
polyhedron_demo_plugin(point_set_average_spacing_plugin Point_set_average_spacing_plugin KEYWORDS PointSetProcessing Classification)
|
||||||
target_link_libraries(point_set_average_spacing_plugin PUBLIC scene_points_with_normal_item scene_callback_signaler)
|
target_link_libraries(point_set_average_spacing_plugin PUBLIC scene_points_with_normal_item scene_callback_signaler)
|
||||||
|
|
||||||
|
qt5_wrap_ui(point_set_shape_detectionUI_FILES Point_set_shape_detection_plugin.ui)
|
||||||
|
polyhedron_demo_plugin(point_set_shape_detection_plugin Point_set_shape_detection_plugin ${point_set_shape_detectionUI_FILES} KEYWORDS PointSetProcessing Classification)
|
||||||
|
target_link_libraries(point_set_shape_detection_plugin PUBLIC scene_surface_mesh_item scene_points_with_normal_item scene_polygon_soup_item scene_callback_signaler)
|
||||||
|
|
||||||
else(EIGEN3_FOUND)
|
else(EIGEN3_FOUND)
|
||||||
message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Surface reconstruction plugin will not be available.")
|
message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Surface reconstruction plugin will not be available.")
|
||||||
message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Normal estimation plugins will not be available.")
|
message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Normal estimation plugins will not be available.")
|
||||||
|
|
@ -39,10 +43,6 @@ endif()
|
||||||
polyhedron_demo_plugin(point_set_selection_plugin Point_set_selection_plugin ${point_set_selectionUI_FILES} KEYWORDS PointSetProcessing Classification)
|
polyhedron_demo_plugin(point_set_selection_plugin Point_set_selection_plugin ${point_set_selectionUI_FILES} KEYWORDS PointSetProcessing Classification)
|
||||||
target_link_libraries(point_set_selection_plugin PUBLIC scene_points_with_normal_item scene_polylines_item scene_edit_box_item)
|
target_link_libraries(point_set_selection_plugin PUBLIC scene_points_with_normal_item scene_polylines_item scene_edit_box_item)
|
||||||
|
|
||||||
qt5_wrap_ui(point_set_shape_detectionUI_FILES Point_set_shape_detection_plugin.ui)
|
|
||||||
polyhedron_demo_plugin(point_set_shape_detection_plugin Point_set_shape_detection_plugin ${point_set_shape_detectionUI_FILES} KEYWORDS PointSetProcessing Classification)
|
|
||||||
target_link_libraries(point_set_shape_detection_plugin PUBLIC scene_surface_mesh_item scene_points_with_normal_item scene_polygon_soup_item scene_callback_signaler)
|
|
||||||
|
|
||||||
qt5_wrap_ui(point_set_simplificationUI_FILES Point_set_simplification_plugin.ui)
|
qt5_wrap_ui(point_set_simplificationUI_FILES Point_set_simplification_plugin.ui)
|
||||||
polyhedron_demo_plugin(point_set_simplification_plugin Point_set_simplification_plugin ${point_set_simplificationUI_FILES} KEYWORDS PointSetProcessing)
|
polyhedron_demo_plugin(point_set_simplification_plugin Point_set_simplification_plugin ${point_set_simplificationUI_FILES} KEYWORDS PointSetProcessing)
|
||||||
target_link_libraries(point_set_simplification_plugin PUBLIC scene_points_with_normal_item scene_callback_signaler)
|
target_link_libraries(point_set_simplification_plugin PUBLIC scene_points_with_normal_item scene_callback_signaler)
|
||||||
|
|
@ -76,10 +76,10 @@ endif()
|
||||||
features_detection_plugin
|
features_detection_plugin
|
||||||
point_set_smoothing_plugin
|
point_set_smoothing_plugin
|
||||||
point_set_average_spacing_plugin
|
point_set_average_spacing_plugin
|
||||||
|
point_set_shape_detection_plugin
|
||||||
point_set_bilateral_smoothing_plugin
|
point_set_bilateral_smoothing_plugin
|
||||||
point_set_outliers_removal_plugin
|
point_set_outliers_removal_plugin
|
||||||
point_set_selection_plugin
|
point_set_selection_plugin
|
||||||
point_set_shape_detection_plugin
|
|
||||||
point_set_simplification_plugin
|
point_set_simplification_plugin
|
||||||
point_set_upsampling_plugin
|
point_set_upsampling_plugin
|
||||||
point_set_wlop_plugin
|
point_set_wlop_plugin
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ struct build_from_pair
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Point_set_demo_point_set_shape_detection_dialog : public QDialog, private Ui::PointSetShapeDetectionDialog
|
class Point_set_demo_point_set_shape_detection_dialog : public QDialog, public Ui::PointSetShapeDetectionDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
@ -114,6 +114,7 @@ class Polyhedron_demo_point_set_shape_detection_plugin :
|
||||||
|
|
||||||
QAction* actionDetect;
|
QAction* actionDetect;
|
||||||
QAction* actionEstimateParameters;
|
QAction* actionEstimateParameters;
|
||||||
|
QAction* actionDetectShapesSM;
|
||||||
|
|
||||||
typedef Point_set_3<Kernel>::Point_map PointPMap;
|
typedef Point_set_3<Kernel>::Point_map PointPMap;
|
||||||
typedef Point_set_3<Kernel>::Vector_map NormalPMap;
|
typedef Point_set_3<Kernel>::Vector_map NormalPMap;
|
||||||
|
|
@ -128,24 +129,35 @@ public:
|
||||||
actionDetect->setObjectName("actionDetect");
|
actionDetect->setObjectName("actionDetect");
|
||||||
actionEstimateParameters = new QAction(tr("Point Set Shape Detection (parameter estimation)"), mainWindow);
|
actionEstimateParameters = new QAction(tr("Point Set Shape Detection (parameter estimation)"), mainWindow);
|
||||||
actionEstimateParameters->setObjectName("actionEstimateParameters");
|
actionEstimateParameters->setObjectName("actionEstimateParameters");
|
||||||
|
actionDetectShapesSM = new QAction(tr("Surface Mesh Shape Detection"), mainWindow);
|
||||||
|
actionDetectShapesSM->setObjectName("actionDetectShapesSM");
|
||||||
autoConnectActions();
|
autoConnectActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool applicable(QAction*) const {
|
bool applicable(QAction* action) const {
|
||||||
|
|
||||||
Scene_points_with_normal_item* item =
|
Scene_points_with_normal_item* item =
|
||||||
qobject_cast<Scene_points_with_normal_item*>(scene->item(scene->mainSelectionIndex()));
|
qobject_cast<Scene_points_with_normal_item*>(scene->item(scene->mainSelectionIndex()));
|
||||||
if (item && item->has_normals())
|
Scene_surface_mesh_item* sm_item =
|
||||||
return true;
|
qobject_cast<Scene_surface_mesh_item*>(scene->item(scene->mainSelectionIndex()));
|
||||||
|
|
||||||
|
if (action->objectName() == "actionDetectShapesSM") {
|
||||||
|
if (sm_item)
|
||||||
|
return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
if (item && item->has_normals()) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QAction*> actions() const {
|
QList<QAction*> actions() const {
|
||||||
return QList<QAction*>() << actionDetect << actionEstimateParameters;
|
return QList<QAction*>() << actionDetect << actionEstimateParameters << actionDetectShapesSM;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void on_actionDetect_triggered();
|
void on_actionDetect_triggered();
|
||||||
void on_actionEstimateParameters_triggered();
|
void on_actionEstimateParameters_triggered();
|
||||||
|
void on_actionDetectShapesSM_triggered();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
@ -161,6 +173,83 @@ private:
|
||||||
ransac.template add_shape_factory<Shape>();
|
ransac.template add_shape_factory<Shape>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void detect_shapes_with_region_growing_sm (
|
||||||
|
Scene_surface_mesh_item* sm_item,
|
||||||
|
Point_set_demo_point_set_shape_detection_dialog& dialog) {
|
||||||
|
|
||||||
|
using Face_range = typename SMesh::Face_range;
|
||||||
|
|
||||||
|
using Neighbor_query =
|
||||||
|
CGAL::Shape_detection::Polygon_mesh::One_ring_neighbor_query<SMesh>;
|
||||||
|
using Region_type =
|
||||||
|
CGAL::Shape_detection::Polygon_mesh::Least_squares_plane_fit_region<Kernel, SMesh>;
|
||||||
|
using Sorting =
|
||||||
|
CGAL::Shape_detection::Polygon_mesh::Least_squares_plane_fit_sorting<Kernel, SMesh, Neighbor_query>;
|
||||||
|
|
||||||
|
using Vertex_to_point_map = typename Region_type::Vertex_to_point_map;
|
||||||
|
using Region_growing = CGAL::Shape_detection::Region_growing<Face_range, Neighbor_query, Region_type>;
|
||||||
|
|
||||||
|
CGAL::Random rand(time(0));
|
||||||
|
const SMesh& mesh = *(sm_item->polyhedron());
|
||||||
|
scene->setSelectedItem(-1);
|
||||||
|
const Face_range face_range = faces(mesh);
|
||||||
|
|
||||||
|
// Set parameters.
|
||||||
|
const double max_distance_to_plane =
|
||||||
|
dialog.epsilon();
|
||||||
|
const double max_accepted_angle =
|
||||||
|
(std::acos(dialog.normal_tolerance()) * 180.0) / CGAL_PI;
|
||||||
|
const std::size_t min_region_size =
|
||||||
|
dialog.min_points();
|
||||||
|
|
||||||
|
// Region growing.
|
||||||
|
Neighbor_query neighbor_query(mesh);
|
||||||
|
const Vertex_to_point_map vertex_to_point_map(get(CGAL::vertex_point, mesh));
|
||||||
|
Region_type region_type(
|
||||||
|
mesh,
|
||||||
|
max_distance_to_plane, max_accepted_angle, min_region_size,
|
||||||
|
vertex_to_point_map);
|
||||||
|
|
||||||
|
Region_growing region_growing(
|
||||||
|
face_range, neighbor_query, region_type);
|
||||||
|
|
||||||
|
std::vector< std::vector<std::size_t> > regions;
|
||||||
|
region_growing.detect(std::back_inserter(regions));
|
||||||
|
|
||||||
|
std::cerr << "* " << regions.size() <<
|
||||||
|
" regions have been found"
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
// Output result as a new colored item.
|
||||||
|
Scene_surface_mesh_item *colored_item = new Scene_surface_mesh_item;
|
||||||
|
colored_item->setName(QString("%1 (region growing)").arg(sm_item->name()));
|
||||||
|
SMesh& fg = *(colored_item->polyhedron());
|
||||||
|
|
||||||
|
fg = mesh;
|
||||||
|
const Face_range fr = faces(fg);
|
||||||
|
|
||||||
|
colored_item->setItemIsMulticolor(true);
|
||||||
|
colored_item->computeItemColorVectorAutomatically(false);
|
||||||
|
auto& color_vector = colored_item->color_vector();
|
||||||
|
color_vector.clear();
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < regions.size(); ++i) {
|
||||||
|
for (const std::size_t idx : regions[i]) {
|
||||||
|
const auto fit = fr.begin() + idx;
|
||||||
|
fg.property_map<face_descriptor, int>("f:patch_id").first[*fit] =
|
||||||
|
static_cast<int>(i);
|
||||||
|
}
|
||||||
|
CGAL::Random rnd(static_cast<unsigned int>(i));
|
||||||
|
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();
|
||||||
|
scene->addItem(colored_item);
|
||||||
|
}
|
||||||
|
|
||||||
void detect_shapes_with_region_growing (
|
void detect_shapes_with_region_growing (
|
||||||
Scene_points_with_normal_item* item,
|
Scene_points_with_normal_item* item,
|
||||||
Point_set_demo_point_set_shape_detection_dialog& dialog) {
|
Point_set_demo_point_set_shape_detection_dialog& dialog) {
|
||||||
|
|
@ -813,6 +902,48 @@ private:
|
||||||
|
|
||||||
}; // end Polyhedron_demo_point_set_shape_detection_plugin
|
}; // end Polyhedron_demo_point_set_shape_detection_plugin
|
||||||
|
|
||||||
|
void Polyhedron_demo_point_set_shape_detection_plugin::on_actionDetectShapesSM_triggered() {
|
||||||
|
|
||||||
|
const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
|
||||||
|
|
||||||
|
Scene_surface_mesh_item* sm_item =
|
||||||
|
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
||||||
|
|
||||||
|
if(sm_item) {
|
||||||
|
|
||||||
|
// Get a surface mesh.
|
||||||
|
SMesh* mesh = sm_item->polyhedron();
|
||||||
|
if(mesh == NULL) return;
|
||||||
|
|
||||||
|
Point_set_demo_point_set_shape_detection_dialog dialog;
|
||||||
|
|
||||||
|
dialog.ransac->setEnabled(false);
|
||||||
|
dialog.m_regularize->setEnabled(false);
|
||||||
|
dialog.m_generate_structured->setEnabled(false);
|
||||||
|
dialog.label_4->setEnabled(false);
|
||||||
|
dialog.m_cluster_epsilon_field->setEnabled(false);
|
||||||
|
dialog.groupBox_3->setEnabled(false);
|
||||||
|
|
||||||
|
if(!dialog.exec()) return;
|
||||||
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
if (dialog.region_growing()) {
|
||||||
|
detect_shapes_with_region_growing_sm(sm_item, dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.ransac->setEnabled(true);
|
||||||
|
dialog.m_regularize->setEnabled(true);
|
||||||
|
dialog.m_generate_structured->setEnabled(true);
|
||||||
|
dialog.label_4->setEnabled(true);
|
||||||
|
dialog.m_cluster_epsilon_field->setEnabled(true);
|
||||||
|
dialog.groupBox_3->setEnabled(true);
|
||||||
|
|
||||||
|
// Update scene.
|
||||||
|
scene->itemChanged(index);
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
sm_item->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Polyhedron_demo_point_set_shape_detection_plugin::on_actionDetect_triggered() {
|
void Polyhedron_demo_point_set_shape_detection_plugin::on_actionDetect_triggered() {
|
||||||
|
|
||||||
const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
|
const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Minimum Number of Points:</string>
|
<string>Minimum Number of Items:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -317,7 +317,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="m_point_subsets">
|
<widget class="QCheckBox" name="m_point_subsets">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Generate N Point subsets</string>
|
<string>Generate N point subsets</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ bool test_region_growing_on_polygon_mesh(int argc, char *argv[]) {
|
||||||
region_growing.detect(std::back_inserter(regions));
|
region_growing.detect(std::back_inserter(regions));
|
||||||
|
|
||||||
// Test data.
|
// Test data.
|
||||||
assert(regions.size() >= 328 && regions.size() <= 332);
|
assert(regions.size() >= 327 && regions.size() <= 331);
|
||||||
if (regions.size() < 328 || regions.size() > 332)
|
if (regions.size() < 327 || regions.size() > 331)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (const auto& region : regions)
|
for (const auto& region : regions)
|
||||||
|
|
@ -81,8 +81,8 @@ bool test_region_growing_on_polygon_mesh(int argc, char *argv[]) {
|
||||||
std::vector<std::size_t> unassigned_faces;
|
std::vector<std::size_t> unassigned_faces;
|
||||||
region_growing.unassigned_items(std::back_inserter(unassigned_faces));
|
region_growing.unassigned_items(std::back_inserter(unassigned_faces));
|
||||||
|
|
||||||
assert(unassigned_faces.size() >= 869 && unassigned_faces.size() <= 889);
|
assert(unassigned_faces.size() >= 908 && unassigned_faces.size() <= 928);
|
||||||
if (unassigned_faces.size() < 869 || unassigned_faces.size() > 889)
|
if (unassigned_faces.size() < 908 || unassigned_faces.size() > 928)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ int main(int argc, char *argv[]) {
|
||||||
region_growing.detect(std::back_inserter(regions));
|
region_growing.detect(std::back_inserter(regions));
|
||||||
|
|
||||||
region_growing.release_memory();
|
region_growing.release_memory();
|
||||||
assert(regions.size() >= 323 && regions.size() <= 327);
|
assert(regions.size() >= 324 && regions.size() <= 328);
|
||||||
|
|
||||||
const bool exact_exact_test_success = (regions.size() >= 323 && regions.size() <= 327);
|
const bool exact_exact_test_success = (regions.size() >= 323 && regions.size() <= 327);
|
||||||
std::cout << "exact_exact_test_success: " << exact_exact_test_success << std::endl;
|
std::cout << "exact_exact_test_success: " << exact_exact_test_success << std::endl;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue