\( \newcommand{\E}{\mathrm{E}} \) \( \newcommand{\A}{\mathrm{A}} \) \( \newcommand{\R}{\mathrm{R}} \) \( \newcommand{\N}{\mathrm{N}} \) \( \newcommand{\Q}{\mathrm{Q}} \) \( \newcommand{\Z}{\mathrm{Z}} \) \( \def\ccSum #1#2#3{ \sum_{#1}^{#2}{#3} } \def\ccProd #1#2#3{ \sum_{#1}^{#2}{#3} }\)
CGAL 4.12.2 - Three
Three/Example_plugin/Example_plugin.cpp
#include <QApplication>
#include <QMainWindow>
#include <QAction>
#include <QVector>
#include <CGAL/Three/Scene_item.h>
#include <CGAL/Three/Viewer_interface.h>
#include <CGAL/Three/Scene_group_item.h>
// The special Scene_item only for triangles
//this is used by the Qt's MOC system to manage the metadata.
#ifdef scene_triangle_item_EXPORTS
# define SCENE_TRIANGLE_ITEM_EXPORT Q_DECL_EXPORT
#else
# define SCENE_TRIANGLE_ITEM_EXPORT Q_DECL_IMPORT
#endif
class Scene_triangle_item : public CGAL::Three::Scene_item
{
Q_OBJECT
public :
Scene_triangle_item(double ax,double ay, double az,
double bx,double by, double bz,
double cx,double cy, double cz);
// Indicates if rendering mode is supported
bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE {
return (m == Flat);
}
//Displays the item
void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE;
//Specifies that the buffers need to be initialized again.
//Is mostly called after a change of geometry in the data.
void invalidateOpenGLBuffers() Q_DECL_OVERRIDE;
//fills the std::vector
void computeElements(double ax,double ay, double az,
double bx,double by, double bz,
double cx,double cy, double cz) const Q_DECL_OVERRIDE;
Scene_item* clone() const Q_DECL_OVERRIDE {return 0;}
QString toolTip() const Q_DECL_OVERRIDE {return QString();}
private:
//contains the data
mutable std::vector<float> vertices;
mutable int nb_pos;
mutable QOpenGLShaderProgram *program;
//Fills the buffers with data. The buffers allow us to give data to the shaders.
void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const Q_DECL_OVERRIDE;
}; //end of class Scene_triangle_item
Scene_triangle_item::Scene_triangle_item(double ax,double ay, double az,
double bx,double by, double bz,
double cx,double cy, double cz)
{
nb_pos = 0;
are_buffers_filled = false;
computeElements(ax, ay, az,
bx, by, bz,
cx, cy, cz);
}
//Fills the position vector with data.
void Scene_triangle_item::computeElements(double ax, double ay, double az,
double bx, double by, double bz,
double cx, double cy, double cz)const
{
vertices.resize(9);
vertices[0] = ax; vertices[1] = ay; vertices[2] = az;
vertices[3] = bx; vertices[4] = by; vertices[5] = bz;
vertices[6] = cx; vertices[7] = cy; vertices[8] = cz;
}
void Scene_triangle_item::draw(CGAL::Three::Viewer_interface* viewer) const
{
//The filling of the buffers should be performed in this function, because it needs a valid openGL context, and we are certain to have one in this function.
if(!are_buffers_filled)
{
computeElements(0, 0, 0,
1, 0, 0,
0.5, 0.5, 0);
}
//Binds the vao corresponding to the type of data we are drawing.
vaos[0]->bind();
//Gets the program corresponding to the type of data we are drawing.
//Here we want triangles with light effects.
program = getShaderProgram(PROGRAM_WITH_LIGHT);
//Gives most of the uniform values to the shaders.
attribBuffers(viewer, PROGRAM_WITH_LIGHT);
//Binds the program chosen before to use the right shaders.
program->bind();
//Gives the wanted color to the fragment shader as uniform value.
program->setAttributeValue("colors", this->color());
//Draws the items
viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(nb_pos/3));
//clean up
vaos[0]->release();
program->release();
}
//Specifies that the buffers need to be initialized again.
//Is mostly called after a change of geometry in the data.
void Scene_triangle_item::invalidateOpenGLBuffers()
{
are_buffers_filled = false;
}
void Scene_triangle_item::initializeBuffers(CGAL::Three::Viewer_interface *viewer)const
{
//vao containing the data for the facets
{
program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer);
program->bind();
vaos[0]->bind();
buffers[0].bind();
buffers[0].allocate(vertices.data(),
static_cast<GLsizei>(vertices.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
buffers[0].release();
vaos[0]->release();
program->release();
}
//once the buffers are fill, we can empty the vectors to optimize memory consumption
nb_pos = vertices.size();
vertices.resize(0);
//"Swap trick" insures that the memory is indeed freed and not kept available
std::vector<float>(vertices).swap(vertices);
are_buffers_filled = true;
}
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
//The actual plugin
using namespace CGAL::Three;
class Q_DECL_EXPORT Polyhedron_demo_example_plugin :
public QObject,
{
//Configures CMake to use MOC correctly
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
public :
// Adds an action to the menu and configures the widget
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) Q_DECL_OVERRIDE{
//get the references
this->scene = scene_interface;
this->mw = mainWindow;
//creates and link the actions
QAction* actionDrawTriangle= new QAction("Draw Triangle", mw);
if(actionDrawTriangle) {
connect(actionDrawTriangle, SIGNAL(triggered()),
this, SLOT(draw_triangle()));
_actions << actionDrawTriangle;
}
}
bool applicable(QAction*) const Q_DECL_OVERRIDE
{
return true;
}
QList<QAction*> actions() const Q_DECL_OVERRIDE{
return _actions;
}
public Q_SLOTS:
void draw_triangle() {
triangle = new Scene_triangle_item(0, 0, 0,
1, 0, 0,
0.5, 0.5, 0);
triangle->setName(QString("Basic triangle"));
scene->addItem(triangle);
}
private:
QList<QAction*> _actions;
}; //end of class Polyhedron_demo_example_plugin
#include "Example_plugin.moc"