mirror of https://github.com/CGAL/cgal
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:
parent
9d70c107b8
commit
3f72bfc8ba
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 -->
|
||||
|
|
|
|||
|
|
@ -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><html><head/><body><p>The prism center's coordinates.</p><p><br/></p></body></html></string>
|
||||
<string><html><head/><body><p>The coordinates of the prism's center.</p><p><br/></p></body></html></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><html><head/><body><p>Mark this if you want the basis of the prism to be constructed as well.</p></body></html></string>
|
||||
<string><html><head/><body><p>If this is unmarked, the bases will not be created.</p></body></html></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><html><head/><body><p>The number of points in the base of the pyramid. Must be at least 3.</p></body></html></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><html><head/><body><p>The coordinates of the pyramid's apex.</p><p><br/></p></body></html></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><html><head/><body><p>The pyramid's height.</p></body></html></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><html><head/><body><p>The radius of the circle in which the base is inscribed.</p></body></html></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><html><head/><body><p>If this is unmarked, the base will not be created.</p></body></html></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">
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue