File: Scene.h

package info (click to toggle)
cgal 6.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,952 kB
  • sloc: cpp: 811,597; ansic: 208,576; sh: 493; python: 411; makefile: 286; javascript: 174
file content (375 lines) | stat: -rw-r--r-- 13,716 bytes parent folder | download | duplicates (2)
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