1 #ifndef __plot3d__
2 #define __plot3d__
3 
4 #include <QOpenGLWidget>
5 
6 #include "qwt3d_coordsys.h"
7 #include "qwt3d_enrichment_std.h"
8 
9 namespace Qwt3D {
10 
11 //! Base class for all plotting widgets
12 /*!
13   Plot3D handles all the common features for plotting widgets - coordinate system, transformations,
14   mouse/keyboard handling, labeling etc.. It contains some pure virtual functions and is, in so far,
15   an abstract base class. The class provides interfaces for data handling and implements basic data
16   controlled color allocation.
17 */
18 class QWT3D_EXPORT Plot3D : public QOpenGLWidget
19 {
20     Q_OBJECT
21 
22 public:
23     Plot3D(QWidget *parent = 0);
24     virtual ~Plot3D();
25 
26     QPixmap renderPixmap(int w = 0, int h = 0, bool useContext = false);
27     void updateData(); //!< Recalculate data
28     void createCoordinateSystem(Qwt3D::Triple beg, Qwt3D::Triple end);
coordinates()29     Qwt3D::CoordinateSystem *coordinates()
30     {
31         return &coordinates_p;
32     } //!< Returns pointer to CoordinateSystem object
legend()33     Qwt3D::ColorLegend *legend() { return &legend_; } //!< Returns pointer to ColorLegend object
34 
xRotation()35     double xRotation() const
36     {
37         return xRot_;
38     } //!< Returns rotation around X axis [-360..360] (some angles are equivalent)
yRotation()39     double yRotation() const
40     {
41         return yRot_;
42     } //!< Returns rotation around Y axis [-360..360] (some angles are equivalent)
zRotation()43     double zRotation() const
44     {
45         return zRot_;
46     } //!< Returns rotation around Z axis [-360..360] (some angles are equivalent)
47 
xShift()48     double xShift() const { return xShift_; } //!< Returns shift along X axis (object coordinates)
yShift()49     double yShift() const { return yShift_; } //!< Returns shift along Y axis (object coordinates)
zShift()50     double zShift() const { return zShift_; } //!< Returns shift along Z axis (object coordinates)
51 
xViewportShift()52     double xViewportShift() const
53     {
54         return xVPShift_;
55     } //!< Returns relative shift [-1..1] along X axis (view coordinates)
yViewportShift()56     double yViewportShift() const
57     {
58         return yVPShift_;
59     } //!< Returns relative shift [-1..1] along Y axis (view coordinates)
60 
xScale()61     double xScale() const { return xScale_; } //!< Returns scaling for X values [0..inf]
yScale()62     double yScale() const { return yScale_; } //!< Returns scaling for Y values [0..inf]
zScale()63     double zScale() const { return zScale_; } //!< Returns scaling for Z values [0..inf]
64 
zoom()65     double zoom() const { return zoom_; } //!< Returns zoom (0..inf)
66 
ortho()67     bool ortho() const
68     {
69         return ortho_;
70     } //!< Returns orthogonal (true) or perspective (false) projection
71     void setPlotStyle(Qwt3D::PLOTSTYLE val);
72     Qwt3D::Enrichment *setPlotStyle(Qwt3D::Enrichment const &val);
plotStyle()73     Qwt3D::PLOTSTYLE plotStyle() const { return plotstyle_; } //!< Returns plotting style
74     //! Returns current Enrichment object used for plotting styles (if set, zero else)
userStyle()75     Qwt3D::Enrichment *userStyle() const { return userplotstyle_p; }
76     void setShading(Qwt3D::SHADINGSTYLE val);
shading()77     Qwt3D::SHADINGSTYLE shading() const { return shading_; } //!< Returns shading style
78     void setIsolines(int isolines);
isolines()79     int isolines() const { return isolines_; } //!< Returns number of isolines
80 
setSmoothMesh(bool val)81     void setSmoothMesh(bool val)
82     {
83         smoothdatamesh_p = val;
84     } //!< Enables/disables smooth data mesh lines. Default is false
smoothDataMesh()85     bool smoothDataMesh() const { return smoothdatamesh_p; } //!< True if mesh antialiasing is on
86     void setBackgroundColor(Qwt3D::RGBA rgba); //!< Sets widgets background color
backgroundRGBAColor()87     Qwt3D::RGBA backgroundRGBAColor() const
88     {
89         return bgcolor_;
90     } //!< Returns the widgets background color
91     void setMeshColor(Qwt3D::RGBA rgba); //!< Sets color for data mesh
meshColor()92     Qwt3D::RGBA meshColor() const { return meshcolor_; } //!< Returns color for data mesh
93     void setMeshLineWidth(double lw); //!< Sets line width for data mesh
meshLineWidth()94     double meshLineWidth() const { return meshLineWidth_; } //!< Returns line width for data mesh
95     void setDataColor(Color *col); //!< Sets new data color object
dataColor()96     const Color *dataColor() const { return datacolor_p; } //!< Returns data color object
97 
98     virtual Qwt3D::Enrichment *addEnrichment(Qwt3D::Enrichment const &); //!< Add an Enrichment
99     virtual bool degrade(Qwt3D::Enrichment *); //!< Remove an Enrichment
100 
hull()101     Qwt3D::ParallelEpiped hull() const { return hull_; } //!< Returns rectangular hull
102 
103     void showColorLegend(bool);
104 
105     void setCoordinateStyle(Qwt3D::COORDSTYLE st); //!< Sets style of coordinate system.
106     void setPolygonOffset(double d);
polygonOffset()107     double polygonOffset() const
108     {
109         return polygonOffset_;
110     } //!< Returns relative value for polygon offset [0..1]
111 
112     void setTitlePosition(double rely, double relx = 0.5, Qwt3D::ANCHOR = Qwt3D::TopCenter);
113     void setTitleFont(const QString &family, int pointSize, int weight = QFont::Normal,
114                       bool italic = false);
setTitleColor(Qwt3D::RGBA col)115     void setTitleColor(Qwt3D::RGBA col) { title_.setColor(col); } //!< Set caption color
setTitle(const QString & title)116     void setTitle(const QString &title)
117     {
118         title_.setString(title);
119     } //!< Set caption text (one row only)
120 
121     void assignMouse(MouseState xrot, MouseState yrot, MouseState zrot, MouseState xscale,
122                      MouseState yscale, MouseState zscale, MouseState zoom, MouseState xshift,
123                      MouseState yshift);
124 
125     bool mouseEnabled() const; //!< Returns true, if the widget accept mouse input from the user
126     void assignKeyboard(KeyboardState xrot_n, KeyboardState xrot_p, KeyboardState yrot_n,
127                         KeyboardState yrot_p, KeyboardState zrot_n, KeyboardState zrot_p,
128                         KeyboardState xscale_n, KeyboardState xscale_p, KeyboardState yscale_n,
129                         KeyboardState yscale_p, KeyboardState zscale_n, KeyboardState zscale_p,
130                         KeyboardState zoom_n, KeyboardState zoom_p, KeyboardState xshift_n,
131                         KeyboardState xshift_p, KeyboardState yshift_n, KeyboardState yshift_p);
132 
133     bool
134     keyboardEnabled() const; //!< Returns true, if the widget accept keyboard input from the user
135     //! Sets speed for keyboard driven transformations
136     void setKeySpeed(double rot, double scale, double shift);
137     //! Gets speed for keyboard driven transformations
138     void keySpeed(double &rot, double &scale, double &shift) const;
139 
140     bool lightingEnabled() const; //!< Returns true, if Lighting is enabled, false else
141     //! Turn light on
142     void illuminate(unsigned light = 0);
143     //! Turn light off
144     void blowout(unsigned light = 0);
145 
146     void setMaterialComponent(GLenum property, double r, double g, double b, double a = 1.0);
147     void setMaterialComponent(GLenum property, double intensity);
148     void setShininess(double exponent);
149     void setLightComponent(GLenum property, double r, double g, double b, double a = 1.0,
150                            unsigned light = 0);
151     void setLightComponent(GLenum property, double intensity, unsigned light = 0);
152 
153     //! Returns Light 'idx' rotation around X axis [-360..360] (some angles are equivalent)
154     double xLightRotation(unsigned idx = 0) const { return (idx < 8) ? lights_[idx].rot.x : 0; }
155     //! Returns Light 'idx' rotation around Y axis [-360..360] (some angles are equivalent)
156     double yLightRotation(unsigned idx = 0) const { return (idx < 8) ? lights_[idx].rot.y : 0; }
157     //! Returns Light 'idx' rotation around Z axis [-360..360] (some angles are equivalent)
158     double zLightRotation(unsigned idx = 0) const { return (idx < 8) ? lights_[idx].rot.z : 0; }
159 
160     //! Returns shift of Light 'idx 'along X axis (object coordinates)
161     double xLightShift(unsigned idx = 0) const { return (idx < 8) ? lights_[idx].shift.x : 0; }
162     //! Returns shift of Light 'idx 'along Y axis (object coordinates)
163     double yLightShift(unsigned idx = 0) const { return (idx < 8) ? lights_[idx].shift.y : 0; }
164     //! Returns shift of Light 'idx 'along Z axis (object coordinates)
165     double zLightShift(unsigned idx = 0) const { return (idx < 8) ? lights_[idx].shift.z : 0; }
166     //! Returns true if valid data available, false else
hasData()167     bool hasData() const { return (actualData_p) ? !actualData_p->empty() : false; }
168 
169 Q_SIGNALS:
170 
171     //! Emitted, if the rotation is changed
172     void rotationChanged(double xAngle, double yAngle, double zAngle);
173     //! Emitted, if the shift is changed
174     void shiftChanged(double xShift, double yShift, double zShift);
175     //! Emitted, if the viewport shift is changed
176     void vieportShiftChanged(double xShift, double yShift);
177     //! Emitted, if the scaling is changed
178     void scaleChanged(double xScale, double yScale, double zScale);
179     //! Emitted, if the zoom is changed
180     void zoomChanged(double);
181     //! Emitted, if the projection mode is changed
182     void projectionChanged(bool);
183 
184 public Q_SLOTS:
185 
186     void setRotation(double xVal, double yVal, double zVal);
187     void setShift(double xVal, double yVal, double zVal);
188     void setViewportShift(double xVal, double yVal);
189     void setScale(double xVal, double yVal, double zVal);
190     void setZoom(double);
191 
192     void setOrtho(bool);
193 
194     void enableMouse(bool val = true); //!< Enable mouse input
195     void disableMouse(bool val = true); //!< Disable mouse input
196     void enableKeyboard(bool val = true); //!< Enable keyboard input
197     void disableKeyboard(bool val = true); //!< Disable keyboard input
198 
199     void enableLighting(bool val = true); //!< Turn Lighting on or off
200     void disableLighting(bool val = true); //!< Turn Lighting on or off
201 
202     void setLightRotation(double xVal, double yVal, double zVal, unsigned int idx = 0);
203     void setLightShift(double xVal, double yVal, double zVal, unsigned int idx = 0);
204 
205     virtual bool savePixmap(QString const &fileName,
206                             QString const &format); //!<  Saves content to pixmap format
207     //!  Saves content to vector format
208     virtual bool saveVector(QString const &fileName, QString const &format,
209                             VectorWriter::TEXTMODE text, VectorWriter::SORTMODE sortmode);
210     virtual bool save(QString const &fileName, QString const &format); //!<  Saves content
211 
212 protected:
213     typedef std::list<Qwt3D::Enrichment *> EnrichmentList;
214     typedef EnrichmentList::iterator ELIT;
215 
216     void initializeGL();
217     void paintGL();
218     void resizeGL(int w, int h);
219 
220     void mousePressEvent(QMouseEvent *e);
221     void mouseReleaseEvent(QMouseEvent *e);
222     void mouseMoveEvent(QMouseEvent *e);
223     void wheelEvent(QWheelEvent *e);
224 
225     void keyPressEvent(QKeyEvent *e);
226 
227     Qwt3D::CoordinateSystem coordinates_p;
228     Qwt3D::Color *datacolor_p;
229     Qwt3D::Enrichment *userplotstyle_p;
230     EnrichmentList elist_p;
231 
232     virtual void calculateHull() = 0;
233     virtual void createData() = 0;
createEnrichment(Qwt3D::Enrichment &)234     virtual void createEnrichment(Qwt3D::Enrichment &) { }
235     virtual void createEnrichments();
236 
237     void createCoordinateSystem();
setHull(Qwt3D::ParallelEpiped p)238     void setHull(Qwt3D::ParallelEpiped p) { hull_ = p; }
239 
initializedGL()240     bool initializedGL() const { return initializedGL_; }
241 
242     enum OBJECTS {
243         DataObject,
244         LegendObject,
245         NormalObject,
246         DisplayListSize // only to have a vector length ...
247     };
248     std::vector<GLuint> displaylists_p;
249     Qwt3D::Data *actualData_p;
250 
251 private:
252     struct Light
253     {
LightLight254         Light() : unlit(true) { }
255         bool unlit;
256         Qwt3D::Triple rot;
257         Qwt3D::Triple shift;
258     };
259     std::vector<Light> lights_;
260 
261     GLdouble xRot_, yRot_, zRot_, xShift_, yShift_, zShift_, zoom_, xScale_, yScale_, zScale_,
262             xVPShift_, yVPShift_;
263 
264     Qwt3D::RGBA meshcolor_;
265     double meshLineWidth_;
266     Qwt3D::RGBA bgcolor_;
267     Qwt3D::PLOTSTYLE plotstyle_;
268     Qwt3D::SHADINGSTYLE shading_;
269     Qwt3D::FLOORSTYLE floorstyle_;
270     bool ortho_;
271     double polygonOffset_;
272     int isolines_;
273     bool displaylegend_;
274     bool smoothdatamesh_p;
275 
276     Qwt3D::ParallelEpiped hull_;
277 
278     Qwt3D::ColorLegend legend_;
279 
280     Label title_;
281     Qwt3D::Tuple titlerel_;
282     Qwt3D::ANCHOR titleanchor_;
283 
284     // mouse
285 
286     QPoint lastMouseMovePosition_;
287     bool mpressed_;
288 
289     MouseState xrot_mstate_, yrot_mstate_, zrot_mstate_, xscale_mstate_, yscale_mstate_,
290             zscale_mstate_, zoom_mstate_, xshift_mstate_, yshift_mstate_;
291 
292     bool mouse_input_enabled_;
293 
294     void setRotationMouse(MouseState bstate, double accel, QPoint diff);
295     void setScaleMouse(MouseState bstate, double accel, QPoint diff);
296     void setShiftMouse(MouseState bstate, double accel, QPoint diff);
297 
298     // keyboard
299 
300     bool kpressed_;
301 
302     KeyboardState xrot_kstate_[2], yrot_kstate_[2], zrot_kstate_[2], xscale_kstate_[2],
303             yscale_kstate_[2], zscale_kstate_[2], zoom_kstate_[2], xshift_kstate_[2],
304             yshift_kstate_[2];
305 
306     bool kbd_input_enabled_;
307     double kbd_rot_speed_, kbd_scale_speed_, kbd_shift_speed_;
308 
309     void setRotationKeyboard(KeyboardState kseq, double speed);
310     void setScaleKeyboard(KeyboardState kseq, double speed);
311     void setShiftKeyboard(KeyboardState kseq, double speed);
312 
313     bool lighting_enabled_;
314     void applyLight(unsigned idx);
315     void applyLights();
316 
317     bool initializedGL_;
318     bool renderpixmaprequest_;
319 };
320 
321 } // ns
322 
323 #endif
324