This commit is contained in:
Maxime Gimeno 2020-08-19 15:50:22 +02:00
parent a13b96220f
commit 5f8e49a963
2 changed files with 76 additions and 15 deletions

View File

@ -578,7 +578,7 @@ public:
#ifdef CGAL_HAS_THREADS #ifdef CGAL_HAS_THREADS
mutable CGAL_MUTEX build_mutex; // mutex used to protect const calls inducing build() and build_kd_tree() mutable CGAL_MUTEX build_mutex; // mutex used to protect const calls inducing build() and build_kd_tree()
#endif #endif
public:
const Node* root_node() const { const Node* root_node() const {
CGAL_assertion(size() > 1); CGAL_assertion(size() > 1);
@ -596,7 +596,7 @@ public:
} }
return m_p_root_node; return m_p_root_node;
} }
private:
const Primitive& singleton_data() const { const Primitive& singleton_data() const {
CGAL_assertion(size() == 1); CGAL_assertion(size() == 1);
return *m_primitives.begin(); return *m_primitives.begin();

View File

@ -34,6 +34,8 @@
#include <QApplication> #include <QApplication>
#include <CGAL/Three/Scene_item.h> #include <CGAL/Three/Scene_item.h>
#include <QMouseEvent> #include <QMouseEvent>
#include <QWidgetAction>
#include <QMenu>
#ifdef CGAL_LINKED_WITH_TBB #ifdef CGAL_LINKED_WITH_TBB
#include <tbb/parallel_for.h> #include <tbb/parallel_for.h>
@ -230,21 +232,18 @@ typedef QMap<QObject*, Facet_sm_tree*> Facet_sm_trees;
typedef QMap<QObject*, Edge_sm_tree*> Edge_sm_trees; typedef QMap<QObject*, Edge_sm_tree*> Edge_sm_trees;
class Q_DECL_EXPORT Scene_aabb_item : public CGAL::Three::Scene_item_rendering_helper class Q_DECL_EXPORT Scene_aabb_item : public CGAL::Three::Scene_item_rendering_helper
{ {
Q_OBJECT Q_OBJECT
public: public:
Scene_aabb_item(const Facet_sm_tree& tree) Scene_aabb_item(const Facet_sm_tree& tree)
{ {
const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); traversal(tree.size(), *tree.root_node(), 0);
positions_lines.clear(); lvlSlider = new QSlider(Qt::Horizontal);
lvlSlider->setMinimum(0);
CGAL::AABB_drawing_traits<Facet_sm_primitive, CGAL::AABB_node<Facet_sm_traits> > traits; lvlSlider->setMaximum(boxes.size()-1);
traits.v_edges = &positions_lines; lvlSlider->setValue(0);
for(int i=0; i<3; ++i)
traits.offset[i] = offset[i];
tree.traversal(0, traits);
const CGAL::Bbox_3 bbox = tree.bbox(); const CGAL::Bbox_3 bbox = tree.bbox();
setBbox(Bbox(bbox.xmin(), setBbox(Bbox(bbox.xmin(),
bbox.ymin(), bbox.ymin(),
@ -256,7 +255,6 @@ public:
<<bbox.zmin()<<", "<<bbox.zmax(); <<bbox.zmin()<<", "<<bbox.zmax();
tree_size = tree.size(); tree_size = tree.size();
is_tree_empty = tree.empty(); is_tree_empty = tree.empty();
nb_lines = positions_lines.size();
setEdgeContainer(0, new Ec(Vi::PROGRAM_NO_SELECTION, false)); setEdgeContainer(0, new Ec(Vi::PROGRAM_NO_SELECTION, false));
for(auto v : CGAL::QGLViewer::QGLViewerPool()) for(auto v : CGAL::QGLViewer::QGLViewerPool())
{ {
@ -270,6 +268,29 @@ public:
{ {
} }
QMenu* contextMenu()
{
const char* prop_name = "Menu modified by Scene_aabb_item.";
QMenu* menu = Scene_item::contextMenu();
bool menuChanged = menu->property(prop_name).toBool();
if (!menuChanged) {
QMenu *container = new QMenu(tr("Tree level"));
QWidgetAction *sliderAction = new QWidgetAction(0);
connect(lvlSlider, &QSlider::valueChanged, this,
[this](){
invalidateOpenGLBuffers();
redraw();
});
sliderAction->setDefaultWidget(lvlSlider);
container->addAction(sliderAction);
menu->addMenu(container);
menu->setProperty(prop_name, true);
}
return menu;
}
bool isFinite() const { return false; } bool isFinite() const { return false; }
bool isEmpty() const { return is_tree_empty; } bool isEmpty() const { return is_tree_empty; }
//computed in constructor //computed in constructor
@ -296,7 +317,6 @@ public:
return (m == Wireframe); return (m == Wireframe);
} }
// Wireframe OpenGL drawing in a display list
void invalidateOpenGLBuffers() void invalidateOpenGLBuffers()
{ {
setBuffersFilled(false); setBuffersFilled(false);
@ -307,17 +327,58 @@ private:
bool is_tree_empty; bool is_tree_empty;
mutable std::vector<float> positions_lines; mutable std::vector<float> positions_lines;
mutable std::size_t nb_lines; mutable std::size_t nb_lines;
std::vector<std::vector<Bbox> > boxes;
QSlider* lvlSlider;
void
traversal(const std::size_t nb_primitives,
const CGAL::AABB_node<Facet_sm_traits>& node,
int lvl)
{
//traversed lvl by lvl, so one push_back should be enough.
if(boxes.size() <= lvl )
boxes.push_back(std::vector<Bbox>());
CGAL_assertion(boxes.size() > lvl);
boxes[lvl].push_back(node.bbox());
// Recursive traversal
switch(nb_primitives)
{
case 2:
break;
case 3:
traversal(2, node.right_child(), lvl +1);
break;
default:
traversal(nb_primitives/2, node.left_child(),lvl +1);
traversal(nb_primitives-nb_primitives/2, node.right_child(), lvl +1);
}
}
public: public:
void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const
{ {
//to put in a computeElements() function.{
positions_lines.clear();
const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset();
CGAL::AABB_drawing_traits<Facet_sm_primitive, CGAL::AABB_node<Facet_sm_traits> > traits;
for(int i=0; i<3; ++i)
traits.offset[i] = offset[i];
traits.v_edges = &positions_lines;
for(const auto& bb : boxes[lvlSlider->value()])
traits.gl_draw(bb);
nb_lines = positions_lines.size();
//}
Ec* ec = getEdgeContainer(0); Ec* ec = getEdgeContainer(0);
ec->allocate(Ec::Vertices, ec->allocate(Ec::Vertices,
positions_lines.data(), positions_lines.data(),
static_cast<int>(positions_lines.size()*sizeof(float))); static_cast<int>(positions_lines.size()*sizeof(float)));
ec->initializeBuffers(viewer); ec->initializeBuffers(viewer);
ec->setFlatDataSize(nb_lines); ec->setFlatDataSize(nb_lines);
//positions_lines.clear(); positions_lines.clear();
//positions_lines.shrink_to_fit(); positions_lines.shrink_to_fit();
setBuffersFilled(true); setBuffersFilled(true);
} }
void drawEdges(CGAL::Three::Viewer_interface* viewer) const void drawEdges(CGAL::Three::Viewer_interface* viewer) const