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