D-pointer for the shortest_path_item

This commit is contained in:
Maxime Gimeno 2016-05-06 09:55:24 +02:00
parent 54c8ce5b8b
commit 7fce02a36e
3 changed files with 161 additions and 124 deletions

View File

@ -31,18 +31,18 @@ struct Scene_polyhedron_transform_item_priv
NbOfVbos
};
Scene_polyhedron_transform_item *item;
const Scene_polyhedron_item* poly_item;
bool manipulable;
qglviewer::ManipulatedFrame* frame;
const Polyhedron* poly;
qglviewer::Vec center_;
Scene_polyhedron_transform_item *item;
mutable QOpenGLShaderProgram *program;
mutable std::vector<float> positions_lines;
mutable std::size_t nb_lines;
mutable bool are_buffers_filled;
bool manipulable;
};
Scene_polyhedron_transform_item::Scene_polyhedron_transform_item(const qglviewer::Vec& pos,const Scene_polyhedron_item* poly_item_,const CGAL::Three::Scene_interface*):

View File

@ -8,21 +8,105 @@
#include <fstream>
#include <CGAL/Surface_mesh_shortest_path/function_objects.h>
#include <QString>
struct Scene_polyhedron_shortest_path_item_priv
{
typedef CGAL::Three::Scene_interface::Bbox Bbox;
typedef boost::property_map<Polyhedron, CGAL::vertex_point_t>::type VertexPointMap;
typedef boost::graph_traits<Polyhedron> GraphTraits;
typedef GraphTraits::face_descriptor face_descriptor;
typedef GraphTraits::face_iterator face_iterator;
typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Polyhedron> Surface_mesh_shortest_path_traits;
typedef CGAL::Surface_mesh_shortest_path<Surface_mesh_shortest_path_traits> Surface_mesh_shortest_path;
typedef Surface_mesh_shortest_path::Face_location Face_location;
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron, VertexPointMap> AABB_face_graph_primitive;
typedef CGAL::AABB_traits<Kernel, AABB_face_graph_primitive> AABB_face_graph_traits;
typedef CGAL::AABB_tree<AABB_face_graph_traits> AABB_face_graph_tree;
typedef Surface_mesh_shortest_path_traits::Barycentric_coordinate Barycentric_coordinate;
typedef Surface_mesh_shortest_path_traits::Construct_barycentric_coordinate Construct_barycentric_coordinate;
typedef Surface_mesh_shortest_path_traits::Ray_3 Ray_3;
typedef Surface_mesh_shortest_path_traits::Point_3 Point_3;
typedef Surface_mesh_shortest_path_traits::FT FT;
Scene_polyhedron_shortest_path_item_priv(Scene_polyhedron_shortest_path_item *parent)
: m_shortestPaths(NULL)
, m_isTreeCached(false)
, m_shiftHeld(false)
{
item = parent;
}
bool get_mouse_ray(QMouseEvent* mouseEvent, Kernel::Ray_3&);
void recreate_shortest_path_object();
void ensure_aabb_object();
void ensure_shortest_paths_tree();
bool run_point_select(const Kernel::Ray_3&);
void remove_nearest_point(const Scene_polyhedron_shortest_path_item::Face_location& ray);
void get_as_edge_point(Scene_polyhedron_shortest_path_item::Face_location& inOutLocation);
void get_as_vertex_point(Scene_polyhedron_shortest_path_item::Face_location& inOutLocation);
void initialize_buffers(CGAL::Three::Viewer_interface *viewer = 0) const;
void compute_elements(void) const;
void deinitialize()
{
if (m_shortestPaths)
{
delete m_shortestPaths;
m_sceneInterface = NULL;
}
}
enum Selection_mode
{
INSERT_POINTS_MODE = 0,
REMOVE_POINTS_MODE = 1,
SHORTEST_PATH_MODE = 2
};
enum Primitives_mode
{
VERTEX_MODE = 0,
EDGE_MODE = 1,
FACE_MODE = 2
};
enum VAOs {
Selected_Edges=0,
NbOfVaos
};
enum VBOs {
Vertices = 0,
NbOfVbos
};
Scene_polyhedron_shortest_path_item* item;
Messages_interface* m_messages;
QMainWindow* m_mainWindow;
CGAL::Three::Scene_interface* m_sceneInterface;
Scene_polyhedron_shortest_path_item::Surface_mesh_shortest_path* m_shortestPaths;
Scene_polyhedron_shortest_path_item::AABB_face_graph_tree m_aabbTree;
std::string m_deferredLoadFilename;
Scene_polyhedron_shortest_path_item::Selection_mode m_selectionMode;
Scene_polyhedron_shortest_path_item::Primitives_mode m_primitivesMode;
bool m_isTreeCached;
bool m_shiftHeld;
mutable std::vector<float> vertices;
mutable QOpenGLShaderProgram *program;
mutable bool are_buffers_filled;
};
Scene_polyhedron_shortest_path_item::Scene_polyhedron_shortest_path_item()
:Scene_polyhedron_item_decorator(NULL, false)
, m_shortestPaths(NULL)
, m_isTreeCached(false)
, m_shiftHeld(false)
{
d = new Scene_polyhedron_shortest_path_item_priv(this);
}
Scene_polyhedron_shortest_path_item::Scene_polyhedron_shortest_path_item(Scene_polyhedron_item* polyhedronItem, CGAL::Three::Scene_interface* sceneInterface, Messages_interface* messages, QMainWindow* mainWindow)
:Scene_polyhedron_item_decorator(polyhedronItem, false)
, m_shortestPaths(NULL)
, m_isTreeCached(false)
, m_shiftHeld(false)
{
{ d = new Scene_polyhedron_shortest_path_item_priv(this);
initialize(polyhedronItem, sceneInterface, messages, mainWindow);
}
@ -31,36 +115,34 @@ Scene_polyhedron_shortest_path_item::~Scene_polyhedron_shortest_path_item()
deinitialize();
}
void Scene_polyhedron_shortest_path_item::compute_elements() const
void Scene_polyhedron_shortest_path_item_priv::compute_elements() const
{
vertices.resize(0);
for(Surface_mesh_shortest_path::Source_point_iterator it = m_shortestPaths->source_points_begin(); it != m_shortestPaths->source_points_end(); ++it)
for(Scene_polyhedron_shortest_path_item::Surface_mesh_shortest_path::Source_point_iterator it = m_shortestPaths->source_points_begin(); it != m_shortestPaths->source_points_end(); ++it)
{
const Point_3& p = m_shortestPaths->point(it->first, it->second);
const Kernel::Point_3& p = m_shortestPaths->point(it->first, it->second);
vertices.push_back(p.x());
vertices.push_back(p.y());
vertices.push_back(p.z());
}
}
void Scene_polyhedron_shortest_path_item::initialize_buffers(CGAL::Three::Viewer_interface* viewer)const
void Scene_polyhedron_shortest_path_item_priv::initialize_buffers(CGAL::Three::Viewer_interface* viewer)const
{
//vao containing the data for the selected lines
{
program = getShaderProgram(PROGRAM_WITHOUT_LIGHT, viewer);
vaos[Selected_Edges]->bind();
program = item->getShaderProgram(Scene_polyhedron_shortest_path_item::PROGRAM_WITHOUT_LIGHT, viewer);
item->vaos[Selected_Edges]->bind();
program->bind();
buffers[Vertices].bind();
buffers[Vertices].allocate(vertices.data(), vertices.size()*sizeof(float));
item->buffers[Vertices].bind();
item->buffers[Vertices].allocate(vertices.data(), vertices.size()*sizeof(float));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
buffers[Vertices].release();
vaos[Selected_Edges]->release();
item->buffers[Vertices].release();
item->vaos[Selected_Edges]->release();
}
are_buffers_filled = true;
}
@ -98,17 +180,17 @@ void Scene_polyhedron_shortest_path_item::draw_points(CGAL::Three::Viewer_interf
{
if(!are_buffers_filled)
{
initialize_buffers(viewer);
d->initialize_buffers(viewer);
}
glPointSize(4.0f);
program = getShaderProgram(PROGRAM_WITHOUT_LIGHT);
d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT);
attrib_buffers(viewer, PROGRAM_WITHOUT_LIGHT);
vaos[Selected_Edges]->bind();
program->bind();
program->setAttributeValue("colors", QColor(Qt::green));
viewer->glDrawArrays(GL_POINTS, 0, vertices.size()/3);
program->release();
vaos[Selected_Edges]->release();
vaos[Scene_polyhedron_shortest_path_item_priv::Selected_Edges]->bind();
d->program->bind();
d->program->setAttributeValue("colors", QColor(Qt::green));
viewer->glDrawArrays(GL_POINTS, 0, d->vertices.size()/3);
d->program->release();
vaos[Scene_polyhedron_shortest_path_item_priv::Selected_Edges]->release();
glPointSize(1.0f);
}
@ -119,43 +201,43 @@ Scene_polyhedron_shortest_path_item* Scene_polyhedron_shortest_path_item::clone(
void Scene_polyhedron_shortest_path_item::set_selection_mode(Selection_mode mode)
{
m_selectionMode = mode;
d->m_selectionMode = mode;
}
Scene_polyhedron_shortest_path_item::Selection_mode Scene_polyhedron_shortest_path_item::get_selection_mode() const
{
return m_selectionMode;
return d->m_selectionMode;
}
void Scene_polyhedron_shortest_path_item::set_primitives_mode(Primitives_mode mode)
{
m_primitivesMode = mode;
d->m_primitivesMode = mode;
}
Scene_polyhedron_shortest_path_item::Primitives_mode Scene_polyhedron_shortest_path_item::get_primitives_mode() const
{
return m_primitivesMode;
return d->m_primitivesMode;
}
void Scene_polyhedron_shortest_path_item::recreate_shortest_path_object()
void Scene_polyhedron_shortest_path_item_priv::recreate_shortest_path_object()
{
if (m_shortestPaths)
{
delete m_shortestPaths;
}
m_shortestPaths = new Surface_mesh_shortest_path(*polyhedron(),
CGAL::get(boost::vertex_index, *polyhedron()),
CGAL::get(CGAL::halfedge_index, *polyhedron()),
CGAL::get(CGAL::face_index, *polyhedron()),
CGAL::get(CGAL::vertex_point, *polyhedron()));
m_shortestPaths = new Scene_polyhedron_shortest_path_item::Surface_mesh_shortest_path(*(item->polyhedron()),
CGAL::get(boost::vertex_index, *(item->polyhedron())),
CGAL::get(CGAL::halfedge_index, *(item->polyhedron())),
CGAL::get(CGAL::face_index, *(item->polyhedron())),
CGAL::get(CGAL::vertex_point, *(item->polyhedron())));
//m_shortestPaths->m_debugOutput = true;
m_isTreeCached = false;
}
void Scene_polyhedron_shortest_path_item::ensure_aabb_object()
void Scene_polyhedron_shortest_path_item_priv::ensure_aabb_object()
{
if (!m_isTreeCached)
{
@ -164,32 +246,32 @@ void Scene_polyhedron_shortest_path_item::ensure_aabb_object()
}
}
void Scene_polyhedron_shortest_path_item::ensure_shortest_paths_tree()
void Scene_polyhedron_shortest_path_item_priv::ensure_shortest_paths_tree()
{
if (!m_shortestPaths->changed_since_last_build())
{
m_messages->information(tr("Recomputing shortest paths tree..."));
m_messages->information("Recomputing shortest paths tree...");
m_shortestPaths->build_sequence_tree();
m_messages->information(tr("Done."));
m_messages->information("Done.");
}
}
void Scene_polyhedron_shortest_path_item::poly_item_changed()
{
recreate_shortest_path_object();
d->recreate_shortest_path_object();
invalidateOpenGLBuffers();
Q_EMIT itemChanged();
}
void Scene_polyhedron_shortest_path_item::invalidateOpenGLBuffers()
{
compute_elements();
d->compute_elements();
compute_bbox();
are_buffers_filled = false;
}
bool Scene_polyhedron_shortest_path_item::get_mouse_ray(QMouseEvent* mouseEvent, Ray_3& outRay)
bool Scene_polyhedron_shortest_path_item_priv::get_mouse_ray(QMouseEvent* mouseEvent, Kernel::Ray_3& outRay)
{
bool found = false;
@ -206,7 +288,7 @@ bool Scene_polyhedron_shortest_path_item::get_mouse_ray(QMouseEvent* mouseEvent,
return found;
}
void Scene_polyhedron_shortest_path_item::remove_nearest_point(const Face_location& faceLocation)
void Scene_polyhedron_shortest_path_item_priv::remove_nearest_point(const Scene_polyhedron_shortest_path_item::Face_location& faceLocation)
{
Surface_mesh_shortest_path_traits::Compute_squared_distance_3 computeSquaredDistance3;
@ -234,7 +316,7 @@ void Scene_polyhedron_shortest_path_item::remove_nearest_point(const Face_locati
}
}
void Scene_polyhedron_shortest_path_item::get_as_edge_point(Scene_polyhedron_shortest_path_item::Face_location& inOutLocation)
void Scene_polyhedron_shortest_path_item_priv::get_as_edge_point(Scene_polyhedron_shortest_path_item::Face_location& inOutLocation)
{
size_t minIndex = 0;
FT minCoord(inOutLocation.second[0]);
@ -263,7 +345,7 @@ void Scene_polyhedron_shortest_path_item::get_as_edge_point(Scene_polyhedron_sho
Construct_barycentric_coordinate construct_barycentric_coordinate;
Point_3 trianglePoints[3] = {
Point_3 trianglePoints[3] = {
m_shortestPaths->point(inOutLocation.first, construct_barycentric_coordinate(FT(1.0), FT(0.0), FT(0.0))),
m_shortestPaths->point(inOutLocation.first, construct_barycentric_coordinate(FT(0.0), FT(1.0), FT(0.0))),
m_shortestPaths->point(inOutLocation.first, construct_barycentric_coordinate(FT(0.0), FT(0.0), FT(1.0))),
@ -283,7 +365,7 @@ void Scene_polyhedron_shortest_path_item::get_as_edge_point(Scene_polyhedron_sho
inOutLocation.second = construct_barycentric_coordinate(coords[0], coords[1], coords[2]);
}
void Scene_polyhedron_shortest_path_item::get_as_vertex_point(Scene_polyhedron_shortest_path_item::Face_location& inOutLocation)
void Scene_polyhedron_shortest_path_item_priv::get_as_vertex_point(Scene_polyhedron_shortest_path_item::Face_location& inOutLocation)
{
size_t maxIndex = 0;
FT maxCoord(inOutLocation.second[0]);
@ -304,7 +386,7 @@ void Scene_polyhedron_shortest_path_item::get_as_vertex_point(Scene_polyhedron_s
inOutLocation.second = construct_barycentric_coordinate(coords[0], coords[1], coords[2]);
}
bool Scene_polyhedron_shortest_path_item::run_point_select(const Ray_3& ray)
bool Scene_polyhedron_shortest_path_item_priv::run_point_select(const Ray_3& ray)
{
ensure_aabb_object();
@ -312,12 +394,12 @@ bool Scene_polyhedron_shortest_path_item::run_point_select(const Ray_3& ray)
if (faceLocation.first == GraphTraits::null_face())
{
m_messages->information(tr("Shortest Paths: No face under cursor."));
m_messages->information(QObject::tr("Shortest Paths: No face under cursor."));
return false;
}
else
{
m_messages->information(tr("Shortest Paths: Selected Face: %1; Barycentric coordinates: %2 %3 %4")
m_messages->information(QObject::tr("Shortest Paths: Selected Face: %1; Barycentric coordinates: %2 %3 %4")
.arg(faceLocation.first->id())
.arg(double(faceLocation.second[0]))
.arg(double(faceLocation.second[1]))
@ -364,7 +446,7 @@ bool Scene_polyhedron_shortest_path_item::run_point_select(const Ray_3& ray)
polylines->polylines.push_back(Scene_polylines_item::Polyline());
m_messages->information(tr("Computing shortest path polyline..."));
m_messages->information(QObject::tr("Computing shortest path polyline..."));
QTime time;
time.start();
@ -372,18 +454,18 @@ bool Scene_polyhedron_shortest_path_item::run_point_select(const Ray_3& ray)
m_shortestPaths->shortest_path_points_to_source_points(faceLocation.first, faceLocation.second, std::back_inserter(polylines->polylines.back()));
std::cout << "ok (" << time.elapsed() << " ms)" << std::endl;
polylines->setName(tr("%1 (shortest path)").arg(polyhedron_item()->name()));
polylines->setName(QObject::tr("%1 (shortest path)").arg(item->polyhedron_item()->name()));
polylines->setColor(Qt::red);
this->m_sceneInterface->addItem(polylines);
}
else
{
m_messages->warning(tr("No source points to compute shortest paths from."));
m_messages->warning(QObject::tr("No source points to compute shortest paths from."));
}
break;
}
invalidateOpenGLBuffers();
item->invalidateOpenGLBuffers();
return true;
}
}
@ -396,19 +478,19 @@ bool Scene_polyhedron_shortest_path_item::eventFilter(QObject* /*target*/, QEven
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
Qt::KeyboardModifiers modifiers = keyEvent->modifiers();
m_shiftHeld = modifiers.testFlag(Qt::ShiftModifier);
d->m_shiftHeld = modifiers.testFlag(Qt::ShiftModifier);
}
if (event->type() == QEvent::MouseButtonPress && m_shiftHeld)
if (event->type() == QEvent::MouseButtonPress && d->m_shiftHeld)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->button() == Qt::LeftButton)
{
Ray_3 mouseRay;
if (get_mouse_ray(mouseEvent, mouseRay))
if (d->get_mouse_ray(mouseEvent, mouseRay))
{
if (run_point_select(mouseRay))
if (d->run_point_select(mouseRay))
{
return true;
}
@ -421,7 +503,7 @@ bool Scene_polyhedron_shortest_path_item::eventFilter(QObject* /*target*/, QEven
bool Scene_polyhedron_shortest_path_item::load(const std::string& file_name)
{
m_deferredLoadFilename = file_name;
d->m_deferredLoadFilename = file_name;
return true;
}
@ -429,14 +511,14 @@ bool Scene_polyhedron_shortest_path_item::deferred_load(Scene_polyhedron_item* p
{
initialize(polyhedronItem, sceneInterface, messages, mainWindow);
std::ifstream inFile(m_deferredLoadFilename.c_str());
std::ifstream inFile(d->m_deferredLoadFilename.c_str());
if (!inFile)
{
return false;
}
m_shortestPaths->clear();
d->m_shortestPaths->clear();
std::vector<face_descriptor> listOfFaces;
listOfFaces.reserve(CGAL::num_faces(*polyhedron()));
@ -461,7 +543,7 @@ bool Scene_polyhedron_shortest_path_item::deferred_load(Scene_polyhedron_item* p
// std::cout << "Read in face: " << faceId << " , " << location << std::endl;
m_shortestPaths->add_source_point(listOfFaces[faceId], location);
d->m_shortestPaths->add_source_point(listOfFaces[faceId], location);
}
return true;
@ -476,7 +558,7 @@ bool Scene_polyhedron_shortest_path_item::save(const std::string& file_name) con
return false;
}
for(Surface_mesh_shortest_path::Source_point_iterator it = m_shortestPaths->source_points_begin(); it != m_shortestPaths->source_points_end(); ++it)
for(Surface_mesh_shortest_path::Source_point_iterator it = d->m_shortestPaths->source_points_begin(); it != d->m_shortestPaths->source_points_end(); ++it)
{
// std::cout << "Output face location: " << it->first->id() << " , " << it->second << std::endl;
out << it->first->id() << " " << it->second[0] << " " << it->second[1] << " " << it->second[3] << std::endl;
@ -487,26 +569,21 @@ bool Scene_polyhedron_shortest_path_item::save(const std::string& file_name) con
void Scene_polyhedron_shortest_path_item::initialize(Scene_polyhedron_item* polyhedronItem, CGAL::Three::Scene_interface* sceneInterface, Messages_interface* messages, QMainWindow* mainWindow)
{
this->m_mainWindow = mainWindow;
this->m_messages = messages;
d->m_mainWindow = mainWindow;
d->m_messages = messages;
this->poly_item = polyhedronItem;
this->m_sceneInterface = sceneInterface;
connect(polyhedronItem, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed()));
d->m_sceneInterface = sceneInterface;
connect(polyhedronItem, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed()));
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
viewer->installEventFilter(this);
m_mainWindow->installEventFilter(this);
recreate_shortest_path_object();
d->m_mainWindow->installEventFilter(this);
d->recreate_shortest_path_object();
}
void Scene_polyhedron_shortest_path_item::deinitialize()
{
if (m_shortestPaths)
{
delete m_shortestPaths;
}
d->deinitialize();
this->poly_item = NULL;
this->m_sceneInterface = NULL;
}
bool Scene_polyhedron_shortest_path_item::isFinite() const

View File

@ -30,6 +30,8 @@
#include <boost/current_function.hpp>
struct Scene_polyhedron_shortest_path_item_priv;
class SCENE_POLYHEDRON_SHORTEST_PATH_ITEM_EXPORT Scene_polyhedron_shortest_path_item : public Scene_polyhedron_item_decorator
{
Q_OBJECT
@ -57,14 +59,14 @@ public:
typedef Surface_mesh_shortest_path_traits::Ray_3 Ray_3;
typedef Surface_mesh_shortest_path_traits::Point_3 Point_3;
typedef Surface_mesh_shortest_path_traits::FT FT;
enum Selection_mode
{
INSERT_POINTS_MODE = 0,
REMOVE_POINTS_MODE = 1,
SHORTEST_PATH_MODE = 2
};
enum Primitives_mode
{
VERTEX_MODE = 0,
@ -72,50 +74,6 @@ public:
FACE_MODE = 2
};
enum VAOs {
Selected_Edges=0,
NbOfVaos = Selected_Edges+1
};
enum VBOs {
Vertices = 0,
NbOfVbos = Vertices+1
};
private:
Messages_interface* m_messages;
QMainWindow* m_mainWindow;
CGAL::Three::Scene_interface* m_sceneInterface;
Surface_mesh_shortest_path* m_shortestPaths;
AABB_face_graph_tree m_aabbTree;
std::string m_deferredLoadFilename;
Selection_mode m_selectionMode;
Primitives_mode m_primitivesMode;
bool m_isTreeCached;
bool m_shiftHeld;
private:
bool get_mouse_ray(QMouseEvent* mouseEvent, Kernel::Ray_3&);
void recreate_shortest_path_object();
void ensure_aabb_object();
void ensure_shortest_paths_tree();
bool run_point_select(const Kernel::Ray_3&);
void remove_nearest_point(const Face_location& ray);
void get_as_edge_point(Face_location& inOutLocation);
void get_as_vertex_point(Face_location& inOutLocation);
mutable std::vector<float> vertices;
mutable QOpenGLShaderProgram *program;
using Scene_polyhedron_item_decorator::initialize_buffers;
void initialize_buffers(CGAL::Three::Viewer_interface *viewer = 0) const;
void compute_elements(void) const;
public:
Scene_polyhedron_shortest_path_item();
@ -147,6 +105,8 @@ protected:
virtual bool isEmpty() const;
virtual void compute_bbox()const;
virtual QString toolTip() const;
friend struct Scene_polyhedron_shortest_path_item_priv;
Scene_polyhedron_shortest_path_item_priv* d;
protected:
bool eventFilter(QObject* /*target*/, QEvent * gen_event);