From c6c3115998f8a4def728d558a99b6e977ed4f8e4 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 21 Jun 2016 10:36:35 +0200 Subject: [PATCH 01/15] Enhancement - Implement the distance functions in the Cut plugin. --- .../Plugins/AABB_tree/Cut_plugin.cpp | 718 ++++++++++++++++-- .../demo/Polyhedron/Scene_plane_item.cpp | 36 +- Polyhedron/demo/Polyhedron/Scene_plane_item.h | 16 +- 3 files changed, 657 insertions(+), 113 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index b387cd8834e..15c84cbae78 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -3,16 +3,20 @@ #include #include +#include "../../AABB_tree/demo/AABB_tree/Color_ramp.h" #include "Messages_interface.h" #include "Scene_plane_item.h" #include "Scene_polyhedron_item.h" #include #include +#include +#include #include #include #include #include +#include #include #include @@ -25,19 +29,57 @@ #include #include #include -#include -//typedef CGAL::Simple_cartesian Epic_kernel; -typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; +#include +#include +const int slow_distance_grid_size = 100; +const int fast_distance_grid_size = 20; +class Texture{ +private: + int Width; + int Height; + int size; + GLubyte *data; +public: + Texture(int w, int h) + { + Width = w; + Height = h; + size = 3*Height*Width; + data = new GLubyte[Height*Width*3]; + } + int getWidth() const {return Width;} + int getHeight() const {return Height;} + int getSize() const {return size;} + void setData(int i, int j, int r, int g, int b){ + data[3*(Width*j+i) + 0] = r; + data[3*(Width*j+i) + 1] = g; + data[3*(Width*j+i) + 2] = b; + } + + GLubyte* getData(){return data; } + +}; +//typedef CGAL::Simple_cartesian Epic_kernel; +typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; + +typedef CGAL::AABB_face_graph_triangle_primitive Facet_primitive; +typedef CGAL::AABB_traits Facet_traits; +typedef CGAL::AABB_tree Facet_tree; + +typedef CGAL::AABB_halfedge_graph_segment_primitive Edge_primitive; +typedef CGAL::AABB_traits Edge_traits; +typedef CGAL::AABB_tree Edge_tree; + + +typedef QMap Facet_trees; +typedef QMap Edge_trees; -typedef CGAL::AABB_face_graph_triangle_primitive AABB_primitive; -typedef CGAL::AABB_traits AABB_traits; -typedef CGAL::AABB_tree AABB_tree; class Q_DECL_EXPORT Scene_aabb_item : public CGAL::Three::Scene_item { Q_OBJECT public: - Scene_aabb_item(const AABB_tree& tree_) : CGAL::Three::Scene_item(1,1), tree(tree_) + Scene_aabb_item(const Facet_tree& tree_) : CGAL::Three::Scene_item(1,1), tree(tree_) { positions_lines.resize(0); invalidateOpenGLBuffers(); @@ -90,7 +132,7 @@ public: compute_bbox(); } public: - const AABB_tree& tree; + const Facet_tree& tree; private: mutable std::vector positions_lines; @@ -119,7 +161,7 @@ private: { positions_lines.clear(); - CGAL::AABB_drawing_traits > traits; + CGAL::AABB_drawing_traits > traits; traits.v_edges = &positions_lines; tree.traversal(0, traits); @@ -262,6 +304,402 @@ private: }; // end class Scene_edges_item +class Q_DECL_EXPORT Scene_aabb_plane_item : public Scene_plane_item +{ +public: + + typedef Kernel::FT FT; + enum Cut_planes_types { + UNSIGNED_FACETS = 0, SIGNED_FACETS, UNSIGNED_EDGES, CUT_SEGMENTS + }; + Scene_aabb_plane_item(const CGAL::Three::Scene_interface* scene_interface) + :Scene_plane_item(scene_interface) + { + for(int i=0; icreate(); + } + for(int i=0; ifacet_trees = facet_trees; + } + + void set_edge_trees(Edge_trees edge_trees) + { + this->edge_trees = edge_trees; + } + void draw(CGAL::Three::Viewer_interface* viewer) const + { + if(!are_buffers_filled) + { + computeElements(); + initializeBuffers(viewer); + } + QMatrix4x4 fMatrix; + fMatrix.setToIdentity(); + for(int i=0; i< 16 ; i++) + fMatrix.data()[i] = frame->matrix()[i]; + + switch( m_cut_plane ) + { + case UNSIGNED_EDGES: + case UNSIGNED_FACETS: + case SIGNED_FACETS: + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureId); + + vaos[TexturedCutplane]->bind(); + program = getShaderProgram(PROGRAM_WITH_TEXTURE, viewer); + attribBuffers(viewer,PROGRAM_WITH_TEXTURE); + program->bind(); + program->setUniformValue("f_matrix", fMatrix); + program->setAttributeValue("color_facets", QColor(Qt::white)); + program->setAttributeValue("normal", QVector3D(0.0,0.0,0.0)); + + glDrawArrays(GL_TRIANGLES, 0,static_cast(positions_quad.size()/3)); + program->release(); + vaos[TexturedCutplane]->release(); + break; + + case CUT_SEGMENTS: + vaos[Facets]->bind(); + program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + attribBuffers(viewer, PROGRAM_NO_SELECTION); + program->bind(); + program->setUniformValue("f_matrix", fMatrix); + program->setAttributeValue("colors", this->color()); + glDrawArrays(GL_TRIANGLES, 0,static_cast(positions_quad.size()/3)); + + program->release(); + vaos[Facets]->release(); + break; + } + } + void drawEdges(CGAL::Three::Viewer_interface *viewer) const + { + QMatrix4x4 fMatrix; + fMatrix.setToIdentity(); + for(int i=0; i< 16 ; i++) + fMatrix.data()[i] = frame->matrix()[i]; + vaos[Edges]->bind(); + program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + attribBuffers(viewer, PROGRAM_NO_SELECTION); + program->bind(); + program->setUniformValue("f_matrix", fMatrix); + program->setAttributeValue("colors", QColor(Qt::black)); + glDrawArrays(GL_LINES, 0,static_cast(positions_lines.size()/3)); + program->release(); + vaos[Edges]->release(); + } + + void invalidateOpenGLBuffers() + { + are_buffers_filled = false; + } + + void set_fast_distance(bool b)const { m_fast_distance = b; update_grid_size(); } + void setCutPlaneType(Cut_planes_types type){ m_cut_plane = type;} + Cut_planes_types cutPlaneType()const {return m_cut_plane;} +private: + Edge_trees edge_trees; + Facet_trees facet_trees; + enum VAOs{ + Facets = 0, + Edges, + TexturedCutplane, + NbVaos + }; + enum VBOs{ + Facets_vertices = 0, + Edges_vertices, + UVCoords, + NbVbos + }; + typedef std::pair Point_distance; + std::vector vaos; + mutable int m_grid_size; + mutable bool m_fast_distance; + mutable Point_distance m_distance_function[100][100]; + mutable GLuint textureId; + mutable Texture *texture; + // An aabb_tree indexing polyhedron facets/segments + mutable Color_ramp m_red_ramp; + mutable Color_ramp m_blue_ramp; + mutable Color_ramp m_thermal_ramp; + mutable Kernel::FT m_max_distance_function; + mutable std::vector tex_map; + mutable Cut_planes_types m_cut_plane; + mutable std::vector buffers; + + FT random_in(const double a, + const double b)const + { + double r = rand() / (double)RAND_MAX; + return (FT)(a + (b - a) * r); + } + + Kernel::Vector_3 random_vector() const + { + FT x = random_in(0.0,1.0); + FT y = random_in(0.0,1.0); + FT z = random_in(0.0,1.0); + return Kernel::Vector_3(x,y,z); + } + + template + void compute_distance_function(const QMap& trees, bool is_signed = false)const + { + // Get transformation + const GLdouble* m = frame->matrix(); + + // OpenGL matrices are row-major matrices + Kernel::Aff_transformation_3 t = Kernel::Aff_transformation_3 (m[0], m[4], m[8], m[12], + m[1], m[5], m[9], m[13], + m[2], m[6], m[10], m[14]); + + m_max_distance_function = FT(0); + FT diag = scene_diag(); + const FT dx = 2*diag; + const FT dy = 2*diag; + const FT z (0); + const FT fd = FT(1); + Tree *min_tree = NULL; + for(int i=0 ; isquared_distance(query) ); + if(dist < min) + { + min = dist; + if(is_signed) + min_tree = tree; + } + } + + m_distance_function[i][j] = Point_distance(query,min); + m_max_distance_function = (std::max)(min, m_max_distance_function); + + if(is_signed) + { + typedef typename Tree::size_type size_type; + Kernel::Vector_3 random_vec = random_vector(); + + const Kernel::Point_3& p = m_distance_function[i][j].first; + const FT unsigned_distance = m_distance_function[i][j].second; + + // get sign through ray casting (random vector) + Kernel::Ray_3 ray(p, random_vec); + size_type nbi = min_tree->number_of_intersected_primitives(ray); + + FT sign ( (nbi&1) == 0 ? 1 : -1); + m_distance_function[i][j].second = sign * unsigned_distance; + } + } + } + } + + void compute_texture(int i, int j,Color_ramp pos_ramp ,Color_ramp neg_ramp)const + { + + + const FT& d00 = m_distance_function[i][j].second; + // determines grey level + unsigned int i00 = 255-(unsigned)(255.0 * (double)std::fabs(d00) / m_max_distance_function); + + if(d00 > 0.0) + texture->setData(i,j,pos_ramp.r(i00),pos_ramp.g(i00),pos_ramp.b(i00)); + else + texture->setData(i,j,neg_ramp.r(i00),neg_ramp.g(i00),neg_ramp.b(i00)); + + + } + void computeElements()const + { + Scene_plane_item::compute_normals_and_vertices(); + + + switch(m_cut_plane) + { + case UNSIGNED_FACETS: + if ( facet_trees.empty() ) { return; } + compute_distance_function(facet_trees); + break; + case SIGNED_FACETS: + if ( facet_trees.empty() ) { return; } + compute_distance_function(facet_trees, true); + + break; + case UNSIGNED_EDGES: + if ( edge_trees.empty() ) { return; } + compute_distance_function(edge_trees); + break; + default: + break; + } + //The texture + switch(m_cut_plane) + { + case SIGNED_FACETS: + for( int i=0 ; i < texture->getWidth(); i++ ) + { + for( int j=0 ; j < texture->getHeight() ; j++) + { + compute_texture(i,j,m_red_ramp,m_blue_ramp); + } + } + break; + case UNSIGNED_FACETS: + case UNSIGNED_EDGES: + for( int i=0 ; i < texture->getWidth(); i++ ) + { + for( int j=0 ; j < texture->getHeight() ; j++) + { + compute_texture(i,j,m_thermal_ramp,m_thermal_ramp); + } + } + break; + default: + break; + } + } + + void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const + { + if(GLuint(-1) == textureId) { + glGenTextures(1, &textureId); + } + + //vaos for the basic cutting plane + { + program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); + program->bind(); + vaos[Facets]->bind(); + + buffers[Facets_vertices].bind(); + buffers[Facets_vertices].allocate(positions_quad.data(), + static_cast(positions_quad.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[Facets_vertices].release(); + vaos[Facets]->release(); + + + vaos[Edges]->bind(); + buffers[Edges_vertices].bind(); + buffers[Edges_vertices].allocate(positions_lines.data(), + static_cast(positions_lines.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[Edges_vertices].release(); + vaos[Edges]->release(); + + + program->release(); + } + //vao for the textured cutting planes + { + program = getShaderProgram(PROGRAM_WITH_TEXTURE); + program->bind(); + vaos[TexturedCutplane]->bind(); + buffers[Facets_vertices].bind(); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[Facets_vertices].release(); + + buffers[UVCoords].bind(); + buffers[UVCoords].allocate(tex_map.data(), static_cast(tex_map.size()*sizeof(float))); + program->attributeLocation("v_texCoord"); + program->setAttributeBuffer("v_texCoord",GL_FLOAT,0,2); + program->enableAttributeArray("v_texCoord"); + buffers[UVCoords].release(); + program->release(); + + glBindTexture(GL_TEXTURE_2D, textureId); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGB, + texture->getWidth(), + texture->getHeight(), + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + texture->getData()); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE ); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE ); + } + are_buffers_filled = true; + } + +}; using namespace CGAL::Three; class Polyhedron_demo_cut_plugin : public QObject, @@ -337,6 +775,31 @@ public: Messages_interface* m); QList actions() const; + bool eventFilter(QObject *, QEvent *event) + { + if(event->type() == QEvent::MouseButtonPress) + { + QMouseEvent * mevent = static_cast(event); + if ( mevent->modifiers() == Qt::ControlModifier ) + { + plane_item->set_fast_distance(true); + plane_item->invalidateOpenGLBuffers(); + plane_item->itemChanged(); + } + } + else if(event->type() == QEvent::MouseButtonRelease) + { + QMouseEvent * mevent = static_cast(event); + if ( mevent->modifiers() == Qt::ControlModifier ) + { + plane_item->set_fast_distance(false); + plane_item->invalidateOpenGLBuffers(); + plane_item->itemChanged(); + } + } + return false; + } + public Q_SLOTS: void updateCutPlane() @@ -344,33 +807,49 @@ public Q_SLOTS: ready_to_cut = true; QTimer::singleShot(0,this,SLOT(cut())); } - void createCutPlane(); void enableAction(); void cut(); + void computeIntersection(); void reset_edges() { edges_item = 0; } + void Intersection(); + void SignedFacets(); + void UnsignedFacets(); + void UnsignedEdges(); + void resetPlane() + { + plane_item = NULL; + } private: + void createCutPlane(); CGAL::Three::Scene_interface* scene; Messages_interface* messages; - Scene_plane_item* plane_item; + Scene_aabb_plane_item* plane_item; Scene_edges_item* edges_item; - QAction* actionCreateCutPlane; - bool ready_to_cut; + QAction* actionIntersection; + QAction* actionSignedFacets; + QAction* actionUnsignedFacets; + QAction* actionUnsignedEdges; - typedef std::map Trees; - Trees trees; + bool ready_to_cut; + Facet_trees facet_trees; + Edge_trees edge_trees; }; // end Polyhedron_demo_cut_plugin Polyhedron_demo_cut_plugin::~Polyhedron_demo_cut_plugin() { - for ( Trees::iterator it = trees.begin(), end = trees.end() ; - it != end ; ++it) + Q_FOREACH(Facet_tree *tree, facet_trees.values()) { - delete it->second; + delete tree; } + Q_FOREACH(Edge_tree *tree, edge_trees.values()) + { + delete tree; + } + } @@ -380,19 +859,40 @@ void Polyhedron_demo_cut_plugin::init(QMainWindow* mainWindow, { scene = scene_interface; messages = m; - actionCreateCutPlane = new QAction(tr("Create Cutting Plane"), mainWindow); - actionCreateCutPlane->setProperty("subMenuName","3D Fast Intersection and Distance Computation"); + actionIntersection = new QAction(tr("Create Cutting Plane"), mainWindow); + actionSignedFacets = new QAction(tr("Signed Distance Function to Facets"), mainWindow); + actionUnsignedFacets= new QAction(tr("Unsigned Distance Function to Facets"), mainWindow); + actionUnsignedEdges = new QAction(tr("Unsigned Distance Function to Edges"), mainWindow); + + actionIntersection->setProperty("subMenuName","3D Fast Intersection and Distance Computation"); + actionSignedFacets->setProperty("subMenuName","3D Fast Intersection and Distance Computation"); + actionUnsignedFacets->setProperty("subMenuName","3D Fast Intersection and Distance Computation"); + actionUnsignedEdges->setProperty("subMenuName","3D Fast Intersection and Distance Computation"); ready_to_cut = true; - connect(actionCreateCutPlane, SIGNAL(triggered()), - this, SLOT(createCutPlane())); + connect(actionIntersection, SIGNAL(triggered()), + this, SLOT(Intersection())); + connect(actionSignedFacets, SIGNAL(triggered()), + this, SLOT(SignedFacets())); + connect(actionUnsignedFacets, SIGNAL(triggered()), + this, SLOT(UnsignedFacets())); + connect(actionUnsignedEdges, SIGNAL(triggered()), + this, SLOT(UnsignedEdges())); + plane_item = NULL; + + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + viewer->installEventFilter(this); + } QList Polyhedron_demo_cut_plugin::actions() const { - return QList() << actionCreateCutPlane; + return QList() << actionIntersection + << actionSignedFacets + << actionUnsignedFacets + << actionUnsignedEdges; } void Polyhedron_demo_cut_plugin::createCutPlane() { - plane_item = new Scene_plane_item(scene); + plane_item = new Scene_aabb_plane_item(scene); const CGAL::Three::Scene_interface::Bbox& bbox = scene->bbox(); plane_item->setPosition((bbox.xmin()+bbox.xmax())/2.f, (bbox.ymin()+bbox.ymax())/2.f, @@ -406,8 +906,10 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { plane_item->setName(tr("Cutting plane")); connect(plane_item->manipulatedFrame(), SIGNAL(modified()), this, SLOT(updateCutPlane())); + connect(plane_item, SIGNAL(aboutToBeDestroyed()), + this, SLOT(resetPlane())); scene->addItem(plane_item); - actionCreateCutPlane->setEnabled(false); + actionIntersection->setEnabled(false); // Hide polyhedrons and call cut() (avoid that nothing shows up until user // decides to move the plane item) @@ -417,11 +919,58 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { if ( NULL != poly_item ) poly_item->setVisible(false); } - cut(); + + //fills the tree maps + for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { + CGAL::Three::Scene_item* item = scene->item(i); + Scene_polyhedron_item* poly_item = qobject_cast(item); + if(!poly_item) continue; + + if(facet_trees.find(poly_item) == facet_trees.end()) { + facet_trees[poly_item] = new Facet_tree(faces(*(poly_item->polyhedron())).first, + faces(*(poly_item->polyhedron())).second, + *poly_item->polyhedron() ); + } + if(edge_trees.find(poly_item) == edge_trees.end()) { + edge_trees[poly_item] = new Edge_tree(edges(*poly_item->polyhedron()).first, + edges(*poly_item->polyhedron()).second, + *poly_item->polyhedron()); + } + } + plane_item->set_facet_trees(facet_trees); + plane_item->set_edge_trees(edge_trees); } +void Polyhedron_demo_cut_plugin::Intersection() +{ + if(!plane_item) + createCutPlane(); + plane_item->setCutPlaneType(Scene_aabb_plane_item::CUT_SEGMENTS); + computeIntersection(); + plane_item->invalidateOpenGLBuffers(); +} -void Polyhedron_demo_cut_plugin::cut() { +void Polyhedron_demo_cut_plugin::SignedFacets() { + if(!plane_item) + createCutPlane(); + plane_item->setCutPlaneType(Scene_aabb_plane_item::SIGNED_FACETS); + plane_item->invalidateOpenGLBuffers(); +} +void Polyhedron_demo_cut_plugin::UnsignedFacets() { + if(!plane_item) + createCutPlane(); + plane_item->setCutPlaneType(Scene_aabb_plane_item::UNSIGNED_FACETS); + plane_item->invalidateOpenGLBuffers(); +} +void Polyhedron_demo_cut_plugin::UnsignedEdges() { + if(!plane_item) + createCutPlane(); + plane_item->setCutPlaneType(Scene_aabb_plane_item::UNSIGNED_EDGES); + plane_item->invalidateOpenGLBuffers(); +} + +void Polyhedron_demo_cut_plugin::computeIntersection() +{ QApplication::setOverrideCursor(Qt::WaitCursor); if(!edges_item) { edges_item = new Scene_edges_item; @@ -433,61 +982,78 @@ void Polyhedron_demo_cut_plugin::cut() { } if(ready_to_cut) { - const qglviewer::Vec& pos = plane_item->manipulatedFrame()->position(); - const qglviewer::Vec& n = - plane_item->manipulatedFrame()->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); - Epic_kernel::Plane_3 plane(n[0], n[1], n[2], - n * pos); - //std::cerr << plane << std::endl; - edges_item->edges.clear(); - QTime time; - time.start(); - for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { - CGAL::Three::Scene_item* item = scene->item(i); - Scene_polyhedron_item* poly_item = qobject_cast(item); - if(!poly_item) continue; - Trees::iterator it = trees.find(poly_item); - if(it == trees.end()) { - it = trees.insert(trees.begin(), - std::make_pair(poly_item, - new AABB_tree(faces(*(poly_item->polyhedron())).first, - faces(*(poly_item->polyhedron())).second, - *poly_item->polyhedron() ))); - Scene_aabb_item* aabb_item = new Scene_aabb_item(*it->second); - aabb_item->setName(tr("AABB tree of %1").arg(poly_item->name())); - aabb_item->setRenderingMode(Wireframe); - aabb_item->setColor(Qt::black); - aabb_item->setVisible(false); - scene->addItem(aabb_item); - //std::cerr << "size: " << it->second->size() << std::endl; - } - - if(!CGAL::do_intersect(plane, it->second->bbox())) - continue; - - std::vector intersections; - it->second->all_intersections(plane, std::back_inserter(intersections)); - - for ( std::vector::iterator it = intersections.begin(), - end = intersections.end() ; it != end ; ++it ) - { - const Epic_kernel::Segment_3* inter_seg = - CGAL::object_cast(&(it->first)); - - if ( NULL != inter_seg ) - edges_item->edges.push_back(*inter_seg); - } - ready_to_cut = false; - } + const qglviewer::Vec& pos = plane_item->manipulatedFrame()->position(); + const qglviewer::Vec& n = + plane_item->manipulatedFrame()->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); + Epic_kernel::Plane_3 plane(n[0], n[1], n[2], - n * pos); + //std::cerr << plane << std::endl; + edges_item->edges.clear(); + QTime time; + time.start(); + for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { + CGAL::Three::Scene_item* item = scene->item(i); + Scene_polyhedron_item* poly_item = qobject_cast(item); + if(!poly_item) continue; + Facet_trees::iterator it = facet_trees.find(poly_item); + if(it == facet_trees.end()) { + it = facet_trees.insert(facet_trees.begin(), + poly_item, + new Facet_tree(faces(*(poly_item->polyhedron())).first, + faces(*(poly_item->polyhedron())).second, + *poly_item->polyhedron() )); + Scene_aabb_item* aabb_item = new Scene_aabb_item(*it.value()); + aabb_item->setName(tr("AABB tree of %1").arg(poly_item->name())); + aabb_item->setRenderingMode(Wireframe); + aabb_item->setColor(Qt::black); + aabb_item->setVisible(false); + scene->addItem(aabb_item); + //std::cerr << "size: " << it->second->size() << std::endl; + } - messages->information(QString("cut (%1 ms). %2 edges.").arg(time.elapsed()).arg(edges_item->edges.size())); - edges_item->invalidateOpenGLBuffers(); - scene->itemChanged(edges_item); + if(!CGAL::do_intersect(plane, it.value()->bbox())) + continue; + + std::vector intersections; + it.value()->all_intersections(plane, std::back_inserter(intersections)); + + for ( std::vector::iterator it = intersections.begin(), + end = intersections.end() ; it != end ; ++it ) + { + const Epic_kernel::Segment_3* inter_seg = + CGAL::object_cast(&(it->first)); + + if ( NULL != inter_seg ) + edges_item->edges.push_back(*inter_seg); + } + } + + messages->information(QString("cut (%1 ms). %2 edges.").arg(time.elapsed()).arg(edges_item->edges.size())); + edges_item->invalidateOpenGLBuffers(); + scene->itemChanged(edges_item); + ready_to_cut = false; } QApplication::restoreOverrideCursor(); } +void Polyhedron_demo_cut_plugin::cut() +{ + plane_item->set_fast_distance(true); + switch(plane_item->cutPlaneType()) + { + case Scene_aabb_plane_item::CUT_SEGMENTS: + computeIntersection(); + break; + default: + if(ready_to_cut) + { + plane_item->invalidateOpenGLBuffers(); + ready_to_cut = false; + } + } +} + void Polyhedron_demo_cut_plugin::enableAction() { - actionCreateCutPlane->setEnabled(true); + actionIntersection->setEnabled(true); } #include "Cut_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp index 9448b5f4ffc..82e61b06f54 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp @@ -2,32 +2,6 @@ using namespace CGAL::Three; -struct Scene_plane_item_priv -{ - Scene_plane_item_priv(Scene_plane_item* parent) - { - item = parent; - } - - ~Scene_plane_item_priv() { - } - - double scene_diag() const { - const Scene_item::Bbox& bbox = item->scene->bbox(); - const double& xdelta = bbox.xmax()-bbox.xmin(); - const double& ydelta = bbox.ymax()-bbox.ymin(); - const double& zdelta = bbox.zmax()-bbox.zmin(); - const double diag = std::sqrt(xdelta*xdelta + - ydelta*ydelta + - zdelta*zdelta); - return diag * 0.7; - } - - - Scene_plane_item* item; - -}; - Scene_plane_item::Scene_plane_item(const CGAL::Three::Scene_interface* scene_interface) :CGAL::Three::Scene_item(NbOfVbos,NbOfVaos), @@ -37,13 +11,11 @@ Scene_plane_item::Scene_plane_item(const CGAL::Three::Scene_interface* scene_int frame(new ManipulatedFrame()) { setNormal(0., 0., 1.); - d = new Scene_plane_item_priv(this); //Generates an integer which will be used as ID for each buffer invalidateOpenGLBuffers(); } Scene_plane_item::~Scene_plane_item() { delete frame; - delete d; } void Scene_plane_item::initializeBuffers(Viewer_interface *viewer) const @@ -75,12 +47,12 @@ void Scene_plane_item::initializeBuffers(Viewer_interface *viewer) const } -void Scene_plane_item::compute_normals_and_vertices(void) +void Scene_plane_item::compute_normals_and_vertices(void) const { positions_quad.resize(0); positions_lines.resize(0); - const double diag = d->scene_diag(); + const double diag = scene_diag(); //The quad { @@ -94,11 +66,11 @@ void Scene_plane_item::compute_normals_and_vertices(void) positions_quad.push_back(-diag); positions_quad.push_back(0.0); - positions_quad.push_back(-diag); positions_quad.push_back(diag); + positions_quad.push_back(-diag); positions_quad.push_back(0.0); - positions_quad.push_back(diag); positions_quad.push_back(-diag); + positions_quad.push_back(diag); positions_quad.push_back(0.0); positions_quad.push_back(diag); positions_quad.push_back(diag); diff --git a/Polyhedron/demo/Polyhedron/Scene_plane_item.h b/Polyhedron/demo/Polyhedron/Scene_plane_item.h index 22c287906fa..321ab2eb4b2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.h @@ -17,7 +17,6 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel_epic; typedef Kernel_epic::Plane_3 Plane_3; -struct Scene_plane_item_priv; class SCENE_BASIC_OBJECTS_EXPORT Scene_plane_item : public CGAL::Three::Scene_item { @@ -28,6 +27,16 @@ public: Scene_plane_item(const CGAL::Three::Scene_interface* scene_interface); ~Scene_plane_item(); + double scene_diag() const { + const Scene_item::Bbox& bbox = scene->bbox(); + const double& xdelta = bbox.xmax()-bbox.xmin(); + const double& ydelta = bbox.ymax()-bbox.ymin(); + const double& zdelta = bbox.zmax()-bbox.zmin(); + const double diag = std::sqrt(xdelta*xdelta + + ydelta*ydelta + + zdelta*zdelta); + return diag * 0.7; + } bool isFinite() const { return false; } bool isEmpty() const { return false; } void compute_bbox() const { _bbox = Bbox(); } @@ -61,9 +70,6 @@ public Q_SLOTS: void setManipulatable(bool b = true); protected: - friend struct Scene_plane_item_priv; - Scene_plane_item_priv* d; - const CGAL::Three::Scene_interface* scene; bool manipulable; @@ -88,7 +94,7 @@ protected: mutable QOpenGLShaderProgram *program; void initializeBuffers(CGAL::Three::Viewer_interface*)const; - void compute_normals_and_vertices(void); + void compute_normals_and_vertices(void) const; mutable bool are_buffers_filled; }; From 3d84bff91f0f43405763293db5536176e3bc9f38 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 23 Jun 2016 14:30:59 +0200 Subject: [PATCH 02/15] Fix segfaults --- .../Plugins/AABB_tree/Cut_plugin.cpp | 43 +++++++++++-------- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 7 ++- .../demo/Polyhedron/Scene_polyhedron_item.h | 2 +- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 15c84cbae78..85eac8e4bbc 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -3,6 +3,7 @@ #include #include +#include "Scene.h" #include "../../AABB_tree/demo/AABB_tree/Color_ramp.h" #include "Messages_interface.h" #include "Scene_plane_item.h" @@ -356,14 +357,14 @@ public: ~Scene_aabb_plane_item() { - Q_FOREACH(Facet_tree *tree, facet_trees.values()) + /* Q_FOREACH(Facet_tree *tree, facet_trees.values()) { delete tree; } Q_FOREACH(Edge_tree *tree, edge_trees.values()) { delete tree; - } + }*/ delete texture; } @@ -375,12 +376,12 @@ public: texture = new Texture(m_grid_size,m_grid_size); } - void set_facet_trees(Facet_trees facet_trees) + void set_facet_trees(Facet_trees *facet_trees) { this->facet_trees = facet_trees; } - void set_edge_trees(Edge_trees edge_trees) + void set_edge_trees(Edge_trees *edge_trees) { this->edge_trees = edge_trees; } @@ -458,8 +459,8 @@ public: void setCutPlaneType(Cut_planes_types type){ m_cut_plane = type;} Cut_planes_types cutPlaneType()const {return m_cut_plane;} private: - Edge_trees edge_trees; - Facet_trees facet_trees; + Edge_trees* edge_trees; + Facet_trees* facet_trees; enum VAOs{ Facets = 0, Edges, @@ -504,7 +505,7 @@ private: } template - void compute_distance_function(const QMap& trees, bool is_signed = false)const + void compute_distance_function(QMap *trees, bool is_signed = false)const { // Get transformation const GLdouble* m = frame->matrix(); @@ -532,7 +533,7 @@ private: Kernel::Point_3 query = t( Kernel::Point_3(x,y,z) ); FT min = DBL_MAX; - Q_FOREACH(Tree *tree, trees.values()) + Q_FOREACH(Tree *tree, trees->values()) { FT dist = CGAL::sqrt( tree->squared_distance(query) ); if(dist < min) @@ -588,16 +589,16 @@ private: switch(m_cut_plane) { case UNSIGNED_FACETS: - if ( facet_trees.empty() ) { return; } + if ( facet_trees->empty() ) { return; } compute_distance_function(facet_trees); break; case SIGNED_FACETS: - if ( facet_trees.empty() ) { return; } + if ( facet_trees->empty() ) { return; } compute_distance_function(facet_trees, true); break; case UNSIGNED_EDGES: - if ( edge_trees.empty() ) { return; } + if ( edge_trees->empty() ) { return; } compute_distance_function(edge_trees); break; default: @@ -821,7 +822,14 @@ public Q_SLOTS: { plane_item = NULL; } - + void deleteTrees(CGAL::Three::Scene_item* sender) + { + Scene_polyhedron_item* item = qobject_cast(sender); + delete facet_trees[item]; + facet_trees.remove(item); + delete edge_trees[item]; + edge_trees.remove(item); + } private: void createCutPlane(); CGAL::Three::Scene_interface* scene; @@ -849,7 +857,6 @@ Polyhedron_demo_cut_plugin::~Polyhedron_demo_cut_plugin() { delete tree; } - } @@ -898,8 +905,6 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { (bbox.ymin()+bbox.ymax())/2.f, (bbox.zmin()+bbox.zmax())/2.f); plane_item->setNormal(0., 0., 1.); - connect(plane_item, SIGNAL(destroyed()), - this, SLOT(enableAction())); plane_item->setManipulatable(true); plane_item->setClonable(false); plane_item->setColor(Qt::green); @@ -908,8 +913,10 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { this, SLOT(updateCutPlane())); connect(plane_item, SIGNAL(aboutToBeDestroyed()), this, SLOT(resetPlane())); +Scene* real_scene = static_cast(scene); + connect(real_scene, SIGNAL(itemAboutToBeDestroyed(CGAL::Three::Scene_item*)), + this, SLOT(deleteTrees(CGAL::Three::Scene_item*))); scene->addItem(plane_item); - actionIntersection->setEnabled(false); // Hide polyhedrons and call cut() (avoid that nothing shows up until user // decides to move the plane item) @@ -937,8 +944,8 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { *poly_item->polyhedron()); } } - plane_item->set_facet_trees(facet_trees); - plane_item->set_edge_trees(edge_trees); + plane_item->set_facet_trees(&facet_trees); + plane_item->set_edge_trees(&edge_trees); } void Polyhedron_demo_cut_plugin::Intersection() diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 799e24ca464..0fd070db796 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -1272,7 +1272,7 @@ Scene_polyhedron_item::select(double orig_x, typedef Input_facets_AABB_tree Tree; typedef Tree::Object_and_primitive_id Object_and_primitive_id; - Tree* aabb_tree = static_cast(d->get_aabb_tree()); + Tree* aabb_tree = static_cast(d->get_aabb_tree()); if(aabb_tree) { const Kernel::Point_3 ray_origin(orig_x, orig_y, orig_z); @@ -1756,3 +1756,8 @@ bool Scene_polyhedron_item::triangulated(){return d->poly->is_pure_triangle();} bool Scene_polyhedron_item::self_intersected(){return !(d->self_intersect);} void Scene_polyhedron_item::setItemIsMulticolor(bool b){ d->is_multicolor = b;} bool Scene_polyhedron_item::isItemMulticolor(){ return d->is_multicolor;} + +void* Scene_polyhedron_item::get_aabb_tree() +{ + return d->get_aabb_tree(); +} diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index bda2600e728..108dc4b96a6 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -62,7 +62,7 @@ public: bool load_obj(std::istream& in); bool save(std::ostream& out) const; bool save_obj(std::ostream& out) const; - + void* get_aabb_tree(); // Function for displaying meta-data of the item virtual QString toolTip() const; From 5fd4ff01f54d606d435c4b19ce136db8077974fe Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 23 Jun 2016 15:21:31 +0200 Subject: [PATCH 03/15] Fix - update the plane and the trees when an item is added. --- .../Plugins/AABB_tree/Cut_plugin.cpp | 42 ++++++++++++++----- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 4 -- .../demo/Polyhedron/Scene_polyhedron_item.h | 2 +- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 85eac8e4bbc..b56e956adcc 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -830,6 +830,7 @@ public Q_SLOTS: delete edge_trees[item]; edge_trees.remove(item); } + void updateTrees(int id); private: void createCutPlane(); CGAL::Three::Scene_interface* scene; @@ -866,7 +867,7 @@ void Polyhedron_demo_cut_plugin::init(QMainWindow* mainWindow, { scene = scene_interface; messages = m; - actionIntersection = new QAction(tr("Create Cutting Plane"), mainWindow); + actionIntersection = new QAction(tr("Cut Segments"), mainWindow); actionSignedFacets = new QAction(tr("Signed Distance Function to Facets"), mainWindow); actionUnsignedFacets= new QAction(tr("Unsigned Distance Function to Facets"), mainWindow); actionUnsignedEdges = new QAction(tr("Unsigned Distance Function to Edges"), mainWindow); @@ -885,6 +886,11 @@ void Polyhedron_demo_cut_plugin::init(QMainWindow* mainWindow, connect(actionUnsignedEdges, SIGNAL(triggered()), this, SLOT(UnsignedEdges())); plane_item = NULL; + Scene* real_scene = static_cast(scene); + connect(real_scene, SIGNAL(itemAboutToBeDestroyed(CGAL::Three::Scene_item*)), + this, SLOT(deleteTrees(CGAL::Three::Scene_item*))); + connect(real_scene, SIGNAL(newItem(int)), + this, SLOT(updateTrees(int))); QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); @@ -898,7 +904,25 @@ QList Polyhedron_demo_cut_plugin::actions() const { << actionUnsignedEdges; } +void Polyhedron_demo_cut_plugin::updateTrees(int id) +{ +if(plane_item && + qobject_cast(scene->item(id))) + createCutPlane(); +} + void Polyhedron_demo_cut_plugin::createCutPlane() { + bool updating = false; + Scene_aabb_plane_item::Cut_planes_types type; + int plane_id = -1; + if(plane_item) + updating = true; + if(updating) + { + type = plane_item->cutPlaneType(); + plane_id = scene->item_id(plane_item); + } + plane_item = new Scene_aabb_plane_item(scene); const CGAL::Three::Scene_interface::Bbox& bbox = scene->bbox(); plane_item->setPosition((bbox.xmin()+bbox.xmax())/2.f, @@ -913,11 +937,13 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { this, SLOT(updateCutPlane())); connect(plane_item, SIGNAL(aboutToBeDestroyed()), this, SLOT(resetPlane())); -Scene* real_scene = static_cast(scene); - connect(real_scene, SIGNAL(itemAboutToBeDestroyed(CGAL::Three::Scene_item*)), - this, SLOT(deleteTrees(CGAL::Three::Scene_item*))); - scene->addItem(plane_item); - + if(updating) + { + scene->replaceItem(plane_id, plane_item)->deleteLater(); + plane_item->setCutPlaneType(type); + } + else + scene->addItem(plane_item); // Hide polyhedrons and call cut() (avoid that nothing shows up until user // decides to move the plane item) for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { @@ -926,7 +952,6 @@ Scene* real_scene = static_cast(scene); if ( NULL != poly_item ) poly_item->setVisible(false); } - //fills the tree maps for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { CGAL::Three::Scene_item* item = scene->item(i); @@ -1059,8 +1084,5 @@ void Polyhedron_demo_cut_plugin::cut() } } -void Polyhedron_demo_cut_plugin::enableAction() { - actionIntersection->setEnabled(true); -} #include "Cut_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 0fd070db796..be8e7662c87 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -1757,7 +1757,3 @@ bool Scene_polyhedron_item::self_intersected(){return !(d->self_intersect);} void Scene_polyhedron_item::setItemIsMulticolor(bool b){ d->is_multicolor = b;} bool Scene_polyhedron_item::isItemMulticolor(){ return d->is_multicolor;} -void* Scene_polyhedron_item::get_aabb_tree() -{ - return d->get_aabb_tree(); -} diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index 108dc4b96a6..bda2600e728 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -62,7 +62,7 @@ public: bool load_obj(std::istream& in); bool save(std::ostream& out) const; bool save_obj(std::ostream& out) const; - void* get_aabb_tree(); + // Function for displaying meta-data of the item virtual QString toolTip() const; From 529fa3dfd66091910297c852946bd6452afa39d4 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 24 Jun 2016 15:53:43 +0200 Subject: [PATCH 04/15] Fix - Fixes link error and display in cut_segments --- .../Plugins/AABB_tree/Cut_plugin.cpp | 103 ++++++++++-------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index b56e956adcc..59e8744c1d2 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -808,7 +808,6 @@ public Q_SLOTS: ready_to_cut = true; QTimer::singleShot(0,this,SLOT(cut())); } - void enableAction(); void cut(); void computeIntersection(); void reset_edges() { @@ -987,18 +986,34 @@ void Polyhedron_demo_cut_plugin::SignedFacets() { createCutPlane(); plane_item->setCutPlaneType(Scene_aabb_plane_item::SIGNED_FACETS); plane_item->invalidateOpenGLBuffers(); + if(edges_item) + { + scene->erase(scene->item_id(edges_item)); + edges_item = NULL; + } + } void Polyhedron_demo_cut_plugin::UnsignedFacets() { if(!plane_item) createCutPlane(); plane_item->setCutPlaneType(Scene_aabb_plane_item::UNSIGNED_FACETS); plane_item->invalidateOpenGLBuffers(); + if(edges_item) + { + scene->erase(scene->item_id(edges_item)); + edges_item = NULL; + } } void Polyhedron_demo_cut_plugin::UnsignedEdges() { if(!plane_item) createCutPlane(); plane_item->setCutPlaneType(Scene_aabb_plane_item::UNSIGNED_EDGES); plane_item->invalidateOpenGLBuffers(); + if(edges_item) + { + scene->erase(scene->item_id(edges_item)); + edges_item = NULL; + } } void Polyhedron_demo_cut_plugin::computeIntersection() @@ -1012,51 +1027,49 @@ void Polyhedron_demo_cut_plugin::computeIntersection() this, SLOT(reset_edges())); scene->addItem(edges_item); } - if(ready_to_cut) - { - const qglviewer::Vec& pos = plane_item->manipulatedFrame()->position(); - const qglviewer::Vec& n = - plane_item->manipulatedFrame()->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); - Epic_kernel::Plane_3 plane(n[0], n[1], n[2], - n * pos); - //std::cerr << plane << std::endl; - edges_item->edges.clear(); - QTime time; - time.start(); - for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { - CGAL::Three::Scene_item* item = scene->item(i); - Scene_polyhedron_item* poly_item = qobject_cast(item); - if(!poly_item) continue; - Facet_trees::iterator it = facet_trees.find(poly_item); - if(it == facet_trees.end()) { - it = facet_trees.insert(facet_trees.begin(), - poly_item, - new Facet_tree(faces(*(poly_item->polyhedron())).first, - faces(*(poly_item->polyhedron())).second, - *poly_item->polyhedron() )); - Scene_aabb_item* aabb_item = new Scene_aabb_item(*it.value()); - aabb_item->setName(tr("AABB tree of %1").arg(poly_item->name())); - aabb_item->setRenderingMode(Wireframe); - aabb_item->setColor(Qt::black); - aabb_item->setVisible(false); - scene->addItem(aabb_item); - //std::cerr << "size: " << it->second->size() << std::endl; - } - if(!CGAL::do_intersect(plane, it.value()->bbox())) - continue; + const qglviewer::Vec& pos = plane_item->manipulatedFrame()->position(); + const qglviewer::Vec& n = + plane_item->manipulatedFrame()->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); + Epic_kernel::Plane_3 plane(n[0], n[1], n[2], - n * pos); + //std::cerr << plane << std::endl; + edges_item->edges.clear(); + QTime time; + time.start(); + for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { + CGAL::Three::Scene_item* item = scene->item(i); + Scene_polyhedron_item* poly_item = qobject_cast(item); + if(!poly_item) continue; + Facet_trees::iterator it = facet_trees.find(poly_item); + if(it == facet_trees.end()) { + it = facet_trees.insert(facet_trees.begin(), + poly_item, + new Facet_tree(faces(*(poly_item->polyhedron())).first, + faces(*(poly_item->polyhedron())).second, + *poly_item->polyhedron() )); + Scene_aabb_item* aabb_item = new Scene_aabb_item(*it.value()); + aabb_item->setName(tr("AABB tree of %1").arg(poly_item->name())); + aabb_item->setRenderingMode(Wireframe); + aabb_item->setColor(Qt::black); + aabb_item->setVisible(false); + scene->addItem(aabb_item); + } + //std::cerr << "size: " << it->second->size() << std::endl; - std::vector intersections; - it.value()->all_intersections(plane, std::back_inserter(intersections)); + if(!CGAL::do_intersect(plane, it.value()->bbox())) + continue; - for ( std::vector::iterator it = intersections.begin(), - end = intersections.end() ; it != end ; ++it ) - { - const Epic_kernel::Segment_3* inter_seg = - CGAL::object_cast(&(it->first)); + std::vector intersections; + it.value()->all_intersections(plane, std::back_inserter(intersections)); - if ( NULL != inter_seg ) - edges_item->edges.push_back(*inter_seg); - } + for ( std::vector::iterator it = intersections.begin(), + end = intersections.end() ; it != end ; ++it ) + { + const Epic_kernel::Segment_3* inter_seg = + CGAL::object_cast(&(it->first)); + + if ( NULL != inter_seg ) + edges_item->edges.push_back(*inter_seg); } messages->information(QString("cut (%1 ms). %2 edges.").arg(time.elapsed()).arg(edges_item->edges.size())); @@ -1073,7 +1086,11 @@ void Polyhedron_demo_cut_plugin::cut() switch(plane_item->cutPlaneType()) { case Scene_aabb_plane_item::CUT_SEGMENTS: - computeIntersection(); + if(ready_to_cut) + { + computeIntersection(); + ready_to_cut = false; + } break; default: if(ready_to_cut) From a1f8a161d86ee7d54fe5824dd0eee55fd94b28e2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 27 Jun 2016 10:01:46 +0200 Subject: [PATCH 05/15] Replace the AABB_Tree demo's Color_ramp by the one already present in the Polyhedron demo. --- Polyhedron/demo/Polyhedron/CMakeLists.txt | 4 ++++ Polyhedron/demo/Polyhedron/Color_ramp.cpp | 15 +++++++++++++++ Polyhedron/demo/Polyhedron/Color_ramp.h | 12 ++++++++++-- .../Plugins/AABB_tree/CMakeLists.txt | 4 ++-- .../Plugins/AABB_tree/Cut_plugin.cpp | 18 +++++------------- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 940f6a5dbf5..7e5baa27174 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -198,6 +198,9 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) ${OPENGL_gl_LIBRARY} ) qt5_use_modules(scene_basic_objects OpenGL Gui Xml Script Widgets) + + add_library(scene_color_ramp SHARED Color_ramp.cpp) + add_library(point_dialog SHARED Show_point_dialog.cpp Show_point_dialog.ui ${Show_point_dialogUI_FILES}) qt5_use_modules(point_dialog OpenGL Gui Xml Script Widgets) @@ -267,6 +270,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) foreach( lib demo_framework scene_basic_objects + scene_color_ramp scene_polyhedron_item scene_polygon_soup_item scene_nef_polyhedron_item) diff --git a/Polyhedron/demo/Polyhedron/Color_ramp.cpp b/Polyhedron/demo/Polyhedron/Color_ramp.cpp index 40c55a9c2d9..c2d18de35d0 100644 --- a/Polyhedron/demo/Polyhedron/Color_ramp.cpp +++ b/Polyhedron/demo/Polyhedron/Color_ramp.cpp @@ -113,6 +113,21 @@ Color_ramp::build_blue() r_.add(0.1,0.4); } +void +Color_ramp::build_thermal() +{ + r_.rebuild(1,0.5); + g_.rebuild(1,0); + b_.rebuild(1,0); + + r_.add(0.3,1); + r_.add(0.05,1); + g_.add(0.05,0.8); + g_.add(0.3,0.5); + b_.add(0.05,0.6); + b_.add(0.05,0.3); +} + void Color_ramp:: print() const diff --git a/Polyhedron/demo/Polyhedron/Color_ramp.h b/Polyhedron/demo/Polyhedron/Color_ramp.h index 4843cd94050..a7733cf7199 100644 --- a/Polyhedron/demo/Polyhedron/Color_ramp.h +++ b/Polyhedron/demo/Polyhedron/Color_ramp.h @@ -1,9 +1,16 @@ #ifndef _COLOR_RAMP_H #define _COLOR_RAMP_H +#include +#ifdef scene_color_ramp_EXPORTS +# define SCENE_COLOR_RAMP_EXPORT Q_DECL_EXPORT +#else +# define SCENE_COLOR_RAMP_EXPORT Q_DECL_IMPORT +#endif + #include -class Color_component +class SCENE_COLOR_RAMP_EXPORT Color_component { typedef std::list > Values; @@ -26,7 +33,7 @@ private: }; -class Color_ramp +class SCENE_COLOR_RAMP_EXPORT Color_ramp { public : Color_ramp(); @@ -39,6 +46,7 @@ public : void build_red(); void build_blue(); + void build_thermal(); void print() const; private : diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/CMakeLists.txt index d35c622c752..a1f0c9c862e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/CMakeLists.txt @@ -1,4 +1,4 @@ include( polyhedron_demo_macros ) -polyhedron_demo_plugin(cut_plugin Cut_plugin) -target_link_libraries(cut_plugin scene_polyhedron_item scene_basic_objects) +polyhedron_demo_plugin(cut_plugin Cut_plugin ) +target_link_libraries(cut_plugin scene_polyhedron_item scene_basic_objects scene_color_ramp) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 59e8744c1d2..3f4b5da802e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -4,7 +4,7 @@ #include #include "Scene.h" -#include "../../AABB_tree/demo/AABB_tree/Color_ramp.h" +#include "Color_ramp.h" #include "Messages_interface.h" #include "Scene_plane_item.h" #include "Scene_polyhedron_item.h" @@ -331,6 +331,7 @@ public: m_grid_size = slow_distance_grid_size; m_red_ramp.build_red(); m_blue_ramp.build_blue(); + m_thermal_ramp.build_thermal(); texture = new Texture(m_grid_size,m_grid_size); @@ -356,15 +357,6 @@ public: ~Scene_aabb_plane_item() { - - /* Q_FOREACH(Facet_tree *tree, facet_trees.values()) - { - delete tree; - } - Q_FOREACH(Edge_tree *tree, edge_trees.values()) - { - delete tree; - }*/ delete texture; } @@ -572,12 +564,12 @@ private: const FT& d00 = m_distance_function[i][j].second; // determines grey level - unsigned int i00 = 255-(unsigned)(255.0 * (double)std::fabs(d00) / m_max_distance_function); + FT i00 = (double)std::fabs(d00) / m_max_distance_function; if(d00 > 0.0) - texture->setData(i,j,pos_ramp.r(i00),pos_ramp.g(i00),pos_ramp.b(i00)); + texture->setData(i,j,255*pos_ramp.r(i00),255*pos_ramp.g(i00),255*pos_ramp.b(i00)); else - texture->setData(i,j,neg_ramp.r(i00),neg_ramp.g(i00),neg_ramp.b(i00)); + texture->setData(i,j,255*neg_ramp.r(i00),255*neg_ramp.g(i00),255*neg_ramp.b(i00)); } From b99bd48c9dd42127377438e51c8e2b3f053edadf Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 28 Jun 2016 11:23:48 +0200 Subject: [PATCH 06/15] Fixes : - Fix segfault due to eventFilter - Fix display for cut edges. - Tries to fix the include bug. --- Polyhedron/demo/Polyhedron/CMakeLists.txt | 1 + .../Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 7e5baa27174..15767e4903a 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -200,6 +200,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) qt5_use_modules(scene_basic_objects OpenGL Gui Xml Script Widgets) add_library(scene_color_ramp SHARED Color_ramp.cpp) + qt5_use_modules(scene_color_ramp Core) add_library(point_dialog SHARED Show_point_dialog.cpp Show_point_dialog.ui ${Show_point_dialogUI_FILES}) qt5_use_modules(point_dialog OpenGL Gui Xml Script Widgets) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 3f4b5da802e..e77560c964f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -770,6 +770,8 @@ public: bool eventFilter(QObject *, QEvent *event) { + if(!plane_item) + return false; if(event->type() == QEvent::MouseButtonPress) { QMouseEvent * mevent = static_cast(event); @@ -1028,6 +1030,7 @@ void Polyhedron_demo_cut_plugin::computeIntersection() edges_item->edges.clear(); QTime time; time.start(); + bool does_intersect = false; for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { CGAL::Three::Scene_item* item = scene->item(i); Scene_polyhedron_item* poly_item = qobject_cast(item); @@ -1050,7 +1053,7 @@ void Polyhedron_demo_cut_plugin::computeIntersection() if(!CGAL::do_intersect(plane, it.value()->bbox())) continue; - + does_intersect = true; std::vector intersections; it.value()->all_intersections(plane, std::back_inserter(intersections)); @@ -1063,12 +1066,12 @@ void Polyhedron_demo_cut_plugin::computeIntersection() if ( NULL != inter_seg ) edges_item->edges.push_back(*inter_seg); } - - messages->information(QString("cut (%1 ms). %2 edges.").arg(time.elapsed()).arg(edges_item->edges.size())); - edges_item->invalidateOpenGLBuffers(); - scene->itemChanged(edges_item); - ready_to_cut = false; } + if(does_intersect) + messages->information(QString("cut (%1 ms). %2 edges.").arg(time.elapsed()).arg(edges_item->edges.size())); + edges_item->invalidateOpenGLBuffers(); + scene->itemChanged(edges_item); + ready_to_cut = false; QApplication::restoreOverrideCursor(); } From 16fe012931289b2837c92656f42017cef000261d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 29 Jun 2016 09:52:07 +0200 Subject: [PATCH 07/15] Fix - Fix LINK errors - Fix openGL errors --- Polyhedron/demo/Polyhedron/CMakeLists.txt | 4 +++- .../Plugins/AABB_tree/Cut_plugin.cpp | 24 +++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 15767e4903a..af960b77efd 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -253,7 +253,8 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) scene_basic_objects) endif() - add_item(scene_implicit_function_item Scene_implicit_function_item.cpp Color_ramp.cpp ) + add_item(scene_implicit_function_item Scene_implicit_function_item.cpp ) + target_link_libraries(scene_implicit_function_item scene_color_ramp) add_item(scene_polygon_soup_item Scene_polygon_soup_item.cpp) target_link_libraries(scene_polygon_soup_item scene_polyhedron_item) @@ -332,6 +333,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) demo_framework scene_polyhedron_item scene_points_with_normal_item + scene_color_ramp scene_implicit_function_item scene_polylines_item scene_basic_objects diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index e77560c964f..19870111260 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -395,8 +395,8 @@ public: case UNSIGNED_FACETS: case SIGNED_FACETS: - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); + viewer->glActiveTexture(GL_TEXTURE0); + viewer->glBindTexture(GL_TEXTURE_2D, textureId); vaos[TexturedCutplane]->bind(); program = getShaderProgram(PROGRAM_WITH_TEXTURE, viewer); @@ -406,7 +406,7 @@ public: program->setAttributeValue("color_facets", QColor(Qt::white)); program->setAttributeValue("normal", QVector3D(0.0,0.0,0.0)); - glDrawArrays(GL_TRIANGLES, 0,static_cast(positions_quad.size()/3)); + viewer->glDrawArrays(GL_TRIANGLES, 0,static_cast(positions_quad.size()/3)); program->release(); vaos[TexturedCutplane]->release(); break; @@ -418,7 +418,7 @@ public: program->bind(); program->setUniformValue("f_matrix", fMatrix); program->setAttributeValue("colors", this->color()); - glDrawArrays(GL_TRIANGLES, 0,static_cast(positions_quad.size()/3)); + viewer->glDrawArrays(GL_TRIANGLES, 0,static_cast(positions_quad.size()/3)); program->release(); vaos[Facets]->release(); @@ -437,7 +437,7 @@ public: program->bind(); program->setUniformValue("f_matrix", fMatrix); program->setAttributeValue("colors", QColor(Qt::black)); - glDrawArrays(GL_LINES, 0,static_cast(positions_lines.size()/3)); + viewer->glDrawArrays(GL_LINES, 0,static_cast(positions_lines.size()/3)); program->release(); vaos[Edges]->release(); } @@ -626,7 +626,7 @@ private: void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const { if(GLuint(-1) == textureId) { - glGenTextures(1, &textureId); + viewer->glGenTextures(1, &textureId); } //vaos for the basic cutting plane @@ -674,8 +674,8 @@ private: buffers[UVCoords].release(); program->release(); - glBindTexture(GL_TEXTURE_2D, textureId); - glTexImage2D(GL_TEXTURE_2D, + viewer->glBindTexture(GL_TEXTURE_2D, textureId); + viewer->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture->getWidth(), @@ -684,10 +684,10 @@ private: GL_RGB, GL_UNSIGNED_BYTE, texture->getData()); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE ); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE ); + viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE ); + viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE ); } are_buffers_filled = true; } From a761fb97e95af5eb81c5799a0d37e90a7e23bd06 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 1 Jul 2016 10:08:40 +0200 Subject: [PATCH 08/15] Use more vivid colors for the textured plane. --- .../Plugins/AABB_tree/Cut_plugin.cpp | 93 ++++++++++++++++--- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 19870111260..61c67f761d5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -353,6 +353,58 @@ public: tex_map.push_back(1.0f); tex_map.push_back(1.0f); + + //Vertex source code + const char tex_vertex_source[] = + { + "#version 120 \n" + "attribute highp vec4 vertex;\n" + "attribute highp vec2 tex_coord; \n" + "uniform highp mat4 mvp_matrix;\n" + "uniform highp mat4 f_matrix;\n" + "varying highp vec2 texc;\n" + "void main(void)\n" + "{\n" + " gl_Position = mvp_matrix * f_matrix * vertex;\n" + " texc = tex_coord;\n" + "}" + }; + //Vertex source code + const char tex_fragment_source[] = + { + "#version 120 \n" + "uniform sampler2D texture;\n" + "varying highp vec2 texc;\n" + "void main(void) { \n" + "gl_FragColor = texture2D(texture, texc.st);\n" + "} \n" + "\n" + }; + QOpenGLShader *tex_vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex); + if(!tex_vertex_shader->compileSourceCode(tex_vertex_source)) + { + std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(tex_fragment_source)) + { + std::cerr<<"Compiling fragmentsource FAILED"<addShader(tex_vertex_shader)) + { + std::cerr<<"adding vertex shader FAILED"<addShader(tex_fragment_shader)) + { + std::cerr<<"adding fragment shader FAILED"<link()) + { + std::cerr<<"linking Program FAILED"<glBindTexture(GL_TEXTURE_2D, textureId); vaos[TexturedCutplane]->bind(); - program = getShaderProgram(PROGRAM_WITH_TEXTURE, viewer); - attribBuffers(viewer,PROGRAM_WITH_TEXTURE); - program->bind(); - program->setUniformValue("f_matrix", fMatrix); - program->setAttributeValue("color_facets", QColor(Qt::white)); - program->setAttributeValue("normal", QVector3D(0.0,0.0,0.0)); + attribTexBuffers(viewer); + + tex_rendering_program->bind(); + tex_rendering_program->setUniformValue("f_matrix", fMatrix); viewer->glDrawArrays(GL_TRIANGLES, 0,static_cast(positions_quad.size()/3)); - program->release(); + tex_rendering_program->release(); vaos[TexturedCutplane]->release(); break; @@ -469,6 +519,7 @@ private: std::vector vaos; mutable int m_grid_size; mutable bool m_fast_distance; + mutable QOpenGLShaderProgram* tex_rendering_program; mutable Point_distance m_distance_function[100][100]; mutable GLuint textureId; mutable Texture *texture; @@ -658,21 +709,19 @@ private: } //vao for the textured cutting planes { - program = getShaderProgram(PROGRAM_WITH_TEXTURE); - program->bind(); + tex_rendering_program->bind(); vaos[TexturedCutplane]->bind(); buffers[Facets_vertices].bind(); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_FLOAT,0,3); + tex_rendering_program->enableAttributeArray("vertex"); + tex_rendering_program->setAttributeBuffer("vertex",GL_FLOAT,0,3); buffers[Facets_vertices].release(); buffers[UVCoords].bind(); buffers[UVCoords].allocate(tex_map.data(), static_cast(tex_map.size()*sizeof(float))); - program->attributeLocation("v_texCoord"); - program->setAttributeBuffer("v_texCoord",GL_FLOAT,0,2); - program->enableAttributeArray("v_texCoord"); + tex_rendering_program->attributeLocation("tex_coord"); + tex_rendering_program->setAttributeBuffer("tex_coord",GL_FLOAT,0,2); + tex_rendering_program->enableAttributeArray("tex_coord"); buffers[UVCoords].release(); - program->release(); viewer->glBindTexture(GL_TEXTURE_2D, textureId); viewer->glTexImage2D(GL_TEXTURE_2D, @@ -688,10 +737,24 @@ private: viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE ); viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE ); + tex_rendering_program->release(); } are_buffers_filled = true; } + void attribTexBuffers(CGAL::Three::Viewer_interface* viewer)const + { + QMatrix4x4 mvpMatrix; + double mat[16]; + viewer->camera()->getModelViewProjectionMatrix(mat); + for(int i=0; i < 16; i++) + { + mvpMatrix.data()[i] = (float)mat[i]; + } + tex_rendering_program->bind(); + tex_rendering_program->setUniformValue("mvp_matrix", mvpMatrix); + tex_rendering_program->release(); + } }; using namespace CGAL::Three; class Polyhedron_demo_cut_plugin : From fc68989e6023d34e1847008e840cb1e4e0992fd9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 1 Jul 2016 12:41:55 +0200 Subject: [PATCH 09/15] Use Simple_cartesian to greatly enhance the performance. --- AABB_tree/demo/AABB_tree/Scene.cpp | 2 - .../Plugins/AABB_tree/Cut_plugin.cpp | 114 +++++++++++------- 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/AABB_tree/demo/AABB_tree/Scene.cpp b/AABB_tree/demo/AABB_tree/Scene.cpp index 5edece4661a..a87cd91e890 100644 --- a/AABB_tree/demo/AABB_tree/Scene.cpp +++ b/AABB_tree/demo/AABB_tree/Scene.cpp @@ -1111,7 +1111,6 @@ void Scene::compute_distance_function(const Tree& tree) { // Get transformation Aff_transformation t = frame_transformation(); - m_max_distance_function = FT(0); FT diag = bbox_diag(); @@ -1126,7 +1125,6 @@ void Scene::compute_distance_function(const Tree& tree) for(int j=0 ; j #include #include -#include +//#include +#include #include @@ -60,15 +61,27 @@ public: GLubyte* getData(){return data; } }; -//typedef CGAL::Simple_cartesian Epic_kernel; -typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; +typedef CGAL::Simple_cartesian Simple_kernel; -typedef CGAL::AABB_face_graph_triangle_primitive Facet_primitive; -typedef CGAL::AABB_traits Facet_traits; +//typedef CGAL::Exact_predicates_inexact_constructions_kernel Simple_kernel; +struct PPMAP +{ + typedef boost::readable_property_map_tag category; + typedef Simple_kernel::Point_3 value_type; + typedef const Simple_kernel::Point_3& reference; + typedef boost::graph_traits::vertex_descriptor key_type; + friend reference get(const PPMAP& pm, key_type v) + { + return reinterpret_cast(v->point()); + } +}; + +typedef CGAL::AABB_face_graph_triangle_primitive Facet_primitive; +typedef CGAL::AABB_traits Facet_traits; typedef CGAL::AABB_tree Facet_tree; -typedef CGAL::AABB_halfedge_graph_segment_primitive Edge_primitive; -typedef CGAL::AABB_traits Edge_traits; +typedef CGAL::AABB_halfedge_graph_segment_primitive Edge_primitive; +typedef CGAL::AABB_traits Edge_traits; typedef CGAL::AABB_tree Edge_tree; @@ -251,7 +264,7 @@ public: } public: - std::vector edges; + std::vector edges; private: mutable std::vector positions_lines; @@ -282,8 +295,8 @@ private: for(size_t i = 0, end = edges.size(); i < end; ++i) { - const Epic_kernel::Point_3& a = edges[i].source(); - const Epic_kernel::Point_3& b = edges[i].target(); + const Simple_kernel::Point_3& a = edges[i].source(); + const Simple_kernel::Point_3& b = edges[i].target(); positions_lines.push_back(a.x()); positions_lines.push_back(a.y()); positions_lines.push_back(a.z()); positions_lines.push_back(b.x()); positions_lines.push_back(b.y()); positions_lines.push_back(b.z()); } @@ -307,9 +320,11 @@ private: class Q_DECL_EXPORT Scene_aabb_plane_item : public Scene_plane_item { + Q_OBJECT + public: - typedef Kernel::FT FT; + typedef Simple_kernel::FT FT; enum Cut_planes_types { UNSIGNED_FACETS = 0, SIGNED_FACETS, UNSIGNED_EDGES, CUT_SEGMENTS }; @@ -405,6 +420,7 @@ public: { std::cerr<<"linking Program FAILED"< Point_distance; + typedef std::pair Point_distance; std::vector vaos; mutable int m_grid_size; mutable bool m_fast_distance; @@ -527,7 +543,7 @@ private: mutable Color_ramp m_red_ramp; mutable Color_ramp m_blue_ramp; mutable Color_ramp m_thermal_ramp; - mutable Kernel::FT m_max_distance_function; + mutable Simple_kernel::FT m_max_distance_function; mutable std::vector tex_map; mutable Cut_planes_types m_cut_plane; mutable std::vector buffers; @@ -539,12 +555,12 @@ private: return (FT)(a + (b - a) * r); } - Kernel::Vector_3 random_vector() const + Simple_kernel::Vector_3 random_vector() const { FT x = random_in(0.0,1.0); FT y = random_in(0.0,1.0); FT z = random_in(0.0,1.0); - return Kernel::Vector_3(x,y,z); + return Simple_kernel::Vector_3(x,y,z); } template @@ -554,10 +570,9 @@ private: const GLdouble* m = frame->matrix(); // OpenGL matrices are row-major matrices - Kernel::Aff_transformation_3 t = Kernel::Aff_transformation_3 (m[0], m[4], m[8], m[12], + Simple_kernel::Aff_transformation_3 t = Simple_kernel::Aff_transformation_3 (m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14]); - m_max_distance_function = FT(0); FT diag = scene_diag(); const FT dx = 2*diag; @@ -568,12 +583,11 @@ private: for(int i=0 ; ivalues()) @@ -586,33 +600,33 @@ private: min_tree = tree; } } - m_distance_function[i][j] = Point_distance(query,min); m_max_distance_function = (std::max)(min, m_max_distance_function); - - if(is_signed) + } + } + if(is_signed) + { + for(int i=0 ; inumber_of_intersected_primitives(ray); FT sign ( (nbi&1) == 0 ? 1 : -1); m_distance_function[i][j].second = sign * unsigned_distance; } - } } } void compute_texture(int i, int j,Color_ramp pos_ramp ,Color_ramp neg_ramp)const { - - const FT& d00 = m_distance_function[i][j].second; // determines grey level FT i00 = (double)std::fabs(d00) / m_max_distance_function; @@ -626,8 +640,6 @@ private: } void computeElements()const { - Scene_plane_item::compute_normals_and_vertices(); - switch(m_cut_plane) { @@ -651,6 +663,7 @@ private: switch(m_cut_plane) { case SIGNED_FACETS: + for( int i=0 ; i < texture->getWidth(); i++ ) { for( int j=0 ; j < texture->getHeight() ; j++) @@ -862,6 +875,8 @@ public Q_SLOTS: void updateCutPlane() { + if(plane_item->manipulatedFrame()->isSpinning()) + plane_item->set_fast_distance(true); ready_to_cut = true; QTimer::singleShot(0,this,SLOT(cut())); } @@ -1015,14 +1030,20 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { if(!poly_item) continue; if(facet_trees.find(poly_item) == facet_trees.end()) { - facet_trees[poly_item] = new Facet_tree(faces(*(poly_item->polyhedron())).first, - faces(*(poly_item->polyhedron())).second, - *poly_item->polyhedron() ); + facet_trees[poly_item] = new Facet_tree(); + PPMAP pmap; + facet_trees[poly_item]->insert(faces(*(poly_item->polyhedron())).first, + faces(*(poly_item->polyhedron())).second, + *poly_item->polyhedron(), + pmap ); } if(edge_trees.find(poly_item) == edge_trees.end()) { - edge_trees[poly_item] = new Edge_tree(edges(*poly_item->polyhedron()).first, - edges(*poly_item->polyhedron()).second, - *poly_item->polyhedron()); + edge_trees[poly_item] = new Edge_tree(); + PPMAP pmap; + edge_trees[poly_item]->insert(edges(*poly_item->polyhedron()).first, + edges(*poly_item->polyhedron()).second, + *poly_item->polyhedron(), + pmap); } } plane_item->set_facet_trees(&facet_trees); @@ -1088,7 +1109,7 @@ void Polyhedron_demo_cut_plugin::computeIntersection() const qglviewer::Vec& pos = plane_item->manipulatedFrame()->position(); const qglviewer::Vec& n = plane_item->manipulatedFrame()->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); - Epic_kernel::Plane_3 plane(n[0], n[1], n[2], - n * pos); + Simple_kernel::Plane_3 plane(n[0], n[1], n[2], - n * pos); //std::cerr << plane << std::endl; edges_item->edges.clear(); QTime time; @@ -1100,11 +1121,13 @@ void Polyhedron_demo_cut_plugin::computeIntersection() if(!poly_item) continue; Facet_trees::iterator it = facet_trees.find(poly_item); if(it == facet_trees.end()) { + PPMAP pmap; it = facet_trees.insert(facet_trees.begin(), poly_item, new Facet_tree(faces(*(poly_item->polyhedron())).first, faces(*(poly_item->polyhedron())).second, - *poly_item->polyhedron() )); + *poly_item->polyhedron(), + pmap )); Scene_aabb_item* aabb_item = new Scene_aabb_item(*it.value()); aabb_item->setName(tr("AABB tree of %1").arg(poly_item->name())); aabb_item->setRenderingMode(Wireframe); @@ -1123,8 +1146,8 @@ void Polyhedron_demo_cut_plugin::computeIntersection() for ( std::vector::iterator it = intersections.begin(), end = intersections.end() ; it != end ; ++it ) { - const Epic_kernel::Segment_3* inter_seg = - CGAL::object_cast(&(it->first)); + const Simple_kernel::Segment_3* inter_seg = + CGAL::object_cast(&(it->first)); if ( NULL != inter_seg ) edges_item->edges.push_back(*inter_seg); @@ -1140,21 +1163,20 @@ void Polyhedron_demo_cut_plugin::computeIntersection() void Polyhedron_demo_cut_plugin::cut() { - plane_item->set_fast_distance(true); switch(plane_item->cutPlaneType()) { case Scene_aabb_plane_item::CUT_SEGMENTS: if(ready_to_cut) { - computeIntersection(); ready_to_cut = false; + computeIntersection(); } break; default: if(ready_to_cut) { - plane_item->invalidateOpenGLBuffers(); ready_to_cut = false; + plane_item->invalidateOpenGLBuffers(); } } } From 4ebaa0de734f1596a9843fd6c730231a7841ac1f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 1 Jul 2016 17:21:06 +0200 Subject: [PATCH 10/15] Fix updating bugs at creation and deletion of items. --- .../Plugins/AABB_tree/Cut_plugin.cpp | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index e938c9aa0fd..69d0f51820e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -896,10 +896,22 @@ public Q_SLOTS: void deleteTrees(CGAL::Three::Scene_item* sender) { Scene_polyhedron_item* item = qobject_cast(sender); + if(!item) + return; delete facet_trees[item]; facet_trees.remove(item); delete edge_trees[item]; edge_trees.remove(item); + if(facet_trees.empty()) + { + scene->erase(scene->item_id(plane_item)); + scene->erase(scene->item_id(edges_item)); + } + else + { + ready_to_cut = true; + cut(); + } } void updateTrees(int id); private: @@ -1036,6 +1048,12 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { faces(*(poly_item->polyhedron())).second, *poly_item->polyhedron(), pmap ); + Scene_aabb_item* aabb_item = new Scene_aabb_item(*facet_trees[poly_item]); + aabb_item->setName(tr("AABB tree of %1").arg(poly_item->name())); + aabb_item->setRenderingMode(Wireframe); + aabb_item->setColor(Qt::black); + aabb_item->setVisible(false); + scene->addItem(aabb_item); } if(edge_trees.find(poly_item) == edge_trees.end()) { edge_trees[poly_item] = new Edge_tree(); @@ -1048,6 +1066,8 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { } plane_item->set_facet_trees(&facet_trees); plane_item->set_edge_trees(&edge_trees); + ready_to_cut = true; + cut(); } void Polyhedron_demo_cut_plugin::Intersection() @@ -1115,28 +1135,8 @@ void Polyhedron_demo_cut_plugin::computeIntersection() QTime time; time.start(); bool does_intersect = false; - for(int i = 0, end = scene->numberOfEntries(); i < end; ++i) { - CGAL::Three::Scene_item* item = scene->item(i); - Scene_polyhedron_item* poly_item = qobject_cast(item); - if(!poly_item) continue; - Facet_trees::iterator it = facet_trees.find(poly_item); - if(it == facet_trees.end()) { - PPMAP pmap; - it = facet_trees.insert(facet_trees.begin(), - poly_item, - new Facet_tree(faces(*(poly_item->polyhedron())).first, - faces(*(poly_item->polyhedron())).second, - *poly_item->polyhedron(), - pmap )); - Scene_aabb_item* aabb_item = new Scene_aabb_item(*it.value()); - aabb_item->setName(tr("AABB tree of %1").arg(poly_item->name())); - aabb_item->setRenderingMode(Wireframe); - aabb_item->setColor(Qt::black); - aabb_item->setVisible(false); - scene->addItem(aabb_item); - } - //std::cerr << "size: " << it->second->size() << std::endl; - + for(Facet_trees::iterator it = facet_trees.begin(); it != facet_trees.end(); ++it) + { if(!CGAL::do_intersect(plane, it.value()->bbox())) continue; does_intersect = true; @@ -1156,7 +1156,7 @@ void Polyhedron_demo_cut_plugin::computeIntersection() if(does_intersect) messages->information(QString("cut (%1 ms). %2 edges.").arg(time.elapsed()).arg(edges_item->edges.size())); edges_item->invalidateOpenGLBuffers(); - scene->itemChanged(edges_item); + edges_item->itemChanged(); ready_to_cut = false; QApplication::restoreOverrideCursor(); } @@ -1168,7 +1168,6 @@ void Polyhedron_demo_cut_plugin::cut() case Scene_aabb_plane_item::CUT_SEGMENTS: if(ready_to_cut) { - ready_to_cut = false; computeIntersection(); } break; From e5db243366befe0ef115ee797bf2afb8b5817a6e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 4 Jul 2016 14:36:27 +0200 Subject: [PATCH 11/15] Parallelize the texture computing if linked with TBB. On elephant.off, the computation is done in 250 ms when parallelized against 600ms when not. --- .../Plugins/AABB_tree/Cut_plugin.cpp | 190 +++++++++++++++--- 1 file changed, 160 insertions(+), 30 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 69d0f51820e..045b31dd7df 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -33,6 +33,109 @@ #include #include #include + +#ifdef CGAL_LINKED_WITH_TBB +#include +#include +#include +#endif // CGAL_LINKED_WITH_TBB + +typedef CGAL::Simple_cartesian Simple_kernel; +typedef Simple_kernel::FT FT; +typedef Simple_kernel::Point_3 Point; +typedef std::pair Point_distance; + + +FT random_in(const double a, + const double b) +{ + double r = rand() / (double)RAND_MAX; + return (FT)(a + (b - a) * r); +} + +Simple_kernel::Vector_3 random_vector() +{ + FT x = random_in(0.0,1.0); + FT y = random_in(0.0,1.0); + FT z = random_in(0.0,1.0); + return Simple_kernel::Vector_3(x,y,z); +} + +#ifdef CGAL_LINKED_WITH_TBB +//functor for tbb parallelization +template +class fill_grid_size { + std::size_t grid_size; + Point_distance (&distance_function)[100][100]; + FT diag; + FT& max_distance_function; + QMap *trees; + bool is_signed; + qglviewer::ManipulatedFrame* frame; +public: + fill_grid_size(std::size_t grid_size, FT diag, Point_distance (&distance_function)[100][100], + FT& max_distance_function,QMap* trees, + bool is_signed, qglviewer::ManipulatedFrame* frame) + : grid_size(grid_size), distance_function (distance_function), diag(diag), + max_distance_function(max_distance_function), + trees(trees), is_signed(is_signed), frame(frame) + { + } + void operator()(const tbb::blocked_range& r) const + { + const GLdouble* m = frame->matrix(); + Simple_kernel::Aff_transformation_3 transfo = Simple_kernel::Aff_transformation_3 (m[0], m[4], m[8], m[12], + m[1], m[5], m[9], m[13], + m[2], m[6], m[10], m[14]); + const FT dx = 2*diag; + const FT dy = 2*diag; + const FT z (0); + const FT fd = FT(1); + Tree *min_tree = NULL ; + for( std::size_t t = r.begin(); t != r.end(); ++t) + { + int i(t%grid_size), j(t/grid_size); + FT x = -diag/fd + FT(i)/FT(grid_size) * dx; + { + FT y = -diag/fd + FT(j)/FT(grid_size) * dy; + + Point query = transfo( Point(x,y,z) ); + FT min = DBL_MAX; + + Q_FOREACH(Tree *tree, trees->values()) + { + FT dist = CGAL::sqrt( tree->squared_distance(query) ); + if(dist < min) + { + min = dist; + if(is_signed) + min_tree = tree; + } + } + distance_function[i][j] = Point_distance(query,min); + max_distance_function = (std::max)(min, max_distance_function); + + if(is_signed) + { + typedef typename Tree::size_type size_type; + Simple_kernel::Vector_3 random_vec = random_vector(); + + const Simple_kernel::Point_3& p = distance_function[i][j].first; + const FT unsigned_distance = distance_function[i][j].second; + + // get sign through ray casting (random vector) + Simple_kernel::Ray_3 ray(p, random_vec); + size_type nbi = min_tree->number_of_intersected_primitives(ray); + + FT sign ( (nbi&1) == 0 ? 1 : -1); + distance_function[i][j].second = sign * unsigned_distance; + } + } + } + } +}; +#endif + const int slow_distance_grid_size = 100; const int fast_distance_grid_size = 20; class Texture{ @@ -548,33 +651,17 @@ private: mutable Cut_planes_types m_cut_plane; mutable std::vector buffers; - FT random_in(const double a, - const double b)const - { - double r = rand() / (double)RAND_MAX; - return (FT)(a + (b - a) * r); - } - - Simple_kernel::Vector_3 random_vector() const - { - FT x = random_in(0.0,1.0); - FT y = random_in(0.0,1.0); - FT z = random_in(0.0,1.0); - return Simple_kernel::Vector_3(x,y,z); - } - template void compute_distance_function(QMap *trees, bool is_signed = false)const { - // Get transformation - const GLdouble* m = frame->matrix(); - // OpenGL matrices are row-major matrices + m_max_distance_function = FT(0); + FT diag = scene_diag(); +#ifndef CGAL_LINKED_WITH_TBB + const GLdouble* m = frame->matrix(); Simple_kernel::Aff_transformation_3 t = Simple_kernel::Aff_transformation_3 (m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14]); - m_max_distance_function = FT(0); - FT diag = scene_diag(); const FT dx = 2*diag; const FT dy = 2*diag; const FT z (0); @@ -623,24 +710,54 @@ private: m_distance_function[i][j].second = sign * unsigned_distance; } } +#else + fill_grid_size f(m_grid_size, diag, m_distance_function, m_max_distance_function, trees, is_signed, frame); + tbb::parallel_for(tbb::blocked_range(0, m_grid_size*m_grid_size), f); +#endif } void compute_texture(int i, int j,Color_ramp pos_ramp ,Color_ramp neg_ramp)const { - const FT& d00 = m_distance_function[i][j].second; - // determines grey level - FT i00 = (double)std::fabs(d00) / m_max_distance_function; + const FT& d00 = m_distance_function[i][j].second; + // determines grey level + FT i00 = (double)std::fabs(d00) / m_max_distance_function; - if(d00 > 0.0) - texture->setData(i,j,255*pos_ramp.r(i00),255*pos_ramp.g(i00),255*pos_ramp.b(i00)); - else - texture->setData(i,j,255*neg_ramp.r(i00),255*neg_ramp.g(i00),255*neg_ramp.b(i00)); + if(d00 > 0.0) + texture->setData(i,j,255*pos_ramp.r(i00),255*pos_ramp.g(i00),255*pos_ramp.b(i00)); + else + texture->setData(i,j,255*neg_ramp.r(i00),255*neg_ramp.g(i00),255*neg_ramp.b(i00)); } - void computeElements()const - { +#ifdef CGAL_LINKED_WITH_TBB + class fill_texture + { + std::size_t grid_size; + Color_ramp pos_ramp; + Color_ramp neg_ramp; + Scene_aabb_plane_item* item; + public : + fill_texture(std::size_t grid_size, + Color_ramp pos_ramp, + Color_ramp neg_ramp, + Scene_aabb_plane_item* item + ) + :grid_size(grid_size), pos_ramp(pos_ramp), neg_ramp(neg_ramp), item(item) {} + + void operator()(const tbb::blocked_range& r) const + { + for(std::size_t t = r.begin(); t!= r.end(); ++t) + { + int i(t%grid_size), j(t/grid_size); + item->compute_texture(i,j, pos_ramp, neg_ramp); + } + } + }; +#endif + + void computeElements() + { switch(m_cut_plane) { case UNSIGNED_FACETS: @@ -663,7 +780,8 @@ private: switch(m_cut_plane) { case SIGNED_FACETS: - + { +#ifndef CGAL_LINKED_WITH_TBB for( int i=0 ; i < texture->getWidth(); i++ ) { for( int j=0 ; j < texture->getHeight() ; j++) @@ -671,9 +789,16 @@ private: compute_texture(i,j,m_red_ramp,m_blue_ramp); } } +#else + fill_texture f(m_grid_size, m_red_ramp, m_blue_ramp, this); + tbb::parallel_for(tbb::blocked_range(0, m_grid_size * m_grid_size), f); +#endif break; + } case UNSIGNED_FACETS: case UNSIGNED_EDGES: + { + #ifndef CGAL_LINKED_WITH_TBB for( int i=0 ; i < texture->getWidth(); i++ ) { for( int j=0 ; j < texture->getHeight() ; j++) @@ -681,7 +806,12 @@ private: compute_texture(i,j,m_thermal_ramp,m_thermal_ramp); } } +#else + fill_texture f(m_grid_size, m_thermal_ramp, m_thermal_ramp, this); + tbb::parallel_for(tbb::blocked_range(0, m_grid_size * m_grid_size), f); +#endif break; + } default: break; } From 1f42d4013bd7735e338deef54fc3a5aa5e70ee8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 4 Jul 2016 18:42:18 +0200 Subject: [PATCH 12/15] remove unused parameter --- Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 045b31dd7df..56d8d07fb55 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -173,7 +173,7 @@ struct PPMAP typedef Simple_kernel::Point_3 value_type; typedef const Simple_kernel::Point_3& reference; typedef boost::graph_traits::vertex_descriptor key_type; - friend reference get(const PPMAP& pm, key_type v) + friend reference get(const PPMAP&, key_type v) { return reinterpret_cast(v->point()); } From 18e11fe41998599485ca656910746b4471faaf69 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 5 Jul 2016 08:51:52 +0200 Subject: [PATCH 13/15] Change functors name. --- .../Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 56d8d07fb55..6af73442d76 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -64,7 +64,7 @@ Simple_kernel::Vector_3 random_vector() #ifdef CGAL_LINKED_WITH_TBB //functor for tbb parallelization template -class fill_grid_size { +class FillGridSize { std::size_t grid_size; Point_distance (&distance_function)[100][100]; FT diag; @@ -73,7 +73,7 @@ class fill_grid_size { bool is_signed; qglviewer::ManipulatedFrame* frame; public: - fill_grid_size(std::size_t grid_size, FT diag, Point_distance (&distance_function)[100][100], + FillGridSize(std::size_t grid_size, FT diag, Point_distance (&distance_function)[100][100], FT& max_distance_function,QMap* trees, bool is_signed, qglviewer::ManipulatedFrame* frame) : grid_size(grid_size), distance_function (distance_function), diag(diag), @@ -711,7 +711,7 @@ private: } } #else - fill_grid_size f(m_grid_size, diag, m_distance_function, m_max_distance_function, trees, is_signed, frame); + FillGridSize f(m_grid_size, diag, m_distance_function, m_max_distance_function, trees, is_signed, frame); tbb::parallel_for(tbb::blocked_range(0, m_grid_size*m_grid_size), f); #endif } @@ -731,14 +731,14 @@ private: } #ifdef CGAL_LINKED_WITH_TBB - class fill_texture + class FillTexture { std::size_t grid_size; Color_ramp pos_ramp; Color_ramp neg_ramp; Scene_aabb_plane_item* item; public : - fill_texture(std::size_t grid_size, + FillTexture(std::size_t grid_size, Color_ramp pos_ramp, Color_ramp neg_ramp, Scene_aabb_plane_item* item @@ -790,7 +790,7 @@ private: } } #else - fill_texture f(m_grid_size, m_red_ramp, m_blue_ramp, this); + FillTexture f(m_grid_size, m_red_ramp, m_blue_ramp, this); tbb::parallel_for(tbb::blocked_range(0, m_grid_size * m_grid_size), f); #endif break; @@ -807,7 +807,7 @@ private: } } #else - fill_texture f(m_grid_size, m_thermal_ramp, m_thermal_ramp, this); + FillTexture f(m_grid_size, m_thermal_ramp, m_thermal_ramp, this); tbb::parallel_for(tbb::blocked_range(0, m_grid_size * m_grid_size), f); #endif break; From 9adbc52f8b81f954482e21a7aa621496df48fec0 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 5 Jul 2016 16:02:15 +0200 Subject: [PATCH 14/15] Fix segfault --- .../Plugins/AABB_tree/Cut_plugin.cpp | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 6af73442d76..afa24f17120 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -1028,14 +1028,22 @@ public Q_SLOTS: Scene_polyhedron_item* item = qobject_cast(sender); if(!item) return; - delete facet_trees[item]; - facet_trees.remove(item); - delete edge_trees[item]; - edge_trees.remove(item); + if(facet_trees.keys().contains(item)) + { + delete facet_trees[item]; + facet_trees.remove(item); + } + if(edge_trees.keys().contains(item)) + { + delete edge_trees[item]; + edge_trees.remove(item); + } if(facet_trees.empty()) { - scene->erase(scene->item_id(plane_item)); - scene->erase(scene->item_id(edges_item)); + if(plane_item) + scene->erase(scene->item_id(plane_item)); + if(edges_item) + scene->erase(scene->item_id(edges_item)); } else { @@ -1293,6 +1301,8 @@ void Polyhedron_demo_cut_plugin::computeIntersection() void Polyhedron_demo_cut_plugin::cut() { + if(!plane_item) + return; switch(plane_item->cutPlaneType()) { case Scene_aabb_plane_item::CUT_SEGMENTS: From 07f94ebf0bbe8c930df7ad632ddc51dbe0af84c3 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 6 Jul 2016 17:07:17 +0200 Subject: [PATCH 15/15] Fix display info and indicate current state of the plugin in the menu. --- .../Plugins/AABB_tree/Cut_plugin.cpp | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index afa24f17120..b051061e2b5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -246,7 +246,6 @@ public: { computeElements(); are_buffers_filled = false; - compute_bbox(); } public: const Facet_tree& tree; @@ -1023,6 +1022,15 @@ public Q_SLOTS: { plane_item = NULL; } + void uncheckActions() + { + Q_FOREACH(QAction* action, _actions) + if(action->isChecked()) + { + action->setChecked(false); + return; + } + } void deleteTrees(CGAL::Three::Scene_item* sender) { Scene_polyhedron_item* item = qobject_cast(sender); @@ -1053,6 +1061,7 @@ public Q_SLOTS: } void updateTrees(int id); private: + QList_actions; void createCutPlane(); CGAL::Three::Scene_interface* scene; Messages_interface* messages; @@ -1097,6 +1106,7 @@ void Polyhedron_demo_cut_plugin::init(QMainWindow* mainWindow, actionSignedFacets->setProperty("subMenuName","3D Fast Intersection and Distance Computation"); actionUnsignedFacets->setProperty("subMenuName","3D Fast Intersection and Distance Computation"); actionUnsignedEdges->setProperty("subMenuName","3D Fast Intersection and Distance Computation"); + ready_to_cut = true; connect(actionIntersection, SIGNAL(triggered()), this, SLOT(Intersection())); @@ -1116,13 +1126,23 @@ void Polyhedron_demo_cut_plugin::init(QMainWindow* mainWindow, QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); + _actions << actionIntersection + << actionSignedFacets + << actionUnsignedFacets + << actionUnsignedEdges; + QActionGroup *group = new QActionGroup(mainWindow); + group->setExclusive(true); + + Q_FOREACH(QAction *action, _actions) + { + action->setActionGroup(group); + action->setCheckable(true); + } + } QList Polyhedron_demo_cut_plugin::actions() const { - return QList() << actionIntersection - << actionSignedFacets - << actionUnsignedFacets - << actionUnsignedEdges; + return _actions; } void Polyhedron_demo_cut_plugin::updateTrees(int id) @@ -1158,6 +1178,8 @@ void Polyhedron_demo_cut_plugin::createCutPlane() { this, SLOT(updateCutPlane())); connect(plane_item, SIGNAL(aboutToBeDestroyed()), this, SLOT(resetPlane())); + connect(plane_item, SIGNAL(aboutToBeDestroyed()), + this, SLOT(uncheckActions())); if(updating) { scene->replaceItem(plane_id, plane_item)->deleteLater();