1 // Copyright (c) 2012-2015  GeometryFactory Sarl (France)
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Three/include/CGAL/Three/Viewer_interface.h $
7 // $Id: Viewer_interface.h 10cdb75 2021-06-02T17:20:47+02:00 Laurent Rineau
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s)     : Laurent RINEAU, Maxime Gimeno
12 
13 #ifndef VIEWER_INTERFACE_H
14 #define VIEWER_INTERFACE_H
15 
16 #include <CGAL/license/Three.h>
17 
18 #include <QMap>
19 #include <CGAL/Qt/qglviewer.h>
20 #include <QWidget>
21 #include <QPoint>
22 #include <QOpenGLFunctions>
23 #include <QOpenGLFunctions_4_3_Core>
24 #include <CGAL/Qt/CreateOpenGLContext.h>
25 // forward declarations
26 class QWidget;
27 class QImage;
28 class QMouseEvent;
29 class QKeyEvent;
30 class QOpenGLShaderProgram;
31 class QOpenGLFramebufferObject;
32 class TextRenderer;
33 class TextListItem;
34 
35 //! \file Viewer_interface.h
36 #include <CGAL/Three/Viewer_config.h> // for VIEWER_EXPORT
37 namespace CGAL{
38 namespace Three{
39 class Scene_draw_interface;
40 class Scene_item;
41 //! Base class to interact with the viewer from the plugins, the items and the scene.
42 class VIEWER_EXPORT Viewer_interface : public CGAL::QGLViewer{
43 
44   Q_OBJECT
45 
46 public:
47   /*!
48     * \brief The OpenGL_program_IDs enum
49     *
50     * This enum holds the OpenGL programs IDs that are given to getShaderProgram() and attribBuffers().
51     * @see getShaderProgram
52     * @see attribBuffers
53     */
54   enum OpenGL_program_IDs
55   {
56    PROGRAM_WITH_LIGHT = 0,      //! Used to render a surface or an edge affected by the light. It uses a per fragment lighting model, and renders the selected item brighter.
57    PROGRAM_WITHOUT_LIGHT,       //! Used to render a polyhedron edge or points. It renders in a uniform color and is not affected by light. \attention It renders the selected item in black.
58    PROGRAM_NO_SELECTION,        //! Used to render a polyline or a surface that is not affected by light, like a cutting plane. It renders in a uniform color that does not change with selection.
59    PROGRAM_WITH_TEXTURE,        //! Used to render a textured polyhedron. Affected by light.
60    PROGRAM_PLANE_TWO_FACES,     //! Used to render a two-faced plane. The two faces have a different color. Not affected by light.
61    PROGRAM_WITH_TEXTURED_EDGES, //! Used to render the edges of a textured polyhedron. Not affected by light.
62    PROGRAM_INSTANCED,           //! Used to display instanced rendered spheres.Affected by light.
63    PROGRAM_INSTANCED_WIRE,      //! Used to display instanced rendered wired spheres. Not affected by light.
64    PROGRAM_C3T3,                //! Used to render a c3t3_item. It discards any fragment on a side of a plane, meaning that nothing is displayed on this side of the plane. Affected by light.
65    PROGRAM_C3T3_EDGES,          //! Used to render the edges of a c3t3_item. It discards any fragment on a side of a plane, meaning that nothing is displayed on this side of the plane. Not affected by light.
66    PROGRAM_CUTPLANE_SPHERES,    //! Used to render the spheres of an item with a cut plane.
67    PROGRAM_SPHERES,             //! Used to render one or several spheres.
68    PROGRAM_DARK_SPHERES,        //! Used to render one or several spheres without light (for picking for example).
69    PROGRAM_FLAT,                /** Used to render flat shading without pre computing normals*/
70    PROGRAM_OLD_FLAT,            /** Used to render flat shading without pre computing normals without geometry shader*/
71    PROGRAM_SOLID_WIREFRAME,     //! Used to render edges with width superior to 1.
72    PROGRAM_NO_INTERPOLATION,   //! Used to render faces without interpolating their color.
73    PROGRAM_HEAT_INTENSITY,      //! Used to render special item in Display_property_plugin
74    NB_OF_PROGRAMS               //! Holds the number of different programs in this enum.
75   };
76 
77  //! \brief The viewer's QPainter
78  //!
79  //! The painter is the element that draws everything on screen,
80  //! but you should only need this if you want to draw 2D things
81  //! on top of the scene, like a selection rectangle.
82  //! See <a href="https://doc.qt.io/qt-5/qpainter.html">QPainter's documentation </a> for details.
83  virtual QPainter *getPainter() =0;
84 
85 
86 
87   //! \brief tests if an id should be displayed or not.
88   //! \param x, y, z the coordinates of the id's position.
89   //! \return true if the ID should be displayed.
90   virtual bool testDisplayId(double x, double y, double z) = 0;
91   //! \brief updates the item's displayed ids.
92   //!
93   //! Call this after the mesh or its ids have changed.
94   virtual void updateIds(CGAL::Three::Scene_item *) = 0;
95   //! \brief specifies if the items ids are being displayed.
96   //!
97   //! \returns true if the primitive ids are currently displayed
hasText()98   virtual bool hasText() const { return false; }
99   //! \brief Constructor
100   //!
101   //! Creates a valid context for OpenGL ES 2.0.
102   //! \param parent the parent widget. It usually is the MainWindow.
Viewer_interface(QWidget * parent)103   Viewer_interface(QWidget* parent) : CGAL::QGLViewer(parent) {}
104   //!
105   //! \brief Constructor for the secondary viewers.
106   //!
107   //! \param parent the parent widget. It usually is the MainWindow.
108   //! \param shared_widget the main viewer of the Application. This will share the
109   //!  context and allow synchronized rendering of multiple views.
110   //!
Viewer_interface(QWidget * parent,QOpenGLWidget * shared_widget)111   Viewer_interface(QWidget* parent, QOpenGLWidget* shared_widget)
112     : QGLViewer(shared_widget->context(),parent){}
~Viewer_interface()113   virtual ~Viewer_interface() {}
114 
115   //! \brief sets the scene for the viewer.
116   virtual void setScene(CGAL::Three::Scene_draw_interface* scene) = 0;
117   //! \brief The antialiasing state.
118   //!
119   //! @returns true if the antialiasing is activated.
120   virtual bool antiAliasing() const = 0;
121 
122   // Those two functions are defined in Viewer.cpp
123   //! \brief sets the position and orientation of a frame using a QString.
124   //! \param s is usually gotten by dumpFrame() and is of the form "Px Py Pz O1 O2 O3 O4 ", with
125   //! - Px to Py : the new position coordinates,
126   //! - O1 to O3 : axis coordinate *sin(angle/2)
127   //! - O4 cos(angle/2).
128   //! \param frame is the frame that will be moved
129   //! @returns true if it worked.
130   //! @see moveCameraToCoordinates()
131   static bool readFrame(QString s, CGAL::qglviewer::Frame& frame);
132   //! \brief gives information about a frame.
133   //! @see readFrame
134   //! @see dumpCameraCoordinates()
135   //!@returns a QString containing the position and orientation of a frame.
136   static QString dumpFrame(const CGAL::qglviewer::Frame&);
137   //! \brief The fastDrawing state.
138   //!
139   //! In fast drawing mode, some items will be simplified while the camera is moving
140   //! to gain in performance.
141   //! @returns the fastDrawing state.
142   virtual bool inFastDrawing() const = 0;
143   //! \brief The drawWithNames state.
144   //!
145   //! In draw with name mode, the scene is not displayed, but a
146   //! \a name is given to each Scene_item. It is used for picking.
147   //! @returns true if the viewer is drawing with names.
148   virtual bool inDrawWithNames() const = 0;
149 
150   //! \brief passes all the uniform data to the shaders.
151   //!
152   //! According to program_name, this data may change.
153   //! This should be called in every Scene_item::draw() call.
154   //! @see OpenGL_program_IDs
155   //!
156   virtual void attribBuffers(int program_name) const = 0;
157   /*! Enables the clipping box. Each Vector4 of `box` contains the equation of a plane of the clipping box.
158    * Everything that is located on the positive side of one of those planes will not be displayed.
159    * @see disableCLippingBox()
160    */
161   virtual void enableClippingBox(QVector4D box[6])=0;
162 
163   /*!
164    * Disables the clipping box. The six clipping planes will be ignored.
165    * @see enableClippingBox()
166    */
167   virtual void disableClippingBox()= 0;
168 
169   //! \brief returns a program according to name.
170   //!
171   //! If the program does not exist yet, it is created and stored in shader_programs.
172   //! @see OpenGL_program_IDs
173   //! @returns a pointer to the corresponding program.
174   virtual QOpenGLShaderProgram* getShaderProgram(int name) const = 0;
175 
176   //!\brief TextRenderer is used to display text on the screen.
177   //!
178   //! The textRenderer uses the painter to display 2D text over the 3D Scene.
179   //! \returns the viewer's TextRender
180   virtual TextRenderer* textRenderer() = 0;
181   //!Allows OpenGL ES 2.0 context to get access to glDrawArraysInstanced.
182   typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
183   //!Allows OpenGL ES 2.0 context to get access to glVertexAttribDivisor.
184   typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);
185   //!Allows OpenGL ES 2.0 context to get access to glVertexAttribDivisor.
186   typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint target, GLuint attachment, GLuint textarget, GLuint texture, GLint level);
187 
188   PFNGLDRAWARRAYSINSTANCEDARBPROC glDrawArraysInstanced;
189   PFNGLVERTEXATTRIBDIVISORARBPROC glVertexAttribDivisor;
190   PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2D;
191 
192   //! \brief Used by the items to avoid SEGFAULT.
193   //!@returns true if glVertexAttribDivisor, and glDrawArraysInstanced are found.
194   virtual bool isExtensionFound() = 0;
195   //!\brief Allows to perform picking from the keyboard and mouse
196   //!
197   //! Sets the combination SHIFT+LEFT CLICK to perform a selection on the screen.
198   //! This is used to perform picking.
199   virtual void setBindingSelect() = 0;
200   //!\brief disable the picking from the keyboard and mouse
201   //!
202   //! Unbinds the combination SHIFT+LEFT CLICK. It allows to
203   //! avoid conflicts in the selection_tool, for example.
204   virtual void setNoBinding() = 0 ;
205 
206   //!
207   //! If this mode is ON, the viewer will display the content of `staticImage()` instead
208   //! of drawing the cene. This is used when drawing 2D lines over the viewer.
209   //! @see `staticImage()`
210   //! @see `setStaticImage()`
211   virtual void set2DSelectionMode(bool) = 0;
212 
213   //!
214   //! Setter for the image to be displayed in 2D selection mode.
215   //!
216   virtual void setStaticImage(QImage image)=0;
217 
218   //! Returns the static image to be displayed in 2D selection mode.
219   virtual const QImage& staticImage() const = 0;
220 
221   //!The number of passes that are performed for the scene transparency.
222   //! Customizable from the MainWindow or the SubViewer menu.
223   virtual float total_pass() = 0;
224 Q_SIGNALS:
225   //!Emit this to signal that the `id`th item has been picked.
226   void selected(int id);
227   //!Emit this to require a contextual menu to appear at `global_pos`.
228   void requestContextMenu(QPoint global_pos);
229   //!Emit this to signal that the point at (`x`, `y`, `z`) has been picked.
230   void selectedPoint(double x, double y, double z);
231   //!Emit this to request the currently selected item to perform a selection based on an AABB_Tree and a raycasting.
232   void selectionRay(double sx, double sy, double sz, double tx, double ty, double tz);
233 
234 public Q_SLOTS:
235   //! Sets the antialiasing to true or false.
236   //! @see antiAliasing()
237   virtual void setAntiAliasing(bool b) = 0;
238   //! If b is true, faces will be ligted from both internal and external side.
239   //! If b is false, only the side that is exposed to the light source will be lighted.
240   virtual void setTwoSides(bool b) = 0;
241   //! If b is true, then a special color mask is applied to points and meshes to differenciate
242   //! front-faced and back-faced elements.
243   virtual void setBackFrontShading(bool b) =0;
244   //! \brief sets the fast drawing mode
245   //! @see inFastDrawing()
246   virtual void setFastDrawing(bool b) = 0;
247   //! Makes the camera turn around.
248   virtual void turnCameraBy180Degres() = 0;
249   //! @returns a QString containing the position and orientation of the camera.
250   //! @see dumpFrame()
251   virtual QString dumpCameraCoordinates() = 0;
252 //! \brief moves the camera to the new coordinates.
253 //!
254 //! The movement is performed through an animation.
255 //! \param target is usually gotten by dumpCameraCoordinates() and is of the form "Px Py Pz O1 O2 O3 O4 ", with
256 //! - Px to Py : the new position coordinates,
257 //! - O1 to O3 : axis coordinate *sin(angle/2)
258 //! - O4 cos(angle/2).
259 //! \param animation_duration is the duration of the animation of the movement.
260   virtual bool moveCameraToCoordinates(QString target,
261                                        float animation_duration = 0.5f) = 0;
262   //!
263   //! Setter for the orthogonal projection of the viewer.
264   //!
265   virtual void SetOrthoProjection( bool b) =0;
266 public:
267 
268   //! Gives acces to recent openGL(4.3) features, allowing use of things like
269   //! Geometry Shaders or Depth Textures.
270   //! @returns a pointer to an initialized  QOpenGLFunctions_4_3_Core if `isOpenGL_4_3()` is `true`
271   //! @returns nullptr if `isOpenGL_4_3()` is `false`
272   virtual QOpenGLFunctions_4_3_Core* openGL_4_3_functions() = 0;
273   //! getter for point size under old openGL context;
274   virtual const GLfloat& getGlPointSize()const = 0;
275   //! setter for point size under old openGL context;
276   virtual void setGlPointSize(const GLfloat& p) = 0;
277   virtual void setCurrentPass(int pass) = 0;
278   virtual void setDepthWriting(bool writing_depth) = 0;
279   virtual void setDepthPeelingFbo(QOpenGLFramebufferObject* fbo) = 0;
280 
281   virtual int currentPass()const = 0;
282   virtual bool isDepthWriting()const = 0;
283   virtual QOpenGLFramebufferObject* depthPeelingFbo() = 0;
284   virtual void makeCurrent() = 0;
285   virtual QVector4D* clipBox() const =0;
286   virtual bool isClipping() const = 0;
287   //!  A vector indicating the scaling factors to apply to the scene when displaying it.
288   //!  It can be useful when a scene is very large along one of it's coordinates, making it hard to visualize it.
289   virtual const QVector3D& scaler() const = 0;
290 
291   virtual void showEntireScene() = 0;
292 }; // end class Viewer_interface
293 }
294 }
295 #endif // VIEWER_INTERFACE_H
296