Changes :

- change types in the functions parameters
- make the tetrahedron based on the unit vectors
- add a function to create a pyramid
- add assertions to protect the numbers of vertices
- move the functions to BGL::helpers.h and add documentation
This commit is contained in:
Maxime Gimeno 2017-05-09 11:12:05 +02:00
parent 9d70c107b8
commit 3f72bfc8ba
5 changed files with 517 additions and 154 deletions

View File

@ -33,6 +33,10 @@ namespace CGAL {
template< typename Graph>
void fill_hole(typename boost::graph_traits<Graph>::halfedge_descriptor h,
Graph& g);
template<typename Graph , typename VertexRange >
typename boost::graph_traits<Graph>::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<class Graph, class P>
void make_regular_prism(
typename boost::graph_traits<Graph>::vertices_size_type nb_vertices,
Graph& g,
const P& center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT height = 1.0,
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0,
bool is_closed = true)
{
CGAL_assertion(nb_vertices >= 3);
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename CGAL::Kernel_traits<P>::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<vertex_descriptor> vertices;
vertices.resize(nb_vertices*2);
for(int i=0; i<nb_vertices*2; ++i)
vertices[i] = add_vertex(g);
//fill vertices
for(int i=0; i < nb_vertices; ++i)
{
put(vpmap,
vertices[i],
P(0.5*diameter*cos(i*precision*to_rad)+center.x(),
0.5*height+center.y(),
-0.5*diameter*sin(i*precision*to_rad) + center.z()));
put(vpmap,
vertices[i+nb_vertices],
P(0.5*diameter*cos(i*precision*to_rad)+center.x(),
-0.5*height+center.y(),
-0.5*diameter*sin(i*precision*to_rad)+center.z()));
}
std::vector<vertex_descriptor> face;
face.resize(3);
//fill faces
for(int i=0; i<nb_vertices; ++i)
{
face[0] = vertices[(i+1)%(nb_vertices)];
face[1] = vertices[i];
face[2] = vertices[(i+1)%(nb_vertices) + nb_vertices];
Euler::add_face(face, g);
face[0] = vertices[(i+1)%(nb_vertices) + nb_vertices];
face[1] = vertices[i];
face[2] = vertices[i + nb_vertices];
Euler::add_face(face, g);
}
//close
if(is_closed)
{
//add the center of the fans
vertex_descriptor top = add_vertex(g);
vertex_descriptor bot = add_vertex(g);
put(vpmap, top, P(center.x(),0.5*height+center.y(),center.z()));
put(vpmap, bot, P(center.x(),-0.5*height+center.y(),center.z()));
//add the faces
for(int i=0; i<nb_vertices; ++i)
{
face[0] = vertices[i];
face[1] = vertices[(i+1)%(nb_vertices)];
face[2] = top;
Euler::add_face(face, g);
face[0] = bot;
face[1] = vertices[(i+1)%(nb_vertices) + nb_vertices];
face[2] = vertices[i + nb_vertices];
Euler::add_face(face, g);
}
}
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates a pyramid.
*
* Creates a pyramid in `g`, having `nb_vertices` vertices in its base.
* \param nb_vertices the number of vertices in the base. It must be greater than or equals 3.
* \param g the graph in which the pyramid will be created
* \param base_center the center of the circle in which the base is inscribed.
* \param height the distance between the base and the apex.
* \param radius the radius of the circle in which the base is inscribed.
* \param is_closed determines if the base must be created or not.
*/
template<class Graph, class P>
void make_pyramid(
typename boost::graph_traits<Graph>::vertices_size_type nb_vertices,
Graph& g,
const P& base_center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT height = 1.0,
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0,
bool is_closed = true)
{
CGAL_assertion(nb_vertices >= 3);
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename CGAL::Kernel_traits<P>::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<vertex_descriptor> vertices;
vertices.resize(nb_vertices);
for(int i=0; i<nb_vertices; ++i)
vertices[i] = add_vertex(g);
vertex_descriptor apex = add_vertex(g);
//fill vertices
put(vpmap,
apex,
P(base_center.x(),
base_center.y() + height,
base_center.z()));
for(int i=0; i < nb_vertices; ++i)
{
put(vpmap,
vertices[i],
P(0.5*diameter*cos(i*precision*to_rad)+base_center.x(),
base_center.y(),
-0.5*diameter*sin(i*precision*to_rad)+base_center.z()));
}
std::vector<vertex_descriptor> face;
face.resize(3);
//fill faces
for(int i=0; i<nb_vertices; ++i)
{
face[0] = apex;
face[1] = vertices[i];
face[2] = vertices[(i+1)%(nb_vertices)];
Euler::add_face(face, g);
}
//close
if(is_closed)
{
//add the center of the fan
vertex_descriptor bot = add_vertex(g);
put(vpmap, bot, P(base_center.x(),base_center.y(),base_center.z()));
//add the faces
for(int i=0; i<nb_vertices; ++i)
{
face[0] = bot;
face[1] = vertices[(i+1)%(nb_vertices)];
face[2] = vertices[i];
Euler::add_face(face, g);
}
}
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates an icosahedron.
*
* Creates an icosahedron in `g` centered in `center`.
* \param g the graph in which the icosahedron will be created.
* \param center the center of the sphere in which the icosahedron is inscribed.
* \param radius the radius of the sphere in which the icosahedron is inscribed.
*/
template<class Graph, class P>
void make_icosahedron(
Graph& g,
const P& center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0)
{
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
Point_property_map vpmap = get(CGAL::vertex_point, g);
// create the initial icosahedron
std::vector<vertex_descriptor> v_vertices;
v_vertices.resize(12);
for(int i=0; i<12; ++i)
v_vertices[i] = add_vertex(g);
typename CGAL::Kernel_traits<P>::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<vertex_descriptor> 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<typename FaceGraph>

View File

@ -178,14 +178,17 @@ and <code>src/</code> directories).
<!-- Interpolation -->
<!-- Kinetic Data Structures -->
<!-- Support Library -->
<h3>CGAL and the Boost Graph Library (BGL)</h3>
<h3>CGAL and the Boost Graph Library</h3>
<ul>
<li>Helper functions to create an icosahedron, a regular prism and a
pyramid have been added.
</li>
<li>
Add class <code>CGAL::Face_filtered_graph</code> that
wraps an existing graph and hide all simplices that are not
in the selected connected components.
</li>
</ul>
</ul>
<!-- Visualization -->
<!-- end of the div for 4.10 -->

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>672</width>
<height>402</height>
<width>696</width>
<height>607</height>
</rect>
</property>
<property name="windowTitle">
@ -57,7 +57,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The prism center's coordinates.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The coordinates of the prism's center.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Center:</string>
@ -131,7 +131,7 @@
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="heightSpinBox">
<widget class="QDoubleSpinBox" name="prismHeightSpinBox">
<property name="decimals">
<number>2</number>
</property>
@ -174,7 +174,7 @@
<item>
<widget class="QLabel" name="label">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mark this if you want the basis of the prism to be constructed as well.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this is unmarked, the bases will not be created.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Closed: </string>
@ -199,6 +199,186 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="pyramidGroupBox">
<property name="title">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="prismLayout_3" stretch="1,0">
<item>
<widget class="QLabel" name="pyramidLabel">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The number of points in the base of the pyramid. Must be at least 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>#Points:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="pyramidSpinBox">
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>360000</number>
</property>
<property name="value">
<number>36</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11" stretch="4,1,0,0,0">
<item>
<widget class="QLabel" name="label_11">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The coordinates of the pyramid's apex.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Center:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDoubleSpinBox" name="pyramidXSpinBox">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-1000000000000000000.000000000000000</double>
</property>
<property name="maximum">
<double>1000000000000000000.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="pyramidYSpinBox">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-1000000000000000000.000000000000000</double>
</property>
<property name="maximum">
<double>1000000000000000000.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="pyramidZSpinBox">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-1000000000000000000.000000000000000</double>
</property>
<property name="maximum">
<double>1000000000000000000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12" stretch="1,0">
<item>
<widget class="QLabel" name="label_12">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The pyramid's height.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Height:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="pyramidHeightSpinBox">
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>1000000000000000000.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13" stretch="0,0">
<item>
<widget class="QLabel" name="label_13">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The radius of the circle in which the base is inscribed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Base Radius:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="pyramidBaseSpinBox">
<property name="maximum">
<double>1000000000000000000.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item>
<widget class="QLabel" name="label_14">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this is unmarked, the base will not be created.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Closed: </string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="pyramidCheckBox">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="sphereGroupBox">
<property name="title">

View File

@ -9,6 +9,7 @@
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
#include "Scene_polyhedron_item.h"
#include <CGAL/Subdivision_method_3.h>
#include <CGAL/Kernel_traits.h>
#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<QAction*> 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<class Mesh, class Traits>
void make_regular_prism(int nb_vertices,
Mesh& prism,
typename CGAL::Point_3<Traits> center = CGAL::Point_3<Traits>(0,0,0),
double height = 1.0,
double radius = 1.0,
bool is_closed = true)
{
const double to_rad = static_cast<float>(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<vertex_descriptor> vertices;
vertices.resize(nb_vertices*2);
for(int i=0; i<nb_vertices*2; ++i)
vertices[i] = add_vertex(prism);
//fill vertices
for(int i=0; i < nb_vertices; ++i)
{
put(vpmap, vertices[i], Point(0.5*diameter*cos(i*precision*to_rad)+center.x(),0.5*height+center.y(),-0.5*diameter*sin(i*precision*to_rad) + center.z()));
put(vpmap, vertices[i+nb_vertices], Point(0.5*diameter*cos(i*precision*to_rad)+center.x(),-0.5*height+center.y(),-0.5*diameter*sin(i*precision*to_rad)+center.z()));
}
std::vector<vertex_descriptor> face;
face.resize(3);
//fill faces
for(int i=0; i<nb_vertices; ++i)
{
face[0] = vertices[(i+1)%(nb_vertices)];
face[1] = vertices[i];
face[2] = vertices[(i+1)%(nb_vertices) + nb_vertices];
euler::add_face(face, prism);
face[0] = vertices[(i+1)%(nb_vertices) + nb_vertices];
face[1] = vertices[i];
face[2] = vertices[i + nb_vertices];
euler::add_face(face, prism);
}
//close
if(is_closed)
{
//add the center of the fans
vertex_descriptor top = add_vertex(prism);
vertex_descriptor bot = add_vertex(prism);
put(vpmap, top, Point(center.x(),0.5*height+center.y(),center.z()));
put(vpmap, bot, Point(center.x(),-0.5*height+center.y(),center.z()));
//add the faces
for(int i=0; i<nb_vertices; ++i)
{
face[0] = vertices[i];
face[1] = vertices[(i+1)%(nb_vertices)];
face[2] = top;
euler::add_face(face, prism);
face[0] = bot;
face[1] = vertices[(i+1)%(nb_vertices) + nb_vertices];
face[2] = vertices[i + nb_vertices];
euler::add_face(face, prism);
}
}
}
template<class Mesh, class Traits>
void make_icosahedron(Mesh& mesh,
typename CGAL::Point_3<Traits> center = CGAL::Point_3<Traits>(0,0,0),
double radius = 1.0)
{
VPMap vpmap = get(CGAL::vertex_point, mesh);
// create the initial icosahedron
std::vector<vertex_descriptor> 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<vertex_descriptor> 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);

View File

@ -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)