From 523bfbd091ec4f1ed0fab08905748bbd1e68fac1 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 18 Oct 2016 12:50:24 +0200 Subject: [PATCH 01/13] Add the new item. --- Polyhedron/demo/Polyhedron/CMakeLists.txt | 1 + .../Polyhedron/Plugins/PCA/CMakeLists.txt | 3 +- .../Plugins/PCA/Scene_edit_box_item.cpp | 225 ++++++++++++++++++ .../Plugins/PCA/Scene_edit_box_item.h | 61 +++++ .../Polyhedron/Plugins/PCA/Trivial_plugin.cpp | 205 ---------------- 5 files changed, 289 insertions(+), 206 deletions(-) create mode 100644 Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp create mode 100644 Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h delete mode 100644 Polyhedron/demo/Polyhedron/Plugins/PCA/Trivial_plugin.cpp diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index fe1e5c382cb..9de2c9b786d 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -221,6 +221,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) target_link_libraries(scene_c3t3_item scene_polyhedron_item scene_polygon_soup_item scene_basic_objects ${TBB_LIBRARIES}) add_item(scene_polyhedron_item Scene_polyhedron_item.cpp) add_item(scene_polyhedron_transform_item Plugins/PCA/Scene_polyhedron_transform_item.cpp ) + add_item(scene_edit_box_item Plugins/PCA/Scene_edit_box_item.cpp ) add_item(scene_image_item Scene_image_item.cpp) # special diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt index 5453f0435ad..82df86e4cf4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt @@ -5,7 +5,8 @@ target_link_libraries(pca_plugin scene_polyhedron_item scene_basic_objects) polyhedron_demo_plugin(affine_transform_plugin Affine_transform_plugin) target_link_libraries(affine_transform_plugin scene_polyhedron_item scene_polyhedron_transform_item scene_points_with_normal_item) -polyhedron_demo_plugin(trivial_plugin Trivial_plugin) +polyhedron_demo_plugin(edit_box_plugin Edit_box_plugin) +target_link_libraries(edit_box_plugin scene_edit_box_item) polyhedron_demo_plugin(create_bbox_mesh_plugin Create_bbox_mesh_plugin) target_link_libraries(create_bbox_mesh_plugin scene_polyhedron_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp new file mode 100644 index 00000000000..77a0ae8035f --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -0,0 +1,225 @@ +#include "Scene_edit_box_item.h" +#include +#include + +struct Scene_edit_box_item::vertex{ + short id; + CGAL::Point_3 position; + // face& face_; +}; +struct Scene_edit_box_item::edge{ + short id; + vertex source; + vertex target; + //face& face_; +}; +struct Scene_edit_box_item::triangle{ + short id; + vertex vertices[3]; + //face& face_; +}; +struct Scene_edit_box_item::face{ + short id; + triangle triangles[2]; + edge edges[4]; + vertex vertices[4]; +}; + +struct Scene_edit_box_item_priv{ + typedef CGAL::Simple_cartesian Kernel; + enum VAOs{ + Edges = 0, + Spheres, + S_Edges, + S_Spheres, + Arrow, + NumberOfVaos + }; + enum VBOs{ + VertexEdges = 0, + VertexSpheres, + NormalSpheres, + VertexArrow, + NormalArrow, + NumberOfVbos + }; + + Scene_edit_box_item_priv(const CGAL::Three::Scene_interface *scene_interface, Scene_edit_box_item* ebi) + { + scene = scene_interface; + item = ebi; + // 5-----6 + // . | . | + // 4------7 | + // | | | | + // | 1-|---2 + // | . |. + // 0------3 + + //vertices + for(short i = 0; i< 8; ++i) + { + double x,y,z; + x = ((i/2)%2)? scene->bbox().min(0):scene->bbox().max(0); + y = (i/4)? scene->bbox().min(1):scene->bbox().max(1); + z = (((i+1)/2)%2)? scene->bbox().min(2):scene->bbox().max(2); + vertices[i].position = Kernel::Point_3(x,y,z); + vertices[i].id = i; + } + + // .--5--. + // 4 | 6 | + // .--7-1-. 2 + // | | | | + // 0 .-39--. + // | 8 |10 + // .--11--. + //edges + for(short i=0; i<12; ++i) + { + edges[i].id = i; + if(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]; + } + else + { + edges[i].source = vertices[i%4]; + edges[i].target = vertices[(i+1) %4]; + } + + vertex_edges.resize(0); + } + + + mutable std::vector vertex_edges; + mutable std::vector vertex_spheres; + mutable std::vector normal_spheres; + mutable std::vector vertex_arrow; + mutable std::vector normal_arrow; + + mutable Scene_edit_box_item::vertex vertices[8]; + mutable Scene_edit_box_item::edge edges[12]; + mutable Scene_edit_box_item::triangle triangles[12]; + mutable Scene_edit_box_item::face faces[6]; + + mutable QOpenGLShaderProgram *program; + void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const; + + void computeElements() const; + + const CGAL::Three::Scene_interface* scene; + Scene_edit_box_item* item; + }; + + + Scene_edit_box_item::Scene_edit_box_item(const CGAL::Three::Scene_interface *scene_interface) + : Scene_item(NumberOfVbos,NumberOfVaos) + + { + d = new Scene_edit_box_item_priv(scene_interface, this); + + are_buffers_filled = false; + } + QString Scene_edit_box_item::toolTip() const { + + return QString(); + } + + void Scene_edit_box_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const + { + if(!are_buffers_filled) + { + d->computeElements(); + d->initializeBuffers(viewer); + } + vaos[Edges]->bind(); + d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); + attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); + d->program->bind(); + d->program->setAttributeValue("colors", this->color()); + viewer->glDrawArrays(GL_LINES, 0, static_cast(d->vertex_edges.size()/3)); + vaos[Edges]->release(); + d->program->release(); + + } + + void Scene_edit_box_item::compute_bbox() const + { + + } + + + void Scene_edit_box_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewer)const + { + + //vao containing the data for the lines + { + program = item->getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer); + program->bind(); + + item->vaos[Edges]->bind(); + item->buffers[VertexEdges].bind(); + item->buffers[VertexEdges].allocate(vertex_edges.data(), + static_cast(vertex_edges.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + item->buffers[VertexEdges].release(); + + item->vaos[Edges]->release(); + program->release(); + + } + item->are_buffers_filled = true; + } + + void Scene_edit_box_item_priv::computeElements() const + { + QApplication::setOverrideCursor(Qt::WaitCursor); + //edges + for(short i=0; i<12; ++i) + { + if(i<4) + { + vertex_edges.push_back(vertices[i].position.x()); + vertex_edges.push_back(vertices[i].position.y()); + vertex_edges.push_back(vertices[i].position.z()); + + vertex_edges.push_back(vertices[i+4].position.x()); + vertex_edges.push_back(vertices[i+4].position.y()); + vertex_edges.push_back(vertices[i+4].position.z()); + } + else if(i<8) + { + vertex_edges.push_back(vertices[i].position.x()); + vertex_edges.push_back(vertices[i].position.y()); + vertex_edges.push_back(vertices[i].position.z()); + + vertex_edges.push_back(vertices[(i+1)%4 +4].position.x()); + vertex_edges.push_back(vertices[(i+1)%4 +4].position.y()); + vertex_edges.push_back(vertices[(i+1)%4 +4].position.z()); + } + else + { + vertex_edges.push_back(vertices[i%4].position.x()); + vertex_edges.push_back(vertices[i%4].position.y()); + vertex_edges.push_back(vertices[i%4].position.z()); + + vertex_edges.push_back(vertices[(i+1) %4].position.x()); + vertex_edges.push_back(vertices[(i+1) %4].position.y()); + vertex_edges.push_back(vertices[(i+1) %4].position.z()); + } + } + QApplication::restoreOverrideCursor(); + } + + Scene_edit_box_item::~Scene_edit_box_item() + { + delete d; + } diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h new file mode 100644 index 00000000000..54244ff1803 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -0,0 +1,61 @@ +#ifndef SCENE_EDIT_BOX_ITEM_H +#define SCENE_EDIT_BOX_ITEM_H + +#include +#include +#include "create_sphere.h" +struct Scene_edit_box_item_priv; +class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item +{ + Q_OBJECT + public: + typedef CGAL::Simple_cartesian Kernel; + struct vertex; + struct edge; + struct triangle; + struct face; + enum VAOs{ + Edges = 0, + Spheres, + S_Edges, + S_Spheres, + Arrow, + NumberOfVaos + }; + enum VBOs{ + VertexEdges = 0, + VertexSpheres, + NormalSpheres, + VertexArrow, + NormalArrow, + NumberOfVbos + }; + Scene_edit_box_item(const CGAL::Three::Scene_interface* scene_interface); + ~Scene_edit_box_item(); + bool isFinite() const { return true; } + bool isEmpty() const { return true; } + void compute_bbox() const; + + Scene_edit_box_item* clone() const { + return 0; + } + + QString toolTip() const; + + // Indicate if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const { + return (m == Wireframe); + } + + void drawEdges(CGAL::Three::Viewer_interface* viewer) const; + void invalidateOpenGLBuffers() + { + compute_bbox(); + are_buffers_filled = false; + } + +protected: + friend struct Scene_edit_box_item_priv; + Scene_edit_box_item_priv* d; +}; +#endif // SCENE_EDIT_BOX_ITEM_H diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Trivial_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Trivial_plugin.cpp deleted file mode 100644 index a169632447a..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Trivial_plugin.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include - -#include -#include -#include - -#include -#include -#include -#include - -class Q_DECL_EXPORT Scene_bbox_item : public CGAL::Three::Scene_item -{ - Q_OBJECT -public: - Scene_bbox_item(const CGAL::Three::Scene_interface* scene_interface) - : Scene_item(1,1), scene(scene_interface) - - { - positions_lines.resize(0); - are_buffers_filled = false; - } - ~Scene_bbox_item() - { - } - bool isFinite() const { return true; } - bool isEmpty() const { return true; } - void compute_bbox() const { _bbox = scene->bbox(); } - - Scene_bbox_item* clone() const { - return 0; - } - - QString toolTip() const { - const Bbox& bb = scene->bbox(); - return QString("

Scene bounding box

" - "

x range: (%1, %2)
" - "y range: (%3, %4)
" - "z range: (%5, %6)

