Do no always compute the AABB tree

- 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`.
This commit is contained in:
Laurent Rineau 2016-04-06 16:20:25 +02:00
parent 0cd5d8a6c4
commit b9ea69e5c3
2 changed files with 132 additions and 75 deletions

View File

@ -7,12 +7,14 @@
#include <QPixmap>
#include <QPainter>
#include <QtCore/qglobal.h>
#include <QGuiApplication>
#include <map>
#include <vector>
#include <CGAL/gl.h>
#include <CGAL/Mesh_3/dihedral_angle_3.h>
#include <CGAL/Three/Scene_interface.h>
#include <CGAL/Real_timer.h>
#include <QGLViewer/manipulatedFrame.h>
#include <QGLViewer/qglviewer.h>
@ -20,12 +22,82 @@
#include <boost/function_output_iterator.hpp>
#include <boost/foreach.hpp>
struct Scene_c3t3_item_priv {
Scene_c3t3_item_priv() : c3t3() {}
Scene_c3t3_item_priv(const C3t3& c3t3_) : c3t3(c3t3_) {}
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_C3T3_triangle_primitive.h>
typedef CGAL::AABB_C3T3_triangle_primitive<Kernel,C3t3> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> 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<QColor> 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
{

View File

@ -25,10 +25,6 @@
#include <Scene_polygon_soup_item.h>
#include <CGAL/IO/File_binary_mesh_3.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_C3T3_triangle_primitive.h>
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<Kernel,C3t3> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> 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