diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 630e7a974c8..ecafdd3a5d2 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -33,6 +33,10 @@ namespace CGAL { template< typename Graph> void fill_hole(typename boost::graph_traits::halfedge_descriptor h, Graph& g); + + template + typename boost::graph_traits::face_descriptor add_face(const VertexRange& vr, + Graph& g); } /*! @@ -724,6 +728,265 @@ bool is_degenerate_triangle_face( } /// \endcond +/** + * \ingroup PkgBGLHelperFct + * \brief Creates a regular prism. + * + * Creates a regular prism in `g`, having `nb_vertices` vertices in each of its bases. + * \param nb_vertices the number of vertices per base. It must be greater than or equals 3. + * \param g the graph in which the regular prism will be created + * \param center the point around which the regular prism will be created. It is the middle point of the prism's axis. + * \param height the distance between the two bases. + * \param radius the radius of the circle in which the bases are inscribed. + * \param is_closed determines if the bases must be created or not. + */ +template +void make_regular_prism( + typename boost::graph_traits::vertices_size_type nb_vertices, + Graph& g, + const P& center = P(0,0,0), + typename CGAL::Kernel_traits

::Kernel::FT height = 1.0, + typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0, + bool is_closed = true) +{ + CGAL_assertion(nb_vertices >= 3); + typedef typename boost::property_map::type Point_property_map; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename CGAL::Kernel_traits

::Kernel::FT FT; + + const FT to_rad = CGAL_PI / 180.0; + const FT precision = 360/nb_vertices; + const FT diameter = 2*radius; + Point_property_map vpmap = get(CGAL::vertex_point, g); + std::vector vertices; + vertices.resize(nb_vertices*2); + for(int i=0; i face; + face.resize(3); + //fill faces + for(int i=0; i +void make_pyramid( + typename boost::graph_traits::vertices_size_type nb_vertices, + Graph& g, + const P& base_center = P(0,0,0), + typename CGAL::Kernel_traits

::Kernel::FT height = 1.0, + typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0, + bool is_closed = true) +{ + CGAL_assertion(nb_vertices >= 3); + typedef typename boost::property_map::type Point_property_map; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename CGAL::Kernel_traits

::Kernel::FT FT; + const FT to_rad = CGAL_PI / 180.0; + const FT precision = 360/nb_vertices; + const FT diameter = 2*radius; + Point_property_map vpmap = get(CGAL::vertex_point, g); + std::vector vertices; + vertices.resize(nb_vertices); + for(int i=0; i face; + face.resize(3); + //fill faces + for(int i=0; i +void make_icosahedron( + Graph& g, + const P& center = P(0,0,0), + typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0) +{ + typedef typename boost::property_map::type Point_property_map; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + Point_property_map vpmap = get(CGAL::vertex_point, g); + // create the initial icosahedron + std::vector v_vertices; + v_vertices.resize(12); + for(int i=0; i<12; ++i) + v_vertices[i] = add_vertex(g); + typename CGAL::Kernel_traits

::Kernel::FT t = + (radius + radius*CGAL::approximate_sqrt(5.0)) / 2.0; + + put(vpmap, v_vertices[0],P(-radius + center.x(), t + center.y(), 0.0 + center.z())); + put(vpmap, v_vertices[1],P( radius + center.x(), t + center.y(), 0.0 + center.z())); + put(vpmap, v_vertices[2],P(-radius + center.x(), -t + center.y(), 0.0 + center.z())); + put(vpmap, v_vertices[3],P( radius + center.x(), -t + center.y(), 0.0 + center.z())); + + put(vpmap, v_vertices[4],P( 0.0 + center.x(), -radius + center.y(), t + center.z())); + put(vpmap, v_vertices[5],P( 0.0 + center.x(), radius + center.y(), t + center.z())); + put(vpmap, v_vertices[6],P( 0.0 + center.x(), -radius + center.y(), -t + center.z())); + put(vpmap, v_vertices[7],P( 0.0 + center.x(), radius + center.y(), -t + center.z())); + + put(vpmap, v_vertices[8],P( t + center.x(), 0.0 + center.y(), -radius + center.z())); + put(vpmap, v_vertices[9],P( t + center.x(), 0.0 + center.y(), radius + center.z())); + put(vpmap, v_vertices[10],P(-t + center.x(), 0.0 + center.y(), -radius + center.z())); + put(vpmap, v_vertices[11],P(-t + center.x(), 0.0 + center.y(), radius + center.z())); + + std::vector face; + face.resize(3); + face[1] = v_vertices[0]; face[0] = v_vertices[11]; face[2] = v_vertices[5]; + Euler::add_face(face, g); + face[1] = v_vertices[0]; face[0] = v_vertices[5]; face[2] = v_vertices[1]; + Euler::add_face(face, g); + face[1] = v_vertices[0]; face[0] = v_vertices[1]; face[2] = v_vertices[7]; + Euler::add_face(face, g); + face[1] = v_vertices[0]; face[0] = v_vertices[7]; face[2] = v_vertices[10]; + Euler::add_face(face, g); + face[1] = v_vertices[0]; face[0] = v_vertices[10]; face[2] = v_vertices[11]; + Euler::add_face(face, g); + + face[1] = v_vertices[1] ; face[0] = v_vertices[5] ; face[2] = v_vertices[9]; + Euler::add_face(face, g); + face[1] = v_vertices[5] ; face[0] = v_vertices[11]; face[2] = v_vertices[4]; + Euler::add_face(face, g); + face[1] = v_vertices[11]; face[0] = v_vertices[10]; face[2] = v_vertices[2]; + Euler::add_face(face, g); + face[1] = v_vertices[10]; face[0] = v_vertices[7] ; face[2] = v_vertices[6]; + Euler::add_face(face, g); + face[1] = v_vertices[7] ; face[0] = v_vertices[1] ; face[2] = v_vertices[8]; + Euler::add_face(face, g); + + face[1] = v_vertices[3] ; face[0] = v_vertices[9] ; face[2] = v_vertices[4]; + Euler::add_face(face, g); + face[1] = v_vertices[3] ; face[0] = v_vertices[4] ; face[2] = v_vertices[2]; + Euler::add_face(face, g); + face[1] = v_vertices[3] ; face[0] = v_vertices[2] ; face[2] = v_vertices[6]; + Euler::add_face(face, g); + face[1] = v_vertices[3] ; face[0] = v_vertices[6] ; face[2] = v_vertices[8]; + Euler::add_face(face, g); + face[1] = v_vertices[3] ; face[0] = v_vertices[8] ; face[2] = v_vertices[9]; + Euler::add_face(face, g); + + face[1] = v_vertices[4] ; face[0] = v_vertices[9] ; face[2] = v_vertices[5] ; + Euler::add_face(face, g); + face[1] = v_vertices[2] ; face[0] = v_vertices[4] ; face[2] = v_vertices[11]; + Euler::add_face(face, g); + face[1] = v_vertices[6] ; face[0] = v_vertices[2] ; face[2] = v_vertices[10]; + Euler::add_face(face, g); + face[1] = v_vertices[8] ; face[0] = v_vertices[6] ; face[2] = v_vertices[7] ; + Euler::add_face(face, g); + face[1] = v_vertices[9] ; face[0] = v_vertices[8] ; face[2] = v_vertices[1] ; + Euler::add_face(face, g); +} + + namespace internal { template diff --git a/Installation/changes.html b/Installation/changes.html index f333407b38d..dda86832ee1 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -178,14 +178,17 @@ and src/ directories). -

CGAL and the Boost Graph Library (BGL)

+

CGAL and the Boost Graph Library

    +
  • Helper functions to create an icosahedron, a regular prism and a + pyramid have been added. +
  • Add class CGAL::Face_filtered_graph that wraps an existing graph and hide all simplices that are not in the selected connected components.
  • -
+ diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_volumes_generator_dialog.ui b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_volumes_generator_dialog.ui index bff5971840d..f7934da9ea9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_volumes_generator_dialog.ui +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_volumes_generator_dialog.ui @@ -6,8 +6,8 @@ 0 0 - 672 - 402 + 696 + 607 @@ -57,7 +57,7 @@ - <html><head/><body><p>The prism center's coordinates.</p><p><br/></p></body></html> + <html><head/><body><p>The coordinates of the prism's center.</p><p><br/></p></body></html> Center: @@ -131,7 +131,7 @@ - + 2 @@ -174,7 +174,7 @@ - <html><head/><body><p>Mark this if you want the basis of the prism to be constructed as well.</p></body></html> + <html><head/><body><p>If this is unmarked, the bases will not be created.</p></body></html> Closed: @@ -199,6 +199,186 @@ + + + + + + + + + + + + <html><head/><body><p>The number of points in the base of the pyramid. Must be at least 3.</p></body></html> + + + #Points: + + + + + + + 3 + + + 360000 + + + 36 + + + + + + + + + + + <html><head/><body><p>The coordinates of the pyramid's apex.</p><p><br/></p></body></html> + + + Center: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 2 + + + -1000000000000000000.000000000000000 + + + 1000000000000000000.000000000000000 + + + + + + + 2 + + + -1000000000000000000.000000000000000 + + + 1000000000000000000.000000000000000 + + + + + + + 2 + + + -1000000000000000000.000000000000000 + + + 1000000000000000000.000000000000000 + + + + + + + + + + + <html><head/><body><p>The pyramid's height.</p></body></html> + + + Height: + + + + + + + 2 + + + 1000000000000000000.000000000000000 + + + 1.000000000000000 + + + + + + + + + + + <html><head/><body><p>The radius of the circle in which the base is inscribed.</p></body></html> + + + Base Radius: + + + + + + + 1000000000000000000.000000000000000 + + + 1.000000000000000 + + + + + + + + + + + <html><head/><body><p>If this is unmarked, the base will not be created.</p></body></html> + + + Closed: + + + + + + + Qt::RightToLeft + + + + + + true + + + + + + + + diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_volumes_generator_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_volumes_generator_plugin.cpp index 1ff52a005f9..b2a216bad25 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_volumes_generator_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_volumes_generator_plugin.cpp @@ -9,6 +9,7 @@ #include #include "Scene_polyhedron_item.h" #include +#include #include "ui_Basic_volumes_generator_dialog.h" class VolumeDialog : @@ -39,24 +40,30 @@ class Q_DECL_EXPORT Basic_volumes_generator_plugin : 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*) + void init(QMainWindow* mainWindow, + CGAL::Three::Scene_interface* scene_interface, + Messages_interface*) { this->scene = scene_interface; this->mw = mainWindow; QAction* actionCube = new QAction("Generate Cube", mw); QAction* actionPrism = new QAction("Generate Regular Prism", mw); + QAction* actionPyramid = new QAction("Generate Pyramid", mw); QAction* actionSphere = new QAction("Generate Sphere", mw); QAction* actionTetrahedron = new QAction("Generate Tetrahedron", mw); connect(actionCube, SIGNAL(triggered()), this, SLOT(on_actionCube_triggered())); connect(actionPrism, SIGNAL(triggered()), this, SLOT(on_actionPrism_triggered())); + connect(actionPyramid, SIGNAL(triggered()), + this, SLOT(on_actionPyramid_triggered())); connect(actionSphere, SIGNAL(triggered()), this, SLOT(on_actionSphere_triggered())); connect(actionTetrahedron, SIGNAL(triggered()), this, SLOT(on_actionTetrahedron_triggered())); _actions << actionCube << actionPrism + << actionPyramid << actionSphere << actionTetrahedron; Q_FOREACH(QAction* action, _actions) @@ -65,6 +72,7 @@ public : bool applicable(QAction*) const { + //always applicable return true; } QList actions() const { @@ -73,6 +81,7 @@ public : public Q_SLOTS: void on_actionCube_triggered(); void on_actionPrism_triggered(); + void on_actionPyramid_triggered(); void on_actionSphere_triggered(); void on_actionTetrahedron_triggered(); private: @@ -100,156 +109,18 @@ void Basic_volumes_generator_plugin::on_actionCube_triggered() scene->addItem(cube_item); } //make a prism -template -void make_regular_prism(int nb_vertices, - Mesh& prism, - typename CGAL::Point_3 center = CGAL::Point_3(0,0,0), - double height = 1.0, - double radius = 1.0, - bool is_closed = true) -{ - const double to_rad = static_cast(CGAL_PI / 180.0); - const double precision = 360/nb_vertices; - double diameter = 2*radius; - VPMap vpmap = get(CGAL::vertex_point, prism); - //const int nb_vertices = 360/precision * 2; - std::vector vertices; - vertices.resize(nb_vertices*2); - for(int i=0; i face; - face.resize(3); - //fill faces - for(int i=0; i -void make_icosahedron(Mesh& mesh, - typename CGAL::Point_3 center = CGAL::Point_3(0,0,0), - double radius = 1.0) -{ - VPMap vpmap = get(CGAL::vertex_point, mesh); - // create the initial icosahedron - std::vector v_vertices; - v_vertices.resize(12); - for(int i=0; i<12; ++i) - v_vertices[i] = add_vertex(mesh); - double t = (radius + radius*CGAL::sqrt(5.0)) / 2.0; - - put(vpmap, v_vertices[0],typename Traits::Point_3(-radius + center.x(), t + center.y(), 0.0 + center.z())); - put(vpmap, v_vertices[1],typename Traits::Point_3( radius + center.x(), t + center.y(), 0.0 + center.z())); - put(vpmap, v_vertices[2],typename Traits::Point_3(-radius + center.x(), -t + center.y(), 0.0 + center.z())); - put(vpmap, v_vertices[3],typename Traits::Point_3( radius + center.x(), -t + center.y(), 0.0 + center.z())); - - put(vpmap, v_vertices[4],typename Traits::Point_3( 0.0 + center.x(), -radius + center.y(), t + center.z())); - put(vpmap, v_vertices[5],typename Traits::Point_3( 0.0 + center.x(), radius + center.y(), t + center.z())); - put(vpmap, v_vertices[6],typename Traits::Point_3( 0.0 + center.x(), -radius + center.y(), -t + center.z())); - put(vpmap, v_vertices[7],typename Traits::Point_3( 0.0 + center.x(), radius + center.y(), -t + center.z())); - - put(vpmap, v_vertices[8],typename Traits::Point_3( t + center.x(), 0.0 + center.y(), -radius + center.z())); - put(vpmap, v_vertices[9],typename Traits::Point_3( t + center.x(), 0.0 + center.y(), radius + center.z())); - put(vpmap, v_vertices[10],typename Traits::Point_3(-t + center.x(), 0.0 + center.y(), -radius + center.z())); - put(vpmap, v_vertices[11],typename Traits::Point_3(-t + center.x(), 0.0 + center.y(), radius + center.z())); - - std::vector face; - face.resize(3); - face[1] = v_vertices[0]; face[0] = v_vertices[11]; face[2] = v_vertices[5]; - euler::add_face(face, mesh); - face[1] = v_vertices[0]; face[0] = v_vertices[5]; face[2] = v_vertices[1]; - euler::add_face(face, mesh); - face[1] = v_vertices[0]; face[0] = v_vertices[1]; face[2] = v_vertices[7]; - euler::add_face(face, mesh); - face[1] = v_vertices[0]; face[0] = v_vertices[7]; face[2] = v_vertices[10]; - euler::add_face(face, mesh); - face[1] = v_vertices[0]; face[0] = v_vertices[10]; face[2] = v_vertices[11]; - euler::add_face(face, mesh); - - face[1] = v_vertices[1] ; face[0] = v_vertices[5] ; face[2] = v_vertices[9]; - euler::add_face(face, mesh); - face[1] = v_vertices[5] ; face[0] = v_vertices[11]; face[2] = v_vertices[4]; - euler::add_face(face, mesh); - face[1] = v_vertices[11]; face[0] = v_vertices[10]; face[2] = v_vertices[2]; - euler::add_face(face, mesh); - face[1] = v_vertices[10]; face[0] = v_vertices[7] ; face[2] = v_vertices[6]; - euler::add_face(face, mesh); - face[1] = v_vertices[7] ; face[0] = v_vertices[1] ; face[2] = v_vertices[8]; - euler::add_face(face, mesh); - - face[1] = v_vertices[3] ; face[0] = v_vertices[9] ; face[2] = v_vertices[4]; - euler::add_face(face, mesh); - face[1] = v_vertices[3] ; face[0] = v_vertices[4] ; face[2] = v_vertices[2]; - euler::add_face(face, mesh); - face[1] = v_vertices[3] ; face[0] = v_vertices[2] ; face[2] = v_vertices[6]; - euler::add_face(face, mesh); - face[1] = v_vertices[3] ; face[0] = v_vertices[6] ; face[2] = v_vertices[8]; - euler::add_face(face, mesh); - face[1] = v_vertices[3] ; face[0] = v_vertices[8] ; face[2] = v_vertices[9]; - euler::add_face(face, mesh); - - face[1] = v_vertices[4] ; face[0] = v_vertices[9] ; face[2] = v_vertices[5] ; - euler::add_face(face, mesh); - face[1] = v_vertices[2] ; face[0] = v_vertices[4] ; face[2] = v_vertices[11]; - euler::add_face(face, mesh); - face[1] = v_vertices[6] ; face[0] = v_vertices[2] ; face[2] = v_vertices[10]; - euler::add_face(face, mesh); - face[1] = v_vertices[8] ; face[0] = v_vertices[6] ; face[2] = v_vertices[7] ; - euler::add_face(face, mesh); - face[1] = v_vertices[9] ; face[0] = v_vertices[8] ; face[2] = v_vertices[1] ; - euler::add_face(face, mesh); -} void Basic_volumes_generator_plugin::on_actionPrism_triggered() { //gets the precision parameter VolumeDialog *dialog = new VolumeDialog(); dialog->sphereGroupBox->setVisible(false); + dialog->pyramidGroupBox->setVisible(false); dialog->prismGroupBox->setVisible(true); //opens the dialog if(!dialog->exec()) return; int nb_vertices = dialog->prismSpinBox->value(); - double height(dialog->heightSpinBox->value()), + double height(dialog->prismHeightSpinBox->value()), radius(dialog->prismBaseSpinBox->value()), center_x(dialog->prismXSpinBox->value()), center_y(dialog->prismYSpinBox->value()), @@ -257,17 +128,61 @@ void Basic_volumes_generator_plugin::on_actionPrism_triggered() bool is_closed = dialog->prismCheckBox->isChecked(); Polyhedron prism; - make_regular_prism(nb_vertices, prism, Point(center_x,center_y,center_z), height, radius, is_closed); + make_regular_prism(nb_vertices, + prism, + Point(center_x, + center_y, + center_z), + height, + radius, + is_closed); + Scene_polyhedron_item* prism_item = new Scene_polyhedron_item(prism); prism_item->setName(QString("Prism")); scene->addItem(prism_item); } + +//make a pyramid +void Basic_volumes_generator_plugin::on_actionPyramid_triggered() +{ + //gets the precision parameter + VolumeDialog *dialog = new VolumeDialog(); + dialog->sphereGroupBox->setVisible(false); + dialog->prismGroupBox->setVisible(false); + dialog->pyramidGroupBox->setVisible(true); + //opens the dialog + if(!dialog->exec()) + return; + int nb_vertices = dialog->pyramidSpinBox->value(); + double height(dialog->pyramidHeightSpinBox->value()), + radius(dialog->pyramidBaseSpinBox->value()), + center_x(dialog->pyramidXSpinBox->value()), + center_y(dialog->pyramidYSpinBox->value()), + center_z(dialog->pyramidZSpinBox->value()); + bool is_closed = dialog->pyramidCheckBox->isChecked(); + + Polyhedron pyramid; + make_pyramid(nb_vertices, + pyramid, + Point(center_x, + center_y, + center_z), + height, + radius, + is_closed); + + Scene_polyhedron_item* pyramid_item = new Scene_polyhedron_item(pyramid); + pyramid_item->setName(QString("Pyramid")); + scene->addItem(pyramid_item); +} + //make a sphere void Basic_volumes_generator_plugin::on_actionSphere_triggered() { //gets the precision parameter VolumeDialog *dialog = new VolumeDialog(); dialog->prismGroupBox->setVisible(false); + dialog->pyramidGroupBox->setVisible(false); dialog->sphereGroupBox->setVisible(true); //opens the dialog if(!dialog->exec()) @@ -280,7 +195,8 @@ void Basic_volumes_generator_plugin::on_actionSphere_triggered() Polyhedron sphere; make_icosahedron(sphere, center, radius); if(precision !=0) - CGAL::Subdivision_method_3::Sqrt3_subdivision(sphere, precision); + CGAL::Subdivision_method_3::Sqrt3_subdivision(sphere, + precision); VPMap vpmap = get(CGAL::vertex_point, sphere); //emplace the points back on the sphere BOOST_FOREACH(vertex_descriptor vd, vertices(sphere)) @@ -300,10 +216,10 @@ void Basic_volumes_generator_plugin::on_actionSphere_triggered() void Basic_volumes_generator_plugin::on_actionTetrahedron_triggered() { Polyhedron tetrahedron; - CGAL::make_tetrahedron(Point(-0.5,-0.5,-0.5), - Point(0.5,-0.5,-0.5), - Point(0,0.5,-0.5), - Point(0,0,0.5), + CGAL::make_tetrahedron(Point(0.0, 0.0, 0.0), + Point(1.0, 0.0, 0.0), + Point(0.0, 1.0, 0.0), + Point(0.0, 0.0, 1.0), tetrahedron); Scene_polyhedron_item* tet_item = new Scene_polyhedron_item(tetrahedron); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt index 750eee2f563..ab97b840d93 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt @@ -13,5 +13,6 @@ polyhedron_demo_plugin(create_bbox_mesh_plugin Create_bbox_mesh_plugin) target_link_libraries(create_bbox_mesh_plugin scene_polyhedron_item) qt5_wrap_ui( volumesUI_FILES Basic_volumes_generator_dialog.ui ) + polyhedron_demo_plugin(basic_volumes_generator_plugin Basic_volumes_generator_plugin ${volumesUI_FILES}) target_link_libraries(basic_volumes_generator_plugin scene_polyhedron_item)