") - .arg(bb.xmin()).arg(bb.xmax()) - .arg(bb.ymin()).arg(bb.ymax()) - .arg(bb.zmin()).arg(bb.zmax()); - } - - // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const { - return (m == Wireframe); - } - - void drawEdges(CGAL::Three::Viewer_interface* viewer) const - { - if(!are_buffers_filled) - { - computeElements(); - initializeBuffers(viewer); - } - vaos[0]->bind(); - program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); - attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); - program->bind(); - program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_LINES, 0, static_cast(positions_lines.size()/3)); - vaos[0]->release(); - program->release(); - - } - - void invalidateOpenGLBuffers() - { - compute_bbox(); - are_buffers_filled = false; - } - -private: - - mutable std::vector positions_lines; - mutable QOpenGLShaderProgram *program; - using CGAL::Three::Scene_item::initializeBuffers; - void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const - { - - //vao containing the data for the lines - { - program = getShaderProgram(PROGRAM_WITHOUT_LIGHT, viewer); - program->bind(); - - vaos[0]->bind(); - buffers[0].bind(); - buffers[0].allocate(positions_lines.data(), - static_cast(positions_lines.size()*sizeof(float))); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[0].release(); - - vaos[0]->release(); - program->release(); - - } - are_buffers_filled = true; - } - - void computeElements() const - { - QApplication::setOverrideCursor(Qt::WaitCursor); - positions_lines.clear(); - const Bbox& bb = scene->bbox(); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmax()); - - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmax()); - - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmin()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmax()); - - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmax()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmax()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmax()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmax()); - - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmax()); - positions_lines.push_back(bb.xmin()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmax()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmax()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymin()); positions_lines.push_back(bb.zmax()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmax()); - positions_lines.push_back(bb.xmax()); positions_lines.push_back(bb.ymax()); positions_lines.push_back(bb.zmin()); - QApplication::restoreOverrideCursor(); - } - - const CGAL::Three::Scene_interface* scene; -}; - -#include -using namespace CGAL::Three; -class Polyhedron_demo_trivial_plugin : - public QObject, - public Polyhedron_demo_plugin_interface -{ - Q_OBJECT - 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*); - QList actions() const { - return QList() << actionBbox; - } - - bool applicable(QAction*) const { - if(scene->numberOfEntries() > 0) - return true; - return false;} -public Q_SLOTS: - - void bbox(); - void enableAction(); - -private: - CGAL::Three::Scene_interface* scene; - QAction* actionBbox; - - -}; // end Polyhedron_demo_trivial_plugin - -void Polyhedron_demo_trivial_plugin::init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) -{ - scene = scene_interface; - actionBbox = new QAction(tr("Create Bbox"), mainWindow); - connect(actionBbox, SIGNAL(triggered()), - this, SLOT(bbox())); -} - -void Polyhedron_demo_trivial_plugin::bbox() -{ - for(int i = 0, end = scene->numberOfEntries(); - i < end; ++i) - { - if(qobject_cast(scene->item(i))) - return; - } - QApplication::setOverrideCursor(Qt::WaitCursor); - Scene_item* item = new Scene_bbox_item(scene); - connect(item, SIGNAL(destroyed()), - this, SLOT(enableAction())); - item->setName("Scene bbox"); - item->setColor(Qt::black); - item->setRenderingMode(Wireframe); - scene->addItem(item); - actionBbox->setEnabled(false); - QApplication::restoreOverrideCursor(); -} - -void Polyhedron_demo_trivial_plugin::enableAction() { - actionBbox->setEnabled(true); -} - -#include "Trivial_plugin.moc" From 50b93ce2dc1fddde29722499376ae58b1df04cf8 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 19 Oct 2016 16:17:51 +0200 Subject: [PATCH 02/13] Add the visualization and the export to polyhedorn features --- .../Polyhedron/Plugins/PCA/CMakeLists.txt | 2 +- .../Plugins/PCA/Scene_edit_box_item.cpp | 563 ++++++++++++++---- .../Plugins/PCA/Scene_edit_box_item.h | 14 +- 3 files changed, 467 insertions(+), 112 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt index 82df86e4cf4..090ccf0a884 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt @@ -6,7 +6,7 @@ polyhedron_demo_plugin(affine_transform_plugin Affine_transform_plugin) target_link_libraries(affine_transform_plugin scene_polyhedron_item scene_polyhedron_transform_item scene_points_with_normal_item) polyhedron_demo_plugin(edit_box_plugin Edit_box_plugin) -target_link_libraries(edit_box_plugin scene_edit_box_item) +target_link_libraries(edit_box_plugin scene_edit_box_item scene_polyhedron_item) polyhedron_demo_plugin(create_bbox_mesh_plugin Create_bbox_mesh_plugin) target_link_libraries(create_bbox_mesh_plugin scene_polyhedron_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 77a0ae8035f..5c1f2f11c29 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -1,26 +1,21 @@ #include "Scene_edit_box_item.h" #include #include +#include struct Scene_edit_box_item::vertex{ short id; CGAL::Point_3 position; - // face& face_; + face* face_; }; struct Scene_edit_box_item::edge{ short id; vertex source; vertex target; - //face& face_; -}; -struct Scene_edit_box_item::triangle{ - short id; - vertex vertices[3]; - //face& face_; + face* face_; }; struct Scene_edit_box_item::face{ short id; - triangle triangles[2]; edge edges[4]; vertex vertices[4]; }; @@ -33,12 +28,15 @@ struct Scene_edit_box_item_priv{ S_Edges, S_Spheres, Arrow, + Faces, NumberOfVaos }; enum VBOs{ VertexEdges = 0, VertexSpheres, NormalSpheres, + VertexFaces, + NormalFaces, VertexArrow, NormalArrow, NumberOfVbos @@ -48,6 +46,25 @@ struct Scene_edit_box_item_priv{ { scene = scene_interface; item = ebi; + CGAL::Three::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(); + frame->setPosition(center_); + constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); + constraint.setRotationConstraintDirection(qglviewer::Vec(.0,.0,.1)); + frame->setConstraint(&constraint); + //create the sphere model + double sq_diag = + (bb.xmax() - bb.xmin()) * (bb.xmax() - bb.xmin()) + + (bb.ymax() - bb.ymin()) * (bb.ymax() - bb.ymin()) + + (bb.zmax() - bb.zmin()) * (bb.zmax() - bb.zmin()) ; + + vertex_spheres.resize(0); + normal_spheres.resize(0); + create_flat_sphere((float)(0.01*sqrt(sq_diag)), vertex_spheres, normal_spheres,10); // 5-----6 // . | . | // 4------7 | @@ -60,9 +77,9 @@ struct Scene_edit_box_item_priv{ for(short i = 0; i< 8; ++i) { double x,y,z; - x = ((i/2)%2)? scene->bbox().min(0):scene->bbox().max(0); - y = (i/4)? scene->bbox().min(1):scene->bbox().max(1); - z = (((i+1)/2)%2)? scene->bbox().min(2):scene->bbox().max(2); + 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; } @@ -74,6 +91,7 @@ struct Scene_edit_box_item_priv{ // 0 .-39--. // | 8 |10 // .--11--. + //edges for(short i=0; i<12; ++i) { @@ -93,133 +111,468 @@ struct Scene_edit_box_item_priv{ edges[i].source = vertices[i%4]; edges[i].target = vertices[(i+1) %4]; } - vertex_edges.resize(0); } - - mutable std::vector vertex_edges; - mutable std::vector vertex_spheres; - mutable std::vector normal_spheres; - mutable std::vector vertex_arrow; - mutable std::vector normal_arrow; - - mutable Scene_edit_box_item::vertex vertices[8]; - mutable Scene_edit_box_item::edge edges[12]; - mutable Scene_edit_box_item::triangle triangles[12]; - mutable Scene_edit_box_item::face faces[6]; - - mutable QOpenGLShaderProgram *program; - void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const; - - void computeElements() const; - - const CGAL::Three::Scene_interface* scene; - Scene_edit_box_item* item; - }; + // + // 5------6 + // | | + // .-----. | 2 | + // . |5 . | | | + // .------.2 | 5------1------2------6------5 + // | 1 | | | | | | | | + // | 4.-|-3-. | 1 | 0 | 3 | 5 | + // | . 0 |. | | | | | + // .------. 4------0------3------7------4 + // | | + // | 4 | + // | | + // 4------7 - Scene_edit_box_item::Scene_edit_box_item(const CGAL::Three::Scene_interface *scene_interface) - : Scene_item(NumberOfVbos,NumberOfVaos) + //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].id=0; - { - d = new Scene_edit_box_item_priv(scene_interface, this); + 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]; - are_buffers_filled = false; - } - QString Scene_edit_box_item::toolTip() const { + 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; + } - return QString(); + 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; + + for(short i=0; i<4; ++i) + { + faces[5].vertices[i] = vertices[i+4]; + faces[5].edges[i] = edges[i+4]; + } + faces[5].id=5; + + vertex_faces.resize(0); + normal_faces.resize(0); + + for(short i=0; i<6; ++i) + { + for(short j=0; j<4; ++j) + { + faces[i].vertices[j].face_ = &faces[i]; + faces[i].edges[j].face_ = &faces[i]; + } + } } - void Scene_edit_box_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const + mutable std::vector vertex_edges; + mutable std::vector vertex_spheres; + mutable std::vector normal_spheres; + mutable std::vector vertex_arrow; + mutable std::vector normal_arrow; + mutable std::vector vertex_faces; + mutable std::vector normal_faces; + + qglviewer::ManipulatedFrame* frame; + qglviewer::LocalConstraint constraint; + qglviewer::Vec center_; + + 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; + + void computeElements() const; + + const CGAL::Three::Scene_interface* scene; + Scene_edit_box_item* item; +}; + + +Scene_edit_box_item::Scene_edit_box_item(const CGAL::Three::Scene_interface *scene_interface) + : Scene_item(NumberOfVbos,NumberOfVaos) + +{ + d = new Scene_edit_box_item_priv(scene_interface, this); + + are_buffers_filled = false; +} +QString Scene_edit_box_item::toolTip() const { + + return QString(); +} + +void Scene_edit_box_item::draw(CGAL::Three::Viewer_interface *viewer) const +{ + if (!are_buffers_filled) { - if(!are_buffers_filled) + d->computeElements(); + d->initializeBuffers(viewer); + } + QMatrix4x4 f_matrix; + for (int i=0; i<16; ++i){ + f_matrix.data()[i] = (float)d->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; + + + vaos[Scene_edit_box_item_priv::Faces]->bind(); + d->program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); + attribBuffers(viewer, PROGRAM_WITH_LIGHT); + d->program->bind(); + d->program->setUniformValue("mvp_matrix", mvp_mat); + d->program->setUniformValue("mv_matrix", mv_mat); + d->program->setUniformValue("light_pos", light_pos); + d->program->setAttributeValue("colors", QColor(this->color())); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(d->vertex_faces.size()/3)); + vaos[Scene_edit_box_item_priv::Faces]->release(); + d->program->release(); + + vaos[Scene_edit_box_item_priv::Spheres]->bind(); + d->program = getShaderProgram(PROGRAM_SPHERES, viewer); + attribBuffers(viewer, PROGRAM_SPHERES); + d->program->bind(); + d->program->setUniformValue("mvp_matrix", mvp_mat); + d->program->setUniformValue("light_pos", light_pos); + d->program->setAttributeValue("colors", QColor(Qt::red)); + viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, + static_cast(d->vertex_spheres.size()/3), + static_cast(8)); + d->program->release(); + vaos[Scene_edit_box_item_priv::Spheres]->release(); +} + +void Scene_edit_box_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const +{ + if(!are_buffers_filled) + { + d->computeElements(); + d->initializeBuffers(viewer); + } + QMatrix4x4 f_matrix; + for (int i=0; i<16; ++i){ + f_matrix.data()[i] = (float)d->frame->matrix()[i]; + } + vaos[Edges]->bind(); + viewer->glLineWidth(4.0f); + d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); + attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); + d->program->bind(); + d->program->setUniformValue("f_matrix", f_matrix); + d->program->setAttributeValue("colors", QColor(Qt::black)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(d->vertex_edges.size()/3)); + viewer->glLineWidth(1.0f); + vaos[Edges]->release(); + d->program->release(); + if(renderingMode() == Wireframe) + { + if (!are_buffers_filled) { d->computeElements(); d->initializeBuffers(viewer); } - vaos[Edges]->bind(); - d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); - attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); + vaos[Scene_edit_box_item_priv::Spheres]->bind(); + 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; + + + d->program = getShaderProgram(PROGRAM_SPHERES, viewer); + attribBuffers(viewer, PROGRAM_SPHERES); d->program->bind(); - d->program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_LINES, 0, static_cast(d->vertex_edges.size()/3)); - vaos[Edges]->release(); + d->program->setUniformValue("mvp_matrix", mvp_mat); + d->program->setUniformValue("mv_matrix", mv_mat); + d->program->setUniformValue("light_pos", light_pos); + d->program->setAttributeValue("colors", QColor(Qt::red)); + viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, + static_cast(d->vertex_spheres.size()/3), + static_cast(8)); d->program->release(); + vaos[Scene_edit_box_item_priv::Spheres]->release(); + } +} + +void Scene_edit_box_item::compute_bbox() const +{ + QMatrix4x4 f_matrix; + for (int i=0; i<16; ++i){ + f_matrix.data()[i] = (float)d->frame->matrix()[i]; + } + + 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(); + 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()); + _bbox = bb; +} + + +void +Scene_edit_box_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewer)const +{ + + //vao containing the data for the lines + { + program = item->getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer); + program->bind(); + + item->vaos[Edges]->bind(); + item->buffers[VertexEdges].bind(); + item->buffers[VertexEdges].allocate(vertex_edges.data(), + static_cast(vertex_edges.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + item->buffers[VertexEdges].release(); + + item->vaos[Edges]->release(); + program->release(); } - void Scene_edit_box_item::compute_bbox() const + //vao containing the data for the spheres { + program = item->getShaderProgram(Scene_edit_box_item::PROGRAM_SPHERES, viewer); + item->attribBuffers(viewer, Scene_edit_box_item::PROGRAM_SPHERES); + program->bind(); + item->vaos[Spheres]->bind(); + item->buffers[VertexSpheres].bind(); + item->buffers[VertexSpheres].allocate(vertex_spheres.data(), + static_cast(vertex_spheres.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + item->buffers[VertexSpheres].release(); + + item->buffers[NormalSpheres].bind(); + item->buffers[NormalSpheres].allocate(normal_spheres.data(), + static_cast(normal_spheres.size()*sizeof(float))); + program->enableAttributeArray("normals"); + program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); + item->buffers[NormalSpheres].release(); + + item->buffers[VertexEdges].bind(); + program->enableAttributeArray("center"); + program->setAttributeBuffer("center", GL_FLOAT, 0, 3, 3*sizeof(float)); + item->buffers[VertexEdges].release(); + program->disableAttributeArray("radius"); + program->setAttributeValue("radius",1); + program->disableAttributeArray("color"); + + viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1); + item->vaos[Spheres]->release(); + + program->release(); } - - void Scene_edit_box_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewer)const + //vao containing the data for the faces { + program = item->getShaderProgram(Scene_edit_box_item::PROGRAM_WITH_LIGHT, viewer); + item->attribBuffers(viewer, Scene_edit_box_item::PROGRAM_WITH_LIGHT); - //vao containing the data for the lines + program->bind(); + item->vaos[Faces]->bind(); + item->buffers[VertexFaces].bind(); + item->buffers[VertexFaces].allocate(vertex_faces.data(), + static_cast(vertex_faces.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + item->buffers[VertexFaces].release(); + + item->buffers[NormalFaces].bind(); + item->buffers[NormalFaces].allocate(normal_faces.data(), + static_cast(normal_faces.size()*sizeof(float))); + program->enableAttributeArray("normals"); + program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); + item->buffers[NormalFaces].release(); + item->vaos[Faces]->release(); + + program->release(); + } + item->are_buffers_filled = true; +} +void push_xyz(std::vector &v, + const Scene_edit_box_item::Kernel::Point_3& p, + qglviewer::Vec center_ = qglviewer::Vec(0,0,0)) +{ + v.push_back(p.x()-center_.x); + v.push_back(p.y()-center_.y); + v.push_back(p.z()-center_.z); +} +void push_normal(std::vector &v, int id) +{ + switch(id) + { + case 0: + v.push_back(0); + v.push_back(-1); + v.push_back(0); + break; + case 1: + v.push_back(-1); + v.push_back(0); + v.push_back(0); + break; + case 2: + v.push_back(0); + v.push_back(0); + v.push_back(-1); + break; + case 3: + v.push_back(1); + v.push_back(0); + v.push_back(0); + break; + case 4: + v.push_back(0); + v.push_back(0); + v.push_back(1); + break; + case 5: + v.push_back(0); + v.push_back(1); + v.push_back(0); + break; + default: + break; + } +} +void Scene_edit_box_item_priv::computeElements() const +{ + QApplication::setOverrideCursor(Qt::WaitCursor); + vertex_edges.clear(); + vertex_faces.clear(); + normal_faces.clear(); + + //edges + for(short i=0; i<12; ++i) + { + if(i<4) { - program = item->getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer); - program->bind(); - - item->vaos[Edges]->bind(); - item->buffers[VertexEdges].bind(); - item->buffers[VertexEdges].allocate(vertex_edges.data(), - static_cast(vertex_edges.size()*sizeof(float))); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_FLOAT,0,3); - item->buffers[VertexEdges].release(); - - item->vaos[Edges]->release(); - program->release(); + 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+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); } - item->are_buffers_filled = true; - } - - void Scene_edit_box_item_priv::computeElements() const - { - QApplication::setOverrideCursor(Qt::WaitCursor); - //edges - for(short i=0; i<12; ++i) + else if(i<8) { - if(i<4) - { - vertex_edges.push_back(vertices[i].position.x()); - vertex_edges.push_back(vertices[i].position.y()); - vertex_edges.push_back(vertices[i].position.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+4].position.x()); - vertex_edges.push_back(vertices[i+4].position.y()); - vertex_edges.push_back(vertices[i+4].position.z()); - } - else if(i<8) - { - vertex_edges.push_back(vertices[i].position.x()); - vertex_edges.push_back(vertices[i].position.y()); - vertex_edges.push_back(vertices[i].position.z()); - - vertex_edges.push_back(vertices[(i+1)%4 +4].position.x()); - vertex_edges.push_back(vertices[(i+1)%4 +4].position.y()); - vertex_edges.push_back(vertices[(i+1)%4 +4].position.z()); - } - else - { - vertex_edges.push_back(vertices[i%4].position.x()); - vertex_edges.push_back(vertices[i%4].position.y()); - vertex_edges.push_back(vertices[i%4].position.z()); - - vertex_edges.push_back(vertices[(i+1) %4].position.x()); - vertex_edges.push_back(vertices[(i+1) %4].position.y()); - vertex_edges.push_back(vertices[(i+1) %4].position.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); } - QApplication::restoreOverrideCursor(); + 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+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); + } + } + //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[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); } - Scene_edit_box_item::~Scene_edit_box_item() + QApplication::restoreOverrideCursor(); +} + +Scene_edit_box_item::~Scene_edit_box_item() +{ + delete d; +} + +// Indicate if rendering mode is supported +bool Scene_edit_box_item::supportsRenderingMode(RenderingMode m) const { + switch(m) { - delete d; + case Wireframe: + case FlatPlusEdges: + return true; + default: + return false; } +} + +CGAL::Three::Scene_item::ManipulatedFrame* +Scene_edit_box_item::manipulatedFrame() { return 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); + QMatrix4x4 f_matrix; + for (int k=0; k<16; ++k){ + f_matrix.data()[k] = (float)d->frame->matrix()[k]; + } + return (f_matrix*pos)[j]; +} diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h index 54244ff1803..a8d0205ee9b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -12,7 +12,6 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item typedef CGAL::Simple_cartesian Kernel; struct vertex; struct edge; - struct triangle; struct face; enum VAOs{ Edges = 0, @@ -20,12 +19,15 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item S_Edges, S_Spheres, Arrow, + Faces, NumberOfVaos }; enum VBOs{ VertexEdges = 0, VertexSpheres, NormalSpheres, + VertexFaces, + NormalFaces, VertexArrow, NormalArrow, NumberOfVbos @@ -36,6 +38,8 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item bool isEmpty() const { return true; } void compute_bbox() const; + bool manipulatable() const { return true; } + ManipulatedFrame* manipulatedFrame(); Scene_edit_box_item* clone() const { return 0; } @@ -43,17 +47,15 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item QString toolTip() const; // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const { - return (m == Wireframe); - } - + bool supportsRenderingMode(RenderingMode m) const; + void draw(CGAL::Three::Viewer_interface *) const; void drawEdges(CGAL::Three::Viewer_interface* viewer) const; void invalidateOpenGLBuffers() { compute_bbox(); are_buffers_filled = false; } - + double point(short i, short j) const; protected: friend struct Scene_edit_box_item_priv; Scene_edit_box_item_priv* d; From 71feaa34be1f12dbeae1c3c12cd193e82456d97e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 20 Oct 2016 16:05:04 +0200 Subject: [PATCH 03/13] WIP editable box --- .../Plugins/PCA/Scene_edit_box_item.cpp | 579 +++++++++++++++--- .../Plugins/PCA/Scene_edit_box_item.h | 14 +- 2 files changed, 496 insertions(+), 97 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 5c1f2f11c29..39d8632d08d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -2,22 +2,32 @@ #include #include #include - +#include +#include +#include +using namespace CGAL::Three; struct Scene_edit_box_item::vertex{ short id; - CGAL::Point_3 position; face* face_; + double *x; + double *y; + double *z; + + CGAL::Point_3 position()const + { + return CGAL::Point_3(*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 vertex_edges; + mutable std::vector color_edges; mutable std::vector vertex_spheres; mutable std::vector normal_spheres; + mutable std::vector center_spheres; + mutable std::vector color_spheres; mutable std::vector vertex_arrow; mutable std::vector normal_arrow; mutable std::vector vertex_faces; mutable std::vector normal_faces; + mutable std::vector 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(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(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(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(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(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); + //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(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(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(vertex_spheres.size()/3), + static_cast(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(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(); + } +} diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h index a8d0205ee9b..ad0ab9253ce 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -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; From f7792308d5e3ff7f1c54cc0eb96218ad30c91d20 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 21 Oct 2016 14:45:12 +0200 Subject: [PATCH 04/13] Fix rotation problems --- .../Plugins/PCA/Scene_edit_box_item.cpp | 62 +++++++++++++------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 39d8632d08d..ca0109a8378 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -70,9 +70,12 @@ struct Scene_edit_box_item_priv{ double y=(bb.ymin()+bb.ymax())/2; double z=(bb.zmin()+bb.zmax())/2; center_ = qglviewer::Vec(x,y,z); + relative_center_ = qglviewer::Vec(0,0,0); remodel_frame = new Scene_item::ManipulatedFrame(); + remodel_frame->setTranslationSensitivity(1.0); frame = new Scene_item::ManipulatedFrame(); frame->setPosition(center_); + frame->setSpinningSensitivity(100.0); //forbid spinning constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); constraint.setRotationConstraintDirection(qglviewer::Vec(.0,.0,.1)); frame->setConstraint(&constraint); @@ -98,7 +101,7 @@ struct Scene_edit_box_item_priv{ // 0------3 //vertices - for(short i = 0; i< 8; ++i) + for( int i = 0; i< 8; ++i) { vertices[i].x = ((i/2)%2==0)? &pool[0]:&pool[3]; @@ -116,7 +119,7 @@ struct Scene_edit_box_item_priv{ // .--11--. //edges - for(short i=0; i<12; ++i) + for( int i=0; i<12; ++i) { edges[i].id = i; if(i<4) @@ -154,14 +157,14 @@ struct Scene_edit_box_item_priv{ //faces - for(short i=0; i<4; ++i) + for( int i=0; i<4; ++i) { faces[0].vertices[i] = &vertices[i]; faces[0].edges[(i+1)%4] = &edges[i+7]; } faces[0].id =0; - for(short i=1; i<4; ++i) + for( int i=1; i<4; ++i) { faces[i].vertices[0] = &vertices[i]; faces[i].vertices[1] = &vertices[(i-1)]; @@ -186,7 +189,7 @@ struct Scene_edit_box_item_priv{ faces[4].edges[3] = &edges[4]; faces[4].id =4; - for(short i=0; i<4; ++i) + for( int i=0; i<4; ++i) { faces[5].vertices[i] = &vertices[i+4]; faces[5].edges[i] = &edges[i+4]; @@ -196,9 +199,9 @@ struct Scene_edit_box_item_priv{ vertex_faces.resize(0); normal_faces.resize(0); - for(short i=0; i<6; ++i) + for( int i=0; i<6; ++i) { - for(short j=0; j<4; ++j) + for( int j=0; j<4; ++j) { faces[i].vertices[j]->face_ = &faces[i]; faces[i].edges[j]->face_ = &faces[i]; @@ -230,6 +233,7 @@ struct Scene_edit_box_item_priv{ qglviewer::Vec rf_last_pos; qglviewer::LocalConstraint constraint; qglviewer::Vec center_; + qglviewer::Vec relative_center_; mutable QOpenGLShaderProgram pick_sphere_program; mutable Scene_edit_box_item::vertex vertices[8]; @@ -608,7 +612,7 @@ void Scene_edit_box_item_priv::computeElements() const color_spheres.clear(); //edges - for(short i=0; i<12; ++i) + for( int i=0; i<12; ++i) { if(i<4) { @@ -659,7 +663,7 @@ void Scene_edit_box_item_priv::computeElements() const } //faces - for(short i=0; i<6; ++i) + for( int 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_); @@ -669,7 +673,7 @@ void Scene_edit_box_item_priv::computeElements() const 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) + for( int j=0; j<6; ++j) { push_normal(normal_faces, i); @@ -680,7 +684,7 @@ void Scene_edit_box_item_priv::computeElements() const } //spheres - for(short i=0; i<8; ++i) + for( int i=0; i<8; ++i) { color_spheres.push_back((20.0*i+10)/255); color_spheres.push_back(0); @@ -710,7 +714,7 @@ bool Scene_edit_box_item::supportsRenderingMode(RenderingMode m) const { Scene_item::ManipulatedFrame* Scene_edit_box_item::manipulatedFrame() { - return d->selection_on? d->remodel_frame :d->frame; + return d->frame; } double Scene_edit_box_item::point(short i, short j) const @@ -757,6 +761,7 @@ void Scene_edit_box_item_priv::reset_selection() QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->setManipulatedFrame(frame); viewer->setMouseBinding(Qt::ShiftModifier, Qt::LeftButton, QGLViewer::SELECT); + constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); selected_vertex= NULL; selected_edge= NULL; selected_face= NULL; @@ -792,8 +797,7 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) 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_; + d->rf_last_pos = d->remodel_frame->position(); 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); @@ -827,11 +831,11 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) 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(); + QVector3D n = QVector3D::crossProduct(a,b); + d->remodel_frame->setConstraint(&d->constraint); 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); @@ -858,9 +862,9 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) { 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->remodel_frame->setOrientation(d->frame->orientation()); + qglviewer::Vec td(d->remodel_frame->transformOf(d->remodel_frame->position() - d->rf_last_pos)); + QVector3D dir(td.x, td.y, td.z); d->rf_last_pos = d->remodel_frame->position(); d->remodel_box(dir); return false; @@ -934,12 +938,19 @@ void Scene_edit_box_item_priv::draw_picking(Viewer_interface* viewer) //!\todo redo the API to only use a list of selected vertices void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) { + qglviewer::AxisPlaneConstraint::Type prev_cons = constraint.translationConstraintType(); + constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); if(selected_vertex != NULL) { *selected_vertex->x += dir.x(); *selected_vertex->y += dir.y(); *selected_vertex->z += dir.z(); + for( int i=0; i<3; ++i) + relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; + for( int i=0; i<3; ++i) + center_[i] =(pool[i]+pool[i+3])/2; + frame->translate(frame->inverseTransformOf(relative_center_)); item->invalidateOpenGLBuffers(); } else if(selected_edge != NULL) @@ -950,16 +961,27 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) *selected_edge->target->x += dir.x(); *selected_edge->target->y += dir.y(); *selected_edge->target->z += dir.z(); + for( int i=0; i<3; ++i) + relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; + for( int i=0; i<3; ++i) + center_[i] =(pool[i]+pool[i+3])/2; + frame->translate(frame->inverseTransformOf(relative_center_)); item->invalidateOpenGLBuffers(); } else if(selected_face != NULL) { - for(short i=0; i<4; ++i) + for( int 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(); } + for( int i=0; i<3; ++i) + relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; + for( int i=0; i<3; ++i) + center_[i] =(pool[i]+pool[i+3])/2; + frame->translate(frame->inverseTransformOf(relative_center_)); item->invalidateOpenGLBuffers(); } + constraint.setTranslationConstraintType(prev_cons); } From ffda7192a98adcb75a74f2c525c77e5071240e8e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 21 Oct 2016 15:23:41 +0200 Subject: [PATCH 05/13] Force the volume of the box to stay positive --- .../Plugins/PCA/Scene_edit_box_item.cpp | 85 ++++++++++++++++--- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index ca0109a8378..69cd2ff055e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -250,9 +250,12 @@ struct Scene_edit_box_item_priv{ void initializeBuffers(Viewer_interface *viewer)const; void computeElements() const; - void draw_picking(Viewer_interface*); void remodel_box(const QVector3D &dir); + + bool applyX(double x, double dirx); + bool applyY(double y, double diry); + bool applyZ(double z, double dirz); const Scene_interface* scene; Scene_edit_box_item* item; }; @@ -943,9 +946,12 @@ 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(); + if(applyX(*selected_vertex->x, dir.x())) + *selected_vertex->x += dir.x(); + if(applyY(*selected_vertex->y, dir.y())) + *selected_vertex->y += dir.y(); + if(applyZ(*selected_vertex->z, dir.z())) + *selected_vertex->z += dir.z(); for( int i=0; i<3; ++i) relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; for( int i=0; i<3; ++i) @@ -955,12 +961,18 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) } 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(); + if(applyX(*selected_edge->source->x, dir.x())) + *selected_edge->source->x += dir.x(); + if(applyY(*selected_edge->source->y, dir.y())) + *selected_edge->source->y += dir.y(); + if(applyZ(*selected_edge->source->z, dir.z())) + *selected_edge->source->z += dir.z(); + if(applyX(*selected_edge->target->x, dir.x())) + *selected_edge->target->x += dir.x(); + if(applyY(*selected_edge->target->y, dir.y())) + *selected_edge->target->y += dir.y(); + if(applyZ(*selected_edge->target->z, dir.z())) + *selected_edge->target->z += dir.z(); for( int i=0; i<3; ++i) relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; for( int i=0; i<3; ++i) @@ -972,9 +984,12 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) { for( int 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(); + if(applyX(*selected_face->vertices[i]->x, dir.x())) + *selected_face->vertices[i]->x += dir.x(); + if(applyY(*selected_face->vertices[i]->y, dir.y())) + *selected_face->vertices[i]->y += dir.y(); + if(applyZ(*selected_face->vertices[i]->z, dir.z())) + *selected_face->vertices[i]->z += dir.z(); } for( int i=0; i<3; ++i) relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; @@ -985,3 +1000,47 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) } constraint.setTranslationConstraintType(prev_cons); } + +bool Scene_edit_box_item_priv::applyX(double x, double dirx) +{ + if(x == pool[0]) + { + if(x+dirx < pool[3]) + return true; + } + else + { + if(x+dirx > pool[0]) + return true; + } + return false; +} + +bool Scene_edit_box_item_priv::applyY(double y, double diry) +{ + if(y == pool[1]) + { + if(y+diry < pool[4]) + return true; + } + else + { + if(y+diry > pool[1]) + return true; + } + return false; +} +bool Scene_edit_box_item_priv::applyZ(double z, double dirz) +{ + if(z == pool[2]) + { + if(z+dirz < pool[5]) + return true; + } + else + { + if(z+dirz > pool[2]) + return true; + } + return false; +} From 76fc3b23de5ec8c7a5f6d5665e00ff405f80cb98 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 21 Oct 2016 16:04:09 +0200 Subject: [PATCH 06/13] computes the right Bbox for the item --- .../Plugins/PCA/Scene_edit_box_item.cpp | 29 +++++++------------ .../Plugins/PCA/Scene_edit_box_item.h | 2 +- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 69cd2ff055e..c3c6d664222 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -393,19 +393,16 @@ void Scene_edit_box_item::compute_bbox() const f_matrix.data()[i] = (float)d->frame->matrix()[i]; } - 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(); - QVector3D min(xmin, ymin, zmin); - QVector3D max(xmax, ymax, zmax); - min = f_matrix*min; - max = f_matrix*max; - Scene_item::Bbox bb(min.x(),min.y(),min.z(),max.x(),max.y(),max.z()); - _bbox = bb; + QVector3D min(d->pool[0], d->pool[1], d->pool[2]); + QVector3D max(d->pool[3], d->pool[4], d->pool[5]); + + for(int i=0; i< 3; ++i) + { + min[i] += d->frame->translation()[i]-d->center_[i]; + max[i] += d->frame->translation()[i]-d->center_[i]; + } + + _bbox = Scene_item::Bbox(min.x(),min.y(),min.z(),max.x(),max.y(),max.z()); } @@ -938,7 +935,6 @@ void Scene_edit_box_item_priv::draw_picking(Viewer_interface* viewer) 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) { qglviewer::AxisPlaneConstraint::Type prev_cons = constraint.translationConstraintType(); @@ -957,7 +953,6 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) for( int i=0; i<3; ++i) center_[i] =(pool[i]+pool[i+3])/2; frame->translate(frame->inverseTransformOf(relative_center_)); - item->invalidateOpenGLBuffers(); } else if(selected_edge != NULL) { @@ -978,7 +973,6 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) for( int i=0; i<3; ++i) center_[i] =(pool[i]+pool[i+3])/2; frame->translate(frame->inverseTransformOf(relative_center_)); - item->invalidateOpenGLBuffers(); } else if(selected_face != NULL) { @@ -996,8 +990,8 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) for( int i=0; i<3; ++i) center_[i] =(pool[i]+pool[i+3])/2; frame->translate(frame->inverseTransformOf(relative_center_)); - item->invalidateOpenGLBuffers(); } + item->invalidateOpenGLBuffers(); constraint.setTranslationConstraintType(prev_cons); } @@ -1015,7 +1009,6 @@ bool Scene_edit_box_item_priv::applyX(double x, double dirx) } return false; } - bool Scene_edit_box_item_priv::applyY(double y, double diry) { if(y == pool[1]) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h index ad0ab9253ce..f3baca8b50c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -43,7 +43,7 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item Scene_edit_box_item(const CGAL::Three::Scene_interface* scene_interface); ~Scene_edit_box_item(); bool isFinite() const { return true; } - bool isEmpty() const { return true; } + bool isEmpty() const { return false; } void compute_bbox() const; bool manipulatable() const { return true; } From c6627aa05f3965c9afab427a505ebe1bb977872e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 24 Oct 2016 10:43:17 +0200 Subject: [PATCH 07/13] Smooth the transformations and factorize the code. --- .../Plugins/PCA/Scene_edit_box_item.cpp | 336 ++++++++---------- .../Plugins/PCA/Scene_edit_box_item.h | 1 + 2 files changed, 158 insertions(+), 179 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index c3c6d664222..8b6d2e3e500 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -7,26 +7,35 @@ #include using namespace CGAL::Three; struct Scene_edit_box_item::vertex{ - short id; - face* face_; + int id; double *x; double *y; double *z; CGAL::Point_3 position()const { - return CGAL::Point_3(*x,*y,*z); + return CGAL::Point_3(*x,*y,*z); + } + double operator[](int i) + { + switch(i) + { + case 0: + return *x; + case 1: + return *y; + case 2: + return *z; + default: + return 0; + } } }; struct Scene_edit_box_item::edge{ - short id; vertex* source; vertex* target; - face* face_; }; struct Scene_edit_box_item::face{ - short id; - edge* edges[4]; vertex* vertices[4]; }; @@ -104,10 +113,10 @@ struct Scene_edit_box_item_priv{ for( int i = 0; i< 8; ++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; + 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--. @@ -121,7 +130,6 @@ struct Scene_edit_box_item_priv{ //edges for( int i=0; i<12; ++i) { - edges[i].id = i; if(i<4) { edges[i].source = &vertices[i]; @@ -160,9 +168,7 @@ struct Scene_edit_box_item_priv{ for( int i=0; i<4; ++i) { faces[0].vertices[i] = &vertices[i]; - faces[0].edges[(i+1)%4] = &edges[i+7]; } - faces[0].id =0; for( int i=1; i<4; ++i) { @@ -170,12 +176,6 @@ struct Scene_edit_box_item_priv{ 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].id = i; } faces[4].vertices[0] = &vertices[0]; @@ -183,30 +183,17 @@ struct Scene_edit_box_item_priv{ 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; - for( int i=0; i<4; ++i) { faces[5].vertices[i] = &vertices[i+4]; - faces[5].edges[i] = &edges[i+4]; } - faces[5].id =5; vertex_faces.resize(0); normal_faces.resize(0); - for( int i=0; i<6; ++i) - { - for( int j=0; j<4; ++j) - { - faces[i].vertices[j]->face_ = &faces[i]; - faces[i].edges[j]->face_ = &faces[i]; - } - } + for(int i=0; i<8; ++i) + for(int j=0; j<3; ++j) + last_pool[i][j] = vertices[i][j]; 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"); @@ -226,6 +213,8 @@ struct Scene_edit_box_item_priv{ mutable std::vector normal_faces; mutable std::vector color_faces; double pool[6]; + //id|coord + double last_pool[8][3]; qglviewer::ManipulatedFrame* frame; @@ -240,9 +229,7 @@ struct Scene_edit_box_item_priv{ mutable Scene_edit_box_item::edge edges[12]; mutable Scene_edit_box_item::face faces[6]; - Scene_edit_box_item::vertex* selected_vertex; - Scene_edit_box_item::edge* selected_edge; - Scene_edit_box_item::face* selected_face; + std::vector selected_vertices; void reset_selection(); bool selection_on; @@ -253,9 +240,9 @@ struct Scene_edit_box_item_priv{ void draw_picking(Viewer_interface*); void remodel_box(const QVector3D &dir); - bool applyX(double x, double dirx); - bool applyY(double y, double diry); - bool applyZ(double z, double dirz); + double applyX(int id, double x, double dirx); + double applyY(int id, double y, double diry); + double applyZ(int id, double z, double dirz); const Scene_interface* scene; Scene_edit_box_item* item; }; @@ -274,6 +261,38 @@ QString Scene_edit_box_item::toolTip() const { return QString(); } +void Scene_edit_box_item::drawSpheres(Viewer_interface *viewer, const QMatrix4x4 f_matrix ) const +{ + vaos[Scene_edit_box_item_priv::Spheres]->bind(); + 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; + + + d->program = getShaderProgram(PROGRAM_SPHERES, viewer); + attribBuffers(viewer, PROGRAM_SPHERES); + d->program->bind(); + d->program->setUniformValue("mvp_matrix", mvp_mat); + d->program->setUniformValue("mv_matrix", mv_mat); + d->program->setUniformValue("light_pos", light_pos); + d->program->setAttributeValue("colors", QColor(Qt::red)); + viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, + static_cast(d->vertex_spheres.size()/3), + static_cast(8)); + d->program->release(); + vaos[Scene_edit_box_item_priv::Spheres]->release(); +} + void Scene_edit_box_item::draw(Viewer_interface *viewer) const { if (!are_buffers_filled) @@ -290,7 +309,7 @@ void Scene_edit_box_item::draw(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) @@ -312,18 +331,7 @@ void Scene_edit_box_item::draw(Viewer_interface *viewer) const vaos[Scene_edit_box_item_priv::Faces]->release(); d->program->release(); - vaos[Scene_edit_box_item_priv::Spheres]->bind(); - d->program = getShaderProgram(PROGRAM_SPHERES, viewer); - attribBuffers(viewer, PROGRAM_SPHERES); - d->program->bind(); - d->program->setUniformValue("mvp_matrix", mvp_mat); - d->program->setUniformValue("light_pos", light_pos); - d->program->setAttributeValue("colors", QColor(Qt::red)); - viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, - static_cast(d->vertex_spheres.size()/3), - static_cast(8)); - d->program->release(); - vaos[Scene_edit_box_item_priv::Spheres]->release(); + drawSpheres(viewer, f_matrix); } void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const @@ -338,7 +346,7 @@ void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const f_matrix.data()[i] = (float)d->frame->matrix()[i]; } vaos[Edges]->bind(); - viewer->glLineWidth(4.0f); + viewer->glLineWidth(8.0f); d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); d->program->bind(); @@ -350,39 +358,7 @@ void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const d->program->release(); if(renderingMode() == Wireframe) { - if (!are_buffers_filled) - { - d->computeElements(); - d->initializeBuffers(viewer); - } - vaos[Scene_edit_box_item_priv::Spheres]->bind(); - 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; - - - d->program = getShaderProgram(PROGRAM_SPHERES, viewer); - attribBuffers(viewer, PROGRAM_SPHERES); - d->program->bind(); - d->program->setUniformValue("mvp_matrix", mvp_mat); - d->program->setUniformValue("mv_matrix", mv_mat); - d->program->setUniformValue("light_pos", light_pos); - d->program->setAttributeValue("colors", QColor(Qt::red)); - viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, - static_cast(d->vertex_spheres.size()/3), - static_cast(8)); - d->program->release(); - vaos[Scene_edit_box_item_priv::Spheres]->release(); + drawSpheres(viewer, f_matrix); } } @@ -398,8 +374,8 @@ void Scene_edit_box_item::compute_bbox() const for(int i=0; i< 3; ++i) { - min[i] += d->frame->translation()[i]-d->center_[i]; - max[i] += d->frame->translation()[i]-d->center_[i]; + min[i] += d->frame->translation()[i]-d->center_[i]; + max[i] += d->frame->translation()[i]-d->center_[i]; } _bbox = Scene_item::Bbox(min.x(),min.y(),min.z(),max.x(),max.y(),max.z()); @@ -554,6 +530,7 @@ Scene_edit_box_item_priv::initializeBuffers(Viewer_interface *viewer)const } item->are_buffers_filled = true; } + void push_xyz(std::vector &v, const Scene_edit_box_item::Kernel::Point_3& p, qglviewer::Vec center_ = qglviewer::Vec(0,0,0)) @@ -562,6 +539,7 @@ void push_xyz(std::vector &v, v.push_back(p.y()-center_.y); v.push_back(p.z()-center_.z); } + void push_normal(std::vector &v, int id) { switch(id) @@ -600,6 +578,7 @@ void push_normal(std::vector &v, int id) break; } } + void Scene_edit_box_item_priv::computeElements() const { QApplication::setOverrideCursor(Qt::WaitCursor); @@ -701,14 +680,7 @@ Scene_edit_box_item::~Scene_edit_box_item() // Indicate if rendering mode is supported bool Scene_edit_box_item::supportsRenderingMode(RenderingMode m) const { - switch(m) - { - case Wireframe: - case FlatPlusEdges: - return true; - default: - return false; - } + return (m==Wireframe || m==FlatPlusEdges); } Scene_item::ManipulatedFrame* @@ -762,9 +734,7 @@ void Scene_edit_box_item_priv::reset_selection() viewer->setManipulatedFrame(frame); viewer->setMouseBinding(Qt::ShiftModifier, Qt::LeftButton, QGLViewer::SELECT); constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - selected_vertex= NULL; - selected_edge= NULL; - selected_face= NULL; + selected_vertices.clear(); } //intercept events for picking bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) @@ -797,7 +767,17 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) if(!(buffer[0]==buffer[1] && buffer[1]==buffer[2])) { d->selection_on = true; - d->rf_last_pos = d->remodel_frame->position(); + bool found = false; + qglviewer::Vec pos = viewer->camera()->pointUnderPixel(e->pos(), found); + if(found) + { + d->rf_last_pos = pos; + d->remodel_frame->setPosition(pos); + } + for(int i=0; i<8; ++i) + for(int j=0; j<3; ++j) + d->last_pool[i][j] = d->vertices[i][j]; + 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); @@ -805,7 +785,7 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) { if(picked <8) { - d->selected_vertex = &d->vertices[picked]; + d->selected_vertices.push_back(&d->vertices[picked]); d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); d->remodel_frame->setConstraint(&d->constraint); } @@ -814,8 +794,9 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) { if(picked <12) { - d->selected_edge = &d->edges[picked]; - Kernel::Point_3 s(d->selected_edge->source->position()), t(d->selected_edge->target->position()); + d->selected_vertices.push_back(d->edges[picked].source); + d->selected_vertices.push_back(d->edges[picked].target); + Kernel::Point_3 s(d->edges[picked].source->position()), t(d->edges[picked].target->position()); qglviewer::Vec normal(t.x()-s.x(), t.y()-s.y(), t.z()-s.z()); d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::PLANE); @@ -827,9 +808,10 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) { 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()); + for(int i=0; i<4; ++i) + d->selected_vertices.push_back(d->faces[picked].vertices[i]); + Kernel::Point_3 a1(d->faces[picked].vertices[1]->position()), a0(d->faces[picked].vertices[0]->position()) + ,a3(d->faces[picked].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,b); @@ -849,7 +831,7 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) } else { - d->reset_selection(); + d->reset_selection(); } delete fbo; } @@ -863,9 +845,9 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) if(d->selection_on) { d->remodel_frame->setOrientation(d->frame->orientation()); + qglviewer::Vec sd(d->remodel_frame->position() - d->rf_last_pos); qglviewer::Vec td(d->remodel_frame->transformOf(d->remodel_frame->position() - d->rf_last_pos)); QVector3D dir(td.x, td.y, td.z); - d->rf_last_pos = d->remodel_frame->position(); d->remodel_box(dir); return false; } @@ -940,51 +922,12 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) qglviewer::AxisPlaneConstraint::Type prev_cons = constraint.translationConstraintType(); constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - if(selected_vertex != NULL) + Q_FOREACH(Scene_edit_box_item::vertex* selected_vertex, selected_vertices ) { - if(applyX(*selected_vertex->x, dir.x())) - *selected_vertex->x += dir.x(); - if(applyY(*selected_vertex->y, dir.y())) - *selected_vertex->y += dir.y(); - if(applyZ(*selected_vertex->z, dir.z())) - *selected_vertex->z += dir.z(); - for( int i=0; i<3; ++i) - relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; - for( int i=0; i<3; ++i) - center_[i] =(pool[i]+pool[i+3])/2; - frame->translate(frame->inverseTransformOf(relative_center_)); - } - else if(selected_edge != NULL) - { - if(applyX(*selected_edge->source->x, dir.x())) - *selected_edge->source->x += dir.x(); - if(applyY(*selected_edge->source->y, dir.y())) - *selected_edge->source->y += dir.y(); - if(applyZ(*selected_edge->source->z, dir.z())) - *selected_edge->source->z += dir.z(); - if(applyX(*selected_edge->target->x, dir.x())) - *selected_edge->target->x += dir.x(); - if(applyY(*selected_edge->target->y, dir.y())) - *selected_edge->target->y += dir.y(); - if(applyZ(*selected_edge->target->z, dir.z())) - *selected_edge->target->z += dir.z(); - for( int i=0; i<3; ++i) - relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; - for( int i=0; i<3; ++i) - center_[i] =(pool[i]+pool[i+3])/2; - frame->translate(frame->inverseTransformOf(relative_center_)); - } - else if(selected_face != NULL) - { - for( int i=0; i<4; ++i) - { - if(applyX(*selected_face->vertices[i]->x, dir.x())) - *selected_face->vertices[i]->x += dir.x(); - if(applyY(*selected_face->vertices[i]->y, dir.y())) - *selected_face->vertices[i]->y += dir.y(); - if(applyZ(*selected_face->vertices[i]->z, dir.z())) - *selected_face->vertices[i]->z += dir.z(); - } + int id = selected_vertex->id; + *selected_vertex->x = applyX(id, last_pool[id][0], dir.x()); + *selected_vertex->y = applyY(id, last_pool[id][1], dir.y()); + *selected_vertex->z = applyZ(id, last_pool[id][2], dir.z()); for( int i=0; i<3; ++i) relative_center_[i] =(pool[i]+pool[i+3])/2 - center_[i]; for( int i=0; i<3; ++i) @@ -995,45 +938,80 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) constraint.setTranslationConstraintType(prev_cons); } -bool Scene_edit_box_item_priv::applyX(double x, double dirx) +double Scene_edit_box_item_priv::applyX(int id, double x, double dirx) { - if(x == pool[0]) + switch(id) { + case 0: + case 1: + case 4: + case 5: if(x+dirx < pool[3]) - return true; - } - else - { + return x+dirx; + else + return pool[3]; + case 2: + case 3: + case 6: + case 7: if(x+dirx > pool[0]) - return true; + return x+dirx; + else + return pool[0]; + default: + return 0; } - return false; + return 0; } -bool Scene_edit_box_item_priv::applyY(double y, double diry) + +double Scene_edit_box_item_priv::applyY(int id, double y, double diry) { - if(y == pool[1]) + switch(id) { + case 0: + case 1: + case 2: + case 3: if(y+diry < pool[4]) - return true; - } - else - { + return y+diry; + else + return pool[4]; + case 4: + case 5: + case 6: + case 7: if(y+diry > pool[1]) - return true; + return y+diry; + else + return pool[1]; + default: + return 0; } - return false; + return 0; } -bool Scene_edit_box_item_priv::applyZ(double z, double dirz) + +double Scene_edit_box_item_priv::applyZ(int id, double z, double dirz) { - if(z == pool[2]) + switch(id) { + case 1: + case 2: + case 5: + case 6: if(z+dirz < pool[5]) - return true; - } - else - { + return z+dirz; + else + return pool[5]; + case 0: + case 3: + case 4: + case 7: if(z+dirz > pool[2]) - return true; + return z+dirz; + else + return pool[2]; + default: + return 0; } - return false; + return 0; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h index f3baca8b50c..10cd7f9d01f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -59,6 +59,7 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item bool supportsRenderingMode(RenderingMode m) const; void draw(CGAL::Three::Viewer_interface *) const; void drawEdges(CGAL::Three::Viewer_interface* viewer) const; + void drawSpheres(CGAL::Three::Viewer_interface* viewer, const QMatrix4x4 f_matrix) const; void invalidateOpenGLBuffers() { compute_bbox(); From 16b48bf5d46cda350eb3cbca5d1e2c71d77be044 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 24 Oct 2016 15:22:01 +0200 Subject: [PATCH 08/13] Add the highlighting. --- .../Plugins/PCA/Scene_edit_box_item.cpp | 400 ++++++++++++++---- .../Plugins/PCA/Scene_edit_box_item.h | 3 + 2 files changed, 317 insertions(+), 86 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 8b6d2e3e500..22d12233fb1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -66,11 +66,19 @@ struct Scene_edit_box_item_priv{ ColorsFaces, VertexArrow, NormalArrow, + S_Vertex, + S_Normal, NumberOfVbos }; - + enum HL_Primitive{ + VERTEX=0, + EDGE, + FACE, + NO_TYPE + }; Scene_edit_box_item_priv(const Scene_interface *scene_interface, Scene_edit_box_item* ebi) { + ready_to_hl = true; scene = scene_interface; item = ebi; selection_on = false; @@ -212,9 +220,13 @@ struct Scene_edit_box_item_priv{ mutable std::vector vertex_faces; mutable std::vector normal_faces; mutable std::vector color_faces; + mutable std::vector hl_vertex; + mutable std::vector hl_normal; + double pool[6]; //id|coord double last_pool[8][3]; + bool ready_to_hl; qglviewer::ManipulatedFrame* frame; @@ -232,6 +244,7 @@ struct Scene_edit_box_item_priv{ std::vector selected_vertices; void reset_selection(); bool selection_on; + void picking(int& type, int& id, Viewer_interface *viewer); mutable QOpenGLShaderProgram* program; void initializeBuffers(Viewer_interface *viewer)const; @@ -245,6 +258,8 @@ struct Scene_edit_box_item_priv{ double applyZ(int id, double z, double dirz); const Scene_interface* scene; Scene_edit_box_item* item; + QPoint picked_pixel; + HL_Primitive hl_type; }; @@ -255,6 +270,8 @@ Scene_edit_box_item::Scene_edit_box_item(const Scene_interface *scene_interface) d = new Scene_edit_box_item_priv(scene_interface, this); are_buffers_filled = false; + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + viewer->setMouseTracking(true); } QString Scene_edit_box_item::toolTip() const { @@ -279,12 +296,13 @@ void Scene_edit_box_item::drawSpheres(Viewer_interface *viewer, const QMatrix4x4 light_pos = light_pos*f_matrix; - d->program = getShaderProgram(PROGRAM_SPHERES, viewer); attribBuffers(viewer, PROGRAM_SPHERES); + d->program = getShaderProgram(PROGRAM_SPHERES, viewer); d->program->bind(); d->program->setUniformValue("mvp_matrix", mvp_mat); d->program->setUniformValue("mv_matrix", mv_mat); d->program->setUniformValue("light_pos", light_pos); + d->program->setAttributeValue("radius",1); d->program->setAttributeValue("colors", QColor(Qt::red)); viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, static_cast(d->vertex_spheres.size()/3), @@ -346,7 +364,7 @@ void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const f_matrix.data()[i] = (float)d->frame->matrix()[i]; } vaos[Edges]->bind(); - viewer->glLineWidth(8.0f); + viewer->glLineWidth(4.0f); d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); d->program->bind(); @@ -360,6 +378,7 @@ void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const { drawSpheres(viewer, f_matrix); } + drawHl(viewer); } void Scene_edit_box_item::compute_bbox() const @@ -438,13 +457,12 @@ Scene_edit_box_item_priv::initializeBuffers(Viewer_interface *viewer)const item->buffers[NormalSpheres].release(); item->buffers[CenterSpheres].bind(); - program->enableAttributeArray("center"); item->buffers[CenterSpheres].allocate(center_spheres.data(), static_cast(center_spheres.size()*sizeof(float))); + program->enableAttributeArray("center"); program->setAttributeBuffer("center", GL_FLOAT, 0, 3); - item->buffers[VertexEdges].release(); + item->buffers[CenterSpheres].release(); program->disableAttributeArray("radius"); - program->setAttributeValue("radius",1); program->disableAttributeArray("colors"); viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1); @@ -675,6 +693,9 @@ void Scene_edit_box_item_priv::computeElements() const Scene_edit_box_item::~Scene_edit_box_item() { + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + viewer->setMouseTracking(false); + delete d; } @@ -703,28 +724,136 @@ double Scene_edit_box_item::point(short i, short j) const 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) + d->ready_to_hl = true; + Viewer_interface* viewer = dynamic_cast(*QGLViewer::QGLViewerPool().begin()); + int type, id; + //pick + d->picking(type, id, viewer); + //highlight + d->hl_normal.clear(); + d->hl_vertex.clear(); + if(type !=-1) { - const qglviewer::Vec& orig = camera->position(); - const qglviewer::Vec& dir = point - orig; - is_highlighting = true; + switch(type) + { + case 0: + { + //compute + d->hl_vertex.push_back(d->vertices[id].position().x()-d->center_.x); + d->hl_vertex.push_back(d->vertices[id].position().y()-d->center_.y); + d->hl_vertex.push_back(d->vertices[id].position().z()-d->center_.z); + //fill buffers + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_SPHERES, viewer); + d->program->bind(); - is_highlighting = false; + vaos[S_Spheres]->bind(); + buffers[VertexSpheres].bind(); + buffers[VertexSpheres].allocate(d->vertex_spheres.data(), + static_cast(d->vertex_spheres.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + buffers[VertexSpheres].release(); + + buffers[NormalSpheres].bind(); + buffers[NormalSpheres].allocate(d->normal_spheres.data(), + static_cast(d->normal_spheres.size()*sizeof(float))); + d->program->enableAttributeArray("normals"); + d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); + buffers[NormalSpheres].release(); + + buffers[S_Vertex].bind(); + buffers[S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("center"); + d->program->setAttributeBuffer("center", GL_FLOAT, 0, 3); + buffers[S_Vertex].release(); + d->program->disableAttributeArray("colors"); + + viewer->glVertexAttribDivisor(d->program->attributeLocation("center"), 1); + d->program->release(); + vaos[S_Spheres]->release(); + //draw + d->hl_type = Scene_edit_box_item_priv::VERTEX; + break; + } + case 1: + { + //compute + d->hl_vertex.push_back(d->edges[id].source->position().x()-d->center_.x); + d->hl_vertex.push_back(d->edges[id].source->position().y()-d->center_.y); + d->hl_vertex.push_back(d->edges[id].source->position().z()-d->center_.z); + + d->hl_vertex.push_back(d->edges[id].target->position().x()-d->center_.x); + d->hl_vertex.push_back(d->edges[id].target->position().y()-d->center_.y); + d->hl_vertex.push_back(d->edges[id].target->position().z()-d->center_.z); + + //fill buffers + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer); + d->program->bind(); + + vaos[S_Edges]->bind(); + buffers[S_Vertex].bind(); + buffers[S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[S_Vertex].release(); + vaos[S_Edges]->release(); + d->program->release(); + //draw + d->hl_type = Scene_edit_box_item_priv::EDGE; + break; + } + case 2: + { + //compute + push_xyz(d->hl_vertex, d->faces[id].vertices[0]->position(), d->center_); + push_xyz(d->hl_vertex, d->faces[id].vertices[3]->position(), d->center_); + push_xyz(d->hl_vertex, d->faces[id].vertices[2]->position(), d->center_); + + push_xyz(d->hl_vertex, d->faces[id].vertices[0]->position(), d->center_); + push_xyz(d->hl_vertex, d->faces[id].vertices[2]->position(), d->center_); + push_xyz(d->hl_vertex, d->faces[id].vertices[1]->position(), d->center_); + + for( int j=0; j<6; ++j) + { + push_normal(d->hl_normal, id); + } + //fill buffers + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITH_LIGHT, viewer); + attribBuffers(viewer, Scene_edit_box_item::PROGRAM_WITH_LIGHT); + + d->program->bind(); + vaos[S_Faces]->bind(); + buffers[S_Vertex].bind(); + buffers[S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + buffers[S_Normal].release(); + + buffers[S_Normal].bind(); + buffers[S_Normal].allocate(d->hl_normal.data(), + static_cast(d->hl_normal.size()*sizeof(float))); + d->program->enableAttributeArray("normals"); + d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); + buffers[S_Normal].release(); + vaos[S_Faces]->release(); + d->program->release(); + + //draw + d->hl_type = Scene_edit_box_item_priv::FACE; + break; + } + default: + d->hl_type = Scene_edit_box_item_priv::NO_TYPE; + break; + } } - else - { - Q_EMIT clearHL(); - } - is_ready_to_highlight = false; - }*/ + itemChanged(); + + d->ready_to_hl = false; } void Scene_edit_box_item_priv::reset_selection() @@ -745,30 +874,15 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *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); - //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])) + //pick + int type, picked; + d->picked_pixel = e->pos(); + d->picking(type, picked, v_i); + if(type !=-1) { - d->selection_on = true; bool found = false; - qglviewer::Vec pos = viewer->camera()->pointUnderPixel(e->pos(), found); + qglviewer::Vec pos = viewer->camera()->pointUnderPixel(d->picked_pixel, found); if(found) { d->rf_last_pos = pos; @@ -777,51 +891,38 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) for(int i=0; i<8; ++i) for(int j=0; j<3; ++j) d->last_pool[i][j] = d->vertices[i][j]; - - 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) + d->selection_on = true; + if(type == 0) { - if(picked <8) - { - d->selected_vertices.push_back(&d->vertices[picked]); - d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - d->remodel_frame->setConstraint(&d->constraint); - } + d->selected_vertices.push_back(&d->vertices[picked]); + d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + d->remodel_frame->setConstraint(&d->constraint); } - else if(buffer[1] > 0) + else if(type == 1) { - if(picked <12) - { - d->selected_vertices.push_back(d->edges[picked].source); - d->selected_vertices.push_back(d->edges[picked].target); - Kernel::Point_3 s(d->edges[picked].source->position()), t(d->edges[picked].target->position()); + d->selected_vertices.push_back(d->edges[picked].source); + d->selected_vertices.push_back(d->edges[picked].target); + Kernel::Point_3 s(d->edges[picked].source->position()), t(d->edges[picked].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); - } + 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) + else if(type == 2) { - if(picked <6) - { - for(int i=0; i<4; ++i) - d->selected_vertices.push_back(d->faces[picked].vertices[i]); - Kernel::Point_3 a1(d->faces[picked].vertices[1]->position()), a0(d->faces[picked].vertices[0]->position()) - ,a3(d->faces[picked].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,b); + for(int i=0; i<4; ++i) + d->selected_vertices.push_back(d->faces[picked].vertices[i]); + Kernel::Point_3 a1(d->faces[picked].vertices[1]->position()), a0(d->faces[picked].vertices[0]->position()) + ,a3(d->faces[picked].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,b); - d->remodel_frame->setConstraint(&d->constraint); - d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); - d->constraint.setTranslationConstraintDirection(qglviewer::Vec(n.x(), n.y(), n.z())); - } + d->remodel_frame->setConstraint(&d->constraint); + d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); + d->constraint.setTranslationConstraintDirection(qglviewer::Vec(n.x(), n.y(), n.z())); } - viewer->setBackgroundColor(bgColor); - fbo->release(); + viewer->setManipulatedFrame(d->remodel_frame); viewer->setMouseBinding( Qt::ShiftModifier, @@ -833,7 +934,6 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) { d->reset_selection(); } - delete fbo; } return false; } @@ -845,17 +945,20 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) if(d->selection_on) { d->remodel_frame->setOrientation(d->frame->orientation()); - qglviewer::Vec sd(d->remodel_frame->position() - d->rf_last_pos); qglviewer::Vec td(d->remodel_frame->transformOf(d->remodel_frame->position() - d->rf_last_pos)); QVector3D dir(td.x, td.y, td.z); d->remodel_box(dir); - return false; } } else if(d->selection_on) { d->reset_selection(); } + + d->ready_to_hl= true; + d->picked_pixel = e->pos(); + QTimer::singleShot(0, this, SLOT(highlight())); + return false; } else if(event->type() == QEvent::MouseButtonRelease) { @@ -921,7 +1024,6 @@ void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) { qglviewer::AxisPlaneConstraint::Type prev_cons = constraint.translationConstraintType(); constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - Q_FOREACH(Scene_edit_box_item::vertex* selected_vertex, selected_vertices ) { int id = selected_vertex->id; @@ -1015,3 +1117,129 @@ double Scene_edit_box_item_priv::applyZ(int id, double z, double dirz) } return 0; } + +//type : 0 = vertex, 1 = edge, 2 = face +void Scene_edit_box_item_priv::picking(int& type, int& id, Viewer_interface *viewer) +{ + type = -1; + id = -1; + 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); + draw_picking(viewer); + + 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(picked_pixel.x(), deviceHeight-1-picked_pixel.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])) + { + int r(std::ceil((buffer[0]-10)/20)), g(std::ceil((buffer[1]-10)/20)), b(std::ceil((buffer[2]-10)/20)); + id = (std::max)(r,g); + id = (std::max)(id,b); + if(buffer[0] > 0) + { + if(id <8) + type = 0 ; + } + else if(buffer[1] > 0) + { + if(id <12) + { + type = 1; + } + } + else if(buffer[2] > 0) + { + if(id <6) + { + type = 2; + } + } + } + viewer->setBackgroundColor(bgColor); + fbo->release(); + delete fbo; +} + +void Scene_edit_box_item::drawHl(Viewer_interface* viewer)const +{ + GLfloat offset_factor; + GLfloat offset_units; + QMatrix4x4 f_matrix; + for (int i=0; i<16; ++i){ + f_matrix.data()[i] = (float)d->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(d->hl_type == Scene_edit_box_item_priv::VERTEX) + { + vaos[Scene_edit_box_item_priv::S_Spheres]->bind(); + attribBuffers(viewer, PROGRAM_SPHERES); + d->program = getShaderProgram(PROGRAM_SPHERES, viewer); + d->program->bind(); + d->program->setUniformValue("mvp_matrix", mvp_mat); + d->program->setUniformValue("mv_matrix", mv_mat); + d->program->setUniformValue("light_pos", light_pos); + d->program->setAttributeValue("colors", QColor(Qt::yellow)); + d->program->setAttributeValue("radius",1); + viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, + static_cast(d->vertex_spheres.size()/3), + static_cast(d->hl_vertex.size()/3)); + + d->program->release(); + vaos[Scene_edit_box_item_priv::S_Spheres]->release(); + } + else if(d->hl_type == Scene_edit_box_item_priv::EDGE) + { + vaos[S_Edges]->bind(); + viewer->glLineWidth(4.0f); + d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); + attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); + d->program->bind(); + d->program->setUniformValue("f_matrix", f_matrix); + d->program->setAttributeValue("colors", QColor(Qt::yellow)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(d->hl_vertex.size()/3)); + viewer->glLineWidth(1.0f); + vaos[S_Edges]->release(); + d->program->release(); + } + else if(d->hl_type == Scene_edit_box_item_priv::FACE) + { + viewer->glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &offset_factor); + viewer->glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); + glPolygonOffset(0.5f, 0.9f); + vaos[Scene_edit_box_item_priv::S_Faces]->bind(); + d->program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); + attribBuffers(viewer, PROGRAM_WITH_LIGHT); + d->program->bind(); + d->program->setUniformValue("mvp_matrix", mvp_mat); + d->program->setUniformValue("mv_matrix", mv_mat); + d->program->setUniformValue("light_pos", light_pos); + d->program->setAttributeValue("colors", QColor(Qt::yellow)); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(d->hl_vertex.size()/3)); + vaos[Scene_edit_box_item_priv::S_Faces]->release(); + d->program->release(); + glPolygonOffset(offset_factor, offset_units); + } +} diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h index 10cd7f9d01f..6d47bb86f8b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -38,6 +38,8 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item ColorsFaces, VertexArrow, NormalArrow, + S_Vertex, + S_Normal, NumberOfVbos }; Scene_edit_box_item(const CGAL::Three::Scene_interface* scene_interface); @@ -58,6 +60,7 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item // Indicate if rendering mode is supported bool supportsRenderingMode(RenderingMode m) const; void draw(CGAL::Three::Viewer_interface *) const; + void drawHl(CGAL::Three::Viewer_interface *) const; void drawEdges(CGAL::Three::Viewer_interface* viewer) const; void drawSpheres(CGAL::Three::Viewer_interface* viewer, const QMatrix4x4 f_matrix) const; void invalidateOpenGLBuffers() From 70f95d11eb3d359e3ee0e30c2227e92b418ea74c Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 24 Oct 2016 16:27:47 +0200 Subject: [PATCH 09/13] Add transparency for the faces. --- .../Plugins/PCA/Scene_edit_box_item.cpp | 377 +++++++++++------- 1 file changed, 240 insertions(+), 137 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 22d12233fb1..0416ecc5918 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -94,6 +94,7 @@ struct Scene_edit_box_item_priv{ frame->setPosition(center_); frame->setSpinningSensitivity(100.0); //forbid spinning constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); + constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); constraint.setRotationConstraintDirection(qglviewer::Vec(.0,.0,.1)); frame->setConstraint(&constraint); //create the sphere model @@ -207,8 +208,80 @@ struct Scene_edit_box_item_priv{ pick_sphere_program.addShaderFromSourceFile(QOpenGLShader::Fragment,":/cgal/Polyhedron_3/resources/shader_without_light.f"); pick_sphere_program.bindAttributeLocation("colors", 1); pick_sphere_program.link(); - } + + //Vertex source code + const char vertex_source[] = + { + "#version 120 \n " + "attribute highp vec4 vertex; " + "attribute highp vec3 normals; " + "attribute highp vec4 colors; " + "uniform highp mat4 mvp_matrix; " + "uniform highp mat4 mv_matrix; " + "varying highp vec4 fP; " + "varying highp vec3 fN; " + "varying highp vec4 color; " + "void main(void) " + "{ " + " color = colors; " + " fP = mv_matrix * vertex; " + " fN = mat3(mv_matrix)* normals; " + " gl_Position = mvp_matrix * vertex; " + "}\n " + "\n " + }; + + //Fragment source code + const char fragment_source[] = + { + "#version 120 \n" + "varying highp vec4 color;" + "varying highp vec4 fP; " + "varying highp vec3 fN; " + "uniform highp vec4 light_pos; " + "uniform highp vec4 light_diff; " + "uniform highp vec4 light_spec; " + "uniform highp vec4 light_amb; " + "uniform highp float spec_power ; " + "uniform int is_two_side; " + "uniform bool is_selected;" + "void main(void) {" + "highp vec3 L = light_pos.xyz - fP.xyz;" + "highp vec3 V = -fP.xyz;" + "highp vec3 N;" + "if(fN == highp vec3(0.0,0.0,0.0)) " + "N = highp vec3(0.0,0.0,0.0);" + "else " + "N = normalize(fN);" + "L = normalize(L);" + "V = normalize(V);" + "highp vec3 R = reflect(-L, N);" + "vec4 diffuse;" + "if(is_two_side == 1) " + "diffuse = abs(dot(N,L)) * light_diff * color;" + "else " + "diffuse = max(dot(N,L), 0.0) * light_diff * color;" + "highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec;" + "vec4 ret_color = vec4((color*light_amb).xyz + diffuse.xyz + specular.xyz,1);" + "if(is_selected) " + "gl_FragColor = vec4(ret_color.r+70.0/255.0, ret_color.g+70.0/255.0, ret_color.b+70.0/255.0, color.a);" + "else " + "gl_FragColor = vec4(ret_color.rgb, color.a); }\n" + "\n" + }; + transparent_face_program.addShaderFromSourceCode(QOpenGLShader::Vertex,vertex_source); + transparent_face_program.addShaderFromSourceCode(QOpenGLShader::Fragment,fragment_source); + transparent_face_program.bindAttributeLocation("colors", 1); + transparent_face_program.link(); + reset_selection(); + last_picked_id = -1; + last_picked_type = -1; + } + ~Scene_edit_box_item_priv(){ + delete frame; + delete remodel_frame; + } mutable std::vector vertex_edges; mutable std::vector color_edges; mutable std::vector vertex_spheres; @@ -237,6 +310,7 @@ struct Scene_edit_box_item_priv{ qglviewer::Vec relative_center_; mutable QOpenGLShaderProgram pick_sphere_program; + mutable QOpenGLShaderProgram transparent_face_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]; @@ -260,6 +334,9 @@ struct Scene_edit_box_item_priv{ Scene_edit_box_item* item; QPoint picked_pixel; HL_Primitive hl_type; + int last_picked_id; + int last_picked_type; + }; @@ -302,7 +379,7 @@ void Scene_edit_box_item::drawSpheres(Viewer_interface *viewer, const QMatrix4x4 d->program->setUniformValue("mvp_matrix", mvp_mat); d->program->setUniformValue("mv_matrix", mv_mat); d->program->setUniformValue("light_pos", light_pos); - d->program->setAttributeValue("radius",1); + d->program->setAttributeValue("radius",2); d->program->setAttributeValue("colors", QColor(Qt::red)); viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, static_cast(d->vertex_spheres.size()/3), @@ -335,20 +412,29 @@ void Scene_edit_box_item::draw(Viewer_interface *viewer) const mv_mat = mv_mat*f_matrix; QVector4D light_pos(0.0f,0.0f,1.0f, 1.0f ); light_pos = light_pos*f_matrix; + QVector4D ambient(0.4f, 0.4f, 0.4f, 0.4f); + // Diffuse + QVector4D diffuse(1.0f, 1.0f, 1.0f, 1.0f); + // Specular + QVector4D specular(0.0f, 0.0f, 0.0f, 1.0f); - + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); vaos[Scene_edit_box_item_priv::Faces]->bind(); - d->program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); - attribBuffers(viewer, PROGRAM_WITH_LIGHT); + d->program = &d->transparent_face_program; d->program->bind(); d->program->setUniformValue("mvp_matrix", mvp_mat); d->program->setUniformValue("mv_matrix", mv_mat); d->program->setUniformValue("light_pos", light_pos); - d->program->setAttributeValue("colors", QColor(this->color())); + d->program->setUniformValue("light_diff",diffuse); + d->program->setUniformValue("light_spec", specular); + d->program->setUniformValue("light_amb", ambient); + d->program->setUniformValue("spec_power", 51.8f); + d->program->setAttributeValue("colors", QColor(128,128,128,128)); viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(d->vertex_faces.size()/3)); vaos[Scene_edit_box_item_priv::Faces]->release(); d->program->release(); - + glDisable(GL_BLEND); drawSpheres(viewer, f_matrix); } @@ -364,7 +450,7 @@ void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const f_matrix.data()[i] = (float)d->frame->matrix()[i]; } vaos[Edges]->bind(); - viewer->glLineWidth(4.0f); + viewer->glLineWidth(6.0f); d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); d->program->bind(); @@ -488,7 +574,7 @@ Scene_edit_box_item_priv::initializeBuffers(Viewer_interface *viewer)const item->buffers[CenterSpheres].release(); pick_sphere_program.disableAttributeArray("radius"); - pick_sphere_program.setAttributeValue("radius",1); + pick_sphere_program.setAttributeValue("radius",2); item->buffers[ColorsSpheres].bind(); item->buffers[ColorsSpheres].allocate(color_spheres.data(), @@ -724,134 +810,139 @@ double Scene_edit_box_item::point(short i, short j) const void Scene_edit_box_item::highlight() { - // highlight with mouse move event - d->ready_to_hl = true; - Viewer_interface* viewer = dynamic_cast(*QGLViewer::QGLViewerPool().begin()); - int type, id; - //pick + // highlight with mouse move event + d->ready_to_hl = true; + Viewer_interface* viewer = dynamic_cast(*QGLViewer::QGLViewerPool().begin()); + int type, id; + //pick + if(!d->selection_on) + { d->picking(type, id, viewer); - //highlight - d->hl_normal.clear(); - d->hl_vertex.clear(); - if(type !=-1) + d->last_picked_id = id; + d->last_picked_type = type; + } + //highlight + d->hl_normal.clear(); + d->hl_vertex.clear(); + if(type !=-1) + { + switch(d->last_picked_type) { - switch(type) - { - case 0: - { - //compute - d->hl_vertex.push_back(d->vertices[id].position().x()-d->center_.x); - d->hl_vertex.push_back(d->vertices[id].position().y()-d->center_.y); - d->hl_vertex.push_back(d->vertices[id].position().z()-d->center_.z); - //fill buffers - d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_SPHERES, viewer); - d->program->bind(); + case 0: + { + //compute + d->hl_vertex.push_back(d->vertices[d->last_picked_id].position().x()-d->center_.x); + d->hl_vertex.push_back(d->vertices[d->last_picked_id].position().y()-d->center_.y); + d->hl_vertex.push_back(d->vertices[d->last_picked_id].position().z()-d->center_.z); + //fill buffers + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_SPHERES, viewer); + d->program->bind(); - vaos[S_Spheres]->bind(); - buffers[VertexSpheres].bind(); - buffers[VertexSpheres].allocate(d->vertex_spheres.data(), - static_cast(d->vertex_spheres.size()*sizeof(float))); - d->program->enableAttributeArray("vertex"); - d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); - buffers[VertexSpheres].release(); + vaos[S_Spheres]->bind(); + buffers[VertexSpheres].bind(); + buffers[VertexSpheres].allocate(d->vertex_spheres.data(), + static_cast(d->vertex_spheres.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + buffers[VertexSpheres].release(); - buffers[NormalSpheres].bind(); - buffers[NormalSpheres].allocate(d->normal_spheres.data(), - static_cast(d->normal_spheres.size()*sizeof(float))); - d->program->enableAttributeArray("normals"); - d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); - buffers[NormalSpheres].release(); + buffers[NormalSpheres].bind(); + buffers[NormalSpheres].allocate(d->normal_spheres.data(), + static_cast(d->normal_spheres.size()*sizeof(float))); + d->program->enableAttributeArray("normals"); + d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); + buffers[NormalSpheres].release(); - buffers[S_Vertex].bind(); - buffers[S_Vertex].allocate(d->hl_vertex.data(), - static_cast(d->hl_vertex.size()*sizeof(float))); - d->program->enableAttributeArray("center"); - d->program->setAttributeBuffer("center", GL_FLOAT, 0, 3); - buffers[S_Vertex].release(); - d->program->disableAttributeArray("colors"); + buffers[S_Vertex].bind(); + buffers[S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("center"); + d->program->setAttributeBuffer("center", GL_FLOAT, 0, 3); + buffers[S_Vertex].release(); + d->program->disableAttributeArray("colors"); - viewer->glVertexAttribDivisor(d->program->attributeLocation("center"), 1); - d->program->release(); - vaos[S_Spheres]->release(); - //draw - d->hl_type = Scene_edit_box_item_priv::VERTEX; - break; - } - case 1: - { - //compute - d->hl_vertex.push_back(d->edges[id].source->position().x()-d->center_.x); - d->hl_vertex.push_back(d->edges[id].source->position().y()-d->center_.y); - d->hl_vertex.push_back(d->edges[id].source->position().z()-d->center_.z); - - d->hl_vertex.push_back(d->edges[id].target->position().x()-d->center_.x); - d->hl_vertex.push_back(d->edges[id].target->position().y()-d->center_.y); - d->hl_vertex.push_back(d->edges[id].target->position().z()-d->center_.z); - - //fill buffers - d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer); - d->program->bind(); - - vaos[S_Edges]->bind(); - buffers[S_Vertex].bind(); - buffers[S_Vertex].allocate(d->hl_vertex.data(), - static_cast(d->hl_vertex.size()*sizeof(float))); - d->program->enableAttributeArray("vertex"); - d->program->setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[S_Vertex].release(); - vaos[S_Edges]->release(); - d->program->release(); - //draw - d->hl_type = Scene_edit_box_item_priv::EDGE; - break; - } - case 2: - { - //compute - push_xyz(d->hl_vertex, d->faces[id].vertices[0]->position(), d->center_); - push_xyz(d->hl_vertex, d->faces[id].vertices[3]->position(), d->center_); - push_xyz(d->hl_vertex, d->faces[id].vertices[2]->position(), d->center_); - - push_xyz(d->hl_vertex, d->faces[id].vertices[0]->position(), d->center_); - push_xyz(d->hl_vertex, d->faces[id].vertices[2]->position(), d->center_); - push_xyz(d->hl_vertex, d->faces[id].vertices[1]->position(), d->center_); - - for( int j=0; j<6; ++j) - { - push_normal(d->hl_normal, id); - } - //fill buffers - d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITH_LIGHT, viewer); - attribBuffers(viewer, Scene_edit_box_item::PROGRAM_WITH_LIGHT); - - d->program->bind(); - vaos[S_Faces]->bind(); - buffers[S_Vertex].bind(); - buffers[S_Vertex].allocate(d->hl_vertex.data(), - static_cast(d->hl_vertex.size()*sizeof(float))); - d->program->enableAttributeArray("vertex"); - d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); - buffers[S_Normal].release(); - - buffers[S_Normal].bind(); - buffers[S_Normal].allocate(d->hl_normal.data(), - static_cast(d->hl_normal.size()*sizeof(float))); - d->program->enableAttributeArray("normals"); - d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); - buffers[S_Normal].release(); - vaos[S_Faces]->release(); - d->program->release(); - - //draw - d->hl_type = Scene_edit_box_item_priv::FACE; - break; - } - default: - d->hl_type = Scene_edit_box_item_priv::NO_TYPE; - break; - } + viewer->glVertexAttribDivisor(d->program->attributeLocation("center"), 1); + d->program->release(); + vaos[S_Spheres]->release(); + //draw + d->hl_type = Scene_edit_box_item_priv::VERTEX; + break; } - itemChanged(); + case 1: + { + //compute + d->hl_vertex.push_back(d->edges[d->last_picked_id].source->position().x()-d->center_.x); + d->hl_vertex.push_back(d->edges[d->last_picked_id].source->position().y()-d->center_.y); + d->hl_vertex.push_back(d->edges[d->last_picked_id].source->position().z()-d->center_.z); + + d->hl_vertex.push_back(d->edges[d->last_picked_id].target->position().x()-d->center_.x); + d->hl_vertex.push_back(d->edges[d->last_picked_id].target->position().y()-d->center_.y); + d->hl_vertex.push_back(d->edges[d->last_picked_id].target->position().z()-d->center_.z); + + //fill buffers + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer); + d->program->bind(); + + vaos[S_Edges]->bind(); + buffers[S_Vertex].bind(); + buffers[S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[S_Vertex].release(); + vaos[S_Edges]->release(); + d->program->release(); + //draw + d->hl_type = Scene_edit_box_item_priv::EDGE; + break; + } + case 2: + { + //compute + push_xyz(d->hl_vertex, d->faces[d->last_picked_id].vertices[0]->position(), d->center_); + push_xyz(d->hl_vertex, d->faces[d->last_picked_id].vertices[3]->position(), d->center_); + push_xyz(d->hl_vertex, d->faces[d->last_picked_id].vertices[2]->position(), d->center_); + + push_xyz(d->hl_vertex, d->faces[d->last_picked_id].vertices[0]->position(), d->center_); + push_xyz(d->hl_vertex, d->faces[d->last_picked_id].vertices[2]->position(), d->center_); + push_xyz(d->hl_vertex, d->faces[d->last_picked_id].vertices[1]->position(), d->center_); + + for( int j=0; j<6; ++j) + { + push_normal(d->hl_normal, d->last_picked_id); + } + //fill buffers + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITH_LIGHT, viewer); + attribBuffers(viewer, Scene_edit_box_item::PROGRAM_WITH_LIGHT); + + d->program->bind(); + vaos[S_Faces]->bind(); + buffers[S_Vertex].bind(); + buffers[S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + buffers[S_Normal].release(); + + buffers[S_Normal].bind(); + buffers[S_Normal].allocate(d->hl_normal.data(), + static_cast(d->hl_normal.size()*sizeof(float))); + d->program->enableAttributeArray("normals"); + d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); + buffers[S_Normal].release(); + vaos[S_Faces]->release(); + d->program->release(); + + //draw + d->hl_type = Scene_edit_box_item_priv::FACE; + break; + } + default: + d->hl_type = Scene_edit_box_item_priv::NO_TYPE; + break; + } + } + itemChanged(); d->ready_to_hl = false; } @@ -1009,7 +1100,7 @@ void Scene_edit_box_item_priv::draw_picking(Viewer_interface* viewer) item->vaos[P_Spheres]->release(); item->vaos[P_Edges]->bind(); - viewer->glLineWidth(4.0f); + viewer->glLineWidth(6.0f); program = item->getShaderProgram(Scene_item::PROGRAM_WITHOUT_LIGHT); item->attribBuffers(viewer, Scene_item::PROGRAM_WITHOUT_LIGHT); program->bind(); @@ -1165,6 +1256,7 @@ void Scene_edit_box_item_priv::picking(int& type, int& id, Viewer_interface *vie } } } + delete buffer; viewer->setBackgroundColor(bgColor); fbo->release(); delete fbo; @@ -1191,6 +1283,11 @@ void Scene_edit_box_item::drawHl(Viewer_interface* viewer)const mv_mat = mv_mat*f_matrix; QVector4D light_pos(0.0f,0.0f,1.0f, 1.0f ); light_pos = light_pos*f_matrix; + QVector4D ambient(0.4f, 0.4f, 0.4f, 0.4f); + // Diffuse + QVector4D diffuse(1.0f, 1.0f, 1.0f, 1.0f); + // Specular + QVector4D specular(0.0f, 0.0f, 0.0f, 1.0f); if(d->hl_type == Scene_edit_box_item_priv::VERTEX) { @@ -1202,7 +1299,7 @@ void Scene_edit_box_item::drawHl(Viewer_interface* viewer)const d->program->setUniformValue("mv_matrix", mv_mat); d->program->setUniformValue("light_pos", light_pos); d->program->setAttributeValue("colors", QColor(Qt::yellow)); - d->program->setAttributeValue("radius",1); + d->program->setAttributeValue("radius",2); viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, static_cast(d->vertex_spheres.size()/3), static_cast(d->hl_vertex.size()/3)); @@ -1213,7 +1310,7 @@ void Scene_edit_box_item::drawHl(Viewer_interface* viewer)const else if(d->hl_type == Scene_edit_box_item_priv::EDGE) { vaos[S_Edges]->bind(); - viewer->glLineWidth(4.0f); + viewer->glLineWidth(6.0f); d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); d->program->bind(); @@ -1228,18 +1325,24 @@ void Scene_edit_box_item::drawHl(Viewer_interface* viewer)const { viewer->glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &offset_factor); viewer->glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); - glPolygonOffset(0.5f, 0.9f); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); vaos[Scene_edit_box_item_priv::S_Faces]->bind(); - d->program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); - attribBuffers(viewer, PROGRAM_WITH_LIGHT); + d->program = &d->transparent_face_program; d->program->bind(); d->program->setUniformValue("mvp_matrix", mvp_mat); d->program->setUniformValue("mv_matrix", mv_mat); d->program->setUniformValue("light_pos", light_pos); - d->program->setAttributeValue("colors", QColor(Qt::yellow)); + d->program->setUniformValue("light_diff",diffuse); + d->program->setUniformValue("light_spec", specular); + d->program->setUniformValue("light_amb", ambient); + d->program->setUniformValue("spec_power", 51.8f); + d->program->setAttributeValue("colors", QColor(128,128,0,128)); viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(d->hl_vertex.size()/3)); vaos[Scene_edit_box_item_priv::S_Faces]->release(); d->program->release(); glPolygonOffset(offset_factor, offset_units); + glDisable(GL_BLEND); + } } From aa79b95559814fae7d0e59743f1cf73bbeaaa448 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 24 Oct 2016 16:53:35 +0200 Subject: [PATCH 10/13] Clean-up. --- .../Plugins/PCA/Scene_edit_box_item.cpp | 67 +++++++++---------- .../Plugins/PCA/Scene_edit_box_item.h | 29 -------- 2 files changed, 32 insertions(+), 64 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 0416ecc5918..3b23f839358 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -48,7 +48,6 @@ struct Scene_edit_box_item_priv{ S_Edges, S_Spheres, S_Faces, - Arrow, P_Edges, P_Spheres, P_Faces, @@ -64,8 +63,6 @@ struct Scene_edit_box_item_priv{ VertexFaces, NormalFaces, ColorsFaces, - VertexArrow, - NormalArrow, S_Vertex, S_Normal, NumberOfVbos @@ -288,8 +285,6 @@ struct Scene_edit_box_item_priv{ mutable std::vector normal_spheres; mutable std::vector center_spheres; mutable std::vector color_spheres; - mutable std::vector vertex_arrow; - mutable std::vector normal_arrow; mutable std::vector vertex_faces; mutable std::vector normal_faces; mutable std::vector color_faces; @@ -341,7 +336,7 @@ struct Scene_edit_box_item_priv{ Scene_edit_box_item::Scene_edit_box_item(const Scene_interface *scene_interface) - : Scene_item(NumberOfVbos,NumberOfVaos) + : Scene_item(Scene_edit_box_item_priv::NumberOfVbos,Scene_edit_box_item_priv::NumberOfVaos) { d = new Scene_edit_box_item_priv(scene_interface, this); @@ -449,7 +444,7 @@ void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const for (int i=0; i<16; ++i){ f_matrix.data()[i] = (float)d->frame->matrix()[i]; } - vaos[Edges]->bind(); + vaos[Scene_edit_box_item_priv::Edges]->bind(); viewer->glLineWidth(6.0f); d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); @@ -458,7 +453,7 @@ void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const d->program->setAttributeValue("colors", QColor(Qt::black)); viewer->glDrawArrays(GL_LINES, 0, static_cast(d->vertex_edges.size()/3)); viewer->glLineWidth(1.0f); - vaos[Edges]->release(); + vaos[Scene_edit_box_item_priv::Edges]->release(); d->program->release(); if(renderingMode() == Wireframe) { @@ -810,7 +805,6 @@ double Scene_edit_box_item::point(short i, short j) const void Scene_edit_box_item::highlight() { - // highlight with mouse move event d->ready_to_hl = true; Viewer_interface* viewer = dynamic_cast(*QGLViewer::QGLViewerPool().begin()); int type, id; @@ -838,32 +832,32 @@ void Scene_edit_box_item::highlight() d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_SPHERES, viewer); d->program->bind(); - vaos[S_Spheres]->bind(); - buffers[VertexSpheres].bind(); - buffers[VertexSpheres].allocate(d->vertex_spheres.data(), + vaos[Scene_edit_box_item_priv::S_Spheres]->bind(); + buffers[Scene_edit_box_item_priv::VertexSpheres].bind(); + buffers[Scene_edit_box_item_priv::VertexSpheres].allocate(d->vertex_spheres.data(), static_cast(d->vertex_spheres.size()*sizeof(float))); d->program->enableAttributeArray("vertex"); d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); - buffers[VertexSpheres].release(); + buffers[Scene_edit_box_item_priv::VertexSpheres].release(); - buffers[NormalSpheres].bind(); - buffers[NormalSpheres].allocate(d->normal_spheres.data(), + buffers[Scene_edit_box_item_priv::NormalSpheres].bind(); + buffers[Scene_edit_box_item_priv::NormalSpheres].allocate(d->normal_spheres.data(), static_cast(d->normal_spheres.size()*sizeof(float))); d->program->enableAttributeArray("normals"); d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); - buffers[NormalSpheres].release(); + buffers[Scene_edit_box_item_priv::NormalSpheres].release(); - buffers[S_Vertex].bind(); - buffers[S_Vertex].allocate(d->hl_vertex.data(), + buffers[Scene_edit_box_item_priv::S_Vertex].bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].allocate(d->hl_vertex.data(), static_cast(d->hl_vertex.size()*sizeof(float))); d->program->enableAttributeArray("center"); d->program->setAttributeBuffer("center", GL_FLOAT, 0, 3); - buffers[S_Vertex].release(); + buffers[Scene_edit_box_item_priv::S_Vertex].release(); d->program->disableAttributeArray("colors"); viewer->glVertexAttribDivisor(d->program->attributeLocation("center"), 1); d->program->release(); - vaos[S_Spheres]->release(); + vaos[Scene_edit_box_item_priv::S_Spheres]->release(); //draw d->hl_type = Scene_edit_box_item_priv::VERTEX; break; @@ -883,14 +877,14 @@ void Scene_edit_box_item::highlight() d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer); d->program->bind(); - vaos[S_Edges]->bind(); - buffers[S_Vertex].bind(); - buffers[S_Vertex].allocate(d->hl_vertex.data(), + vaos[Scene_edit_box_item_priv::S_Edges]->bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].allocate(d->hl_vertex.data(), static_cast(d->hl_vertex.size()*sizeof(float))); d->program->enableAttributeArray("vertex"); d->program->setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[S_Vertex].release(); - vaos[S_Edges]->release(); + buffers[Scene_edit_box_item_priv::S_Vertex].release(); + vaos[Scene_edit_box_item_priv::S_Edges]->release(); d->program->release(); //draw d->hl_type = Scene_edit_box_item_priv::EDGE; @@ -916,21 +910,21 @@ void Scene_edit_box_item::highlight() attribBuffers(viewer, Scene_edit_box_item::PROGRAM_WITH_LIGHT); d->program->bind(); - vaos[S_Faces]->bind(); - buffers[S_Vertex].bind(); - buffers[S_Vertex].allocate(d->hl_vertex.data(), + vaos[Scene_edit_box_item_priv::S_Faces]->bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].allocate(d->hl_vertex.data(), static_cast(d->hl_vertex.size()*sizeof(float))); d->program->enableAttributeArray("vertex"); d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); - buffers[S_Normal].release(); + buffers[Scene_edit_box_item_priv::S_Normal].release(); - buffers[S_Normal].bind(); - buffers[S_Normal].allocate(d->hl_normal.data(), + buffers[Scene_edit_box_item_priv::S_Normal].bind(); + buffers[Scene_edit_box_item_priv::S_Normal].allocate(d->hl_normal.data(), static_cast(d->hl_normal.size()*sizeof(float))); d->program->enableAttributeArray("normals"); d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); - buffers[S_Normal].release(); - vaos[S_Faces]->release(); + buffers[Scene_edit_box_item_priv::S_Normal].release(); + vaos[Scene_edit_box_item_priv::S_Faces]->release(); d->program->release(); //draw @@ -956,6 +950,7 @@ void Scene_edit_box_item_priv::reset_selection() constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); selected_vertices.clear(); } + //intercept events for picking bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) { @@ -973,6 +968,7 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) if(type !=-1) { bool found = false; + QApplication::setOverrideCursor(Qt::DragMoveCursor); qglviewer::Vec pos = viewer->camera()->pointUnderPixel(d->picked_pixel, found); if(found) { @@ -1054,6 +1050,7 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) else if(event->type() == QEvent::MouseButtonRelease) { d->reset_selection(); + QApplication::restoreOverrideCursor(); } return false; } @@ -1309,7 +1306,7 @@ void Scene_edit_box_item::drawHl(Viewer_interface* viewer)const } else if(d->hl_type == Scene_edit_box_item_priv::EDGE) { - vaos[S_Edges]->bind(); + vaos[Scene_edit_box_item_priv::S_Edges]->bind(); viewer->glLineWidth(6.0f); d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attribBuffers(viewer, PROGRAM_WITHOUT_LIGHT); @@ -1318,7 +1315,7 @@ void Scene_edit_box_item::drawHl(Viewer_interface* viewer)const d->program->setAttributeValue("colors", QColor(Qt::yellow)); viewer->glDrawArrays(GL_LINES, 0, static_cast(d->hl_vertex.size()/3)); viewer->glLineWidth(1.0f); - vaos[S_Edges]->release(); + vaos[Scene_edit_box_item_priv::S_Edges]->release(); d->program->release(); } else if(d->hl_type == Scene_edit_box_item_priv::FACE) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h index 6d47bb86f8b..83a4e70f99a 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -13,35 +13,6 @@ class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item struct vertex; struct edge; struct face; - enum VAOs{ - Edges = 0, - Spheres, - Faces, - S_Edges, - S_Spheres, - S_Faces, - Arrow, - P_Edges, - P_Spheres, - P_Faces, - NumberOfVaos - }; - enum VBOs{ - VertexEdges = 0, - ColorsEdges, - VertexSpheres, - NormalSpheres, - CenterSpheres, - ColorsSpheres, - VertexFaces, - NormalFaces, - ColorsFaces, - VertexArrow, - NormalArrow, - S_Vertex, - S_Normal, - NumberOfVbos - }; Scene_edit_box_item(const CGAL::Three::Scene_interface* scene_interface); ~Scene_edit_box_item(); bool isFinite() const { return true; } From 2ac90fc5d335a409bb3aee815de57b0d2b3ae83e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 28 Oct 2016 14:34:03 +0200 Subject: [PATCH 11/13] Add the missing file --- .../Plugins/PCA/Edit_box_plugin.cpp | 135 ++++++++++++++++++ .../Plugins/PCA/Scene_edit_box_item.cpp | 3 - 2 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 Polyhedron/demo/Polyhedron/Plugins/PCA/Edit_box_plugin.cpp diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Edit_box_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Edit_box_plugin.cpp new file mode 100644 index 00000000000..782bc9a50b6 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Edit_box_plugin.cpp @@ -0,0 +1,135 @@ +#include + +#include +#include +#include "Scene_edit_box_item.h" +#include "Scene_polyhedron_item.h" +#include +#include +#include +#include +#include + + +#include +#include +using namespace CGAL::Three; +class Edit_box_plugin : + public QObject, + public Polyhedron_demo_plugin_interface +{ + Q_OBJECT + 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*); + QList actions() const { + return QList() << actionBbox + << actionExport; + } + + bool applicable(QAction* a) const { + if(a==actionBbox &&scene->numberOfEntries() > 0) + return true; + else if(a==actionExport ) + { + for(int i = 0, end = scene->numberOfEntries(); + i < end; ++i) + { + if(qobject_cast(scene->item(i))) + { + return true; + } + } + } + return false;} +public Q_SLOTS: + + void bbox(); + void enableAction(); + void exportToPoly(); + +private: + CGAL::Three::Scene_interface* scene; + QAction* actionBbox; + QAction* actionExport; + + +}; // end Edit_box_plugin + +void Edit_box_plugin::init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) +{ + scene = scene_interface; + actionBbox = new QAction(tr("Create Bbox"), mainWindow); + connect(actionBbox, SIGNAL(triggered()), + this, SLOT(bbox())); + actionExport = new QAction(tr("Export to Polyhedron item"), mainWindow); + connect(actionExport, SIGNAL(triggered()), + this, SLOT(exportToPoly())); +} + +void Edit_box_plugin::bbox() +{ + for(int i = 0, end = scene->numberOfEntries(); + i < end; ++i) + { + if(qobject_cast(scene->item(i))) + return; + } + QApplication::setOverrideCursor(Qt::WaitCursor); + Scene_edit_box_item* item = new Scene_edit_box_item(scene); + connect(item, SIGNAL(destroyed()), + this, SLOT(enableAction())); + item->setName("Edit box"); + item->setRenderingMode(FlatPlusEdges); + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + viewer->installEventFilter(item); + scene->addItem(item); + actionBbox->setEnabled(false); + + QApplication::restoreOverrideCursor(); +} + +void Edit_box_plugin::enableAction() { + actionBbox->setEnabled(true); +} + +void Edit_box_plugin::exportToPoly() +{ + int id =0; + Scene_edit_box_item* item = NULL; + for(int i = 0, end = scene->numberOfEntries(); + i < end; ++i) + { + item = qobject_cast(scene->item(i)); + if(item) + { + id = i; + break; + } + } + Polyhedron::Point_3 points[8]; + for(int i=0; i<8; ++i) + { + points[i] = Polyhedron::Point_3(item->point(i,0),item->point(i,1), item->point(i,2)); + } + Scene_polyhedron_item* poly_item = new Scene_polyhedron_item(); + CGAL::make_hexahedron( + points[0], + points[1], + points[2], + points[3], + points[4], + points[5], + points[6], + points[7], + *poly_item->polyhedron()); + CGAL::Polygon_mesh_processing::triangulate_faces(*poly_item->polyhedron()); + item->setName("Edit box"); + item->setRenderingMode(FlatPlusEdges); + scene->replaceItem(id, poly_item, true); + item->deleteLater(); + actionBbox->setEnabled(true); +} +#include "Edit_box_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 3b23f839358..d118dd702e4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -680,7 +680,6 @@ void push_normal(std::vector &v, int id) void Scene_edit_box_item_priv::computeElements() const { - QApplication::setOverrideCursor(Qt::WaitCursor); vertex_edges.clear(); vertex_faces.clear(); normal_faces.clear(); @@ -768,8 +767,6 @@ void Scene_edit_box_item_priv::computeElements() const color_spheres.push_back(0); color_spheres.push_back(0); } - - QApplication::restoreOverrideCursor(); } Scene_edit_box_item::~Scene_edit_box_item() From 7814689e4825d95c46a89b7e145c8a2adc7c5294 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 2 Nov 2016 11:31:47 +0100 Subject: [PATCH 12/13] Fix warnings and MSVC bug --- .../Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp | 4 ++-- .../demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h | 3 ++- .../Plugins/PCA/Scene_edit_box_item_config.h | 10 ++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item_config.h diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index d118dd702e4..1eda577b641 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -804,7 +804,7 @@ void Scene_edit_box_item::highlight() { d->ready_to_hl = true; Viewer_interface* viewer = dynamic_cast(*QGLViewer::QGLViewerPool().begin()); - int type, id; + int type = -1, id = -1; //pick if(!d->selection_on) { @@ -1250,7 +1250,7 @@ void Scene_edit_box_item_priv::picking(int& type, int& id, Viewer_interface *vie } } } - delete buffer; + delete[] buffer; viewer->setBackgroundColor(bgColor); fbo->release(); delete fbo; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h index 83a4e70f99a..a248ce210c9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -4,8 +4,9 @@ #include #include #include "create_sphere.h" +#include "Scene_edit_box_item_config.h" struct Scene_edit_box_item_priv; -class Q_DECL_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item +class SCENE_EDIT_BOX_ITEM_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_item { Q_OBJECT public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item_config.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item_config.h new file mode 100644 index 00000000000..b6f40b5ada8 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item_config.h @@ -0,0 +1,10 @@ +#ifndef SCENE_EDIT_BOX_ITEM_CONFIG_H +#define SCENE_EDIT_BOX_ITEM_CONFIG_H + +#ifdef scene_edit_box_item_EXPORTS +# define SCENE_EDIT_BOX_ITEM_EXPORT Q_DECL_EXPORT +#else +# define SCENE_EDIT_BOX_ITEM_EXPORT Q_DECL_IMPORT +#endif + +#endif // SCENE_EDIT_BOX_ITEM_CONFIG_H From 9b1342ea47177aaa028dcd633701cc07f3c69f9b Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 14 Nov 2016 12:01:24 +0100 Subject: [PATCH 13/13] enhancements: - Only highlight if shift is pressed - Use a special cursor when rotating the frame. --- .../Plugins/PCA/Scene_edit_box_item.cpp | 115 +++++++++++++++++- .../Plugins/PCA/Scene_edit_box_item.h | 1 + Polyhedron/demo/Polyhedron/Polyhedron_3.qrc | 3 + .../resources/rotate_around_cursor.png | Bin 0 -> 1242 bytes 4 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 Polyhedron/demo/Polyhedron/resources/rotate_around_cursor.png diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 1eda577b641..cec4aab31d2 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -5,6 +5,8 @@ #include #include #include +#include + using namespace CGAL::Three; struct Scene_edit_box_item::vertex{ int id; @@ -274,6 +276,8 @@ struct Scene_edit_box_item_priv{ reset_selection(); last_picked_id = -1; last_picked_type = -1; + QPixmap pix(":/cgal/cursors/resources/rotate_around_cursor.png"); + rotate_cursor = QCursor(pix); } ~Scene_edit_box_item_priv(){ delete frame; @@ -321,7 +325,6 @@ struct Scene_edit_box_item_priv{ void computeElements() const; void draw_picking(Viewer_interface*); void remodel_box(const QVector3D &dir); - double applyX(int id, double x, double dirx); double applyY(int id, double y, double diry); double applyZ(int id, double z, double dirz); @@ -331,6 +334,7 @@ struct Scene_edit_box_item_priv{ HL_Primitive hl_type; int last_picked_id; int last_picked_type; + QCursor rotate_cursor; }; @@ -938,6 +942,81 @@ void Scene_edit_box_item::highlight() d->ready_to_hl = false; } +void Scene_edit_box_item::clearHL() +{ + Viewer_interface* viewer = dynamic_cast(*QGLViewer::QGLViewerPool().begin()); + d->hl_normal.clear(); + d->hl_vertex.clear(); + + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_SPHERES, viewer); + d->program->bind(); + + vaos[Scene_edit_box_item_priv::S_Spheres]->bind(); + buffers[Scene_edit_box_item_priv::VertexSpheres].bind(); + buffers[Scene_edit_box_item_priv::VertexSpheres].allocate(d->vertex_spheres.data(), + static_cast(d->vertex_spheres.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + buffers[Scene_edit_box_item_priv::VertexSpheres].release(); + + buffers[Scene_edit_box_item_priv::NormalSpheres].bind(); + buffers[Scene_edit_box_item_priv::NormalSpheres].allocate(d->normal_spheres.data(), + static_cast(d->normal_spheres.size()*sizeof(float))); + d->program->enableAttributeArray("normals"); + d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); + buffers[Scene_edit_box_item_priv::NormalSpheres].release(); + + buffers[Scene_edit_box_item_priv::S_Vertex].bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("center"); + d->program->setAttributeBuffer("center", GL_FLOAT, 0, 3); + buffers[Scene_edit_box_item_priv::S_Vertex].release(); + d->program->disableAttributeArray("colors"); + + viewer->glVertexAttribDivisor(d->program->attributeLocation("center"), 1); + d->program->release(); + vaos[Scene_edit_box_item_priv::S_Spheres]->release(); + //draw + d->hl_type = Scene_edit_box_item_priv::VERTEX; + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITHOUT_LIGHT, viewer); + d->program->bind(); + + vaos[Scene_edit_box_item_priv::S_Edges]->bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[Scene_edit_box_item_priv::S_Vertex].release(); + vaos[Scene_edit_box_item_priv::S_Edges]->release(); + d->program->release(); + + d->program = getShaderProgram(Scene_edit_box_item::PROGRAM_WITH_LIGHT, viewer); + attribBuffers(viewer, Scene_edit_box_item::PROGRAM_WITH_LIGHT); + + d->program->bind(); + vaos[Scene_edit_box_item_priv::S_Faces]->bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].bind(); + buffers[Scene_edit_box_item_priv::S_Vertex].allocate(d->hl_vertex.data(), + static_cast(d->hl_vertex.size()*sizeof(float))); + d->program->enableAttributeArray("vertex"); + d->program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + buffers[Scene_edit_box_item_priv::S_Normal].release(); + + buffers[Scene_edit_box_item_priv::S_Normal].bind(); + buffers[Scene_edit_box_item_priv::S_Normal].allocate(d->hl_normal.data(), + static_cast(d->hl_normal.size()*sizeof(float))); + d->program->enableAttributeArray("normals"); + d->program->setAttributeBuffer("normals", GL_FLOAT, 0, 3); + buffers[Scene_edit_box_item_priv::S_Normal].release(); + vaos[Scene_edit_box_item_priv::S_Faces]->release(); + d->program->release(); + d->hl_type = Scene_edit_box_item_priv::NO_TYPE; + + itemChanged(); + +} void Scene_edit_box_item_priv::reset_selection() { selection_on = false; @@ -1033,21 +1112,47 @@ bool Scene_edit_box_item::eventFilter(QObject *, QEvent *event) QVector3D dir(td.x, td.y, td.z); d->remodel_box(dir); } + d->ready_to_hl= true; + d->picked_pixel = e->pos(); + QTimer::singleShot(0, this, SLOT(highlight())); + } + else if(e->modifiers() == Qt::ControlModifier && + e->buttons() == Qt::LeftButton) + { + QApplication::setOverrideCursor(d->rotate_cursor); } else if(d->selection_on) { d->reset_selection(); } - - d->ready_to_hl= true; d->picked_pixel = e->pos(); - QTimer::singleShot(0, this, SLOT(highlight())); return false; } else if(event->type() == QEvent::MouseButtonRelease) { d->reset_selection(); - QApplication::restoreOverrideCursor(); + QApplication::setOverrideCursor(QCursor()); + } + + else if(event->type() == QEvent::KeyPress) + { + QKeyEvent* e = static_cast(event); + if(e->key() == Qt::Key_Shift) + { + d->ready_to_hl= true; + QTimer::singleShot(0, this, SLOT(highlight())); + } + } + else if(event->type() == QEvent::KeyRelease) + { + QKeyEvent* e = static_cast(event); + if(e->key() == Qt::Key_Shift) + QTimer::singleShot(0, this, SLOT(clearHL())); + else if(e->key() == Qt::Key_Control) + { + + QApplication::setOverrideCursor(QCursor()); + } } return false; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h index a248ce210c9..84bc78fafb9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.h @@ -44,6 +44,7 @@ class SCENE_EDIT_BOX_ITEM_EXPORT Scene_edit_box_item: public CGAL::Three::Scene_ public Q_SLOTS: void highlight(); + void clearHL(); protected: friend struct Scene_edit_box_item_priv; Scene_edit_box_item_priv* d; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_3.qrc b/Polyhedron/demo/Polyhedron/Polyhedron_3.qrc index c53ecca8c40..cad520dff02 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_3.qrc +++ b/Polyhedron/demo/Polyhedron/Polyhedron_3.qrc @@ -47,4 +47,7 @@ resources/euler_facet.png resources/euler_vertex.png + + resources/rotate_around_cursor.png + diff --git a/Polyhedron/demo/Polyhedron/resources/rotate_around_cursor.png b/Polyhedron/demo/Polyhedron/resources/rotate_around_cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..b217433a936da97bf168625aee582f438f88cfb1 GIT binary patch literal 1242 zcmV<01SR{4P)K}A72>%)B57HNcSuVs4>eHa5p$k4K{L)HDEcB2pV*)J{Pxh~G{?ngY}^md%lTiv-}AeCf4^fOIc5edfC^jyt|^LgDJ3Q49aUA| zHy8}>DvELy$UHbWco+(W?gNq}Y%YW^OXT?^a#%?MfxAUTMJz2Xv9+~@-|t66Vm_Oj zn~^jBkVLZqvb(!0Cz;df3?|d{(e?m1kw8=kj!mRXz!e}hQ3k52PB%6-#w9Q_GZP_D zbo6{0a6dmkf92-Qn|}ijjYi{J339j!$mr;3ToP? z@bei$;Q++z^&U&W=ktl(Zr6pvnwy*J85B{9apItKD^Ycqo&T zlM)ODwRhv=;{u4mU{C<;M-!-{qeFlelgVUA)CG#7ybZkQ@9!58k>1{30RlZeJvxkA zw{E@iLTYO2(32-mbS}Dl`LY+d^9EIM+hj7m?Ca|jhr=O2+r^6)ebHWMZEe-UARdoL zTX_2PsQ}NDP?}#FjmGC@v-!7hh0Szzb!j+zdwZ`5L|a8gg#bS!NguMJ@~F0~tSpu; z=n15!rwj1$If&J@tgNh)352sV{XFC{Gc!|mc6M}FF`JQy1o)p!Ii{4%=LV=K@d;#S zXA=sAuAc+;4OLai$jFFKpuD^sp!^&N+$k(9jJY7|>+4!#JbU&`fSGe3Fx%bTtrI-0 z3LZUrq%8!4LCMR@dkK7zMDWjZa&r8kP)NgRX=%|2lmohE5mv*Y@Vxh?NoNJdBfa5> z27FCesbpwqNGFq3RaFA~7@l;`YAW!P!{HF0&!^o#I5_ya9h=Q&1Mp2{Wu@%z?`xZu zmzTw6vk7odRaMg&z%9UcHk(b>*4DIp_xJZB;FUU&0;IjYT|`78v2wXwQe0dtz+>P> z0^rwy$EBsEGCx1BbA5AjvzSb#KV!`rg;uL|dtzcjN5bRrNMmE8SS*&m!o%l>aezMp z9w>^k=yW<|b93{!nefwNTd37)mFeke-N8U0AS){?Qd3hCFq_Q>z&bDhbO6oa>1ows zu^d)cR|i*DS0xY#=~_1~@ArQXw4Ek~p8--=S0{^$i*i<5SXhvThK7jS zZ^!xQn05vD6_EP+dU3g2rv{#zn~Mhi1$ghQb!-AYi2ku`YHE^^kr8pb-Qx9nWn*JQ z+-|oF4-bpe>D2ZajmGA1HKZgzDiP3s0o7~}k~F^@uK)l507*qoM6N<$ Eg4Yo$^#A|> literal 0 HcmV?d00001