mirror of https://github.com/CGAL/cgal
WIP editable box
This commit is contained in:
parent
50b93ce2dc
commit
71feaa34be
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue