// Copyright (c) 2012-2015 GeometryFactory Sarl (France) // All rights reserved. // // This file is part of CGAL (www.cgal.org). // You can redistribute it and/or modify it under the terms of the GNU // General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // // // Author(s) : Laurent RINEAU, Maxime Gimeno #ifndef SCENE_ITEM_H #define SCENE_ITEM_H #include #include #include #include #include #include #include #include #include #include #include namespace CGAL { namespace Three { class Viewer_interface; } } namespace CGAL{ namespace qglviewer { class ManipulatedFrame; } } class QMenu; class QKeyEvent; namespace CGAL { namespace Three { class Scene_group_item; class Viewer_interface; //! This class represents an object in the OpenGL scene. //! It contains all the functions called by the Scene. It //! acts like a mix between an interface and a helper. class SCENE_ITEM_EXPORT Scene_item : public QObject{ Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(bool visible READ visible WRITE setVisible) Q_ENUMS(RenderingMode) Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode) public: /*! * \brief The OpenGL_program_IDs enum * * This enum holds the OpenGL programs IDs that are given to getShaderProgram() and attribBuffers(). * @see getShaderProgram * @see attribBuffers */ enum OpenGL_program_IDs { PROGRAM_WITH_LIGHT = 0, /** Used to render a surface or edge affected by the light. It uses a per fragment lighting model, and renders brighter the selected item.*/ PROGRAM_WITHOUT_LIGHT, /** Used to render a polygon edge or points. It renders in a uniform color and is not affected by light. It renders the selected item in black.*/ 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.*/ PROGRAM_WITH_TEXTURE, /** Used to render a textured polyhedron. Affected by light.*/ PROGRAM_PLANE_TWO_FACES, /** Used to render a two-faced plane. The two faces have a different color. Not affected by light.*/ PROGRAM_WITH_TEXTURED_EDGES, /** Used to render the edges of a textured polyhedorn. Not affected by light.*/ PROGRAM_INSTANCED, /** Used to display instanced rendered spheres.Affected by light.*/ PROGRAM_INSTANCED_WIRE, /** Used to display instanced rendered wired spheres. Not affected by light.*/ 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.*/ 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.*/ PROGRAM_CUTPLANE_SPHERES, /** Used to render the spheres of an item with a cut plane.*/ PROGRAM_SPHERES, /** Used to render one or several spheres.*/ PROGRAM_FLAT, /** Used to render flat shading without pre computing normals*/ PROGRAM_OLD_FLAT, /** Used to render flat shading without pre computing normals without geometry shader*/ PROGRAM_SOLID_WIREFRAME, //! Used to render edges with width superior to 1. NB_OF_PROGRAMS /** Holds the number of different programs in this enum.*/ }; typedef CGAL::Bbox_3 Bbox; typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; //! \brief The default color of a scene_item. //! //! This color is the one that will be displayed if none is specified after its creation. static const QColor defaultColor; // defined in Scene_item.cpp //!\brief The Constructor. //! //! This is where the vectors of VBOs and VAOs are initialized. Scene_item(int buffers_size = 20, int vaos_size = 10); //! \brief Sets the number of isolated vertices. //! //! This number will be displayed in a warning box at loading. //! @see getNbIsolatedvertices void setNbIsolatedvertices(std::size_t nb) { nb_isolated_vertices = nb;} //! Getter for the number of isolated vertices. //! @see setNbIsolatedvertices std::size_t getNbIsolatedvertices() const {return nb_isolated_vertices;} virtual ~Scene_item(); //! \brief Duplicates the item. //! //! Creates a new item as a copy of this one. virtual Scene_item* clone() const = 0; //! \brief Indicates if `m` is supported //! //! If it is, it will be displayed in the context menu of the item. virtual bool supportsRenderingMode(RenderingMode m) const = 0; //! Deprecated. Does nothing. virtual void draw() const {} /*! \brief The drawing function for faces. * * Draws the faces of the item in the viewer. The data * for the drawing is gathered in computeElements(), and is sent * to buffers in initializeBuffers(). * @see computeElements() * @see initializeBuffers() */ virtual void draw(CGAL::Three::Viewer_interface*) const { draw(); } //! Deprecated. Does nothing. virtual void drawEdges() const { draw(); } /*! \brief The drawing function for the edges. * * Draws the edges and lines of the item in the viewer. The data * for the drawing is gathered in computeElements(), and is sent * to buffers in initializeBuffers(). * @see computeElements() * @see initializeBuffers() */ virtual void drawEdges(CGAL::Three::Viewer_interface* viewer) const { draw(viewer); } //! Deprecated. Does nothing. virtual void drawPoints() const { draw(); } /*! \brief The drawing function for the points. * * Draws the points of the item in the viewer. The data * for the drawing is gathered in computeElements(), and is sent * to buffers in initializeBuffers(). * @see computeElements() * @see initializeBuffers() */ virtual void drawPoints(CGAL::Three::Viewer_interface*) const { drawPoints(); } //! Called by the scene. If b is true, then this item is currently selected. virtual void selection_changed(bool b); // Functions for displaying meta-data of the item //!\brief Contains meta-data about the item. //! @returns a QString containing meta-data about the item. virtual QString toolTip() const = 0; //! \brief Contains graphical meta-data about the item. //! @returns a QPixmap containing graphical meta-data about the item. virtual QPixmap graphicalToolTip() const { return QPixmap(); } //! \brief Contains the font used for the data of the item. //! @returns a QFont containing the font used for the data of the item. virtual QFont font() const { return QFont(); } // Functions that help the Scene to compute its bbox //! \brief Determines if the item is finite or not. //! //! For example, a plane is not finite. //! If false, the BBox is not computed. virtual bool isFinite() const { return true; } //! Specifies if the item is empty or null. //! If true, the BBox is not computed. virtual bool isEmpty() const { return true; } //! \brief The item's bounding box. //! //! If the Bbox has never been computed, computes it and //! saves the result for further calls. //! @returns the item's bounding box. virtual Bbox bbox() const { if(!is_bbox_computed) compute_bbox(); is_bbox_computed = true; return _bbox; } //! \brief the item's bounding box's diagonal length. //! //! If the diagonal's length has never been computed, computes it and //! saves the result for further calls. //! @returns the item's bounding box's diagonal length. virtual double diagonalBbox() const { if(!is_diag_bbox_computed) compute_diag_bbox(); is_diag_bbox_computed = true; return _diag_bbox; } // Function about manipulation //! Returns true if the item has a ManipulatedFrame. //! @see manipulatedFrame() virtual bool manipulatable() const { return false; } //!\brief The manipulatedFrame of the item. //! //! A manipulated frame is an independant system that can be //! translated or rotated using the Ctrl key and the mouse. //!@returns the manipulatedFrame of the item. virtual ManipulatedFrame* manipulatedFrame() { return 0; } // Getters for the four basic properties //!Getter for the item's color. //! @returns the current color of the item. virtual QColor color() const { return color_; } //!Getter for the item's name. //! @returns the current name of the item. virtual QString name() const { return name_; } //! If the item is not visible, it is not drawn and its Bbox //! is ignored in the computation of the scene's. //! @returns the current visibility of the item. virtual bool visible() const { return visible_; } //!Getter for the item's rendering mode. //! @returns the current rendering mode of the item. //!@see RenderingMode virtual RenderingMode renderingMode() const { return rendering_mode; } //!The renderingMode's name. //! @returns the current rendering mode of the item as a human readable string. virtual QString renderingModeName() const; //! \brief Context menu //! //! Contains the list of the supported rendering modes, //! the Operations menu, actions to save or clone the item if it is supported //! and any contextual action for the item. virtual QMenu* contextMenu(); //! //! \brief setId informs the item of its current index in the scene entries. //! void setId(int id); //! //! \brief getId returns the current index of this item in the scene entries. //! int getId()const; //!Handles key press events. virtual bool keyPressEvent(QKeyEvent*){return false;} //!The group containing the item. //! \returns the parent group if the item is in a group //! \returns 0 if the item is not in a group. Scene_group_item* parentGroup() const; //!Contains the header for the table in the statistics dialog /*! * A header data is composed of 2 columns : the Categories and the titles. * A category is the name given to an association of titles. * A title is the name of a line. *\verbatim * For example, * Category : | Titles| Values * 2 lines | | * ____________________________ * | |Name |Cube | * | |_______|_____| * |General Info | #Edges|12 | * |_____________|_______|_____| * * would be stored as follows : * categories = std::pair(QString("General Info"),2) * titles.append("Name"); * titles.append("#Edges");\endverbatim */ struct Header_data{ //!Contains the name of the category of statistics and the number of lines it will contain QList > categories; //!Contains the name of the lines of each category. Must be sorted from top to bottom. QList titles; }; //!Returns a Header_data struct containing the header information. virtual Header_data header()const; //!Returns true if the item has statistics. virtual bool has_stats()const{return false;} //!Returns a QString containing the requested value for the the table in the statistics dialog /*! \verbatim * Example : * ____________________________ * | |Name |Cube | * | |_______|_____| * |General Info | #Edges|12 | * |_____________|_______|_____| * compute stats(0) should return "Cube" and computeStats(1) should return QString::number(12); * The numbers must be coherent with the order of declaration of the titles in the header. * \endverbatim * */ virtual QString computeStats(int i); //!Contains the number of group and subgroups containing this item. int has_group; public Q_SLOTS: //! Notifies the program that the internal data or the properties of //! an item has changed, and that it must be computed again. It is //! important to call this function whenever the internal data is changed, //! or the displayed item will not be updated. virtual void invalidateOpenGLBuffers(); //!Setter for the color of the item. virtual void setColor(QColor c) { color_ = c;} //!Setter for the RGB color of the item. Calls setColor(QColor). //!@see setColor(QColor c) void setRbgColor(int r, int g, int b) { setColor(QColor(r, g, b)); } //!Sets the name of the item. virtual void setName(QString n) { name_ = n; } //!Sets the visibility of the item. virtual void setVisible(bool b); //!Set the parent group. If `group==0`, then the item has no parent. //!This function is called by `Scene::changeGroup` and should not be //!called manually. virtual void moveToGroup(Scene_group_item* group); //!Sets the rendering mode of the item. //!@see RenderingMode virtual void setRenderingMode(RenderingMode m) { if (supportsRenderingMode(m)) rendering_mode = m; Q_EMIT redraw(); } //!Sets the RenderingMode to Points. void setPointsMode() { setRenderingMode(Points); } //!Sets the RenderingMode to Points. void setShadedPointsMode() { setRenderingMode(ShadedPoints); } //!Sets the RenderingMode to Wireframe. void setWireframeMode() { setRenderingMode(Wireframe); } //!Sets the RenderingMode to Flat. void setFlatMode() { setRenderingMode(Flat); } //!Set the RenderingMode to FlatPlusEdges. void setFlatPlusEdgesMode() { setRenderingMode(FlatPlusEdges); } //!Sets the RenderingMode to Gouraud. void setGouraudMode() { setRenderingMode(Gouraud); } //!Sets the RenderingMode to PointsPlusNormals. void setPointsPlusNormalsMode(){ setRenderingMode(PointsPlusNormals); } //!Emits an aboutToBeDestroyed() signal. //!Override this function to delete what needs to be deleted on destruction. //!This might be needed as items are not always deleted right away by Qt and this behaviour may cause a simily //!memory leak, for example when multiple items are created at the same time. virtual void itemAboutToBeDestroyed(Scene_item*); //!Returns the alpha value for the item. //! Must be called within a valid openGl context. virtual float alpha() const; //! Sets the value of the aplha Slider for this item. //! //! Must be overriden; //! \param alpha must be between 0 and 255 virtual void setAlpha(int alpha); //!Selects a point through raycasting. virtual void select(double orig_x, double orig_y, double orig_z, double dir_x, double dir_y, double dir_z); Q_SIGNALS: //! Is emitted to notify a change in the item's data. void itemChanged(); //! Is emitted when the item is shown to notify a change in the item's visibility. //! Typically used to update the scene's bbox; void itemVisibilityChanged(); //! Is emitted to notify that the item is about to be deleted. void aboutToBeDestroyed(); //! Is emitted to require a new display. void redraw(); protected: //!Holds the BBox of the item mutable Bbox _bbox; mutable double _diag_bbox; mutable bool is_bbox_computed; mutable bool is_diag_bbox_computed; virtual void compute_bbox()const{} virtual void compute_diag_bbox()const; // The four basic properties //!The name of the item. QString name_; //!The color of the item. QColor color_; //!The visibility of the item. bool visible_; //!The parent group, or 0 if the item is not in a group. Scene_group_item* parent_group; //!Specifies if the item is currently selected. bool is_selected; //! Holds the number of vertices that are not linked to the polyhedron from the OFF //! file. std::size_t nb_isolated_vertices; /*! Decides if the draw function must call initializeBuffers() or not. It is set * to true in the end of initializeBuffers() and to false in invalidateOpenGLBuffers(). The need of * this boolean comes from the need of a context from the OpenGLFunctions used in * initializeBuffers(). * @see initializeBuffers() * @see invalidateOpenGLBuffers() */ mutable bool are_buffers_filled; //!The rendering mode of the item. //!@see RenderingMode RenderingMode rendering_mode; //!The default context menu. QMenu* defaultContextMenu; /*! Contains the previous RenderingMode. * This is used to determine if invalidateOpenGLBuffers should be called or not * in certain cases. * @see invalidateOpenGLBuffers()*/ RenderingMode prev_shading; /*! \todo replace it by RenderingMode(). * \brief Contains the current RenderingMode. * * This is used to determine if invalidateOpenGLBuffers should be called or not * in certain cases. * @see invalidateOpenGLBuffers()*/ RenderingMode cur_shading; //!Contains the size of the vector of VBOs int buffersSize; //!Contains the size of the map of VAOs int vaosSize; //!Contains the VBOs mutable std::vector buffers; /*! Contains the VAOs. */ std::vector vaos; int cur_id; //!Adds a VAO to the Map. void addVaos(int i) { QOpenGLVertexArrayObject* n_vao = new QOpenGLVertexArrayObject(); vaos[i] = n_vao; } /*! Fills the VBOs with data. */ void initializeBuffers(){} /*! Passes all the uniform data to the shaders. * According to program_name, this data may change. */ void attribBuffers(CGAL::Three::Viewer_interface*, int program_name) const; /*! Compatibility function. Calls `viewer->getShaderProgram()`. */ virtual QOpenGLShaderProgram* getShaderProgram(int name , CGAL::Three::Viewer_interface *viewer = 0) const; }; // end class Scene_item } } #include Q_DECLARE_METATYPE(CGAL::Three::Scene_item*) #endif // SCENE_ITEM_H