1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
|
//! \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 <QtOpenGLWidgets>
#include <QStandardItemModel>
#include <QString>
#include <QColor>
#include <QList>
#include <QVector>
#include <QMap>
#include <QItemDelegate>
#include <QPixmap>
#include <QItemSelection>
#include <CGAL/Qt/qglviewer.h>
#include <QDebug>
#include <iostream>
#include <cmath>
#include <variant>
#include <CGAL/Three/Scene_group_item.h>
class QEvent;
class QMouseEvent;
class QOpenGLFramebufferObject;
namespace CGAL { namespace Three{ class Viewer_interface;}}
//! This class is not supposed to be used by Plugins, but sometimes you may need access to
//! peculiar signals or slots.
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();
int addItem(CGAL::Three::Scene_item* item) override;
void addChild(Scene_item* item) override;
Q_INVOKABLE void changeGroup(CGAL::Three::Scene_item* item, CGAL::Three::Scene_group_item* target_group) override;
CGAL::Three::Scene_item* replaceItem(int index, CGAL::Three::Scene_item* item, bool emit_item_about_to_be_destroyed = false) override;
Q_INVOKABLE int erase(int) override;
int erase(QList<int>) override;
int duplicate(int index) override;
// Accessors (getters)
int numberOfEntries() const override;
// returns the list of items.
const QList<CGAL::Three::Scene_item*>& entries() const { return m_entries; }
Q_INVOKABLE CGAL::Three::Scene_item* item(int) const override;
int item_id(CGAL::Three::Scene_item*) const override;
//! \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;
///@}
int mainSelectionIndex() const override;
QList<int> selectionIndices() const override;
int selectionAindex() const override;
int selectionBindex() const override;
void initializeGL(CGAL::Three::Viewer_interface*) override;
void initGL(CGAL::Three::Viewer_interface* viewer);
void setPickedPixel(const QPoint &p) override {picked_pixel = p;}
void draw(CGAL::Three::Viewer_interface*) override;
void drawWithNames(CGAL::Three::Viewer_interface*) override;
bool keyPressEvent(QKeyEvent* e) override;
void printPrimitiveId(QPoint point,
CGAL::Three::Viewer_interface*) override;
void printVertexIds() override;
void printEdgeIds() override;
void printFaceIds() override;
void printAllIds() override;
//!Re-computes the primitiveIds for `item`
void updatePrimitiveIds(Scene_item *item) override;
bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer) override;
Bbox bbox() const override;
void computeBbox();
double len_diagonal() const override
{
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);
}
//Moves a name up in the Geometric Objects view
void moveRowUp();
//Moves a name down in the Geometric Objects view
void moveRowDown();
// QStandardItemModel functions
//Defines the behavior when a name is drag-and-dropped in the Geometric Objects view
bool dropMimeData(const QMimeData *, Qt::DropAction, int, int,
const QModelIndex &parent) override;
//Contains the text and icons of an item in the Geometric Objects view
QVariant data ( const QModelIndex & index,
int role = ::Qt::DisplayRole ) const override;
//@returns the type of data corresponding to the role.
QVariant headerData ( int section, ::Qt::Orientation orientation,
int role = ::Qt::DisplayRole ) const override;
//@returns the flags for the item at the target index.
::Qt::ItemFlags flags ( const QModelIndex & index ) const override;
// 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) override;
//Returns a list of all the items.
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);
//same for lists
QItemSelection createSelection(QList<int> is);
//Selects all the rows in the sceneView.
QItemSelection createSelectionAll();
//Connects specific signals to a group when it is added and
// gives a reference to the scene to it.
void addGroup(Scene_group_item* group);
void zoomToPosition(QPoint point,
CGAL::Three::Viewer_interface*) override;
void setUpdatesEnabled(bool b) override
{
dont_emit_changes = !b;
if(!b)
allItemsChanged();
}
public Q_SLOTS:
//!Specifies a group as Expanded for the Geometric Objects view
void setExpanded(QModelIndex);
//!Specifies a group as Collapsed for the Geometric Objects view
void setCollapsed(QModelIndex);
//!Transmits a CGAL::Three::Scene_item::itemChanged() signal to the scene.
void itemChanged();
void itemChanged(int i) override;
void itemChanged(CGAL::Three::Scene_item*) override;
void allItemsChanged() override;
//!Transmits a CGAL::Three::Scene_item::itemVisibilityChanged() signal to the scene.
void itemVisibilityChanged();
void itemVisibilityChanged(CGAL::Three::Scene_item*) override;
//!Removes `item` from all the groups of the scene.
void remove_item_from_groups(CGAL::Three::Scene_item* item);
//!Re-organizes the sceneView.
void redraw_model();
//! Sets the selected item to the target index. Emits a signal to notify
//! that a new item is now selected, but does not update the Geometric Objects view.
//! Used in intern and by the mainwindow
void setSelectedItemIndex(int i)
{
selected_item = i;
Q_EMIT itemIndexSelected(i);
}
void setSelectedItem(int i ) override
{
selected_item = i;
Q_EMIT selectionChanged(i);
}
//! Does the same as setSelectedItem(int)
void setSelectedItem(CGAL::Three::Scene_item* item_to_select)
{
int i=0;
for(CGAL::Three::Scene_item* item : m_entries)
{
if (item==item_to_select)
{
setSelectedItem(i);
break;
}
++i;
}
}
//! Sets the target list of indices as the selected indices.
const QList<int>& setSelectedItemIndices(QList<int> l,
const bool do_emit = true)
{
for(int i :l)
{
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item(i));
if(group)
{
QList<int> list;
for(Item_id id : group->getChildrenForSelection())
list << id;
l << setSelectedItemIndices(list, false /*do not emit*/);
}
}
selected_items_list = l;
if(do_emit)
Q_EMIT itemIndicesSelected(selected_items_list);
return selected_items_list;
}
//! Sets the target list of indices as the selected indices.
const QList<int>& setSelectedItemList(QList<int> l,
const bool do_emit = true)
{
for(int i :l)
{
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item(i));
if(group)
{
QList<int> list;
for(Item_id id : group->getChildrenForSelection())
list << id;
l << setSelectedItemList(list, false /*do not emit*/);
}
}
selected_items_list = l;
if(do_emit)
Q_EMIT selectionChanged(selected_items_list);
return selected_items_list;
}
// 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);
void newViewer(CGAL::Three::Viewer_interface*);
void removeViewer(CGAL::Three::Viewer_interface*);
void enableVisibilityRecentering(bool);
Q_SIGNALS:
//generated automatically by moc
//!Is emitted when the ids of the items are changed.
void indexErased(Scene_interface::Item_id id);
//! Emit this to mark `modelindex` as selected in the Geometric Objects view.
void itemPicked(const QModelIndex& modelindex);
//! Is emitted when a new item is added to the scene.
void newItem(int);
//! Emit this to re-compute the viewer's Bbox;
//! If `b` is true, the scene will be recentered
void updated_bbox(bool b);
//! Emit this to redraw the scene.
void updated();
//! Is emitted when `item` is erased.
void itemAboutToBeDestroyed(CGAL::Three::Scene_item* item);
//! Is emitted when the selection ray is changed.
void selectionRay(double, double, double, double, double, double);
//! Used to update the selected item in the Geometric Objects view.
void selectionChanged(int i);
//! Used to update the selected items in the Geometric Objects view.
void selectionChanged(QList<int> is);
//! Used when you don't want to update the selectedItem in the Geometric Objects view.
void itemIndexSelected(int i);
//! Used when you don't want to update the selectedItem in the Geometric Objects view.
void itemIndicesSelected(QList<int> is);
//! Emit this to reset the collapsed state of all groups after the Geometric Objects view has been redrawn.
void restoreCollapsedState();
//! Is emitted when draw() is finished.
void drawFinished();
private Q_SLOTS:
// Casts a selection ray and calls the item function select.
void adjustIds(Scene_interface::Item_id removed_id);
void setSelectionRay(double, double, double, double, double, double);
void callDraw();
void s_itemAboutToBeDestroyed(CGAL::Three::Scene_item *);
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*);
bool has_alpha();
void renderScene(const QList<Scene_interface::Item_id > &items,
CGAL::Three::Viewer_interface* viewer, QMap<float, int> &picked_item_IDs, bool with_names,
int pass, bool writing_depth,
QOpenGLFramebufferObject* fbo);
void renderWireScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer, QMap<float, int> &picked_item_IDs, bool with_names);
void renderPointScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names);
// 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;
QList<Item_id> m_groups; //used to optimize createSelectionAll()
QList<Item_id> children;
// Index of the currently selected item.
int selected_item;
//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;
QMap<QModelIndex, int> index_map;
float points[18];
float uvs[12];
QOpenGLShaderProgram program;
QMap<CGAL::Three::Viewer_interface*, QOpenGLVertexArrayObject*> vaos;
mutable QOpenGLBuffer vbo[2];
Bbox last_bbox;
//the scene will ignore the itemChanged() signals while this is true.
bool dont_emit_changes;
bool visibility_recentering_enabled;
bool sort_lists(QVector<QList<int> >&sorted_lists, bool up);
}; // 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 = nullptr)
: 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
|