cgal/Polyhedron/demo/Polyhedron/Scene.h

329 lines
11 KiB
C++

//! \file Scene.h
#ifndef SCENE_H
#define SCENE_H
#include "config.h"
#include "Scene_config.h"
#include <CGAL/Three/Scene_interface.h>
#include <CGAL/Three/Scene_draw_interface.h>
#include <CGAL/Three/Viewer_config.h>
#include <QtOpenGL/qgl.h>
#include <QStandardItemModel>
#include <QString>
#include <QColor>
#include <QList>
#include <QMap>
#include <QItemDelegate>
#include <QPixmap>
#include <QItemSelection>
#include <QGLViewer/qglviewer.h>
#include <QDebug>
#include <iostream>
#include <cmath>
#include <boost/variant.hpp>
#include <CGAL/Three/Scene_group_item.h>
class QEvent;
class QMouseEvent;
namespace GlSplat { class SplatRenderer; }
namespace CGAL { namespace Three{ class Viewer_interface;}}
class SCENE_EXPORT Scene :
public QStandardItemModel, public CGAL::Three::Scene_interface, public CGAL::Three::Scene_draw_interface
{
Q_OBJECT
Q_PROPERTY(int numberOfEntries READ numberOfEntries)
friend class SceneDelegate;
public:
QList<QModelIndex> getModelIndexFromId(int id) const;
int getIdFromModelIndex(QModelIndex modelId) const;
enum Columns { NameColumn = 0,
ColorColumn,
RenderingModeColumn,
VisibleColumn,
ABColumn,
LastColumn = ABColumn,
NumberOfColumns = LastColumn + 1};
Scene(QObject* parent);
~Scene();
//!Adds item to the items list, gives it an ID and
//!updates the bounding box if needed.
int addItem(CGAL::Three::Scene_item* item);
void changeGroup(CGAL::Three::Scene_item* item, CGAL::Three::Scene_group_item* target_group);
//!Sets item as the item at index and calls @ref Scene_item#changed().
//!If emit_item_about_to_be_destroyed is set to true, emits
//!an itemAboutToBeDestroyed signal.
CGAL::Three::Scene_item* replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emit_item_about_to_be_destroyed = false);
/*! Deletes the item with the target index.
* @returns the index of the polyhedra just before the
* one that is erased, or just after. -1 if
* the list is empty.
*/
Q_INVOKABLE Item_id erase(Item_id);
/*! Deletes the items with the target indexes.
* @returns the index of the polyhedra just before the
* one that is erased, or just after. Returns -1 if
* the list is empty.
*/
int erase(QList<int>);
/*! Duplicate a scene item.
* @returns the ID of the new item (-1 on error).
*/
int duplicate(int index);
// Accessors (getters)
//! @returns the number of items.
int numberOfEntries() const;
//! @returns the list of items.
const QList<CGAL::Three::Scene_item*>& entries() const { return m_entries; }
//! @returns the item at the target index.
Q_INVOKABLE CGAL::Three::Scene_item* item(int) const ;
//! @returns the id of the target item.
Item_id item_id(CGAL::Three::Scene_item*) const;
//! \todo Replace Index based selection functionality with those
//! functions.
///@{
CGAL::Three::Scene_item* selectedItem() const;
QList<CGAL::Three::Scene_item*> selectedItems() const;
QList<CGAL::Three::Scene_item*> selectionA() const;
QList<CGAL::Three::Scene_item*> selectionB() const;
///@}
//!@returns the currently selected item's index.
int mainSelectionIndex() const;
//!@returns the list of currently selected items indices.
QList<int> selectionIndices() const;
//!@returns the index of the Item_A
int selectionAindex() const;
//!@returns the index of the Item_B
int selectionBindex() const;
/*! Is called by Viewer::initializeGL(). Allows all the initialization
* of OpenGL code that needs a context.
*/
void initializeGL();
/*! Is called by Viewer::draw(). Is deprecated and does nothing.*/
void draw();
/*! Sets the screen coordinates of the currently picked point.*/
void setPickedPixel(const QPoint &p) {picked_pixel = p;}
/*! Is deprecated and does nothing.*/
void drawWithNames();
/*! Is called by Viewer::draw(Viewer_interface*). Calls draw_aux(false, viewer).
* @see draw_aux(bool with_names, Viewer_interface).*/
void draw(CGAL::Three::Viewer_interface*);
/*! Is called by Viewer::drawWithNames(Viewer_interface*). Calls draw_aux(true, viewer).
* @see draw_aux(bool with_names, Viewer_interface).*/
void drawWithNames(CGAL::Three::Viewer_interface*);
/*! Manages the key events.
* @returns true if the keyEvent executed well.
*/
bool keyPressEvent(QKeyEvent* e);
//!@returns the scene bounding box
Bbox bbox() const;
float get_bbox_length() const;
//!@returns the length of the bounding box's diagonal.
double len_diagonal() const
{
Bbox box = bbox();
double dx = box.xmax - box.xmin;
double dy = box.ymax - box.ymin;
double dz = box.zmax - box.zmin;
return std::sqrt(dx*dx + dy*dy + dz*dz);
}
// QStandardItemModel functions
void moveRowUp();
void moveRowDown();
bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &parent);
QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const;
//!@returns the type of data correspondind to the role.
QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const;
//!@returns the flags for the item at the target index.
::Qt::ItemFlags flags ( const QModelIndex & index ) const;
/*! Sets the column data for the target index. Returns false if index is not valid and
* if role is not EditRole.*/
bool setData(const QModelIndex &index, const QVariant &value, int role);
QList<CGAL::Three::Scene_group_item*> group_entries() const ;
QList<CGAL::Three::Scene_item*> item_entries() const ;
// auxiliary public function for QMainWindow
//!Selects the row at index i in the sceneView.
QItemSelection createSelection(int i);
//!Selects all the rows in the sceneView.
QItemSelection createSelectionAll();
public Q_SLOTS:
//!Specifies a group as Expanded for the view
void setExpanded(QModelIndex);
//!Specifies a group as Collapsed for the view
void setCollapsed(QModelIndex);
/*! This is an overloaded function.
* Notifies the scene that the sender item was modified.
* Called by the items. Calls @ref Scene_item#changed().
* This function is called by the items.*/
void itemChanged();
/*! Notifies the scene that the item at index i was modified.
* Called by the items. Calls @ref Scene_item#changed().
* This function is called by the items.*/
void itemChanged(int i);
/*! Notifies the scene that the item was modified.
* Calls @ref Scene_item#changed().
* This function is called by the items.*/
void itemChanged(CGAL::Three::Scene_item*);
//!Removes item from all the groups of the scene.
void remove_item_from_groups(CGAL::Three::Scene_item* item);
void add_group(Scene_group_item* group);
//!Re-organizes the sceneView.
void group_added();
//! Sets the selected item to the target index.
void setSelectedItemIndex(int i)
{
selected_item = i;
}
//! Sets the selected item to the target index and emits selectionChanged(i).
void setSelectedItem(int i )
{
selected_item = i;
Q_EMIT selectionChanged(i);
}
//! Sets the target item as selected and emits setSelectedItem for its index.
void setSelectedItem(CGAL::Three::Scene_item* item_to_select)
{
int i=0;
Q_FOREACH(CGAL::Three::Scene_item* item, m_entries)
{
if (item==item_to_select)
{
Q_EMIT setSelectedItem(i);
break;
}
++i;
}
}
//! Sets the target list of indices as the selected indices.
QList<int> setSelectedItemsList(QList<int> l )
{
Q_FOREACH(int i,l)
{
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item(i));
if(group)
{
QList<int> list;
Q_FOREACH(CGAL::Three::Scene_item* child, group->getChildren())
list<<m_entries.indexOf(child);
l << setSelectedItemsList(list);
}
}
selected_items_list = l;
return l;
}
// Accessors (setters)
//!Sets the item at index i to visible or not visible.
void setItemVisible(int, bool b);
//!Sets the item_A as the item at index i .
void setItemA(int i);
//!Sets the item_B as the item at index i .
void setItemB(int i);
Q_SIGNALS:
//generated automatically by moc
void itemPicked(const QModelIndex &);
void newItem(int);
void updated_bbox();
void updated();
void itemAboutToBeDestroyed(CGAL::Three::Scene_item*);
void selectionRay(double, double, double, double, double, double);
void selectionChanged(int i);
void restoreCollapsedState();
private Q_SLOTS:
//! Casts a selection ray and calls the item function select.
void setSelectionRay(double, double, double, double, double, double);
void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();}
private:
/*! Calls the drawing functions of each visible item according
* to its current renderingMode. If with_names is true, uses
* the OpenGL mode GL_WITH_NAMES, essentially used for the picking.*/
void draw_aux(bool with_names, CGAL::Three::Viewer_interface*);
//! Re-draw the hierarchy of the view.
void organize_items(CGAL::Three::Scene_item* item, QStandardItem *root, int loop);
//! List of Scene_items.
typedef QList<CGAL::Three::Scene_item*> Entries;
//!List containing all the scene_items.
Entries m_entries;
//! Index of the currently selected item.
int selected_item;
//!List containing all the scene_group_items.
QList<CGAL::Three::Scene_group_item*> m_group_entries;
//!List of indices of the currently selected items.
QList<int> selected_items_list;
//!Index of the item_A.
int item_A;
//!Index of the item_B.
int item_B;
bool picked;
QPoint picked_pixel;
bool gl_init;
static GlSplat::SplatRenderer* ms_splatting;
static int ms_splattingCounter;
QMap<QModelIndex, int> index_map;
public:
static GlSplat::SplatRenderer* splatting();
}; // end class Scene
class QAbstractProxyModel;
/*!
* \brief The SceneDelegate class
* Handles the columns of the sceneView
*/
class SCENE_EXPORT SceneDelegate : public QItemDelegate
{
public:
SceneDelegate(QObject * parent = 0)
: QItemDelegate(parent),
checkOnPixmap(":/cgal/icons/check-on.png"),
checkOffPixmap(":/cgal/icons/check-off.png")
{
}
//! Handles the clicks on the sceneView
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index);
//! Draws the content of the sceneView
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
void setProxy(QAbstractProxyModel* p_proxy){
proxy = p_proxy;
}
void setScene(Scene* p_scene){
scene = p_scene;
}
private:
QPixmap checkOnPixmap;
QPixmap checkOffPixmap;
QAbstractProxyModel *proxy;
Scene *scene;
mutable int size;
}; // end class SceneDelegate
#endif // SCENE_H