File indexing completed on 2024-04-21 03:40:41

0001 /*************************************************************************************
0002  *  Copyright (C) 2012 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com>      * 
0003  *  Copyright (C) 2007 by Abderrahman Taha: Basic OpenGL calls like scene, lights    *
0004  *                                          and mouse behaviour taken from K3DSurf   *
0005  *                                                                                   *
0006  *  This program is free software; you can redistribute it and/or                    *
0007  *  modify it under the terms of the GNU General Public License                      *
0008  *  as published by the Free Software Foundation; either version 2                   *
0009  *  of the License, or (at your option) any later version.                           *
0010  *                                                                                   *
0011  *  This program is distributed in the hope that it will be useful,                  *
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0014  *  GNU General Public License for more details.                                     *
0015  *                                                                                   *
0016  *  You should have received a copy of the GNU General Public License                *
0017  *  along with this program; if not, write to the Free Software                      *
0018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0019  *************************************************************************************/
0020 
0021 #ifndef PLOTTER3DES_H
0022 #define PLOTTER3DES_H
0023 
0024 #include "plotitem.h"
0025 
0026 #include <QModelIndex>
0027 #include <QRect>
0028 #include <QVector3D>
0029 #include <QMatrix4x4>
0030 #include <QOpenGLFunctions>
0031 #include <QOpenGLBuffer>
0032 #include <QOpenGLShaderProgram>
0033 #include "analitzaplotexport.h"
0034 
0035 class QAbstractItemModel;
0036 
0037 namespace Analitza
0038 {
0039 
0040 /**
0041  * \class Plotter3DES
0042  * 
0043  * \ingroup AnalitzaPlotModule
0044  *
0045  * \brief This class manage the OpenGL scene where the plots will be rendered.
0046  *
0047  * Plotter3DES provides an agnostic way to manage a 3d scene for draw math plots,
0048  * Contains just OpenGL calls, so is uncoupled with QWidget nor QtQuick. This 
0049  * class needs the PlotsModel (to create the geometry for 3D plots) and also 
0050  * exposes some methods to change the scene (like hide/show the axis or 
0051  * reference planes for example)
0052  */
0053 
0054 class ANALITZAPLOT_EXPORT Plotter3DES : private QOpenGLFunctions
0055 {
0056     public:
0057         //TODO transparency effect when select current item
0058 //         enum FocusEffect {};
0059 
0060         explicit Plotter3DES(QAbstractItemModel* model = nullptr);
0061         virtual ~Plotter3DES();
0062 
0063         virtual void initGL();
0064         virtual void setViewport(const QRectF &vp);
0065         void drawPlots();
0066         virtual int currentPlot() const = 0;
0067         virtual void modelChanged() = 0;
0068 
0069         /** Force OpenGL to render the scene. QGLWidget should call updateGL in this method. */
0070         virtual void renderGL() = 0;
0071 
0072         void exportSurfaces(const QString& path) const;
0073 
0074         /** Force the plots from @p start to @p end to be recalculated. */
0075         void updatePlots(const QModelIndex & parent, int start, int end);
0076 
0077         void setModel(QAbstractItemModel* f);
0078         QAbstractItemModel* model() const { return m_model; }
0079 
0080         PlotStyle plotStyle() const { return m_plotStyle; }
0081         void setPlotStyle(PlotStyle ps) { m_plotStyle = ps; renderGL(); }
0082 //         void setPlottingAttributes(PlotStyle st) { m_plotStyle = ps; }
0083         PlottingFocusPolicy plottingFocusPolicy() const { return m_plottingFocusPolicy; }
0084         void setPlottingFocusPolicy(PlottingFocusPolicy fp);
0085 
0086         /** Set the scale of all the scene by @p factor */
0087         void scale(qreal factor);
0088 
0089         // Advanced rotation features
0090 
0091         /** Rotates by @p dx and @p dy in screen coordinates. */
0092         void rotate(int dx, int dy);
0093 
0094         /** Query if there is a valid axis arrow for @p x and @p y screen coordinates. */
0095         CartesianAxis selectAxisArrow(int x, int y);
0096 
0097         /** Fix the rotation around @p direction */
0098         void fixRotation(const QVector3D &direction);
0099 
0100         /** Query if the rotation is fixed by a specific direction. */
0101         bool isRotationFixed() const { return !m_rotFixed.isNull(); }
0102 
0103         /** Show a little indicator (as a hint) next to the arrow of @p axis */
0104         void showAxisArrowHint(CartesianAxis axis);
0105 
0106         /** Hide the current indicator of the axis */
0107         void hideAxisHint();
0108 
0109         /**  If the flag @p simplerot is true the rotation ignores any fixed or free direction */
0110         ANALITZAPLOT_DEPRECATED void setUseSimpleRotation(bool simplerot);
0111 
0112         /**  Get information about the current rotarion approach: if return true then rotation is simple. */
0113         bool isUsingSimpleRotation() const { return m_simpleRotation; }
0114 
0115         /** sets the view to the initial perspective */
0116         void resetViewport();
0117 
0118         /**
0119          * saves the currently displayed plot in @p url
0120          *
0121          * @returns whether it was saved successfully
0122          */
0123         bool save(const QUrl &url);
0124 
0125         /**
0126          * @returns the filters supported by save
0127          *
0128          * @see save()
0129          */
0130         QStringList filters() const;
0131 
0132         void setReferencePlaneColor(const QColor &color) { m_referencePlaneColor = color; }
0133 
0134     protected:
0135         void addPlots(PlotItem* item);
0136 
0137     private:
0138         static const quint8 XAxisArrowColor[];
0139         static const quint8 YAxisArrowColor[];
0140         static const quint8 ZAxisArrowColor[];
0141 
0142         virtual QImage grabImage() = 0;
0143 
0144         void resetViewPrivate(const QVector3D& rot);
0145 
0146         enum SceneObjectType {Axes, RefPlaneXY, XArrowAxisHint, YArrowAxisHint, ZArrowAxisHint};
0147 
0148         PlotItem *itemAt(int row) const;
0149 
0150         void drawAxes();
0151         void drawRefPlane();
0152 
0153         QAbstractItemModel* m_model;
0154 
0155         QMap<PlotItem*, QOpenGLBuffer> m_itemGeometries; // pair:=<indexdata_id, vertex-normals_id>
0156 
0157         PlotStyle m_plotStyle;
0158         PlottingFocusPolicy m_plottingFocusPolicy;
0159 
0160         //scene properties
0161         QMap<SceneObjectType, uint > m_sceneObjects;
0162         QRectF m_viewport;
0163         const GLfloat m_depth;
0164         qreal m_scale;
0165         QMatrix4x4 m_rot;
0166         QVector3D m_rotFixed;
0167         CartesianAxis m_currentAxisIndicator;
0168         bool m_simpleRotation;
0169         QVector3D m_simpleRotationVector;
0170         QVector3D m_lightpos;
0171         QColor m_referencePlaneColor;
0172 
0173         QOpenGLShaderProgram program;
0174         QMatrix4x4 m_projection;
0175 };
0176 
0177 }
0178 
0179 #endif // PLOTTER3D_H