From b9ea69e5c3dc3aa976ac0381d0b2b51c5ef9c2c7 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 6 Apr 2016 16:20:25 +0200 Subject: [PATCH] Do no always compute the AABB tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The c3t3 item has an option "Show tetrahedra". - The AABB tree is built lazily, when needed. - The AABB tree data member is moved in `Scene_c3t3_item_priv`. --- .../demo/Polyhedron/Scene_c3t3_item.cpp | 178 +++++++++++++----- Polyhedron/demo/Polyhedron/Scene_c3t3_item.h | 29 +-- 2 files changed, 132 insertions(+), 75 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index 32029db933b..8863ec24c40 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -7,12 +7,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -20,12 +22,82 @@ #include #include -struct Scene_c3t3_item_priv { - Scene_c3t3_item_priv() : c3t3() {} - Scene_c3t3_item_priv(const C3t3& c3t3_) : c3t3(c3t3_) {} +#include +#include +#include +typedef CGAL::AABB_C3T3_triangle_primitive Primitive; +typedef CGAL::AABB_traits Traits; +typedef CGAL::AABB_tree Tree; +typedef Tree::Point_and_primitive_id Point_and_primitive_id; + + +struct Scene_c3t3_item_priv { + Scene_c3t3_item_priv(Scene_c3t3_item* item) + : item(item), c3t3() + { + init_default_values(); + } + Scene_c3t3_item_priv(const C3t3& c3t3_, Scene_c3t3_item* item) + : item(item), c3t3(c3t3_) + { + init_default_values(); + } + + void init_default_values() { + show_tetrahedra = false; + is_aabb_tree_built = false; + } + + void compute_intersection(const Primitive& facet); + + void fill_aabb_tree() { + if(item->isEmpty()) return; + QGuiApplication::setOverrideCursor(Qt::WaitCursor); + CGAL::Real_timer timer; + timer.start(); + tree.clear(); + for (Tr::Finite_facets_iterator + fit = c3t3.triangulation().finite_facets_begin(), + end = c3t3.triangulation().finite_facets_end(); + fit != end; ++fit) + { + Tr::Cell_handle ch = fit->first, nh =ch->neighbor(fit->second); + + if( (!c3t3.is_in_complex(ch)) && (!c3t3.is_in_complex(nh)) ) + continue; + + if(c3t3.is_in_complex(ch)){ + tree.insert(Primitive(fit)); + } else{ + int ni = nh->index(ch); + tree.insert(Primitive(Tr::Facet(nh,ni))); + } + } + tree.build(); + std::cerr << "C3t3 facets AABB tree built in " << timer.time() + << " wall-clock seconds\n"; + + is_aabb_tree_built = true; + QGuiApplication::restoreOverrideCursor(); + } + + Scene_c3t3_item* item; C3t3 c3t3; + Tree tree; QVector colors; + bool show_tetrahedra; + bool is_aabb_tree_built; +}; + +struct Set_show_tetrahedra { + Scene_c3t3_item_priv* priv; + Set_show_tetrahedra(Scene_c3t3_item_priv* priv) : priv(priv) {} + void operator()(bool b) { + priv->show_tetrahedra = b; + priv->item->changed(); + priv->item->itemChanged(); + } }; void Scene_c3t3_item::compile_shaders() @@ -95,7 +167,7 @@ double complex_diag(const Scene_item* item) { Scene_c3t3_item::Scene_c3t3_item() : Scene_item(NumberOfBuffers, NumberOfVaos) - , d(new Scene_c3t3_item_priv()) + , d(new Scene_c3t3_item_priv(this)) , frame(new ManipulatedFrame()) , last_known_scene(NULL) , data_item_(NULL) @@ -122,7 +194,7 @@ Scene_c3t3_item::Scene_c3t3_item() Scene_c3t3_item::Scene_c3t3_item(const C3t3& c3t3) : Scene_item(NumberOfBuffers, NumberOfVaos) - , d(new Scene_c3t3_item_priv(c3t3)) + , d(new Scene_c3t3_item_priv(c3t3, this)) , frame(new ManipulatedFrame()) , last_known_scene(NULL) , data_item_(NULL) @@ -229,7 +301,9 @@ Scene_c3t3_item::c3t3_changed() // Rebuild histogram build_histogram(); - + + d->tree.clear(); + d->is_aabb_tree_built = false; } QPixmap @@ -505,7 +579,7 @@ void Scene_c3t3_item::draw(CGAL::Three::Viewer_interface* viewer) const { vaos[Facets]->release(); - if(!frame->isManipulated()) { + if(d->show_tetrahedra && !frame->isManipulated()) { if (!are_intersection_buffers_filled) { ncthis->compute_intersections(); @@ -603,7 +677,7 @@ void Scene_c3t3_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const { program->release(); vaos[Edges]->release(); - if(!frame->isManipulated()) { + if(d->show_tetrahedra && !frame->isManipulated()) { if (!are_intersection_buffers_filled) { ncthis->compute_intersections(); @@ -822,6 +896,13 @@ QMenu* Scene_c3t3_item::contextMenu() actionShowSpheres->setObjectName("actionShowSpheres"); connect(actionShowSpheres, SIGNAL(toggled(bool)), this, SLOT(show_spheres(bool))); + + QAction* actionShowTets = + menu->addAction(tr("Show &tetrahedra")); + actionShowTets->setCheckable(true); + actionShowTets->setObjectName("actionShowTets"); + connect(actionShowTets, &QAction::toggled, Set_show_tetrahedra(this->d)); + menu->setProperty(prop_name, true); } return menu; @@ -1052,62 +1133,81 @@ void Scene_c3t3_item::initialize_buffers(CGAL::Three::Viewer_interface *viewer) -void Scene_c3t3_item::compute_intersection(const Primitive& facet) +void Scene_c3t3_item_priv::compute_intersection(const Primitive& facet) { const Kernel::Point_3& pa = facet.id().first->vertex(0)->point(); const Kernel::Point_3& pb = facet.id().first->vertex(1)->point(); const Kernel::Point_3& pc = facet.id().first->vertex(2)->point(); const Kernel::Point_3& pd = facet.id().first->vertex(3)->point(); - QColor color = d->colors[facet.id().first->subdomain_index()].darker(150); + QColor color = this->colors[facet.id().first->subdomain_index()].darker(150); for(int i=0; i < 12;i++){ - f_colors.push_back(color.redF());f_colors.push_back(color.greenF());f_colors.push_back(color.blueF()); + item->f_colors.push_back(color.redF()); + item->f_colors.push_back(color.greenF()); + item->f_colors.push_back(color.blueF()); } - draw_triangle(pb, pa, pc, true); - draw_triangle(pa, pb, pd, true); - draw_triangle(pa, pd, pc, true); - draw_triangle(pb, pc, pd, true); + item->draw_triangle(pb, pa, pc, true); + item->draw_triangle(pa, pb, pd, true); + item->draw_triangle(pa, pd, pc, true); + item->draw_triangle(pb, pc, pd, true); - draw_triangle_edges(pb, pa, pc); - draw_triangle_edges(pa, pb, pd); - draw_triangle_edges(pa, pd, pc); - draw_triangle_edges(pb, pc, pd); + item->draw_triangle_edges(pb, pa, pc); + item->draw_triangle_edges(pa, pb, pd); + item->draw_triangle_edges(pa, pd, pc); + item->draw_triangle_edges(pb, pc, pd); { Tr::Cell_handle nh = facet.id().first->neighbor(facet.id().second); - if(c3t3().is_in_complex(nh)){ + if(c3t3.is_in_complex(nh)){ const Kernel::Point_3& pa = nh->vertex(0)->point(); const Kernel::Point_3& pb = nh->vertex(1)->point(); const Kernel::Point_3& pc = nh->vertex(2)->point(); const Kernel::Point_3& pd = nh->vertex(3)->point(); for(int i=0; i < 12;i++){ - f_colors.push_back(color.redF());f_colors.push_back(color.greenF());f_colors.push_back(color.blueF()); + item->f_colors.push_back(color.redF()); + item->f_colors.push_back(color.greenF()); + item->f_colors.push_back(color.blueF()); } - draw_triangle(pb, pa, pc, true); - draw_triangle(pa, pb, pd, true); - draw_triangle(pa, pd, pc, true); - draw_triangle(pb, pc, pd, true); + item->draw_triangle(pb, pa, pc, true); + item->draw_triangle(pa, pb, pd, true); + item->draw_triangle(pa, pd, pc, true); + item->draw_triangle(pb, pc, pd, true); - draw_triangle_edges(pb, pa, pc); - draw_triangle_edges(pa, pb, pd); - draw_triangle_edges(pa, pd, pc); - draw_triangle_edges(pb, pc, pd); + item->draw_triangle_edges(pb, pa, pc); + item->draw_triangle_edges(pa, pb, pd); + item->draw_triangle_edges(pa, pd, pc); + item->draw_triangle_edges(pb, pc, pd); } } } +struct Compute_intersection { + Scene_c3t3_item_priv& item_priv; + + Compute_intersection(Scene_c3t3_item_priv& item_priv) + : item_priv(item_priv) + {} + + void operator()(const Primitive& facet) const + { + item_priv.compute_intersection(facet); + } +}; void Scene_c3t3_item::compute_intersections() { + if(!d->is_aabb_tree_built) d->fill_aabb_tree(); + positions_poly.clear(); normals.clear(); f_colors.clear(); positions_lines.clear(); const Kernel::Plane_3& plane = this->plane(); - tree.all_intersected_primitives(plane, boost::make_function_output_iterator(Compute_intersection(*this))); + d->tree.all_intersected_primitives(plane, + boost::make_function_output_iterator(Compute_intersection(*this->d))); } @@ -1154,24 +1254,6 @@ void Scene_c3t3_item::compute_elements() if (isEmpty()){ return; } - for (Tr::Finite_facets_iterator - fit = c3t3().triangulation().finite_facets_begin(), - end = c3t3().triangulation().finite_facets_end(); - fit != end; ++fit) - { - Tr::Cell_handle ch = fit->first, nh =ch->neighbor(fit->second); - - if( (!c3t3().is_in_complex(ch)) && (!c3t3().is_in_complex(nh)) ) - continue; - - if(c3t3().is_in_complex(ch)){ - tree.insert(Primitive(fit)); - } else{ - int ni = nh->index(ch); - tree.insert(Primitive(Tr::Facet(nh,ni))); - } - } - tree.build(); //The facets { diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h index 1da98da8082..d6df45aec63 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h @@ -25,10 +25,6 @@ #include #include -#include -#include -#include - struct Scene_c3t3_item_priv; using namespace CGAL::Three; @@ -113,13 +109,6 @@ public: void draw_points(CGAL::Three::Viewer_interface * viewer) const; private: - typedef CGAL::AABB_C3T3_triangle_primitive Primitive; - typedef CGAL::AABB_traits Traits; - typedef CGAL::AABB_tree Tree; - typedef Tree::Point_and_primitive_id Point_and_primitive_id; - - Tree tree; - bool need_changed; void reset_cut_plane(); void draw_triangle(const Kernel::Point_3& pa, @@ -164,6 +153,8 @@ public: void set_scene(CGAL::Three::Scene_interface* scene){ last_known_scene = scene; } protected: + friend struct Scene_c3t3_item_priv; + Scene_c3t3_item_priv* d; private: @@ -241,23 +232,7 @@ private: void initialize_intersection_buffers(CGAL::Three::Viewer_interface *viewer); void compute_elements(); void compute_intersections(); - void compute_intersection(const Primitive& facet); void compile_shaders(); - -struct Compute_intersection { - Scene_c3t3_item& item; - - Compute_intersection(Scene_c3t3_item& item) - : item(item) - {} - - void operator()(const Primitive& facet) const - { - item.compute_intersection(facet); - } -}; - - }; #endif // SCENE_C3T3_ITEM_H