You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

563 lines
14 KiB

/***************************************************************************
qsaxes3d.h
-------------------
begin : 01-January-2000
copyright : (C) 2000 by Kamil Dobkowski
email : kamildobk@poczta.onet.pl
***************************************************************************/
/***************************************************************************
* *
* This program is free software; 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QSAXES3D_H
#define QSAXES3D_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include"qsaxes.h"
#include"qsprojection3d.h"
/**
* \brief Ordinary XYZ axes
*
* @author Kamil Dobkowski
*/
class QSAxes3D : public QSAxes
{
Q_OBJECT
Q_PROPERTY( bool openGL READ openGL WRITE setOpenGL )
Q_PROPERTY( bool glTransparency READ glTransparency WRITE glSetTransparency )
Q_PROPERTY( int glGlobalTransparency READ glGlobalTransparency WRITE glSetGlobalTransparency )
Q_PROPERTY( bool glShadeWalls READ glShadeWalls WRITE glSetShadeWalls )
Q_PROPERTY( bool glMeshAutoStroke READ glMeshAutoStroke WRITE glSetMeshAutoStroke )
Q_PROPERTY( int glAutoStrokeLightness READ glAutoStrokeLightness WRITE glSetAutoStrokeLightness )
Q_PROPERTY( double xEdgeLength READ xEdgeLength WRITE setXEdgeLength )
Q_PROPERTY( double yEdgeLength READ yEdgeLength WRITE setYEdgeLength )
Q_PROPERTY( double zEdgeLength READ zEdgeLength WRITE setZEdgeLength )
Q_PROPERTY( double xyWallThickness READ xyWallThickness WRITE setXYWallThickness )
Q_PROPERTY( double xzWallThickness READ xzWallThickness WRITE setXZWallThickness )
Q_PROPERTY( double yzWallThickness READ yzWallThickness WRITE setYZWallThickness )
Q_PROPERTY( int azimuth READ azimuth WRITE setAzimuth )
Q_PROPERTY( int elevation READ elevation WRITE setElevation )
Q_PROPERTY( int distance READ distance WRITE setDistance )
Q_PROPERTY( int focusDistance READ focusDistance WRITE setFocusDistance )
Q_PROPERTY( int lightAzimuth READ lightAzimuth WRITE setLightAzimuth )
Q_PROPERTY( int lightElevation READ lightElevation WRITE setLightElevation )
Q_PROPERTY( int directLight READ directLight WRITE setDirectLight )
Q_PROPERTY( int ambientLight READ ambientLight WRITE setAmbientLight )
Q_PROPERTY( bool perspective READ perspective WRITE setPerspective )
Q_PROPERTY( bool autoscale READ autoscale WRITE setAutoscale )
Q_PROPERTY( bool light READ light WRITE setLight )
public:
/**
* Constructor.
*/
QSAxes3D(QObject* parent=0, const char * name=0);
/**
* Destructor.
*/
virtual ~QSAxes3D();
/**
* Reimplemented from @ref QSPlot::stop .
*/
void stop();
/**
*
*/
void setOpenGL( bool enabled );
/**
* OpenGL
*/
bool openGL() const { return m_gl.enabled; }
/**
*
*/
void glSetTransparency( bool enabled );
/**
* Range <0,255>
*/
void glSetGlobalTransparency( int value );
/**
*
*/
void glSetShadeWalls( bool enabled );
/**
*
*/
void glSetMeshAutoStroke( bool enable );
/**
*
*/
void glSetAutoStrokeLightness( int value );
/**
*
*/
bool glTransparency() const { return m_gl.transparency; }
/**
*
*/
bool glShadeWalls() const { return m_gl.shadewalls; }
/**
*
*/
int glGlobalTransparency() const { return m_gl.globaltr; }
/**
*
*/
bool glMeshAutoStroke() const { return m_gl.autostroke; }
/**
*
*/
int glAutoStrokeLightness() const { return m_gl.autostrokel; }
/**
* Sets lenghts of the edges of the axis cube.
*/
void setEdgeLength( double xEdge, double yEdge, double zEdge );
/**
* Sets lenght of the x edge.
*/
void setXEdgeLength( double lenght );
/**
* Sets lenght of the x edge.
*/
void setYEdgeLength( double lenght );
/**
* Sets lenght of the x edge.
*/
void setZEdgeLength( double lenght );
/**
* Returns the lenght of the x edge.
*/
double xEdgeLength() const { return m_view.xEdge; }
/**
* Returns the lenght of the y edge.
*/
double yEdgeLength() const { return m_view.yEdge; }
/**
* Returns the lenght of the z edge.
*/
double zEdgeLength() const { return m_view.zEdge; }
/**
* Sets a thickness of the axis walls.
*/
void setWallThickness( double xy, double xz, double yz );
/**
* Sets a thickness of the xy wall.
*/
void setXYWallThickness( double thickness );
/**
* Sets a thickness of the xz wall.
*/
void setXZWallThickness( double thickness );
/**
* Sets a thickness of the yz wall.
*/
void setYZWallThickness( double thickness );
/**
* Returns a thickness of the xy wall.
*/
double xyWallThickness() const { return m_view.xyThick; }
/**
* Returns a thickness of the xz wall.
*/
double xzWallThickness() const { return m_view.xzThick; }
/**
* Returns a thickness of the yz wall.
*/
double yzWallThickness() const { return m_view.yzThick; }
/**
* Returns the current azimuth.
*/
int azimuth() const { return m_view.azimuth; }
/**
* Returns the current elevation.
*/
int elevation() const { return m_view.elevation; }
/**
* Returns the current distance.
*/
int distance() const { return m_view.distance; }
/**
* Returns the current focus distance.
*/
int focusDistance() const { return m_view.focus; }
/**
* Returns the current light source direction
*/
int lightAzimuth() const { return m_view.lightAzimuth; }
/**
* Returns the current light source direction.
*/
int lightElevation() const { return m_view.lightElevation; }
/**
* Returns the current intensity of the directed light source .
*/
int directLight() const { return m_view.directLight; }
/**
* Returns the current intensity of the ambient light source .
*/
int ambientLight() const { return m_view.ambientLight; }
/**
* Enables/disables the perspective projection.
*/
void setPerspective( bool enabled );
/**
* Enables/disables the autoscale. If the autoscale is turned on,
* the graph size is fitted to the widget area ( when 'distance' is zero ).
* The graph size may change, when it is turned in the 3d space, to
* fit exactly to the widget.
*/
void setAutoscale( bool enabled );
/**
* Enables/disables the light source.
*/
void setLight( bool enabled );
/**
* Returns the current light setting.
*/
bool light() const { return m_view.lighted; }
/**
* Returns the current perspective setting.
*/
bool perspective() const { return m_view.perspective; }
/**
* Returns the current autoscale setting.
*/
bool autoscale() const { return m_view.autoscale; }
/**
* Sets all fonts, fills and lines to their default values.
*/
void defaultSettings();
/**
* Returns transformation.
*/
const QSProjection3D *p3D() const { return &t; }
/**
* Reimplemented
*/
virtual void initMappings( QSDrv *drv );
/**
* From mixed type coordinates to canvas. You can't mix world, data coordinates with other types,
* ( you can mix world and data of course ). Z can't be normCoordinate.
*/
virtual QSPt3f mixedToCanvas( const QSPt3f& pos, CoordinateSystem in_coords[3], double dpi, QSAxis *xAxis, QSAxis *yAxis, QSAxis *zAxis ) const;
/**
* From canvas to mixed coordinates. You can't mix world, data coordinates with other types
* ( you can mix world and data of course ). Z can't be normCoordinate.
*/
virtual QSPt3f canvasToMixed( const QSPt3f& pos, CoordinateSystem out_coords[3], double dpi, QSAxis *xAxis, QSAxis *yAxis, QSAxis *zAxis ) const;
/**
* Reimplemented
*/
virtual void paintPlot( QPainter *p, double dpi=72.0, bool blocking=true, bool transparent=true );
/**
* Reimplemented
*/
virtual void drawPlot( QSDrv *drv, bool blocking=true, bool transparent=true );
/**
* Reimpemented
*/
virtual void paintSkeleton( QPainter *p, double dpi=72.0, bool reallyFast=false );
/**
* Just see QSGraphicalData::setFill() .
*/
enum FillElement {
BWallFill,
RWallFill,
XYWallFill,
XZWallFill,
YZWallFill
};
/**
* Just see QSGraphicalData::setLine().
*/
enum LineElement { BoxLine = 0,
TicsLine,
XYWallLine,
XZWallLine,
YZWallLine
};
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
public slots:
/**
* Sets the viewpoint position. Azimuth must be in the range < 0 deg, 359 deg >.
*/
void setAzimuth( int angle );
/**
* Sets the viewpoint position. Elevation must be in the range <-90 deg, 90 deg>
*/
void setElevation( int angle );
/**
* Sets the distance from the viewpoint to the screen.
* Value must be in the range < -50, 50 >. This means graph
* has its size in the range from 0% (-50), to 200 % (50).
* Zero ( 100% ) is default.
*/
void setDistance( int d );
/**
* Sets the distance from the screen to the focus point.
* Value must be in the range < -50, 50 >. This means
* almost the same as 'distance()' for -50 and
* almost INF for (50). Default is 0.
* @see QSPlot3D::setPerspective
*/
void setFocusDistance( int d );
/**
* Sets the direction of the light source.
* Value must be in the range <0, 359> deg.
* Light source is always directed to the center of the axis box.
* @see QSPlot3D::setLight
*/
void setLightAzimuth( int azimuth );
/**
* Sets the direction of the light source.
* Value is in the range < -90, 90 deg >.
* @see QSPlot3D::setLight
*/
void setLightElevation( int elevation );
/**
* Sets the intensity of the directed light source.
* Value must be in the range <-50, 50>
* @see QSPlot3D::setLight
*/
void setDirectLight( int lightness );
/**
* Sets the intensity of the ambient light source.
* Value has to be in the range <-50, 50>
*/
void setAmbientLight( int lightness );
protected:
virtual void axisRangesCalculated();
virtual void allocRuntimeData();
virtual void freeRuntimeData();
virtual void drawAxis( QSAxis *axis );
virtual void drawGrid( QSAxis *axis, bool major );
private:
// drawing parameters
struct view_t {
int azimuth;
int elevation;
int distance;
int focus;
int lightAzimuth;
int lightElevation;
int directLight;
int ambientLight;
bool lighted;
bool perspective;
bool autoscale;
double xEdge;
double yEdge;
double zEdge;
double xyThick;
double xzThick;
double yzThick;
} m_view;
struct gl_t {
bool enabled;
bool transparency;
bool autostroke;
bool shadewalls;
int autostrokel;
int globaltr;
} m_gl;
QSProjection3D t;
QSDrv::CNormals m_cnormals;
QSDrv::CColors m_ccolors;
QSDrv::COrdering m_corder;
class qsaxes3d_runtime_data;
qsaxes3d_runtime_data *d;
bool m_is_graphics_active;
void init_3dtr();
void draw_arrow();
void draw_box();
void draw_grid( QSAxis *axis, bool major, QSPt3f p[4], QSPt3f norm[5] );
void draw_line( QSPt3f p1, QSPt3f p2, QSPt3f *normals = NULL );
void get_side_wall( const QSPt3f& p1, const QSPt3f& p2, int side_nr, QSPt3f result_pts[4], QSPt3f result_norm[5] );
void get_axis_wall( int wall_nr, QSPt3f *p1, QSPt3f *p2, bool *visible );
void get_axis_lengths( double *xaxis_scale, double *yaxis_scale, double *zaxis_scale );
void get_cube_min_max( QSPt3f* min, QSPt3f *max );
int get_label_align( const QSPt3f& p1, const QSPt3f& p2, int axis );
bool visible( const QSPt3f& p, const QSPt3f& norm );
double opposite_side( double value );
QSPt3f thickness( int wall_nr );
bool point_on_side( const QSPt3f& p, int side );
};
/**
* \example demo3d.cpp
*
* Example of how to use QSAxes2D
*/
#endif