1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #ifndef _U2_OPENGL_WIDGET_H_
23 #define _U2_OPENGL_WIDGET_H_
24 
25 #include <QAction>
26 #include <QActionGroup>
27 #include <QColor>
28 #include <QGLWidget>
29 #include <QMenu>
30 #include <QSharedPointer>
31 #include <QTimer>
32 
33 #include <U2Algorithm/MolecularSurface.h>
34 
35 #include <U2Core/BioStruct3DObject.h>
36 #include <U2Core/Vector3D.h>
37 
38 #include "AnaglyphRenderer.h"
39 #include "BioStruct3DColorScheme.h"
40 #include "BioStruct3DGLRender.h"
41 #include "MolecularSurfaceRenderer.h"
42 
43 namespace U2 {
44 
45 class ADVSequenceObjectContext;
46 class AnnotatedDNAView;
47 class Annotation;
48 class AnnotationSelection;
49 class AnnotationTableObject;
50 class BioStruct3D;
51 class BioStruct3DColorSchemeFactory;
52 class BioStruct3DGLRendererFactory;
53 class Document;
54 class GLFrame;
55 class GLFrameManager;
56 class LRegionsSelection;
57 class MolecularSurfaceCalcTask;
58 class MolecularSurfaceRendererFactory;
59 class Task;
60 class U2Region;
61 class U2SequenceObject;
62 
63 /** Each biostruct added to scene should be represented by context */
64 class BioStruct3DRendererContext {
65 public:
BioStruct3DRendererContext(const BioStruct3DObject * obj)66     BioStruct3DRendererContext(const BioStruct3DObject *obj)
67         : obj(obj), biostruct(&obj->getBioStruct3D()) {
68     }
69 
70     const BioStruct3DObject *obj;
71     const BioStruct3D *biostruct;
72 
73     QSharedPointer<BioStruct3DGLRenderer> renderer;
74     QSharedPointer<BioStruct3DColorScheme> colorScheme;
75 };
76 
77 /*!
78  * @class BioStruct3DGLWidget BioStruct3DGLWidget.h
79  * @brief Class for BioStruct3DObject visualization.
80  *
81  * This widget provides a 3D graphical view of a macromolecular structure.   In terms
82  * of the Model-View architecture we consider
83  * the BioStruct3D the model and GLWidget a view of this model.
84  *
85  * The widget relies on various GLRenderer and ColorScheme subclasses to handle the
86  * rendering of the 3d objects.
87  *
88  * Also it includes actions for visualization control.
89  */
90 class BioStruct3DGLWidget : public QGLWidget {
91     Q_OBJECT
92     static int widgetCount;
93 
94 public:
95     // Used in PluginChecker to detect whether the GL is available
96     static void tryGL();
97 
98 public:
99     /*!
100      * Constructor.
101      * @param bsObj BioStruct3DObject contains 3d model for visualization
102      * @param view DnaView context for connecting structure 3D representation and sequence view
103      * @param manager GlFrameManager is required for OpenGL frame manipulation
104      * @param parent Parent widget
105      */
106     BioStruct3DGLWidget(BioStruct3DObject *bsObj, const AnnotatedDNAView *view, GLFrameManager *manager, QWidget *parent);
107 
108     //! Destructor.
109     ~BioStruct3DGLWidget();
110 
111     //! @return BioStruct3D const reference.
112     const BioStruct3D &getBioStruct3D() const;
113 
114     //! @return BioStruct3D Protein Data Bank id.
115     const QString getPDBId() const;
116 
117     //! @return BioStruct3DObject name.
118     const QString getBioStruct3DObjectName() const;
119 
120     /*!
121      * @return Menu containing display actions: renderers, color schemes etc.
122      */
123     QMenu *getDisplayMenu();
124     /*!
125      * Records widget active settings (part of UGENE architecture).
126      * @return Current widgets settings.
127      */
128     QVariantMap getState();
129     /*!
130      * Restores widget settings with given (part of UGENE architecture).
131      * @param state Widgets settings.
132      */
133     void setState(const QVariantMap &state);
134     /*!
135      * Restores default widget settings (viewMatrix, glRenderer, color scheme)
136      */
137     void restoreDefaultSettigns();
138     /*!
139      * @param delta Positive value: zoom in, negative value: zoom out.
140      */
141     void zoom(float delta);
142     void shift(float deltaX, float deltaY);
143     /*!
144      * Creates 2d vector image of BioStruct3DGLWidget contents using gl2ps.
145      */
146     void writeImage2DToFile(int format, int options, int nbcol, const char *fileName);
147 
148     void setBackgroundColor(QColor backgroundColor);
149 
150     /** @returns This widget GLFrame */
151     GLFrame *getGLFrame();
152 
153     /** Draws scene without setting camera */
154     void draw();
155 
156     /** @returns scene rotation center */
157     Vector3D getSceneCenter() const;
158 
159     /** @returns scene bounding sphere radius */
160     float getSceneRadius() const;
161 
162     void setImageRenderingMode(bool status);
163 
164 protected:
165     /*!
166      * QGlWidget virtual function, initializes OpenGL params. See, Qt docs "QGLWidget" for details.
167      */
168     void initializeGL();
169     /*!
170      * QGlWidget virtual function, sets viewport
171      * @param width GLWidget width
172      * @param height GLWidget height
173      */
174     void resizeGL(int width, int height);
175     /*!
176      * QGlWidget virtual function, draw GL scene.
177      */
178     void paintGL();
179     /*!
180      * QWidget virtual function, mouse button down event handler.
181      */
182     void mousePressEvent(QMouseEvent *event);
183     /*!
184      * QWidget virtual function, mouse move event handler.
185      */
186     void mouseMoveEvent(QMouseEvent *event);
187     /*!
188      * QWidget virtual function, mouse wheel event handler.
189      */
190     void wheelEvent(QWheelEvent *event);
191     /*!
192      * QWidget virtual function, executes context menu.
193      */
194     void contextMenuEvent(QContextMenuEvent *_event);
195 
196 private:
197     //! Sets unselected regions shading level
198     void setUnselectedShadingLevel(int shading);
199 
200     /*!
201      * Sets light position.
202      * @param pos New light source position. Directional light is being used.
203      */
204     void setLightPosition(const Vector3D &pos);
205 
206     // controller logic
207     //! Creates actions for existing GLRenderers, loads default renderer.
208     void loadGLRenderers(const QList<QString> &availableRenderers);
209     //! Creates actions for existing ColorSchemes, loads default color scheme.
210     void loadColorSchemes();
211 
212     //! Creates actions for structural alignment
213     void createStrucluralAlignmentActions();
214 
215     //! Creates menu for structural alignment
216     QMenu *createStructuralAlignmentMenu();
217 
218     void createActions();
219     void createMenus();
220 
221     // view logic
222     /** Adds biostruct object to scene.
223      * @param shownModels is a modelId list (same as in PDB)
224      */
225     void addBiostruct(const BioStruct3DObject *biostruct, const QList<int> &shownModels = QList<int>());
226 
227     //! Creates renderers for all biostructs.
228     void setupRenderer(const QString &name);
229 
230     //! Creates color scheme for all biostructs.
231     void setupColorScheme(const QString &name);
232 
233     //! Updates color scheme for all renderers.
234     void updateAllColorSchemes();
235 
236     /** Updates all renderers.
237      * Should be called from initializeGL for display list recreation
238      */
239     void updateAllRenderers();
240 
241     //! Show/hide selected model for first biostruct
242     //! @param modelId - key from BioStruct3D::modelMap
243     void showModel(int modelId, bool show);
244 
245     //! Show/hide all models for first biostruct
246     void showAllModels(bool show);
247 
248     /** Setup frame settings: camera clip, camera position */
249     void setupFrame();
250 
251     void saveDefaultSettings();
252 
253     void connectExternalSignals();
254 
255     Vector3D getTrackballMapping(int x, int y);
256     static int getWidgetCount(QString objectName);
257     bool isSyncModeOn();
258 
259     // Checks if this widget can render and creates a label with a text error if it cannot
260     void checkRenderingAndCreateLblError();
261 
262 private:
263     // related sequences view
264     const AnnotatedDNAView *dnaView;
265 
266     QList<BioStruct3DRendererContext> contexts;
267 
268     // Settings common for all renderers, such as detail level
269     BioStruct3DRendererSettings rendererSettings;
270 
271     GLFrameManager *frameManager;
272     QScopedPointer<GLFrame> glFrame;
273 
274     QScopedPointer<MolecularSurface> molSurface;
275     QScopedPointer<MolecularSurfaceRenderer> surfaceRenderer;
276 
277     MolecularSurfaceCalcTask *surfaceCalcTask;
278 
279     AnaglyphStatus anaglyphStatus;
280     QScopedPointer<AnaglyphRenderer> anaglyph;
281 
282     QVariantMap defaultsSettings;
283 
284     // controller logic
285     QString currentColorSchemeName;
286     QString currentGLRendererName;
287 
288     // camera
289     GLfloat rotAngle, spinAngle;
290     Vector3D rotAxis, lastPos;
291 
292     // light
293     GLfloat lightPosition[4];
294 
295     QColor backgroundColor;
296     QColor selectionColor;
297     QTimer *animationTimer;
298 
299     int unselectedShadingLevel;
300     // Should be true when painting an image
301     bool imageRenderingMode;
302 
303     // controller logic
304     QAction *spinAction;
305     QAction *settingsAction;
306     QAction *closeAction;
307     QAction *exportImageAction;
308 
309     // actions for selecting/deselecting shown models
310     QAction *selectModelsAction;
311 
312     // structural alignment related actions
313     QAction *alignWithAction;
314     QAction *resetAlignmentAction;
315 
316     QActionGroup *colorSchemeActions;
317     QActionGroup *rendererActions;
318     QActionGroup *molSurfaceRenderActions;
319     QActionGroup *molSurfaceTypeActions;
320 
321     QMenu *selectColorSchemeMenu;
322     QMenu *selectRendererMenu;
323     QMenu *displayMenu;
324 
325     // if OpenGL has error, label is not null and overlaps GlWidget with text "Failed to initialize OpenGL",
326     // otherwise label is null
327     QLabel *lblGlError;
328 
329 private slots:
330     void sl_selectColorScheme(QAction *action);
331     void sl_selectGLRenderer(QAction *action);
332     void sl_updateRenderSettings(const QStringList &list);
333     void sl_acitvateSpin();
334     void sl_updateAnnimation();
335     void sl_settings();
336     void sl_exportImage();
337 
338     // structural alignment relalated slots
339     void sl_alignWith();
340     void sl_resetAlignment();
341     void sl_onAlignmentDone(Task *);
342 
343     // slots for handling sequence selection
344     void sl_onSequenceAddedToADV(ADVSequenceObjectContext *ctx);
345     void sl_onSequenceRemovedFromADV(ADVSequenceObjectContext *ctx);
346     void sl_onSequenceSelectionChanged(LRegionsSelection *s, const QVector<U2Region> &added, const QVector<U2Region> &removed);
347 
348     // slots for select/deselect shown models actions
349     // they affects only first biostruct
350     void sl_selectModels();
351 
352     // slots for surface renderers
353     void sl_showSurface();
354     void sl_hideSurface();
355     void sl_selectSurfaceRenderer(QAction *surfaceRenderer);
356 
357     // used only for handling MolecularSurfaceCalcTask
358     // should be in special MolecularSurfaceProxy
359     void sl_onTaskFinished(Task *task);
360 
361 public:
362     static const QString BACKGROUND_COLOR_NAME;
363 
364     static const QString PRODUCT_NAME;
365     static const QString PLUGIN_NAME;
366     static const QString COLOR_SCHEME_NAME;
367     static const QString RENDERER_NAME;
368     static const QString OBJECT_ID_NAME;
369 
370     static const QString SELECTION_COLOR_NAME;
371     static const QString RENDER_DETAIL_LEVEL_NAME;
372     static const QString SHADING_LEVEL_NAME;
373     static const QString ANAGLYPH_STATUS_NAME;
374 };
375 
376 }  // namespace U2
377 
378 #endif  // _U2_OPENGL_WIDGET_H
379