File indexing completed on 2024-04-14 03:39:24
0001 /************************************************************************************* 0002 * Copyright (C) 2015 by Aleix Pol <aleixpol@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 #include "graph3ditem.h" 0020 #include <QQuickWindow> 0021 #include <QOpenGLFramebufferObject> 0022 #include <analitzaplot/plotsmodel.h> 0023 #include <QTimer> 0024 #include <QQuickItemGrabResult> 0025 #include <QGuiApplication> 0026 #include <QElapsedTimer> 0027 0028 using namespace Analitza; 0029 0030 Plotter3DRenderer::Plotter3DRenderer(Graph3DItem* item) 0031 : QObject(item) 0032 , m_item(item) 0033 {} 0034 0035 void Plotter3DRenderer::renderGL() 0036 { 0037 QTimer::singleShot(0, m_item, &Graph3DItem::update); 0038 } 0039 0040 QQuickWindow* Plotter3DRenderer::window() const 0041 { 0042 return m_item->window(); 0043 } 0044 0045 Graph3DItem::Graph3DItem(QQuickItem* parent) 0046 : QQuickFramebufferObject(parent) 0047 , m_plotter(new Plotter3DRenderer(this)) 0048 { 0049 //FIXME 0050 m_plotter->setUseSimpleRotation(true); 0051 setModel(new PlotsModel(this)); 0052 0053 setMirrorVertically(true); 0054 } 0055 0056 Graph3DItem::~Graph3DItem() 0057 {} 0058 0059 QStringList Graph3DItem::addFunction(const QString& expression, const QSharedPointer<Analitza::Variables>& vars) 0060 { 0061 PlotsModel* plotsmodel = qobject_cast<PlotsModel*>(m_plotter->model()); 0062 if(!plotsmodel) 0063 qWarning() << "only can add plots to a PlotsModel instance"; 0064 else 0065 return plotsmodel->addFunction(expression, Dim3D, vars); 0066 return {}; 0067 } 0068 0069 QAbstractItemModel* Graph3DItem::model() const 0070 { 0071 return m_plotter->model(); 0072 } 0073 0074 void Graph3DItem::setModel(QAbstractItemModel* model) 0075 { 0076 if (m_plotter->model()) 0077 disconnect(m_plotter->model(), nullptr, this, nullptr); 0078 0079 m_plotter->setModel(model); 0080 0081 connect(model, &QAbstractItemModel::dataChanged, m_plotter, [this](const QModelIndex& start, const QModelIndex& end) 0082 { m_plotter->updatePlots(QModelIndex(), start.row(), end.row()); } 0083 ); 0084 0085 auto updateCount = [this](const QModelIndex &parent, int start, int end) { m_plotter->updatePlots(parent, start, end); }; 0086 connect(model, &QAbstractItemModel::rowsInserted, this, updateCount); 0087 connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, this, updateCount); 0088 0089 Q_EMIT modelChanged(model); 0090 } 0091 0092 void Graph3DItem::rotate(qreal x, qreal y) 0093 { 0094 m_plotter->rotate(x, y); 0095 } 0096 0097 void Graph3DItem::scale(qreal s) 0098 { 0099 m_plotter->scale(s); 0100 } 0101 0102 void Graph3DItem::resetViewport() 0103 { 0104 m_plotter->resetViewport(); 0105 } 0106 0107 bool Graph3DItem::save(const QUrl& url) 0108 { 0109 return m_plotter->save(url); 0110 } 0111 0112 QStringList Graph3DItem::filters() const 0113 { 0114 return m_plotter->filters(); 0115 } 0116 0117 class Plotter3DFboRenderer : public QQuickFramebufferObject::Renderer 0118 { 0119 public: 0120 Plotter3DFboRenderer(Plotter3DRenderer* plotter) 0121 : m_plotter(plotter) 0122 { 0123 m_plotter->initGL(); 0124 } 0125 0126 void render() override { 0127 m_plotter->drawPlots(); 0128 } 0129 0130 QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override 0131 { 0132 QOpenGLFramebufferObjectFormat format; 0133 format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); 0134 return new QOpenGLFramebufferObject(size, format); 0135 } 0136 0137 private: 0138 Plotter3DRenderer* m_plotter; 0139 }; 0140 0141 QQuickFramebufferObject::Renderer* Graph3DItem::createRenderer() const 0142 { 0143 m_plotter->setViewport(QRectF({0,0}, QSizeF(width(), height()))); 0144 return new Plotter3DFboRenderer(m_plotter); 0145 } 0146 0147 QImage Plotter3DRenderer::grabImage() 0148 { 0149 QSharedPointer<QQuickItemGrabResult> imgGrab = m_item->grabToImage(); 0150 QImage ret; 0151 connect(imgGrab.data(), &QQuickItemGrabResult::ready, this, [imgGrab, &ret]() { 0152 ret = imgGrab->image(); 0153 }); 0154 QElapsedTimer timer; 0155 timer.start(); 0156 while(ret.size().isEmpty() && timer.elapsed()<2000) { 0157 qGuiApp->processEvents(); 0158 } 0159 return ret; 0160 } 0161 0162 #include "moc_graph3ditem.cpp"