WIP editable box

This commit is contained in:
Maxime Gimeno 2016-10-20 16:05:04 +02:00
parent 50b93ce2dc
commit 71feaa34be
2 changed files with 496 additions and 97 deletions

View File

@ -2,22 +2,32 @@
#include <QApplication>
#include <CGAL/Three/Viewer_interface.h>
#include <QGLViewer/manipulatedFrame.h>
#include <QMouseEvent>
#include <QOpenGLFramebufferObject>
#include <QOpenGLShaderProgram>
using namespace CGAL::Three;
struct Scene_edit_box_item::vertex{
short id;
CGAL::Point_3<Kernel> position;
face* face_;
double *x;
double *y;
double *z;
CGAL::Point_3<Kernel> position()const
{
return CGAL::Point_3<Kernel>(*x,*y,*z);
}
};
struct Scene_edit_box_item::edge{
short id;
vertex source;
vertex target;
vertex* source;
vertex* target;
face* face_;
};
struct Scene_edit_box_item::face{
short id;
edge edges[4];
vertex vertices[4];
edge* edges[4];
vertex* vertices[4];
};
struct Scene_edit_box_item_priv{
@ -25,38 +35,52 @@ struct Scene_edit_box_item_priv{
enum VAOs{
Edges = 0,
Spheres,
Faces,
S_Edges,
S_Spheres,
S_Faces,
Arrow,
Faces,
P_Edges,
P_Spheres,
P_Faces,
NumberOfVaos
};
enum VBOs{
VertexEdges = 0,
ColorsEdges,
VertexSpheres,
NormalSpheres,
CenterSpheres,
ColorsSpheres,
VertexFaces,
NormalFaces,
ColorsFaces,
VertexArrow,
NormalArrow,
NumberOfVbos
};
Scene_edit_box_item_priv(const CGAL::Three::Scene_interface *scene_interface, Scene_edit_box_item* ebi)
Scene_edit_box_item_priv(const Scene_interface *scene_interface, Scene_edit_box_item* ebi)
{
scene = scene_interface;
item = ebi;
CGAL::Three::Scene_item::Bbox bb = scene->bbox();
selection_on = false;
Scene_item::Bbox bb = scene->bbox();
double x=(bb.xmin()+bb.xmax())/2;
double y=(bb.ymin()+bb.ymax())/2;
double z=(bb.zmin()+bb.zmax())/2;
center_ = qglviewer::Vec(x,y,z);
frame = new CGAL::Three::Scene_item::ManipulatedFrame();
remodel_frame = new Scene_item::ManipulatedFrame();
frame = new Scene_item::ManipulatedFrame();
frame->setPosition(center_);
constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS);
constraint.setRotationConstraintDirection(qglviewer::Vec(.0,.0,.1));
frame->setConstraint(&constraint);
//create the sphere model
pool[0] = bb.xmin(); pool[3] = bb.xmax();
pool[1] = bb.ymin(); pool[4] = bb.ymax();
pool[2] = bb.zmin(); pool[5] = bb.zmax();
double sq_diag =
(bb.xmax() - bb.xmin()) * (bb.xmax() - bb.xmin()) +
(bb.ymax() - bb.ymin()) * (bb.ymax() - bb.ymin()) +
@ -76,12 +100,11 @@ struct Scene_edit_box_item_priv{
//vertices
for(short i = 0; i< 8; ++i)
{
double x,y,z;
x = ((i/2)%2==0)? scene->bbox().min(0):scene->bbox().max(0);
y = (i/4==0)? scene->bbox().min(1):scene->bbox().max(1);
z = (((i+1)/2)%2==1)? scene->bbox().min(2):scene->bbox().max(2);
vertices[i].position = Kernel::Point_3(x,y,z);
vertices[i].id = i;
vertices[i].x = ((i/2)%2==0)? &pool[0]:&pool[3];
vertices[i].y = (i/4==0)? &pool[1]:&pool[4];
vertices[i].z = (((i+1)/2)%2==1)? &pool[2]:&pool[5];
vertices[i].id = i;
}
// .--5--.
@ -98,18 +121,18 @@ struct Scene_edit_box_item_priv{
edges[i].id = i;
if(i<4)
{
edges[i].source = vertices[i];
edges[i].target = vertices[i+4];
edges[i].source = &vertices[i];
edges[i].target = &vertices[i+4];
}
else if(i<8)
{
edges[i].source = vertices[i];
edges[i].target = vertices[(i+1)%4 +4];
edges[i].source = &vertices[i];
edges[i].target = &vertices[(i+1)%4 +4];
}
else
{
edges[i].source = vertices[i%4];
edges[i].target = vertices[(i+1) %4];
edges[i].source = &vertices[i%4];
edges[i].target = &vertices[(i+1) %4];
}
vertex_edges.resize(0);
}
@ -133,42 +156,42 @@ struct Scene_edit_box_item_priv{
//faces
for(short i=0; i<4; ++i)
{
faces[0].vertices[i] = vertices[i];
faces[0].edges[(i+1)%4] = edges[i+7];
faces[0].vertices[i] = &vertices[i];
faces[0].edges[(i+1)%4] = &edges[i+7];
}
faces[0].id=0;
faces[0].id =0;
for(short i=1; i<4; ++i)
{
faces[i].vertices[0] = vertices[i];
faces[i].vertices[1] = vertices[(i-1)];
faces[i].vertices[2] = vertices[i+3];
faces[i].vertices[3] = vertices[i+4];
faces[i].vertices[0] = &vertices[i];
faces[i].vertices[1] = &vertices[(i-1)];
faces[i].vertices[2] = &vertices[i+3];
faces[i].vertices[3] = &vertices[i+4];
faces[i].edges[0] = edges[i+7];
faces[i].edges[1] = edges[i-1];
faces[i].edges[2] = edges[i+3];
faces[i].edges[3] = edges[i];
faces[i].edges[0] = &edges[i+7];
faces[i].edges[1] = &edges[i-1];
faces[i].edges[2] = &edges[i+3];
faces[i].edges[3] = &edges[i];
faces[i].id = i;
}
faces[4].vertices[0] = vertices[0];
faces[4].vertices[1] = vertices[3];
faces[4].vertices[2] = vertices[7];
faces[4].vertices[3] = vertices[4];
faces[4].vertices[0] = &vertices[0];
faces[4].vertices[1] = &vertices[3];
faces[4].vertices[2] = &vertices[7];
faces[4].vertices[3] = &vertices[4];
faces[4].edges[0] = edges[0];
faces[4].edges[1] = edges[3];
faces[4].edges[2] = edges[7];
faces[4].edges[3] = edges[4];
faces[4].id=4;
faces[4].edges[0] = &edges[0];
faces[4].edges[1] = &edges[3];
faces[4].edges[2] = &edges[7];
faces[4].edges[3] = &edges[4];
faces[4].id =4;
for(short i=0; i<4; ++i)
{
faces[5].vertices[i] = vertices[i+4];
faces[5].edges[i] = edges[i+4];
faces[5].vertices[i] = &vertices[i+4];
faces[5].edges[i] = &edges[i+4];
}
faces[5].id=5;
faces[5].id =5;
vertex_faces.resize(0);
normal_faces.resize(0);
@ -177,39 +200,61 @@ struct Scene_edit_box_item_priv{
{
for(short j=0; j<4; ++j)
{
faces[i].vertices[j].face_ = &faces[i];
faces[i].edges[j].face_ = &faces[i];
faces[i].vertices[j]->face_ = &faces[i];
faces[i].edges[j]->face_ = &faces[i];
}
}
pick_sphere_program.addShaderFromSourceFile(QOpenGLShader::Vertex,":/cgal/Polyhedron_3/resources/shader_spheres.v");
pick_sphere_program.addShaderFromSourceFile(QOpenGLShader::Fragment,":/cgal/Polyhedron_3/resources/shader_without_light.f");
pick_sphere_program.bindAttributeLocation("colors", 1);
pick_sphere_program.link();
}
mutable std::vector<float> vertex_edges;
mutable std::vector<float> color_edges;
mutable std::vector<float> vertex_spheres;
mutable std::vector<float> normal_spheres;
mutable std::vector<float> center_spheres;
mutable std::vector<float> color_spheres;
mutable std::vector<float> vertex_arrow;
mutable std::vector<float> normal_arrow;
mutable std::vector<float> vertex_faces;
mutable std::vector<float> normal_faces;
mutable std::vector<float> color_faces;
double pool[6];
qglviewer::ManipulatedFrame* frame;
qglviewer::ManipulatedFrame* remodel_frame;
qglviewer::Vec rf_last_pos;
qglviewer::LocalConstraint constraint;
qglviewer::Vec center_;
mutable QOpenGLShaderProgram pick_sphere_program;
mutable Scene_edit_box_item::vertex vertices[8];
mutable Scene_edit_box_item::edge edges[12];
mutable Scene_edit_box_item::face faces[6];
mutable QOpenGLShaderProgram *program;
void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const;
Scene_edit_box_item::vertex* selected_vertex;
Scene_edit_box_item::edge* selected_edge;
Scene_edit_box_item::face* selected_face;
void reset_selection();
bool selection_on;
mutable QOpenGLShaderProgram* program;
void initializeBuffers(Viewer_interface *viewer)const;
void computeElements() const;
const CGAL::Three::Scene_interface* scene;
void draw_picking(Viewer_interface*);
void remodel_box(const QVector3D &dir);
const Scene_interface* scene;
Scene_edit_box_item* item;
};
Scene_edit_box_item::Scene_edit_box_item(const CGAL::Three::Scene_interface *scene_interface)
Scene_edit_box_item::Scene_edit_box_item(const Scene_interface *scene_interface)
: Scene_item(NumberOfVbos,NumberOfVaos)
{
@ -222,7 +267,7 @@ QString Scene_edit_box_item::toolTip() const {
return QString();
}
void Scene_edit_box_item::draw(CGAL::Three::Viewer_interface *viewer) const
void Scene_edit_box_item::draw(Viewer_interface *viewer) const
{
if (!are_buffers_filled)
{
@ -238,7 +283,7 @@ void Scene_edit_box_item::draw(CGAL::Three::Viewer_interface *viewer) const
viewer->camera()->getModelViewProjectionMatrix(d_mat);
for (int i=0; i<16; ++i)
mvp_mat.data()[i] = GLfloat(d_mat[i]);
mvp_mat = mvp_mat*f_matrix;
mvp_mat = mvp_mat*f_matrix;
QMatrix4x4 mv_mat;
viewer->camera()->getModelViewMatrix(d_mat);
for (int i=0; i<16; ++i)
@ -274,7 +319,7 @@ void Scene_edit_box_item::draw(CGAL::Three::Viewer_interface *viewer) const
vaos[Scene_edit_box_item_priv::Spheres]->release();
}
void Scene_edit_box_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const
void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const
{
if(!are_buffers_filled)
{
@ -342,23 +387,23 @@ void Scene_edit_box_item::compute_bbox() const
}
double xmin,ymin,zmin,xmax,ymax,zmax;
xmin =d->vertices[0].position.x();
ymin =d->vertices[0].position.y();
zmin =d->vertices[0].position.z();
xmax =d->vertices[6].position.x();
ymax =d->vertices[6].position.y();
zmax =d->vertices[6].position.z();
xmin =d->vertices[0].position().x();
ymin =d->vertices[0].position().y();
zmin =d->vertices[0].position().z();
xmax =d->vertices[6].position().x();
ymax =d->vertices[6].position().y();
zmax =d->vertices[6].position().z();
QVector3D min(xmin, ymin, zmin);
QVector3D max(xmax, ymax, zmax);
min = f_matrix*min;
max = f_matrix*max;
CGAL::Three::Scene_item::Bbox bb(min.x(),min.y(),min.z(),max.x(),max.y(),max.z());
Scene_item::Bbox bb(min.x(),min.y(),min.z(),max.x(),max.y(),max.z());
_bbox = bb;
}
void
Scene_edit_box_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewer)const
Scene_edit_box_item_priv::initializeBuffers(Viewer_interface *viewer)const
{
//vao containing the data for the lines
@ -373,8 +418,20 @@ Scene_edit_box_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewe
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
item->buffers[VertexEdges].release();
item->vaos[Edges]->release();
item->vaos[P_Edges]->bind();
item->buffers[VertexEdges].bind();
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
item->buffers[VertexEdges].release();
item->buffers[ColorsEdges].bind();
item->buffers[ColorsEdges].allocate(color_edges.data(),
static_cast<GLsizei>(color_edges.size()*sizeof(float)));
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors",GL_FLOAT,0,3);
item->buffers[ColorsEdges].release();
item->vaos[P_Edges]->release();
program->release();
}
@ -400,18 +457,52 @@ Scene_edit_box_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewe
program->setAttributeBuffer("normals", GL_FLOAT, 0, 3);
item->buffers[NormalSpheres].release();
item->buffers[VertexEdges].bind();
item->buffers[CenterSpheres].bind();
program->enableAttributeArray("center");
program->setAttributeBuffer("center", GL_FLOAT, 0, 3, 3*sizeof(float));
item->buffers[CenterSpheres].allocate(center_spheres.data(),
static_cast<int>(center_spheres.size()*sizeof(float)));
program->setAttributeBuffer("center", GL_FLOAT, 0, 3);
item->buffers[VertexEdges].release();
program->disableAttributeArray("radius");
program->setAttributeValue("radius",1);
program->disableAttributeArray("color");
program->disableAttributeArray("colors");
viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1);
item->vaos[Spheres]->release();
program->release();
pick_sphere_program.bind();
pick_sphere_program.bind();
item->vaos[P_Spheres]->bind();
item->buffers[VertexSpheres].bind();
pick_sphere_program.enableAttributeArray("vertex");
pick_sphere_program.setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
item->buffers[VertexSpheres].release();
item->buffers[NormalSpheres].bind();
pick_sphere_program.disableAttributeArray("normals");
pick_sphere_program.setAttributeValue("normals",QVector3D(0,0,0));
item->buffers[NormalSpheres].release();
item->buffers[CenterSpheres].bind();
pick_sphere_program.enableAttributeArray("center");
pick_sphere_program.setAttributeBuffer("center", GL_FLOAT, 0, 3);
item->buffers[CenterSpheres].release();
pick_sphere_program.disableAttributeArray("radius");
pick_sphere_program.setAttributeValue("radius",1);
item->buffers[ColorsSpheres].bind();
item->buffers[ColorsSpheres].allocate(color_spheres.data(),
static_cast<int>(color_spheres.size()*sizeof(float)));
pick_sphere_program.enableAttributeArray("colors");
pick_sphere_program.setAttributeBuffer("colors", GL_FLOAT, 0, 3);
item->buffers[ColorsSpheres].release();
viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1);
viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1);
item->vaos[P_Spheres]->release();
pick_sphere_program.release();
}
//vao containing the data for the faces
@ -435,7 +526,26 @@ Scene_edit_box_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewe
program->setAttributeBuffer("normals", GL_FLOAT, 0, 3);
item->buffers[NormalFaces].release();
item->vaos[Faces]->release();
program->release();
program = item->getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer);
item->attribBuffers(viewer, Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT);
program->bind();
item->vaos[P_Faces]->bind();
item->buffers[VertexFaces].bind();
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
item->buffers[VertexFaces].release();
item->buffers[ColorsFaces].bind();
item->buffers[ColorsFaces].allocate(color_faces.data(),
static_cast<int>(color_faces.size()*sizeof(float)));
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors", GL_FLOAT, 0, 3);
item->buffers[ColorsFaces].release();
item->vaos[P_Faces]->release();
program->release();
}
item->are_buffers_filled = true;
@ -492,54 +602,89 @@ void Scene_edit_box_item_priv::computeElements() const
vertex_edges.clear();
vertex_faces.clear();
normal_faces.clear();
center_spheres.clear();
color_edges.clear();
color_faces.clear();
color_spheres.clear();
//edges
for(short i=0; i<12; ++i)
{
if(i<4)
{
vertex_edges.push_back(vertices[i].position.x()-center_.x);
vertex_edges.push_back(vertices[i].position.y()-center_.y);
vertex_edges.push_back(vertices[i].position.z()-center_.z);
vertex_edges.push_back(vertices[i].position().x()-center_.x);
vertex_edges.push_back(vertices[i].position().y()-center_.y);
vertex_edges.push_back(vertices[i].position().z()-center_.z);
center_spheres.push_back(vertices[i].position().x()-center_.x);
center_spheres.push_back(vertices[i].position().y()-center_.y);
center_spheres.push_back(vertices[i].position().z()-center_.z);
vertex_edges.push_back(vertices[i+4].position().x()-center_.x);
vertex_edges.push_back(vertices[i+4].position().y()-center_.y);
vertex_edges.push_back(vertices[i+4].position().z()-center_.z);
vertex_edges.push_back(vertices[i+4].position.x()-center_.x);
vertex_edges.push_back(vertices[i+4].position.y()-center_.y);
vertex_edges.push_back(vertices[i+4].position.z()-center_.z);
}
else if(i<8)
{
vertex_edges.push_back(vertices[i].position.x()-center_.x);
vertex_edges.push_back(vertices[i].position.y()-center_.y);
vertex_edges.push_back(vertices[i].position.z()-center_.z);
vertex_edges.push_back(vertices[i].position().x()-center_.x);
vertex_edges.push_back(vertices[i].position().y()-center_.y);
vertex_edges.push_back(vertices[i].position().z()-center_.z);
vertex_edges.push_back(vertices[(i+1)%4 +4].position.x()-center_.x);
vertex_edges.push_back(vertices[(i+1)%4 +4].position.y()-center_.y);
vertex_edges.push_back(vertices[(i+1)%4 +4].position.z()-center_.z);
center_spheres.push_back(vertices[i].position().x()-center_.x);
center_spheres.push_back(vertices[i].position().y()-center_.y);
center_spheres.push_back(vertices[i].position().z()-center_.z);
vertex_edges.push_back(vertices[(i+1)%4 +4].position().x()-center_.x);
vertex_edges.push_back(vertices[(i+1)%4 +4].position().y()-center_.y);
vertex_edges.push_back(vertices[(i+1)%4 +4].position().z()-center_.z);
}
else
{
vertex_edges.push_back(vertices[i%4].position.x()-center_.x);
vertex_edges.push_back(vertices[i%4].position.y()-center_.y);
vertex_edges.push_back(vertices[i%4].position.z()-center_.z);
vertex_edges.push_back(vertices[i%4].position().x()-center_.x);
vertex_edges.push_back(vertices[i%4].position().y()-center_.y);
vertex_edges.push_back(vertices[i%4].position().z()-center_.z);
vertex_edges.push_back(vertices[(i+1) %4].position.x()-center_.x);
vertex_edges.push_back(vertices[(i+1) %4].position.y()-center_.y);
vertex_edges.push_back(vertices[(i+1) %4].position.z()-center_.z);
vertex_edges.push_back(vertices[(i+1) %4].position().x()-center_.x);
vertex_edges.push_back(vertices[(i+1) %4].position().y()-center_.y);
vertex_edges.push_back(vertices[(i+1) %4].position().z()-center_.z);
}
color_edges.push_back(0);
color_edges.push_back((20.0*i+10)/255);
color_edges.push_back(0);
color_edges.push_back(0);
color_edges.push_back((20.0*i+10)/255);
color_edges.push_back(0);
}
//faces
for(short i=0; i<6; ++i)
{
push_xyz(vertex_faces, faces[i].vertices[0].position, center_);
push_xyz(vertex_faces, faces[i].vertices[3].position, center_);
push_xyz(vertex_faces, faces[i].vertices[2].position, center_);
push_xyz(vertex_faces, faces[i].vertices[0]->position(), center_);
push_xyz(vertex_faces, faces[i].vertices[3]->position(), center_);
push_xyz(vertex_faces, faces[i].vertices[2]->position(), center_);
push_xyz(vertex_faces, faces[i].vertices[0].position, center_);
push_xyz(vertex_faces, faces[i].vertices[2].position, center_);
push_xyz(vertex_faces, faces[i].vertices[1].position, center_);
push_xyz(vertex_faces, faces[i].vertices[0]->position(), center_);
push_xyz(vertex_faces, faces[i].vertices[2]->position(), center_);
push_xyz(vertex_faces, faces[i].vertices[1]->position(), center_);
for(short j=0; j<6; ++j)
{
push_normal(normal_faces, i);
color_faces.push_back(0);
color_faces.push_back(0);
color_faces.push_back((20.0*i+10)/255);
}
}
//spheres
for(short i=0; i<8; ++i)
{
color_spheres.push_back((20.0*i+10)/255);
color_spheres.push_back(0);
color_spheres.push_back(0);
}
QApplication::restoreOverrideCursor();
@ -562,17 +707,259 @@ bool Scene_edit_box_item::supportsRenderingMode(RenderingMode m) const {
}
}
CGAL::Three::Scene_item::ManipulatedFrame*
Scene_edit_box_item::manipulatedFrame() { return d->frame; }
Scene_item::ManipulatedFrame*
Scene_edit_box_item::manipulatedFrame()
{
return d->selection_on? d->remodel_frame :d->frame;
}
double Scene_edit_box_item::point(short i, short j) const
{
QVector3D pos(d->vertices[i].position.x()-d->center_.x,
d->vertices[i].position.y()-d->center_.y,
d->vertices[i].position.z()-d->center_.z);
QVector3D pos(d->vertices[i].position().x()-d->center_.x,
d->vertices[i].position().y()-d->center_.y,
d->vertices[i].position().z()-d->center_.z);
QMatrix4x4 f_matrix;
for (int k=0; k<16; ++k){
f_matrix.data()[k] = (float)d->frame->matrix()[k];
}
return (f_matrix*pos)[j];
}
void Scene_edit_box_item::highlight()
{
/* if(is_ready_to_highlight)
{
// highlight with mouse move event
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
qglviewer::Camera* camera = viewer->camera();
bool found = false;
const qglviewer::Vec& point = camera->pointUnderPixel(hl_pos, found);
if(found)
{
const qglviewer::Vec& orig = camera->position();
const qglviewer::Vec& dir = point - orig;
is_highlighting = true;
is_highlighting = false;
}
else
{
Q_EMIT clearHL();
}
is_ready_to_highlight = false;
}*/
}
void Scene_edit_box_item_priv::reset_selection()
{
selection_on = false;
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
viewer->setManipulatedFrame(frame);
viewer->setMouseBinding(Qt::ShiftModifier, Qt::LeftButton, QGLViewer::SELECT);
selected_vertex= NULL;
selected_edge= NULL;
selected_face= NULL;
}
//intercept events for picking
bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event)
{
if(event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* e = static_cast<QMouseEvent*>(event);
if(e->modifiers() == Qt::ShiftModifier)
{
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
int deviceWidth = viewer->camera()->screenWidth();
int deviceHeight = viewer->camera()->screenHeight();
QOpenGLFramebufferObject* fbo = new QOpenGLFramebufferObject(deviceWidth, deviceHeight,QOpenGLFramebufferObject::Depth);
fbo->bind();
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QColor bgColor(viewer->backgroundColor());
//draws the image in the fbo
viewer->setBackgroundColor(::Qt::white);
Viewer_interface* v_i = dynamic_cast<Viewer_interface*>(viewer);
//draw_picking
d->draw_picking(v_i);
int rowLength = deviceWidth * 4; // data asked in RGBA,so 4 bytes.
const static int dataLength = rowLength * deviceHeight;
GLubyte* buffer = new GLubyte[dataLength];
// Qt uses upper corner for its origin while GL uses the lower corner.
glReadPixels(e->pos().x(), deviceHeight-1-e->pos().y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
//decode ID and pick (don't forget the case nothing is picked
if(!(buffer[0]==buffer[1] && buffer[1]==buffer[2]))
{
d->selection_on = true;
d->remodel_frame->setPosition(d->center_);
d->rf_last_pos = d->center_;
int r(std::ceil((buffer[0]-10)/20)), g(std::ceil((buffer[1]-10)/20)), b(std::ceil((buffer[2]-10)/20));
int picked = (std::max)(r,g);
picked = (std::max)(picked,b);
if(buffer[0] > 0)
{
if(picked <8)
{
d->selected_vertex = &d->vertices[picked];
d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE);
d->remodel_frame->setConstraint(&d->constraint);
}
}
else if(buffer[1] > 0)
{
if(picked <12)
{
d->selected_edge = &d->edges[picked];
Kernel::Point_3 s(d->selected_edge->source->position()), t(d->selected_edge->target->position());
qglviewer::Vec normal(t.x()-s.x(), t.y()-s.y(), t.z()-s.z());
d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::PLANE);
d->constraint.setTranslationConstraintDirection(normal);
d->remodel_frame->setConstraint(&d->constraint);
}
}
else if(buffer[2] > 0)
{
if(picked <6)
{
d->selected_face= &d->faces[picked];
Kernel::Point_3 a1(d->selected_face->vertices[1]->position()), a0(d->selected_face->vertices[0]->position())
,a3(d->selected_face->vertices[3]->position());
QVector3D a(a1.x()-a0.x(), a1.y()-a0.y(),a1.z()-a0.z()),b(a3.x()-a0.x(), a3.y()-a0.y(),a3.z()-a0.z());
QVector3D n = QVector3D::crossProduct(a.normalized(),b.normalized()).normalized();
d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::AXIS);
d->constraint.setTranslationConstraintDirection(qglviewer::Vec(n.x(), n.y(), n.z()));
d->remodel_frame->setConstraint(&d->constraint);
}
}
viewer->setBackgroundColor(bgColor);
fbo->release();
viewer->setManipulatedFrame(d->remodel_frame);
viewer->setMouseBinding(
Qt::ShiftModifier,
Qt::LeftButton,
QGLViewer::FRAME,
QGLViewer::TRANSLATE);
}
else
{
d->reset_selection();
}
delete fbo;
}
return false;
}
else if(event->type() == QEvent::MouseMove)
{
QMouseEvent* e = static_cast<QMouseEvent*>(event);
if(e->modifiers() == Qt::ShiftModifier)
{
if(d->selection_on)
{
QVector3D dir(d->remodel_frame->position().x - d->rf_last_pos.x,
d->remodel_frame->position().y - d->rf_last_pos.y,
d->remodel_frame->position().z - d->rf_last_pos.z);
d->rf_last_pos = d->remodel_frame->position();
d->remodel_box(dir);
return false;
}
}
else if(d->selection_on)
{
d->reset_selection();
}
}
else if(event->type() == QEvent::MouseButtonRelease)
{
d->reset_selection();
}
return false;
}
void Scene_edit_box_item_priv::draw_picking(Viewer_interface* viewer)
{
QMatrix4x4 f_matrix;
for (int i=0; i<16; ++i){
f_matrix.data()[i] = (float)frame->matrix()[i];
}
GLdouble d_mat[16];
QMatrix4x4 mvp_mat;
viewer->camera()->getModelViewProjectionMatrix(d_mat);
for (int i=0; i<16; ++i)
mvp_mat.data()[i] = GLfloat(d_mat[i]);
mvp_mat = mvp_mat*f_matrix;
QMatrix4x4 mv_mat;
viewer->camera()->getModelViewMatrix(d_mat);
for (int i=0; i<16; ++i)
mv_mat.data()[i] = GLfloat(d_mat[i]);
mv_mat = mv_mat*f_matrix;
QVector4D light_pos(0.0f,0.0f,1.0f, 1.0f );
light_pos = light_pos*f_matrix;
if(item->renderingMode() == FlatPlusEdges)
{
item->vaos[P_Faces]->bind();
program = item->getShaderProgram(Scene_item::PROGRAM_WITHOUT_LIGHT, viewer);
item->attribBuffers(viewer, Scene_item::PROGRAM_WITHOUT_LIGHT);
program->bind();
program->setUniformValue("mvp_matrix", mvp_mat);
viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertex_faces.size()/3));
item->vaos[P_Faces]->release();
program->release();
}
item->vaos[P_Spheres]->bind();
pick_sphere_program.bind();
pick_sphere_program.setUniformValue("mvp_matrix", mvp_mat);
viewer->glDrawArraysInstanced(GL_TRIANGLES, 0,
static_cast<GLsizei>(vertex_spheres.size()/3),
static_cast<GLsizei>(8));
pick_sphere_program.release();
item->vaos[P_Spheres]->release();
item->vaos[P_Edges]->bind();
viewer->glLineWidth(4.0f);
program = item->getShaderProgram(Scene_item::PROGRAM_WITHOUT_LIGHT);
item->attribBuffers(viewer, Scene_item::PROGRAM_WITHOUT_LIGHT);
program->bind();
program->setUniformValue("f_matrix", f_matrix);
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(vertex_edges.size()/3));
viewer->glLineWidth(1.0f);
item->vaos[P_Edges]->release();
program->release();
}
//!\todo redo the API to only use a list of selected vertices
void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir)
{
if(selected_vertex != NULL)
{
*selected_vertex->x += dir.x();
*selected_vertex->y += dir.y();
*selected_vertex->z += dir.z();
item->invalidateOpenGLBuffers();
}
else if(selected_edge != NULL)
{
*selected_edge->source->x += dir.x();
*selected_edge->source->y += dir.y();
*selected_edge->source->z += dir.z();
*selected_edge->target->x += dir.x();
*selected_edge->target->y += dir.y();
*selected_edge->target->z += dir.z();
item->invalidateOpenGLBuffers();
}
else if(selected_face != NULL)
{
for(short i=0; i<4; ++i)
{
*selected_face->vertices[i]->x += dir.x();
*selected_face->vertices[i]->y += dir.y();
*selected_face->vertices[i]->z += dir.z();
}
item->invalidateOpenGLBuffers();
}
}

View File

@ -16,18 +16,26 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item
enum VAOs{
Edges = 0,
Spheres,
Faces,
S_Edges,
S_Spheres,
S_Faces,
Arrow,
Faces,
P_Edges,
P_Spheres,
P_Faces,
NumberOfVaos
};
enum VBOs{
VertexEdges = 0,
ColorsEdges,
VertexSpheres,
NormalSpheres,
CenterSpheres,
ColorsSpheres,
VertexFaces,
NormalFaces,
ColorsFaces,
VertexArrow,
NormalArrow,
NumberOfVbos
@ -46,6 +54,7 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item
QString toolTip() const;
bool eventFilter(QObject *, QEvent *);
// Indicate if rendering mode is supported
bool supportsRenderingMode(RenderingMode m) const;
void draw(CGAL::Three::Viewer_interface *) const;
@ -56,6 +65,9 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item
are_buffers_filled = false;
}
double point(short i, short j) const;
public Q_SLOTS:
void highlight();
protected:
friend struct Scene_edit_box_item_priv;
Scene_edit_box_item_priv* d;