diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index 6fdeda48ca4d..ba917e038361 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -46,4 +46,6 @@ \example Polygon_mesh_processing/cc_compatible_orientations.cpp \example Polygon_mesh_processing/remesh_planar_patches.cpp \example Polygon_mesh_processing/remesh_almost_planar_patches.cpp +\example Polygon_mesh_processing/sample_example.cpp +*/ */ diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 590305c0c8ad..5adc0de4597c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -7,6 +7,7 @@ project(Polygon_mesh_processing_Examples) # CGAL and its components find_package(CGAL REQUIRED) +create_single_source_cgal_program("sample_example.cpp" ) create_single_source_cgal_program("extrude.cpp" ) create_single_source_cgal_program("polyhedral_envelope.cpp" ) create_single_source_cgal_program("polyhedral_envelope_of_triangle_soup.cpp" ) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp new file mode 100644 index 000000000000..fa60ae6538f7 --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp @@ -0,0 +1,47 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_3 Point; + +typedef CGAL::Point_set_3 Point_set; + +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char* argv[]) +{ + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); + + Mesh mesh; + if(!PMP::IO::read_polygon_mesh(filename, mesh)) + { + std::cerr << "Invalid input." << std::endl; + return 1; + } + + const int points_per_face = (argc > 2) ? std::stoi(argv[2]) : 10; + + std::vector points; + PMP::sample_triangle_mesh(mesh, + std::back_inserter(points), + CGAL::parameters::number_of_points_per_face(points_per_face)); + + + Point_set point_set; + PMP::sample_triangle_mesh(mesh, + point_set.point_back_inserter()); + + std::cout << point_set.number_of_points() << std::endl; + return 0; +} diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h index 8b41ff2ecdb7..b3aaf70604f6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h @@ -747,7 +747,7 @@ struct Triangle_structure_sampler_for_triangle_soup * @tparam TriangleMesh a model of the concepts `EdgeListGraph` and `FaceListGraph` * @tparam PointOutputIterator a model of `OutputIterator` * holding objects of the same point type as - * the value type of the point type associated to the mesh `tm`, i.e. the value type of the vertex + * the value type of the point type associated to the mesh `tm`, i.e., the value type of the vertex * point map property map, if provided, or the value type of the internal point property map otherwise * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * @@ -1570,7 +1570,7 @@ bounded_error_squared_Hausdorff_distance_impl(const TriangleMesh1& tm1, candidate_triangles.pop(); // Only process the triangle if it can contribute to the Hausdorff distance, - // i.e. if its upper bound is higher than the currently known best lower bound + // i.e., if its upper bound is higher than the currently known best lower bound // and the difference between the bounds to be obtained is larger than the // user-given error. const auto& triangle_bounds = triangle_and_bounds.bounds; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt index 2e030be7f6df..8c27fa77cad8 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt @@ -13,6 +13,13 @@ target_link_libraries( PUBLIC scene_surface_mesh_item scene_polygon_soup_item scene_points_with_normal_item) +polyhedron_demo_plugin(point_set_from_sampling_plugin + Point_set_from_sampling_plugin) +target_link_libraries( + point_set_from_sampling_plugin + PUBLIC scene_surface_mesh_item scene_polygon_soup_item + scene_points_with_normal_item) + polyhedron_demo_plugin(diff_between_meshes_plugin Diff_between_meshes_plugin) target_link_libraries(diff_between_meshes_plugin PUBLIC scene_surface_mesh_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp new file mode 100644 index 000000000000..aa6ea4c1ba01 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp @@ -0,0 +1,150 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Scene_points_with_normal_item.h" +#include "Scene_surface_mesh_item.h" +#include "Scene_polygon_soup_item.h" + +#include +#include "Messages_interface.h" + +#include +#include + +using namespace CGAL::Three; +class Polyhedron_demo_point_set_from_sampling_plugin : + public QObject, + public Polyhedron_demo_plugin_interface +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + +public: + void init(QMainWindow* mainWindow, + CGAL::Three::Scene_interface* scene_interface, Messages_interface*); + + bool applicable(QAction*) const { + const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); + + return qobject_cast(scene->item(index)) + || qobject_cast(scene->item(index)); + } + + QList actions() const; + +public Q_SLOTS: + void createPointSet(); + +private: + CGAL::Three::Scene_interface* scene; + QAction* actionPointSetFromSampling; + + +}; // end Polyhedron_demo_point_set_from_sampling_plugin + +void Polyhedron_demo_point_set_from_sampling_plugin::init(QMainWindow* mainWindow, + CGAL::Three::Scene_interface* scene_interface, + Messages_interface*) +{ + scene = scene_interface; + actionPointSetFromSampling = new QAction(tr("Create Point Set from Sampling"), mainWindow); + actionPointSetFromSampling->setObjectName("actionPointSetFromSampling"); + connect(actionPointSetFromSampling, SIGNAL(triggered()), + this, SLOT(createPointSet())); +} + +QList Polyhedron_demo_point_set_from_sampling_plugin::actions() const { + return QList() << actionPointSetFromSampling; +} + + + +void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() +{ + QApplication::setOverrideCursor(Qt::WaitCursor); + const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Scene_points_with_normal_item* points = new Scene_points_with_normal_item(); + + + if (points){ + points->setColor(Qt::blue); + }else{ + QApplication::restoreOverrideCursor(); + return; + } + Scene_surface_mesh_item* sm_item = + qobject_cast(scene->item(index)); + + if (sm_item){ + if(! CGAL::is_triangle_mesh(*sm_item->polyhedron())){ + CGAL::Three::Three::error(QString("The mesh must have triangle faces")); + QApplication::restoreOverrideCursor(); + return; + } + int nf = num_faces(*sm_item->polyhedron()); + + bool ok; + int nb = 0; + nb = QInputDialog::getInt(QApplication::activeWindow(), "Sampling", + "Number of sample points:", + nf , 0, (std::numeric_limits::max)(), 1, &ok); + + points->setName(QString("%1 (sampled)").arg(sm_item->name())); + if( ok & (nb > 0)){ + points->point_set()->reserve(nb); + CGAL::Polygon_mesh_processing::sample_triangle_mesh(*sm_item->polyhedron(), + points->point_set()->point_back_inserter(), + CGAL::parameters::number_of_points_on_faces(nb) + .do_sample_vertices(false) + .do_sample_edges(false)); + scene->addItem(points); + } + } + + Scene_polygon_soup_item* soup_item = + qobject_cast(scene->item(index)); + + if (soup_item){ + int nf = static_cast(soup_item->polygons().size()); + + for(const auto& f : soup_item->polygons()){ + if(f.size() != 3){ + CGAL::Three::Three::error(QString("The polygons must be triangles")); + QApplication::restoreOverrideCursor(); + return; + } + } + + bool ok; + int nb = 0; + nb = QInputDialog::getInt(QApplication::activeWindow(), "Sampling", + "Number of sample points:", + nf , 0, (std::numeric_limits::max)(), 1, &ok); + points->setName(QString("%1 (sampled)").arg(soup_item->name())); + if( ok & (nb > 0)){ + points->point_set()->reserve(nb); + CGAL::Polygon_mesh_processing::sample_triangle_soup(soup_item->points(), + soup_item->polygons(), + points->point_set()->point_back_inserter(), + CGAL::parameters::number_of_points_on_faces(nb) + .do_sample_vertices(false) + .do_sample_edges(false)); + scene->addItem(points); + } + } + + + QApplication::restoreOverrideCursor(); +} + + +#include "Point_set_from_sampling_plugin.moc"