qwtplot3d-0.2.7+svn191/0000755000203200020320000000000010663257711014050 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/include/0000755000203200020320000000000010663257711015473 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/include/qwt3d_io.h0000644000203200020320000000721310663257610017376 0ustar gudjongudjon#ifndef __qwt3d_io_2003_07_04_23_27__ #define __qwt3d_io_2003_07_04_23_27__ #include #include #include #include #include "qwt3d_global.h" namespace Qwt3D { class Plot3D; /** IO provides a generic interface for standard and user written I/O handlers. It also provides functionality for the registering of such handlers in the framework.\n The interface mimics roughly Qt's QImageIO functions for defining image input/output functions. */ class QWT3D_EXPORT IO { public: /*! The function type that can be processed by the define... members. An extension is the IO::Functor. */ typedef bool (*Function)(Plot3D*, QString const& fname); /*! This class gives more flexibility in implementing userdefined IO handlers than the simple IO::Function type. */ class Functor { public: virtual ~Functor() {} /*! Must clone the content of *this for an object of a derived class with \c new and return the pointer. Like operator() the predefined Functors hide this function from the user, still allowing IO access (friend declaration) */ virtual Functor* clone() const = 0; /*! The workhorse of the user-defined implementation. Eventually, the framework will call this operator. */ virtual bool operator()(Plot3D* plot, QString const& fname) = 0; }; static bool defineInputHandler( QString const& format, Function func); static bool defineOutputHandler( QString const& format, Function func); static bool defineInputHandler( QString const& format, Functor const& func); static bool defineOutputHandler( QString const& format, Functor const& func); static bool save(Plot3D*, QString const& fname, QString const& format); static bool load(Plot3D*, QString const& fname, QString const& format); static QStringList inputFormatList(); static QStringList outputFormatList(); static Functor* outputHandler(QString const& format); static Functor* inputHandler(QString const& format); private: IO(){} //! Lightweight Functor encapsulating an IO::Function class Wrapper : public Functor { public: //! Performs actual input Functor* clone() const { return new Wrapper(*this); } //! Creates a Wrapper object from a function pointer explicit Wrapper(Function h) : hdl(h) {} //! Returns a pointer to the wrapped function bool operator()(Plot3D* plot, QString const& fname) { return (hdl) ? (*hdl)(plot, fname) : false; } private: Function hdl; }; struct Entry { Entry(); ~Entry(); Entry(Entry const& e); void operator=(Entry const& e); Entry(QString const& s, Functor const& f); Entry(QString const& s, Function f); QString fmt; Functor* iofunc; }; struct FormatCompare { explicit FormatCompare(Entry const& e); bool operator() (Entry const& e); Entry e_; }; struct FormatCompare2 { explicit FormatCompare2(QString s); bool operator() (Entry const& e); QString s_; }; typedef std::vector Container; typedef Container::iterator IT; static bool add_unique(Container& l, Entry const& e); static IT find(Container& l, QString const& fmt); static Container& rlist(); static Container& wlist(); static void setupHandler(); }; //! Provides Qt's Pixmap output facilities class QWT3D_EXPORT PixmapWriter : public IO::Functor { friend class IO; public: PixmapWriter() : quality_(-1) {} void setQuality(int val); private: IO::Functor* clone() const {return new PixmapWriter(*this);} bool operator()(Plot3D* plot, QString const& fname); QString fmt_; int quality_; }; } //ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_io_gl2ps.h0000644000203200020320000000516410663257610020510 0ustar gudjongudjon#ifndef qwt3d_io_gl2ps_h__2004_05_07_01_16_begin_guarded_code #define qwt3d_io_gl2ps_h__2004_05_07_01_16_begin_guarded_code #include #if QT_VERSION < 0x040000 #include #else #include #endif #include "qwt3d_types.h" #include "qwt3d_io.h" namespace Qwt3D { //! Provides EPS, PS, PDF and TeX output /*! */ class QWT3D_EXPORT VectorWriter : public IO::Functor { friend class IO; public: //! The possible output formats for the text parts of the scene enum TEXTMODE { PIXEL, //!< All text will be converted to pixmaps NATIVE, //!< Text output in the native output format TEX //!< Text output in additional LaTeX file as an overlay }; //! The possible behaviour for landscape settings enum LANDSCAPEMODE { ON, //!< Landscape mode on OFF, //!< Landscape mode off AUTO //!< The output orientation depends on the plot widgets aspect ratio (default) }; //! The possible sorting types which are translated in gl2ps types enum SORTMODE { NOSORT, //!< No sorting at all SIMPLESORT, //!< A more simple (yet quicker) algorithm (default) BSPSORT //!< BSP SORT (best and slow!) }; VectorWriter(); void setLandscape(LANDSCAPEMODE val) {landscape_ = val;} //!< Sets landscape mode. LANDSCAPEMODE landscape() const {return landscape_;} //!< Returns the current landscape mode void setTextMode(TEXTMODE val, QString fname = ""); TEXTMODE textMode() const {return textmode_;} //!< Return current text output mode. //! Sets one of the SORTMODE sorting modes. void setSortMode(SORTMODE val) {sortmode_ = val;} SORTMODE sortMode() const {return sortmode_;} //!< Returns gl2ps sorting type. //! Turns compressed output on or off (no effect if zlib support is not available) void setCompressed(bool val); //! Returns compression mode (always false if zlib support has not been set) bool compressed() const {return compressed_;} bool setFormat(QString const& format); private: IO::Functor* clone() const; bool operator()(Plot3D* plot, QString const& fname); GLint gl2ps_format_; bool formaterror_; bool compressed_; SORTMODE sortmode_; LANDSCAPEMODE landscape_; TEXTMODE textmode_; QString texfname_; }; GLint setDeviceLineWidth(GLfloat val); GLint setDevicePointSize(GLfloat val); GLint drawDevicePixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); GLint drawDeviceText(const char* str, const char* fontname, int fontsize, Qwt3D::Triple pos, Qwt3D::RGBA rgba, Qwt3D::ANCHOR align, double gap); void setDevicePolygonOffset(GLfloat factor, GLfloat units); } // ns #endif /* include guarded */ qwtplot3d-0.2.7+svn191/include/qwt3d_color.h0000644000203200020320000000411510663257610020103 0ustar gudjongudjon#ifndef __COLORGENERATOR_H__ #define __COLORGENERATOR_H__ #include #include "qwt3d_global.h" #include "qwt3d_types.h" namespace Qwt3D { //! Abstract base class for color functors /*! Use your own color model by providing an implementation of operator()(double x, double y, double z). Colors destructor has been declared \c protected, in order to use only heap based objects. Plot3D will handle the objects destruction. See StandardColor for an example */ class QWT3D_EXPORT Color { public: virtual Qwt3D::RGBA operator()(double x, double y, double z) const = 0; //!< Implement your color model here virtual Qwt3D::RGBA operator()(Qwt3D::Triple const& t) const {return this->operator()(t.x,t.y,t.z);} //! Should create a color vector usable by ColorLegend. The default implementation returns his argument virtual Qwt3D::ColorVector& createVector(Qwt3D::ColorVector& vec) { return vec; } void destroy() const { delete this;} protected: virtual ~Color(){} //!< Allow heap based objects only }; class Plot3D; //! Standard color model for Plot3D - implements the data driven operator()(double x, double y, double z) /*! The class has a ColorVector representing z values, which will be used by operator()(double x, double y, double z) */ class QWT3D_EXPORT StandardColor : public Color { public: //! Initializes with data and set up a ColorVector with a size of 100 z values (default); explicit StandardColor(Qwt3D::Plot3D* data, unsigned size = 100); Qwt3D::RGBA operator()(double x, double y, double z) const; //!< Receives z-dependend color from ColorVector void setColorVector(Qwt3D::ColorVector const& cv); void reset(unsigned size=100); //!< Resets the standard colors; void setAlpha(double a); //!< Sets unitary alpha value for all colors /** \brief Creates color vector Creates a color vector used by ColorLegend. This is essentially a copy from the internal used vector. \return The vector created */ Qwt3D::ColorVector& createVector(Qwt3D::ColorVector& vec) {vec = colors_; return vec;} protected: Qwt3D::ColorVector colors_; Qwt3D::Plot3D* data_; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_plot.h0000644000203200020320000003175110663257610017751 0ustar gudjongudjon#ifndef __plot3d_2003_06_09_12_14__ #define __plot3d_2003_06_09_12_14__ #include "qwt3d_coordsys.h" #include "qwt3d_enrichment_std.h" namespace Qwt3D { //! Base class for all plotting widgets /*! Plot3D handles all the common features for plotting widgets - coordinate system, transformations, mouse/keyboard handling, labeling etc.. It contains some pure virtual functions and is, in so far, an abstract base class. The class provides interfaces for data handling and implements basic data controlled color allocation. */ class QWT3D_EXPORT Plot3D : public QGLWidget { Q_OBJECT public: #if QT_VERSION < 0x040000 Plot3D( QWidget* parent = 0, const char* name = 0 ); #else Plot3D ( QWidget * parent = 0, const QGLWidget * shareWidget = 0 ); #endif virtual ~Plot3D(); QPixmap renderPixmap (int w=0, int h=0, bool useContext=false); void updateData(); //!< Recalculate data void createCoordinateSystem(Qwt3D::Triple beg, Qwt3D::Triple end); Qwt3D::CoordinateSystem* coordinates() { return &coordinates_p; } //!< Returns pointer to CoordinateSystem object Qwt3D::ColorLegend* legend() { return &legend_;} //!< Returns pointer to ColorLegend object double xRotation() const { return xRot_;} //!< Returns rotation around X axis [-360..360] (some angles are equivalent) double yRotation() const { return yRot_;} //!< Returns rotation around Y axis [-360..360] (some angles are equivalent) double zRotation() const { return zRot_;} //!< Returns rotation around Z axis [-360..360] (some angles are equivalent) double xShift() const { return xShift_;} //!< Returns shift along X axis (object coordinates) double yShift() const { return yShift_;} //!< Returns shift along Y axis (object coordinates) double zShift() const { return zShift_;} //!< Returns shift along Z axis (object coordinates) double xViewportShift() const { return xVPShift_;} //!< Returns relative shift [-1..1] along X axis (view coordinates) double yViewportShift() const { return yVPShift_;} //!< Returns relative shift [-1..1] along Y axis (view coordinates) double xScale() const { return xScale_;} //!< Returns scaling for X values [0..inf] double yScale() const { return yScale_;} //!< Returns scaling for Y values [0..inf] double zScale() const { return zScale_;} //!< Returns scaling for Z values [0..inf] double zoom() const { return zoom_;} //!< Returns zoom (0..inf) bool ortho() const { return ortho_; } //!< Returns orthogonal (true) or perspective (false) projection void setPlotStyle( Qwt3D::PLOTSTYLE val); Qwt3D::Enrichment* setPlotStyle( Qwt3D::Enrichment const& val); Qwt3D::PLOTSTYLE plotStyle() const { return plotstyle_; }//!< Returns plotting style //! Returns current Enrichment object used for plotting styles (if set, zero else) Qwt3D::Enrichment* userStyle() const { return userplotstyle_p; } void setShading( Qwt3D::SHADINGSTYLE val ); Qwt3D::SHADINGSTYLE shading() const { return shading_; }//!< Returns shading style void setIsolines(int isolines); int isolines() const { return isolines_;} //!< Returns number of isolines void setSmoothMesh(bool val) {smoothdatamesh_p = val;} //!< Enables/disables smooth data mesh lines. Default is false bool smoothDataMesh() const {return smoothdatamesh_p;} //!< True if mesh antialiasing is on void setBackgroundColor(Qwt3D::RGBA rgba); //!< Sets widgets background color Qwt3D::RGBA backgroundRGBAColor() const {return bgcolor_;} //!< Returns the widgets background color void setMeshColor(Qwt3D::RGBA rgba); //!< Sets color for data mesh Qwt3D::RGBA meshColor() const {return meshcolor_;} //!< Returns color for data mesh void setMeshLineWidth(double lw); //!< Sets line width for data mesh double meshLineWidth() const {return meshLineWidth_;} //!< Returns line width for data mesh void setDataColor(Color* col); //!< Sets new data color object const Color* dataColor() const {return datacolor_p;} //!< Returns data color object virtual Qwt3D::Enrichment* addEnrichment(Qwt3D::Enrichment const&); //!< Add an Enrichment virtual bool degrade(Qwt3D::Enrichment*); //!< Remove an Enrichment Qwt3D::ParallelEpiped hull() const { return hull_;} //!< Returns rectangular hull void showColorLegend(bool); void setCoordinateStyle(Qwt3D::COORDSTYLE st); //!< Sets style of coordinate system. void setPolygonOffset(double d); double polygonOffset() const {return polygonOffset_;} //!< Returns relative value for polygon offset [0..1] void setTitlePosition(double rely, double relx = 0.5, Qwt3D::ANCHOR = Qwt3D::TopCenter); void setTitleFont(const QString& family, int pointSize, int weight = QFont::Normal, bool italic = false); void setTitleColor(Qwt3D::RGBA col) {title_.setColor(col);} //!< Set caption color void setTitle(const QString& title) {title_.setString(title);} //!< Set caption text (one row only) void assignMouse(MouseState xrot, MouseState yrot, MouseState zrot, MouseState xscale, MouseState yscale, MouseState zscale, MouseState zoom, MouseState xshift, MouseState yshift); bool mouseEnabled() const; //!< Returns true, if the widget accept mouse input from the user void assignKeyboard( KeyboardState xrot_n, KeyboardState xrot_p ,KeyboardState yrot_n, KeyboardState yrot_p ,KeyboardState zrot_n, KeyboardState zrot_p ,KeyboardState xscale_n, KeyboardState xscale_p ,KeyboardState yscale_n, KeyboardState yscale_p ,KeyboardState zscale_n, KeyboardState zscale_p ,KeyboardState zoom_n, KeyboardState zoom_p ,KeyboardState xshift_n, KeyboardState xshift_p ,KeyboardState yshift_n, KeyboardState yshift_p ); bool keyboardEnabled() const; //!< Returns true, if the widget accept keyboard input from the user //! Sets speed for keyboard driven transformations void setKeySpeed(double rot, double scale, double shift); //! Gets speed for keyboard driven transformations void keySpeed(double& rot, double& scale, double& shift) const; bool lightingEnabled() const; //!< Returns true, if Lighting is enabled, false else //! Turn light on void illuminate(unsigned light = 0); //! Turn light off void blowout(unsigned light = 0); void setMaterialComponent(GLenum property, double r, double g, double b, double a = 1.0); void setMaterialComponent(GLenum property, double intensity); void setShininess(double exponent); void setLightComponent(GLenum property, double r, double g, double b, double a = 1.0, unsigned light=0); void setLightComponent(GLenum property, double intensity, unsigned light=0); //! Returns Light 'idx' rotation around X axis [-360..360] (some angles are equivalent) double xLightRotation(unsigned idx = 0) const { return (idx<8) ? lights_[idx].rot.x : 0;} //! Returns Light 'idx' rotation around Y axis [-360..360] (some angles are equivalent) double yLightRotation(unsigned idx = 0) const { return (idx<8) ? lights_[idx].rot.y : 0;} //! Returns Light 'idx' rotation around Z axis [-360..360] (some angles are equivalent) double zLightRotation(unsigned idx = 0) const { return (idx<8) ? lights_[idx].rot.z : 0;} //! Returns shift of Light 'idx 'along X axis (object coordinates) double xLightShift(unsigned idx = 0) const {return (idx<8) ? lights_[idx].shift.x : 0;} //! Returns shift of Light 'idx 'along Y axis (object coordinates) double yLightShift(unsigned idx = 0) const {return (idx<8) ? lights_[idx].shift.y : 0;} //! Returns shift of Light 'idx 'along Z axis (object coordinates) double zLightShift(unsigned idx = 0) const {return (idx<8) ? lights_[idx].shift.z : 0;} //! Returns true if valid data available, false else bool hasData() const { return (actualData_p) ? !actualData_p->empty() : false;} signals: //! Emitted, if the rotation is changed void rotationChanged( double xAngle, double yAngle, double zAngle ); //! Emitted, if the shift is changed void shiftChanged( double xShift, double yShift, double zShift ); //! Emitted, if the viewport shift is changed void vieportShiftChanged( double xShift, double yShift ); //! Emitted, if the scaling is changed void scaleChanged( double xScale, double yScale, double zScale ); //! Emitted, if the zoom is changed void zoomChanged(double); //! Emitted, if the projection mode is changed void projectionChanged(bool); public slots: void setRotation( double xVal, double yVal, double zVal ); void setShift( double xVal, double yVal, double zVal ); void setViewportShift( double xVal, double yVal ); void setScale( double xVal, double yVal, double zVal ); void setZoom( double ); void setOrtho(bool); void enableMouse(bool val=true); //!< Enable mouse input void disableMouse(bool val =true); //!< Disable mouse input void enableKeyboard(bool val=true); //!< Enable keyboard input void disableKeyboard(bool val =true); //!< Disable keyboard input void enableLighting(bool val = true); //!< Turn Lighting on or off void disableLighting(bool val = true); //!< Turn Lighting on or off void setLightRotation( double xVal, double yVal, double zVal, unsigned int idx = 0 ); void setLightShift( double xVal, double yVal, double zVal, unsigned int idx = 0 ); virtual bool savePixmap(QString const& fileName, QString const& format); //!< Saves content to pixmap format //! Saves content to vector format virtual bool saveVector(QString const& fileName, QString const& format, VectorWriter::TEXTMODE text, VectorWriter::SORTMODE sortmode); virtual bool save(QString const& fileName, QString const& format); //!< Saves content protected: typedef std::list EnrichmentList; typedef EnrichmentList::iterator ELIT; void initializeGL(); void paintGL(); void resizeGL( int w, int h ); void mousePressEvent( QMouseEvent *e ); void mouseReleaseEvent( QMouseEvent *e ); void mouseMoveEvent( QMouseEvent *e ); void wheelEvent( QWheelEvent *e ); void keyPressEvent( QKeyEvent *e ); Qwt3D::CoordinateSystem coordinates_p; Qwt3D::Color* datacolor_p; Qwt3D::Enrichment* userplotstyle_p; EnrichmentList elist_p; virtual void calculateHull() = 0; virtual void createData() = 0; virtual void createEnrichment(Qwt3D::Enrichment&){} virtual void createEnrichments(); void createCoordinateSystem(); void setHull(Qwt3D::ParallelEpiped p) {hull_ = p;} bool initializedGL() const {return initializedGL_;} enum OBJECTS { DataObject, LegendObject, NormalObject, DisplayListSize // only to have a vector length ... }; std::vector displaylists_p; Qwt3D::Data* actualData_p; private: struct Light { Light() : unlit(true){} bool unlit; Qwt3D::Triple rot; Qwt3D::Triple shift; }; std::vector lights_; GLdouble xRot_, yRot_, zRot_, xShift_, yShift_, zShift_, zoom_ , xScale_, yScale_, zScale_, xVPShift_, yVPShift_; Qwt3D::RGBA meshcolor_; double meshLineWidth_; Qwt3D::RGBA bgcolor_; Qwt3D::PLOTSTYLE plotstyle_; Qwt3D::SHADINGSTYLE shading_; Qwt3D::FLOORSTYLE floorstyle_; bool ortho_; double polygonOffset_; int isolines_; bool displaylegend_; bool smoothdatamesh_p; Qwt3D::ParallelEpiped hull_; Qwt3D::ColorLegend legend_; Label title_; Qwt3D::Tuple titlerel_; Qwt3D::ANCHOR titleanchor_; // mouse QPoint lastMouseMovePosition_; bool mpressed_; MouseState xrot_mstate_, yrot_mstate_, zrot_mstate_, xscale_mstate_, yscale_mstate_, zscale_mstate_, zoom_mstate_, xshift_mstate_, yshift_mstate_; bool mouse_input_enabled_; void setRotationMouse(MouseState bstate, double accel, QPoint diff); void setScaleMouse(MouseState bstate, double accel, QPoint diff); void setShiftMouse(MouseState bstate, double accel, QPoint diff); // keyboard bool kpressed_; KeyboardState xrot_kstate_[2], yrot_kstate_[2], zrot_kstate_[2], xscale_kstate_[2], yscale_kstate_[2], zscale_kstate_[2], zoom_kstate_[2], xshift_kstate_[2], yshift_kstate_[2]; bool kbd_input_enabled_; double kbd_rot_speed_, kbd_scale_speed_, kbd_shift_speed_; void setRotationKeyboard(KeyboardState kseq, double speed); void setScaleKeyboard(KeyboardState kseq, double speed); void setShiftKeyboard(KeyboardState kseq, double speed); bool lighting_enabled_; void applyLight(unsigned idx); void applyLights(); bool initializedGL_; bool renderpixmaprequest_; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_helper.h0000644000203200020320000000074110663257610020245 0ustar gudjongudjon#ifndef __HELPER_H__ #define __HELPER_H__ #include #include #include #include namespace { inline double Min_(double a, double b) { return (a0) ? int(d+0.5) : int(d-0.5); } } //ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_label.h0000644000203200020320000000434510663257610020051 0ustar gudjongudjon#ifndef __LABELPIXMAP_H__ #define __LABELPIXMAP_H__ #include #include #include #include #include #include "qwt3d_drawable.h" namespace Qwt3D { //! A Qt string or an output device dependent string class QWT3D_EXPORT Label : public Drawable { public: Label(); //! Construct label and initialize with font Label(const QString & family, int pointSize, int weight = QFont::Normal, bool italic = false); //! Sets the labels font void setFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); void adjust(int gap); //!< Fine tunes label; double gap() const {return gap_;} //!< Returns the gap caused by adjust(); void setPosition(Qwt3D::Triple pos, ANCHOR a = BottomLeft); //!< Sets the labels position void setRelPosition(Tuple rpos, ANCHOR a); //!< Sets the labels position relative to screen Qwt3D::Triple first() const { return beg_;} //!< Receives bottom left label position Qwt3D::Triple second() const { return end_;} //!< Receives top right label position ANCHOR anchor() const { return anchor_; } //!< Defines an anchor point for the labels surrounding rectangle virtual void setColor(double r, double g, double b, double a = 1); virtual void setColor(Qwt3D::RGBA rgba); /*! \brief Sets the labels string For unicode labeling ( QChar(0x3c0) etc.) please look at www.unicode.org. */ void setString(QString const& s); void draw(); //!< Actual drawing /** \brief Decides about use of PDF standard fonts for PDF output If true, Label can use one of the PDF standard fonts (unprecise positioning for now), otherwise it dumps pixmaps in the PDF stream (poor quality) */ static void useDeviceFonts(bool val); private: Qwt3D::Triple beg_, end_, pos_; QPixmap pm_; QImage buf_, tex_; QFont font_; QString text_; ANCHOR anchor_; void init(); void init(const QString & family, int pointSize, int weight = QFont::Normal, bool italic = false); void update(); //!< Enforces an update of the internal pixmap void convert2screen(); double width() const; double height() const; int gap_; bool flagforupdate_; static bool devicefonts_; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_drawable.h0000644000203200020320000000217610663257610020553 0ustar gudjongudjon#ifndef __DRAWABLE_H__ #define __DRAWABLE_H__ #include #include "qwt3d_global.h" #include "qwt3d_types.h" #include "qwt3d_io_gl2ps.h" namespace Qwt3D { //! ABC for Drawables class QWT3D_EXPORT Drawable { public: virtual ~Drawable() = 0; virtual void draw(); virtual void saveGLState(); virtual void restoreGLState(); void attach(Drawable*); void detach(Drawable*); void detachAll(); virtual void setColor(double r, double g, double b, double a = 1); virtual void setColor(Qwt3D::RGBA rgba); Qwt3D::Triple relativePosition(Qwt3D::Triple rel); protected: Qwt3D::RGBA color; void Enable(GLenum what, GLboolean val); Qwt3D::Triple ViewPort2World(Qwt3D::Triple win, bool* err = 0); Qwt3D::Triple World2ViewPort(Qwt3D::Triple obj, bool* err = 0); GLdouble modelMatrix[16]; GLdouble projMatrix[16]; GLint viewport[4]; private: GLboolean ls; GLboolean pols; GLint polmode[2]; GLfloat lw; GLint blsrc, bldst; GLdouble col[4]; GLint pattern, factor; GLboolean sallowed; GLboolean tex2d; GLint matrixmode; GLfloat poloffs[2]; GLboolean poloffsfill; std::list dlist; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_openglhelper.h0000644000203200020320000000512410663257610021452 0ustar gudjongudjon#ifndef __openglhelper_2003_06_06_15_49__ #define __openglhelper_2003_06_06_15_49__ #include "qglobal.h" #if QT_VERSION < 0x040000 #include #else #include #endif namespace Qwt3D { #ifndef QWT3D_NOT_FOR_DOXYGEN class GLStateBewarer { public: GLStateBewarer(GLenum what, bool on, bool persist=false) { state_ = what; stateval_ = glIsEnabled(what); if (on) turnOn(persist); else turnOff(persist); } ~GLStateBewarer() { if (stateval_) glEnable(state_); else glDisable(state_); } void turnOn(bool persist = false) { glEnable(state_); if (persist) stateval_ = true; } void turnOff(bool persist = false) { glDisable(state_); if (persist) stateval_ = false; } private: GLenum state_; bool stateval_; }; inline const GLubyte* gl_error() { GLenum errcode; const GLubyte* err = 0; if ((errcode = glGetError()) != GL_NO_ERROR) { err = gluErrorString(errcode); } return err; } inline void SaveGlDeleteLists(GLuint& lstidx, GLsizei range) { if (glIsList(lstidx)) glDeleteLists(lstidx, range); lstidx = 0; } //! get OpenGL transformation matrices /** Don't rely on (use) this in display lists ! \param modelMatrix should be a GLdouble[16] \param projMatrix should be a GLdouble[16] \param viewport should be a GLint[4] */ inline void getMatrices(GLdouble* modelMatrix, GLdouble* projMatrix, GLint* viewport) { glGetIntegerv(GL_VIEWPORT, viewport); glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); } //! simplified glut routine (glUnProject): windows coordinates_p --> object coordinates_p /** Don't rely on (use) this in display lists ! */ inline bool ViewPort2World(double& objx, double& objy, double& objz, double winx, double winy, double winz) { GLdouble modelMatrix[16]; GLdouble projMatrix[16]; GLint viewport[4]; getMatrices(modelMatrix, projMatrix, viewport); int res = gluUnProject(winx, winy, winz, modelMatrix, projMatrix, viewport, &objx, &objy, &objz); return (res == GL_FALSE) ? false : true; } //! simplified glut routine (glProject): object coordinates_p --> windows coordinates_p /** Don't rely on (use) this in display lists ! */ inline bool World2ViewPort(double& winx, double& winy, double& winz, double objx, double objy, double objz ) { GLdouble modelMatrix[16]; GLdouble projMatrix[16]; GLint viewport[4]; getMatrices(modelMatrix, projMatrix, viewport); int res = gluProject(objx, objy, objz, modelMatrix, projMatrix, viewport, &winx, &winy, &winz); return (res == GL_FALSE) ? false : true; } #endif // QWT3D_NOT_FOR_DOXYGEN } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_function.h0000644000203200020320000000313610663257610020614 0ustar gudjongudjon#ifndef qwt3d_function_h__2004_03_05_13_51_begin_guarded_code #define qwt3d_function_h__2004_03_05_13_51_begin_guarded_code #include "qwt3d_gridmapping.h" namespace Qwt3D { class SurfacePlot; //! Abstract base class for mathematical functions /** A Function encapsulates a mathematical function with rectangular domain. The user has to adapt the pure virtual operator() to get a working object. Also, the client code should call setDomain, setMesh and create for reasonable operating conditions. */ class QWT3D_EXPORT Function : public GridMapping { public: Function(); //!< Constructs Function object w/o assigned SurfacePlot. explicit Function(Qwt3D::SurfacePlot& plotWidget); //!< Constructs Function object and assigns a SurfacePlot explicit Function(Qwt3D::SurfacePlot* plotWidget); //!< Constructs Function object and assigns a SurfacePlot virtual double operator()(double x, double y) = 0; //!< Overwrite this. void setMinZ(double val); //!< Sets minimal z value. void setMaxZ(double val); //!< Sets maximal z value. //! Assigns a new SurfacePlot and creates a data representation for it. virtual bool create(Qwt3D::SurfacePlot& plotWidget); //! Creates data representation for the actual assigned SurfacePlot. virtual bool create(); //! Assigns the object to another widget. To see the changes, you have to call this function before create(). void assign(Qwt3D::SurfacePlot& plotWidget); //! Assigns the object to another widget. To see the changes, you have to call this function before create(). void assign(Qwt3D::SurfacePlot* plotWidget); }; } // ns #endif /* include guarded */ qwtplot3d-0.2.7+svn191/include/qwt3d_scale.h0000644000203200020320000000541110663257610020054 0ustar gudjongudjon#ifndef qwt3d_scale_h__2004_06_02_22_02_begin_guarded_code #define qwt3d_scale_h__2004_06_02_22_02_begin_guarded_code #include #include "qwt3d_types.h" #include "qwt3d_autoscaler.h" #include "qwt3d_autoptr.h" namespace Qwt3D { /*! The class encapsulates non-visual scales. She is utilized by Axis and also collaborates closely with AutoScaler. A Scale allows control over all aspects of tic generation including arbitrary transformations of tic values into corresponding strings. The strings contain what eventually will be shown as tic labels.\n Standard linear and logarithmic scales have been integrated yet into the Axis interface. User-defined axes can be derived from Scale, LinearScale et al. */ class QWT3D_EXPORT Scale { friend class Axis; friend class qwt3d_ptr; protected: Scale(); virtual ~Scale(){} virtual QString ticLabel(unsigned int idx) const; virtual void setLimits(double start, double stop); virtual void setMajors(int val) {majorintervals_p=val;} //!< Sets number of major intervals virtual void setMinors(int val) {minorintervals_p=val;} //!< Sets number of minor intervals per major interval virtual void setMajorLimits(double start, double stop); int majors() const {return majorintervals_p;} //!< Returns major intervals int minors() const {return minorintervals_p;} //!< Returns minor intervals //! Derived classes should return a new heap based object here. virtual Scale* clone() const = 0; //! This function should setup the 2 vectors for major and minor positions; virtual void calculate() = 0; virtual int autoscale(double& a, double& b, double start, double stop, int ivals); std::vector majors_p, minors_p; double start_p, stop_p; int majorintervals_p, minorintervals_p; double mstart_p, mstop_p; private: void destroy() const {delete this;} //!< Used by qwt3d_ptr }; //! The standard (1:1) mapping class for axis numbering class QWT3D_EXPORT LinearScale : public Scale { friend class Axis; friend class qwt3d_ptr; protected: int autoscale(double& a, double& b, double start, double stop, int ivals); //! Returns a new heap based object utilized from qwt3d_ptr Scale* clone() const {return new LinearScale(*this);} void calculate(); LinearAutoScaler autoscaler_p; }; //! log10 scale class QWT3D_EXPORT LogScale : public Scale { friend class Axis; friend class qwt3d_ptr; protected: QString ticLabel(unsigned int idx) const; void setMinors(int val); //! Standard ctor LogScale(); //! Returns a new heap based object utilized from qwt3d_ptr Scale* clone() const {return new LogScale;} void calculate(); private: void setupCounter(double& k, int& step); }; } // namespace Qwt3D #endif /* include guarded */ qwtplot3d-0.2.7+svn191/include/qwt3d_surfaceplot.h0000644000203200020320000000767610663257610021333 0ustar gudjongudjon#ifndef qwt3d_SurfacePlot_h__2004_03_05_11_36_begin_guarded_code #define qwt3d_SurfacePlot_h__2004_03_05_11_36_begin_guarded_code #include "qwt3d_plot.h" namespace Qwt3D { //! A class representing Surfaces /** A SurfacePlot ... */ class QWT3D_EXPORT SurfacePlot : public Plot3D { Q_OBJECT public: #if QT_VERSION < 0x040000 SurfacePlot( QWidget* parent = 0, const char* name = 0 ); #else SurfacePlot( QWidget * parent = 0, const QGLWidget * shareWidget = 0 ); #endif ~SurfacePlot(); void updateNormals(); //!< Recalculates surface normals; int resolution() const {return resolution_p;} //!< Returns data resolution (1 means all data) std::pair facets() const; //!< Returns the number of mesh cells for the ORIGINAL data bool loadFromData(Qwt3D::Triple** data, unsigned int columns, unsigned int rows , bool uperiodic = false, bool vperiodic = false); bool loadFromData(double** data, unsigned int columns, unsigned int rows ,double minx, double maxx, double miny, double maxy); bool loadFromData(Qwt3D::TripleField const& data, Qwt3D::CellField const& poly); //! Equivalent to loadFromData(); /** \deprecated Use loadFromData instead */ bool createDataRepresentation(Qwt3D::Triple** data, unsigned int columns, unsigned int rows , bool uperiodic = false, bool vperiodic = false) { return loadFromData(data, columns, rows, uperiodic, vperiodic); } //! Equivalent to loadFromData(); /** \deprecated Use loadFromData instead */ bool createDataRepresentation(double** data, unsigned int columns, unsigned int rows ,double minx, double maxx, double miny, double maxy) { return loadFromData(data, columns, rows, minx, maxx, miny, maxy); } //! Equivalent to loadFromData(); /** \deprecated Use loadFromData instead */ bool createDataRepresentation(Qwt3D::TripleField const& data, Qwt3D::CellField const& poly) { return loadFromData(data, poly); } Qwt3D::FLOORSTYLE floorStyle() const { return floorstyle_;} //!< Return floor style void setFloorStyle( Qwt3D::FLOORSTYLE val ) {floorstyle_ = val;} //!< Sets floor style void showNormals(bool); //!< Draw normals to every vertex bool normals() const { return datanormals_p;} //!< Returns \c true, if normal drawing is on void setNormalLength(double val); //!< Sets length of normals in percent per hull diagonale double normalLength() const { return normalLength_p; }//!< Returns relative length of normals void setNormalQuality(int val); //!< Increases plotting quality of normal arrows int normalQuality() const { return normalQuality_p; }//!< Returns plotting quality of normal arrows signals: void resolutionChanged(int); public slots: void setResolution( int ); protected: bool datanormals_p; double normalLength_p; int normalQuality_p; virtual void calculateHull(); virtual void createData(); virtual void createEnrichment(Qwt3D::Enrichment& p); virtual void createFloorData(); void createNormals(); void createPoints(); int resolution_p; void readIn(Qwt3D::GridData& gdata, Triple** data, unsigned int columns, unsigned int rows); void readIn(Qwt3D::GridData& gdata, double** data, unsigned int columns, unsigned int rows, double minx, double maxx, double miny, double maxy); void calcNormals(GridData& gdata); void sewPeriodic(GridData& gdata); //void calcLowResolution(); private: void Data2Floor(); void Isolines2Floor(); Qwt3D::FLOORSTYLE floorstyle_; // grid plot Qwt3D::GridData* actualDataG_; virtual void createDataG(); virtual void createFloorDataG(); void createNormalsG(); void Data2FloorG(); void Isolines2FloorG(); void setColorFromVertexG(int ix, int iy, bool skip = false); // mesh plot Qwt3D::CellData* actualDataC_; virtual void createDataC(); virtual void createFloorDataC(); void createNormalsC(); void Data2FloorC(); void Isolines2FloorC(); void setColorFromVertexC(int node, bool skip = false); }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_io_reader.h0000644000203200020320000000150710663257610020720 0ustar gudjongudjon#ifndef qwt3d_reader_h__2004_03_07_14_03_begin_guarded_code #define qwt3d_reader_h__2004_03_07_14_03_begin_guarded_code #include "qwt3d_io.h" namespace Qwt3D { /*! Functor for reading of native files containing grid data. As a standart input functor associated with "mes" and "MES" file extensions. */ class QWT3D_EXPORT NativeReader : public IO::Functor { friend class IO; public: NativeReader(); private: //! Provides new NativeReader object. IO::Functor* clone() const{return new NativeReader(*this);} //! Performs actual input bool operator()(Plot3D* plot, QString const& fname); static const char* magicstring; double minz_, maxz_; bool collectInfo(FILE*& file, QString const& fname, unsigned& xmesh, unsigned& ymesh, double& minx, double& maxx, double& miny, double& maxy); }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_multiplot.h0000644000203200020320000000056710663257610021025 0ustar gudjongudjon#ifndef qwt3d_multiplot_h__2004_03_06_02_05_begin_guarded_code #define qwt3d_multiplot_h__2004_03_06_02_05_begin_guarded_code #include "qwt3d_plot.h" namespace Qwt3D { //! TODO class QWT3D_EXPORT MultiPlot : public Plot3D { // Q_OBJECT public: MultiPlot( QWidget* parent = 0, const char* name = 0 ){} protected: virtual void createData() = 0; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_mapping.h0000644000203200020320000000072610663257610020424 0ustar gudjongudjon#ifndef qwt3d_mapping_h__2004_03_05_13_51_begin_guarded_code #define qwt3d_mapping_h__2004_03_05_13_51_begin_guarded_code #include #include "qwt3d_global.h" #include "qwt3d_types.h" namespace Qwt3D { //! Abstract base class for general mappings /** */ class QWT3D_EXPORT Mapping { public: virtual ~Mapping(){} //!< Destructor. virtual QString name() const { return QString(""); } //!< Descriptive String. }; } // ns #endif /* include guarded */ qwtplot3d-0.2.7+svn191/include/qwt3d_enrichment.h0000644000203200020320000000403510663257610021122 0ustar gudjongudjon#ifndef qwt3d_enrichment_h__2004_02_23_19_24_begin_guarded_code #define qwt3d_enrichment_h__2004_02_23_19_24_begin_guarded_code #include "qwt3d_global.h" #include "qwt3d_types.h" namespace Qwt3D { class Plot3D; //! Abstract base class for data dependent visible user objects /** Enrichments provide a framework for user defined OPenGL objects. The base class has a pure virtuell function clone(). 2 additional functions are per default empty and could also get a new implementation in derived classes. They can be used for initialization issues or actions not depending on the related primitive. */ class QWT3D_EXPORT Enrichment { public: enum TYPE{ VERTEXENRICHMENT, EDGEENRICHMENT, FACEENRICHMENT, VOXELENRICHMENT }; //!< Type of the Enrichment - only VERTEXENRICHMENT's are defined at this moment. Enrichment() : plot(0) {} virtual ~Enrichment(){} virtual Enrichment* clone() const = 0; //!< The derived class should give back a new Derived(something) here virtual void drawBegin(){}; //!< Empty per default. Can be overwritten. virtual void drawEnd(){}; //!< Empty per default. Can be overwritten. virtual void assign(Plot3D const& pl) {plot = &pl;} //!< Assign to existent plot; virtual TYPE type() const = 0; //!< Overwrite protected: const Plot3D* plot; }; //! Abstract base class for vertex dependent visible user objects /** VertexEnrichments introduce a specialized draw routine for vertex dependent data. draw() is called, when the Plot realizes its internal OpenGL data representation for every Vertex associated to his argument. */ class QWT3D_EXPORT VertexEnrichment : public Enrichment { public: VertexEnrichment() : Qwt3D::Enrichment() {} virtual Enrichment* clone() const = 0; //!< The derived class should give back a new Derived(something) here virtual void draw(Qwt3D::Triple const&) = 0; //!< Overwrite this virtual TYPE type() const {return Qwt3D::Enrichment::VERTEXENRICHMENT;} //!< This gives VERTEXENRICHMENT }; // todo EdgeEnrichment, FaceEnrichment, VoxelEnrichment etc. } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_colorlegend.h0000644000203200020320000000450510663257610021265 0ustar gudjongudjon#ifndef __PLANE_H__ #define __PLANE_H__ #include "qwt3d_global.h" #include "qwt3d_drawable.h" #include "qwt3d_axis.h" #include "qwt3d_color.h" namespace Qwt3D { //! A flat color legend /** The class visualizes a ColorVector together with a scale (axis) and a caption. ColorLegends are vertical or horizontal */ class QWT3D_EXPORT ColorLegend : public Drawable { public: //! Possible anchor points for caption and axis enum SCALEPOSITION { Top, //!< scale on top Bottom, //!< scale on bottom Left, //!< scale left Right //!< scale right }; //! Orientation of the legend enum ORIENTATION { BottomTop, //!< Positionate the legend vertically, the lowest color index is on the bottom LeftRight //!< Positionate the legend horizontally, the lowest color index is on left side }; ColorLegend(); //!< Standard constructor void draw(); //!< Draws the object. You should not use this explicitely - the function is called by updateGL(). void setRelPosition(Qwt3D::Tuple relMin, Qwt3D::Tuple relMax); //!< Sets the relative position of the legend inside widget void setOrientation(ORIENTATION, SCALEPOSITION); //!< Sets legend orientation and scale position void setLimits(double start, double stop); //!< Sets the limit of the scale. void setMajors(int); //!< Sets scale major tics. void setMinors(int); //!< Sets scale minor tics. void drawScale(bool val) { showaxis_ = val; } //!< Sets whether a scale will be drawn. void drawNumbers(bool val) { axis_.setNumbers(val); } //!< Sets whether the scale will have scale numbers. void setAutoScale(bool val); //!< Sets, whether the axis is autoscaled or not. void setScale(Qwt3D::Scale *scale); //!< Sets another scale void setScale(Qwt3D::SCALETYPE); //!< Sets one of the predefined scale types void setTitleString(QString const& s); //!< Sets the legends caption string. //! Sets the legends caption font. void setTitleFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); Qwt3D::ColorVector colors; //!< The color vector private: Qwt3D::Label caption_; Qwt3D::ParallelEpiped geometry() const { return pe_;} void setGeometryInternal(); Qwt3D::ParallelEpiped pe_; Qwt3D::Tuple relMin_, relMax_; Qwt3D::Axis axis_; SCALEPOSITION axisposition_; ORIENTATION orientation_; bool showaxis_; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_autoptr.h0000644000203200020320000000263210663257610020465 0ustar gudjongudjon#ifndef qwt3d_autoptr_h__2004_05_14_18_57_begin_guarded_code #define qwt3d_autoptr_h__2004_05_14_18_57_begin_guarded_code namespace Qwt3D { //! Simple Auto pointer providing deep copies for raw pointer /*! Requirements: \n virtual T* T::clone() const;\n T::destroy() const; virtual ~T() private/protected\n\n clone() is necessary for the pointer to preserve polymorphic behaviour. The pointer requires also heap based objects with regard to the template argument in order to be able to get ownership and control over destruction. */ template class qwt3d_ptr { public: //! Standard ctor explicit qwt3d_ptr(T* ptr = 0) :rawptr_(ptr) { } //! Dtor (calls T::destroy) ~qwt3d_ptr() { destroyRawPtr(); } //! Copy ctor (calls (virtual) clone()) qwt3d_ptr(qwt3d_ptr const& val) { rawptr_ = val.rawptr_->clone(); } //! Assignment in the same spirit as copy ctor qwt3d_ptr& operator=(qwt3d_ptr const& val) { if (this == &val) return *this; destroyRawPtr(); rawptr_ = val.rawptr_->clone(); return *this; } //! It's a pointerlike object, isn't it ? T* operator->() const { return rawptr_; } //! Dereferencing T& operator*() const { return *rawptr_; } private: T* rawptr_; void destroyRawPtr() { if (rawptr_) rawptr_->destroy(); rawptr_ = 0; } }; } // ns #endif /* include guarded */ qwtplot3d-0.2.7+svn191/include/qwt3d_graphplot.h0000644000203200020320000000056610663257610020773 0ustar gudjongudjon#ifndef qwt3d_graphplot_h__2004_03_06_01_57_begin_guarded_code #define qwt3d_graphplot_h__2004_03_06_01_57_begin_guarded_code #include "qwt3d_plot.h" namespace Qwt3D { //! TODO class QWT3D_EXPORT GraphPlot : public Plot3D { // Q_OBJECT public: GraphPlot( QWidget* parent = 0, const char* name = 0 ); protected: virtual void createData() = 0; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_global.h0000644000203200020320000000300710663257610020224 0ustar gudjongudjon#ifndef QWT3D_GLOBAL_H #define QWT3D_GLOBAL_H #include #if QT_VERSION < 0x040000 #include #endif #define QWT3D_MAJOR_VERSION 0 #define QWT3D_MINOR_VERSION 2 #define QWT3D_PATCH_VERSION 6 // // Create Qwt3d DLL if QWT3D_DLL is defined (Windows only) // #if defined(Q_WS_WIN) #if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning(disable: 4251) // dll interface required for stl templates //pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data #pragma warning(disable: 4786) // truncating debug info after 255 characters #pragma warning(disable: 4660) // template-class specialization 'identifier' is already instantiated #if (_MSC_VER >= 1400) /* VS8 - not sure about VC7 */ #pragma warning(disable: 4996) /* MS security enhancements */ #endif #endif #if defined(QWT3D_NODLL) #undef QWT3D_MAKEDLL #undef QWT3D_DLL #undef QWT3D_TEMPLATEDLL #endif #ifdef QWT3D_DLL #if defined(QWT3D_MAKEDLL) /* create a Qwt3d DLL library */ #undef QWT3D_DLL #define QWT3D_EXPORT __declspec(dllexport) #define QWT3D_TEMPLATEDLL #endif #endif #if defined(QWT3D_DLL) /* use a Qwt3d DLL library */ #define QWT3D_EXPORT __declspec(dllimport) #define QWT3D_TEMPLATEDLL #endif #else // ! Q_WS_WIN #undef QWT3D_MAKEDLL /* ignore these for other platforms */ #undef QWT3D_DLL #undef QWT3D_TEMPLATEDLL #endif #ifndef QWT3D_EXPORT #define QWT3D_EXPORT #endif #endif qwtplot3d-0.2.7+svn191/include/qwt3d_parametricsurface.h0000644000203200020320000000274310663257610022472 0ustar gudjongudjon#ifndef qwt3d_parametricsurface_h__2004_03_05_23_43_begin_guarded_code #define qwt3d_parametricsurface_h__2004_03_05_23_43_begin_guarded_code #include "qwt3d_gridmapping.h" namespace Qwt3D { class SurfacePlot; //! Abstract base class for parametric surfaces /** */ class QWT3D_EXPORT ParametricSurface : public GridMapping { public: ParametricSurface(); //!< Constructs ParametricSurface object w/o assigned SurfacePlot. //! Constructs ParametricSurface object and assigns a SurfacePlot explicit ParametricSurface(Qwt3D::SurfacePlot& plotWidget); //! Constructs ParametricSurface object and assigns a SurfacePlot explicit ParametricSurface(Qwt3D::SurfacePlot* plotWidget); //! Overwrite this virtual Qwt3D::Triple operator()(double u, double v) = 0; //! Assigns a new SurfacePlot and creates a data representation for it. virtual bool create(Qwt3D::SurfacePlot& plotWidget); //! Creates data representation for the actual assigned SurfacePlot. virtual bool create(); //! Assigns the object to another widget. To see the changes, you have to call this function before create(). void assign(Qwt3D::SurfacePlot& plotWidget); //! Assigns the object to another widget. To see the changes, you have to call this function before create(). void assign(Qwt3D::SurfacePlot* plotWidget); //! Provide information about periodicity of the 'u' resp. 'v' domains. void setPeriodic(bool u, bool v); private: bool uperiodic_, vperiodic_; }; } // ns #endif /* include guarded */ qwtplot3d-0.2.7+svn191/include/qwt3d_gridmapping.h0000644000203200020320000000161510663257610021270 0ustar gudjongudjon#ifndef qwt3d_gridmapping_h__2004_03_06_12_31_begin_guarded_code #define qwt3d_gridmapping_h__2004_03_06_12_31_begin_guarded_code #include "qwt3d_mapping.h" namespace Qwt3D { class SurfacePlot; //! Abstract base class for mappings acting on rectangular grids /** */ class QWT3D_EXPORT GridMapping : public Mapping { public: GridMapping(); //!< Constructs GridMapping object w/o assigned SurfacePlot. void setMesh(unsigned int columns, unsigned int rows); //!< Sets number of rows and columns. void setDomain(double minu, double maxu, double minv, double maxv); //!< Sets u-v domain boundaries. void restrictRange(Qwt3D::ParallelEpiped const&); //!< Restrict the mappings range to the parallelepiped protected: Qwt3D::ParallelEpiped range_p; Qwt3D::SurfacePlot* plotwidget_p; unsigned int umesh_p, vmesh_p; double minu_p, maxu_p, minv_p, maxv_p; }; } // ns #endif /* include guarded */ qwtplot3d-0.2.7+svn191/include/qwt3d_autoscaler.h0000644000203200020320000000255510663257610021135 0ustar gudjongudjon#ifndef __qwt3d_autoscaler_2003_08_18_12_05__ #define __qwt3d_autoscaler_2003_08_18_12_05__ #include #include "qwt3d_global.h" #include "qwt3d_autoptr.h" namespace Qwt3D { //! ABC for autoscaler class QWT3D_EXPORT AutoScaler { friend class qwt3d_ptr; protected: //! Returns a new heap based object of the derived class. virtual AutoScaler* clone() const = 0; //! To implement from subclasses virtual int execute(double& a, double& b, double start, double stop, int ivals) = 0; virtual ~AutoScaler(){} private: void destroy() const {delete this;} //!< Used by qwt3d_ptr }; //! Automatic beautifying of linear scales class QWT3D_EXPORT LinearAutoScaler : public AutoScaler { friend class LinearScale; protected: LinearAutoScaler(); explicit LinearAutoScaler(std::vector& mantisses); //! Returns a new heap based object utilized from qwt3d_ptr AutoScaler* clone() const {return new LinearAutoScaler(*this);} int execute(double& a, double& b, double start, double stop, int ivals); private: double start_, stop_; int intervals_; void init(double start, double stop, int ivals); double anchorvalue(double start, double mantisse, int exponent); int segments(int& l_intervals, int& r_intervals, double start, double stop, double anchor, double mantissa, int exponent); std::vector mantissi_; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_portability.h0000644000203200020320000000347510663257610021337 0ustar gudjongudjon#ifndef qwt3d_portability_h__2005_07_02_11_55_begin_guarded_code #define qwt3d_portability_h__2005_07_02_11_55_begin_guarded_code //! Portability classes providing transparent Qt3/4 support #include #include "qwt3d_global.h" #if QT_VERSION < 0x040000 namespace Qwt3D { #define QWT3DLOCAL8BIT(qstring) \ ((const char*)(qstring.local8Bit())) typedef int MouseState; typedef int KeyboardState; const Qt::TextFlags SingleLine = Qt::SingleLine; } // ns #else // Qt4 #include namespace Qwt3D { #define QWT3DLOCAL8BIT(qstring) \ ((const char*)(qstring.toLocal8Bit())) const Qt::TextFlag SingleLine = Qt::TextSingleLine; //! This class creates a (mouse-button,modifier) pair (ordinary typedef for int if Qt3 is used) class MouseState { public: MouseState(Qt::MouseButtons mb = Qt::NoButton, Qt::KeyboardModifiers km = Qt::NoModifier) : mb_(mb), km_(km) { } MouseState(Qt::MouseButton mb, Qt::KeyboardModifiers km = Qt::NoModifier) : mb_(mb), km_(km) { } bool operator==(const MouseState& ms) { return mb_ == ms.mb_ && km_ == ms.km_; } bool operator!=(const MouseState& ms) { return !operator==(ms); } private: Qt::MouseButtons mb_; Qt::KeyboardModifiers km_; }; //! This class creates a (key-button,modifier) pair (ordinary typedef for int if Qt3 is used) class KeyboardState { public: KeyboardState(int key = Qt::Key_unknown, Qt::KeyboardModifiers km = Qt::NoModifier) : key_(key), km_(km) { } bool operator==(const KeyboardState& ms) { return key_ == ms.key_ && km_ == ms.km_; } bool operator!=(const KeyboardState& ms) { return !operator==(ms); } private: int key_; Qt::KeyboardModifiers km_; }; } // ns #endif #endif qwtplot3d-0.2.7+svn191/include/qwt3d_axis.h0000644000203200020320000001320410663257610017730 0ustar gudjongudjon#ifndef __AXIS_H__ #define __AXIS_H__ #include "qwt3d_autoptr.h" #include "qwt3d_label.h" #include "qwt3d_scale.h" #include "qwt3d_autoscaler.h" namespace Qwt3D { //! Autoscalable axis with caption. /*! Axes are highly customizable especially in terms of labeling and scaling. */ class QWT3D_EXPORT Axis : public Drawable { public: Axis(); //!< Constructs standard axis Axis(Qwt3D::Triple beg, Qwt3D::Triple end); //!< Constructs a new axis with specified limits virtual ~Axis(); // dtor virtual void draw(); //!< Draws axis void setPosition(const Qwt3D::Triple& beg, const Qwt3D::Triple& end); //!< Positionate axis void position(Qwt3D::Triple& beg, Qwt3D::Triple& end) const {beg = beg_; end = end_;} //!< Returns axis' position Qwt3D::Triple begin() const { return beg_; } //!< Returns axis' beginning position Qwt3D::Triple end() const { return end_; } //!< Returns axis' ending position double length() const { return (end_-beg_).length(); } //!< Returns axis' length void setTicLength(double majorl, double minorl); //!< Sets tics lengths in world coordinates //! Returns tics lengths void ticLength(double& majorl, double& minorl) const {majorl = lmaj_; minorl = lmin_;} void setTicOrientation(double tx, double ty, double tz); //!< Sets tic orientation void setTicOrientation(const Qwt3D::Triple& val); //!< Same function as above Qwt3D::Triple ticOrientation() const { return orientation_;} //!< Returns tic orientation void setSymmetricTics( bool b) { symtics_ = b;} //!< Sets two-sided tics (default is false) //! Sets font for axis label void setLabelFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); void setLabelFont(QFont const& font); //!< Sets font for axis label QFont const& labelFont() const {return labelfont_;} //!< Returns current label font void setLabelString(QString const& name); //!< Sets label content void setLabelPosition(const Qwt3D::Triple& pos, Qwt3D::ANCHOR); void setLabelColor(Qwt3D::RGBA col); void setLabel(bool d) {drawLabel_ = d;} //!< Turns label drawing on or off void adjustLabel(int val) {labelgap_ = val;} //!< Shifts label in device coordinates dependent on anchor; void setScaling(bool d) {drawTics_ = d;} //!< Turns scale drawing on or off bool scaling() const {return drawTics_;} //!< Returns, if scale drawing is on or off void setScale(Qwt3D::SCALETYPE); void setScale(Scale* item); void setNumbers(bool d) {drawNumbers_ = d;} //!< Turns number drawing on or off bool numbers() const {return drawNumbers_;} //!< Returns, if number drawing is on or off void setNumberColor(Qwt3D::RGBA col); //!< Sets the color for axes numbers Qwt3D::RGBA numberColor() const {return numbercolor_;} //!< Returns the color for axes numbers //! Sets font for numbering void setNumberFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); void setNumberFont(QFont const&); //!< Overloaded member, works like the above function QFont const& numberFont() const {return numberfont_;} //!< Returns current numbering font void setNumberAnchor(Qwt3D::ANCHOR a) { scaleNumberAnchor_ = a;} //!< Sets anchor position for numbers void adjustNumbers(int val) {numbergap_ = val;} //!< Shifts axis numbers in device coordinates dependent on anchor; void setAutoScale(bool val = true) {autoscale_ = val;} //!< Turns Autoscaling on or off bool autoScale() const { return autoscale_;} //!< actual Autoscaling mode void setMajors(int val); //!< Requests major intervals (maybe changed, if autoscaling is present) void setMinors(int val); //!< Requests minor intervals int majors() const { return majorintervals_; } //!< Returns number of major intervals int minors() const { return minorintervals_; } //!< Returns number of minor intervals Qwt3D::TripleField const& majorPositions() const {return majorpos_;} //!< Returns positions for actual major tics (also if invisible) Qwt3D::TripleField const& minorPositions() const {return minorpos_;} //!< Returns positions for actual minor tics (also if invisible) //! Sets line width for axis components void setLineWidth(double val, double majfac = 0.9, double minfac = 0.5); double lineWidth() const { return lineWidth_;} //!< Returns line width for axis body double majLineWidth() const { return majLineWidth_;} //!< Returns Line width for major tics double minLineWidth() const { return minLineWidth_;} //!< Returns Line width for minor tics void setLimits(double start, double stop) {start_=start; stop_=stop;} //!< Sets interval void limits(double& start, double& stop) const {start = start_; stop = stop_;} //!< Returns axis interval void recalculateTics(); //!< Enforces recalculation of ticmark positions private: void init(); void drawBase(); void drawTics(); void drawTicLabel(Qwt3D::Triple Pos, int mtic); Qwt3D::Triple drawTic(Qwt3D::Triple nadir, double length); void drawLabel(); bool prepTicCalculation(Triple& startpoint); Qwt3D::Triple biggestNumberString(); Qwt3D::ANCHOR scaleNumberAnchor_; Qwt3D::Label label_; std::vector markerLabel_; Qwt3D::Triple beg_, end_; Qwt3D::TripleField majorpos_, minorpos_; //! vectors, holding major resp. minor tic positions; Qwt3D::Triple ncube_beg_, ncube_end_; //!< enclosing parallelepiped for axis numbering double start_, stop_, autostart_, autostop_; double lmaj_, lmin_; Qwt3D::Triple orientation_; int majorintervals_, minorintervals_; double lineWidth_, majLineWidth_, minLineWidth_; bool symtics_; bool drawNumbers_, drawTics_, drawLabel_; bool autoscale_; QFont numberfont_, labelfont_; Qwt3D::RGBA numbercolor_; int numbergap_, labelgap_; Qwt3D::qwt3d_ptr scale_; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_types.h0000644000203200020320000002114110663257610020127 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4786 ) #endif #ifndef __DATATYPES_H__ #define __DATATYPES_H__ #ifdef _DEBUG #include #endif #include #include "qwt3d_global.h" #if defined(Q_WS_WIN) #include #endif #ifndef WHEEL_DELTA #define WHEEL_DELTA 120 #endif #include "qwt3d_portability.h" #include "qwt3d_helper.h" #include "qwt3d_openglhelper.h" //! Common namespace for all QwtPlot3D classes namespace Qwt3D { const double PI = 3.14159265358979323846264338328; //! Plotting style enum PLOTSTYLE { NOPLOT , //!< No visible data WIREFRAME , //!< Wireframe style HIDDENLINE , //!< Hidden Line style FILLED , //!< Color filled polygons w/o edges FILLEDMESH , //!< Color filled polygons w/ separately colored edges POINTS , //!< User defined style (used by Enrichments) USER //!< User defined style (used by Enrichments) }; //! Shading style enum SHADINGSTYLE { FLAT, //!< Flat shading (OpenGL) GOURAUD //!< Gouraud Shading (OpenGL) }; //! Style of Coordinate system enum COORDSTYLE { NOCOORD, //!< Coordinate system is not visible BOX, //!< Boxed FRAME //!< Frame - 3 visible axes }; //! Different types of axis scales enum SCALETYPE { LINEARSCALE,//!< Linear scaling LOG10SCALE, //!< Logarithmic scaling (base 10) USERSCALE //!< User-defined (for extensions) }; //! Plotting style for floor data (projections) enum FLOORSTYLE { NOFLOOR, //!< Empty floor FLOORISO, //!< Isoline projections visible FLOORDATA //!< Projected polygons visible }; //! Mesh type enum DATATYPE { GRID, //!< Rectangular grid POLYGON //!< Convex polygon }; //! The 12 axes /** \image html axes.png */ enum AXIS { X1 = 0, //!< 1st x-axis X2 = 3, //!< 2nd x-axis X3 = 4, //!< 3th x-axis X4 = 5, //!< 4th x-axis Y1 = 1, //!< 1st y-axis Y2 = 8, //!< 2nd y-axis Y3 = 7, //!< 3th y-axis Y4 = 6, //!< 4th y-axis Z1 = 2, //!< 1st z-axis Z2 = 9, //!< 2nd z-axis Z3 = 11, //!< 3th z-axis Z4 = 10 //!< 4th z-axis }; //! The 6 sides enum SIDE { NOSIDEGRID = 0, LEFT = 1 << 0, RIGHT = 1 << 1, CEIL = 1 << 2, FLOOR = 1 << 3, FRONT = 1 << 4, BACK = 1 << 5 }; //! Possible anchor points for drawing operations enum ANCHOR { BottomLeft, BottomRight, BottomCenter, TopLeft, TopRight, TopCenter, CenterLeft, CenterRight, Center }; //! Tuple [x,y] struct QWT3D_EXPORT Tuple { Tuple() : x(0), y(0) {} //!< Calls Tuple(0,0) Tuple(double X, double Y) : x(X), y(Y) {} //!< Initialize Tuple with x and y //! Tuple coordinates double x,y; }; //! Triple [x,y,z] /** Consider Triples also as vectors in R^3 */ struct QWT3D_EXPORT Triple { //! Initialize Triple with x,y and z explicit Triple(double xv = 0,double yv = 0,double zv = 0) : x(xv), y(yv), z(zv) { } #ifndef QWT3D_NOT_FOR_DOXYGEN #ifdef Q_OS_IRIX Triple(const Triple& val) { if (&val == this) return; x = val.x; y = val.y; z = val.z; } const Triple& operator=(const Triple& val) { if (&val == this) return *this; x = val.x; y = val.y; z = val.z; return *this; } #endif #endif // QWT3D_NOT_FOR_DOXYGEN //! Triple coordinates double x,y,z; Triple& operator+=(Triple t) { x += t.x; y += t.y; z += t.z; return *this; } Triple& operator-=(Triple t) { x -= t.x; y -= t.y; z -= t.z; return *this; } Triple& operator*=(double d) { x *= d; y *= d; z *= d; return *this; } Triple& operator/=(double d) { x /= d; y /= d; z /= d; return *this; } Triple& operator*=(Triple t) // scale { x *= t.x; y *= t.y; z *= t.z; return *this; } bool operator!=(Triple t) const { return !isPracticallyZero(x,t.x) || !isPracticallyZero(y,t.y) || !isPracticallyZero(z,t.z); } bool operator==(Triple t) const { return !operator!=(t); } double length() const { double l2 = x*x + y*y + z*z; return (isPracticallyZero(l2)) ? 0 :sqrt(l2); } void normalize() { double l = length(); if (l) *this /= l; } }; inline const Triple operator+(const Triple& t, const Triple& t2) { return Triple(t) += t2; } inline const Triple operator-(const Triple& t, const Triple& t2) { return Triple(t) -= t2; } inline const Triple operator*(double d, const Triple& t) { return Triple(t) *= d; } inline const Triple operator*(const Triple& t, double d) { return Triple(t) *= d; } inline const Triple operator/(double d, const Triple& t) { return Triple(t) /= d; } inline const Triple operator/(const Triple& t, double d) { return Triple(t) /= d; } inline const Triple operator*(const Triple& t, const Triple& t2) { return Triple(t) *= t2; } //! Parallelepiped spanned by 2 Triples /** Please use \em normalized Parallelepipeds:\n\n minVertex.x <= maxVertex.x\n minVertex.y <= maxVertex.y\n minVertex.z <= maxVertex.z\n */ struct QWT3D_EXPORT ParallelEpiped { //! Construct non-initialized Parallelepiped ParallelEpiped() { } //! Construct initialized Parallelepiped /** minv -> minVertex\n maxv -> maxVertex\n */ ParallelEpiped(Triple minv, Triple maxv) : minVertex(minv), maxVertex(maxv) { } Triple minVertex; Triple maxVertex; }; //! Free vector /** FreeVectors represent objects like normal vectors and other vector fields inside R^3 */ struct QWT3D_EXPORT FreeVector { FreeVector() { } //! Construct initialized vector /** b -> base\n e -> top\n */ FreeVector(Triple b, Triple t) : base(b), top(t) { } Triple base; Triple top; }; //! A free vector field in R^3 typedef std::vector FreeVectorField; //! A point field in R^3 typedef std::vector TripleField; //! Holds indices in a TripleField interpreted as counterclockwise node numbering for a convex polygon typedef std::vector Cell; //! Vector of convex polygons. You need a TripleField as base for the node data typedef std::vector CellField; //! Returns the sum over the sizes of the single cells unsigned tesselationSize(Qwt3D::CellField const& t); //! Red-Green-Blue-Alpha value struct QWT3D_EXPORT RGBA { RGBA() : r(0), g(0), b(0), a(1) {} RGBA(double rr, double gg, double bb, double aa = 1) : r(rr), g(gg), b(bb), a(aa) {} double r,g,b,a; }; //! A Color field typedef std::vector ColorVector; #ifndef QWT3D_NOT_FOR_DOXYGEN QWT3D_EXPORT QColor GL2Qt(GLdouble r, GLdouble g, GLdouble b); //!< RGB -> QColor QWT3D_EXPORT Qwt3D::RGBA Qt2GL(QColor col); //!< QColor -> RGBA typedef double *Vertex; typedef std::vector DataRow; typedef std::vector DataMatrix; class Data { public: Qwt3D::DATATYPE datatype; Data() {datatype= Qwt3D::POLYGON;} virtual ~Data() {} virtual void clear() = 0; //!< destroy content virtual bool empty() const = 0; //!< no data void setHull(Qwt3D::ParallelEpiped const& h) {hull_p = h;} Qwt3D::ParallelEpiped const& hull() const {return hull_p;} protected: Qwt3D::ParallelEpiped hull_p; }; //! Implements a matrix of z-Values with limit access functions class GridData : public Data { public: GridData(); GridData(unsigned int columns, unsigned int rows);//!< see setSize() ~GridData() { clear();} int columns() const; int rows() const; void clear(); //!< destroy content bool empty() const { return vertices.empty();} void setSize(unsigned int columns, unsigned int rows); //!< destroys content and set new size, elements are uninitialized DataMatrix vertices; //!< mesh vertices DataMatrix normals; //!< mesh normals void setPeriodic(bool u, bool v) {uperiodic_ = u; vperiodic_ = v;} bool uperiodic() const {return uperiodic_;} bool vperiodic() const {return vperiodic_;} private: bool uperiodic_, vperiodic_; }; //! Implements a graph-like cell structure with limit access functions class CellData : public Data { public: CellData() {datatype=Qwt3D::POLYGON;} ~CellData() { clear();} void clear(); //!< destroy content bool empty() const { return cells.empty();} Triple const& operator()(unsigned cellnumber, unsigned vertexnumber); CellField cells; //!< polygon/cell mesh TripleField nodes; TripleField normals; //!< mesh normals }; inline Triple normalizedcross(Triple const& u, Triple const& v) { Triple n; /* compute the cross product (u x v for right-handed [ccw]) */ n.x = u.y * v.z - u.z * v.y; n.y = u.z * v.x - u.x * v.z; n.z = u.x * v.y - u.y * v.x; /* normalize */ double l = n.length(); if (l) { n /= l; } else { n = Triple(0,0,0); } return n; } inline double dotProduct(Triple const& u, Triple const& v) { return u.x*v.x + u.y*v.y + u.z*v.z; } void convexhull2d( std::vector& idx, const std::vector& src ); #endif // QWT3D_NOT_FOR_DOXYGEN } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_coordsys.h0000644000203200020320000000711410663257610020634 0ustar gudjongudjon#ifndef __COORDSYS_H__ #define __COORDSYS_H__ #include "qwt3d_axis.h" #include "qwt3d_colorlegend.h" namespace Qwt3D { //! A coordinate system with different styles (BOX, FRAME) class QWT3D_EXPORT CoordinateSystem : public Drawable { public: explicit CoordinateSystem(Qwt3D::Triple blb = Qwt3D::Triple(0,0,0), Qwt3D::Triple ftr = Qwt3D::Triple(0,0,0), Qwt3D::COORDSTYLE = Qwt3D::BOX); ~CoordinateSystem(); void init(Qwt3D::Triple beg = Qwt3D::Triple(0,0,0), Qwt3D::Triple end = Qwt3D::Triple(0,0,0)); //! Set style for the coordinate system (NOCOORD, FRAME or BOX) void setStyle(Qwt3D::COORDSTYLE s, Qwt3D::AXIS frame_1 = Qwt3D::X1, Qwt3D::AXIS frame_2 = Qwt3D::Y1, Qwt3D::AXIS frame_3 = Qwt3D::Z1); Qwt3D::COORDSTYLE style() const { return style_;} //!< Return style oft the coordinate system void setPosition(Qwt3D::Triple first, Qwt3D::Triple second); //!< first == front_left_bottom, second == back_right_top void setAxesColor(Qwt3D::RGBA val); //!< Set common color for all axes //! Set common font for all axis numberings void setNumberFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); //! Set common font for all axis numberings void setNumberFont(QFont const& font); //! Set common color for all axis numberings void setNumberColor(Qwt3D::RGBA val); void setStandardScale(); //!< Sets an linear axis with real number items void adjustNumbers(int val); //!< Fine tunes distance between axis numbering and axis body void adjustLabels(int val); //!< Fine tunes distance between axis label and axis body //! Sets color for the grid lines void setGridLinesColor(Qwt3D::RGBA val) {gridlinecolor_ = val;} //! Set common font for all axis labels void setLabelFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); //! Set common font for all axis labels void setLabelFont(QFont const& font); //! Set common color for all axis labels void setLabelColor(Qwt3D::RGBA val); //! Set line width for tic marks and axes void setLineWidth(double val, double majfac = 0.9, double minfac = 0.5); //! Set length for tic marks void setTicLength(double major, double minor); //! Switch autoscaling of axes void setAutoScale(bool val = true); Qwt3D::Triple first() const { return first_;} Qwt3D::Triple second() const { return second_;} void setAutoDecoration(bool val = true) {autodecoration_ = val;} bool autoDecoration() const { return autodecoration_;} void setLineSmooth(bool val = true) {smooth_ = val;} //!< draw smooth axes bool lineSmooth() const {return smooth_;} //!< smooth axes ? void draw(); //! Defines whether a grid between the major and/or minor tics should be drawn void setGridLines(bool majors, bool minors, int sides = Qwt3D::NOSIDEGRID); int grids() const {return sides_;} //!< Returns grids switched on //! The vector of all12 axes - use them to set axis properties individually. std::vector axes; private: void destroy(); Qwt3D::Triple first_, second_; Qwt3D::COORDSTYLE style_; Qwt3D::RGBA gridlinecolor_; bool smooth_; void chooseAxes(); void autoDecorateExposedAxis(Axis& ax, bool left); void drawMajorGridLines(); //!< Draws a grid between the major tics on the site void drawMinorGridLines(); //!< Draws a grid between the minor tics on the site void drawMajorGridLines(Qwt3D::Axis&, Qwt3D::Axis&); //! Helper void drawMinorGridLines(Qwt3D::Axis&, Qwt3D::Axis&); //! Helper void recalculateAxesTics(); bool autodecoration_; bool majorgridlines_, minorgridlines_; int sides_; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_enrichment_std.h0000644000203200020320000000466710663257610022007 0ustar gudjongudjon#ifndef qwt3d_enrichment_std_h__2004_02_23_19_25_begin_guarded_code #define qwt3d_enrichment_std_h__2004_02_23_19_25_begin_guarded_code #include "qwt3d_enrichment.h" namespace Qwt3D { class Plot3D; //! The Cross Hair Style class QWT3D_EXPORT CrossHair : public VertexEnrichment { public: CrossHair(); CrossHair(double rad, double linewidth, bool smooth, bool boxed); Qwt3D::Enrichment* clone() const {return new CrossHair(*this);} void configure(double rad, double linewidth, bool smooth, bool boxed); void drawBegin(); void drawEnd(); void draw(Qwt3D::Triple const&); private: bool boxed_, smooth_; double linewidth_, radius_; GLboolean oldstate_; }; //! The Point Style class QWT3D_EXPORT Dot : public VertexEnrichment { public: Dot(); Dot(double pointsize, bool smooth); Qwt3D::Enrichment* clone() const {return new Dot(*this);} void configure(double pointsize, bool smooth); void drawBegin(); void drawEnd(); void draw(Qwt3D::Triple const&); private: bool smooth_; double pointsize_; GLboolean oldstate_; }; //! The Cone Style class QWT3D_EXPORT Cone : public VertexEnrichment { public: Cone(); Cone(double rad, unsigned quality); ~Cone(); Qwt3D::Enrichment* clone() const {return new Cone(*this);} void configure(double rad, unsigned quality); void draw(Qwt3D::Triple const&); private: GLUquadricObj *hat; GLUquadricObj *disk; unsigned quality_; double radius_; GLboolean oldstate_; }; //! 3D vector field. /** The class encapsulates a vector field including his OpenGL representation as arrow field. The arrows can be configured in different aspects (color, shape, painting quality). */ class QWT3D_EXPORT Arrow : public VertexEnrichment { public: Arrow(); ~Arrow(); Qwt3D::Enrichment* clone() const {return new Arrow(*this);} void configure(int segs, double relconelength, double relconerad, double relstemrad); void setQuality(int val) {segments_ = val;} //!< Set the number of faces for the arrow void draw(Qwt3D::Triple const&); void setTop(Qwt3D::Triple t){top_ = t;} void setColor(Qwt3D::RGBA rgba) {rgba_ = rgba;} private: GLUquadricObj *hat; GLUquadricObj *disk; GLUquadricObj *base; GLUquadricObj *bottom; GLboolean oldstate_; double calcRotation(Qwt3D::Triple& axis, Qwt3D::FreeVector const& vec); int segments_; double rel_cone_length; double rel_cone_radius; double rel_stem_radius; Qwt3D::Triple top_; Qwt3D::RGBA rgba_; }; } // ns #endif qwtplot3d-0.2.7+svn191/include/qwt3d_volumeplot.h0000644000203200020320000000057310663257610021177 0ustar gudjongudjon#ifndef qwt3d_volumeplot_h__2004_03_06_01_52_begin_guarded_code #define qwt3d_volumeplot_h__2004_03_06_01_52_begin_guarded_code #include "qwt3d_plot.h" namespace Qwt3D { //! TODO class QWT3D_EXPORT VolumePlot : public Plot3D { // Q_OBJECT public: VolumePlot( QWidget* parent = 0, const char* name = 0 ){} protected: virtual void createData() = 0; }; } // ns #endif qwtplot3d-0.2.7+svn191/doc/0000755000203200020320000000000010663257711014615 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/doc/web/0000755000203200020320000000000010663257711015372 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/doc/web/navigation/0000755000203200020320000000000010663257711017531 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/doc/web/navigation/doxygen.png0000644000203200020320000000446010663257610021716 0ustar gudjongudjonPNG  IHDRn5/pItRNS7X}bKGDûJ3IDATxXklTUg44*TJw1)bD%`-&D%4"0!դ&FiEQ>V(],Ƕv#?JBQO;3=nwJfv73|{{53?JMYJO,- @eĎؕm:RBA#vdst\)3WJ̕1st\)iK٥J6=)ضEލؕ- 1&ZA>͎XKb6,'ixt@ ZV3]e`=ˎz `Ch ZT^3Pi4ϠA@0E##KV޸͉SRVM C)^XMGhϗ+ tS#Jw`eOUb VV+ؤjN*15r[ұ7+Q|A͐L}[G;!\㝖IBJҟqOd^iYM&;4M|:TTEZJc w$޸;8mYZI Lb RZiuT=B,s%=fL0#,5i6ZQ;.2գ+Mo"}D*AoWtr'ka )XI*씜iUNFHJ>yː̙X&2q#O`6Veۘf!q8G}Jݭ#xl&wa6gz #ݞ4@' ybz夤꨹2regqnjySxCAԛ yK pG͘$sS*MZk 49FM| Xt>wBJFWKG'F0侄6)/_~:YKzB'zHRj*F p㓽Wwkq`b$18ϣ"c?2c4';δoɸ3v|&d6Ν}z :YY)JџdòyYb罹-0Q3Ǿ~?\sFsѯŗ4&?X2 CUPT!FiK,rѹ%%R&ᖭaG*d̬ASi%U<ӢMLiPX㯲,%,mލIm2W5-\)3WJ̕1st\)3WJ̕1st\)3WJ̕1st\)3WJ̕1stc*:MCtEXtSoftware@(#)ImageMagick 4.2.7 99/07/01 cristy@mystic.es.dupont.comk*tEXtSignature5463a785bb11d367022701c77ebe81abctEXtPage110x53+0+0EBIENDB`qwtplot3d-0.2.7+svn191/doc/web/navigation/doxygen.css0000644000203200020320000001120110663257610021711 0ustar gudjongudjonBODY { background-color: #FAF8E8; background: white; font-family:sans-serif; color:black; font-size: 13px; } h1, h2, h3, h4 { font-family:sans-serif; color: #005A9C; background: transparent; } H1 { text-align: center; font-size: 18px; } H2 { font-size: 16px; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #eeeeff; border: 4px solid #eeeeff; text-align: center; margin-bottom: 2px } a:link { font-family: Arial, Helvetica, sans-serif; font-size: 13px; line-height: 13px; color: #3366ff} a:visited { font-family: Arial, Helvetica, sans-serif; font-size: 13px; line-height: 13px; color: #3366ff} a:hover { font-family: Arial, Helvetica, sans-serif; font-size: 13px; line-height: 13px; color: #3366ff} A.qindex:hover { background-color: #ddddff } A.qindexHL { background-color: #6666cc; color: #ffffff } A.qindexHL:hover { background-color: #6666cc } A.qindexRef:hover { background-color: #ddddff } A.qindexRefHL { background-color: #6666cc; color: #ffffff } A.qindexRefHL:hover { background-color: #6666cc } A.el { text-decoration: none } A.code { text-decoration: none; font-weight: normal; color: #4444ee } A.codeRef { font-weight: normal; color: #4444ee } A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } DIV.fragment { width: 98%; border: 1px solid #CCCCCC; background-color: #f5f5f5; padding-left: 4px; margin: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } TD{ font-size: 13px;} TD.md { background-color: #f2f2ff; font-weight: bold} TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020} TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px} DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #eeeeff; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px } TD.indexvalue { background-color: #eeeeff; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdTable { border: 1px solid #868686; background-color: #f2f2ff; } .mdRow { padding: 8px 20px; } .mdescLeft { font-size: smaller; font-family: Arial, Helvetica, sans-serif; background-color: #FAFAFA; padding-left: 8px; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { font-size: smaller; font-family: Arial, Helvetica, sans-serif; font-style: italic; background-color: #FAFAFA; padding-left: 4px; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; padding-bottom: 0px; padding-right: 8px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-family: Geneva, Arial, Helvetica, sans-serif; font-size: 13px; } .memItemRight { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-family: Geneva, Arial, Helvetica, sans-serif; font-size: 13px; } qwtplot3d-0.2.7+svn191/doc/web/navigation/menu.css0000644000203200020320000000064010663257610021205 0ustar gudjongudjonBODY{ background: url(bg1.gif) } A:link {text-decoration:none; color: #004080} A:visited {text-decoration:none; color: #003060} A:active {text-decoration:none; color:#6F6F00} TD { font-family:Arial,sans-serif } TD.outside{background-color: #D0A000} TD.inside{background-color: #FAF8D0; text-align: center; font-size:14px;} TD.selected_outside{background-color: #0000E0} TD.alt_outside{background-color:#88BBAA} qwtplot3d-0.2.7+svn191/doc/web/navigation/sflogo.png0000644000203200020320000000410010663257610021521 0ustar gudjongudjonPNG  IHDRX쪝gAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbTSRf 7ᡠ@LieaX3[11ٳ眜dX@gΞ۴e?3ROfSfc?{zUZJHG[ 4k@qNwe@0huuqy꩓'5\\]!,,(Gx+X5c*yyD5Ϝ;'/'WU^ɹA^e%Eg̞} 216216>|(cnV&0t>|fZ* i*J@r֭.22@I9]x}|l $ҀIJJE \(ncm <M1%i?~J LA˚}cK 8A!!?*V^dܽw(]YI (Q 46#5u`0!t0Z\x & \MP $P|Ӗ@[;$A A = %`ځN|0%߽w\]0 ƫl6^ ,؟D3 h X  D9@] 9 :;/\91%v3gBAϴ#?5@[ ]{{{?|f+ "b灎T'M&IPITt0;p?!At"ГW]G xo Eϟ,Y8 ILh>p[~`Z  9 `hZ&̖߿cUt 6<YE~3f1`q t PѣZZ kte8@1!g R`1y B.ۮ\ Z\O\ ->ZD!X N .+J_֐xǐ e2f\Ɇ Ql@4ؽc tJL>l\xh0DH>r 9X!p)\7&!_s'c:wvǏ2 RL *Q+@g9](0 9*^Oo1\=[ .>| [imY@K 9 ,Q؈P@żw",n$4e _tV)iu!PY}7x6TEY!?=F5ngxu  R lbSא5!jʲ x}ٽ{ڵdh'Op)J} Lx !N u-Xj|bbUM5D Pɓ7_Ԭ~<b! ! b(-:0+='O](G 7&2 *r@@-he )ii ,ΘAԱwP:k 4 qָSf6B) #u䉓ಟ?į_F6q|× Œn[r׽|bQ L,! Р_2\ g̠ .ud @1 y w70} ӟ'AP&xxf ` |?o1pl˯EA?)8ׯ] ,2⣭^ xchoEWۗϰiEfKZ˗_~@Jʠ_~mۺϟ EQAaDT2PX\pذnݩ\\]!6N4 iׅGJ
The documentation for the QwtPlot3D API has been created by doxygen $doxygenversion and is hosted at SourceForge.net Logo
qwtplot3d-0.2.7+svn191/scripts/0000755000203200020320000000000010663257711015537 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/scripts/makedocu.py0000644000203200020320000000207610663257610017704 0ustar gudjongudjonimport os.path import shutil import tarfile import zlib import zipfile from time import gmtime, strftime refuseddirs = ['CVS','images'] refuseddirsextra = ['CVS','small'] source = 'V:\\\\cvs\\porting24\\qwtplot3d\\doc\\' sourceim = 'V:\\\\cvs\\porting24\\qwtplot3d\\doc\\images\\' zipname = 'V:\\\\cvs\\uploads\\qwtplot3d-doc.zip' zipextraname = 'V:\\\\cvs\\uploads\\qwtplot3d-doc-extra.zip' def compresstree(src, zip, refdir): names = os.listdir(src) for name in names: srcname = os.path.join(src, name) if os.path.isdir(srcname): if name not in refdir: compresstree(srcname, zip, refdir) if name == 'images': compresstree(srcname +'\\small', zip, refdir) else: zip.write(srcname,'qwtplot3d\\doc\\' + srcname[len(source):]) zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) compresstree(source, zip, refuseddirs) zip.close() zip = zipfile.ZipFile(zipextraname, 'w', zipfile.ZIP_DEFLATED) compresstree(sourceim, zip, refuseddirsextra) zip.close() qwtplot3d-0.2.7+svn191/scripts/valgr.sh0000644000203200020320000000011210663257610017176 0ustar gudjongudjonvalgrind --logfile=valog --suppressions=qwtplot3d.supp --error-limit=no $1qwtplot3d-0.2.7+svn191/scripts/qwtplot3d.supp0000644000203200020320000000041410663257610020406 0ustar gudjongudjon{ nvidia_suppression Addrcheck,Memcheck:Param ioctl(generic) obj:/lib/libc-2.3.2.so fun:NvRm* } { nvidia_suppression_2 Addrcheck,Memcheck:Cond fun:__nvsym* } { nvidia_suppression_3 Addrcheck,Memcheck:Cond obj:/usr/lib/opengl/nvidia/lib/libGL* }qwtplot3d-0.2.7+svn191/scripts/makedistro.py0000644000203200020320000000413110663257610020250 0ustar gudjongudjonimport os.path import shutil import tarfile import zlib import zipfile from time import gmtime, strftime refuseddirs = ['CVS','Debug','Release','moc','obj','tmp','data','hannes','doc','lib','bin'] refusedfiles = ['Makefile','.cvsignore','gl2psTest.c','gl2ps.bat','gl2ps.pro'] requiredfiles = ['qwtplot3d.dsw','examples.dsw','qwtplot3d.sln','examples.sln','thesis.tex','valgr.sh','qwtplot3d.supp','install.nsi'] requiredfiletypes = ['pro','bat','cpp','c','h','ui','ts','png','rc','ico','py','qrc'] srcfiletypes = ['cpp','c','h'] source = 'V:\\\\cvs\\porting24\\qwtplot3d\\' #tstr = strftime("%y%m%d", gmtime()) #tarname = 'V:\\\\cvs\\uploads\\' + tstr + 'plot3d.tgz' #zipname = 'V:\\\\cvs\\uploads\\' + tstr + 'plot3d.zip' refuseddirs.append('scripts') tarname = 'V:\\\\cvs\\uploads\\qwtplot3d-0.2.6.tgz' zipname = 'V:\\\\cvs\\uploads\\qwtplot3d-0.2.6.zip' def dos2unix(filename): if os.path.isdir(filename): print filename, "Directory!" return data = open(filename, "rb").read() if '\0' in data: print filename, "Binary!" return newdata = data.replace("\r\n", "\n") if newdata != data: print filename f = open(filename, "wb") f.write(newdata) f.close() def compresstree(src, tar, zip): names = os.listdir(src) for name in names: srcname = os.path.join(src, name) if os.path.isdir(srcname): if name not in refuseddirs: compresstree(srcname,tar, zip) else: (base,ext) = os.path.splitext(name) ext2 = ext[1:] if ((ext2 in requiredfiletypes) and (name not in refusedfiles)) or (name in requiredfiles): zip.write(srcname, 'qwtplot3d/' + srcname[len(source):]) if (ext2 in srcfiletypes): dos2unix(srcname) tar.add(srcname, 'qwtplot3d/' + srcname[len(source):]) if os.path.exists(tarname): os.remove(tarname) tar = tarfile.open(tarname, "w:gz") zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) compresstree(source,tar, zip) tar.close() zip.close() qwtplot3d-0.2.7+svn191/scripts/fixvc7.py0000644000203200020320000000074010663257610017316 0ustar gudjongudjonsourcedir = 'V:\\\\cvs\\qwtplot3d\\' stext=""$(QTDIR)"\\bin\\" rtext="$(QTDIR)\\bin\\" import os, string, sys from os.path import join, getsize for root, dirs, files in os.walk(sourcedir): for name in files: if '.vcproj' in name: f = file(join(root,name),'r') s = f.read() f.close() ss = string.replace(s,stext,rtext) f = file(join(root,name),'w+') f.write(ss); f.close(); qwtplot3d-0.2.7+svn191/src/0000755000203200020320000000000010663257711014637 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/src/qwt3d_movements.cpp0000644000203200020320000000476410663257610020513 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4305 ) #pragma warning ( disable : 4786 ) #endif #include #include "qwt3d_plot.h" using namespace Qwt3D; /** Set the rotation angle of the object. If you look along the respective axis towards ascending values, the rotation is performed in mathematical \e negative sense \param xVal angle in \e degree to rotate around the X axis \param yVal angle in \e degree to rotate around the Y axis \param zVal angle in \e degree to rotate around the Z axis */ void Plot3D::setRotation( double xVal, double yVal, double zVal ) { if (xRot_ == xVal && yRot_ == yVal && zRot_ == zVal) return; xRot_ = xVal; yRot_ = yVal; zRot_ = zVal; updateGL(); emit rotationChanged(xVal, yVal, zVal); } /** Set the shift in object (world) coordinates. \param xVal shift along (world) X axis \param yVal shift along (world) Y axis \param zVal shift along (world) Z axis \see setViewportShift() */ void Plot3D::setShift( double xVal, double yVal, double zVal ) { if (xShift_ == xVal && yShift_ == yVal && zShift_ == zVal) return; xShift_ = xVal; yShift_ = yVal; zShift_ = zVal; updateGL(); emit shiftChanged(xVal, yVal, zVal); } /** Performs shifting along screen axes. The shift moves points inside a sphere, which encloses the unscaled and unzoomed data by multiples of the spheres diameter \param xVal shift along (view) X axis \param yVal shift along (view) Y axis \see setShift() */ void Plot3D::setViewportShift( double xVal, double yVal ) { if (xVPShift_ == xVal && yVPShift_ == yVal) return; xVPShift_ = xVal; yVPShift_ = yVal; updateGL(); emit vieportShiftChanged(xVPShift_, yVPShift_); } /** Set the scale in object (world) coordinates. \param xVal scaling for X values \param yVal scaling for Y values \param zVal scaling for Z values A respective value of 1 represents no scaling; */ void Plot3D::setScale( double xVal, double yVal, double zVal ) { if (xScale_ == xVal && yScale_ == yVal && zScale_ == zVal) return; xScale_ = (xVal < DBL_EPSILON ) ? DBL_EPSILON : xVal; yScale_ = (yVal < DBL_EPSILON ) ? DBL_EPSILON : yVal; zScale_ = (zVal < DBL_EPSILON ) ? DBL_EPSILON : zVal; updateGL(); emit scaleChanged(xVal, yVal, zVal); } /** Set the (zoom in addition to scale). \param val zoom value (value == 1 indicates no zooming) */ void Plot3D::setZoom( double val ) { if (zoom_ == val) return; zoom_ = (val < DBL_EPSILON ) ? DBL_EPSILON : val; updateGL(); emit zoomChanged(val); } qwtplot3d-0.2.7+svn191/src/qwt3d_io_gl2ps.cpp0000644000203200020320000002203710663257610020205 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4786 ) #endif #include #include #include "qwt3d_openglhelper.h" #include "../3rdparty/gl2ps/gl2ps.h" #include "qwt3d_io_gl2ps.h" #include "qwt3d_plot.h" using namespace Qwt3D; //! Provides a new VectorWriter object. IO::Functor* VectorWriter::clone() const { return new VectorWriter(*this); } VectorWriter::VectorWriter() : gl2ps_format_(GL2PS_EPS), formaterror_(false), #ifdef GL2PS_HAVE_ZLIB compressed_(true), #else compressed_(false), #endif sortmode_(SIMPLESORT), landscape_(VectorWriter::AUTO), textmode_(VectorWriter::PIXEL), texfname_("") {} /*! Sets the mode for text output:\n \param val The underlying format for the generated output:\n PIXEL - poor quality but exact positioning\n NATIVE - high quality but inexact positioning\n TEX - high quality and exact positioning, arbitrary TeX strings as content for the saved labels are possible. The disadvantage is the need for an additionally TeX run to get the final output.\n \param fname Optional, used only in conjunction with TeX output; file name for the generated TeX file. If not set, a file called "OUTPUT.FOR.tex" will be generated, where "OUTPUT.FOR" describes the file name argument for IO::save().\n\n (04/05/27: On Linux platforms, pdflatex seems a file named 'dump_0.pdf.tex' mistakenly to identify as PDF file.) */ void VectorWriter::setTextMode(TEXTMODE val, QString fname) { textmode_ = val; texfname_ = (fname.isEmpty()) ? QString("") : fname; } #ifdef GL2PS_HAVE_ZLIB //! Turns compressed output on or off (no effect if zlib support has not been set) void VectorWriter::setCompressed(bool val) { compressed_ = val; } #else //! Turns compressed output on or off (no effect if zlib support has not been set) void VectorWriter::setCompressed(bool) { compressed_ = false; } #endif /*! Set output format, must be one of "EPS_GZ", "PS_GZ", "SVG_GZ", "EPS", "PS", "PDF", "SVG", or "PGF" (case sensitive) */ bool VectorWriter::setFormat(QString const& format) { if (format == QString("EPS")) { gl2ps_format_ = GL2PS_EPS; } else if (format == QString("PS")) { gl2ps_format_ = GL2PS_PS; } else if (format == QString("PDF")) { gl2ps_format_ = GL2PS_PDF; } #ifdef GL2PS_HAVE_ZLIB else if (format == QString("EPS_GZ")) { gl2ps_format_ = GL2PS_EPS; } else if (format == QString("PS_GZ")) { gl2ps_format_ = GL2PS_PS; } #endif else if (format == QString("SVG")) { gl2ps_format_ = GL2PS_SVG; } #ifdef GL2PS_HAVE_ZLIB else if (format == QString("SVG_GZ")) { gl2ps_format_ = GL2PS_SVG; } #endif else if (format == QString("PGF")) { gl2ps_format_ = GL2PS_PGF; } else { formaterror_ = true; return false; } formaterror_ = false; return true; } //! Performs actual output bool VectorWriter::operator()(Plot3D* plot, QString const& fname) { if (formaterror_) return false; char* tmploc = setlocale(LC_ALL, "C"); plot->makeCurrent(); GLint bufsize = 0, state = GL2PS_OVERFLOW; GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); GLint options = GL2PS_SIMPLE_LINE_OFFSET | GL2PS_SILENT | GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT; if (compressed_) options |= GL2PS_COMPRESS; switch (landscape_) { case VectorWriter::AUTO: if (viewport[2] - viewport[0] > viewport[3] - viewport[0]) options |= GL2PS_LANDSCAPE; break; case VectorWriter::ON: options |= GL2PS_LANDSCAPE; break; default: break; } int sortmode = GL2PS_SIMPLE_SORT; switch (sortmode_) { case VectorWriter::NOSORT: sortmode = GL2PS_NO_SORT; break; case VectorWriter::SIMPLESORT: sortmode = GL2PS_SIMPLE_SORT; break; case VectorWriter::BSPSORT: sortmode = GL2PS_BSP_SORT; break; default: break; } switch (textmode_) { case NATIVE: Label::useDeviceFonts(true); break; case PIXEL: Label::useDeviceFonts(false); break; case TEX: options |= GL2PS_NO_PIXMAP | GL2PS_NO_TEXT; break; default: break; } QString version = QString::number(QWT3D_MAJOR_VERSION) + "." + QString::number(QWT3D_MINOR_VERSION) + "." + QString::number(QWT3D_PATCH_VERSION); QString producer = QString("QwtPlot3D ") + version + ", (C) 2002"; // calculate actual year time_t now; struct tm *newtime; time(&now); newtime = gmtime(&now); if (newtime && newtime->tm_year + 1900 > 2002) producer += "-" + QString::number(newtime->tm_year+1900); // the SVG format does not like some of the characters in a mail address producer += " Micha Bieber, mailto: krischnamurti at users.sourceforge.net"; FILE *fp = fopen(QWT3DLOCAL8BIT(fname), "wb"); if (!fp) { Label::useDeviceFonts(false); setlocale(LC_ALL, tmploc); return false; } while( state == GL2PS_OVERFLOW ) { bufsize += 2*1024*1024; gl2psBeginPage ( QWT3DLOCAL8BIT(fname), QWT3DLOCAL8BIT(producer), viewport, gl2ps_format_, sortmode, options, GL_RGBA, 0, NULL, 0, 0, 0, bufsize, fp, QWT3DLOCAL8BIT(fname) ); plot->updateData(); plot->updateGL(); state = gl2psEndPage(); } fclose(fp); // extra TeX file if (textmode_ == TEX) { QString fn = (texfname_.isEmpty()) ? fname + ".tex" : texfname_; fp = fopen(QWT3DLOCAL8BIT(fn), "wb"); if (!fp) { Label::useDeviceFonts(false); setlocale(LC_ALL, tmploc); return false; } Label::useDeviceFonts(true); options &= ~GL2PS_NO_PIXMAP & ~GL2PS_NO_TEXT; state = GL2PS_OVERFLOW; while( state == GL2PS_OVERFLOW ) { bufsize += 2*1024*1024; gl2psBeginPage ( QWT3DLOCAL8BIT(fname), QWT3DLOCAL8BIT(producer), viewport, GL2PS_TEX, sortmode, options, GL_RGBA, 0, NULL, 0, 0, 0, bufsize, fp, QWT3DLOCAL8BIT(fn) ); plot->updateData(); plot->updateGL(); state = gl2psEndPage(); } fclose(fp); } Label::useDeviceFonts(false); setlocale(LC_ALL, tmploc); return true; } // moved GLint Qwt3D::setDeviceLineWidth(GLfloat val) { if (val<0) val=0; GLint ret = gl2psLineWidth(val); GLfloat lw[2]; glGetFloatv(GL_LINE_WIDTH_RANGE, lw); if (val < lw[0]) val = lw[0]; else if (val > lw[1]) val = lw[1]; glLineWidth(val); return ret; } GLint Qwt3D::setDevicePointSize(GLfloat val) { if (val<0) val=0; GLint ret = gl2psPointSize(val); GLfloat lw[2]; glGetFloatv(GL_POINT_SIZE_RANGE, lw); if (val < lw[0]) val = lw[0]; else if (val > lw[1]) val = lw[1]; glPointSize(val); return ret; } GLint Qwt3D::drawDevicePixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { glDrawPixels(width, height, format, type, pixels); if(format != GL_RGBA || type != GL_UNSIGNED_BYTE) return GL2PS_ERROR; GLfloat* convertedpixel = (GLfloat*)malloc(3 * width * height * sizeof(GLfloat)); if (!convertedpixel) return GL2PS_ERROR; GLubyte* px = (GLubyte*)pixels; for (int i=0; i!=3*width*height; i+=3) { int pxi = (4*i)/3; convertedpixel[i] = px[pxi] / float(255); convertedpixel[i+1] = px[pxi+1] / float(255); convertedpixel[i+2] = px[pxi+2] / float(255); } GLint ret = gl2psDrawPixels(width, height, 0, 0, GL_RGB, GL_FLOAT, convertedpixel); free(convertedpixel); return ret; } GLint Qwt3D::drawDeviceText(const char* str, const char* fontname, int fontsize, Triple pos, RGBA /*rgba*/, ANCHOR align, double gap) { double vp[3]; World2ViewPort(vp[0], vp[1], vp[2], pos.x, pos.y, pos.z); Triple start(vp[0],vp[1],vp[2]); GLdouble fcol[4]; glGetDoublev(GL_CURRENT_COLOR, fcol); GLdouble bcol[4]; glGetDoublev(GL_COLOR_CLEAR_VALUE, bcol); // glColor4d(color.r, color.g, color.b, color.a); // glClearColor(color.r, color.g, color.b, color.a); GLint ret = GL2PS_SUCCESS; GLint a = GL2PS_TEXT_BL; switch(align) { case Center: a = GL2PS_TEXT_C; break; case CenterLeft: a = GL2PS_TEXT_CL; start += Triple(gap,0,0); break; case CenterRight: a = GL2PS_TEXT_CR; start += Triple(-gap,0,0); break; case BottomCenter: a = GL2PS_TEXT_B; start += Triple(0,gap,0); break; case BottomLeft: a = GL2PS_TEXT_BL; start += Triple(gap,gap,0); break; case BottomRight: a = GL2PS_TEXT_BR; start += Triple(-gap,gap,0); break; case TopCenter: a = GL2PS_TEXT_T; start += Triple(0,-gap,0); break; case TopLeft: a = GL2PS_TEXT_TL; start += Triple(gap,-gap,0); break; case TopRight: a = GL2PS_TEXT_TR; start += Triple(-gap,-gap,0); break; default: break; } ViewPort2World(vp[0], vp[1], vp[2], start.x, start.y, start.z); Triple adjpos(vp[0],vp[1],vp[2]); glRasterPos3d(adjpos.x, adjpos.y, adjpos.z); ret = gl2psTextOpt(str, fontname, (int)fontsize, a, 0); glColor4dv(fcol); glClearColor(bcol[0], bcol[1], bcol[2], bcol[3]); return ret; } void Qwt3D::setDevicePolygonOffset(GLfloat factor, GLfloat units) { glPolygonOffset(factor, units); gl2psEnable(GL2PS_POLYGON_OFFSET_FILL); } qwtplot3d-0.2.7+svn191/src/qwt3d_color.cpp0000644000203200020320000000221510663257610017601 0ustar gudjongudjon#include "qwt3d_color.h" #include "qwt3d_plot.h" using namespace Qwt3D; StandardColor::StandardColor(Plot3D* data, unsigned size) : data_(data) { Q_ASSERT(data_); reset(size); } void StandardColor::reset(unsigned size) { colors_ = ColorVector(size); RGBA elem; double dsize = size; for (unsigned int i=0; i!=size; ++i) { elem.r = i / dsize; elem.g = i / dsize / 4; elem.b = 1 - i/dsize; elem.a = 1.0; colors_[i] = elem; } } /** Assigns a new ColorVector (Also overwrites the constructors size argument) */ void StandardColor::setColorVector(ColorVector const& cv) { colors_ = cv; } void StandardColor::setAlpha(double a) { if (a<0 || a>1) return; RGBA elem; for (unsigned int i=0; i!=colors_.size(); ++i) { elem = colors_[i]; elem.a = a; colors_[i] = elem; } } RGBA StandardColor::operator()(double, double, double z) const { Q_ASSERT(data_); int index = (int)((colors_.size()-1) * (z - data_->hull().minVertex.z) / (data_->hull().maxVertex.z-data_->hull().minVertex.z)); if (index < 0) index = 0; if ((unsigned int)index > colors_.size() - 1) index = (int)(colors_.size() - 1); return colors_[index]; } qwtplot3d-0.2.7+svn191/src/qwt3d_plot.cpp0000644000203200020320000002613210663257610017445 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4305 ) #pragma warning ( disable : 4786 ) #endif #include "qwt3d_plot.h" #include "qwt3d_enrichment.h" using namespace Qwt3D; /*! This should be the first call in your derived classes constructors. */ #if QT_VERSION < 0x040000 Plot3D::Plot3D( QWidget* parent, const char* name ) : QGLWidget( parent, name ) #else Plot3D::Plot3D( QWidget * parent, const QGLWidget * shareWidget) : QGLWidget( parent, shareWidget) #endif { initializedGL_ = false; renderpixmaprequest_ = false; xRot_ = yRot_ = zRot_ = 0.0; // default object rotation xShift_ = yShift_ = zShift_ = xVPShift_ = yVPShift_ = 0.0; xScale_ = yScale_ = zScale_ = 1.0; zoom_ = 1; ortho_ = true; plotstyle_ = FILLEDMESH; userplotstyle_p = 0; shading_ = GOURAUD; floorstyle_ = NOFLOOR; isolines_ = 10; displaylegend_ = false; smoothdatamesh_p = false; actualData_p = 0; lastMouseMovePosition_ = QPoint(0,0); mpressed_ = false; mouse_input_enabled_ = true; setPolygonOffset(0.5); setMeshColor(RGBA(0.0,0.0,0.0)); setMeshLineWidth(1); setBackgroundColor(RGBA(1.0,1.0,1.0,1.0)); displaylists_p = std::vector(DisplayListSize); for (unsigned k=0; k!=displaylists_p.size(); ++k) { displaylists_p[k] = 0; } datacolor_p = new StandardColor(this, 100); title_.setFont("Courier", 16, QFont::Bold); title_.setString(""); setTitlePosition(0.95); kbd_input_enabled_ = true; #if QT_VERSION < 0x040000 setFocusPolicy(QWidget::StrongFocus); assignMouse(Qt::LeftButton, Qt::LeftButton | Qt::ShiftButton, Qt::LeftButton, Qt::LeftButton | Qt::AltButton, Qt::LeftButton | Qt::AltButton, Qt::LeftButton | Qt::AltButton | Qt::ShiftButton, Qt::LeftButton | Qt::AltButton | Qt::ControlButton, Qt::LeftButton | Qt::ControlButton, Qt::LeftButton | Qt::ControlButton); assignKeyboard(Qt::Key_Down, Qt::Key_Up, Qt::ShiftButton + Qt::Key_Right, Qt::ShiftButton + Qt::Key_Left, Qt::Key_Right, Qt::Key_Left, Qt::AltButton + Qt::Key_Right, Qt::AltButton + Qt::Key_Left, Qt::AltButton + Qt::Key_Down, Qt::AltButton + Qt::Key_Up, Qt::AltButton + Qt::ShiftButton + Qt::Key_Down, Qt::AltButton + Qt::ShiftButton + Qt::Key_Up, Qt::AltButton + Qt::ControlButton + Qt::Key_Down, Qt::AltButton + Qt::ControlButton + Qt::Key_Up, Qt::ControlButton + Qt::Key_Right, Qt::ControlButton + Qt::Key_Left, Qt::ControlButton + Qt::Key_Down, Qt::ControlButton + Qt::Key_Up ); #else setFocusPolicy(Qt::StrongFocus); assignMouse(Qt::LeftButton, MouseState(Qt::LeftButton, Qt::ShiftModifier), Qt::LeftButton, MouseState(Qt::LeftButton, Qt::AltModifier), MouseState(Qt::LeftButton, Qt::AltModifier), MouseState(Qt::LeftButton, Qt::AltModifier | Qt::ShiftModifier), MouseState(Qt::LeftButton, Qt::AltModifier | Qt::ControlModifier), MouseState(Qt::LeftButton, Qt::ControlModifier), MouseState(Qt::LeftButton, Qt::ControlModifier) ); assignKeyboard(Qt::Key_Down, Qt::Key_Up, KeyboardState(Qt::Key_Right, Qt::ShiftModifier), KeyboardState(Qt::Key_Left, Qt::ShiftModifier), Qt::Key_Right, Qt::Key_Left, KeyboardState(Qt::Key_Right, Qt::AltModifier), KeyboardState(Qt::Key_Left, Qt::AltModifier), KeyboardState(Qt::Key_Down, Qt::AltModifier), KeyboardState(Qt::Key_Up, Qt::AltModifier), KeyboardState(Qt::Key_Down, Qt::AltModifier|Qt::ShiftModifier), KeyboardState(Qt::Key_Up, Qt::AltModifier|Qt::ShiftModifier), KeyboardState(Qt::Key_Down, Qt::AltModifier|Qt::ControlModifier), KeyboardState(Qt::Key_Up, Qt::AltModifier|Qt::ControlModifier), KeyboardState(Qt::Key_Right, Qt::ControlModifier), KeyboardState(Qt::Key_Left, Qt::ControlModifier), KeyboardState(Qt::Key_Down, Qt::ControlModifier), KeyboardState(Qt::Key_Up, Qt::ControlModifier) ); #endif setKeySpeed(3,5,5); legend_.setLimits(0, 100); legend_.setMajors(10); legend_.setMinors(2); legend_.setOrientation(ColorLegend::BottomTop, ColorLegend::Left); lighting_enabled_ = false; disableLighting(); lights_ = std::vector(8); } /*! Release allocated resources */ Plot3D::~Plot3D() { makeCurrent(); SaveGlDeleteLists( displaylists_p[0], displaylists_p.size() ); datacolor_p->destroy(); delete userplotstyle_p; for (ELIT it = elist_p.begin(); it!=elist_p.end(); ++it) delete (*it); elist_p.clear(); } /*! Set up the OpenGL rendering state */ void Plot3D::initializeGL() { glEnable( GL_BLEND ); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); // Set up the lights disableLighting(); GLfloat whiteAmb[4] = {1.0, 1.0, 1.0, 1.0}; setLightShift(0, 0, 3000); glEnable(GL_COLOR_MATERIAL); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, whiteAmb); setMaterialComponent(GL_DIFFUSE, 1.0); setMaterialComponent(GL_SPECULAR, 0.3); setMaterialComponent(GL_SHININESS, 5.0); setLightComponent(GL_DIFFUSE, 1.0); setLightComponent(GL_SPECULAR, 1.0); initializedGL_ = true; if (renderpixmaprequest_) { updateData(); renderpixmaprequest_ = false; } } /*! Paint the widgets content. */ void Plot3D::paintGL() { glClearColor(bgcolor_.r, bgcolor_.g, bgcolor_.b, bgcolor_.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); applyLights(); glRotatef( -90, 1.0, 0.0, 0.0 ); glRotatef( 0.0, 0.0, 1.0, 0.0 ); glRotatef( 0.0, 0.0, 0.0, 1.0 ); if (displaylegend_) { legend_.draw(); } title_.setRelPosition(titlerel_, titleanchor_); title_.draw(); Triple beg = coordinates_p.first(); Triple end = coordinates_p.second(); Triple center = beg + (end-beg) / 2; double radius = (center-beg).length(); glLoadIdentity(); glRotatef( xRot_-90, 1.0, 0.0, 0.0 ); glRotatef( yRot_, 0.0, 1.0, 0.0 ); glRotatef( zRot_, 0.0, 0.0, 1.0 ); glScalef( zoom_ * xScale_, zoom_ * yScale_, zoom_ * zScale_ ); glTranslatef(xShift_-center.x, yShift_-center.y, zShift_-center.z); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); if (beg != end) { if (ortho_) { glOrtho( -radius, +radius, -radius, +radius, 0, 40 * radius); } else { glFrustum( -radius, +radius, -radius, +radius, 5 * radius, 400 * radius ); } } else { if (ortho_) glOrtho( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); else glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); } glTranslatef( xVPShift_ * 2 * radius , yVPShift_ * 2 * radius , -7 * radius ); if (lighting_enabled_) glEnable(GL_NORMALIZE); for (unsigned i=0; i!= displaylists_p.size(); ++i) { if (i!=LegendObject) glCallList( displaylists_p[i] ); } coordinates_p.draw(); if (lighting_enabled_) glDisable(GL_NORMALIZE); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); } /*! Set up the OpenGL view port */ void Plot3D::resizeGL( int w, int h ) { glViewport( 0, 0, w, h ); paintGL(); } /*! Reimplemented from QGLWidget */ QPixmap Plot3D::renderPixmap(int w/* =0 */, int h/* =0 */, bool useContext/* =false */) { renderpixmaprequest_ = true; return QGLWidget::renderPixmap(w,h,useContext); } /*! Create a coordinate system with generating corners beg and end */ void Plot3D::createCoordinateSystem( Triple beg, Triple end ) { if (beg != coordinates_p.first() || end != coordinates_p.second()) coordinates_p.init(beg, end); } /*! Create a coordinate system from data */ void Plot3D::createCoordinateSystem() { calculateHull(); Triple beg = hull().minVertex; // Irix 6.5 compiler bug Triple end = hull().maxVertex; createCoordinateSystem(beg, end); } /*! Show a color legend */ void Plot3D::showColorLegend( bool show ) { displaylegend_ = show; if (show) datacolor_p->createVector(legend_.colors); updateGL(); } void Plot3D::setMeshColor(RGBA rgba) { meshcolor_ = rgba; } void Plot3D::setBackgroundColor(RGBA rgba) { bgcolor_ = rgba; } /*! assign a new coloring object for the data. */ void Plot3D::setDataColor( Color* col ) { Q_ASSERT(datacolor_p); datacolor_p->destroy(); datacolor_p = col; } /*! Set up ortogonal or perspective mode and updates widget */ void Plot3D::setOrtho( bool val ) { if (val == ortho_) return; ortho_ = val; updateGL(); emit projectionChanged(val); } /*! Set style of coordinate system */ void Plot3D::setCoordinateStyle(COORDSTYLE st) { coordinates_p.setStyle(st); updateGL(); } /*! Set plotstyle for the standard plotting types. An argument of value Qwt3D::USER is ignored. */ void Plot3D::setPlotStyle( PLOTSTYLE val ) { if (val == Qwt3D::USER) return; delete userplotstyle_p; userplotstyle_p = 0; plotstyle_ = val; } /*! Set plotstyle to Qwt3D::USER and an associated enrichment object. */ Qwt3D::Enrichment* Plot3D::setPlotStyle( Qwt3D::Enrichment const& obj ) { if (&obj == userplotstyle_p) return userplotstyle_p; delete userplotstyle_p; userplotstyle_p = obj.clone(); plotstyle_ = Qwt3D::USER; return userplotstyle_p; } /*! Set shading style */ void Plot3D::setShading( SHADINGSTYLE val ) { if (val == shading_) return; shading_ = val; switch (shading_) { case FLAT: glShadeModel(GL_FLAT); break; case GOURAUD: glShadeModel(GL_SMOOTH); break; default: break; } updateGL(); } /*! Set number of isolines. The lines are equidistant between minimal and maximal Z value */ void Plot3D::setIsolines(int steps) { if (steps < 0) return; isolines_ = steps; } /*! Set Polygon offset. The function affects the OpenGL rendering process. Try different values for surfaces with polygons only and with mesh and polygons */ void Plot3D::setPolygonOffset( double val ) { polygonOffset_ = val; } void Plot3D::setMeshLineWidth( double val ) { Q_ASSERT(val>=0); if (val < 0) return; meshLineWidth_ = val; } /*! Set relative caption position (0.5,0.5) means, the anchor point lies in the center of the screen */ void Plot3D::setTitlePosition(double rely, double relx, Qwt3D::ANCHOR anchor) { titlerel_.y = (rely<0 || rely>1) ? 0.5 : rely; titlerel_.x = (relx<0 || relx>1) ? 0.5 : relx; titleanchor_ = anchor; } /*! Set caption font */ void Plot3D::setTitleFont(const QString& family, int pointSize, int weight, bool italic) { title_.setFont(family, pointSize, weight, italic); } Enrichment* Plot3D::addEnrichment(Enrichment const& e) { if ( elist_p.end() == std::find( elist_p.begin(), elist_p.end(), &e ) ) elist_p.push_back(e.clone()); return elist_p.back(); } bool Plot3D::degrade(Enrichment* e) { ELIT it = std::find(elist_p.begin(), elist_p.end(), e); if ( it != elist_p.end() ) { delete (*it); elist_p.erase(it); return true; } return false; } void Plot3D::createEnrichments() { for (ELIT it = elist_p.begin(); it!=elist_p.end(); ++it) { this->createEnrichment(**it); } } /*! Update OpenGL data representation */ void Plot3D::updateData() { makeCurrent(); GLStateBewarer dt(GL_DEPTH_TEST, true); GLStateBewarer ls(GL_LINE_SMOOTH, true); calculateHull(); SaveGlDeleteLists(displaylists_p[DataObject], 1); // nur Daten displaylists_p[DataObject] = glGenLists(1); glNewList(displaylists_p[DataObject], GL_COMPILE); this->createEnrichments(); this->createData(); glEndList(); } qwtplot3d-0.2.7+svn191/src/qwt3d_label.cpp0000644000203200020320000001321010663257610017537 0ustar gudjongudjon#include #include "qwt3d_label.h" using namespace Qwt3D; bool Label::devicefonts_ = false; Label::Label() { init(); } Label::Label(const QString & family, int pointSize, int weight, bool italic) { init(family, pointSize, weight, italic); } void Label::init(const QString & family, int pointSize, int weight, bool italic) { init(); font_ = QFont(family, pointSize, weight, italic ); } void Label::init() { beg_ = Triple(0.0, 0.0, 0.0); end_ = beg_; pos_ = beg_; setColor(0,0,0); pm_ = QPixmap(0, 0); font_ = QFont(); anchor_ = BottomLeft; gap_ = 0; flagforupdate_ = true; } void Label::useDeviceFonts(bool val) { devicefonts_ = val; } void Label::setFont(const QString & family, int pointSize, int weight, bool italic) { font_ = QFont(family, pointSize, weight, italic ); flagforupdate_ = true; } void Label::setString(QString const& s) { text_ = s; flagforupdate_ = true; } void Label::setColor(double r, double g, double b, double a) { Drawable::setColor(r,g,b,a); flagforupdate_ = true; } void Label::setColor(Qwt3D::RGBA rgba) { Drawable::setColor(rgba); flagforupdate_ = true; } /** example: \verbatim Anchor TopCenter (*) resp. BottomRight(X) +----*----+ | Pixmap | +---------X \endverbatim */ void Label::setPosition(Triple pos, ANCHOR a) { anchor_ = a; pos_ = pos; } void Label::setRelPosition(Tuple rpos, ANCHOR a) { double ot = 0.99; getMatrices(modelMatrix, projMatrix, viewport); beg_ = relativePosition(Triple(rpos.x, rpos.y, ot)); setPosition(beg_, a); } void Label::update() { QPainter p; QFontMetrics fm(font_); QFontInfo info(font_); QRect r = QRect(QPoint(0,0),fm.size(Qwt3D::SingleLine, text_));//fm.boundingRect(text_) misbehaviour under linux; #if QT_VERSION < 0x040000 r.moveBy(0, -r.top()); #else r.translate(0, -r.top()); #endif pm_ = QPixmap(r.width(), r.bottom()); if (pm_.isNull()) // else crash under linux { r = QRect(QPoint(0,0),fm.size(Qwt3D::SingleLine, QString(" "))); // draw empty space else //todo #if QT_VERSION < 0x040000 r.moveBy(0, -r.top()); #else r.translate(0, -r.top()); #endif pm_ = QPixmap(r.width(), r.bottom()); } QBitmap bm(pm_.width(),pm_.height()); #if QT_VERSION >= 0x040000 && defined(Q_WS_X11) bm.fill(Qt::white); p.begin( &bm ); p.setPen(Qt::black); p.setFont(font_); p.drawText(0,r.height() - fm.descent() -1 , text_); p.end(); pm_.setMask(bm); // avoids uninitialized areas in some cases pm_.fill(Qt::white); p.begin( &pm_ ); p.setFont( font_ ); p.setPen( Qt::SolidLine ); p.setPen( GL2Qt(color.r, color.g, color.b) ); p.drawText(0,r.height() - fm.descent() -1 , text_); p.end(); buf_ = pm_.toImage(); #else bm.fill(Qt::color0); p.begin( &bm ); p.setPen(Qt::color1); p.setFont(font_); p.drawText(0,r.height() - fm.descent() -1 , text_); p.end(); pm_.setMask(bm); // avoids uninitialized areas in some cases #if QT_VERSION < 0x040000 pm_.fill(); #endif p.begin( &pm_ ); p.setFont( font_ ); p.setPen( Qt::SolidLine ); p.setPen( GL2Qt(color.r, color.g, color.b) ); p.drawText(0,r.height() - fm.descent() -1 , text_); p.end(); #endif #if QT_VERSION < 0x040000 buf_ = pm_.convertToImage(); #else buf_ = pm_.toImage(); #endif tex_ = QGLWidget::convertToGLFormat( buf_ ); // flipped 32bit RGBA ? } /** Adds an additional shift to the anchor point. This happens in a more or less intelligent manner depending on the nature of the anchor: \verbatim anchor type shift left aligned --> right aligned <-- top aligned top-down bottom aligned bottom-up \endverbatim The unit is user space dependend (one pixel on screen - play around to get satisfying results) */ void Label::adjust(int gap) { gap_ = gap; } void Label::convert2screen() { Triple start = World2ViewPort(pos_); switch (anchor_) { case BottomLeft : beg_ = pos_; break; case BottomRight: beg_ = ViewPort2World(start - Triple(width() + gap_, 0, 0)); break; case BottomCenter: beg_ = ViewPort2World(start - Triple(width() / 2, -gap_, 0)); break; case TopRight: beg_ = ViewPort2World(start - Triple(width() + gap_, height(), 0)); break; case TopLeft: beg_ = ViewPort2World(start - Triple(-gap_, height(), 0)); break; case TopCenter: beg_ = ViewPort2World(start - Triple(width() / 2, height() + gap_, 0)); break; case CenterLeft: beg_ = ViewPort2World(start - Triple(-gap_, height() / 2, 0)); break; case CenterRight: beg_ = ViewPort2World(start - Triple(width() + gap_, height() / 2, 0)); break; case Center: beg_ = ViewPort2World(start - Triple(width() / 2, height() / 2, 0)); break; default: break; } start = World2ViewPort(beg_); end_ = ViewPort2World(start + Triple(width(), height(), 0)); } void Label::draw() { if (flagforupdate_) { update(); flagforupdate_ = false; } if (buf_.isNull()) return; GLboolean b; GLint func; GLdouble v; glGetBooleanv(GL_ALPHA_TEST, &b); glGetIntegerv(GL_ALPHA_TEST_FUNC, &func); glGetDoublev(GL_ALPHA_TEST_REF, &v); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_NOTEQUAL, 0.0); convert2screen(); glRasterPos3d(beg_.x, beg_.y, beg_.z); int w = tex_.width(); int h = tex_.height(); if (devicefonts_) { drawDeviceText(QWT3DLOCAL8BIT(text_), "Courier", font_.pointSize(), pos_, color, anchor_, gap_); } else { drawDevicePixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, tex_.bits()); // glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, tex_.bits()); } glAlphaFunc(func,v); Enable(GL_ALPHA_TEST, b); } double Label::width() const { return pm_.width(); } double Label::height() const { return pm_.height(); } qwtplot3d-0.2.7+svn191/src/qwt3d_drawable.cpp0000644000203200020320000000605310663257610020250 0ustar gudjongudjon#include "qwt3d_drawable.h" using namespace Qwt3D; Drawable::~Drawable() { detachAll(); } void Drawable::saveGLState() { glGetBooleanv(GL_LINE_SMOOTH, &ls); glGetBooleanv(GL_POLYGON_SMOOTH, &pols); glGetFloatv(GL_LINE_WIDTH, &lw); glGetIntegerv(GL_BLEND_SRC, &blsrc); glGetIntegerv(GL_BLEND_DST, &bldst); glGetDoublev(GL_CURRENT_COLOR, col); glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &pattern); glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &factor); glGetBooleanv(GL_LINE_STIPPLE, &sallowed); glGetBooleanv(GL_TEXTURE_2D, &tex2d); glGetIntegerv(GL_POLYGON_MODE, polmode); glGetIntegerv(GL_MATRIX_MODE, &matrixmode); glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &poloffs[0]); glGetFloatv(GL_POLYGON_OFFSET_UNITS, &poloffs[1]); glGetBooleanv(GL_POLYGON_OFFSET_FILL, &poloffsfill); } void Drawable::restoreGLState() { Enable(GL_LINE_SMOOTH, ls); Enable(GL_POLYGON_SMOOTH, pols); setDeviceLineWidth(lw); glBlendFunc(blsrc, bldst); glColor4dv(col); glLineStipple(factor,pattern); Enable(GL_LINE_STIPPLE,sallowed); Enable(GL_TEXTURE_2D,tex2d); glPolygonMode(polmode[0], polmode[1]); glMatrixMode(matrixmode); glPolygonOffset(poloffs[0], poloffs[1]); setDevicePolygonOffset(poloffs[0], poloffs[1]); Enable(GL_POLYGON_OFFSET_FILL, poloffsfill); } void Drawable::Enable(GLenum what, GLboolean val) { if (val) glEnable(what); else glDisable(what); } void Drawable::attach(Drawable* dr) { if ( dlist.end() == std::find( dlist.begin(), dlist.end(), dr ) ) if (dr) { dlist.push_back(dr); } } void Drawable::detach(Drawable* dr) { std::list::iterator it = std::find(dlist.begin(), dlist.end(), dr); if ( it != dlist.end() ) { dlist.erase(it); } } void Drawable::detachAll() { dlist.clear(); } //! simplified glut routine (glUnProject): windows coordinates_p --> object coordinates_p /** Don't rely on (use) this in display lists ! */ Triple Drawable::ViewPort2World(Triple win, bool* err) { Triple obj; getMatrices(modelMatrix, projMatrix, viewport); int res = gluUnProject(win.x, win.y, win.z, modelMatrix, projMatrix, viewport, &obj.x, &obj.y, &obj.z); if (err) *err = (res) ? false : true; return obj; } //! simplified glut routine (glProject): object coordinates_p --> windows coordinates_p /** Don't rely on (use) this in display lists ! */ Triple Drawable::World2ViewPort(Triple obj, bool* err) { Triple win; getMatrices(modelMatrix, projMatrix, viewport); int res = gluProject(obj.x, obj.y, obj.z, modelMatrix, projMatrix, viewport, &win.x, &win.y, &win.z); if (err) *err = (res) ? false : true; return win; } /** Don't rely on (use) this in display lists ! */ Triple Drawable::relativePosition(Triple rel) { return ViewPort2World(Triple((rel.x-viewport[0])*viewport[2],(rel.y-viewport[1])*viewport[3],rel.z)); } void Drawable::draw() { saveGLState(); for (std::list::iterator it = dlist.begin(); it!=dlist.end(); ++it) { (*it)->draw(); } restoreGLState(); } void Drawable::setColor(double r, double g, double b, double a) { color = RGBA(r,g,b,a); } void Drawable::setColor(RGBA rgba) { color = rgba; } qwtplot3d-0.2.7+svn191/src/qwt3d_gridplot.cpp0000644000203200020320000003661310663257610020320 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4305 ) #pragma warning ( disable : 4786 ) #endif #include "qwt3d_surfaceplot.h" #include "qwt3d_enrichment_std.h" using namespace std; using namespace Qwt3D; void SurfacePlot::createDataG() { createFloorData(); if (plotStyle() == NOPLOT) return; int i, j; RGBA col; int step = resolution(); if (plotStyle() == Qwt3D::POINTS) { createPoints(); return; } else if (plotStyle() == Qwt3D::USER) { if (userplotstyle_p) createEnrichment(*userplotstyle_p); return; } setDeviceLineWidth(meshLineWidth()); GLStateBewarer sb(GL_POLYGON_OFFSET_FILL,true); setDevicePolygonOffset(polygonOffset(),1.0); GLStateBewarer sb2(GL_LINE_SMOOTH, smoothDataMesh()); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); int lastcol = actualDataG_->columns(); int lastrow = actualDataG_->rows(); if (plotStyle() != WIREFRAME) { glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS); bool hl = (plotStyle() == HIDDENLINE); if (hl) { col = backgroundRGBAColor(); glColor4d(col.r, col.g, col.b, col.a); } for (i = 0; i < lastcol - step; i += step) { glBegin(GL_TRIANGLE_STRIP); setColorFromVertexG(i, 0, hl); glNormal3dv(actualDataG_->normals[i][0]); glVertex3dv(actualDataG_->vertices[i][0]); setColorFromVertexG(i+step, 0, hl); glNormal3dv(actualDataG_->normals[i+step][0]); glVertex3dv(actualDataG_->vertices[i+step][0]); for (j = 0; j < lastrow - step; j += step) { setColorFromVertexG(i,j+step, hl); glNormal3dv(actualDataG_->normals[i][j+step]); glVertex3dv(actualDataG_->vertices[i][j+step]); setColorFromVertexG(i+step, j+step, hl); glNormal3dv(actualDataG_->normals[i+step][j+step]); glVertex3dv(actualDataG_->vertices[i+step][j+step]); } glEnd(); } } if (plotStyle() == FILLEDMESH || plotStyle() == WIREFRAME || plotStyle() == HIDDENLINE) { glColor4d(meshColor().r, meshColor().g, meshColor().b, meshColor().a); if (step < actualDataG_->columns() && step < actualDataG_->rows()) { glBegin(GL_LINE_LOOP); for (i = 0; i < actualDataG_->columns() - step; i += step) glVertex3dv(actualDataG_->vertices[i][0]); for (j = 0; j < actualDataG_->rows() - step; j += step) glVertex3dv(actualDataG_->vertices[i][j]); for (; i >= 0; i -= step) glVertex3dv(actualDataG_->vertices[i][j]); for (; j >= 0; j -= step) glVertex3dv(actualDataG_->vertices[0][j]); glEnd(); } // weaving for (i = step; i < actualDataG_->columns() - step; i += step) { glBegin(GL_LINE_STRIP); for (j = 0; j < actualDataG_->rows(); j += step) glVertex3dv(actualDataG_->vertices[i][j]); glEnd(); } for (j = step; j < actualDataG_->rows() - step; j += step) { glBegin(GL_LINE_STRIP); for (i = 0; i < actualDataG_->columns(); i += step) glVertex3dv(actualDataG_->vertices[i][j]); glEnd(); } } } void SurfacePlot::setColorFromVertexG(int ix, int iy, bool skip) { if (skip) return; RGBA col = (*datacolor_p)( actualDataG_->vertices[ix][iy][0], actualDataG_->vertices[ix][iy][1], actualDataG_->vertices[ix][iy][2]); glColor4d(col.r, col.g, col.b, col.a); } void SurfacePlot::createNormalsG() { if (!normals() || actualDataG_->empty()) return; Arrow arrow; arrow.setQuality(normalQuality()); Triple basev, topv, norm; int step = resolution(); double diag = (actualDataG_->hull().maxVertex-actualDataG_->hull().minVertex).length() * normalLength(); arrow.assign(*this); arrow.drawBegin(); for (int i = 0; i <= actualDataG_->columns() - step; i += step) { for (int j = 0; j <= actualDataG_->rows() - step; j += step) { basev = Triple(actualDataG_->vertices[i][j][0],actualDataG_->vertices[i][j][1],actualDataG_->vertices[i][j][2]); topv = Triple(actualDataG_->vertices[i][j][0]+actualDataG_->normals[i][j][0], actualDataG_->vertices[i][j][1]+actualDataG_->normals[i][j][1], actualDataG_->vertices[i][j][2]+actualDataG_->normals[i][j][2]); norm = topv-basev; norm.normalize(); norm *= diag; arrow.setTop(basev+norm); arrow.setColor((*datacolor_p)(basev.x,basev.y,basev.z)); arrow.draw(basev); } } arrow.drawEnd(); } void SurfacePlot::readIn(GridData& gdata, Triple** data, unsigned int columns, unsigned int rows) { gdata.setSize(columns,rows); ParallelEpiped range(Triple(DBL_MAX,DBL_MAX,DBL_MAX),Triple(-DBL_MAX,-DBL_MAX,-DBL_MAX)); /* fill out the vertex array for the mesh. */ for (unsigned i = 0; i != columns; ++i) { for (unsigned j = 0; j != rows; ++j) { gdata.vertices[i][j][0] = data[i][j].x; gdata.vertices[i][j][1] = data[i][j].y; gdata.vertices[i][j][2] = data[i][j].z; if (data[i][j].x > range.maxVertex.x) range.maxVertex.x = data[i][j].x; if (data[i][j].y > range.maxVertex.y) range.maxVertex.y = data[i][j].y; if (data[i][j].z > range.maxVertex.z) range.maxVertex.z = data[i][j].z; if (data[i][j].x < range.minVertex.x) range.minVertex.x = data[i][j].x; if (data[i][j].y < range.minVertex.y) range.minVertex.y = data[i][j].y; if (data[i][j].z < range.minVertex.z) range.minVertex.z = data[i][j].z; } } gdata.setHull(range); } void SurfacePlot::readIn(GridData& gdata, double** data, unsigned int columns, unsigned int rows , double minx, double maxx, double miny, double maxy) { gdata.setPeriodic(false,false); gdata.setSize(columns,rows); double dx = (maxx - minx) / (gdata.columns() - 1); double dy = (maxy - miny) / (gdata.rows() - 1); double tmin = DBL_MAX; double tmax = -DBL_MAX; /* fill out the vertex array for the mesh. */ for (unsigned i = 0; i != columns; ++i) { for (unsigned j = 0; j != rows; ++j) { gdata.vertices[i][j][0] = minx + i*dx; gdata.vertices[i][j][1] = miny + j*dy; gdata.vertices[i][j][2] = data[i][j]; if (data[i][j] > tmax) tmax = data[i][j]; if (data[i][j] < tmin) tmin = data[i][j]; } } ParallelEpiped hull = ParallelEpiped( Triple( gdata.vertices[0][0][0], gdata.vertices[0][0][1], tmin ), Triple( gdata.vertices[gdata.columns()-1][gdata.rows()-1][0], gdata.vertices[gdata.columns()-1][gdata.rows()-1][1], tmax ) ); gdata.setHull(hull); } void SurfacePlot::calcNormals(GridData& gdata) { unsigned int rows = gdata.rows(); unsigned int columns = gdata.columns(); // normals Triple u, v, n; // for cross product for (unsigned i = 0; i != columns; ++i) { for (unsigned j = 0; j != rows; ++j) { n = Triple(0,0,0); if (i0 && j0 && j>0) { u = Triple( gdata.vertices[i-1][j][0] - gdata.vertices[i][j][0], gdata.vertices[i-1][j][1] - gdata.vertices[i][j][1], gdata.vertices[i-1][j][2] - gdata.vertices[i][j][2] ); v = Triple( gdata.vertices[i][j-1][0] - gdata.vertices[i][j][0], gdata.vertices[i][j-1][1] - gdata.vertices[i][j][1], gdata.vertices[i][j-1][2] - gdata.vertices[i][j][2] ); n += normalizedcross(u,v); } if (i0) { u = Triple( gdata.vertices[i][j-1][0] - gdata.vertices[i][j][0], gdata.vertices[i][j-1][1] - gdata.vertices[i][j][1], gdata.vertices[i][j-1][2] - gdata.vertices[i][j][2] ); v = Triple( gdata.vertices[i+1][j][0] - gdata.vertices[i][j][0], gdata.vertices[i+1][j][1] - gdata.vertices[i][j][1], gdata.vertices[i+1][j][2] - gdata.vertices[i][j][2] ); n += normalizedcross(u,v); } n.normalize(); gdata.normals[i][j][0] = n.x; gdata.normals[i][j][1] = n.y; gdata.normals[i][j][2] = n.z; } } } void SurfacePlot::sewPeriodic(GridData& gdata) { // sewing Triple n; unsigned int columns = gdata.columns(); unsigned int rows = gdata.rows(); if (gdata.uperiodic()) { for (unsigned i = 0; i != columns; ++i) { n = Triple( gdata.normals[i][0][0] + gdata.normals[i][rows-1][0], gdata.normals[i][0][1] + gdata.normals[i][rows-1][1], gdata.normals[i][0][2] + gdata.normals[i][rows-1][2] ); n.normalize(); gdata.normals[i][0][0] = gdata.normals[i][rows-1][0] = n.x; gdata.normals[i][0][1] = gdata.normals[i][rows-1][1] = n.y; gdata.normals[i][0][2] = gdata.normals[i][rows-1][2] = n.z; } } if (gdata.vperiodic()) { for (unsigned j = 0; j != rows; ++j) { n = Triple( gdata.normals[0][j][0] + gdata.normals[columns-1][j][0], gdata.normals[0][j][1] + gdata.normals[columns-1][j][1], gdata.normals[0][j][2] + gdata.normals[columns-1][j][2] ); n.normalize(); gdata.normals[0][j][0] = gdata.normals[columns-1][j][0] = n.x; gdata.normals[0][j][1] = gdata.normals[columns-1][j][1] = n.y; gdata.normals[0][j][2] = gdata.normals[columns-1][j][2] = n.z; } } } /*! Convert user grid data to internal vertex structure. See also NativeReader::read() and Function::create() */ bool SurfacePlot::loadFromData(Triple** data, unsigned int columns, unsigned int rows, bool uperiodic, bool vperiodic) { actualDataC_->clear(); actualData_p = actualDataG_; readIn(*actualDataG_, data, columns, rows); calcNormals(*actualDataG_); actualDataG_->setPeriodic(uperiodic,vperiodic); sewPeriodic(*actualDataG_); updateData(); updateNormals(); createCoordinateSystem(); return true; } /*! Convert user grid data to internal vertex structure. See also NativeReader::read() and Function::create() */ bool SurfacePlot::loadFromData(double** data, unsigned int columns, unsigned int rows , double minx, double maxx, double miny, double maxy) { actualDataC_->clear(); actualData_p = actualDataG_; actualDataG_->setPeriodic(false,false); actualDataG_->setSize(columns,rows); readIn(*actualDataG_,data,columns,rows,minx,maxx,miny,maxy); calcNormals(*actualDataG_); updateData(); updateNormals(); createCoordinateSystem(); return true; } void SurfacePlot::createFloorDataG() { switch (floorStyle()) { case FLOORDATA: Data2FloorG(); break; case FLOORISO: Isolines2FloorG(); break; default: break; } } void SurfacePlot::Data2FloorG() { if (actualData_p->empty()) return; int step = resolution(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS); double zshift = actualData_p->hull().minVertex.z; for (int i = 0; i < actualDataG_->columns() - step; i += step) { glBegin(GL_TRIANGLE_STRIP); setColorFromVertexG(i, 0); glVertex3d(actualDataG_->vertices[i][0][0], actualDataG_->vertices[i][0][1], zshift); setColorFromVertexG(i+step, 0); glVertex3d(actualDataG_->vertices[i+step][0][0],actualDataG_->vertices[i+step][0][1], zshift); for (int j = 0; j < actualDataG_->rows() - step; j += step) { setColorFromVertexG(i, j+step); glVertex3d(actualDataG_->vertices[i][j+step][0],actualDataG_->vertices[i][j+step][1], zshift); setColorFromVertexG(i+step, j+step); glVertex3d(actualDataG_->vertices[i+step][j+step][0],actualDataG_->vertices[i+step][j+step][1], zshift); } glEnd(); } } void SurfacePlot::Isolines2FloorG() { if (isolines() <= 0 || actualData_p->empty()) return; double count = (actualData_p->hull().maxVertex.z - actualData_p->hull().minVertex.z) / isolines(); RGBA col; int step = resolution(); double zshift = actualData_p->hull().minVertex.z; int cols = actualDataG_->columns(); int rows = actualDataG_->rows(); Triple t[4]; vector intersection; double lambda = 0; GLStateBewarer sb2(GL_LINE_SMOOTH, false); for (int k = 0; k != isolines(); ++k) { double val = zshift + k * count; for (int i = 0; i < cols-step; i += step) { for (int j = 0; j < rows-step; j += step) { t[0] = Triple( actualDataG_->vertices[i][j][0], actualDataG_->vertices[i][j][1], actualDataG_->vertices[i][j][2]); col = (*datacolor_p)(t[0].x,t[0].y,t[0].z); glColor4d(col.r, col.g, col.b, col.a); // glColor4d(0,0,0,1); t[1] = Triple( actualDataG_->vertices[i+step][j][0], actualDataG_->vertices[i+step][j][1], actualDataG_->vertices[i+step][j][2]); t[2] = Triple( actualDataG_->vertices[i+step][j+step][0], actualDataG_->vertices[i+step][j+step][1], actualDataG_->vertices[i+step][j+step][2]); t[3] = Triple( actualDataG_->vertices[i][j+step][0], actualDataG_->vertices[i][j+step][1], actualDataG_->vertices[i][j+step][2]); double diff = 0; for (int m = 0; m!=4; ++m) { int mm = (m+1)%4; if ((val>=t[m].z && val<=t[mm].z) || (val>=t[mm].z && val<=t[m].z)) { diff = t[mm].z - t[m].z; if (isPracticallyZero(diff)) // degenerated { intersection.push_back(t[m]); intersection.push_back(t[mm]); continue; } lambda = (val - t[m].z) / diff; intersection.push_back(Triple(t[m].x + lambda * (t[mm].x-t[m].x), t[m].y + lambda * (t[mm].y-t[m].y), val)); } } if (!intersection.empty()) { if (intersection.size()>2) { glBegin(GL_LINE_STRIP); for (unsigned dd = 0; dd!=intersection.size(); ++dd) { glVertex3d(intersection[dd].x, intersection[dd].y, zshift); } glEnd(); glBegin(GL_POINTS); glVertex3d(intersection[0].x,intersection[0].y,zshift); glEnd(); } else if (intersection.size() == 2) { glBegin(GL_LINES); glVertex3d(intersection[0].x,intersection[0].y,zshift); glVertex3d(intersection[1].x,intersection[1].y,zshift); // small pixel gap problem (see OpenGL spec.) glVertex3d(intersection[1].x,intersection[1].y,zshift); glVertex3d(intersection[0].x,intersection[0].y,zshift); glEnd(); } intersection.clear(); } } } } } /* void SurfacePlot::calcLowResolution() { if (!actualDataG_) return; int res = resolution(); if (res == 1) { lowresData_p = *actualDataG_; return; } GridData const& src = *actualDataG_; result.clear(); }*/ qwtplot3d-0.2.7+svn191/src/qwt3d_function.cpp0000644000203200020320000000333610663257610020315 0ustar gudjongudjon#include "qwt3d_surfaceplot.h" #include "qwt3d_function.h" using namespace Qwt3D; Function::Function() :GridMapping() { } Function::Function(SurfacePlot& pw) :GridMapping() { plotwidget_p = &pw; } Function::Function(SurfacePlot* pw) :GridMapping() { plotwidget_p = pw; } void Function::assign(SurfacePlot& plotWidget) { if (&plotWidget != plotwidget_p) plotwidget_p = &plotWidget; } void Function::assign(SurfacePlot* plotWidget) { if (plotWidget != plotwidget_p) plotwidget_p = plotWidget; } void Function:: setMinZ(double val) { range_p.minVertex.z = val; } void Function:: setMaxZ(double val) { range_p.maxVertex.z = val; } bool Function::create() { if ((umesh_p<=2) || (vmesh_p<=2) || !plotwidget_p) return false; /* allocate some space for the mesh */ double** data = new double* [umesh_p] ; unsigned i,j; for ( i = 0; i < umesh_p; i++) { data[i] = new double [vmesh_p]; } /* get the data */ double dx = (maxu_p - minu_p) / (umesh_p - 1); double dy = (maxv_p - minv_p) / (vmesh_p - 1); for (i = 0; i < umesh_p; ++i) { for (j = 0; j < vmesh_p; ++j) { data[i][j] = operator()(minu_p + i*dx, minv_p + j*dy); if (data[i][j] > range_p.maxVertex.z) data[i][j] = range_p.maxVertex.z; else if (data[i][j] < range_p.minVertex.z) data[i][j] = range_p.minVertex.z; } } Q_ASSERT(plotwidget_p); if (!plotwidget_p) { fprintf(stderr,"Function: no valid Plot3D Widget assigned"); } else { ((SurfacePlot*)plotwidget_p)->loadFromData(data, umesh_p, vmesh_p, minu_p, maxu_p, minv_p, maxv_p); } for ( i = 0; i < umesh_p; i++) { delete [] data[i]; } delete [] data; return true; } bool Function::create(SurfacePlot& pl) { assign(pl); return create(); } qwtplot3d-0.2.7+svn191/src/qwt3d_dataviews.cpp0000644000203200020320000000027610663257610020457 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4305 ) #pragma warning ( disable : 4786 ) #endif #include "qwt3d_plot.h" using namespace std; using namespace Qwt3D; qwtplot3d-0.2.7+svn191/src/qwt3d_scale.cpp0000644000203200020320000001435110663257610017556 0ustar gudjongudjon#include "qwt3d_scale.h" using namespace Qwt3D; Scale::Scale() : start_p(0.), stop_p(0.), majorintervals_p(0), minorintervals_p(0), mstart_p(0.), mstop_p(0.) { } /*! The function maps the double value at tic-position idx to a final representation. The default return value is simply the tic values QString representation. Overwrite this function, if you plan to transform the value in some way. See e.g. LogScale::ticLabel. \param idx the current major tic index \return The QString representation for the value corresponding to a valid index, an empty QString else. */ QString Scale::ticLabel(unsigned int idx) const { if (idxstop_p) // return; majors_p.push_back(mstart_p); // remaining tics for (i = 1; i <= majorintervals_p; ++i) { double t = double(i) / majorintervals_p; runningval = mstart_p + t * interval; if (runningval>stop_p) break; if (isPracticallyZero(mstart_p, -t*interval)) // prevent rounding errors near 0 runningval = 0.0; majors_p.push_back(runningval); } majorintervals_p = majors_p.size(); if (majorintervals_p) --majorintervals_p; // minors if (!majorintervals_p || !minorintervals_p) // no valid interval { minorintervals_p = 0; return; } // start_p mstart_p // |_____________|_____ _ _ _ double step = (majors_p[1]-majors_p[0]) / minorintervals_p; if (isPracticallyZero(step)) return; runningval = mstart_p-step; while (runningval>start_p) { minors_p.push_back(runningval); runningval -= step; } // mstart_p mstop_p // ________|_____ _ _ _ _ _ ___|__________ for (i=0; i!=majorintervals_p; ++i) { runningval = majors_p[i] + step; for (int j=0; j!=minorintervals_p; ++j) { minors_p.push_back(runningval); runningval += step; } } // mstop_p stop_p // _ _ _|_____________| runningval = mstop_p + step; while (runningval DBL_MAX_10_EXP) stop_p = DBL_MAX_10_EXP; double interval = stop_p-start_p; if (interval<=0) return; double runningval = floor(start_p); while(runningval<=stop_p) { if (runningval>=start_p) majors_p.push_back(runningval); ++runningval; } majorintervals_p = majors_p.size(); if (majorintervals_p) --majorintervals_p; if (majors_p.size()<1) // not even a single major tic { return; } // minors // start_p mstart_p // |_____________|_____ _ _ _ double k; int step; setupCounter(k,step); runningval = log10(k)+(majors_p[0]-1); while (runningval>start_p && k>1) { minors_p.push_back(runningval); k -=step; runningval = log10(k)+(majors_p[0]-1); } // mstart_p mstop_p // ________|_____ _ _ _ _ _ ___|__________ for (int i=0; i!=majorintervals_p; ++i) { setupCounter(k,step); runningval = log10(k)+(majors_p[i]); while (k>1) { minors_p.push_back(runningval); k-=step; runningval = log10(k)+(majors_p[i]); } } // mstop_p stop_p // _ _ _|_____________| setupCounter(k,step); runningval = log10(k)+(majors_p.back()); do { k-=step; runningval = log10(k)+(majors_p.back()); } while(runningval>=stop_p); while (k>1) { minors_p.push_back(runningval); k-=step; runningval = log10(k)+(majors_p.back()); } } /*! Sets the minor intervals for the logarithmic scale. Only values of 9,5,3 or 2 are accepted as arguments. They will produce mantissa sets of {2,3,4,5,6,7,8,9}, {2,4,6,8}, {2,5} or {5} respectively. */ void LogScale::setMinors(int val) { if ((val == 2) || (val == 3) || (val == 5) || (val == 9)) minorintervals_p = val; } LogScale::LogScale() { minorintervals_p = 9; } //! Returns a power of 10 associated to the major value at index idx. QString LogScale::ticLabel(unsigned int idx) const { if (idx 1 are ignored */ void SurfacePlot::setNormalLength(double val) { if (val<0 || val>1) return; normalLength_p = val; } /** Values < 3 are ignored */ void SurfacePlot::setNormalQuality(int val) { if (val<3) return; normalQuality_p = val; } /** Calculates the smallest x-y-z parallelepiped enclosing the data. It can be accessed by hull(); */ void SurfacePlot::calculateHull() { if (actualData_p->empty()) return; setHull(actualData_p->hull()); } /*! Sets data resolution (res == 1 original resolution) and updates widget If res < 1, the function does nothing */ void SurfacePlot::setResolution( int res ) { if (!actualData_p || actualData_p->datatype == Qwt3D::POLYGON) return; if ((resolution_p == res) || res < 1) return; resolution_p = res; updateNormals(); updateData(); if (initializedGL()) updateGL(); emit resolutionChanged(res); } void SurfacePlot::updateNormals() { SaveGlDeleteLists(displaylists_p[NormalObject], 1); if (plotStyle() == NOPLOT && !normals() || !actualData_p) return; displaylists_p[NormalObject] = glGenLists(1); glNewList(displaylists_p[NormalObject], GL_COMPILE); if (actualData_p->datatype == Qwt3D::POLYGON) createNormalsC(); else if (actualData_p->datatype == Qwt3D::GRID) createNormalsG(); glEndList(); } void SurfacePlot::createData() { if (!actualData_p) return; if (actualData_p->datatype == Qwt3D::POLYGON) createDataC(); else if (actualData_p->datatype == Qwt3D::GRID) createDataG(); } void SurfacePlot::createFloorData() { if (!actualData_p) return; if (actualData_p->datatype == Qwt3D::POLYGON) createFloorDataC(); else if (actualData_p->datatype == Qwt3D::GRID) createFloorDataG(); } /** The returned value is not affected by resolution(). The pair gives (columns,rows) for grid data , (number of cells,1) for free formed data (datatype() == POLYGON) and (0,0) else */ pair SurfacePlot::facets() const { if (!hasData()) return pair(0,0); if (actualData_p->datatype == Qwt3D::POLYGON) return pair(int(actualDataC_->cells.size()), 1); else if (actualData_p->datatype == Qwt3D::GRID) return pair(actualDataG_->columns(), actualDataG_->rows()); else return pair(0,0); } void SurfacePlot::createPoints() { Dot pt; createEnrichment(pt); } void SurfacePlot::createEnrichment(Enrichment& p) { if (!actualData_p) return; //todo future work if (p.type() != Enrichment::VERTEXENRICHMENT) return; p.assign(*this); p.drawBegin(); VertexEnrichment* ve = (VertexEnrichment*)&p; if (actualData_p->datatype == Qwt3D::POLYGON) { for (unsigned i = 0; i != actualDataC_->normals.size(); ++i) ve->draw(actualDataC_->nodes[i]); } else if (actualData_p->datatype == Qwt3D::GRID) { int step = resolution(); for (int i = 0; i <= actualDataG_->columns() - step; i += step) for (int j = 0; j <= actualDataG_->rows() - step; j += step) ve->draw(Triple(actualDataG_->vertices[i][j][0], actualDataG_->vertices[i][j][1], actualDataG_->vertices[i][j][2])); } p.drawEnd(); } qwtplot3d-0.2.7+svn191/src/qwt3d_io_reader.cpp0000644000203200020320000001041510663257610020415 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4786 ) #endif #include #include #include #include "qwt3d_surfaceplot.h" #include "qwt3d_io_reader.h" using namespace std; using namespace Qwt3D; const char* NativeReader::magicstring = "jk:11051895-17021986"; namespace { FILE* open(QString fname) { FILE* file = fopen(QWT3DLOCAL8BIT(fname), "r"); if (!file) { fprintf(stderr, "NativeReader::read: cannot open data file \"%s\"\n", QWT3DLOCAL8BIT(fname)); } return file; } int read_char (FILE * fp, bool skipcomments = true) { int c; if ((c = fgetc (fp)) == EOF) return (c); if (skipcomments) { if (c == '#') { do { if ((c = fgetc (fp)) == EOF) return (c); } while (c != '\n' && c != '\r'); } } return (c); } char* read_field (FILE * fp, bool skipcomments = true) { static char buf[71]; int c, i; do { if ((c = read_char (fp,skipcomments)) == EOF) return (NULL); } while (isspace (c)); for (i = 0; i < 70 && !isspace (c); ++i) { buf[i] = c; if ((c = read_char (fp,skipcomments)) == EOF) break; } buf[i] = '\0'; return (buf); } //! set to data begin bool extract_info(FILE* fp, unsigned int& xmesh, unsigned int& ymesh, double& xmin, double& xmax, double& ymin, double& ymax) { char* p; // find out the size if ((p = read_field (fp)) == 0) return false; xmesh = (unsigned int)atoi(p); if ((p = read_field (fp)) == 0) return false; ymesh = (unsigned int)atoi (p); if (xmesh < 1 || ymesh < 1) return false; // ... and the limits if ((p = read_field (fp)) == 0) return false; xmin = atof (p); if ((p = read_field (fp)) == 0) return false; xmax = atof (p); if ((p = read_field (fp)) == 0) return false; ymin = atof (p); if ((p = read_field (fp)) == 0) return false; ymax = atof (p); if (xmin > xmax || ymin > ymax) return false; return true; } //! find out what the magic string is and compare bool check_magic(FILE* fp, const char* val) { char* p; if ((p = read_field (fp,false)) == 0) return false; if (strcmp (p, val ) != 0) return false; return true; } //! find out what the type is bool check_type(FILE* fp, const char* val) { char* p; if ((p = read_field (fp)) == 0) return false; if (strcmp (p, val ) != 0) return false; return true; } double** allocateData(int columns, int rows) { double** data = new double* [columns] ; for ( int i = 0; i < columns; ++i) { data[i] = new double [rows]; } return data; } void deleteData(double**data, int columns) { for ( int i = 0; i < columns; i++) { delete [] data[i]; } delete [] data; } } NativeReader::NativeReader() : minz_(-DBL_MAX), maxz_(DBL_MAX) { } bool NativeReader::collectInfo(FILE*& file, QString const& fname, unsigned& xmesh, unsigned& ymesh, double& minx, double& maxx, double& miny, double& maxy) { if (fname.isEmpty()) return false; file = open(fname); if (!file) return false; if ( (!check_magic(file, magicstring)) ||(!check_type(file, "MESH")) ||(!extract_info(file, xmesh, ymesh, minx, maxx, miny, maxy)) ) { fclose(file); return false; } return true; } bool NativeReader::operator()(Plot3D* plot, QString const& fname) { FILE* file; unsigned int xmesh, ymesh; double minx, maxx, miny, maxy; if ( !collectInfo(file, fname, xmesh, ymesh, minx, maxx, miny, maxy) ) return false; /* allocate some space for the mesh */ double** data = allocateData(xmesh, ymesh); for (unsigned int j = 0; j < ymesh; j++) { for (unsigned int i = 0; i < xmesh; i++) { if (fscanf(file, "%lf", &data[i][j]) != 1) { fprintf(stderr, "NativeReader::read: error in data file \"%s\"\n", QWT3DLOCAL8BIT(fname)); return false; } if (data[i][j] > maxz_) data[i][j] = maxz_; else if (data[i][j] < minz_) data[i][j] = minz_; } } /* close the file */ fclose(file); ((SurfacePlot*)plot)->loadFromData(data, xmesh, ymesh, minx, maxx, miny, maxy); deleteData(data,xmesh); return true; } qwtplot3d-0.2.7+svn191/src/qwt3d_meshplot.cpp0000644000203200020320000001703310663257610020322 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4305 ) #pragma warning ( disable : 4786 ) #endif #include "qwt3d_surfaceplot.h" #include "qwt3d_enrichment_std.h" using namespace std; using namespace Qwt3D; ///////////////////////////////////////////////////////////////////////////////// // // cell specific // void SurfacePlot::createDataC() { createFloorDataC(); if (plotStyle() == NOPLOT) return; if (plotStyle() == Qwt3D::POINTS) { createPoints(); return; } else if (plotStyle() == Qwt3D::USER) { if (userplotstyle_p) createEnrichment(*userplotstyle_p); return; } setDeviceLineWidth(meshLineWidth()); GLStateBewarer sb(GL_POLYGON_OFFSET_FILL,true); setDevicePolygonOffset(polygonOffset(),1.0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); int idx = 0; if (plotStyle() != WIREFRAME) { glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS); bool hl = (plotStyle() == HIDDENLINE); if (hl) { RGBA col = backgroundRGBAColor(); glColor4d(col.r, col.g, col.b, col.a); } for (unsigned i=0; i!=actualDataC_->cells.size(); ++i) { glBegin(GL_POLYGON); for (unsigned j=0; j!=actualDataC_->cells[i].size(); ++j) { idx = actualDataC_->cells[i][j]; setColorFromVertexC(idx, hl); glVertex3d( actualDataC_->nodes[idx].x, actualDataC_->nodes[idx].y, actualDataC_->nodes[idx].z ); glNormal3d( actualDataC_->normals[idx].x, actualDataC_->normals[idx].y, actualDataC_->normals[idx].z ); } glEnd(); } } if (plotStyle() == FILLEDMESH || plotStyle() == WIREFRAME || plotStyle() == HIDDENLINE) { glColor4d(meshColor().r, meshColor().g, meshColor().b, meshColor().a); { for (unsigned i=0; i!=actualDataC_->cells.size(); ++i) { glBegin(GL_LINE_LOOP); for (unsigned j=0; j!=actualDataC_->cells[i].size(); ++j) { idx = actualDataC_->cells[i][j]; glVertex3d( actualDataC_->nodes[idx].x, actualDataC_->nodes[idx].y, actualDataC_->nodes[idx].z ); } glEnd(); } } } } // ci = cell index // cv = vertex index in cell ci void SurfacePlot::setColorFromVertexC(int node, bool skip) { if (skip) return; RGBA col = (*datacolor_p)( actualDataC_->nodes[node].x, actualDataC_->nodes[node].y, actualDataC_->nodes[node].z); glColor4d(col.r, col.g, col.b, col.a); } void SurfacePlot::createFloorDataC() { switch (floorStyle()) { case FLOORDATA: Data2FloorC(); break; case FLOORISO: Isolines2FloorC(); break; default: break; } } void SurfacePlot::Data2FloorC() { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); double zshift = actualDataC_->hull().minVertex.z; int idx; for (unsigned i = 0; i!=actualDataC_->cells.size(); ++i) { glBegin(GL_POLYGON); for (unsigned j=0; j!=actualDataC_->cells[i].size(); ++j) { idx = actualDataC_->cells[i][j]; setColorFromVertexC(idx); glVertex3d( actualDataC_->nodes[idx].x, actualDataC_->nodes[idx].y, zshift ); } glEnd(); } } void SurfacePlot::Isolines2FloorC() { if (isolines() <= 0 || actualData_p->empty()) return; double step = (actualData_p->hull().maxVertex.z - actualData_p->hull().minVertex.z) / isolines(); RGBA col; double zshift = actualData_p->hull().minVertex.z; TripleField nodes; TripleField intersection; double lambda = 0; GLStateBewarer sb2(GL_LINE_SMOOTH, false); for (int k = 0; k != isolines(); ++k) { double val = zshift + k * step; for (unsigned i=0; i!=actualDataC_->cells.size(); ++i) { nodes.clear(); unsigned cellnodes = actualDataC_->cells[i].size(); for (unsigned j=0; j!=cellnodes; ++j) { nodes.push_back(actualDataC_->nodes[actualDataC_->cells[i][j]]); } double diff = 0; for (unsigned m = 0; m!=cellnodes; ++m) { unsigned mm = (m+1)%cellnodes; if ((val>=nodes[m].z && val<=nodes[mm].z) || (val>=nodes[mm].z && val<=nodes[m].z)) { diff = nodes[mm].z - nodes[m].z; if (isPracticallyZero(diff)) // degenerated { intersection.push_back(nodes[m]); intersection.push_back(nodes[mm]); continue; } lambda = (val - nodes[m].z) / diff; intersection.push_back(Triple(nodes[m].x + lambda * (nodes[mm].x-nodes[m].x), nodes[m].y + lambda * (nodes[mm].y-nodes[m].y), val)); } } if (!intersection.empty()) { col = (*datacolor_p)(nodes[0].x,nodes[0].y,nodes[0].z); glColor4d(col.r, col.g, col.b, col.a); if (intersection.size()>2) { glBegin(GL_LINE_STRIP); for (unsigned dd = 0; dd!=intersection.size(); ++dd) { glVertex3d(intersection[dd].x, intersection[dd].y, zshift); } glEnd(); glBegin(GL_POINTS); glVertex3d(intersection[0].x,intersection[0].y,zshift); glEnd(); } else if (intersection.size() == 2) { glBegin(GL_LINES); glVertex3d(intersection[0].x,intersection[0].y,zshift); glVertex3d(intersection[1].x,intersection[1].y,zshift); // small pixel gap problem (see OpenGL spec.) glVertex3d(intersection[1].x,intersection[1].y,zshift); glVertex3d(intersection[0].x,intersection[0].y,zshift); glEnd(); } intersection.clear(); } } } } void SurfacePlot::createNormalsC() { if (!normals() || actualData_p->empty()) return; if (actualDataC_->nodes.size() != actualDataC_->normals.size()) return; Arrow arrow; arrow.setQuality(normalQuality()); Triple basev, topv, norm; double diag = (actualData_p->hull().maxVertex-actualData_p->hull().minVertex).length() * normalLength(); RGBA col; arrow.assign(*this); arrow.drawBegin(); for (unsigned i = 0; i != actualDataC_->normals.size(); ++i) { basev = actualDataC_->nodes[i]; topv = basev + actualDataC_->normals[i]; norm = topv-basev; norm.normalize(); norm *= diag; arrow.setTop(basev+norm); arrow.setColor((*datacolor_p)(basev.x,basev.y,basev.z)); arrow.draw(basev); } arrow.drawEnd(); } /*! Convert user (non-rectangular) mesh based data to internal structure. See also Qwt3D::TripleField and Qwt3D::CellField */ bool SurfacePlot::loadFromData(TripleField const& data, CellField const& poly) { actualDataG_->clear(); actualData_p = actualDataC_; actualDataC_->nodes = data; actualDataC_->cells = poly; actualDataC_->normals = TripleField(actualDataC_->nodes.size()); unsigned i; // normals for the moment Triple n, u, v; for ( i = 0; i < poly.size(); ++i) { if (poly[i].size() < 3) n = Triple(0,0,0); else { for (unsigned j = 0; j < poly[i].size(); ++j) { unsigned jj = (j+1) % poly[i].size(); unsigned pjj = (j) ? j-1 : poly[i].size()-1; u = actualDataC_->nodes[poly[i][jj]]-actualDataC_->nodes[poly[i][j]]; v = actualDataC_->nodes[poly[i][pjj]]-actualDataC_->nodes[poly[i][j]]; n = normalizedcross(u,v); actualDataC_->normals[poly[i][j]] += n; } } } for ( i = 0; i != actualDataC_->normals.size(); ++i) { actualDataC_->normals[i].normalize(); } ParallelEpiped hull(Triple(DBL_MAX,DBL_MAX,DBL_MAX),Triple(-DBL_MAX,-DBL_MAX,-DBL_MAX)); for (i = 0; i!=data.size(); ++i) { if (data[i].x < hull.minVertex.x) hull.minVertex.x = data[i].x; if (data[i].y < hull.minVertex.y) hull.minVertex.y = data[i].y; if (data[i].z < hull.minVertex.z) hull.minVertex.z = data[i].z; if (data[i].x > hull.maxVertex.x) hull.maxVertex.x = data[i].x; if (data[i].y > hull.maxVertex.y) hull.maxVertex.y = data[i].y; if (data[i].z > hull.maxVertex.z) hull.maxVertex.z = data[i].z; } actualDataC_->setHull(hull); updateData(); updateNormals(); createCoordinateSystem(); return true; } qwtplot3d-0.2.7+svn191/src/qwt3d_colorlegend.cpp0000644000203200020320000001135010663257610020760 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4305 ) #endif #include "qwt3d_colorlegend.h" using namespace Qwt3D; /** Contructs a legend object with an axis at the left side. The legend resides in the top-right area and has no caption. Scale numbering is shown. */ ColorLegend::ColorLegend() { axis_.setNumbers(true); axis_.setScaling(true); axis_.setNumberColor(RGBA(0,0,0,1)); axis_.setNumberAnchor(CenterRight); axis_.setNumberFont(QFont("Courier",8)); caption_.setFont("Courier", 10, QFont::Bold); caption_.setColor(RGBA(0,0,0,1)); axisposition_ = ColorLegend::Left; orientation_ = ColorLegend::BottomTop; showaxis_ = true; setRelPosition(Tuple(0.94, 1-0.36),Tuple(0.97, 1-0.04)); } void ColorLegend::setTitleString(QString const& s) { caption_.setString(s); } void ColorLegend::setTitleFont(QString const& family, int pointSize, int weight, bool italic) { caption_.setFont(family, pointSize, weight, italic); } void ColorLegend::setLimits(double start, double stop) { axis_.setLimits(start, stop); } void ColorLegend::setMajors(int majors) { axis_.setMajors(majors); } void ColorLegend::setMinors(int minors) { axis_.setMinors(minors); } void ColorLegend::setAutoScale(bool val) { axis_.setAutoScale(val); } void ColorLegend::setScale(SCALETYPE val) { axis_.setScale(val); } void ColorLegend::setScale(Scale* val) { axis_.setScale(val); } void ColorLegend::setOrientation(ORIENTATION orientation, SCALEPOSITION pos) { orientation_ = orientation; axisposition_ = pos; if (orientation_==BottomTop) { if (axisposition_ == Bottom || axisposition_ == Top) axisposition_ = Left; } else { if (axisposition_ == Left || axisposition_ == Right) axisposition_ = Bottom; } } void ColorLegend::setRelPosition(Tuple relMin, Tuple relMax) { relMin_ = relMin; relMax_ = relMax; } void ColorLegend::setGeometryInternal() { double ot = .99; getMatrices(modelMatrix, projMatrix, viewport); pe_.minVertex = relativePosition(Triple(relMin_.x, relMin_.y, ot)); pe_.maxVertex = relativePosition(Triple(relMax_.x, relMax_.y, ot)); double diff = 0; Triple b; Triple e; switch (axisposition_) { case ColorLegend::Left: b = pe_.minVertex; e = pe_.maxVertex; e.x = b.x; axis_.setTicOrientation(-1,0,0); axis_.setNumberAnchor(CenterRight); diff = pe_.maxVertex.x - pe_.minVertex.x; break; case ColorLegend::Right: e = pe_.maxVertex; b = pe_.minVertex; b.x = e.x; axis_.setTicOrientation(+1,0,0); axis_.setNumberAnchor(CenterLeft); diff = pe_.maxVertex.x - pe_.minVertex.x; break; case ColorLegend::Top: e = pe_.maxVertex; b = pe_.minVertex; b.z = e.z; axis_.setTicOrientation(0,0,+1); axis_.setNumberAnchor(BottomCenter); diff = pe_.maxVertex.z - pe_.minVertex.z; break; case ColorLegend::Bottom: b = pe_.minVertex; e = pe_.maxVertex; e.z = b.z; axis_.setTicOrientation(0,0,-1); axis_.setNumberAnchor(TopCenter); diff = pe_.maxVertex.z - pe_.minVertex.z; break; default: break; } axis_.setPosition(b,e); diff /= 10; axis_.setTicLength(diff, 0.6*diff); Triple c; c.x = pe_.minVertex.x + ((pe_.maxVertex-pe_.minVertex) / 2).x; c.z = pe_.maxVertex.z; c.z += (pe_.maxVertex.z-pe_.minVertex.z)/20; c.y = pe_.maxVertex.y; caption_.setPosition(c, BottomCenter); } void ColorLegend::draw() { if (colors.empty()) return; setGeometryInternal(); saveGLState(); Triple one = pe_.minVertex; Triple two = pe_.maxVertex; double h = (orientation_ == ColorLegend::BottomTop) ? (two-one).z / colors.size() : (two-one).x / colors.size(); //glEnable(GL_DEPTH_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); GLStateBewarer(GL_POLYGON_OFFSET_FILL,true); // glPolygonOffset(0.0, 0.0); glColor4d(0, 0, 0, 1); glBegin(GL_LINE_LOOP); glVertex3d(one.x, one.y, one.z); glVertex3d(one.x, one.y, two.z); glVertex3d(two.x, one.y, two.z); glVertex3d(two.x, one.y, one.z); glEnd(); unsigned size = colors.size(); RGBA rgb; if (orientation_ == ColorLegend::BottomTop) { for (unsigned i=1; i<=size; ++i) { rgb = colors[i-1]; glColor4d(rgb.r,rgb.g,rgb.b,rgb.a); glBegin( GL_POLYGON ); glVertex3d( one.x, one.y, one.z+(i-1)*h ); glVertex3d( one.x, one.y, one.z+i*h ); glVertex3d( two.x, one.y, one.z+i*h ); glVertex3d( two.x, one.y, one.z+(i-1)*h ); glEnd(); } } else { for (unsigned i=1; i<=size; ++i) { rgb = colors[i-1]; glColor4d(rgb.r,rgb.g,rgb.b,rgb.a); glBegin( GL_POLYGON ); glVertex3d( one.x+(i-1)*h, one.y, one.z ); glVertex3d( one.x+i*h, one.y, one.z ); glVertex3d( one.x+i*h, one.y, two.z ); glVertex3d( one.x+(i-1)*h, one.y, two.z ); glEnd(); } } restoreGLState(); if (showaxis_) axis_.draw(); caption_.draw(); } qwtplot3d-0.2.7+svn191/src/qwt3d_parametricsurface.cpp0000644000203200020320000000427510663257610022173 0ustar gudjongudjon#include "qwt3d_parametricsurface.h" #include "qwt3d_surfaceplot.h" using namespace Qwt3D; ParametricSurface::ParametricSurface() :GridMapping() { } ParametricSurface::ParametricSurface(SurfacePlot& pw) :GridMapping() { plotwidget_p = &pw; uperiodic_ = false; vperiodic_ = false; } ParametricSurface::ParametricSurface(SurfacePlot* pw) :GridMapping() { plotwidget_p = pw; uperiodic_ = false; vperiodic_ = false; } void ParametricSurface::setPeriodic(bool u, bool v) { uperiodic_ = u; vperiodic_ = v; } void ParametricSurface::assign(SurfacePlot& plotWidget) { if (&plotWidget != plotwidget_p) plotwidget_p = &plotWidget; } void ParametricSurface::assign(SurfacePlot* plotWidget) { if (plotWidget != plotwidget_p) plotwidget_p = plotWidget; } /** For plotWidget != 0 the function permanently assigns her argument (In fact, assign(plotWidget) is called) */ bool ParametricSurface::create() { if ((umesh_p<=2) || (vmesh_p<=2) || !plotwidget_p) return false; /* allocate some space for the mesh */ Triple** data = new Triple* [umesh_p] ; unsigned i,j; for ( i = 0; i < umesh_p; i++) { data[i] = new Triple [vmesh_p]; } /* get the data */ double du = (maxu_p - minu_p) / (umesh_p - 1); double dv = (maxv_p - minv_p) / (vmesh_p - 1); for (i = 0; i < umesh_p; ++i) { for (j = 0; j < vmesh_p; ++j) { data[i][j] = operator()(minu_p + i*du, minv_p + j*dv); if (data[i][j].x > range_p.maxVertex.x) data[i][j].x = range_p.maxVertex.x; else if (data[i][j].y > range_p.maxVertex.y) data[i][j].y = range_p.maxVertex.y; else if (data[i][j].z > range_p.maxVertex.z) data[i][j].z = range_p.maxVertex.z; else if (data[i][j].x < range_p.minVertex.x) data[i][j].x = range_p.minVertex.x; else if (data[i][j].y < range_p.minVertex.y) data[i][j].y = range_p.minVertex.y; else if (data[i][j].z < range_p.minVertex.z) data[i][j].z = range_p.minVertex.z; } } ((SurfacePlot*)plotwidget_p)->loadFromData(data, umesh_p, vmesh_p, uperiodic_, vperiodic_); for ( i = 0; i < umesh_p; i++) { delete [] data[i]; } delete [] data; return true; } bool ParametricSurface::create(SurfacePlot& pl) { assign(pl); return create(); } qwtplot3d-0.2.7+svn191/src/qwt3d_gridmapping.cpp0000644000203200020320000000114710663257610020767 0ustar gudjongudjon#include "qwt3d_gridmapping.h" #include "qwt3d_surfaceplot.h" using namespace Qwt3D; GridMapping::GridMapping() { plotwidget_p = 0; setMesh(0,0); setDomain(0,0,0,0); restrictRange(ParallelEpiped(Triple(-DBL_MAX,-DBL_MAX,-DBL_MAX),Triple(DBL_MAX,DBL_MAX,DBL_MAX))); } void GridMapping::setMesh(unsigned int columns,unsigned int rows) { umesh_p = columns; vmesh_p = rows; } void GridMapping::setDomain(double minu, double maxu, double minv, double maxv) { minu_p = minu; maxu_p = maxu; minv_p = minv; maxv_p = maxv; } void GridMapping::restrictRange(Qwt3D::ParallelEpiped const& p) { range_p = p; } qwtplot3d-0.2.7+svn191/src/qwt3d_autoscaler.cpp0000644000203200020320000001306010663257610020625 0ustar gudjongudjon#include "qwt3d_helper.h" #include "qwt3d_autoscaler.h" using namespace Qwt3D; namespace { double floorExt( int& exponent, double x, std::vector& sortedmantissi) { if (x == 0.0) { exponent = 0; return 0.0; } double sign = (x > 0) ? 1.0 : -1.0; double lx = log10(fabs(x)); exponent = (int)floor(lx); double fr = pow(10.0, lx - exponent); if (fr >= 10.0) { fr = 1.0; ++exponent; } else { for (int i=(int)sortedmantissi.size()-1; i>=0;--i) { if (fr>=sortedmantissi[i]) { fr = sortedmantissi[i]; break; } } } return sign * fr; } /* \brief Find the largest value out of {1,2,5}*10^n with an integer number n which is smaller than or equal to x \param exponent n \param x Input value \return Mantissa */ double floor125( int& exponent, double x) { std::vector m(2); m[0] = 1; m[1] = 2; m[2] = 5; return floorExt(exponent, x, m); } } // anon ns //! Initializes with an {1,2,5} sequence of mantissas LinearAutoScaler::LinearAutoScaler() { init(0,1,1); mantissi_ = std::vector(3); mantissi_[0] = 1; mantissi_[1] = 2; mantissi_[2] = 5; } //! Initialize with interval [0,1] and one requested interval /*! val mantisse A increasing ordered vector of values representing mantisse values between 1 and 9. */ LinearAutoScaler::LinearAutoScaler(std::vector& mantisse) { init(0,1,1); if (mantisse.empty()) { mantissi_ = std::vector(3); mantissi_[0] = 1; mantissi_[1] = 2; mantissi_[2] = 5; return; } mantissi_ = mantisse; } //! Initialize with interval [start,stop] and number of requested intervals /** Switchs start and stop, if stop < start and sets intervals = 1 if ivals < 1 */ void LinearAutoScaler::init(double start, double stop, int ivals) { start_ = start; stop_ = stop; intervals_ = ivals; if (start_ > stop_) { double tmp = start_; start_ = stop_; stop_ = tmp; } if (intervals_ < 1) intervals_ = 1; } /*! \return Anchor value \verbatim |_______|____________ _ _ _ _ _____|_____________|________________ 0 m*10^n start anchor := c*m*10^n c 'minimal' (anchor-start < m*10^n) \endverbatim */ double LinearAutoScaler::anchorvalue(double start, double m, int n) { double stepval = m * pow(10.0, n); return stepval * ceil(start / stepval); } /*! \return New number of intervals (:= l_intervals + r_intervals) \param l_intervals Number of intervals left from anchor \param r_intervals Number of intervals right from anchor \verbatim -l_intervals * i -2 * i -i +r_intervals * i | |______|_______ _ _ _ ____|____|___ _ _ _ _ _ _ _|_______|_______|_ _ _ _ _ _ _____|__|_____ | | | | 0 i := m*10^n start anchor stop c 'minimal' (anchor-start < m*10^n) \endverbatim */ int LinearAutoScaler::segments(int& l_intervals, int& r_intervals, double start, double stop, double anchor, double m, int n) { double val = m * pow(10.0, n); double delta = (stop - anchor) / val; r_intervals = (int)floor(delta); // right side intervals delta = (anchor - start) / val; l_intervals = (int)floor(delta); // left side intervals return r_intervals + l_intervals; } /*! \brief Does the actual scaling \return Number of intervals after rescaling. This will in the most cases differ from the requested interval number! Always >0. \param a Start value after scaling (always >= start) \param b Stop value after scaling (always <= stop) \param start Start value \param stop Stop value \param ivals Requested intervals \return Number of intervals after autoscaling If the given interval has zero length the function returns the current interval number and a and b remain unchanged. */ int LinearAutoScaler::execute(double& a, double& b, double start, double stop, int ivals) { init(start,stop,ivals); double delta = stop_ - start_; if (isPracticallyZero(delta)) return intervals_; double c; int n; c = floorExt(n, delta, mantissi_); int l_ival, r_ival; double anchor = anchorvalue(start_, c, n); int ival = segments(l_ival, r_ival, start_, stop_, anchor, c, n); if (ival >= intervals_) { a = anchor - l_ival * c * pow(10.0,n); b = anchor + r_ival * c * pow(10.0,n); intervals_ = ival; return intervals_; } int prev_ival, prev_l_ival, prev_r_ival; double prev_anchor; double prev_c; int prev_n; while(1) { prev_c = c; prev_n = n; prev_anchor = anchor; prev_ival = ival; prev_l_ival = l_ival; prev_r_ival = r_ival; if (int(c) == 1) { c = mantissi_.back(); --n; } else { for (unsigned int i=mantissi_.size()-1; i>0; --i) { if (int(c) == mantissi_[i]) { c = mantissi_[i-1]; break; } } } anchor = anchorvalue(start_, c, n); ival = segments(l_ival, r_ival, start_, stop_, anchor, c, n); int prev_diff = intervals_ - prev_ival; int actual_diff = ival - intervals_; if (prev_diff >= 0 && actual_diff >= 0) { if (prev_diff < actual_diff) { c = prev_c; n = prev_n; anchor = prev_anchor; ival = prev_ival; l_ival = prev_l_ival; r_ival = prev_r_ival; } a = anchor - l_ival * c * pow(10.0,n); b = anchor + r_ival * c * pow(10.0,n); intervals_ = ival; break; } } return intervals_; } qwtplot3d-0.2.7+svn191/src/qwt3d_axis.cpp0000644000203200020320000001774110663257610017441 0ustar gudjongudjon#include "qwt3d_axis.h" using namespace Qwt3D; Axis::Axis() { init(); }; Axis::~Axis() { } Axis::Axis(Triple beg, Triple end) { init(); setPosition(beg,end); } void Axis::init() { detachAll(); scale_ = qwt3d_ptr(new LinearScale); beg_ = Triple(0.0, 0.0, 0.0); end_ = beg_; majorintervals_ = 0; minorintervals_ = 0; setMajors(1); setMinors(1); setLimits(0,0); setTicOrientation(0.0, 0.0, 0.0); setTicLength(0.0, 0.0); setColor(0.0, 0.0, 0.0); setLineWidth(1.0); symtics_ = false; drawNumbers_ = false; drawLabel_ = false; drawTics_ = false; autoscale_ = true; markerLabel_.clear(); numberfont_ = QFont("Courier",12); setLabelFont(QFont("Courier",14)); numbercolor_ = RGBA(0,0,0,0); setNumberAnchor(Center); numbergap_ = 0; labelgap_ = 0; } void Axis::setPosition(const Triple& beg, const Triple& end) { beg_ = beg; end_ = end; } void Axis::setMajors(int val) { if (val == majorintervals_) return; majorintervals_ = (val<=0) ? 1 : val; // always >= 1 } /*! \see LogScale::setMinors(). */ void Axis::setMinors(int val) { if (val == minorintervals_) return; minorintervals_ = (val<=0) ? 1 : val; // always >= 1 } void Axis::setTicLength(double majorl, double minorl) { lmaj_ = majorl; lmin_ = minorl; } void Axis::setTicOrientation(double tx, double ty, double tz) { setTicOrientation(Triple(tx,ty,tz)); } void Axis::setTicOrientation(const Triple& val) { orientation_ = val; orientation_.normalize(); } /** \param val thickness for axis base line \param majfac relative thickness for axis major tics (majfac*val) \param minfac relative thickness for axis minor tics (minfac*val) */ void Axis::setLineWidth(double val, double majfac, double minfac) { lineWidth_ = val; majLineWidth_ = majfac * lineWidth_; minLineWidth_ = minfac * lineWidth_; } void Axis::draw() { Drawable::draw(); saveGLState(); // GLStateBewarer sb(GL_LINE_SMOOTH, true); // glBlendFunc(GL_ONE, GL_ZERO); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4d(color.r,color.g,color.b,color.a); drawBase(); drawTics(); drawLabel(); restoreGLState(); } /** Always use AFTER drawNumbers() ! (Needs length of number string) */ void Axis::drawLabel() { if (!drawLabel_) return; Triple diff = end() - begin(); Triple center = begin() + diff/2; Triple bnumber = biggestNumberString(); // double fac = 6*(second()-first()).length() / 100; switch (scaleNumberAnchor_) { case BottomLeft: case TopLeft: case CenterLeft: bnumber.y = 0; break; case BottomRight: case TopRight: case CenterRight: bnumber.x = -bnumber.x; bnumber.y = 0; break; case TopCenter: bnumber.x = 0; bnumber.y = -bnumber.y; break; case BottomCenter: bnumber.x = 0; break; default: break; } Triple pos = ViewPort2World(World2ViewPort(center + ticOrientation() * lmaj_) + bnumber); setLabelPosition(pos, scaleNumberAnchor_); label_.adjust(labelgap_); label_.draw(); } void Axis::drawBase() { setDeviceLineWidth( lineWidth_ ); glBegin( GL_LINES ); glVertex3d( beg_.x, beg_.y, beg_.z); glVertex3d( end_.x, end_.y, end_.z); glEnd(); } bool Axis::prepTicCalculation(Triple& startpoint) { if (isPracticallyZero(start_, stop_)) return false; autostart_ = start_; autostop_ = stop_; if (autoScale()) { setMajors(scale_->autoscale(autostart_, autostop_, start_, stop_, majors())); if (isPracticallyZero(autostart_, autostop_)) return false; } scale_->setLimits(start_,stop_); scale_->setMajors(majors()); scale_->setMinors(minors()); scale_->setMajorLimits(autostart_,autostop_); scale_->calculate(); Triple normal = (end_ - beg_); //normal.normalize(); Triple beg = beg_ + ((autostart_ - start_) / (stop_ - start_)) * normal; Triple end = end_ - ((stop_ - autostop_) / (stop_ - start_))* normal; startpoint = end_ - beg_; majorpos_.clear(); minorpos_.clear(); return true; } void Axis::recalculateTics() { Triple runningpoint; if (false==prepTicCalculation(runningpoint)) return; unsigned int i; for (i = 0; i != scale_->majors_p.size(); ++i) { double t = (scale_->majors_p[i] - start_) / (stop_-start_); majorpos_.push_back(beg_ + t * runningpoint); } for (i = 0; i != scale_->minors_p.size(); ++i) { double t = (scale_->minors_p[i] - start_) / (stop_-start_); minorpos_.push_back(beg_ + t * runningpoint); } } void Axis::drawTics() { Triple runningpoint; if (!drawTics_ || false==prepTicCalculation(runningpoint)) return; unsigned int i; Triple nadir; markerLabel_.resize(scale_->majors_p.size()); setDeviceLineWidth(majLineWidth_); for (i = 0; i != scale_->majors_p.size(); ++i) { double t = (scale_->majors_p[i] - start_) / (stop_-start_); nadir = beg_ + t * runningpoint; majorpos_.push_back(drawTic(nadir, lmaj_)); drawTicLabel(nadir + 1.2 * lmaj_ * orientation_, i); } setDeviceLineWidth(minLineWidth_); for (i = 0; i != scale_->minors_p.size(); ++i) { double t = (scale_->minors_p[i] - start_) / (stop_-start_); nadir = beg_ + t * runningpoint; minorpos_.push_back(drawTic(nadir, lmin_)); } } void Axis::drawTicLabel(Triple pos, int mtic) { if (!drawNumbers_ || (mtic < 0)) return; markerLabel_[mtic].setFont(numberfont_.family(), numberfont_.pointSize(), numberfont_.weight(), numberfont_.italic()); markerLabel_[mtic].setColor(numbercolor_); markerLabel_[mtic].setString(scale_->ticLabel(mtic)); markerLabel_[mtic].setPosition(pos, scaleNumberAnchor_); markerLabel_[mtic].adjust(numbergap_); markerLabel_[mtic].draw(); } Triple Axis::drawTic(Triple nadir, double length) { double ilength = (symtics_) ? -length : 0.0; glBegin( GL_LINES ); glVertex3d( nadir.x + ilength * orientation_.x, nadir.y + ilength * orientation_.y, nadir.z + ilength * orientation_.z) ; glVertex3d( nadir.x + length * orientation_.x, nadir.y + length * orientation_.y, nadir.z + length * orientation_.z); glEnd(); return nadir; } void Axis::setNumberFont(QString const& family, int pointSize, int weight, bool italic) { numberfont_ = QFont(family, pointSize, weight, italic ); } void Axis::setNumberFont(QFont const& font) { numberfont_ = font; } void Axis::setNumberColor(RGBA col) { numbercolor_ = col; } void Axis::setLabelFont(QString const& family, int pointSize, int weight, bool italic) { labelfont_ = QFont(family, pointSize, weight, italic ); label_.setFont(family, pointSize, weight, italic); } void Axis::setLabelFont(QFont const& font) { setLabelFont(font.family(), font.pointSize(), font.weight(), font.italic()); } void Axis::setLabelString(QString const& name) { label_.setString(name); } /*! Sets label position in conjunction with an anchoring strategy */ void Axis::setLabelPosition(const Triple& pos,Qwt3D::ANCHOR an) { label_.setPosition(pos, an); } //! Sets color for label void Axis::setLabelColor(RGBA col) { label_.setColor(col); } Triple Axis::biggestNumberString() { Triple ret; unsigned size = markerLabel_.size(); double width, height; for (unsigned i=0; i!=size; ++i) { width = fabs( (World2ViewPort(markerLabel_[i].second())-World2ViewPort(markerLabel_[i].first())).x ); height = fabs( (World2ViewPort(markerLabel_[i].second())-World2ViewPort(markerLabel_[i].first())).y ); if (width > ret.x) ret.x = width + markerLabel_[i].gap(); if (height > ret.y) ret.y = height + markerLabel_[i].gap();; } return ret; } /*! This variant sets a user-defined scale object. Use with a heap based initialized pointer only. The axis adopts ownership. */ void Axis::setScale(Scale* val) { scale_ = qwt3d_ptr(val); } /*! Sets one of the predefined scaling types. \warning Too small intervals in logarithmic scales lead to empty scales (or perhaps a scale only containing an isolated major tic). Better switch to linear scales in such cases. */ void Axis::setScale(Qwt3D::SCALETYPE val) { switch(val) { case Qwt3D::LINEARSCALE: setScale(new LinearScale); break; case Qwt3D::LOG10SCALE: setScale(new LogScale); setMinors(9); break; default: break; } } qwtplot3d-0.2.7+svn191/src/qwt3d_types.cpp0000644000203200020320000001032510663257610017630 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4786 ) #endif #include // qsort #include #include #include "qwt3d_types.h" using namespace Qwt3D; #ifndef QWT3D_NOT_FOR_DOXYGEN namespace { // convex hull typedef double coordinate_type; int ccw(coordinate_type **P, int i, int j, int k) { coordinate_type a = P[i][0] - P[j][0], b = P[i][1] - P[j][1], c = P[k][0] - P[j][0], d = P[k][1] - P[j][1]; return a*d - b*c <= 0; /* true if points i, j, k counterclockwise */ } #define CMPM(c,A,B) \ v = (*(coordinate_type**)A)[c] - (*(coordinate_type**)B)[c];\ if (v>0) return 1;\ if (v<0) return -1; int cmpl(const void *a, const void *b) { double v; CMPM(0,a,b); CMPM(1,b,a); return 0; } int cmph(const void *a, const void *b) {return cmpl(b,a);} int make_chain(coordinate_type** V, int n, int (*cmp)(const void*, const void*)) { int i, j, s = 1; coordinate_type* t; qsort(V, n, sizeof(coordinate_type*), cmp); for (i=2; i=1 && ccw(V, i, j, j-1); j--){} s = j+1; t = V[s]; V[s] = V[i]; V[i] = t; } return s; } int _ch2d(coordinate_type **P, int n) { int u = make_chain(P, n, cmpl); /* make lower hull */ if (!n) return 0; P[n] = P[0]; return u+make_chain(P+u, n-u+1, cmph); /* make upper hull */ } } // ns anon GridData::GridData() { datatype = Qwt3D::GRID; setSize(0,0); setPeriodic(false,false); } GridData::GridData(unsigned int columns, unsigned int rows) { datatype = Qwt3D::GRID; setSize(columns,rows); setPeriodic(false,false); } int GridData::columns() const { return (int)vertices.size(); } int GridData::rows() const { return (empty()) ? 0 : (int)vertices[0].size(); } void GridData::clear() { setHull(ParallelEpiped()); { for (unsigned i=0; i!=vertices.size(); ++i) { for (unsigned j=0; j!=vertices[i].size(); ++j) { delete [] vertices[i][j]; } vertices[i].clear(); } } vertices.clear(); { for (unsigned i=0; i!=normals.size(); ++i) { for (unsigned j=0; j!=normals[i].size(); ++j) { delete [] normals[i][j]; } normals[i].clear(); } } normals.clear(); } void GridData::setSize(unsigned int columns, unsigned int rows) { this->clear(); vertices = std::vector(columns); { for (unsigned int i=0; i!=vertices.size(); ++i) { vertices[i] = DataRow(rows); for (unsigned int j=0; j!=vertices[i].size(); ++j) { vertices[i][j] = new GLdouble[3]; } } } normals = std::vector(columns); { for (unsigned int i=0; i!=normals.size(); ++i) { normals[i] = DataRow(rows); for (unsigned int j=0; j!=normals[i].size(); ++j) { normals[i][j] = new GLdouble[3]; } } } } Triple const& CellData::operator()(unsigned cellnumber, unsigned vertexnumber) { return nodes[cells[cellnumber][vertexnumber]]; } void CellData::clear() { setHull(ParallelEpiped()); cells.clear(); nodes.clear(); normals.clear(); } QColor Qwt3D::GL2Qt(GLdouble r, GLdouble g, GLdouble b) { return QColor(round(r * 255), round(g * 255), round(b * 255)); } RGBA Qwt3D::Qt2GL(QColor col) { QRgb qrgb = col.rgb(); RGBA rgba; rgba.r = qRed(qrgb) / 255.0; rgba.g = qGreen(qrgb) / 255.0; rgba.b = qBlue(qrgb) / 255.0; rgba.a = qAlpha(qrgb) / 255.0; return rgba; } void Qwt3D::convexhull2d( std::vector& idx, const std::vector& src ) { idx.clear(); if (src.empty()) return; if (src.size()==1) { idx.push_back(0); return; } coordinate_type** points = new coordinate_type*[src.size()+1] ; coordinate_type* P = new coordinate_type[src.size()*2]; int i; for (i=0; i<(int)src.size(); ++i) { points[i] = &P[2*i]; points[i][0] = src[i].x; points[i][1] = src[i].y; } coordinate_type* start = points[0]; int m = _ch2d( points, src.size() ); idx.resize(m); for (i=0; i #include "qwt3d_plot.h" using namespace Qwt3D; namespace { inline GLenum lightEnum(unsigned idx) { switch(idx) { case 0: return GL_LIGHT0; case 1: return GL_LIGHT1; case 2: return GL_LIGHT2; case 3: return GL_LIGHT3; case 4: return GL_LIGHT4; case 5: return GL_LIGHT5; case 6: return GL_LIGHT6; case 7: return GL_LIGHT7; default: return GL_LIGHT0; } } } void Plot3D::enableLighting(bool val) { if (lighting_enabled_ == val) return; lighting_enabled_ = val; makeCurrent(); if (val) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); if (!initializedGL()) return; updateGL(); } void Plot3D::disableLighting(bool val) { enableLighting(!val); } bool Plot3D::lightingEnabled() const { return lighting_enabled_; } /** \param light light number [0..7] \see setLight */ void Plot3D::illuminate(unsigned light) { if (light>7) return; lights_[light].unlit = false; } /** \param light light number [0..7] \see setLight */ void Plot3D::blowout(unsigned light) { if (light>7) return; lights_[light].unlit = false; } /** Sets GL material properties */ void Plot3D::setMaterialComponent(GLenum property, double r, double g, double b, double a) { GLfloat rgba[4] = {(GLfloat)r, (GLfloat)g, (GLfloat)b, (GLfloat)a}; makeCurrent(); glMaterialfv(GL_FRONT_AND_BACK, property, rgba); } /** This function is for convenience. It sets GL material properties with the equal r,g,b values and a blending alpha with value 1.0 */ void Plot3D::setMaterialComponent(GLenum property, double intensity) { setMaterialComponent(property,intensity,intensity,intensity,1.0); } /** Sets GL shininess */ void Plot3D::setShininess(double exponent) { makeCurrent(); glMaterialf(GL_FRONT, GL_SHININESS, exponent); } /** Sets GL light properties for light 'light' */ void Plot3D::setLightComponent(GLenum property, double r, double g, double b, double a, unsigned light) { GLfloat rgba[4] = {(GLfloat)r, (GLfloat)g, (GLfloat)b, (GLfloat)a}; makeCurrent(); glLightfv(lightEnum(light), property, rgba); } /** This function is for convenience. It sets GL light properties with the equal r,g,b values and a blending alpha with value 1.0 */ void Plot3D::setLightComponent(GLenum property, double intensity, unsigned light) { setLightComponent(property,intensity,intensity,intensity,1.0, lightEnum(light)); } /** Set the rotation angle of the light source. If you look along the respective axis towards ascending values, the rotation is performed in mathematical \e negative sense \param xVal angle in \e degree to rotate around the X axis \param yVal angle in \e degree to rotate around the Y axis \param zVal angle in \e degree to rotate around the Z axis \param light light number */ void Plot3D::setLightRotation( double xVal, double yVal, double zVal, unsigned light ) { if (light>7) return; lights_[light].rot.x = xVal; lights_[light].rot.y = yVal; lights_[light].rot.z = zVal; } /** Set the shift in light source (world) coordinates. \param xVal shift along (world) X axis \param yVal shift along (world) Y axis \param zVal shift along (world) Z axis \param light light number \see setViewportShift() */ void Plot3D::setLightShift( double xVal, double yVal, double zVal, unsigned light ) { if (light>7) return; lights_[light].shift.x = xVal; lights_[light].shift.y = yVal; lights_[light].shift.z = zVal; } void Plot3D::applyLight(unsigned light) { if (lights_[light].unlit) return; glEnable(lightEnum(light)); glLoadIdentity(); glRotatef( lights_[light].rot.x-90, 1.0, 0.0, 0.0 ); glRotatef( lights_[light].rot.y , 0.0, 1.0, 0.0 ); glRotatef( lights_[light].rot.z , 0.0, 0.0, 1.0 ); GLfloat lightPos[4] = { lights_[light].shift.x, lights_[light].shift.y, lights_[light].shift.z, 1.0}; GLenum le = lightEnum(light); glLightfv(le, GL_POSITION, lightPos); } void Plot3D::applyLights() { glMatrixMode( GL_MODELVIEW ); glPushMatrix(); for (unsigned i=0; i<8; ++i) { applyLight(i); } glPopMatrix(); } qwtplot3d-0.2.7+svn191/src/qwt3d_coordsys.cpp0000644000203200020320000003644710663257610020346 0ustar gudjongudjon#include "qwt3d_coordsys.h" using namespace std; using namespace Qwt3D; CoordinateSystem::CoordinateSystem(Triple first, Triple second, COORDSTYLE st) { autodecoration_ = true; axes = std::vector(12); setStyle(st); setLineSmooth(true); init(first,second); setAxesColor(RGBA(0,0,0,1)); setGridLinesColor(RGBA(0.2,0.2,0.2,1)); setNumberFont("Courier", 12); setNumberColor(RGBA(0,0,0)); setLabelFont("Courier", 14, QFont::Bold); setGridLines(false, false); } CoordinateSystem::~CoordinateSystem() { destroy(); } void CoordinateSystem::destroy() { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setLabelString(""); detachAll(); } void CoordinateSystem::init(Triple first, Triple second) { destroy(); for (unsigned i=0; i!=axes.size(); ++i) axes[i].setScale(LINEARSCALE); Triple dv = second - first; setPosition(first, second); double majl = dv.length() / 100; // 1 % setTicLength(majl, 0.6 * majl); axes[X1].setPosition(first, first+Triple(dv.x, 0, 0)); // front bottom x axes[Y1].setPosition(first, first+Triple( 0, dv.y, 0)); // bottom left y axes[Z1].setPosition (first+Triple( 0, dv.y, 0), first+Triple( 0, dv.y, dv.z)); // back left z axes[X1].setTicOrientation(0,-1,0); axes[Y1].setTicOrientation(-1,0,0); axes[Z1].setTicOrientation(-1,0,0); axes[X1].setLimits(first.x, second.x); axes[X2].setLimits(first.x, second.x); axes[X3].setLimits(first.x, second.x); axes[X4].setLimits(first.x, second.x); axes[Y1].setLimits(first.y, second.y); axes[Y2].setLimits(first.y, second.y); axes[Y3].setLimits(first.y, second.y); axes[Y4].setLimits(first.y, second.y); axes[Z1].setLimits(first.z, second.z); axes[Z2].setLimits(first.z, second.z); axes[Z3].setLimits(first.z, second.z); axes[Z4].setLimits(first.z, second.z); // remaining x axes axes[X2].setPosition(first+Triple( 0, 0, dv.z), first+Triple( dv.x, 0, dv.z)); // front top x axes[X3].setPosition(first+Triple( 0, dv.y, dv.z), second); // back top x axes[X4].setPosition(first+Triple( 0, dv.y, 0), first+Triple( dv.x, dv.y, 0)); // back bottom x axes[X2].setTicOrientation(0,-1,0); axes[X3].setTicOrientation(0,1,0); axes[X4].setTicOrientation(0,1,0); // remaining y axes axes[Y2].setPosition(first+Triple(dv.x, 0, 0), first+Triple(dv.x, dv.y, 0)); // bottom right y axes[Y3].setPosition(first+Triple(dv.x, 0, dv.z), second); // top right y axes[Y4].setPosition(first+Triple(0, 0, dv.z), first+Triple(0, dv.y, dv.z)); // top left y axes[Y2].setTicOrientation(1,0,0); axes[Y3].setTicOrientation(1,0,0); axes[Y4].setTicOrientation (-1,0,0); // remaining z axes axes[Z2].setPosition(first, first+Triple( 0, 0, dv.z)); // front left z axes[Z4].setPosition(first+Triple(dv.x, dv.y, 0), second ); // back right z axes[Z3].setPosition(first+Triple(dv.x, 0, 0), first+Triple(dv.x, 0, dv.z)); // front right z axes[Z2].setTicOrientation(-1,0,0); axes[Z4].setTicOrientation(1,0,0); axes[Z3].setTicOrientation(1,0,0); setStyle(style_); } void CoordinateSystem::draw() { // saveGLState(); GLStateBewarer sb(GL_LINE_SMOOTH, true); if (!lineSmooth()) sb.turnOff(); if (autoDecoration()) chooseAxes(); Drawable::draw(); if( style_ == NOCOORD) return; if (majorgridlines_ || minorgridlines_) recalculateAxesTics(); if (majorgridlines_) drawMajorGridLines(); if (minorgridlines_) drawMinorGridLines(); // restoreGLState(); } //! build convex hull (6 axes: 2 x, 2 y, 2 z) and choose one of them at a time for scales, labels etc. void CoordinateSystem::chooseAxes() { vector beg(axes.size()); vector end(axes.size()); vector src(2*axes.size()); unsigned i; // collect axes viewport coordinates and initialize for (i=0; i!=axes.size(); ++i) { if (style() != NOCOORD) attach(&axes[i]); beg[i] = World2ViewPort(axes[i].begin()); end[i] = World2ViewPort(axes[i].end()); src[i] = Tuple(beg[i].x, beg[i].y); src[axes.size()+i] = Tuple(end[i].x, end[i].y); axes[i].setScaling(false); axes[i].setNumbers(false); axes[i].setLabel(false); } vector idx; convexhull2d(idx,src); int rem_x = -1; int rem_y = -1; int rem_z = -1; bool left; int choice_x = -1; int choice_y = -1; int choice_z = -1; int other_x = -1; int other_y = -1; int other_z = -1; //traverse convex hull for (unsigned k=0; k!=idx.size(); ++k) { Triple one, two; if (idx[k] >= axes.size()) // is end point one = end[idx[k]-axes.size()]; else // is begin point one = beg[idx[k]]; unsigned int next = idx[(k+1) % idx.size()]; // next point in cv (considered as ring buffer of points) if (next >= axes.size()) two = end[next-axes.size()]; else two = beg[next]; for (i=0; i!=axes.size(); ++i) { if ( (one == beg[i] && two == end[i]) || (two == beg[i] && one == end[i]) ) { if (i==X1 || i==X2 || i==X3 || i==X4) // x Achsen { if (rem_x>=0) // schon zweite Achse der konvexen Huelle ? { // untere der beiden x Achsen double y = min(min(end[rem_x].y,end[i].y),min(beg[rem_x].y,beg[i].y)); choice_x = (y == beg[i].y || y == end[i].y) ? i : rem_x; other_x = (choice_x == (int)i) ? rem_x : (int)i; left = (beg[choice_x].x < beg[other_x].x || end[choice_x].x < end[other_x].x) ? true : false; autoDecorateExposedAxis(axes[choice_x], left); rem_x = -1; } else { rem_x = i; } } else if (i==Y1 || i==Y2 || i==Y3 || i==Y4) { if (rem_y>=0) { // untere der beiden y Achsen double y = min(min(end[rem_y].y,end[i].y),min(beg[rem_y].y,beg[i].y)); choice_y = (y == beg[i].y || y == end[i].y) ? i : rem_y; other_y = (choice_y == (int)i) ? rem_y : (int)i; left = (beg[choice_y].x < beg[other_y].x || end[choice_y].x < end[other_y].x) ? true : false; autoDecorateExposedAxis(axes[choice_y], left); rem_y = -1; } else { rem_y = i; } } else if (i==Z1 || i==Z2 || i==Z3 || i==Z4) { if (rem_z>=0) { // hintere der beiden z Achsen double z = max(max(end[rem_z].z,end[i].z),max(beg[rem_z].z,beg[i].z)); choice_z = (z == beg[i].z || z == end[i].z) ? i : rem_z; other_z = (choice_z == (int)i) ? rem_z : (int)i; rem_z = -1; } else { rem_z = i; } } } } // for axes } // for idx // fit z axis in - the onthewall axis if the decorated axes build a continous line, the opposite else if (choice_x>=0 && choice_y>=0 && choice_z>=0) { left = (beg[choice_z].x < beg[other_z].x || end[choice_z].x < end[other_z].x) ? true : false; if ( axes[choice_z].begin() == axes[choice_x].begin() || axes[choice_z].begin() == axes[choice_x].end() || axes[choice_z].begin() == axes[choice_y].begin() || axes[choice_z].begin() == axes[choice_y].end() || axes[choice_z].end() == axes[choice_x].begin() || axes[choice_z].end() == axes[choice_x].end() || axes[choice_z].end() == axes[choice_y].begin() || axes[choice_z].end() == axes[choice_y].end() ) { autoDecorateExposedAxis(axes[choice_z], left); } else { autoDecorateExposedAxis(axes[other_z], !left); choice_z = other_z; // for FRAME } } if (style() == FRAME) { for (i=0; i!=axes.size(); ++i) { if ((int)i!=choice_x && (int)i!=choice_y && (int)i!=choice_z) detach(&axes[i]); } } } void CoordinateSystem::autoDecorateExposedAxis(Axis& ax, bool left) { Triple diff = World2ViewPort(ax.end()) - World2ViewPort(ax.begin()); diff = Triple(diff.x,diff.y,0); // projection double s = diff.length(); if (!s) return; ax.setScaling(true); ax.setNumbers(true); ax.setLabel(true); const double SQRT_2 = 0.7071067; double sina = fabs(diff.y / s); if (left) // leftmost (compared with antagonist in CV) axis -> draw decorations on the left side { if ( diff.x >= 0 && diff.y >= 0 && sina < SQRT_2) // 0..Pi/4 { ax.setNumberAnchor(BottomCenter); } else if ( diff.x >= 0 && diff.y >= 0 && !left) // octant 2 { ax.setNumberAnchor(CenterRight); } else if ( diff.x <= 0 && diff.y >= 0 && sina >= SQRT_2) // octant 3 { ax.setNumberAnchor(CenterRight); } else if ( diff.x <= 0 && diff.y >= 0 ) // octant 4 { ax.setNumberAnchor(TopCenter); } else if ( diff.x <= 0 && diff.y <= 0 && sina <= SQRT_2) // octant 5 { ax.setNumberAnchor(BottomCenter); } else if ( diff.x <= 0 && diff.y <= 0) // octant 6 { ax.setNumberAnchor(CenterRight); } else if ( diff.x >= 0 && diff.y <= 0 && sina >= SQRT_2) // octant 7 { ax.setNumberAnchor(CenterRight); } else if ( diff.x >= 0 && diff.y <= 0) // octant 8 { ax.setNumberAnchor(TopCenter); } } else // rightmost axis { if ( diff.x >= 0 && diff.y >= 0 && sina <= SQRT_2) { ax.setNumberAnchor(TopCenter); } else if ( diff.x >= 0 && diff.y >= 0 && !left) { ax.setNumberAnchor(CenterLeft); } else if ( diff.x <= 0 && diff.y >= 0 && sina >= SQRT_2) { ax.setNumberAnchor(CenterLeft); } else if ( diff.x <= 0 && diff.y >= 0) { ax.setNumberAnchor(BottomCenter); } else if ( diff.x <= 0 && diff.y <= 0 && sina <= SQRT_2) { ax.setNumberAnchor(TopCenter); } else if ( diff.x <= 0 && diff.y <= 0) { ax.setNumberAnchor(CenterLeft); } else if ( diff.x >= 0 && diff.y <= 0 && sina >= SQRT_2) { ax.setNumberAnchor(CenterLeft); } else if ( diff.x >= 0 && diff.y <= 0) { ax.setNumberAnchor(BottomCenter); } } } void CoordinateSystem::setPosition(Triple first, Triple second) { first_ = first; second_ = second; } void CoordinateSystem::setTicLength(double major, double minor) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setTicLength(major, minor); } void CoordinateSystem::adjustNumbers(int val) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].adjustNumbers(val); } void CoordinateSystem::adjustLabels(int val) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].adjustLabel(val); } void CoordinateSystem::setAutoScale(bool val) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setAutoScale(val); } void CoordinateSystem::setAxesColor(RGBA val) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setColor(val); } void CoordinateSystem::recalculateAxesTics() { for (unsigned i=0; i!=axes.size(); ++i) axes[i].recalculateTics(); } void CoordinateSystem::setNumberFont(QString const& family, int pointSize, int weight, bool italic) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setNumberFont(family,pointSize,weight,italic); } void CoordinateSystem::setNumberFont(QFont const& font) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setNumberFont(font); } void CoordinateSystem::setNumberColor(RGBA val) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setNumberColor( val); } void CoordinateSystem::setStandardScale() { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setScale(LINEARSCALE); } void CoordinateSystem::setLabelFont(QFont const& font) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setLabelFont(font); } void CoordinateSystem::setLabelFont(QString const& family, int pointSize, int weight, bool italic) { setLabelFont(QFont(family,pointSize,weight,italic)); } void CoordinateSystem::setLabelColor(RGBA val) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setLabelColor(val); } void CoordinateSystem::setLineWidth(double val, double majfac, double minfac) { for (unsigned i=0; i!=axes.size(); ++i) axes[i].setLineWidth(val, majfac, minfac); } void CoordinateSystem::setStyle(COORDSTYLE s, AXIS frame_1, AXIS frame_2, AXIS frame_3) { style_ = s; switch (s) { case NOCOORD: { for (unsigned i=0; i!=axes.size(); ++i) detach (&axes[i]); } break; case BOX: { for (unsigned i=0; i!=axes.size(); ++i) attach (&axes[i]); } break; case FRAME: { for (unsigned i=0; i!=axes.size(); ++i) detach (&axes[i]); if (!autoDecoration()) { attach(&axes[frame_1]); attach(&axes[frame_2]); attach(&axes[frame_3]); } } break; default: break; } } /** The axis used for tic calculation is chosen randomly from the respective pair. For most cases an identical tic distribution is therefore recommended. \param majors Draw grid between major tics \param minors Draw grid between minor tics \param sides Side(s), where the grid should be drawn */ void CoordinateSystem::setGridLines(bool majors, bool minors, int sides) { sides_ = sides; majorgridlines_ = majors; minorgridlines_ = minors; } void CoordinateSystem::drawMajorGridLines() { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4d(gridlinecolor_.r,gridlinecolor_.g,gridlinecolor_.b,gridlinecolor_.a); setDeviceLineWidth(axes[X1].majLineWidth()); glBegin( GL_LINES ); if (sides_ & Qwt3D::FLOOR) { drawMajorGridLines(axes[X1],axes[X4]); drawMajorGridLines(axes[Y1],axes[Y2]); } if (sides_ & Qwt3D::CEIL) { drawMajorGridLines(axes[X2],axes[X3]); drawMajorGridLines(axes[Y3],axes[Y4]); } if (sides_ & Qwt3D::LEFT) { drawMajorGridLines(axes[Y1],axes[Y4]); drawMajorGridLines(axes[Z1],axes[Z2]); } if (sides_ & Qwt3D::RIGHT) { drawMajorGridLines(axes[Y2],axes[Y3]); drawMajorGridLines(axes[Z3],axes[Z4]); } if (sides_ & Qwt3D::FRONT) { drawMajorGridLines(axes[X1],axes[X2]); drawMajorGridLines(axes[Z2],axes[Z3]); } if (sides_ & Qwt3D::BACK) { drawMajorGridLines(axes[X3],axes[X4]); drawMajorGridLines(axes[Z4],axes[Z1]); } glEnd(); } void CoordinateSystem::drawMinorGridLines() { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4d(gridlinecolor_.r,gridlinecolor_.g,gridlinecolor_.b,gridlinecolor_.a); setDeviceLineWidth(axes[X1].minLineWidth()); glBegin( GL_LINES ); if (sides_ & Qwt3D::FLOOR) { drawMinorGridLines(axes[X1],axes[X4]); drawMinorGridLines(axes[Y1],axes[Y2]); } if (sides_ & Qwt3D::CEIL) { drawMinorGridLines(axes[X2],axes[X3]); drawMinorGridLines(axes[Y3],axes[Y4]); } if (sides_ & Qwt3D::LEFT) { drawMinorGridLines(axes[Y1],axes[Y4]); drawMinorGridLines(axes[Z1],axes[Z2]); } if (sides_ & Qwt3D::RIGHT) { drawMinorGridLines(axes[Y2],axes[Y3]); drawMinorGridLines(axes[Z3],axes[Z4]); } if (sides_ & Qwt3D::FRONT) { drawMinorGridLines(axes[X1],axes[X2]); drawMinorGridLines(axes[Z2],axes[Z3]); } if (sides_ & Qwt3D::BACK) { drawMinorGridLines(axes[X3],axes[X4]); drawMinorGridLines(axes[Z4],axes[Z1]); } glEnd(); } void CoordinateSystem::drawMajorGridLines(Axis& a0, Axis& a1) { Triple d = a1.begin()-a0.begin(); for (unsigned int i=0; i!=a0.majorPositions().size(); ++i) { glVertex3d( a0.majorPositions()[i].x, a0.majorPositions()[i].y, a0.majorPositions()[i].z ); glVertex3d( a0.majorPositions()[i].x + d.x, a0.majorPositions()[i].y + d.y, a0.majorPositions()[i].z +d.z); } } void CoordinateSystem::drawMinorGridLines(Axis& a0, Axis& a1) { Triple d = a1.begin()-a0.begin(); for (unsigned int i=0; i!=a0.minorPositions().size(); ++i) { glVertex3d( a0.minorPositions()[i].x, a0.minorPositions()[i].y, a0.minorPositions()[i].z ); glVertex3d( a0.minorPositions()[i].x + d.x, a0.minorPositions()[i].y + d.y, a0.minorPositions()[i].z +d.z); } } qwtplot3d-0.2.7+svn191/src/qwt3d_enrichment_std.cpp0000644000203200020320000001761610663257610021504 0ustar gudjongudjon#include #include "qwt3d_color.h" #include "qwt3d_plot.h" #include "qwt3d_enrichment_std.h" using namespace Qwt3D; ///////////////////////////////////////////////////////////////// // // CrossHair // ///////////////////////////////////////////////////////////////// CrossHair::CrossHair() { configure(0, 1, false, false); } CrossHair::CrossHair(double rad, double linewidth, bool smooth, bool boxed) { configure(rad, linewidth, smooth, boxed); } void CrossHair::configure(double rad, double linewidth, bool smooth, bool boxed) { plot = 0; radius_ = rad; linewidth_ = linewidth; smooth_ = smooth; boxed_ = boxed; } void CrossHair::drawBegin() { setDeviceLineWidth( linewidth_ ); oldstate_ = glIsEnabled(GL_LINE_SMOOTH); if (smooth_) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH); glBegin( GL_LINES ); } void CrossHair::drawEnd() { glEnd(); if (oldstate_) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH); } void CrossHair::draw(Qwt3D::Triple const& pos) { RGBA rgba = (*plot->dataColor())(pos); glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); double diag = (plot->hull().maxVertex-plot->hull().minVertex).length() * radius_; glVertex3d( pos.x - diag, pos.y, pos.z); glVertex3d( pos.x + diag, pos.y, pos.z); glVertex3d( pos.x, pos.y - diag, pos.z); glVertex3d( pos.x, pos.y + diag, pos.z); glVertex3d( pos.x, pos.y, pos.z - diag); glVertex3d( pos.x, pos.y, pos.z + diag); // hull if (!boxed_) return; glVertex3d( pos.x - diag, pos.y - diag, pos.z + diag); glVertex3d( pos.x + diag, pos.y - diag, pos.z + diag); glVertex3d( pos.x - diag, pos.y - diag, pos.z - diag); glVertex3d( pos.x + diag, pos.y - diag, pos.z - diag); glVertex3d( pos.x - diag, pos.y + diag, pos.z + diag); glVertex3d( pos.x + diag, pos.y + diag, pos.z + diag); glVertex3d( pos.x - diag, pos.y + diag, pos.z - diag); glVertex3d( pos.x + diag, pos.y + diag, pos.z - diag); glVertex3d( pos.x - diag, pos.y - diag, pos.z + diag); glVertex3d( pos.x - diag, pos.y + diag, pos.z + diag); glVertex3d( pos.x - diag, pos.y - diag, pos.z - diag); glVertex3d( pos.x - diag, pos.y + diag, pos.z - diag); glVertex3d( pos.x + diag, pos.y - diag, pos.z + diag); glVertex3d( pos.x + diag, pos.y + diag, pos.z + diag); glVertex3d( pos.x + diag, pos.y - diag, pos.z - diag); glVertex3d( pos.x + diag, pos.y + diag, pos.z - diag); glVertex3d( pos.x - diag, pos.y - diag, pos.z - diag); glVertex3d( pos.x - diag, pos.y - diag, pos.z + diag); glVertex3d( pos.x + diag, pos.y - diag, pos.z - diag); glVertex3d( pos.x + diag, pos.y - diag, pos.z + diag); glVertex3d( pos.x - diag, pos.y + diag, pos.z - diag); glVertex3d( pos.x - diag, pos.y + diag, pos.z + diag); glVertex3d( pos.x + diag, pos.y + diag, pos.z - diag); glVertex3d( pos.x + diag, pos.y + diag, pos.z + diag); } ///////////////////////////////////////////////////////////////// // // Dot // ///////////////////////////////////////////////////////////////// Dot::Dot() { configure(1, false); } Dot::Dot(double pointsize, bool smooth) { configure(pointsize, smooth); } void Dot::configure(double pointsize, bool smooth) { plot = 0; pointsize_ = pointsize; smooth_ = smooth; } void Dot::drawBegin() { setDevicePointSize( pointsize_ ); oldstate_ = glIsEnabled(GL_POINT_SMOOTH); if (smooth_) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); //glPointSize(10); glBegin( GL_POINTS ); } void Dot::drawEnd() { glEnd(); if (oldstate_) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); } void Dot::draw(Qwt3D::Triple const& pos) { RGBA rgba = (*plot->dataColor())(pos); glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); glVertex3d( pos.x, pos.y, pos.z); } ///////////////////////////////////////////////////////////////// // // Cone // ///////////////////////////////////////////////////////////////// Cone::Cone() { hat = gluNewQuadric(); disk = gluNewQuadric(); configure(0, 3); } Cone::Cone(double rad, unsigned quality) { hat = gluNewQuadric(); disk = gluNewQuadric(); configure(rad, quality); } Cone::~Cone() { gluDeleteQuadric(hat); gluDeleteQuadric(disk); } void Cone::configure(double rad, unsigned quality) { plot = 0; radius_ = rad; quality_ = quality; oldstate_ = GL_FALSE; gluQuadricDrawStyle(hat,GLU_FILL); gluQuadricNormals(hat,GLU_SMOOTH); gluQuadricOrientation(hat,GLU_OUTSIDE); gluQuadricDrawStyle(disk,GLU_FILL); gluQuadricNormals(disk,GLU_SMOOTH); gluQuadricOrientation(disk,GLU_OUTSIDE); } void Cone::draw(Qwt3D::Triple const& pos) { RGBA rgba = (*plot->dataColor())(pos); glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); GLint mode; glGetIntegerv(GL_MATRIX_MODE, &mode); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glTranslatef(pos.x, pos.y, pos.z); gluCylinder(hat, 0.0, radius_, radius_*2, quality_, 1); glTranslatef(0, 0, radius_*2); gluDisk(disk, 0.0, radius_, quality_, 1); glPopMatrix(); glMatrixMode(mode); } ///////////////////////////////////////////////////////////////// // // Arrow // ///////////////////////////////////////////////////////////////// Arrow::Arrow() { hat = gluNewQuadric(); disk = gluNewQuadric(); base = gluNewQuadric(); bottom = gluNewQuadric(); gluQuadricDrawStyle(hat,GLU_FILL); gluQuadricNormals(hat,GLU_SMOOTH); gluQuadricOrientation(hat,GLU_OUTSIDE); gluQuadricDrawStyle(disk,GLU_FILL); gluQuadricNormals(disk,GLU_SMOOTH); gluQuadricOrientation(disk,GLU_OUTSIDE); gluQuadricDrawStyle(base,GLU_FILL); gluQuadricNormals(base,GLU_SMOOTH); gluQuadricOrientation(base,GLU_OUTSIDE); gluQuadricDrawStyle(bottom,GLU_FILL); gluQuadricNormals(bottom,GLU_SMOOTH); gluQuadricOrientation(bottom,GLU_OUTSIDE); configure(3, 0.4, 0.06, 0.02); } Arrow::~Arrow() { gluDeleteQuadric(hat); gluDeleteQuadric(disk); gluDeleteQuadric(base); gluDeleteQuadric(bottom); } /** \param segs number of faces for the fields arrows (see the gallery for examples) \param relconelength see picture \param relconerad see picture \param relstemrad see picture \image html arrowanatomy.png */ void Arrow::configure(int segs, double relconelength, double relconerad, double relstemrad) { plot = 0; segments_ = segs; oldstate_ = GL_FALSE; rel_cone_length = relconelength; rel_cone_radius = relconerad; rel_stem_radius = relstemrad; } void Arrow::draw(Qwt3D::Triple const& pos) { Triple end = top_; Triple beg = pos; Triple vdiff = end-beg; double length = vdiff.length(); glColor4d(rgba_.r,rgba_.g,rgba_.b,rgba_.a); double radius[2]; radius[0] = rel_cone_radius * length; radius[1] = rel_stem_radius * length; GLint mode; glGetIntegerv(GL_MATRIX_MODE, &mode); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); Triple axis; double phi = calcRotation(axis, FreeVector(beg,end)); glTranslatef(beg.x, beg.y, beg.z); glRotatef(phi, axis.x, axis.y, axis.z); double baseheight = (1-rel_cone_length) * length; glTranslatef(0, 0, baseheight); gluCylinder(hat, radius[0], 0.0, rel_cone_length * length, segments_,1); gluDisk(disk,radius[1],radius[0], segments_,1); glTranslatef(0, 0, -baseheight); gluCylinder(base, radius[1],radius[1], baseheight,segments_,1); gluDisk(disk,0,radius[1],segments_,1); glPopMatrix(); glMatrixMode(mode); } //! transform a vector on the z axis with length |beg-end|, to get them in coincidence with the vector(beg,end) /** \return Angle in degree to rotate \param axis The axis to rotate around \param beg result vector base point \param end result vector top point */ double Arrow::calcRotation(Triple& axis, FreeVector const& vec) { Triple end = vec.top; Triple beg = vec.base; Triple firstbeg(0.0,0.0,0.0); Triple firstend(0.0,0.0,(end-beg).length()); Triple first = firstend - firstbeg; first.normalize(); Triple second = end-beg; second.normalize(); axis = normalizedcross(first,second); double cosphi = dotProduct(first,second); return 180 * acos(cosphi) / Qwt3D::PI; } qwtplot3d-0.2.7+svn191/src/qwt3d_io.cpp0000644000203200020320000002010110663257610017064 0ustar gudjongudjon#include #include "qwt3d_plot.h" #include "qwt3d_io_gl2ps.h" #include "qwt3d_io_reader.h" #if QT_VERSION < 0x040000 #else #include #endif using namespace Qwt3D; IO::Entry::Entry() : iofunc(0) { } IO::Entry::~Entry() { delete iofunc; } IO::Entry::Entry(IO::Entry const& e) { if (this==&e) return; fmt = e.fmt; iofunc = e.iofunc->clone(); } void IO::Entry::operator=(IO::Entry const& e) { if (this==&e) return; delete iofunc; fmt = e.fmt; iofunc = e.iofunc->clone(); } IO::Entry::Entry(QString const& s, Functor const& f) : fmt(s) { iofunc = f.clone(); } IO::Entry::Entry(QString const& s, Function f) : fmt(s) { Wrapper w(f); iofunc = w.clone(); } IO::FormatCompare::FormatCompare(IO::Entry const& e) { e_ = e; } bool IO::FormatCompare::operator() (IO::Entry const& e) { return ( e.fmt == e_.fmt); } IO::FormatCompare2::FormatCompare2(QString s) { s_ = s; } bool IO::FormatCompare2::operator() (IO::Entry const& e) { return( e.fmt == s_); } bool IO::add_unique(Container& l, Entry const& e) { FormatCompare comp(e); l.erase(std::remove_if(l.begin(), l.end(), comp), l.end()); l.push_back(e); return true; } IO::IT IO::find(Container& l, QString const& fmt) { FormatCompare2 comp(fmt); return std::find_if(l.begin(), l.end(), comp); } IO::Container& IO::rlist() { static Container rl = Container(); static bool rfirst = true; bool f = false; f = rfirst; if (rfirst) { rfirst = false; setupHandler(); } return rl; } IO::Container& IO::wlist() { static Container wl = Container(); static bool wfirst = true; bool f = false; f = wfirst; if (wfirst) { wfirst = false; setupHandler(); } return wl; } /*! Registers a new IO::Function for data input.\n Every call overwrites a formerly registered handler for the same format string (case sensitive). */ bool IO::defineInputHandler(QString const& format, IO::Function func) { return add_unique(rlist(), Entry(format, func)); } /*! Registers a new Functor for data input.\n Every call overwrites a formerly registered handler for the same format string (case sensitive). */ bool IO::defineInputHandler(QString const& format, IO::Functor const& func) { return add_unique(rlist(), Entry(format, func)); } /*! Registers a new IO::Function for data output. Every call overwrites a formerly registered handler for the same format string (case sensitive). */ bool IO::defineOutputHandler(QString const& format, IO::Function func) { return add_unique(wlist(), Entry(format, func)); } /*! Registers a new Functor for data output.\n Every call overwrites a formerly registered handler for the same format string (case sensitive). */ bool IO::defineOutputHandler(QString const& format, IO::Functor const& func) { return add_unique(wlist(), Entry(format, func)); } /*! Applies a reading IO::Function or IO::Functor. \param plot Plot with the content that should be loaded \param fname File name \param format Input format \return The return value from the called Function/Functor. The function returns false, if no registered handler could be found. */ bool IO::load(Plot3D* plot, QString const& fname, QString const& format) { IT it = IO::find(rlist(), format); if (it == rlist().end()) return false; return (*it->iofunc)(plot, fname); } /*! Applies a writing IO::Function or IO::Functor. \param plot Plot with the content that should be saved \param fname File name \param format Output format \return The return value from the called Function/Functor. The function returns false, if no registered handler could be found. */ bool IO::save(Plot3D* plot, QString const& fname, QString const& format) { IT it = IO::find(wlist(), format); if (it == wlist().end()) return false; return (*it->iofunc)(plot, fname); } /*! Returns a list of currently registered input formats. */ QStringList IO::inputFormatList() { QStringList list; for ( IT it = rlist().begin(); it!=rlist().end(); ++it ) list.append(it->fmt); return list; } /*! Returns a list of currently registered output formats. */ QStringList IO::outputFormatList() { QStringList list; for ( IT it = wlist().begin(); it!=wlist().end(); ++it ) list.append(it->fmt); return list; } /*! Returns the input functor in charge for format and 0 if non-existent. */ IO::Functor* IO::inputHandler(QString const& format) { IO::IT it = IO::find(rlist(), format); if (it==rlist().end()) return 0; return it->iofunc; } /*! Returns the output functor in charge for format and 0 if non-existent. */ IO::Functor* IO::outputHandler(QString const& format) { IO::IT it = IO::find(wlist(), format); if (it==wlist().end()) return 0; return it->iofunc; } bool PixmapWriter::operator()(Plot3D* plot, QString const& fname) { QImage im = plot->grabFrameBuffer(true); #if QT_VERSION < 0x040000 QImageIO iio; iio.setImage(im); #else QImageWriter iio; #endif iio.setFormat(QWT3DLOCAL8BIT(fmt_)); iio.setQuality(quality_); iio.setFileName(fname); #if QT_VERSION < 0x040000 return iio.write(); #else return iio.write(im); #endif } //! Calls Qt's QImageIO::setQuality() function. void PixmapWriter::setQuality(int val) { quality_ = val; } void IO::setupHandler() { #if QT_VERSION < 0x040000 QStringList list = QImage::outputFormatList(); QStringList::Iterator it = list.begin(); #else QList list = QImageWriter::supportedImageFormats(); QList::Iterator it = list.begin(); #endif PixmapWriter qtw; while( it != list.end() ) { qtw.fmt_ = *it; defineOutputHandler(*it, qtw); ++it; } VectorWriter vecfunc; vecfunc.setCompressed(false); vecfunc.setFormat("EPS"); defineOutputHandler("EPS", vecfunc); vecfunc.setFormat("PS"); defineOutputHandler("PS", vecfunc); #ifdef GL2PS_HAVE_ZLIB vecfunc.setCompressed(true); vecfunc.setFormat("EPS_GZ"); defineOutputHandler("EPS_GZ", vecfunc); vecfunc.setFormat("PS_GZ"); defineOutputHandler("PS_GZ", vecfunc); #endif vecfunc.setFormat("PDF"); defineOutputHandler("PDF", vecfunc); vecfunc.setFormat("SVG"); defineOutputHandler("SVG", vecfunc); vecfunc.setFormat("PGF"); defineOutputHandler("PGF", vecfunc); #ifdef GL2PS_HAVE_ZLIB vecfunc.setFormat("SVG_GZ"); defineOutputHandler("SVG_GZ", vecfunc); #endif defineInputHandler("mes", NativeReader()); defineInputHandler("MES", NativeReader()); } /*! \deprecated Use Plot3D::save or IO::save instead. Writes vector data supported by gl2ps. The corresponding format types are "EPS","PS", "PDF", "SVG", or "PGF". If zlib has been configured this will be extended by "EPS_GZ", "PS_GZ" and "SVG_GZ". \b Beware: BSPSORT turns out to behave very slowly and memory consuming, especially in cases where many polygons appear. It is still more exact than SIMPLESORT. */ bool Plot3D::saveVector(QString const& fileName, QString const& format, VectorWriter::TEXTMODE textmode, VectorWriter::SORTMODE sortmode) { if (format == "EPS" || format == "EPS_GZ" || format == "PS" || format == "PS_GZ" || format == "PDF" || format == "SVG" || format == "SVG_GZ" || format == "PGF") { VectorWriter* gl2ps = (VectorWriter*)IO::outputHandler(format); if (gl2ps) { gl2ps->setSortMode(sortmode); gl2ps->setTextMode(textmode); } return IO::save(this, fileName, format); } return false; } /*! \deprecated Use Plot3D::save or IO::save instead. Saves the framebuffer to the file fileName using one of the image file formats supported by Qt. */ bool Plot3D::savePixmap(QString const& fileName, QString const& format) { if (format == "EPS" || format == "EPS_GZ" || format == "PS" || format == "PS_GZ" || format == "PDF" || format == "SVG" || format == "SVG_GZ" || format == "PGF") return false; return IO::save(this, fileName, format); } /*! Saves content in one of the registered output formats. To modify the behaviour for more complex output handling use IO::outputHandler. */ bool Plot3D::save(QString const& fileName, QString const& format) { return IO::save(this, fileName, format); } qwtplot3d-0.2.7+svn191/src/qwt3d_mousekeyboard.cpp0000644000203200020320000002463110663257610021342 0ustar gudjongudjon#if defined(_MSC_VER) /* MSVC Compiler */ #pragma warning ( disable : 4305 ) #pragma warning ( disable : 4786 ) #endif #include "qwt3d_plot.h" using namespace std; using namespace Qwt3D; /** Standard mouse button Function. Prepares the call to mouseMoveEvent \see mouseMoveEvent() */ void Plot3D::mousePressEvent( QMouseEvent *e ) { lastMouseMovePosition_ = e->pos(); mpressed_ = true; } /** Standard mouse button Function. Completes the call to mouseMoveEvent \see mouseMoveEvent() */ void Plot3D::mouseReleaseEvent( QMouseEvent* ) { mpressed_ = false; } /** Standard mouse button Function \see assignMouse() */ void Plot3D::mouseMoveEvent( QMouseEvent *e ) { if (!mpressed_ || !mouseEnabled()) { e->ignore(); return; } #if QT_VERSION < 0x040000 MouseState bstate = e->state(); #else MouseState bstate(e->buttons(),e->modifiers()); #endif QPoint diff = e->pos() - lastMouseMovePosition_; setRotationMouse(bstate, 3, diff); setScaleMouse(bstate, 5, diff); setShiftMouse(bstate, 2, diff); lastMouseMovePosition_ = e->pos(); } void Plot3D::setRotationMouse(MouseState bstate, double accel, QPoint diff) { // Rotation double w = max(1,width()); double h = max(1,height()); double relx = accel*360 * diff.x() / w; double relyz = accel*360 * diff.y() / h; double new_xrot = xRotation(); double new_yrot = yRotation(); double new_zrot = zRotation(); if ( bstate == xrot_mstate_ ) new_xrot = round(xRotation() + relyz) % 360; if ( bstate == yrot_mstate_ ) new_yrot = round(yRotation() + relx) % 360; if ( bstate == zrot_mstate_ ) new_zrot = round(zRotation() + relx) % 360; setRotation(new_xrot, new_yrot, new_zrot); } void Plot3D::setScaleMouse(MouseState bstate, double accel, QPoint diff) { // Scale double w = max(1,width()); double h = max(1,height()); double relx = diff.x() * accel / w; relx = exp(relx) - 1; double relyz = diff.y() * accel / h; relyz = exp(relyz) - 1; double new_xscale = xScale(); double new_yscale = yScale(); double new_zscale = zScale(); if ( bstate == xscale_mstate_) new_xscale = max(0.0,xScale() + relx); if ( bstate == yscale_mstate_) new_yscale = max(0.0,yScale() - relyz); if ( bstate == zscale_mstate_) new_zscale = max(0.0,zScale() - relyz); setScale(new_xscale, new_yscale, new_zscale); if ( bstate == zoom_mstate_) setZoom(max(0.0,zoom() - relyz)); } void Plot3D::setShiftMouse(MouseState bstate, double accel, QPoint diff) { // Shift double w = max(1,width()); double h = max(1,height()); double relx = diff.x() * accel / w; double relyz = diff.y() * accel / h; double new_xshift = xViewportShift(); double new_yshift = yViewportShift(); if ( bstate == xshift_mstate_) new_xshift = xViewportShift() + relx; if ( bstate == yshift_mstate_) new_yshift = yViewportShift() - relyz; setViewportShift(new_xshift, new_yshift); } /** Standard wheel Function - zoom (wheel only) or z-scale (shift+wheel) */ void Plot3D::wheelEvent( QWheelEvent *e ) { if (!mouseEnabled()) return; double accel = 0.05; double step = accel * e->delta() / WHEEL_DELTA ; step = exp(step)-1; #if QT_VERSION < 0x040000 if ( e->state() & Qt::ShiftButton ) #else if ( e->modifiers() & Qt::ShiftModifier ) #endif setScale(xScale(),yScale(), max(0.0,zScale() + step)); else setZoom(max(0.0,zoom() + step )); } /** Sets the key/mousebutton combination for data/coordinatesystem moves inside the widget\n\n default behaviour:\n \verbatim rotate around x axis: Qt::LeftButton rotate around y axis: Qt::LeftButton | Qt::ShiftButton rotate around z axis: Qt::LeftButton scale x: Qt::LeftButton | Qt::AltButton scale y: Qt::LeftButton | Qt::AltButton scale z: Qt::LeftButton | Qt::AltButton | Qt::ShiftButton zoom: Qt::LeftButton | Qt::AltButton | Qt::ControlButton shifting along x: Qt::LeftButton | Qt::ControlButton shifting along y: Qt::LeftButton | Qt::ControlButton \endverbatim mouseMoveEvent() evaluates this function - if overridden, their usefulness becomes somehow limited */ void Plot3D::assignMouse(MouseState xrot, MouseState yrot, MouseState zrot, MouseState xscale, MouseState yscale, MouseState zscale, MouseState zoom, MouseState xshift, MouseState yshift) { xrot_mstate_ = xrot; yrot_mstate_ = yrot; zrot_mstate_ = zrot; xscale_mstate_ = xscale; yscale_mstate_ = yscale; zscale_mstate_ = zscale; zoom_mstate_ = zoom; xshift_mstate_ = xshift; yshift_mstate_ = yshift; } /** The function has no effect if you derive from Plot3D and overrides the mouse Function too careless. In this case check first against mouseEnabled() in your version of mouseMoveEvent() and wheelEvent(). A more fine grained input control can be achieved by combining assignMouse() with enableMouse(). */ void Plot3D::enableMouse(bool val) {mouse_input_enabled_ = val;} /** \see enableMouse() */ void Plot3D::disableMouse(bool val) {mouse_input_enabled_ = !val;} bool Plot3D::mouseEnabled() const {return mouse_input_enabled_;} void Plot3D::keyPressEvent( QKeyEvent *e ) { if (!keyboardEnabled()) { e->ignore(); return; } #if QT_VERSION < 0x040000 int bstate = e->state() & Qt::KeyButtonMask; // filter kbd modifier only KeyboardState keyseq = bstate + e->key(); #else KeyboardState keyseq(e->key(), e->modifiers()); #endif setRotationKeyboard(keyseq, kbd_rot_speed_); setScaleKeyboard(keyseq, kbd_scale_speed_); setShiftKeyboard(keyseq, kbd_shift_speed_); } void Plot3D::setRotationKeyboard(KeyboardState kseq, double speed) { // Rotation double w = max(1,width()); double h = max(1,height()); double relx = speed*360 / w; double relyz = speed*360 / h; double new_xrot = xRotation(); double new_yrot = yRotation(); double new_zrot = zRotation(); if ( kseq == xrot_kstate_[0] ) new_xrot = round(xRotation() + relyz) % 360; if ( kseq == xrot_kstate_[1] ) new_xrot = round(xRotation() - relyz) % 360; if ( kseq == yrot_kstate_[0] ) new_yrot = round(yRotation() + relx) % 360; if ( kseq == yrot_kstate_[1] ) new_yrot = round(yRotation() - relx) % 360; if ( kseq == zrot_kstate_[0] ) new_zrot = round(zRotation() + relx) % 360; if ( kseq == zrot_kstate_[1] ) new_zrot = round(zRotation() - relx) % 360; setRotation(new_xrot, new_yrot, new_zrot); } void Plot3D::setScaleKeyboard(KeyboardState kseq, double speed) { // Scale double w = max(1,width()); double h = max(1,height()); double relx = speed / w; relx = exp(relx) - 1; double relyz = speed / h; relyz = exp(relyz) - 1; double new_xscale = xScale(); double new_yscale = yScale(); double new_zscale = zScale(); if ( kseq == xscale_kstate_[0]) new_xscale = max(0.0,xScale() + relx); if ( kseq == xscale_kstate_[1]) new_xscale = max(0.0,xScale() - relx); if ( kseq == yscale_kstate_[0]) new_yscale = max(0.0,yScale() - relyz); if ( kseq == yscale_kstate_[1]) new_yscale = max(0.0,yScale() + relyz); if ( kseq == zscale_kstate_[0]) new_zscale = max(0.0,zScale() - relyz); if ( kseq == zscale_kstate_[1]) new_zscale = max(0.0,zScale() + relyz); setScale(new_xscale, new_yscale, new_zscale); if ( kseq == zoom_kstate_[0]) setZoom(max(0.0,zoom() - relyz)); if ( kseq == zoom_kstate_[1]) setZoom(max(0.0,zoom() + relyz)); } void Plot3D::setShiftKeyboard(KeyboardState kseq, double speed) { // Shift double w = max(1,width()); double h = max(1,height()); double relx = speed / w; double relyz = speed / h; double new_xshift = xViewportShift(); double new_yshift = yViewportShift(); if ( kseq == xshift_kstate_[0]) new_xshift = xViewportShift() + relx; if ( kseq == xshift_kstate_[1]) new_xshift = xViewportShift() - relx; if ( kseq == yshift_kstate_[0]) new_yshift = yViewportShift() - relyz; if ( kseq == yshift_kstate_[1]) new_yshift = yViewportShift() + relyz; setViewportShift(new_xshift, new_yshift); } /** Sets the keybutton combination for data/coordinatesystem moves inside the widget\n\n default behaviour:\n \verbatim rotate around x axis: [Key_Down, Key_Up] rotate around y axis: SHIFT+[Key_Right, Key_Left] rotate around z axis: [Key_Right, Key_Left] scale x: ALT+[Key_Right, Key_Left] scale y: ALT+[Key_Up, Key_Down] scale z: ALT+SHIFT[Key_Down, Key_Up] zoom: ALT+CTRL+[Key_Down, Key_Up] shifting along x: CTRL+[Key_Right, Key_Left] shifting along z: CTRL+[Key_Down, Key_Up] \endverbatim */ void Plot3D::assignKeyboard( KeyboardState xrot_n, KeyboardState xrot_p ,KeyboardState yrot_n, KeyboardState yrot_p ,KeyboardState zrot_n, KeyboardState zrot_p ,KeyboardState xscale_n, KeyboardState xscale_p ,KeyboardState yscale_n, KeyboardState yscale_p ,KeyboardState zscale_n, KeyboardState zscale_p ,KeyboardState zoom_n, KeyboardState zoom_p ,KeyboardState xshift_n, KeyboardState xshift_p ,KeyboardState yshift_n, KeyboardState yshift_p ) { xrot_kstate_[0] = xrot_n; yrot_kstate_[0] = yrot_n; zrot_kstate_[0] = zrot_n; xrot_kstate_[1] = xrot_p; yrot_kstate_[1] = yrot_p; zrot_kstate_[1] = zrot_p; xscale_kstate_[0] = xscale_n; yscale_kstate_[0] = yscale_n; zscale_kstate_[0] = zscale_n; xscale_kstate_[1] = xscale_p; yscale_kstate_[1] = yscale_p; zscale_kstate_[1] = zscale_p; zoom_kstate_[0] = zoom_n; xshift_kstate_[0] = xshift_n; yshift_kstate_[0] = yshift_n; zoom_kstate_[1] = zoom_p; xshift_kstate_[1] = xshift_p; yshift_kstate_[1] = yshift_p; } /** The function has no effect if you derive from Plot3D and overrides the keyboard Functions too careless. In this case check first against keyboardEnabled() in your version of keyPressEvent() A more fine grained input control can be achieved by combining assignKeyboard() with enableKeyboard(). */ void Plot3D::enableKeyboard(bool val) {kbd_input_enabled_ = val;} /** \see enableKeyboard() */ void Plot3D::disableKeyboard(bool val) {kbd_input_enabled_ = !val;} bool Plot3D::keyboardEnabled() const {return kbd_input_enabled_;} /** Values < 0 are ignored. Default is (3,5,5) */ void Plot3D::setKeySpeed(double rot, double scale, double shift) { if (rot > 0) kbd_rot_speed_ = rot; if (scale > 0) kbd_scale_speed_ = scale; if (shift > 0) kbd_shift_speed_ = shift; } void Plot3D::keySpeed(double& rot, double& scale, double& shift) const { rot = kbd_rot_speed_; scale = kbd_scale_speed_; shift = kbd_shift_speed_; } qwtplot3d-0.2.7+svn191/3rdparty/0000755000203200020320000000000010663257711015620 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/3rdparty/gl2ps/0000755000203200020320000000000010663257711016647 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/3rdparty/gl2ps/COPYING.LGPL0000644000203200020320000006142410663257610020444 0ustar gudjongudjon GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! qwtplot3d-0.2.7+svn191/3rdparty/gl2ps/gl2ps.c0000644000203200020320000054212110663257610020045 0ustar gudjongudjon/* $Id: gl2ps.c 188 2007-08-19 15:51:12Z krischnamurti $ */ /* * GL2PS, an OpenGL to PostScript Printing Library * Copyright (C) 1999-2006 Christophe Geuzaine * * This program is free software; you can redistribute it and/or * modify it under the terms of either: * * a) the GNU Library General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your * option) any later version; or * * b) the GL2PS License as published by Christophe Geuzaine, either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either * the GNU Library General Public License or the GL2PS License for * more details. * * You should have received a copy of the GNU Library General Public * License along with this library in the file named "COPYING.LGPL"; * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. * * You should have received a copy of the GL2PS License with this * library in the file named "COPYING.GL2PS"; if not, I will be glad * to provide one. * * Contributors: * Michael Sweet * Marc Ume * Jean-Francois Remacle * Bart Kaptein * Quy Nguyen-Dai * Sam Buss * Shane Hill * Romain Boman * Rouben Rostamian * Diego Santa Cruz * Shahzad Muzaffar * Lassi Tuura * Guy Barrand * Prabhu Ramachandran * Micha Bieber * Olivier Couet * Shai Ayal * Fabian Wenzel * Ian D. Gay * Cosmin Truta * Baiju Devani * Alexander Danilov * * For the latest info about gl2ps, see http://www.geuz.org/gl2ps/. * Please report all bugs and problems to . */ #include "gl2ps.h" #include #include #include #include #include #include #if defined(GL2PS_HAVE_ZLIB) #include #endif #if defined(GL2PS_HAVE_LIBPNG) #include #endif /********************************************************************* * * Private definitions, data structures and prototypes * *********************************************************************/ /* Magic numbers (assuming that the order of magnitude of window coordinates is 10^3) */ #define GL2PS_EPSILON 5.0e-3F #define GL2PS_ZSCALE 1000.0F #define GL2PS_ZOFFSET 5.0e-2F #define GL2PS_ZOFFSET_LARGE 20.0F #define GL2PS_ZERO(arg) (fabs(arg) < 1.e-20) /* Primitive types */ #define GL2PS_NO_TYPE -1 #define GL2PS_TEXT 1 #define GL2PS_POINT 2 #define GL2PS_LINE 3 #define GL2PS_QUADRANGLE 4 #define GL2PS_TRIANGLE 5 #define GL2PS_PIXMAP 6 #define GL2PS_IMAGEMAP 7 #define GL2PS_IMAGEMAP_WRITTEN 8 #define GL2PS_IMAGEMAP_VISIBLE 9 #define GL2PS_SPECIAL 10 /* BSP tree primitive comparison */ #define GL2PS_COINCIDENT 1 #define GL2PS_IN_FRONT_OF 2 #define GL2PS_IN_BACK_OF 3 #define GL2PS_SPANNING 4 /* 2D BSP tree primitive comparison */ #define GL2PS_POINT_COINCIDENT 0 #define GL2PS_POINT_INFRONT 1 #define GL2PS_POINT_BACK 2 /* Internal feedback buffer pass-through tokens */ #define GL2PS_BEGIN_OFFSET_TOKEN 1 #define GL2PS_END_OFFSET_TOKEN 2 #define GL2PS_BEGIN_BOUNDARY_TOKEN 3 #define GL2PS_END_BOUNDARY_TOKEN 4 #define GL2PS_BEGIN_STIPPLE_TOKEN 5 #define GL2PS_END_STIPPLE_TOKEN 6 #define GL2PS_POINT_SIZE_TOKEN 7 #define GL2PS_LINE_WIDTH_TOKEN 8 #define GL2PS_BEGIN_BLEND_TOKEN 9 #define GL2PS_END_BLEND_TOKEN 10 #define GL2PS_SRC_BLEND_TOKEN 11 #define GL2PS_DST_BLEND_TOKEN 12 #define GL2PS_IMAGEMAP_TOKEN 13 #define GL2PS_DRAW_PIXELS_TOKEN 14 #define GL2PS_TEXT_TOKEN 15 typedef enum { T_UNDEFINED = -1, T_CONST_COLOR = 1, T_VAR_COLOR = 1<<1, T_ALPHA_1 = 1<<2, T_ALPHA_LESS_1 = 1<<3, T_VAR_ALPHA = 1<<4 } GL2PS_TRIANGLE_PROPERTY; typedef GLfloat GL2PSxyz[3]; typedef GLfloat GL2PSplane[4]; typedef struct _GL2PSbsptree2d GL2PSbsptree2d; struct _GL2PSbsptree2d { GL2PSplane plane; GL2PSbsptree2d *front, *back; }; typedef struct { GLint nmax, size, incr, n; char *array; } GL2PSlist; typedef struct _GL2PSbsptree GL2PSbsptree; struct _GL2PSbsptree { GL2PSplane plane; GL2PSlist *primitives; GL2PSbsptree *front, *back; }; typedef struct { GL2PSxyz xyz; GL2PSrgba rgba; } GL2PSvertex; typedef struct { GL2PSvertex vertex[3]; int prop; } GL2PStriangle; typedef struct { GLshort fontsize; char *str, *fontname; /* Note: for a 'special' string, 'alignment' holds the format (PostScript, PDF, etc.) of the special string */ GLint alignment; GLfloat angle; } GL2PSstring; typedef struct { GLsizei width, height; /* Note: for an imagemap, 'type' indicates if it has already been written to the file or not, and 'format' indicates if it is visible or not */ GLenum format, type; GLfloat *pixels; } GL2PSimage; typedef struct _GL2PSimagemap GL2PSimagemap; struct _GL2PSimagemap { GL2PSimage *image; GL2PSimagemap *next; }; typedef struct { GLshort type, numverts; GLushort pattern; char boundary, offset, culled; GLint factor; GLfloat width; GL2PSvertex *verts; union { GL2PSstring *text; GL2PSimage *image; } data; } GL2PSprimitive; typedef struct { #if defined(GL2PS_HAVE_ZLIB) Bytef *dest, *src, *start; uLongf destLen, srcLen; #else int dummy; #endif } GL2PScompress; typedef struct{ GL2PSlist* ptrlist; int gsno, fontno, imno, shno, maskshno, trgroupno; int gsobjno, fontobjno, imobjno, shobjno, maskshobjno, trgroupobjno; } GL2PSpdfgroup; typedef struct { /* General */ GLint format, sort, options, colorsize, colormode, buffersize; char *title, *producer, *filename; GLboolean boundary, blending; GLfloat *feedback, offset[2], lastlinewidth; GLint viewport[4], blendfunc[2], lastfactor; GL2PSrgba *colormap, lastrgba, threshold, bgcolor; GLushort lastpattern; GL2PSvertex lastvertex; GL2PSlist *primitives, *auxprimitives; FILE *stream; GL2PScompress *compress; GLboolean header; /* BSP-specific */ GLint maxbestroot; /* Occlusion culling-specific */ GLboolean zerosurfacearea; GL2PSbsptree2d *imagetree; GL2PSprimitive *primitivetoadd; /* PDF-specific */ int streamlength; GL2PSlist *pdfprimlist, *pdfgrouplist; int *xreflist; int objects_stack; /* available objects */ int extgs_stack; /* graphics state object number */ int font_stack; /* font object number */ int im_stack; /* image object number */ int trgroupobjects_stack; /* xobject numbers */ int shader_stack; /* shader object numbers */ int mshader_stack; /* mask shader object numbers */ /* for image map list */ GL2PSimagemap *imagemap_head; GL2PSimagemap *imagemap_tail; } GL2PScontext; typedef struct { void (*printHeader)(void); void (*printFooter)(void); void (*beginViewport)(GLint viewport[4]); GLint (*endViewport)(void); void (*printPrimitive)(void *data); void (*printFinalPrimitive)(void); const char *file_extension; const char *description; } GL2PSbackend; /* The gl2ps context. gl2ps is not thread safe (we should create a local GL2PScontext during gl2psBeginPage) */ static GL2PScontext *gl2ps = NULL; /* Need to forward-declare this one */ static GLint gl2psPrintPrimitives(void); /********************************************************************* * * Utility routines * *********************************************************************/ static void gl2psMsg(GLint level, const char *fmt, ...) { va_list args; if(!(gl2ps->options & GL2PS_SILENT)){ switch(level){ case GL2PS_INFO : fprintf(stderr, "GL2PS info: "); break; case GL2PS_WARNING : fprintf(stderr, "GL2PS warning: "); break; case GL2PS_ERROR : fprintf(stderr, "GL2PS error: "); break; } va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr, "\n"); } /* if(level == GL2PS_ERROR) exit(1); */ } static void *gl2psMalloc(size_t size) { void *ptr; if(!size) return(NULL); ptr = malloc(size); if(!ptr){ gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory"); exit(1); } return(ptr); } static void *gl2psRealloc(void *ptr, size_t size) { if(!size) return(NULL); ptr = realloc(ptr, size); if(!ptr){ gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory"); exit(1); } return(ptr); } static void gl2psFree(void *ptr) { if(!ptr) return; free(ptr); } static size_t gl2psWriteBigEndian(unsigned long data, size_t bytes) { size_t i; size_t size = sizeof(unsigned long); for(i = 1; i <= bytes; ++i){ fputc(0xff & (data >> (size-i) * 8), gl2ps->stream); } return bytes; } /* zlib compression helper routines */ #if defined(GL2PS_HAVE_ZLIB) static void gl2psSetupCompress(void) { gl2ps->compress = (GL2PScompress*)gl2psMalloc(sizeof(GL2PScompress)); gl2ps->compress->src = NULL; gl2ps->compress->start = NULL; gl2ps->compress->dest = NULL; gl2ps->compress->srcLen = 0; gl2ps->compress->destLen = 0; } static void gl2psFreeCompress(void) { if(!gl2ps->compress) return; gl2psFree(gl2ps->compress->start); gl2psFree(gl2ps->compress->dest); gl2ps->compress->src = NULL; gl2ps->compress->start = NULL; gl2ps->compress->dest = NULL; gl2ps->compress->srcLen = 0; gl2ps->compress->destLen = 0; } static int gl2psAllocCompress(unsigned int srcsize) { gl2psFreeCompress(); if(!gl2ps->compress || !srcsize) return GL2PS_ERROR; gl2ps->compress->srcLen = srcsize; gl2ps->compress->destLen = (int)ceil(1.001 * gl2ps->compress->srcLen + 12); gl2ps->compress->src = (Bytef*)gl2psMalloc(gl2ps->compress->srcLen); gl2ps->compress->start = gl2ps->compress->src; gl2ps->compress->dest = (Bytef*)gl2psMalloc(gl2ps->compress->destLen); return GL2PS_SUCCESS; } static void *gl2psReallocCompress(unsigned int srcsize) { if(!gl2ps->compress || !srcsize) return NULL; if(srcsize < gl2ps->compress->srcLen) return gl2ps->compress->start; gl2ps->compress->srcLen = srcsize; gl2ps->compress->destLen = (int)ceil(1.001 * gl2ps->compress->srcLen + 12); gl2ps->compress->src = (Bytef*)gl2psRealloc(gl2ps->compress->src, gl2ps->compress->srcLen); gl2ps->compress->start = gl2ps->compress->src; gl2ps->compress->dest = (Bytef*)gl2psRealloc(gl2ps->compress->dest, gl2ps->compress->destLen); return gl2ps->compress->start; } static size_t gl2psWriteBigEndianCompress(unsigned long data, size_t bytes) { size_t i; size_t size = sizeof(unsigned long); for(i = 1; i <= bytes; ++i){ *gl2ps->compress->src = (Bytef)(0xff & (data >> (size-i) * 8)); ++gl2ps->compress->src; } return bytes; } static int gl2psDeflate(void) { /* For compatibility with older zlib versions, we use compress(...) instead of compress2(..., Z_BEST_COMPRESSION) */ return compress(gl2ps->compress->dest, &gl2ps->compress->destLen, gl2ps->compress->start, gl2ps->compress->srcLen); } #endif static int gl2psPrintf(const char* fmt, ...) { int ret; va_list args; #if defined(GL2PS_HAVE_ZLIB) unsigned int oldsize = 0; static char buf[1000]; if(gl2ps->options & GL2PS_COMPRESS){ va_start(args, fmt); ret = vsprintf(buf, fmt, args); va_end(args); oldsize = gl2ps->compress->srcLen; gl2ps->compress->start = (Bytef*)gl2psReallocCompress(oldsize + ret); memcpy(gl2ps->compress->start+oldsize, buf, ret); ret = 0; } else{ #endif va_start(args, fmt); ret = vfprintf(gl2ps->stream, fmt, args); va_end(args); #if defined(GL2PS_HAVE_ZLIB) } #endif return ret; } static void gl2psPrintGzipHeader() { #if defined(GL2PS_HAVE_ZLIB) char tmp[10] = {'\x1f', '\x8b', /* magic numbers: 0x1f, 0x8b */ 8, /* compression method: Z_DEFLATED */ 0, /* flags */ 0, 0, 0, 0, /* time */ 2, /* extra flags: max compression */ '\x03'}; /* OS code: 0x03 (Unix) */ if(gl2ps->options & GL2PS_COMPRESS){ gl2psSetupCompress(); /* add the gzip file header */ fwrite(tmp, 10, 1, gl2ps->stream); } #endif } static void gl2psPrintGzipFooter() { #if defined(GL2PS_HAVE_ZLIB) int n; uLong crc, len; char tmp[8]; if(gl2ps->options & GL2PS_COMPRESS){ if(Z_OK != gl2psDeflate()){ gl2psMsg(GL2PS_ERROR, "Zlib deflate error"); } else{ /* determine the length of the header in the zlib stream */ n = 2; /* CMF+FLG */ if(gl2ps->compress->dest[1] & (1<<5)){ n += 4; /* DICTID */ } /* write the data, without the zlib header and footer */ fwrite(gl2ps->compress->dest+n, gl2ps->compress->destLen-(n+4), 1, gl2ps->stream); /* add the gzip file footer */ crc = crc32(0L, gl2ps->compress->start, gl2ps->compress->srcLen); for(n = 0; n < 4; ++n){ tmp[n] = (char)(crc & 0xff); crc >>= 8; } len = gl2ps->compress->srcLen; for(n = 4; n < 8; ++n){ tmp[n] = (char)(len & 0xff); len >>= 8; } fwrite(tmp, 8, 1, gl2ps->stream); } gl2psFreeCompress(); gl2psFree(gl2ps->compress); gl2ps->compress = NULL; } #endif } /* The list handling routines */ static void gl2psListRealloc(GL2PSlist *list, GLint n) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot reallocate NULL list"); return; } if(n <= 0) return; if(!list->array){ list->nmax = n; list->array = (char*)gl2psMalloc(list->nmax * list->size); } else{ if(n > list->nmax){ list->nmax = ((n - 1) / list->incr + 1) * list->incr; list->array = (char*)gl2psRealloc(list->array, list->nmax * list->size); } } } static GL2PSlist *gl2psListCreate(GLint n, GLint incr, GLint size) { GL2PSlist *list; if(n < 0) n = 0; if(incr <= 0) incr = 1; list = (GL2PSlist*)gl2psMalloc(sizeof(GL2PSlist)); list->nmax = 0; list->incr = incr; list->size = size; list->n = 0; list->array = NULL; gl2psListRealloc(list, n); return(list); } static void gl2psListReset(GL2PSlist *list) { if(!list) return; list->n = 0; } static void gl2psListDelete(GL2PSlist *list) { if(!list) return; gl2psFree(list->array); gl2psFree(list); } static void gl2psListAdd(GL2PSlist *list, void *data) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot add into unallocated list"); return; } list->n++; gl2psListRealloc(list, list->n); memcpy(&list->array[(list->n - 1) * list->size], data, list->size); } static int gl2psListNbr(GL2PSlist *list) { if(!list) return 0; return(list->n); } static void *gl2psListPointer(GL2PSlist *list, GLint index) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot point into unallocated list"); return NULL; } if((index < 0) || (index >= list->n)){ gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer"); return NULL; } return(&list->array[index * list->size]); } static void gl2psListSort(GL2PSlist *list, int (*fcmp)(const void *a, const void *b)) { if(!list) return; qsort(list->array, list->n, list->size, fcmp); } static void gl2psListAction(GL2PSlist *list, void (*action)(void *data)) { GLint i; for(i = 0; i < gl2psListNbr(list); i++){ (*action)(gl2psListPointer(list, i)); } } static void gl2psListActionInverse(GL2PSlist *list, void (*action)(void *data)) { GLint i; for(i = gl2psListNbr(list); i > 0; i--){ (*action)(gl2psListPointer(list, i-1)); } } #if defined(GL2PS_HAVE_LIBPNG) static void gl2psListRead(GL2PSlist *list, int index, void *data) { if((index < 0) || (index >= list->n)) gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListRead"); memcpy(data, &list->array[index * list->size], list->size); } static void gl2psEncodeBase64Block(unsigned char in[3], unsigned char out[4], int len) { static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; out[0] = cb64[ in[0] >> 2 ]; out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; out[2] = (len > 1) ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='; out[3] = (len > 2) ? cb64[ in[2] & 0x3f ] : '='; } static void gl2psListEncodeBase64(GL2PSlist *list) { unsigned char *buffer, in[3], out[4]; int i, n, index, len; n = list->n * list->size; buffer = (unsigned char*)gl2psMalloc(n * sizeof(unsigned char)); memcpy(buffer, list->array, n * sizeof(unsigned char)); gl2psListReset(list); index = 0; while(index < n) { len = 0; for(i = 0; i < 3; i++) { if(index < n){ in[i] = buffer[index]; len++; } else{ in[i] = 0; } index++; } if(len) { gl2psEncodeBase64Block(in, out, len); for(i = 0; i < 4; i++) gl2psListAdd(list, &out[i]); } } gl2psFree(buffer); } #endif /* Helpers for rgba colors */ static GLboolean gl2psSameColor(GL2PSrgba rgba1, GL2PSrgba rgba2) { if(!GL2PS_ZERO(rgba1[0] - rgba2[0]) || !GL2PS_ZERO(rgba1[1] - rgba2[1]) || !GL2PS_ZERO(rgba1[2] - rgba2[2])) return GL_FALSE; return GL_TRUE; } static GLboolean gl2psVertsSameColor(const GL2PSprimitive *prim) { int i; for(i = 1; i < prim->numverts; i++){ if(!gl2psSameColor(prim->verts[0].rgba, prim->verts[i].rgba)){ return GL_FALSE; } } return GL_TRUE; } static GLboolean gl2psSameColorThreshold(int n, GL2PSrgba rgba[], GL2PSrgba threshold) { int i; if(n < 2) return GL_TRUE; for(i = 1; i < n; i++){ if(fabs(rgba[0][0] - rgba[i][0]) > threshold[0] || fabs(rgba[0][1] - rgba[i][1]) > threshold[1] || fabs(rgba[0][2] - rgba[i][2]) > threshold[2]) return GL_FALSE; } return GL_TRUE; } static void gl2psSetLastColor(GL2PSrgba rgba) { int i; for(i = 0; i < 3; ++i){ gl2ps->lastrgba[i] = rgba[i]; } } static GLfloat gl2psGetRGB(GL2PSimage *im, GLuint x, GLuint y, GLfloat *red, GLfloat *green, GLfloat *blue) { GLsizei width = im->width; GLsizei height = im->height; GLfloat *pixels = im->pixels; GLfloat *pimag; /* OpenGL image is from down to up, PS image is up to down */ switch(im->format){ case GL_RGBA: pimag = pixels + 4 * (width * (height - 1 - y) + x); break; case GL_RGB: default: pimag = pixels + 3 * (width * (height - 1 - y) + x); break; } *red = *pimag; pimag++; *green = *pimag; pimag++; *blue = *pimag; pimag++; return (im->format == GL_RGBA) ? *pimag : 1.0F; } /* Helper routines for pixmaps */ static GL2PSimage *gl2psCopyPixmap(GL2PSimage *im) { int size; GL2PSimage *image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); image->width = im->width; image->height = im->height; image->format = im->format; image->type = im->type; switch(image->format){ case GL_RGBA: size = image->height * image->width * 4 * sizeof(GLfloat); break; case GL_RGB: default: size = image->height * image->width * 3 * sizeof(GLfloat); break; } image->pixels = (GLfloat*)gl2psMalloc(size); memcpy(image->pixels, im->pixels, size); return image; } static void gl2psFreePixmap(GL2PSimage *im) { if(!im) return; gl2psFree(im->pixels); gl2psFree(im); } #if defined(GL2PS_HAVE_LIBPNG) #if !defined(png_jmpbuf) # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif static void gl2psUserWritePNG(png_structp png_ptr, png_bytep data, png_size_t length) { unsigned int i; GL2PSlist *png = (GL2PSlist*)png_get_io_ptr(png_ptr); for(i = 0; i < length; i++) gl2psListAdd(png, &data[i]); } static void gl2psUserFlushPNG(png_structp png_ptr) { } static void gl2psConvertPixmapToPNG(GL2PSimage *pixmap, GL2PSlist *png) { png_structp png_ptr; png_infop info_ptr; unsigned char *row_data; GLfloat dr, dg, db; int row, col; if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) return; if(!(info_ptr = png_create_info_struct(png_ptr))){ png_destroy_write_struct(&png_ptr, NULL); return; } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return; } png_set_write_fn(png_ptr, (void *)png, gl2psUserWritePNG, gl2psUserFlushPNG); png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, pixmap->width, pixmap->height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); row_data = (unsigned char*)gl2psMalloc(3 * pixmap->width * sizeof(unsigned char)); for(row = 0; row < pixmap->height; row++){ for(col = 0; col < pixmap->width; col++){ gl2psGetRGB(pixmap, col, row, &dr, &dg, &db); row_data[3*col] = (unsigned char)(255. * dr); row_data[3*col+1] = (unsigned char)(255. * dg); row_data[3*col+2] = (unsigned char)(255. * db); } png_write_row(png_ptr, (png_bytep)row_data); } gl2psFree(row_data); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); } #endif /* Helper routines for text strings */ static GLint gl2psAddText(GLint type, const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle) { GLfloat pos[4]; GL2PSprimitive *prim; GLboolean valid; if(!gl2ps || !str || !fontname) return GL2PS_UNINITIALIZED; if(gl2ps->options & GL2PS_NO_TEXT) return GL2PS_SUCCESS; glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = type; prim->boundary = 0; prim->numverts = 1; prim->verts = (GL2PSvertex*)gl2psMalloc(sizeof(GL2PSvertex)); prim->verts[0].xyz[0] = pos[0]; prim->verts[0].xyz[1] = pos[1]; prim->verts[0].xyz[2] = pos[2]; prim->culled = 0; prim->offset = 0; prim->pattern = 0; prim->factor = 0; prim->width = 1; glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba); prim->data.text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring)); prim->data.text->str = (char*)gl2psMalloc((strlen(str)+1)*sizeof(char)); strcpy(prim->data.text->str, str); prim->data.text->fontname = (char*)gl2psMalloc((strlen(fontname)+1)*sizeof(char)); strcpy(prim->data.text->fontname, fontname); prim->data.text->fontsize = fontsize; prim->data.text->alignment = alignment; prim->data.text->angle = angle; gl2psListAdd(gl2ps->auxprimitives, &prim); glPassThrough(GL2PS_TEXT_TOKEN); return GL2PS_SUCCESS; } static GL2PSstring *gl2psCopyText(GL2PSstring *t) { GL2PSstring *text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring)); text->str = (char*)gl2psMalloc((strlen(t->str)+1)*sizeof(char)); strcpy(text->str, t->str); text->fontname = (char*)gl2psMalloc((strlen(t->fontname)+1)*sizeof(char)); strcpy(text->fontname, t->fontname); text->fontsize = t->fontsize; text->alignment = t->alignment; text->angle = t->angle; return text; } static void gl2psFreeText(GL2PSstring *text) { if(!text) return; gl2psFree(text->str); gl2psFree(text->fontname); gl2psFree(text); } /* Helpers for blending modes */ static GLboolean gl2psSupportedBlendMode(GLenum sfactor, GLenum dfactor) { /* returns TRUE if gl2ps supports the argument combination: only two blending modes have been implemented so far */ if( (sfactor == GL_SRC_ALPHA && dfactor == GL_ONE_MINUS_SRC_ALPHA) || (sfactor == GL_ONE && dfactor == GL_ZERO) ) return GL_TRUE; return GL_FALSE; } static void gl2psAdaptVertexForBlending(GL2PSvertex *v) { /* Transforms vertex depending on the actual blending function - currently the vertex v is considered as source vertex and his alpha value is changed to 1.0 if source blending GL_ONE is active. This might be extended in the future */ if(!v || !gl2ps) return; if(gl2ps->options & GL2PS_NO_BLENDING || !gl2ps->blending){ v->rgba[3] = 1.0F; return; } switch(gl2ps->blendfunc[0]){ case GL_ONE: v->rgba[3] = 1.0F; break; default: break; } } static void gl2psAssignTriangleProperties(GL2PStriangle *t) { /* int i; */ t->prop = T_VAR_COLOR; /* Uncommenting the following lines activates an even more fine grained distinction between triangle types - please don't delete, a remarkable amount of PDF handling code inside this file depends on it if activated */ /* t->prop = T_CONST_COLOR; for(i = 0; i < 3; ++i){ if(!GL2PS_ZERO(t->vertex[0].rgba[i] - t->vertex[1].rgba[i]) || !GL2PS_ZERO(t->vertex[1].rgba[i] - t->vertex[2].rgba[i])){ t->prop = T_VAR_COLOR; break; } } */ if(!GL2PS_ZERO(t->vertex[0].rgba[3] - t->vertex[1].rgba[3]) || !GL2PS_ZERO(t->vertex[1].rgba[3] - t->vertex[2].rgba[3])){ t->prop |= T_VAR_ALPHA; } else{ if(t->vertex[0].rgba[3] < 1) t->prop |= T_ALPHA_LESS_1; else t->prop |= T_ALPHA_1; } } static void gl2psFillTriangleFromPrimitive(GL2PStriangle *t, GL2PSprimitive *p, GLboolean assignprops) { t->vertex[0] = p->verts[0]; t->vertex[1] = p->verts[1]; t->vertex[2] = p->verts[2]; if(GL_TRUE == assignprops) gl2psAssignTriangleProperties(t); } static void gl2psInitTriangle(GL2PStriangle *t) { int i; GL2PSvertex vertex = { {-1.0F, -1.0F, -1.0F}, {-1.0F, -1.0F, -1.0F, -1.0F} }; for(i = 0; i < 3; i++) t->vertex[i] = vertex; t->prop = T_UNDEFINED; } /* Miscellaneous helper routines */ static GL2PSprimitive *gl2psCopyPrimitive(GL2PSprimitive *p) { GL2PSprimitive *prim; if(!p){ gl2psMsg(GL2PS_ERROR, "Trying to copy an empty primitive"); return NULL; } prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = p->type; prim->numverts = p->numverts; prim->boundary = p->boundary; prim->offset = p->offset; prim->pattern = p->pattern; prim->factor = p->factor; prim->culled = p->culled; prim->width = p->width; prim->verts = (GL2PSvertex*)gl2psMalloc(p->numverts*sizeof(GL2PSvertex)); memcpy(prim->verts, p->verts, p->numverts * sizeof(GL2PSvertex)); switch(prim->type){ case GL2PS_PIXMAP : prim->data.image = gl2psCopyPixmap(p->data.image); break; case GL2PS_TEXT : case GL2PS_SPECIAL : prim->data.text = gl2psCopyText(p->data.text); break; default: break; } return prim; } static GLboolean gl2psSamePosition(GL2PSxyz p1, GL2PSxyz p2) { if(!GL2PS_ZERO(p1[0] - p2[0]) || !GL2PS_ZERO(p1[1] - p2[1]) || !GL2PS_ZERO(p1[2] - p2[2])) return GL_FALSE; return GL_TRUE; } /********************************************************************* * * 3D sorting routines * *********************************************************************/ static GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane) { return(plane[0] * point[0] + plane[1] * point[1] + plane[2] * point[2] + plane[3]); } static GLfloat gl2psPsca(GLfloat *a, GLfloat *b) { return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); } static void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c) { c[0] = a[1]*b[2] - a[2]*b[1]; c[1] = a[2]*b[0] - a[0]*b[2]; c[2] = a[0]*b[1] - a[1]*b[0]; } static GLfloat gl2psNorm(GLfloat *a) { return (GLfloat)sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]); } static void gl2psGetNormal(GLfloat *a, GLfloat *b, GLfloat *c) { GLfloat norm; gl2psPvec(a, b, c); if(!GL2PS_ZERO(norm = gl2psNorm(c))){ c[0] = c[0] / norm; c[1] = c[1] / norm; c[2] = c[2] / norm; } else{ /* The plane is still wrong despite our tests in gl2psGetPlane. Let's return a dummy value for now (this is a hack: we should do more intelligent tests in GetPlane) */ c[0] = c[1] = 0.0F; c[2] = 1.0F; } } static void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane) { GL2PSxyz v = {0.0F, 0.0F, 0.0F}, w = {0.0F, 0.0F, 0.0F}; switch(prim->type){ case GL2PS_TRIANGLE : case GL2PS_QUADRANGLE : v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; w[0] = prim->verts[2].xyz[0] - prim->verts[0].xyz[0]; w[1] = prim->verts[2].xyz[1] - prim->verts[0].xyz[1]; w[2] = prim->verts[2].xyz[2] - prim->verts[0].xyz[2]; if((GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])) || (GL2PS_ZERO(w[0]) && GL2PS_ZERO(w[1]) && GL2PS_ZERO(w[2]))){ plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; } else{ gl2psGetNormal(v, w, plane); plane[3] = - plane[0] * prim->verts[0].xyz[0] - plane[1] * prim->verts[0].xyz[1] - plane[2] * prim->verts[0].xyz[2]; } break; case GL2PS_LINE : v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; if(GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])){ plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; } else{ if(GL2PS_ZERO(v[0])) w[0] = 1.0F; else if(GL2PS_ZERO(v[1])) w[1] = 1.0F; else w[2] = 1.0F; gl2psGetNormal(v, w, plane); plane[3] = - plane[0] * prim->verts[0].xyz[0] - plane[1] * prim->verts[0].xyz[1] - plane[2] * prim->verts[0].xyz[2]; } break; case GL2PS_POINT : case GL2PS_PIXMAP : case GL2PS_TEXT : case GL2PS_SPECIAL : case GL2PS_IMAGEMAP: plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; break; default : gl2psMsg(GL2PS_ERROR, "Unknown primitive type in BSP tree"); plane[0] = plane[1] = plane[3] = 0.0F; plane[2] = 1.0F; break; } } static void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane, GL2PSvertex *c) { GL2PSxyz v; GLfloat sect; v[0] = b->xyz[0] - a->xyz[0]; v[1] = b->xyz[1] - a->xyz[1]; v[2] = b->xyz[2] - a->xyz[2]; sect = - gl2psComparePointPlane(a->xyz, plane) / gl2psPsca(plane, v); c->xyz[0] = a->xyz[0] + v[0] * sect; c->xyz[1] = a->xyz[1] + v[1] * sect; c->xyz[2] = a->xyz[2] + v[2] * sect; c->rgba[0] = (1 - sect) * a->rgba[0] + sect * b->rgba[0]; c->rgba[1] = (1 - sect) * a->rgba[1] + sect * b->rgba[1]; c->rgba[2] = (1 - sect) * a->rgba[2] + sect * b->rgba[2]; c->rgba[3] = (1 - sect) * a->rgba[3] + sect * b->rgba[3]; } static void gl2psCreateSplitPrimitive(GL2PSprimitive *parent, GL2PSplane plane, GL2PSprimitive *child, GLshort numverts, GLshort *index0, GLshort *index1) { GLshort i; if(parent->type == GL2PS_IMAGEMAP){ child->type = GL2PS_IMAGEMAP; child->data.image = parent->data.image; } else{ if(numverts > 4){ gl2psMsg(GL2PS_WARNING, "%d vertices in polygon", numverts); numverts = 4; } switch(numverts){ case 1 : child->type = GL2PS_POINT; break; case 2 : child->type = GL2PS_LINE; break; case 3 : child->type = GL2PS_TRIANGLE; break; case 4 : child->type = GL2PS_QUADRANGLE; break; default: child->type = GL2PS_NO_TYPE; break; } } child->boundary = 0; /* FIXME: not done! */ child->culled = parent->culled; child->offset = parent->offset; child->pattern = parent->pattern; child->factor = parent->factor; child->width = parent->width; child->numverts = numverts; child->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); for(i = 0; i < numverts; i++){ if(index1[i] < 0){ child->verts[i] = parent->verts[index0[i]]; } else{ gl2psCutEdge(&parent->verts[index0[i]], &parent->verts[index1[i]], plane, &child->verts[i]); } } } static void gl2psAddIndex(GLshort *index0, GLshort *index1, GLshort *nb, GLshort i, GLshort j) { GLint k; for(k = 0; k < *nb; k++){ if((index0[k] == i && index1[k] == j) || (index1[k] == i && index0[k] == j)) return; } index0[*nb] = i; index1[*nb] = j; (*nb)++; } static GLshort gl2psGetIndex(GLshort i, GLshort num) { return (i < num - 1) ? i + 1 : 0; } static GLint gl2psTestSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane) { GLint type = GL2PS_COINCIDENT; GLshort i, j; GLfloat d[5]; for(i = 0; i < prim->numverts; i++){ d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane); } if(prim->numverts < 2){ return 0; } else{ for(i = 0; i < prim->numverts; i++){ j = gl2psGetIndex(i, prim->numverts); if(d[j] > GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF; else if(type != GL2PS_IN_BACK_OF) return 1; if(d[i] < -GL2PS_EPSILON) return 1; } else if(d[j] < -GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF; else if(type != GL2PS_IN_FRONT_OF) return 1; if(d[i] > GL2PS_EPSILON) return 1; } } } return 0; } static GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane, GL2PSprimitive **front, GL2PSprimitive **back) { GLshort i, j, in = 0, out = 0, in0[5], in1[5], out0[5], out1[5]; GLint type; GLfloat d[5]; type = GL2PS_COINCIDENT; for(i = 0; i < prim->numverts; i++){ d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane); } switch(prim->type){ case GL2PS_POINT : if(d[0] > GL2PS_EPSILON) type = GL2PS_IN_BACK_OF; else if(d[0] < -GL2PS_EPSILON) type = GL2PS_IN_FRONT_OF; else type = GL2PS_COINCIDENT; break; default : for(i = 0; i < prim->numverts; i++){ j = gl2psGetIndex(i, prim->numverts); if(d[j] > GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF; else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING; if(d[i] < -GL2PS_EPSILON){ gl2psAddIndex(in0, in1, &in, i, j); gl2psAddIndex(out0, out1, &out, i, j); type = GL2PS_SPANNING; } gl2psAddIndex(out0, out1, &out, j, -1); } else if(d[j] < -GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF; else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING; if(d[i] > GL2PS_EPSILON){ gl2psAddIndex(in0, in1, &in, i, j); gl2psAddIndex(out0, out1, &out, i, j); type = GL2PS_SPANNING; } gl2psAddIndex(in0, in1, &in, j, -1); } else{ gl2psAddIndex(in0, in1, &in, j, -1); gl2psAddIndex(out0, out1, &out, j, -1); } } break; } if(type == GL2PS_SPANNING){ *back = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); *front = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); gl2psCreateSplitPrimitive(prim, plane, *back, out, out0, out1); gl2psCreateSplitPrimitive(prim, plane, *front, in, in0, in1); } return type; } static void gl2psDivideQuad(GL2PSprimitive *quad, GL2PSprimitive **t1, GL2PSprimitive **t2) { *t1 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); *t2 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); (*t1)->type = (*t2)->type = GL2PS_TRIANGLE; (*t1)->numverts = (*t2)->numverts = 3; (*t1)->culled = (*t2)->culled = quad->culled; (*t1)->offset = (*t2)->offset = quad->offset; (*t1)->pattern = (*t2)->pattern = quad->pattern; (*t1)->factor = (*t2)->factor = quad->factor; (*t1)->width = (*t2)->width = quad->width; (*t1)->verts = (GL2PSvertex*)gl2psMalloc(3 * sizeof(GL2PSvertex)); (*t2)->verts = (GL2PSvertex*)gl2psMalloc(3 * sizeof(GL2PSvertex)); (*t1)->verts[0] = quad->verts[0]; (*t1)->verts[1] = quad->verts[1]; (*t1)->verts[2] = quad->verts[2]; (*t1)->boundary = ((quad->boundary & 1) ? 1 : 0) | ((quad->boundary & 2) ? 2 : 0); (*t2)->verts[0] = quad->verts[0]; (*t2)->verts[1] = quad->verts[2]; (*t2)->verts[2] = quad->verts[3]; (*t1)->boundary = ((quad->boundary & 4) ? 2 : 0) | ((quad->boundary & 4) ? 2 : 0); } static int gl2psCompareDepth(const void *a, const void *b) { GL2PSprimitive *q, *w; GLfloat dq = 0.0F, dw = 0.0F, diff; int i; q = *(GL2PSprimitive**)a; w = *(GL2PSprimitive**)b; for(i = 0; i < q->numverts; i++){ dq += q->verts[i].xyz[2]; } dq /= (GLfloat)q->numverts; for(i = 0; i < w->numverts; i++){ dw += w->verts[i].xyz[2]; } dw /= (GLfloat)w->numverts; diff = dq - dw; if(diff > 0.){ return -1; } else if(diff < 0.){ return 1; } else{ return 0; } } static int gl2psTrianglesFirst(const void *a, const void *b) { GL2PSprimitive *q, *w; q = *(GL2PSprimitive**)a; w = *(GL2PSprimitive**)b; return(q->type < w->type ? 1 : -1); } static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root) { GLint i, j, count, best = 1000000, index = 0; GL2PSprimitive *prim1, *prim2; GL2PSplane plane; GLint maxp; if(!gl2psListNbr(primitives)){ gl2psMsg(GL2PS_ERROR, "Cannot fint root in empty primitive list"); return 0; } *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0); if(gl2ps->options & GL2PS_BEST_ROOT){ maxp = gl2psListNbr(primitives); if(maxp > gl2ps->maxbestroot){ maxp = gl2ps->maxbestroot; } for(i = 0; i < maxp; i++){ prim1 = *(GL2PSprimitive**)gl2psListPointer(primitives, i); gl2psGetPlane(prim1, plane); count = 0; for(j = 0; j < gl2psListNbr(primitives); j++){ if(j != i){ prim2 = *(GL2PSprimitive**)gl2psListPointer(primitives, j); count += gl2psTestSplitPrimitive(prim2, plane); } if(count > best) break; } if(count < best){ best = count; index = i; *root = prim1; if(!count) return index; } } /* if(index) gl2psMsg(GL2PS_INFO, "GL2PS_BEST_ROOT was worth it: %d", index); */ return index; } else{ return 0; } } static void gl2psFreeImagemap(GL2PSimagemap *list){ GL2PSimagemap *next; while(list != NULL){ next = list->next; gl2psFree(list->image->pixels); gl2psFree(list->image); gl2psFree(list); list = next; } } static void gl2psFreePrimitive(void *data) { GL2PSprimitive *q; q = *(GL2PSprimitive**)data; gl2psFree(q->verts); if(q->type == GL2PS_TEXT || q->type == GL2PS_SPECIAL){ gl2psFreeText(q->data.text); } else if(q->type == GL2PS_PIXMAP){ gl2psFreePixmap(q->data.image); } gl2psFree(q); } static void gl2psAddPrimitiveInList(GL2PSprimitive *prim, GL2PSlist *list) { GL2PSprimitive *t1, *t2; if(prim->type != GL2PS_QUADRANGLE){ gl2psListAdd(list, &prim); } else{ gl2psDivideQuad(prim, &t1, &t2); gl2psListAdd(list, &t1); gl2psListAdd(list, &t2); gl2psFreePrimitive(&prim); } } static void gl2psFreeBspTree(GL2PSbsptree **tree) { if(*tree){ if((*tree)->back) gl2psFreeBspTree(&(*tree)->back); if((*tree)->primitives){ gl2psListAction((*tree)->primitives, gl2psFreePrimitive); gl2psListDelete((*tree)->primitives); } if((*tree)->front) gl2psFreeBspTree(&(*tree)->front); gl2psFree(*tree); *tree = NULL; } } static GLboolean gl2psGreater(GLfloat f1, GLfloat f2) { if(f1 > f2) return GL_TRUE; else return GL_FALSE; } static GLboolean gl2psLess(GLfloat f1, GLfloat f2) { if(f1 < f2) return GL_TRUE; else return GL_FALSE; } static void gl2psBuildBspTree(GL2PSbsptree *tree, GL2PSlist *primitives) { GL2PSprimitive *prim, *frontprim = NULL, *backprim = NULL; GL2PSlist *frontlist, *backlist; GLint i, index; tree->front = NULL; tree->back = NULL; tree->primitives = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); index = gl2psFindRoot(primitives, &prim); gl2psGetPlane(prim, tree->plane); gl2psAddPrimitiveInList(prim, tree->primitives); frontlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); backlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); for(i = 0; i < gl2psListNbr(primitives); i++){ if(i != index){ prim = *(GL2PSprimitive**)gl2psListPointer(primitives,i); switch(gl2psSplitPrimitive(prim, tree->plane, &frontprim, &backprim)){ case GL2PS_COINCIDENT: gl2psAddPrimitiveInList(prim, tree->primitives); break; case GL2PS_IN_BACK_OF: gl2psAddPrimitiveInList(prim, backlist); break; case GL2PS_IN_FRONT_OF: gl2psAddPrimitiveInList(prim, frontlist); break; case GL2PS_SPANNING: gl2psAddPrimitiveInList(backprim, backlist); gl2psAddPrimitiveInList(frontprim, frontlist); gl2psFreePrimitive(&prim); break; } } } if(gl2psListNbr(tree->primitives)){ gl2psListSort(tree->primitives, gl2psTrianglesFirst); } if(gl2psListNbr(frontlist)){ gl2psListSort(frontlist, gl2psTrianglesFirst); tree->front = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(tree->front, frontlist); } else{ gl2psListDelete(frontlist); } if(gl2psListNbr(backlist)){ gl2psListSort(backlist, gl2psTrianglesFirst); tree->back = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(tree->back, backlist); } else{ gl2psListDelete(backlist); } gl2psListDelete(primitives); } static void gl2psTraverseBspTree(GL2PSbsptree *tree, GL2PSxyz eye, GLfloat epsilon, GLboolean (*compare)(GLfloat f1, GLfloat f2), void (*action)(void *data), int inverse) { GLfloat result; if(!tree) return; result = gl2psComparePointPlane(eye, tree->plane); if(GL_TRUE == compare(result, epsilon)){ gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); if(inverse){ gl2psListActionInverse(tree->primitives, action); } else{ gl2psListAction(tree->primitives, action); } gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); } else if(GL_TRUE == compare(-epsilon, result)){ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); if(inverse){ gl2psListActionInverse(tree->primitives, action); } else{ gl2psListAction(tree->primitives, action); } gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); } else{ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); } } static void gl2psRescaleAndOffset() { GL2PSprimitive *prim; GLfloat minZ, maxZ, rangeZ, scaleZ; GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ; int i, j; if(!gl2psListNbr(gl2ps->primitives)) return; /* get z-buffer range */ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, 0); minZ = maxZ = prim->verts[0].xyz[2]; for(i = 1; i < prim->numverts; i++){ if(prim->verts[i].xyz[2] < minZ) minZ = prim->verts[i].xyz[2]; if(prim->verts[i].xyz[2] > maxZ) maxZ = prim->verts[i].xyz[2]; } for(i = 1; i < gl2psListNbr(gl2ps->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i); for(j = 0; j < prim->numverts; j++){ if(prim->verts[j].xyz[2] < minZ) minZ = prim->verts[j].xyz[2]; if(prim->verts[j].xyz[2] > maxZ) maxZ = prim->verts[j].xyz[2]; } } rangeZ = (maxZ - minZ); /* rescale z-buffer coordinate in [0,GL2PS_ZSCALE], to make it of the same order of magnitude as the x and y coordinates */ scaleZ = GL2PS_ZERO(rangeZ) ? GL2PS_ZSCALE : (GL2PS_ZSCALE / rangeZ); /* avoid precision loss (we use floats!) */ if(scaleZ > 100000.F) scaleZ = 100000.F; /* apply offsets */ for(i = 0; i < gl2psListNbr(gl2ps->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i); for(j = 0; j < prim->numverts; j++){ prim->verts[j].xyz[2] = (prim->verts[j].xyz[2] - minZ) * scaleZ; } if((gl2ps->options & GL2PS_SIMPLE_LINE_OFFSET) && (prim->type == GL2PS_LINE)){ if(gl2ps->sort == GL2PS_SIMPLE_SORT){ prim->verts[0].xyz[2] -= GL2PS_ZOFFSET_LARGE; prim->verts[1].xyz[2] -= GL2PS_ZOFFSET_LARGE; } else{ prim->verts[0].xyz[2] -= GL2PS_ZOFFSET; prim->verts[1].xyz[2] -= GL2PS_ZOFFSET; } } else if(prim->offset && (prim->type == GL2PS_TRIANGLE)){ factor = gl2ps->offset[0]; units = gl2ps->offset[1]; area = (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) - (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]); dZdX = ((prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) * (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) - (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) * (prim->verts[2].xyz[2] - prim->verts[1].xyz[2])) / area; dZdY = ((prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) - (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * (prim->verts[1].xyz[2] - prim->verts[0].xyz[2])) / area; maxdZ = (GLfloat)sqrt(dZdX * dZdX + dZdY * dZdY); dZ = factor * maxdZ + units; prim->verts[0].xyz[2] += dZ; prim->verts[1].xyz[2] += dZ; prim->verts[2].xyz[2] += dZ; } } } /********************************************************************* * * 2D sorting routines (for occlusion culling) * *********************************************************************/ static GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane) { GLfloat n; plane[0] = b[1] - a[1]; plane[1] = a[0] - b[0]; n = (GLfloat)sqrt(plane[0]*plane[0] + plane[1]*plane[1]); plane[2] = 0.0F; if(!GL2PS_ZERO(n)){ plane[0] /= n; plane[1] /= n; plane[3] = -plane[0]*a[0]-plane[1]*a[1]; return 1; } else{ plane[0] = -1.0F; plane[1] = 0.0F; plane[3] = a[0]; return 0; } } static void gl2psFreeBspImageTree(GL2PSbsptree2d **tree) { if(*tree){ if((*tree)->back) gl2psFreeBspImageTree(&(*tree)->back); if((*tree)->front) gl2psFreeBspImageTree(&(*tree)->front); gl2psFree(*tree); *tree = NULL; } } static GLint gl2psCheckPoint(GL2PSxyz point, GL2PSplane plane) { GLfloat pt_dis; pt_dis = gl2psComparePointPlane(point, plane); if(pt_dis > GL2PS_EPSILON) return GL2PS_POINT_INFRONT; else if(pt_dis < -GL2PS_EPSILON) return GL2PS_POINT_BACK; else return GL2PS_POINT_COINCIDENT; } static void gl2psAddPlanesInBspTreeImage(GL2PSprimitive *prim, GL2PSbsptree2d **tree) { GLint ret = 0; GLint i; GLint offset = 0; GL2PSbsptree2d *head = NULL, *cur = NULL; if((*tree == NULL) && (prim->numverts > 2)){ head = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); for(i = 0; i < prim->numverts-1; i++){ if(!gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[i+1].xyz, head->plane)){ if(prim->numverts-i > 3){ offset++; } else{ gl2psFree(head); return; } } else{ break; } } head->back = NULL; head->front = NULL; for(i = 2+offset; i < prim->numverts; i++){ ret = gl2psCheckPoint(prim->verts[i].xyz, head->plane); if(ret != GL2PS_POINT_COINCIDENT) break; } switch(ret){ case GL2PS_POINT_INFRONT : cur = head; for(i = 1+offset; i < prim->numverts-1; i++){ if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[i+1].xyz, cur->front->plane)){ cur = cur->front; cur->front = NULL; cur->back = NULL; } } if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[offset].xyz, cur->front->plane)){ cur->front->front = NULL; cur->front->back = NULL; } else{ gl2psFree(cur->front); cur->front = NULL; } break; case GL2PS_POINT_BACK : for(i = 0; i < 4; i++){ head->plane[i] = -head->plane[i]; } cur = head; for(i = 1+offset; i < prim->numverts-1; i++){ if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i+1].xyz, prim->verts[i].xyz, cur->front->plane)){ cur = cur->front; cur->front = NULL; cur->back = NULL; } } if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[offset].xyz, prim->verts[i].xyz, cur->front->plane)){ cur->front->front = NULL; cur->front->back = NULL; } else{ gl2psFree(cur->front); cur->front = NULL; } break; default: gl2psFree(head); return; } (*tree) = head; } } static GLint gl2psCheckPrimitive(GL2PSprimitive *prim, GL2PSplane plane) { GLint i; GLint pos; pos = gl2psCheckPoint(prim->verts[0].xyz, plane); for(i = 1; i < prim->numverts; i++){ pos |= gl2psCheckPoint(prim->verts[i].xyz, plane); if(pos == (GL2PS_POINT_INFRONT | GL2PS_POINT_BACK)) return GL2PS_SPANNING; } if(pos & GL2PS_POINT_INFRONT) return GL2PS_IN_FRONT_OF; else if(pos & GL2PS_POINT_BACK) return GL2PS_IN_BACK_OF; else return GL2PS_COINCIDENT; } static GL2PSprimitive *gl2psCreateSplitPrimitive2D(GL2PSprimitive *parent, GLshort numverts, GL2PSvertex *vertx) { GLint i; GL2PSprimitive *child = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); if(parent->type == GL2PS_IMAGEMAP){ child->type = GL2PS_IMAGEMAP; child->data.image = parent->data.image; } else { switch(numverts){ case 1 : child->type = GL2PS_POINT; break; case 2 : child->type = GL2PS_LINE; break; case 3 : child->type = GL2PS_TRIANGLE; break; case 4 : child->type = GL2PS_QUADRANGLE; break; default: child->type = GL2PS_NO_TYPE; break; /* FIXME */ } } child->boundary = 0; /* FIXME: not done! */ child->culled = parent->culled; child->offset = parent->offset; child->pattern = parent->pattern; child->factor = parent->factor; child->width = parent->width; child->numverts = numverts; child->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); for(i = 0; i < numverts; i++){ child->verts[i] = vertx[i]; } return child; } static void gl2psSplitPrimitive2D(GL2PSprimitive *prim, GL2PSplane plane, GL2PSprimitive **front, GL2PSprimitive **back) { /* cur will hold the position of the current vertex prev will hold the position of the previous vertex prev0 will hold the position of the vertex number 0 v1 and v2 represent the current and previous vertices, respectively flag is set if the current vertex should be checked against the plane */ GLint cur = -1, prev = -1, i, v1 = 0, v2 = 0, flag = 1, prev0 = -1; /* list of vertices that will go in front and back primitive */ GL2PSvertex *front_list = NULL, *back_list = NULL; /* number of vertices in front and back list */ GLshort front_count = 0, back_count = 0; for(i = 0; i <= prim->numverts; i++){ v1 = i; if(v1 == prim->numverts){ if(prim->numverts < 3) break; v1 = 0; v2 = prim->numverts-1; cur = prev0; } else if(flag){ cur = gl2psCheckPoint(prim->verts[v1].xyz, plane); if(i == 0){ prev0 = cur; } } if(((prev == -1) || (prev == cur) || (prev == 0) || (cur == 0)) && (i < prim->numverts)){ if(cur == GL2PS_POINT_INFRONT){ front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); front_list[front_count-1] = prim->verts[v1]; } else if(cur == GL2PS_POINT_BACK){ back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = prim->verts[v1]; } else{ front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); front_list[front_count-1] = prim->verts[v1]; back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = prim->verts[v1]; } flag = 1; } else if((prev != cur) && (cur != 0) && (prev != 0)){ if(v1 != 0){ v2 = v1-1; i--; } front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); gl2psCutEdge(&prim->verts[v2], &prim->verts[v1], plane, &front_list[front_count-1]); back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = front_list[front_count-1]; flag = 0; } prev = cur; } *front = gl2psCreateSplitPrimitive2D(prim, front_count, front_list); *back = gl2psCreateSplitPrimitive2D(prim, back_count, back_list); gl2psFree(front_list); gl2psFree(back_list); } static GLint gl2psAddInBspImageTree(GL2PSprimitive *prim, GL2PSbsptree2d **tree) { GLint ret = 0; GL2PSprimitive *frontprim = NULL, *backprim = NULL; /* FIXME: until we consider the actual extent of text strings and pixmaps, never cull them. Otherwise the whole string/pixmap gets culled as soon as the reference point is hidden */ if(prim->type == GL2PS_PIXMAP || prim->type == GL2PS_TEXT || prim->type == GL2PS_SPECIAL){ return 1; } if(*tree == NULL){ if((prim->type != GL2PS_IMAGEMAP) && (GL_FALSE == gl2ps->zerosurfacearea)){ gl2psAddPlanesInBspTreeImage(gl2ps->primitivetoadd, tree); } return 1; } else{ switch(gl2psCheckPrimitive(prim, (*tree)->plane)){ case GL2PS_IN_BACK_OF: return gl2psAddInBspImageTree(prim, &(*tree)->back); case GL2PS_IN_FRONT_OF: if((*tree)->front != NULL) return gl2psAddInBspImageTree(prim, &(*tree)->front); else return 0; case GL2PS_SPANNING: gl2psSplitPrimitive2D(prim, (*tree)->plane, &frontprim, &backprim); ret = gl2psAddInBspImageTree(backprim, &(*tree)->back); if((*tree)->front != NULL){ if(gl2psAddInBspImageTree(frontprim, &(*tree)->front)){ ret = 1; } } gl2psFree(frontprim->verts); gl2psFree(frontprim); gl2psFree(backprim->verts); gl2psFree(backprim); return ret; case GL2PS_COINCIDENT: if((*tree)->back != NULL){ gl2ps->zerosurfacearea = GL_TRUE; ret = gl2psAddInBspImageTree(prim, &(*tree)->back); gl2ps->zerosurfacearea = GL_FALSE; if(ret) return ret; } if((*tree)->front != NULL){ gl2ps->zerosurfacearea = GL_TRUE; ret = gl2psAddInBspImageTree(prim, &(*tree)->front); gl2ps->zerosurfacearea = GL_FALSE; if(ret) return ret; } if(prim->type == GL2PS_LINE) return 1; else return 0; } } return 0; } static void gl2psAddInImageTree(void *data) { GL2PSprimitive *prim = *(GL2PSprimitive **)data; gl2ps->primitivetoadd = prim; if(prim->type == GL2PS_IMAGEMAP && prim->data.image->format == GL2PS_IMAGEMAP_VISIBLE){ prim->culled = 1; } else if(!gl2psAddInBspImageTree(prim, &gl2ps->imagetree)){ prim->culled = 1; } else if(prim->type == GL2PS_IMAGEMAP){ prim->data.image->format = GL2PS_IMAGEMAP_VISIBLE; } } /* Boundary construction */ static void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list) { GL2PSprimitive *b; GLshort i; GL2PSxyz c; c[0] = c[1] = c[2] = 0.0F; for(i = 0; i < prim->numverts; i++){ c[0] += prim->verts[i].xyz[0]; c[1] += prim->verts[i].xyz[1]; } c[0] /= prim->numverts; c[1] /= prim->numverts; for(i = 0; i < prim->numverts; i++){ if(prim->boundary & (GLint)pow(2., i)){ b = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); b->type = GL2PS_LINE; b->offset = prim->offset; b->pattern = prim->pattern; b->factor = prim->factor; b->culled = prim->culled; b->width = prim->width; b->boundary = 0; b->numverts = 2; b->verts = (GL2PSvertex*)gl2psMalloc(2 * sizeof(GL2PSvertex)); #if 0 /* FIXME: need to work on boundary offset... */ v[0] = c[0] - prim->verts[i].xyz[0]; v[1] = c[1] - prim->verts[i].xyz[1]; v[2] = 0.0F; norm = gl2psNorm(v); v[0] /= norm; v[1] /= norm; b->verts[0].xyz[0] = prim->verts[i].xyz[0] +0.1*v[0]; b->verts[0].xyz[1] = prim->verts[i].xyz[1] +0.1*v[1]; b->verts[0].xyz[2] = prim->verts[i].xyz[2]; v[0] = c[0] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0]; v[1] = c[1] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1]; norm = gl2psNorm(v); v[0] /= norm; v[1] /= norm; b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0] +0.1*v[0]; b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1] +0.1*v[1]; b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2]; #else b->verts[0].xyz[0] = prim->verts[i].xyz[0]; b->verts[0].xyz[1] = prim->verts[i].xyz[1]; b->verts[0].xyz[2] = prim->verts[i].xyz[2]; b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0]; b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1]; b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2]; #endif b->verts[0].rgba[0] = 0.0F; b->verts[0].rgba[1] = 0.0F; b->verts[0].rgba[2] = 0.0F; b->verts[0].rgba[3] = 0.0F; b->verts[1].rgba[0] = 0.0F; b->verts[1].rgba[1] = 0.0F; b->verts[1].rgba[2] = 0.0F; b->verts[1].rgba[3] = 0.0F; gl2psListAdd(list, &b); } } } static void gl2psBuildPolygonBoundary(GL2PSbsptree *tree) { GLint i; GL2PSprimitive *prim; if(!tree) return; gl2psBuildPolygonBoundary(tree->back); for(i = 0; i < gl2psListNbr(tree->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(tree->primitives, i); if(prim->boundary) gl2psAddBoundaryInList(prim, tree->primitives); } gl2psBuildPolygonBoundary(tree->front); } /********************************************************************* * * Feedback buffer parser * *********************************************************************/ static void gl2psAddPolyPrimitive(GLshort type, GLshort numverts, GL2PSvertex *verts, GLint offset, GLushort pattern, GLint factor, GLfloat width, char boundary) { GL2PSprimitive *prim; prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = type; prim->numverts = numverts; prim->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); memcpy(prim->verts, verts, numverts * sizeof(GL2PSvertex)); prim->boundary = boundary; prim->offset = offset; prim->pattern = pattern; prim->factor = factor; prim->width = width; prim->culled = 0; /* FIXME: here we should have an option to split stretched tris/quads to enhance SIMPLE_SORT */ gl2psListAdd(gl2ps->primitives, &prim); } static GLint gl2psGetVertex(GL2PSvertex *v, GLfloat *p) { GLint i; v->xyz[0] = p[0]; v->xyz[1] = p[1]; v->xyz[2] = p[2]; if(gl2ps->colormode == GL_COLOR_INDEX && gl2ps->colorsize > 0){ i = (GLint)(p[3] + 0.5); v->rgba[0] = gl2ps->colormap[i][0]; v->rgba[1] = gl2ps->colormap[i][1]; v->rgba[2] = gl2ps->colormap[i][2]; v->rgba[3] = gl2ps->colormap[i][3]; return 4; } else{ v->rgba[0] = p[3]; v->rgba[1] = p[4]; v->rgba[2] = p[5]; v->rgba[3] = p[6]; return 7; } } static void gl2psParseFeedbackBuffer(GLint used) { char flag; GLushort pattern = 0; GLboolean boundary; GLint i, sizeoffloat, count, v, vtot, offset = 0, factor = 0, auxindex = 0; GLfloat lwidth = 1.0F, psize = 1.0F; GLfloat *current; GL2PSvertex vertices[3]; GL2PSprimitive *prim; GL2PSimagemap *node; current = gl2ps->feedback; boundary = gl2ps->boundary = GL_FALSE; while(used > 0){ if(GL_TRUE == boundary) gl2ps->boundary = GL_TRUE; switch((GLint)*current){ case GL_POINT_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; gl2psAddPolyPrimitive(GL2PS_POINT, 1, vertices, 0, pattern, factor, psize, 0); break; case GL_LINE_TOKEN : case GL_LINE_RESET_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; i = gl2psGetVertex(&vertices[1], current); current += i; used -= i; gl2psAddPolyPrimitive(GL2PS_LINE, 2, vertices, 0, pattern, factor, lwidth, 0); break; case GL_POLYGON_TOKEN : count = (GLint)current[1]; current += 2; used -= 2; v = vtot = 0; while(count > 0 && used > 0){ i = gl2psGetVertex(&vertices[v], current); gl2psAdaptVertexForBlending(&vertices[v]); current += i; used -= i; count --; vtot++; if(v == 2){ if(GL_TRUE == boundary){ if(!count && vtot == 2) flag = 1|2|4; else if(!count) flag = 2|4; else if(vtot == 2) flag = 1|2; else flag = 2; } else flag = 0; gl2psAddPolyPrimitive(GL2PS_TRIANGLE, 3, vertices, offset, pattern, factor, 1, flag); vertices[1] = vertices[2]; } else v ++; } break; case GL_BITMAP_TOKEN : case GL_DRAW_PIXEL_TOKEN : case GL_COPY_PIXEL_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; break; case GL_PASS_THROUGH_TOKEN : switch((GLint)current[1]){ case GL2PS_BEGIN_OFFSET_TOKEN : offset = 1; break; case GL2PS_END_OFFSET_TOKEN : offset = 0; break; case GL2PS_BEGIN_BOUNDARY_TOKEN : boundary = GL_TRUE; break; case GL2PS_END_BOUNDARY_TOKEN : boundary = GL_FALSE; break; case GL2PS_END_STIPPLE_TOKEN : pattern = factor = 0; break; case GL2PS_BEGIN_BLEND_TOKEN : gl2ps->blending = GL_TRUE; break; case GL2PS_END_BLEND_TOKEN : gl2ps->blending = GL_FALSE; break; case GL2PS_BEGIN_STIPPLE_TOKEN : current += 2; used -= 2; pattern = (GLushort)current[1]; current += 2; used -= 2; factor = (GLint)current[1]; break; case GL2PS_SRC_BLEND_TOKEN : current += 2; used -= 2; gl2ps->blendfunc[0] = (GLint)current[1]; break; case GL2PS_DST_BLEND_TOKEN : current += 2; used -= 2; gl2ps->blendfunc[1] = (GLint)current[1]; break; case GL2PS_POINT_SIZE_TOKEN : current += 2; used -= 2; psize = current[1]; break; case GL2PS_LINE_WIDTH_TOKEN : current += 2; used -= 2; lwidth = current[1]; break; case GL2PS_IMAGEMAP_TOKEN : prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = GL2PS_IMAGEMAP; prim->boundary = 0; prim->numverts = 4; prim->verts = (GL2PSvertex *)gl2psMalloc(4 * sizeof(GL2PSvertex)); prim->culled = 0; prim->offset = 0; prim->pattern = 0; prim->factor = 0; prim->width = 1; node = (GL2PSimagemap*)gl2psMalloc(sizeof(GL2PSimagemap)); node->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); node->image->type = 0; node->image->format = 0; node->next = NULL; if(gl2ps->imagemap_head == NULL) gl2ps->imagemap_head = node; else gl2ps->imagemap_tail->next = node; gl2ps->imagemap_tail = node; prim->data.image = node->image; current += 2; used -= 2; i = gl2psGetVertex(&prim->verts[0], ¤t[1]); current += i; used -= i; node->image->width = (GLint)current[2]; current += 2; used -= 2; node->image->height = (GLint)current[2]; prim->verts[0].xyz[0] = prim->verts[0].xyz[0] - (int)(node->image->width / 2) + 0.5f; prim->verts[0].xyz[1] = prim->verts[0].xyz[1] - (int)(node->image->height / 2) + 0.5f; for(i = 1; i < 4; i++){ for(v = 0; v < 3; v++){ prim->verts[i].xyz[v] = prim->verts[0].xyz[v]; prim->verts[i].rgba[v] = prim->verts[0].rgba[v]; } prim->verts[i].rgba[v] = prim->verts[0].rgba[v]; } prim->verts[1].xyz[0] = prim->verts[1].xyz[0] + node->image->width; prim->verts[2].xyz[0] = prim->verts[1].xyz[0]; prim->verts[2].xyz[1] = prim->verts[2].xyz[1] + node->image->height; prim->verts[3].xyz[1] = prim->verts[2].xyz[1]; sizeoffloat = sizeof(GLfloat); v = 2 * sizeoffloat; vtot = node->image->height + node->image->height * ((node->image->width-1)/8); node->image->pixels = (GLfloat*)gl2psMalloc(v + vtot); node->image->pixels[0] = prim->verts[0].xyz[0]; node->image->pixels[1] = prim->verts[0].xyz[1]; for(i = 0; i < vtot; i += sizeoffloat){ current += 2; used -= 2; if((vtot - i) >= 4) memcpy(&(((char*)(node->image->pixels))[i + v]), &(current[2]), sizeoffloat); else memcpy(&(((char*)(node->image->pixels))[i + v]), &(current[2]), vtot - i); } current++; used--; gl2psListAdd(gl2ps->primitives, &prim); break; case GL2PS_DRAW_PIXELS_TOKEN : case GL2PS_TEXT_TOKEN : if(auxindex < gl2psListNbr(gl2ps->auxprimitives)) gl2psListAdd(gl2ps->primitives, gl2psListPointer(gl2ps->auxprimitives, auxindex++)); else gl2psMsg(GL2PS_ERROR, "Wrong number of auxiliary tokens in buffer"); break; } current += 2; used -= 2; break; default : gl2psMsg(GL2PS_WARNING, "Unknown token in buffer"); current ++; used --; break; } } gl2psListReset(gl2ps->auxprimitives); } /********************************************************************* * * PostScript routines * *********************************************************************/ static void gl2psWriteByte(unsigned char byte) { unsigned char h = byte / 16; unsigned char l = byte % 16; gl2psPrintf("%x%x", h, l); } static void gl2psPrintPostScriptPixmap(GLfloat x, GLfloat y, GL2PSimage *im) { GLuint nbhex, nbyte, nrgb, nbits; GLuint row, col, ibyte, icase; GLfloat dr, dg, db, fgrey; unsigned char red = 0, green = 0, blue = 0, b, grey; GLuint width = (GLuint)im->width; GLuint height = (GLuint)im->height; /* FIXME: should we define an option for these? Or just keep the 8-bit per component case? */ int greyscale = 0; /* set to 1 to output greyscale image */ int nbit = 8; /* number of bits per color compoment (2, 4 or 8) */ if((width <= 0) || (height <= 0)) return; gl2psPrintf("gsave\n"); gl2psPrintf("%.2f %.2f translate\n", x, y); gl2psPrintf("%d %d scale\n", width, height); if(greyscale){ /* greyscale */ gl2psPrintf("/picstr %d string def\n", width); gl2psPrintf("%d %d %d\n", width, height, 8); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile picstr readhexstring pop }\n"); gl2psPrintf("image\n"); for(row = 0; row < height; row++){ for(col = 0; col < width; col++){ gl2psGetRGB(im, col, row, &dr, &dg, &db); fgrey = (0.30f * dr + 0.59f * dg + 0.11f * db); grey = (unsigned char)(255. * fgrey); gl2psWriteByte(grey); } gl2psPrintf("\n"); } nbhex = width * height * 2; gl2psPrintf("%%%% nbhex digit :%d\n", nbhex); } else if(nbit == 2){ /* color, 2 bits for r and g and b; rgbs following each other */ nrgb = width * 3; nbits = nrgb * nbit; nbyte = nbits/8; if((nbyte * 8) != nbits) nbyte++; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, nbit); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ icase = 1; col = 0; b = 0; for(ibyte = 0; ibyte < nbyte; ibyte++){ if(icase == 1) { if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = red; b = (b<<2) + green; b = (b<<2) + blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (b<<2) + red; gl2psWriteByte(b); b = 0; icase++; } else if(icase == 2) { b = green; b = (b<<2) + blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (b<<2) + red; b = (b<<2) + green; gl2psWriteByte(b); b = 0; icase++; } else if(icase == 3) { b = blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (b<<2) + red; b = (b<<2) + green; b = (b<<2) + blue; gl2psWriteByte(b); b = 0; icase = 1; } } gl2psPrintf("\n"); } } else if(nbit == 4){ /* color, 4 bits for r and g and b; rgbs following each other */ nrgb = width * 3; nbits = nrgb * nbit; nbyte = nbits/8; if((nbyte * 8) != nbits) nbyte++; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, nbit); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ col = 0; icase = 1; for(ibyte = 0; ibyte < nbyte; ibyte++){ if(icase == 1) { if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(15. * dr); green = (unsigned char)(15. * dg); gl2psPrintf("%x%x", red, green); icase++; } else if(icase == 2) { blue = (unsigned char)(15. * db); if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(15. * dr); gl2psPrintf("%x%x", blue, red); icase++; } else if(icase == 3) { green = (unsigned char)(15. * dg); blue = (unsigned char)(15. * db); gl2psPrintf("%x%x", green, blue); icase = 1; } } gl2psPrintf("\n"); } } else{ /* 8 bit for r and g and b */ nbyte = width * 3; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, 8); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ for(col = 0; col < width; col++){ gl2psGetRGB(im, col, row, &dr, &dg, &db); red = (unsigned char)(255. * dr); gl2psWriteByte(red); green = (unsigned char)(255. * dg); gl2psWriteByte(green); blue = (unsigned char)(255. * db); gl2psWriteByte(blue); } gl2psPrintf("\n"); } } gl2psPrintf("grestore\n"); } static void gl2psPrintPostScriptImagemap(GLfloat x, GLfloat y, GLsizei width, GLsizei height, const unsigned char *imagemap){ int i, size; if((width <= 0) || (height <= 0)) return; size = height + height * (width-1)/8; gl2psPrintf("gsave\n"); gl2psPrintf("%.2f %.2f translate\n", x, y); gl2psPrintf("%d %d scale\n%d %d\ntrue\n", width, height,width, height); gl2psPrintf("[ %d 0 0 -%d 0 %d ] {<", width, height); for(i = 0; i < size; i++){ gl2psWriteByte(*imagemap); imagemap++; } gl2psPrintf(">} imagemask\ngrestore\n"); } static void gl2psPrintPostScriptHeader(void) { time_t now; /* Since compression is not part of the PostScript standard, compressed PostScript files are just gzipped PostScript files ("ps.gz" or "eps.gz") */ gl2psPrintGzipHeader(); time(&now); if(gl2ps->format == GL2PS_PS){ gl2psPrintf("%%!PS-Adobe-3.0\n"); } else{ gl2psPrintf("%%!PS-Adobe-3.0 EPSF-3.0\n"); } gl2psPrintf("%%%%Title: %s\n" "%%%%Creator: GL2PS %d.%d.%d%s, %s\n" "%%%%For: %s\n" "%%%%CreationDate: %s" "%%%%LanguageLevel: 3\n" "%%%%DocumentData: Clean7Bit\n" "%%%%Pages: 1\n", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); if(gl2ps->format == GL2PS_PS){ gl2psPrintf("%%%%Orientation: %s\n" "%%%%DocumentMedia: Default %d %d 0 () ()\n", (gl2ps->options & GL2PS_LANDSCAPE) ? "Landscape" : "Portrait", (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] : (int)gl2ps->viewport[2], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] : (int)gl2ps->viewport[3]); } gl2psPrintf("%%%%BoundingBox: %d %d %d %d\n" "%%%%EndComments\n", (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[1] : (int)gl2ps->viewport[0], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[0] : (int)gl2ps->viewport[1], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] : (int)gl2ps->viewport[2], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] : (int)gl2ps->viewport[3]); /* RGB color: r g b C (replace C by G in output to change from rgb to gray) Grayscale: r g b G Font choose: size fontname FC Text string: (string) x y size fontname S?? Rotated text string: (string) angle x y size fontname S??R Point primitive: x y size P Line width: width W Line start: x y LS Line joining last point: x y L Line end: x y LE Flat-shaded triangle: x3 y3 x2 y2 x1 y1 T Smooth-shaded triangle: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 ST */ gl2psPrintf("%%%%BeginProlog\n" "/gl2psdict 64 dict def gl2psdict begin\n" "0 setlinecap 0 setlinejoin\n" "/tryPS3shading %s def %% set to false to force subdivision\n" "/rThreshold %g def %% red component subdivision threshold\n" "/gThreshold %g def %% green component subdivision threshold\n" "/bThreshold %g def %% blue component subdivision threshold\n", (gl2ps->options & GL2PS_NO_PS3_SHADING) ? "false" : "true", gl2ps->threshold[0], gl2ps->threshold[1], gl2ps->threshold[2]); gl2psPrintf("/BD { bind def } bind def\n" "/C { setrgbcolor } BD\n" "/G { 0.082 mul exch 0.6094 mul add exch 0.3086 mul add neg 1.0 add setgray } BD\n" "/W { setlinewidth } BD\n"); gl2psPrintf("/FC { findfont exch /SH exch def SH scalefont setfont } BD\n" "/SW { dup stringwidth pop } BD\n" "/S { FC moveto show } BD\n" "/SBC{ FC moveto SW -2 div 0 rmoveto show } BD\n" "/SBR{ FC moveto SW neg 0 rmoveto show } BD\n" "/SCL{ FC moveto 0 SH -2 div rmoveto show } BD\n" "/SCC{ FC moveto SW -2 div SH -2 div rmoveto show } BD\n" "/SCR{ FC moveto SW neg SH -2 div rmoveto show } BD\n" "/STL{ FC moveto 0 SH neg rmoveto show } BD\n" "/STC{ FC moveto SW -2 div SH neg rmoveto show } BD\n" "/STR{ FC moveto SW neg SH neg rmoveto show } BD\n"); /* rotated text routines: same nameanem with R appended */ gl2psPrintf("/FCT { FC translate 0 0 } BD\n" "/SR { gsave FCT moveto rotate show grestore } BD\n" "/SBCR{ gsave FCT moveto rotate SW -2 div 0 rmoveto show grestore } BD\n" "/SBRR{ gsave FCT moveto rotate SW neg 0 rmoveto show grestore } BD\n" "/SCLR{ gsave FCT moveto rotate 0 SH -2 div rmoveto show grestore} BD\n"); gl2psPrintf("/SCCR{ gsave FCT moveto rotate SW -2 div SH -2 div rmoveto show grestore} BD\n" "/SCRR{ gsave FCT moveto rotate SW neg SH -2 div rmoveto show grestore} BD\n" "/STLR{ gsave FCT moveto rotate 0 SH neg rmoveto show grestore } BD\n" "/STCR{ gsave FCT moveto rotate SW -2 div SH neg rmoveto show grestore } BD\n" "/STRR{ gsave FCT moveto rotate SW neg SH neg rmoveto show grestore } BD\n"); gl2psPrintf("/P { newpath 0.0 360.0 arc closepath fill } BD\n" "/LS { newpath moveto } BD\n" "/L { lineto } BD\n" "/LE { lineto stroke } BD\n" "/T { newpath moveto lineto lineto closepath fill } BD\n"); /* Smooth-shaded triangle with PostScript level 3 shfill operator: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STshfill */ gl2psPrintf("/STshfill {\n" " /b1 exch def /g1 exch def /r1 exch def /y1 exch def /x1 exch def\n" " /b2 exch def /g2 exch def /r2 exch def /y2 exch def /x2 exch def\n" " /b3 exch def /g3 exch def /r3 exch def /y3 exch def /x3 exch def\n" " gsave << /ShadingType 4 /ColorSpace [/DeviceRGB]\n" " /DataSource [ 0 x1 y1 r1 g1 b1 0 x2 y2 r2 g2 b2 0 x3 y3 r3 g3 b3 ] >>\n" " shfill grestore } BD\n"); /* Flat-shaded triangle with middle color: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 Tm */ gl2psPrintf(/* stack : x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 */ "/Tm { 3 -1 roll 8 -1 roll 13 -1 roll add add 3 div\n" /* r = (r1+r2+r3)/3 */ /* stack : x3 y3 g3 b3 x2 y2 g2 b2 x1 y1 g1 b1 r */ " 3 -1 roll 7 -1 roll 11 -1 roll add add 3 div\n" /* g = (g1+g2+g3)/3 */ /* stack : x3 y3 b3 x2 y2 b2 x1 y1 b1 r g b */ " 3 -1 roll 6 -1 roll 9 -1 roll add add 3 div" /* b = (b1+b2+b3)/3 */ /* stack : x3 y3 x2 y2 x1 y1 r g b */ " C T } BD\n"); /* Split triangle in four sub-triangles (at sides middle points) and call the STnoshfill procedure on each, interpolating the colors in RGB space: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STsplit (in procedure comments key: (Vi) = xi yi ri gi bi) */ gl2psPrintf("/STsplit {\n" " 4 index 15 index add 0.5 mul\n" /* x13 = (x1+x3)/2 */ " 4 index 15 index add 0.5 mul\n" /* y13 = (y1+y3)/2 */ " 4 index 15 index add 0.5 mul\n" /* r13 = (r1+r3)/2 */ " 4 index 15 index add 0.5 mul\n" /* g13 = (g1+g3)/2 */ " 4 index 15 index add 0.5 mul\n" /* b13 = (b1+b3)/2 */ " 5 copy 5 copy 25 15 roll\n"); /* at his point, stack = (V3) (V13) (V13) (V13) (V2) (V1) */ gl2psPrintf(" 9 index 30 index add 0.5 mul\n" /* x23 = (x2+x3)/2 */ " 9 index 30 index add 0.5 mul\n" /* y23 = (y2+y3)/2 */ " 9 index 30 index add 0.5 mul\n" /* r23 = (r2+r3)/2 */ " 9 index 30 index add 0.5 mul\n" /* g23 = (g2+g3)/2 */ " 9 index 30 index add 0.5 mul\n" /* b23 = (b2+b3)/2 */ " 5 copy 5 copy 35 5 roll 25 5 roll 15 5 roll\n"); /* stack = (V3) (V13) (V23) (V13) (V23) (V13) (V23) (V2) (V1) */ gl2psPrintf(" 4 index 10 index add 0.5 mul\n" /* x12 = (x1+x2)/2 */ " 4 index 10 index add 0.5 mul\n" /* y12 = (y1+y2)/2 */ " 4 index 10 index add 0.5 mul\n" /* r12 = (r1+r2)/2 */ " 4 index 10 index add 0.5 mul\n" /* g12 = (g1+g2)/2 */ " 4 index 10 index add 0.5 mul\n" /* b12 = (b1+b2)/2 */ " 5 copy 5 copy 40 5 roll 25 5 roll 15 5 roll 25 5 roll\n"); /* stack = (V3) (V13) (V23) (V13) (V12) (V23) (V13) (V1) (V12) (V23) (V12) (V2) */ gl2psPrintf(" STnoshfill STnoshfill STnoshfill STnoshfill } BD\n"); /* Gouraud shaded triangle using recursive subdivision until the difference between corner colors does not exceed the thresholds: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STnoshfill */ gl2psPrintf("/STnoshfill {\n" " 2 index 8 index sub abs rThreshold gt\n" /* |r1-r2|>rth */ " { STsplit }\n" " { 1 index 7 index sub abs gThreshold gt\n" /* |g1-g2|>gth */ " { STsplit }\n" " { dup 6 index sub abs bThreshold gt\n" /* |b1-b2|>bth */ " { STsplit }\n" " { 2 index 13 index sub abs rThreshold gt\n" /* |r1-r3|>rht */ " { STsplit }\n" " { 1 index 12 index sub abs gThreshold gt\n" /* |g1-g3|>gth */ " { STsplit }\n" " { dup 11 index sub abs bThreshold gt\n" /* |b1-b3|>bth */ " { STsplit }\n" " { 7 index 13 index sub abs rThreshold gt\n"); /* |r2-r3|>rht */ gl2psPrintf(" { STsplit }\n" " { 6 index 12 index sub abs gThreshold gt\n" /* |g2-g3|>gth */ " { STsplit }\n" " { 5 index 11 index sub abs bThreshold gt\n" /* |b2-b3|>bth */ " { STsplit }\n" " { Tm }\n" /* all colors sufficiently similar */ " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse } BD\n"); gl2psPrintf("tryPS3shading\n" "{ /shfill where\n" " { /ST { STshfill } BD }\n" " { /ST { STnoshfill } BD }\n" " ifelse }\n" "{ /ST { STnoshfill } BD }\n" "ifelse\n"); gl2psPrintf("end\n" "%%%%EndProlog\n" "%%%%BeginSetup\n" "/DeviceRGB setcolorspace\n" "gl2psdict begin\n" "%%%%EndSetup\n" "%%%%Page: 1 1\n" "%%%%BeginPageSetup\n"); if(gl2ps->options & GL2PS_LANDSCAPE){ gl2psPrintf("%d 0 translate 90 rotate\n", (int)gl2ps->viewport[3]); } gl2psPrintf("%%%%EndPageSetup\n" "mark\n" "gsave\n" "1.0 1.0 scale\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psPrintf("%g %g %g C\n" "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath fill\n", gl2ps->bgcolor[0], gl2ps->bgcolor[1], gl2ps->bgcolor[2], (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3], (int)gl2ps->viewport[0], (int)gl2ps->viewport[3]); } } static void gl2psPrintPostScriptColor(GL2PSrgba rgba) { if(!gl2psSameColor(gl2ps->lastrgba, rgba)){ gl2psSetLastColor(rgba); gl2psPrintf("%g %g %g C\n", rgba[0], rgba[1], rgba[2]); } } static void gl2psResetPostScriptColor(void) { gl2ps->lastrgba[0] = gl2ps->lastrgba[1] = gl2ps->lastrgba[2] = -1.; } static void gl2psEndPostScriptLine(void) { int i; if(gl2ps->lastvertex.rgba[0] >= 0.){ gl2psPrintf("%g %g LE\n", gl2ps->lastvertex.xyz[0], gl2ps->lastvertex.xyz[1]); for(i = 0; i < 3; i++) gl2ps->lastvertex.xyz[i] = -1.; for(i = 0; i < 4; i++) gl2ps->lastvertex.rgba[i] = -1.; } } static void gl2psParseStipplePattern(GLushort pattern, GLint factor, int *nb, int array[10]) { int i, n; int on[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int off[8] = {0, 0, 0, 0, 0, 0, 0, 0}; char tmp[16]; /* extract the 16 bits from the OpenGL stipple pattern */ for(n = 15; n >= 0; n--){ tmp[n] = (char)(pattern & 0x01); pattern >>= 1; } /* compute the on/off pixel sequence */ n = 0; for(i = 0; i < 8; i++){ while(n < 16 && !tmp[n]){ off[i]++; n++; } while(n < 16 && tmp[n]){ on[i]++; n++; } if(n >= 15){ i++; break; } } /* store the on/off array from right to left, starting with off pixels. The PostScript specification allows for at most 11 elements in the on/off array, so we limit ourselves to 5 on/off couples (our longest possible array is thus [on4 off4 on3 off3 on2 off2 on1 off1 on0 off0]) */ *nb = 0; for(n = i - 1; n >= 0; n--){ array[(*nb)++] = factor * on[n]; array[(*nb)++] = factor * off[n]; if(*nb == 10) break; } } static int gl2psPrintPostScriptDash(GLushort pattern, GLint factor, char *str) { int len = 0, i, n, array[10]; if(pattern == gl2ps->lastpattern && factor == gl2ps->lastfactor) return 0; gl2ps->lastpattern = pattern; gl2ps->lastfactor = factor; if(!pattern || !factor){ /* solid line */ len += gl2psPrintf("[] 0 %s\n", str); } else{ gl2psParseStipplePattern(pattern, factor, &n, array); len += gl2psPrintf("["); for(i = 0; i < n; i++){ if(i) len += gl2psPrintf(" "); len += gl2psPrintf("%d", array[i]); } len += gl2psPrintf("] 0 %s\n", str); } return len; } static void gl2psPrintPostScriptPrimitive(void *data) { int newline; GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; /* Every effort is made to draw lines as connected segments (i.e., using a single PostScript path): this is the only way to get nice line joins and to not restart the stippling for every line segment. So if the primitive to print is not a line we must first finish the current line (if any): */ if(prim->type != GL2PS_LINE) gl2psEndPostScriptLine(); switch(prim->type){ case GL2PS_POINT : gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %g P\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], 0.5 * prim->width); break; case GL2PS_LINE : if(!gl2psSamePosition(gl2ps->lastvertex.xyz, prim->verts[0].xyz) || !gl2psSameColor(gl2ps->lastrgba, prim->verts[0].rgba) || gl2ps->lastlinewidth != prim->width || gl2ps->lastpattern != prim->pattern || gl2ps->lastfactor != prim->factor){ /* End the current line if the new segment does not start where the last one ended, or if the color, the width or the stippling have changed (multi-stroking lines with changing colors is necessary until we use /shfill for lines; unfortunately this means that at the moment we can screw up line stippling for smooth-shaded lines) */ gl2psEndPostScriptLine(); newline = 1; } else{ newline = 0; } if(gl2ps->lastlinewidth != prim->width){ gl2ps->lastlinewidth = prim->width; gl2psPrintf("%g W\n", gl2ps->lastlinewidth); } gl2psPrintPostScriptDash(prim->pattern, prim->factor, "setdash"); gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %s\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], newline ? "LS" : "L"); gl2ps->lastvertex = prim->verts[1]; break; case GL2PS_TRIANGLE : if(!gl2psVertsSameColor(prim)){ gl2psResetPostScriptColor(); gl2psPrintf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ST\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[2].rgba[0], prim->verts[2].rgba[1], prim->verts[2].rgba[2], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[1].rgba[0], prim->verts[1].rgba[1], prim->verts[1].rgba[2], prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2]); } else{ gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %g %g %g %g T\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; case GL2PS_QUADRANGLE : gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print"); break; case GL2PS_PIXMAP : gl2psPrintPostScriptPixmap(prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->data.image); break; case GL2PS_IMAGEMAP : if(prim->data.image->type != GL2PS_IMAGEMAP_WRITTEN){ gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintPostScriptImagemap(prim->data.image->pixels[0], prim->data.image->pixels[1], prim->data.image->width, prim->data.image->height, (const unsigned char*)(&(prim->data.image->pixels[2]))); prim->data.image->type = GL2PS_IMAGEMAP_WRITTEN; } break; case GL2PS_TEXT : gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("(%s) ", prim->data.text->str); if(prim->data.text->angle) gl2psPrintf("%g ", prim->data.text->angle); gl2psPrintf("%g %g %d /%s ", prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->data.text->fontsize, prim->data.text->fontname); switch(prim->data.text->alignment){ case GL2PS_TEXT_C: gl2psPrintf(prim->data.text->angle ? "SCCR\n" : "SCC\n"); break; case GL2PS_TEXT_CL: gl2psPrintf(prim->data.text->angle ? "SCLR\n" : "SCL\n"); break; case GL2PS_TEXT_CR: gl2psPrintf(prim->data.text->angle ? "SCRR\n" : "SCR\n"); break; case GL2PS_TEXT_B: gl2psPrintf(prim->data.text->angle ? "SBCR\n" : "SBC\n"); break; case GL2PS_TEXT_BR: gl2psPrintf(prim->data.text->angle ? "SBRR\n" : "SBR\n"); break; case GL2PS_TEXT_T: gl2psPrintf(prim->data.text->angle ? "STCR\n" : "STC\n"); break; case GL2PS_TEXT_TL: gl2psPrintf(prim->data.text->angle ? "STLR\n" : "STL\n"); break; case GL2PS_TEXT_TR: gl2psPrintf(prim->data.text->angle ? "STRR\n" : "STR\n"); break; case GL2PS_TEXT_BL: default: gl2psPrintf(prim->data.text->angle ? "SR\n" : "S\n"); break; } break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(prim->data.text->alignment == GL2PS_PS || prim->data.text->alignment == GL2PS_EPS) gl2psPrintf("%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintPostScriptFooter(void) { gl2psPrintf("grestore\n" "showpage\n" "cleartomark\n" "%%%%PageTrailer\n" "%%%%Trailer\n" "end\n" "%%%%EOF\n"); gl2psPrintGzipFooter(); } static void gl2psPrintPostScriptBeginViewport(GLint viewport[4]) { GLint index; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintPostScriptHeader(); gl2ps->header = GL_FALSE; } gl2psPrintf("gsave\n" "1.0 1.0 scale\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index); rgba[0] = gl2ps->colormap[index][0]; rgba[1] = gl2ps->colormap[index][1]; rgba[2] = gl2ps->colormap[index][2]; rgba[3] = 1.0F; } gl2psPrintf("%g %g %g C\n" "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath fill\n", rgba[0], rgba[1], rgba[2], x, y, x+w, y, x+w, y+h, x, y+h); } gl2psPrintf("newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath clip\n", x, y, x+w, y, x+w, y+h, x, y+h); } static GLint gl2psPrintPostScriptEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2psPrintf("grestore\n"); return res; } static void gl2psPrintPostScriptFinalPrimitive(void) { /* End any remaining line, if any */ gl2psEndPostScriptLine(); } /* definition of the PostScript and Encapsulated PostScript backends */ static GL2PSbackend gl2psPS = { gl2psPrintPostScriptHeader, gl2psPrintPostScriptFooter, gl2psPrintPostScriptBeginViewport, gl2psPrintPostScriptEndViewport, gl2psPrintPostScriptPrimitive, gl2psPrintPostScriptFinalPrimitive, "ps", "Postscript" }; static GL2PSbackend gl2psEPS = { gl2psPrintPostScriptHeader, gl2psPrintPostScriptFooter, gl2psPrintPostScriptBeginViewport, gl2psPrintPostScriptEndViewport, gl2psPrintPostScriptPrimitive, gl2psPrintPostScriptFinalPrimitive, "eps", "Encapsulated Postscript" }; /********************************************************************* * * LaTeX routines * *********************************************************************/ static void gl2psPrintTeXHeader(void) { char name[256]; time_t now; int i; if(gl2ps->filename && strlen(gl2ps->filename) < 256){ for(i = strlen(gl2ps->filename)-1; i >= 0; i--){ if(gl2ps->filename[i] == '.'){ strncpy(name, gl2ps->filename, i); name[i] = '\0'; break; } } if(i <= 0) strcpy(name, gl2ps->filename); } else{ strcpy(name, "untitled"); } time(&now); fprintf(gl2ps->stream, "%% Title: %s\n" "%% Creator: GL2PS %d.%d.%d%s, %s\n" "%% For: %s\n" "%% CreationDate: %s", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); fprintf(gl2ps->stream, "\\setlength{\\unitlength}{1pt}\n" "\\begin{picture}(0,0)\n" "\\includegraphics{%s}\n" "\\end{picture}%%\n" "%s\\begin{picture}(%d,%d)(0,0)\n", name, (gl2ps->options & GL2PS_LANDSCAPE) ? "\\rotatebox{90}{" : "", (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); } static void gl2psPrintTeXPrimitive(void *data) { GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; switch(prim->type){ case GL2PS_TEXT : fprintf(gl2ps->stream, "\\fontsize{%d}{0}\n\\selectfont", prim->data.text->fontsize); fprintf(gl2ps->stream, "\\put(%g,%g){\\makebox(0,0)", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); switch(prim->data.text->alignment){ case GL2PS_TEXT_C: fprintf(gl2ps->stream, "{"); break; case GL2PS_TEXT_CL: fprintf(gl2ps->stream, "[l]{"); break; case GL2PS_TEXT_CR: fprintf(gl2ps->stream, "[r]{"); break; case GL2PS_TEXT_B: fprintf(gl2ps->stream, "[b]{"); break; case GL2PS_TEXT_BR: fprintf(gl2ps->stream, "[br]{"); break; case GL2PS_TEXT_T: fprintf(gl2ps->stream, "[t]{"); break; case GL2PS_TEXT_TL: fprintf(gl2ps->stream, "[tl]{"); break; case GL2PS_TEXT_TR: fprintf(gl2ps->stream, "[tr]{"); break; case GL2PS_TEXT_BL: default: fprintf(gl2ps->stream, "[bl]{"); break; } if(prim->data.text->angle) fprintf(gl2ps->stream, "\\rotatebox{%g}{", prim->data.text->angle); fprintf(gl2ps->stream, "\\textcolor[rgb]{%g,%g,%g}{{%s}}", prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2], prim->data.text->str); if(prim->data.text->angle) fprintf(gl2ps->stream, "}"); fprintf(gl2ps->stream, "}}\n"); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if (prim->data.text->alignment == GL2PS_TEX) fprintf(gl2ps->stream, "%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintTeXFooter(void) { fprintf(gl2ps->stream, "\\end{picture}%s\n", (gl2ps->options & GL2PS_LANDSCAPE) ? "}" : ""); } static void gl2psPrintTeXBeginViewport(GLint viewport[4]) { glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintTeXHeader(); gl2ps->header = GL_FALSE; } } static GLint gl2psPrintTeXEndViewport(void) { return gl2psPrintPrimitives(); } static void gl2psPrintTeXFinalPrimitive(void) { } /* definition of the LaTeX backend */ static GL2PSbackend gl2psTEX = { gl2psPrintTeXHeader, gl2psPrintTeXFooter, gl2psPrintTeXBeginViewport, gl2psPrintTeXEndViewport, gl2psPrintTeXPrimitive, gl2psPrintTeXFinalPrimitive, "tex", "LaTeX text" }; /********************************************************************* * * PDF routines * *********************************************************************/ static int gl2psPrintPDFCompressorType(void) { #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ return fprintf(gl2ps->stream, "/Filter [/FlateDecode]\n"); } #endif return 0; } static int gl2psPrintPDFStrokeColor(GL2PSrgba rgba) { int i, offs = 0; gl2psSetLastColor(rgba); for(i = 0; i < 3; ++i){ if(GL2PS_ZERO(rgba[i])) offs += gl2psPrintf("%.0f ", 0.); else if(rgba[i] < 1e-4 || rgba[i] > 1e6) /* avoid %e formatting */ offs += gl2psPrintf("%f ", rgba[i]); else offs += gl2psPrintf("%g ", rgba[i]); } offs += gl2psPrintf("RG\n"); return offs; } static int gl2psPrintPDFFillColor(GL2PSrgba rgba) { int i, offs = 0; for(i = 0; i < 3; ++i){ if(GL2PS_ZERO(rgba[i])) offs += gl2psPrintf("%.0f ", 0.); else if(rgba[i] < 1e-4 || rgba[i] > 1e6) /* avoid %e formatting */ offs += gl2psPrintf("%f ", rgba[i]); else offs += gl2psPrintf("%g ", rgba[i]); } offs += gl2psPrintf("rg\n"); return offs; } static int gl2psPrintPDFLineWidth(GLfloat lw) { if(GL2PS_ZERO(lw)) return gl2psPrintf("%.0f w\n", 0.); else if(lw < 1e-4 || lw > 1e6) /* avoid %e formatting */ return gl2psPrintf("%f w\n", lw); else return gl2psPrintf("%g w\n", lw); } static void gl2psPutPDFText(GL2PSstring *text, int cnt, GLfloat x, GLfloat y) { gl2ps->streamlength += gl2psPrintf("BT\n" "/F%d %d Tf\n" "%f %f Td\n" "(%s) Tj\n" "ET\n", cnt, text->fontsize, x, y, text->str); } static void gl2psPutPDFImage(GL2PSimage *image, int cnt, GLfloat x, GLfloat y) { gl2ps->streamlength += gl2psPrintf("q\n" "%d 0 0 %d %f %f cm\n" "/Im%d Do\n" "Q\n", (int)image->width, (int)image->height, x, y, cnt); } static void gl2psPDFstacksInit(void) { gl2ps->objects_stack = 7 /* FIXED_XREF_ENTRIES */ + 1; gl2ps->extgs_stack = 0; gl2ps->font_stack = 0; gl2ps->im_stack = 0; gl2ps->trgroupobjects_stack = 0; gl2ps->shader_stack = 0; gl2ps->mshader_stack = 0; } static void gl2psPDFgroupObjectInit(GL2PSpdfgroup *gro) { if(!gro) return; gro->ptrlist = NULL; gro->fontno = gro->gsno = gro->imno = gro->maskshno = gro->shno = gro->trgroupno = gro->fontobjno = gro->imobjno = gro->shobjno = gro->maskshobjno = gro->gsobjno = gro->trgroupobjno = -1; } /* Build up group objects and assign name and object numbers */ static void gl2psPDFgroupListInit(void) { int i; GL2PSprimitive *p = NULL; GL2PSpdfgroup gro; int lasttype = GL2PS_NO_TYPE; GL2PSrgba lastrgba = {-1.0F, -1.0F, -1.0F, -1.0F}; GLushort lastpattern = 0; GLint lastfactor = 0; GLfloat lastwidth = 1; GL2PStriangle lastt, tmpt; int lastTriangleWasNotSimpleWithSameColor = 0; if(!gl2ps->pdfprimlist) return; gl2ps->pdfgrouplist = gl2psListCreate(500, 500, sizeof(GL2PSpdfgroup)); gl2psInitTriangle(&lastt); for(i = 0; i < gl2psListNbr(gl2ps->pdfprimlist); ++i){ p = *(GL2PSprimitive**)gl2psListPointer(gl2ps->pdfprimlist, i); switch(p->type){ case GL2PS_PIXMAP: gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gro.imno = gl2ps->im_stack++; gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); break; case GL2PS_TEXT: gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gro.fontno = gl2ps->font_stack++; gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); break; case GL2PS_LINE: if(lasttype != p->type || lastwidth != p->width || lastpattern != p->pattern || lastfactor != p->factor || !gl2psSameColor(p->verts[0].rgba, lastrgba)){ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } else{ gl2psListAdd(gro.ptrlist, &p); } lastpattern = p->pattern; lastfactor = p->factor; lastwidth = p->width; lastrgba[0] = p->verts[0].rgba[0]; lastrgba[1] = p->verts[0].rgba[1]; lastrgba[2] = p->verts[0].rgba[2]; break; case GL2PS_POINT: if(lasttype != p->type || lastwidth != p->width || !gl2psSameColor(p->verts[0].rgba, lastrgba)){ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1,2,sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } else{ gl2psListAdd(gro.ptrlist, &p); } lastwidth = p->width; lastrgba[0] = p->verts[0].rgba[0]; lastrgba[1] = p->verts[0].rgba[1]; lastrgba[2] = p->verts[0].rgba[2]; break; case GL2PS_TRIANGLE: gl2psFillTriangleFromPrimitive(&tmpt, p, GL_TRUE); lastTriangleWasNotSimpleWithSameColor = !(tmpt.prop & T_CONST_COLOR && tmpt.prop & T_ALPHA_1) || !gl2psSameColor(tmpt.vertex[0].rgba, lastt.vertex[0].rgba); if(lasttype == p->type && tmpt.prop == lastt.prop && lastTriangleWasNotSimpleWithSameColor){ /* TODO Check here for last alpha */ gl2psListAdd(gro.ptrlist, &p); } else{ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } lastt = tmpt; break; default: break; } lasttype = p->type; } } static void gl2psSortOutTrianglePDFgroup(GL2PSpdfgroup *gro) { GL2PStriangle t; GL2PSprimitive *prim = NULL; if(!gro) return; if(!gl2psListNbr(gro->ptrlist)) return; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); if(prim->type != GL2PS_TRIANGLE) return; gl2psFillTriangleFromPrimitive(&t, prim, GL_TRUE); if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_LESS_1){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack ++; } else if(t.prop & T_CONST_COLOR && t.prop & T_VAR_ALPHA){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->trgroupno = gl2ps->trgroupobjects_stack++; gro->trgroupobjno = gl2ps->objects_stack++; gro->maskshno = gl2ps->mshader_stack++; gro->maskshobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_1){ gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_LESS_1){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_VAR_ALPHA){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; gro->trgroupno = gl2ps->trgroupobjects_stack++; gro->trgroupobjno = gl2ps->objects_stack++; gro->maskshno = gl2ps->mshader_stack++; gro->maskshobjno = gl2ps->objects_stack++; } } /* Main stream data */ static void gl2psPDFgroupListWriteMainStream(void) { int i, j, lastel; GL2PSprimitive *prim = NULL, *prev = NULL; GL2PSpdfgroup *gro; GL2PStriangle t; if(!gl2ps->pdfgrouplist) return; for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); lastel = gl2psListNbr(gro->ptrlist) - 1; if(lastel < 0) continue; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(prim->type){ case GL2PS_POINT: gl2ps->streamlength += gl2psPrintf("1 J\n"); gl2ps->streamlength += gl2psPrintPDFLineWidth(prim->width); gl2ps->streamlength += gl2psPrintPDFStrokeColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2ps->streamlength += gl2psPrintf("%f %f m %f %f l\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } gl2ps->streamlength += gl2psPrintf("S\n"); gl2ps->streamlength += gl2psPrintf("0 J\n"); break; case GL2PS_LINE: /* We try to use as few paths as possible to draw lines, in order to get nice stippling even when the individual segments are smaller than the stipple */ gl2ps->streamlength += gl2psPrintPDFLineWidth(prim->width); gl2ps->streamlength += gl2psPrintPDFStrokeColor(prim->verts[0].rgba); gl2ps->streamlength += gl2psPrintPostScriptDash(prim->pattern, prim->factor, "d"); /* start new path */ gl2ps->streamlength += gl2psPrintf("%f %f m\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); for(j = 1; j <= lastel; ++j){ prev = prim; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); if(!gl2psSamePosition(prim->verts[0].xyz, prev->verts[1].xyz)){ /* the starting point of the new segment does not match the end point of the previous line, so we end the current path and start a new one */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prev->verts[1].xyz[0], prev->verts[1].xyz[1]); gl2ps->streamlength += gl2psPrintf("%f %f m\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } else{ /* the two segements are connected, so we just append to the current path */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } } /* end last path */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prim->verts[1].xyz[0], prim->verts[1].xyz[1]); gl2ps->streamlength += gl2psPrintf("S\n"); break; case GL2PS_TRIANGLE: gl2psFillTriangleFromPrimitive(&t, prim, GL_TRUE); gl2psSortOutTrianglePDFgroup(gro); /* No alpha and const color: Simple PDF draw orders */ if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_1){ gl2ps->streamlength += gl2psPrintPDFFillColor(t.vertex[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } } /* Const alpha < 1 and const color: Simple PDF draw orders and an extra extended Graphics State for the alpha const */ else if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_LESS_1){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n", gro->gsno); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } gl2ps->streamlength += gl2psPrintf("Q\n"); } /* Variable alpha and const color: Simple PDF draw orders and an extra extended Graphics State + Xobject + Shader object for the alpha mask */ else if(t.prop & T_CONST_COLOR && t.prop & T_VAR_ALPHA){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/TrG%d Do\n", gro->gsno, gro->trgroupno); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } gl2ps->streamlength += gl2psPrintf("Q\n"); } /* Variable color and no alpha: Shader Object for the colored triangle(s) */ else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_1){ gl2ps->streamlength += gl2psPrintf("/Sh%d sh\n", gro->shno); } /* Variable color and const alpha < 1: Shader Object for the colored triangle(s) and an extra extended Graphics State for the alpha const */ else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_LESS_1){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/Sh%d sh\n" "Q\n", gro->gsno, gro->shno); } /* Variable alpha and color: Shader Object for the colored triangle(s) and an extra extended Graphics State + Xobject + Shader object for the alpha mask */ else if(t.prop & T_VAR_COLOR && t.prop & T_VAR_ALPHA){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/TrG%d Do\n" "/Sh%d sh\n" "Q\n", gro->gsno, gro->trgroupno, gro->shno); } break; case GL2PS_PIXMAP: for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psPutPDFImage(prim->data.image, gro->imno, prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; case GL2PS_TEXT: for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); gl2psPutPDFText(prim->data.text, gro->fontno, prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; default: break; } } } /* Graphics State names */ static int gl2psPDFgroupListWriteGStateResources(void) { GL2PSpdfgroup *gro; int offs = 0; int i; offs += fprintf(gl2ps->stream, "/ExtGState\n" "<<\n" "/GSa 7 0 R\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->gsno >= 0) offs += fprintf(gl2ps->stream, "/GS%d %d 0 R\n", gro->gsno, gro->gsobjno); } offs += fprintf(gl2ps->stream, ">>\n"); return offs; } /* Main Shader names */ static int gl2psPDFgroupListWriteShaderResources(void) { GL2PSpdfgroup *gro; int offs = 0; int i; offs += fprintf(gl2ps->stream, "/Shading\n" "<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->shno >= 0) offs += fprintf(gl2ps->stream, "/Sh%d %d 0 R\n", gro->shno, gro->shobjno); if(gro->maskshno >= 0) offs += fprintf(gl2ps->stream, "/TrSh%d %d 0 R\n", gro->maskshno, gro->maskshobjno); } offs += fprintf(gl2ps->stream,">>\n"); return offs; } /* Images & Mask Shader XObject names */ static int gl2psPDFgroupListWriteXObjectResources(void) { int i; GL2PSprimitive *p = NULL; GL2PSpdfgroup *gro; int offs = 0; offs += fprintf(gl2ps->stream, "/XObject\n" "<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(!gl2psListNbr(gro->ptrlist)) continue; p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(p->type){ case GL2PS_PIXMAP: gro->imobjno = gl2ps->objects_stack++; if(GL_RGBA == p->data.image->format) /* reserve one object for image mask */ gl2ps->objects_stack++; offs += fprintf(gl2ps->stream, "/Im%d %d 0 R\n", gro->imno, gro->imobjno); case GL2PS_TRIANGLE: if(gro->trgroupno >=0) offs += fprintf(gl2ps->stream, "/TrG%d %d 0 R\n", gro->trgroupno, gro->trgroupobjno); break; default: break; } } offs += fprintf(gl2ps->stream,">>\n"); return offs; } /* Font names */ static int gl2psPDFgroupListWriteFontResources(void) { int i; GL2PSpdfgroup *gro; int offs = 0; offs += fprintf(gl2ps->stream, "/Font\n<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->fontno < 0) continue; gro->fontobjno = gl2ps->objects_stack++; offs += fprintf(gl2ps->stream, "/F%d %d 0 R\n", gro->fontno, gro->fontobjno); } offs += fprintf(gl2ps->stream, ">>\n"); return offs; } static void gl2psPDFgroupListDelete(void) { int i; GL2PSpdfgroup *gro = NULL; if(!gl2ps->pdfgrouplist) return; for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist,i); gl2psListDelete(gro->ptrlist); } gl2psListDelete(gl2ps->pdfgrouplist); gl2ps->pdfgrouplist = NULL; } /* Print 1st PDF object - file info */ static int gl2psPrintPDFInfo(void) { int offs; time_t now; struct tm *newtime; time(&now); newtime = gmtime(&now); offs = fprintf(gl2ps->stream, "1 0 obj\n" "<<\n" "/Title (%s)\n" "/Creator (GL2PS %d.%d.%d%s, %s)\n" "/Producer (%s)\n", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer); if(!newtime){ offs += fprintf(gl2ps->stream, ">>\n" "endobj\n"); return offs; } offs += fprintf(gl2ps->stream, "/CreationDate (D:%d%02d%02d%02d%02d%02d)\n" ">>\n" "endobj\n", newtime->tm_year+1900, newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec); return offs; } /* Create catalog and page structure - 2nd and 3th PDF object */ static int gl2psPrintPDFCatalog(void) { return fprintf(gl2ps->stream, "2 0 obj\n" "<<\n" "/Type /Catalog\n" "/Pages 3 0 R\n" ">>\n" "endobj\n"); } static int gl2psPrintPDFPages(void) { return fprintf(gl2ps->stream, "3 0 obj\n" "<<\n" "/Type /Pages\n" "/Kids [6 0 R]\n" "/Count 1\n" ">>\n" "endobj\n"); } /* Open stream for data - graphical objects, fonts etc. PDF object 4 */ static int gl2psOpenPDFDataStream(void) { int offs = 0; offs += fprintf(gl2ps->stream, "4 0 obj\n" "<<\n" "/Length 5 0 R\n" ); offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, ">>\n" "stream\n"); return offs; } /* Stream setup - Graphics state, fill background if allowed */ static int gl2psOpenPDFDataStreamWritePreface(void) { int offs; offs = gl2psPrintf("/GSa gs\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ offs += gl2psPrintPDFFillColor(gl2ps->bgcolor); offs += gl2psPrintf("%d %d %d %d re\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); offs += gl2psPrintf("f\n"); } return offs; } /* Use the functions above to create the first part of the PDF*/ static void gl2psPrintPDFHeader(void) { int offs = 0; gl2ps->pdfprimlist = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); gl2psPDFstacksInit(); gl2ps->xreflist = (int*)gl2psMalloc(sizeof(int) * gl2ps->objects_stack); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psSetupCompress(); } #endif gl2ps->xreflist[0] = 0; offs += fprintf(gl2ps->stream, "%%PDF-1.4\n"); gl2ps->xreflist[1] = offs; offs += gl2psPrintPDFInfo(); gl2ps->xreflist[2] = offs; offs += gl2psPrintPDFCatalog(); gl2ps->xreflist[3] = offs; offs += gl2psPrintPDFPages(); gl2ps->xreflist[4] = offs; offs += gl2psOpenPDFDataStream(); gl2ps->xreflist[5] = offs; /* finished in gl2psPrintPDFFooter */ gl2ps->streamlength = gl2psOpenPDFDataStreamWritePreface(); } /* The central primitive drawing */ static void gl2psPrintPDFPrimitive(void *data) { GL2PSprimitive *prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; prim = gl2psCopyPrimitive(prim); /* deep copy */ gl2psListAdd(gl2ps->pdfprimlist, &prim); } /* close stream and ... */ static int gl2psClosePDFDataStream(void) { int offs = 0; #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ if(Z_OK != gl2psDeflate()) gl2psMsg(GL2PS_ERROR, "Zlib deflate error"); else fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); gl2ps->streamlength += gl2ps->compress->destLen; offs += gl2ps->streamlength; gl2psFreeCompress(); } #endif offs += fprintf(gl2ps->stream, "endstream\n" "endobj\n"); return offs; } /* ... write the now known length object */ static int gl2psPrintPDFDataStreamLength(int val) { return fprintf(gl2ps->stream, "5 0 obj\n" "%d\n" "endobj\n", val); } /* Put the info created before in PDF objects */ static int gl2psPrintPDFOpenPage(void) { int offs; /* Write fixed part */ offs = fprintf(gl2ps->stream, "6 0 obj\n" "<<\n" "/Type /Page\n" "/Parent 3 0 R\n" "/MediaBox [%d %d %d %d]\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); if(gl2ps->options & GL2PS_LANDSCAPE) offs += fprintf(gl2ps->stream, "/Rotate -90\n"); offs += fprintf(gl2ps->stream, "/Contents 4 0 R\n" "/Resources\n" "<<\n" "/ProcSet [/PDF /Text /ImageB /ImageC] %%/ImageI\n"); return offs; /* End fixed part, proceeds in gl2psPDFgroupListWriteVariableResources() */ } static int gl2psPDFgroupListWriteVariableResources(void) { int offs = 0; /* a) Graphics States for shader alpha masks*/ offs += gl2psPDFgroupListWriteGStateResources(); /* b) Shader and shader masks */ offs += gl2psPDFgroupListWriteShaderResources(); /* c) XObjects (Images & Shader Masks) */ offs += gl2psPDFgroupListWriteXObjectResources(); /* d) Fonts */ offs += gl2psPDFgroupListWriteFontResources(); /* End resources and page */ offs += fprintf(gl2ps->stream, ">>\n" ">>\n" "endobj\n"); return offs; } /* Standard Graphics State */ static int gl2psPrintPDFGSObject(void) { return fprintf(gl2ps->stream, "7 0 obj\n" "<<\n" "/Type /ExtGState\n" "/SA false\n" "/SM 0.02\n" "/OP false\n" "/op false\n" "/OPM 0\n" "/BG2 /Default\n" "/UCR2 /Default\n" "/TR2 /Default\n" ">>\n" "endobj\n"); } /* Put vertex' edge flag (8bit) and coordinates (32bit) in shader stream */ static int gl2psPrintPDFShaderStreamDataCoord(GL2PSvertex *vertex, size_t (*action)(unsigned long data, size_t size), GLfloat dx, GLfloat dy, GLfloat xmin, GLfloat ymin) { int offs = 0; unsigned long imap; GLfloat diff; double dmax = ~1UL; char edgeflag = 0; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; offs += (*action)(edgeflag, 1); /* The Shader stream in PDF requires to be in a 'big-endian' order */ if(GL2PS_ZERO(dx*dy)){ offs += (*action)(0, 4); offs += (*action)(0, 4); } else{ diff = (vertex->xyz[0] - xmin) / dx; if(diff > 1) diff = 1.0F; else if(diff < 0) diff = 0.0F; imap = (unsigned long)(diff * dmax); offs += (*action)(imap, 4); diff = (vertex->xyz[1] - ymin) / dy; if(diff > 1) diff = 1.0F; else if(diff < 0) diff = 0.0F; imap = (unsigned long)(diff * dmax); offs += (*action)(imap, 4); } return offs; } /* Put vertex' rgb value (8bit for every component) in shader stream */ static int gl2psPrintPDFShaderStreamDataRGB(GL2PSvertex *vertex, size_t (*action)(unsigned long data, size_t size)) { int offs = 0; unsigned long imap; double dmax = ~1UL; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; imap = (unsigned long)((vertex->rgba[0]) * dmax); offs += (*action)(imap, 1); imap = (unsigned long)((vertex->rgba[1]) * dmax); offs += (*action)(imap, 1); imap = (unsigned long)((vertex->rgba[2]) * dmax); offs += (*action)(imap, 1); return offs; } /* Put vertex' alpha (8/16bit) in shader stream */ static int gl2psPrintPDFShaderStreamDataAlpha(GL2PSvertex *vertex, size_t (*action)(unsigned long data, size_t size), int sigbyte) { int offs = 0; unsigned long imap; double dmax = ~1UL; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; if(sigbyte != 8 && sigbyte != 16) sigbyte = 8; sigbyte /= 8; imap = (unsigned long)((vertex->rgba[3]) * dmax); offs += (*action)(imap, sigbyte); return offs; } /* Put a triangles raw data in shader stream */ static int gl2psPrintPDFShaderStreamData(GL2PStriangle *triangle, GLfloat dx, GLfloat dy, GLfloat xmin, GLfloat ymin, size_t (*action)(unsigned long data, size_t size), int gray) { int i, offs = 0; GL2PSvertex v; if(gray && gray != 8 && gray != 16) gray = 8; for(i = 0; i < 3; ++i){ offs += gl2psPrintPDFShaderStreamDataCoord(&triangle->vertex[i], action, dx, dy, xmin, ymin); if(gray){ v = triangle->vertex[i]; offs += gl2psPrintPDFShaderStreamDataAlpha(&v, action, gray); } else{ offs += gl2psPrintPDFShaderStreamDataRGB(&triangle->vertex[i], action); } } return offs; } static void gl2psPDFRectHull(GLfloat *xmin, GLfloat *xmax, GLfloat *ymin, GLfloat *ymax, GL2PStriangle *triangles, int cnt) { int i, j; *xmin = triangles[0].vertex[0].xyz[0]; *xmax = triangles[0].vertex[0].xyz[0]; *ymin = triangles[0].vertex[0].xyz[1]; *ymax = triangles[0].vertex[0].xyz[1]; for(i = 0; i < cnt; ++i){ for(j = 0; j < 3; ++j){ if(*xmin > triangles[i].vertex[j].xyz[0]) *xmin = triangles[i].vertex[j].xyz[0]; if(*xmax < triangles[i].vertex[j].xyz[0]) *xmax = triangles[i].vertex[j].xyz[0]; if(*ymin > triangles[i].vertex[j].xyz[1]) *ymin = triangles[i].vertex[j].xyz[1]; if(*ymax < triangles[i].vertex[j].xyz[1]) *ymax = triangles[i].vertex[j].xyz[1]; } } } /* Writes shaded triangle gray == 0 means write RGB triangles gray == 8 8bit-grayscale (for alpha masks) gray == 16 16bit-grayscale (for alpha masks) */ static int gl2psPrintPDFShader(int obj, GL2PStriangle *triangles, int size, int gray) { int i, offs = 0, vertexbytes, done = 0; GLfloat xmin, xmax, ymin, ymax; switch(gray){ case 0: vertexbytes = 1+4+4+1+1+1; break; case 8: vertexbytes = 1+4+4+1; break; case 16: vertexbytes = 1+4+4+2; break; default: gray = 8; vertexbytes = 1+4+4+1; break; } gl2psPDFRectHull(&xmin, &xmax, &ymin, &ymax, triangles, size); offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<< " "/ShadingType 4 " "/ColorSpace %s " "/BitsPerCoordinate 32 " "/BitsPerComponent %d " "/BitsPerFlag 8 " "/Decode [%f %f %f %f 0 1 %s] ", obj, (gray) ? "/DeviceGray" : "/DeviceRGB", (gray) ? gray : 8, xmin, xmax, ymin, ymax, (gray) ? "" : "0 1 0 1"); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psAllocCompress(vertexbytes * size * 3); for(i = 0; i < size; ++i) gl2psPrintPDFShaderStreamData(&triangles[i], xmax-xmin, ymax-ymin, xmin, ymin, gl2psWriteBigEndianCompress, gray); if(Z_OK == gl2psDeflate() && 23 + gl2ps->compress->destLen < gl2ps->compress->srcLen){ offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)gl2ps->compress->destLen); offs += gl2ps->compress->destLen * fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); done = 1; } gl2psFreeCompress(); } #endif if(!done){ /* no compression, or too long after compression, or compress error -> write non-compressed entry */ offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", vertexbytes * 3 * size); for(i = 0; i < size; ++i) offs += gl2psPrintPDFShaderStreamData(&triangles[i], xmax-xmin, ymax-ymin, xmin, ymin, gl2psWriteBigEndian, gray); } offs += fprintf(gl2ps->stream, "\nendstream\n" "endobj\n"); return offs; } /* Writes a XObject for a shaded triangle mask */ static int gl2psPrintPDFShaderMask(int obj, int childobj) { int offs = 0, len; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /XObject\n" "/Subtype /Form\n" "/BBox [ %d %d %d %d ]\n" "/Group \n<<\n/S /Transparency /CS /DeviceRGB\n" ">>\n", obj, (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); len = (childobj>0) ? strlen("/TrSh sh\n") + (int)log10((double)childobj)+1 : strlen("/TrSh0 sh\n"); offs += fprintf(gl2ps->stream, "/Length %d\n" ">>\n" "stream\n", len); offs += fprintf(gl2ps->stream, "/TrSh%d sh\n", childobj); offs += fprintf(gl2ps->stream, "endstream\n" "endobj\n"); return offs; } /* Writes a Extended graphics state for a shaded triangle mask if simplealpha ist true the childobj argument is ignored and a /ca statement will be written instead */ static int gl2psPrintPDFShaderExtGS(int obj, int childobj) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n", obj); offs += fprintf(gl2ps->stream, "/SMask << /S /Alpha /G %d 0 R >> ", childobj); offs += fprintf(gl2ps->stream, ">>\n" "endobj\n"); return offs; } /* a simple graphics state */ static int gl2psPrintPDFShaderSimpleExtGS(int obj, GLfloat alpha) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/ca %g" ">>\n" "endobj\n", obj, alpha); return offs; } /* Similar groups of functions for pixmaps and text */ static int gl2psPrintPDFPixmapStreamData(GL2PSimage *im, size_t (*action)(unsigned long data, size_t size), int gray) { int x, y; GLfloat r, g, b, a; if(im->format != GL_RGBA && gray) return 0; if(gray && gray !=8 && gray != 16) gray = 8; gray /= 8; for(y = 0; y < im->height; ++y){ for(x = 0; x < im->width; ++x){ a = gl2psGetRGB(im, x, y, &r, &g, &b); if(im->format == GL_RGBA && gray){ (*action)((unsigned long)(a*255) << 24, gray); } else{ (*action)((unsigned long)(r*255) << 24, 1); (*action)((unsigned long)(g*255) << 24, 1); (*action)((unsigned long)(b*255) << 24, 1); } } } switch(gray){ case 0: return 3 * im->width * im->height; case 1: return im->width * im->height; case 2: return 2 * im->width * im->height; default: return 3 * im->width * im->height; } } static int gl2psPrintPDFPixmap(int obj, int childobj, GL2PSimage *im, int gray) { int offs = 0, done = 0, sigbytes = 3; if(gray && gray !=8 && gray != 16) gray = 8; if(gray) sigbytes = gray / 8; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /XObject\n" "/Subtype /Image\n" "/Width %d\n" "/Height %d\n" "/ColorSpace %s \n" "/BitsPerComponent 8\n", obj, (int)im->width, (int)im->height, (gray) ? "/DeviceGray" : "/DeviceRGB" ); if(GL_RGBA == im->format && gray == 0){ offs += fprintf(gl2ps->stream, "/SMask %d 0 R\n", childobj); } #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psAllocCompress((int)(im->width * im->height * sigbytes)); gl2psPrintPDFPixmapStreamData(im, gl2psWriteBigEndianCompress, gray); if(Z_OK == gl2psDeflate() && 23 + gl2ps->compress->destLen < gl2ps->compress->srcLen){ offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)gl2ps->compress->destLen); offs += gl2ps->compress->destLen * fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); done = 1; } gl2psFreeCompress(); } #endif if(!done){ /* no compression, or too long after compression, or compress error -> write non-compressed entry */ offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)(im->width * im->height * sigbytes)); offs += gl2psPrintPDFPixmapStreamData(im, gl2psWriteBigEndian, gray); } offs += fprintf(gl2ps->stream, "\nendstream\n" "endobj\n"); return offs; } static int gl2psPrintPDFText(int obj, GL2PSstring *s, int fontnumber) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /Font\n" "/Subtype /Type1\n" "/Name /F%d\n" "/BaseFont /%s\n" "/Encoding /MacRomanEncoding\n" ">>\n" "endobj\n", obj, fontnumber, s->fontname); return offs; } /* Write the physical objects */ static int gl2psPDFgroupListWriteObjects(int entryoffs) { int i,j; GL2PSprimitive *p = NULL; GL2PSpdfgroup *gro; int offs = entryoffs; GL2PStriangle *triangles; int size = 0; if(!gl2ps->pdfgrouplist) return offs; for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(!gl2psListNbr(gro->ptrlist)) continue; p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(p->type){ case GL2PS_POINT: break; case GL2PS_LINE: break; case GL2PS_TRIANGLE: size = gl2psListNbr(gro->ptrlist); triangles = (GL2PStriangle*)gl2psMalloc(sizeof(GL2PStriangle) * size); for(j = 0; j < size; ++j){ p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&triangles[j], p, GL_TRUE); } if(triangles[0].prop & T_VAR_COLOR){ gl2ps->xreflist[gro->shobjno] = offs; offs += gl2psPrintPDFShader(gro->shobjno, triangles, size, 0); } if(triangles[0].prop & T_ALPHA_LESS_1){ gl2ps->xreflist[gro->gsobjno] = offs; offs += gl2psPrintPDFShaderSimpleExtGS(gro->gsobjno, triangles[0].vertex[0].rgba[3]); } if(triangles[0].prop & T_VAR_ALPHA){ gl2ps->xreflist[gro->gsobjno] = offs; offs += gl2psPrintPDFShaderExtGS(gro->gsobjno, gro->trgroupobjno); gl2ps->xreflist[gro->trgroupobjno] = offs; offs += gl2psPrintPDFShaderMask(gro->trgroupobjno, gro->maskshno); gl2ps->xreflist[gro->maskshobjno] = offs; offs += gl2psPrintPDFShader(gro->maskshobjno, triangles, size, 8); } gl2psFree(triangles); break; case GL2PS_PIXMAP: gl2ps->xreflist[gro->imobjno] = offs; offs += gl2psPrintPDFPixmap(gro->imobjno, gro->imobjno+1, p->data.image, 0); if(p->data.image->format == GL_RGBA){ gl2ps->xreflist[gro->imobjno+1] = offs; offs += gl2psPrintPDFPixmap(gro->imobjno+1, -1, p->data.image, 8); } break; case GL2PS_TEXT: gl2ps->xreflist[gro->fontobjno] = offs; offs += gl2psPrintPDFText(gro->fontobjno,p->data.text,gro->fontno); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(p->data.text->alignment == GL2PS_PDF) offs += fprintf(gl2ps->stream, "%s\n", p->data.text->str); break; default: break; } } return offs; } /* All variable data has been written at this point and all required functioninality has been gathered, so we can write now file footer with cross reference table and trailer */ static void gl2psPrintPDFFooter(void) { int i, offs; gl2psPDFgroupListInit(); gl2psPDFgroupListWriteMainStream(); offs = gl2ps->xreflist[5] + gl2ps->streamlength; offs += gl2psClosePDFDataStream(); gl2ps->xreflist[5] = offs; offs += gl2psPrintPDFDataStreamLength(gl2ps->streamlength); gl2ps->xreflist[6] = offs; gl2ps->streamlength = 0; offs += gl2psPrintPDFOpenPage(); offs += gl2psPDFgroupListWriteVariableResources(); gl2ps->xreflist = (int*)gl2psRealloc(gl2ps->xreflist, sizeof(int) * (gl2ps->objects_stack + 1)); gl2ps->xreflist[7] = offs; offs += gl2psPrintPDFGSObject(); gl2ps->xreflist[8] = offs; gl2ps->xreflist[gl2ps->objects_stack] = gl2psPDFgroupListWriteObjects(gl2ps->xreflist[8]); /* Start cross reference table. The file has to been opened in binary mode to preserve the 20 digit string length! */ fprintf(gl2ps->stream, "xref\n" "0 %d\n" "%010d 65535 f \n", gl2ps->objects_stack, 0); for(i = 1; i < gl2ps->objects_stack; ++i) fprintf(gl2ps->stream, "%010d 00000 n \n", gl2ps->xreflist[i]); fprintf(gl2ps->stream, "trailer\n" "<<\n" "/Size %d\n" "/Info 1 0 R\n" "/Root 2 0 R\n" ">>\n" "startxref\n%d\n" "%%%%EOF\n", gl2ps->objects_stack, gl2ps->xreflist[gl2ps->objects_stack]); /* Free auxiliary lists and arrays */ gl2psFree(gl2ps->xreflist); gl2psListDelete(gl2ps->pdfprimlist); gl2psPDFgroupListDelete(); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psFreeCompress(); gl2psFree(gl2ps->compress); gl2ps->compress = NULL; } #endif } /* PDF begin viewport */ static void gl2psPrintPDFBeginViewport(GLint viewport[4]) { int offs = 0; GLint index; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintPDFHeader(); gl2ps->header = GL_FALSE; } offs += gl2psPrintf("q\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index); rgba[0] = gl2ps->colormap[index][0]; rgba[1] = gl2ps->colormap[index][1]; rgba[2] = gl2ps->colormap[index][2]; rgba[3] = 1.0F; } offs += gl2psPrintPDFFillColor(rgba); offs += gl2psPrintf("%d %d %d %d re\n" "W\n" "f\n", x, y, w, h); } else{ offs += gl2psPrintf("%d %d %d %d re\n" "W\n" "n\n", x, y, w, h); } gl2ps->streamlength += offs; } static GLint gl2psPrintPDFEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2ps->streamlength += gl2psPrintf("Q\n"); return res; } static void gl2psPrintPDFFinalPrimitive(void) { } /* definition of the PDF backend */ static GL2PSbackend gl2psPDF = { gl2psPrintPDFHeader, gl2psPrintPDFFooter, gl2psPrintPDFBeginViewport, gl2psPrintPDFEndViewport, gl2psPrintPDFPrimitive, gl2psPrintPDFFinalPrimitive, "pdf", "Portable Document Format" }; /********************************************************************* * * SVG routines * *********************************************************************/ static void gl2psSVGGetCoordsAndColors(int n, GL2PSvertex *verts, GL2PSxyz *xyz, GL2PSrgba *rgba) { int i, j; for(i = 0; i < n; i++){ xyz[i][0] = verts[i].xyz[0]; xyz[i][1] = gl2ps->viewport[3] - verts[i].xyz[1]; xyz[i][2] = 0.0F; for(j = 0; j < 4; j++) rgba[i][j] = verts[i].rgba[j]; } } static void gl2psSVGGetColorString(GL2PSrgba rgba, char str[32]) { int r = (int)(255. * rgba[0]); int g = (int)(255. * rgba[1]); int b = (int)(255. * rgba[2]); int rc = (r < 0) ? 0 : (r > 255) ? 255 : r; int gc = (g < 0) ? 0 : (g > 255) ? 255 : g; int bc = (b < 0) ? 0 : (b > 255) ? 255 : b; sprintf(str, "#%2.2x%2.2x%2.2x", rc, gc, bc); } static void gl2psPrintSVGHeader(void) { int x, y, width, height; char col[32]; time_t now; time(&now); if (gl2ps->options & GL2PS_LANDSCAPE){ x = (int)gl2ps->viewport[1]; y = (int)gl2ps->viewport[0]; width = (int)gl2ps->viewport[3]; height = (int)gl2ps->viewport[2]; } else{ x = (int)gl2ps->viewport[0]; y = (int)gl2ps->viewport[1]; width = (int)gl2ps->viewport[2]; height = (int)gl2ps->viewport[3]; } /* Compressed SVG files (.svgz) are simply gzipped SVG files */ gl2psPrintGzipHeader(); gl2psPrintf("\n"); gl2psPrintf("\n", width, height, x, y, width, height); gl2psPrintf("%s\n", gl2ps->title); gl2psPrintf("\n"); gl2psPrintf("Creator: GL2PS %d.%d.%d%s, %s\n" "For: %s\n" "CreationDate: %s", GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); gl2psPrintf("\n"); gl2psPrintf("\n"); gl2psPrintf("\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psSVGGetColorString(gl2ps->bgcolor, col); gl2psPrintf("\n", col, (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3], (int)gl2ps->viewport[0], (int)gl2ps->viewport[3]); } gl2psPrintf("\n"); } static void gl2psPrintSVGSmoothTriangle(GL2PSxyz xyz[3], GL2PSrgba rgba[3]) { int i; GL2PSxyz xyz2[3]; GL2PSrgba rgba2[3]; char col[32]; /* Apparently there is no easy way to do Gouraud shading in SVG without explicitly pre-defining gradients, so for now we just do recursive subdivision */ if(gl2psSameColorThreshold(3, rgba, gl2ps->threshold)){ gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("\n", xyz[0][0], xyz[0][1], xyz[1][0], xyz[1][1], xyz[2][0], xyz[2][1]); } else{ /* subdivide into 4 subtriangles */ for(i = 0; i < 3; i++){ xyz2[0][i] = xyz[0][i]; xyz2[1][i] = 0.5f * (xyz[0][i] + xyz[1][i]); xyz2[2][i] = 0.5f * (xyz[0][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = rgba[0][i]; rgba2[1][i] = 0.5f * (rgba[0][i] + rgba[1][i]); rgba2[2][i] = 0.5f * (rgba[0][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5f * (xyz[0][i] + xyz[1][i]); xyz2[1][i] = xyz[1][i]; xyz2[2][i] = 0.5f * (xyz[1][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5f * (rgba[0][i] + rgba[1][i]); rgba2[1][i] = rgba[1][i]; rgba2[2][i] = 0.5f * (rgba[1][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5f * (xyz[0][i] + xyz[2][i]); xyz2[1][i] = xyz[2][i]; xyz2[2][i] = 0.5f * (xyz[1][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5f * (rgba[0][i] + rgba[2][i]); rgba2[1][i] = rgba[2][i]; rgba2[2][i] = 0.5f * (rgba[1][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5f * (xyz[0][i] + xyz[1][i]); xyz2[1][i] = 0.5f * (xyz[1][i] + xyz[2][i]); xyz2[2][i] = 0.5f * (xyz[0][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5f * (rgba[0][i] + rgba[1][i]); rgba2[1][i] = 0.5f * (rgba[1][i] + rgba[2][i]); rgba2[2][i] = 0.5f * (rgba[0][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); } } static void gl2psPrintSVGDash(GLushort pattern, GLint factor) { int i, n, array[10]; if(!pattern || !factor) return; /* solid line */ gl2psParseStipplePattern(pattern, factor, &n, array); gl2psPrintf("stroke-dasharray=\""); for(i = 0; i < n; i++){ if(i) gl2psPrintf(","); gl2psPrintf("%d", array[i]); } gl2psPrintf("\" "); } static void gl2psEndSVGLine(void) { int i; if(gl2ps->lastvertex.rgba[0] >= 0.){ gl2psPrintf("%g,%g\"/>\n", gl2ps->lastvertex.xyz[0], gl2ps->viewport[3] - gl2ps->lastvertex.xyz[1]); for(i = 0; i < 3; i++) gl2ps->lastvertex.xyz[i] = -1.; for(i = 0; i < 4; i++) gl2ps->lastvertex.rgba[i] = -1.; } } static void gl2psPrintSVGPixmap(GLfloat x, GLfloat y, GL2PSimage *pixmap) { #if defined(GL2PS_HAVE_LIBPNG) GL2PSlist *png; unsigned char c; int i; /* The only image types supported by the SVG standard are JPEG, PNG and SVG. Here we choose PNG, and since we want to embed the image directly in the SVG stream (and not link to an external image file), we need to encode the pixmap into PNG in memory, then encode it into base64. */ png = gl2psListCreate(pixmap->width * pixmap->height * 3, 1000, sizeof(unsigned char)); gl2psConvertPixmapToPNG(pixmap, png); gl2psListEncodeBase64(png); gl2psPrintf("height, pixmap->width, pixmap->height); gl2psPrintf("xlink:href=\"data:image/png;base64,"); for(i = 0; i < gl2psListNbr(png); i++){ gl2psListRead(png, i, &c); gl2psPrintf("%c", c); } gl2psPrintf("\"/>\n"); gl2psListDelete(png); #else gl2psMsg(GL2PS_WARNING, "GL2PS has to be compiled with PNG support in " "order to embed images in SVG streams"); #endif } static void gl2psPrintSVGPrimitive(void *data) { GL2PSprimitive *prim; GL2PSxyz xyz[4]; GL2PSrgba rgba[4]; char col[32]; int newline; prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; /* We try to draw connected lines as a single path to get nice line joins and correct stippling. So if the primitive to print is not a line we must first finish the current line (if any): */ if(prim->type != GL2PS_LINE) gl2psEndSVGLine(); gl2psSVGGetCoordsAndColors(prim->numverts, prim->verts, xyz, rgba); switch(prim->type){ case GL2PS_POINT : gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("\n", xyz[0][0], xyz[0][1], 0.5 * prim->width); break; case GL2PS_LINE : if(!gl2psSamePosition(gl2ps->lastvertex.xyz, prim->verts[0].xyz) || !gl2psSameColor(gl2ps->lastrgba, prim->verts[0].rgba) || gl2ps->lastlinewidth != prim->width || gl2ps->lastpattern != prim->pattern || gl2ps->lastfactor != prim->factor){ /* End the current line if the new segment does not start where the last one ended, or if the color, the width or the stippling have changed (we will need to use multi-point gradients for smooth-shaded lines) */ gl2psEndSVGLine(); newline = 1; } else{ newline = 0; } gl2ps->lastvertex = prim->verts[1]; gl2psSetLastColor(prim->verts[0].rgba); gl2ps->lastlinewidth = prim->width; gl2ps->lastpattern = prim->pattern; gl2ps->lastfactor = prim->factor; if(newline){ gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("width); if(rgba[0][3] < 1.0F) gl2psPrintf("stroke-opacity=\"%g\" ", rgba[0][3]); gl2psPrintSVGDash(prim->pattern, prim->factor); gl2psPrintf("points=\"%g,%g ", xyz[0][0], xyz[0][1]); } else{ gl2psPrintf("%g,%g ", xyz[0][0], xyz[0][1]); } break; case GL2PS_TRIANGLE : gl2psPrintSVGSmoothTriangle(xyz, rgba); break; case GL2PS_QUADRANGLE : gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print"); break; case GL2PS_PIXMAP : gl2psPrintSVGPixmap(xyz[0][0], xyz[0][1], prim->data.image); break; case GL2PS_TEXT : gl2psSVGGetColorString(prim->verts[0].rgba, col); gl2psPrintf("%s\n", col, xyz[0][0], xyz[0][1], prim->data.text->fontsize, prim->data.text->fontname, prim->data.text->str); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(prim->data.text->alignment == GL2PS_SVG) gl2psPrintf("%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintSVGFooter(void) { gl2psPrintf("\n"); gl2psPrintf("\n"); gl2psPrintGzipFooter(); } static void gl2psPrintSVGBeginViewport(GLint viewport[4]) { GLint index; char col[32]; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintSVGHeader(); gl2ps->header = GL_FALSE; } if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index); rgba[0] = gl2ps->colormap[index][0]; rgba[1] = gl2ps->colormap[index][1]; rgba[2] = gl2ps->colormap[index][2]; rgba[3] = 1.0F; } gl2psSVGGetColorString(rgba, col); gl2psPrintf("\n", col, x, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - (y + h), x, gl2ps->viewport[3] - (y + h)); } gl2psPrintf("\n", x, y, w, h); gl2psPrintf(" \n", x, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - (y + h), x, gl2ps->viewport[3] - (y + h)); gl2psPrintf("\n"); gl2psPrintf("\n", x, y, w, h); } static GLint gl2psPrintSVGEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2psPrintf("\n"); return res; } static void gl2psPrintSVGFinalPrimitive(void) { /* End any remaining line, if any */ gl2psEndSVGLine(); } /* definition of the SVG backend */ static GL2PSbackend gl2psSVG = { gl2psPrintSVGHeader, gl2psPrintSVGFooter, gl2psPrintSVGBeginViewport, gl2psPrintSVGEndViewport, gl2psPrintSVGPrimitive, gl2psPrintSVGFinalPrimitive, "svg", "Scalable Vector Graphics" }; /********************************************************************* * * PGF routines * *********************************************************************/ static void gl2psPrintPGFColor(GL2PSrgba rgba) { if(!gl2psSameColor(gl2ps->lastrgba, rgba)){ gl2psSetLastColor(rgba); fprintf(gl2ps->stream, "\\color[rgb]{%f,%f,%f}\n", rgba[0], rgba[1], rgba[2]); } } static void gl2psPrintPGFHeader(void) { time_t now; time(&now); fprintf(gl2ps->stream, "%% Title: %s\n" "%% Creator: GL2PS %d.%d.%d%s, %s\n" "%% For: %s\n" "%% CreationDate: %s", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); fprintf(gl2ps->stream, "\\begin{pgfpicture}\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psPrintPGFColor(gl2ps->bgcolor); fprintf(gl2ps->stream, "\\pgfpathrectanglecorners{" "\\pgfpoint{%dpt}{%dpt}}{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{fill}\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); } } static void gl2psPrintPGFDash(GLushort pattern, GLint factor) { int i, n, array[10]; if(pattern == gl2ps->lastpattern && factor == gl2ps->lastfactor) return; gl2ps->lastpattern = pattern; gl2ps->lastfactor = factor; if(!pattern || !factor){ /* solid line */ fprintf(gl2ps->stream, "\\pgfsetdash{}{0pt}\n"); } else{ gl2psParseStipplePattern(pattern, factor, &n, array); fprintf(gl2ps->stream, "\\pgfsetdash{"); for(i = 0; i < n; i++) fprintf(gl2ps->stream, "{%dpt}", array[i]); fprintf(gl2ps->stream, "}{0pt}\n"); } } static const char *gl2psPGFTextAlignment(int align) { switch(align){ case GL2PS_TEXT_C : return "center"; case GL2PS_TEXT_CL : return "west"; case GL2PS_TEXT_CR : return "east"; case GL2PS_TEXT_B : return "south"; case GL2PS_TEXT_BR : return "south east"; case GL2PS_TEXT_T : return "north"; case GL2PS_TEXT_TL : return "north west"; case GL2PS_TEXT_TR : return "north east"; case GL2PS_TEXT_BL : default : return "south west"; } } static void gl2psPrintPGFPrimitive(void *data) { GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; switch(prim->type){ case GL2PS_POINT : /* Points in openGL are rectangular */ gl2psPrintPGFColor(prim->verts[0].rgba); fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%fpt}{%fpt}}" "{\\pgfpoint{%fpt}{%fpt}}\n\\pgfusepath{fill}\n", prim->verts[0].xyz[0]-0.5*prim->width, prim->verts[0].xyz[1]-0.5*prim->width, prim->width,prim->width); break; case GL2PS_LINE : gl2psPrintPGFColor(prim->verts[0].rgba); if(gl2ps->lastlinewidth != prim->width){ gl2ps->lastlinewidth = prim->width; fprintf(gl2ps->stream, "\\pgfsetlinewidth{%fpt}\n", gl2ps->lastlinewidth); } gl2psPrintPGFDash(prim->pattern, prim->factor); fprintf(gl2ps->stream, "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgfusepath{stroke}\n", prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); break; case GL2PS_TRIANGLE : if(gl2ps->lastlinewidth != 0){ gl2ps->lastlinewidth = 0; fprintf(gl2ps->stream, "\\pgfsetlinewidth{0.01pt}\n"); } gl2psPrintPGFColor(prim->verts[0].rgba); fprintf(gl2ps->stream, "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgfpathclose\n" "\\pgfusepath{fill,stroke}\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); break; case GL2PS_TEXT : fprintf(gl2ps->stream, "{\n\\pgftransformshift{\\pgfpoint{%fpt}{%fpt}}\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); if(prim->data.text->angle) fprintf(gl2ps->stream, "\\pgftransformrotate{%f}{", prim->data.text->angle); fprintf(gl2ps->stream, "\\pgfnode{rectangle}{%s}{\\fontsize{%d}{0}\\selectfont", gl2psPGFTextAlignment(prim->data.text->alignment), prim->data.text->fontsize); fprintf(gl2ps->stream, "\\textcolor[rgb]{%g,%g,%g}{{%s}}", prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2], prim->data.text->str); fprintf(gl2ps->stream, "}{}{\\pgfusepath{discard}}}\n"); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if (prim->data.text->alignment == GL2PS_PGF) fprintf(gl2ps->stream, "%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintPGFFooter(void) { fprintf(gl2ps->stream, "\\end{pgfpicture}\n"); } static void gl2psPrintPGFBeginViewport(GLint viewport[4]) { GLint index; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintPGFHeader(); gl2ps->header = GL_FALSE; } fprintf(gl2ps->stream, "\\begin{pgfscope}\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index); rgba[0] = gl2ps->colormap[index][0]; rgba[1] = gl2ps->colormap[index][1]; rgba[2] = gl2ps->colormap[index][2]; rgba[3] = 1.0F; } gl2psPrintPGFColor(rgba); fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}" "{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{fill}\n", x, y, w, h); } fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}" "{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{clip}\n", x, y, w, h); } static GLint gl2psPrintPGFEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); fprintf(gl2ps->stream, "\\end{pgfscope}\n"); return res; } static void gl2psPrintPGFFinalPrimitive(void) { } /* definition of the PGF backend */ static GL2PSbackend gl2psPGF = { gl2psPrintPGFHeader, gl2psPrintPGFFooter, gl2psPrintPGFBeginViewport, gl2psPrintPGFEndViewport, gl2psPrintPGFPrimitive, gl2psPrintPGFFinalPrimitive, "tex", "PGF Latex Graphics" }; /********************************************************************* * * General primitive printing routine * *********************************************************************/ /* Warning: the ordering of the backends must match the format #defines in gl2ps.h */ static GL2PSbackend *gl2psbackends[] = { &gl2psPS, /* 0 */ &gl2psEPS, /* 1 */ &gl2psTEX, /* 2 */ &gl2psPDF, /* 3 */ &gl2psSVG, /* 4 */ &gl2psPGF /* 5 */ }; static void gl2psComputeTightBoundingBox(void *data) { GL2PSprimitive *prim; int i; prim = *(GL2PSprimitive**)data; for(i = 0; i < prim->numverts; i++){ if(prim->verts[i].xyz[0] < gl2ps->viewport[0]) gl2ps->viewport[0] = (GLint)prim->verts[i].xyz[0]; if(prim->verts[i].xyz[0] > gl2ps->viewport[2]) gl2ps->viewport[2] = (GLint)(prim->verts[i].xyz[0] + 0.5F); if(prim->verts[i].xyz[1] < gl2ps->viewport[1]) gl2ps->viewport[1] = (GLint)prim->verts[i].xyz[1]; if(prim->verts[i].xyz[1] > gl2ps->viewport[3]) gl2ps->viewport[3] = (GLint)(prim->verts[i].xyz[1] + 0.5F); } } static GLint gl2psPrintPrimitives(void) { GL2PSbsptree *root; GL2PSxyz eye = {0.0F, 0.0F, 100.0F * GL2PS_ZSCALE}; GLint used; used = glRenderMode(GL_RENDER); if(used < 0){ gl2psMsg(GL2PS_INFO, "OpenGL feedback buffer overflow"); return GL2PS_OVERFLOW; } if(used > 0) gl2psParseFeedbackBuffer(used); gl2psRescaleAndOffset(); if(gl2ps->header){ if(gl2psListNbr(gl2ps->primitives) && (gl2ps->options & GL2PS_TIGHT_BOUNDING_BOX)){ gl2ps->viewport[0] = gl2ps->viewport[1] = 100000; gl2ps->viewport[2] = gl2ps->viewport[3] = -100000; gl2psListAction(gl2ps->primitives, gl2psComputeTightBoundingBox); } (gl2psbackends[gl2ps->format]->printHeader)(); gl2ps->header = GL_FALSE; } if(!gl2psListNbr(gl2ps->primitives)){ /* empty feedback buffer and/or nothing else to print */ return GL2PS_NO_FEEDBACK; } switch(gl2ps->sort){ case GL2PS_NO_SORT : gl2psListAction(gl2ps->primitives, gl2psbackends[gl2ps->format]->printPrimitive); gl2psListAction(gl2ps->primitives, gl2psFreePrimitive); /* reset the primitive list, waiting for the next viewport */ gl2psListReset(gl2ps->primitives); break; case GL2PS_SIMPLE_SORT : gl2psListSort(gl2ps->primitives, gl2psCompareDepth); if(gl2ps->options & GL2PS_OCCLUSION_CULL){ gl2psListActionInverse(gl2ps->primitives, gl2psAddInImageTree); gl2psFreeBspImageTree(&gl2ps->imagetree); } gl2psListAction(gl2ps->primitives, gl2psbackends[gl2ps->format]->printPrimitive); gl2psListAction(gl2ps->primitives, gl2psFreePrimitive); /* reset the primitive list, waiting for the next viewport */ gl2psListReset(gl2ps->primitives); break; case GL2PS_BSP_SORT : root = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(root, gl2ps->primitives); if(GL_TRUE == gl2ps->boundary) gl2psBuildPolygonBoundary(root); if(gl2ps->options & GL2PS_OCCLUSION_CULL){ gl2psTraverseBspTree(root, eye, -GL2PS_EPSILON, gl2psLess, gl2psAddInImageTree, 1); gl2psFreeBspImageTree(&gl2ps->imagetree); } gl2psTraverseBspTree(root, eye, GL2PS_EPSILON, gl2psGreater, gl2psbackends[gl2ps->format]->printPrimitive, 0); gl2psFreeBspTree(&root); /* reallocate the primitive list (it's been deleted by gl2psBuildBspTree) in case there is another viewport */ gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); break; } gl2psbackends[gl2ps->format]->printFinalPrimitive(); return GL2PS_SUCCESS; } /********************************************************************* * * Public routines * *********************************************************************/ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename) { GLint index; int i; if(gl2ps){ gl2psMsg(GL2PS_ERROR, "gl2psBeginPage called in wrong program state"); return GL2PS_ERROR; } gl2ps = (GL2PScontext*)gl2psMalloc(sizeof(GL2PScontext)); if(format >= 0 && format < (GLint)(sizeof(gl2psbackends)/sizeof(gl2psbackends[0]))){ gl2ps->format = format; } else { gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", format); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } switch(sort){ case GL2PS_NO_SORT : case GL2PS_SIMPLE_SORT : case GL2PS_BSP_SORT : gl2ps->sort = sort; break; default : gl2psMsg(GL2PS_ERROR, "Unknown sorting algorithm: %d", sort); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } if(stream){ gl2ps->stream = stream; } else{ gl2psMsg(GL2PS_ERROR, "Bad file pointer"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->header = GL_TRUE; gl2ps->maxbestroot = 10; gl2ps->options = options; gl2ps->compress = NULL; gl2ps->imagemap_head = NULL; gl2ps->imagemap_tail = NULL; if(gl2ps->options & GL2PS_USE_CURRENT_VIEWPORT){ glGetIntegerv(GL_VIEWPORT, gl2ps->viewport); } else{ for(i = 0; i < 4; i++){ gl2ps->viewport[i] = viewport[i]; } } if(!gl2ps->viewport[2] || !gl2ps->viewport[3]){ gl2psMsg(GL2PS_ERROR, "Incorrect viewport (x=%d, y=%d, width=%d, height=%d)", gl2ps->viewport[0], gl2ps->viewport[1], gl2ps->viewport[2], gl2ps->viewport[3]); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->threshold[0] = nr ? 1.0F/(GLfloat)nr : 0.064F; gl2ps->threshold[1] = ng ? 1.0F/(GLfloat)ng : 0.034F; gl2ps->threshold[2] = nb ? 1.0F/(GLfloat)nb : 0.100F; gl2ps->colormode = colormode; gl2ps->buffersize = buffersize > 0 ? buffersize : 2048 * 2048; for(i = 0; i < 3; i++){ gl2ps->lastvertex.xyz[i] = -1.0F; } for(i = 0; i < 4; i++){ gl2ps->lastvertex.rgba[i] = -1.0F; gl2ps->lastrgba[i] = -1.0F; } gl2ps->lastlinewidth = -1.0F; gl2ps->lastpattern = 0; gl2ps->lastfactor = 0; gl2ps->imagetree = NULL; gl2ps->primitivetoadd = NULL; gl2ps->zerosurfacearea = GL_FALSE; gl2ps->pdfprimlist = NULL; gl2ps->pdfgrouplist = NULL; gl2ps->xreflist = NULL; /* get default blending mode from current OpenGL state (enabled by default for SVG) */ gl2ps->blending = (gl2ps->format == GL2PS_SVG) ? GL_TRUE : glIsEnabled(GL_BLEND); glGetIntegerv(GL_BLEND_SRC, &gl2ps->blendfunc[0]); glGetIntegerv(GL_BLEND_DST, &gl2ps->blendfunc[1]); if(gl2ps->colormode == GL_RGBA){ gl2ps->colorsize = 0; gl2ps->colormap = NULL; glGetFloatv(GL_COLOR_CLEAR_VALUE, gl2ps->bgcolor); } else if(gl2ps->colormode == GL_COLOR_INDEX){ if(!colorsize || !colormap){ gl2psMsg(GL2PS_ERROR, "Missing colormap for GL_COLOR_INDEX rendering"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->colorsize = colorsize; gl2ps->colormap = (GL2PSrgba*)gl2psMalloc(gl2ps->colorsize * sizeof(GL2PSrgba)); memcpy(gl2ps->colormap, colormap, gl2ps->colorsize * sizeof(GL2PSrgba)); glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index); gl2ps->bgcolor[0] = gl2ps->colormap[index][0]; gl2ps->bgcolor[1] = gl2ps->colormap[index][1]; gl2ps->bgcolor[2] = gl2ps->colormap[index][2]; gl2ps->bgcolor[3] = 1.0F; } else{ gl2psMsg(GL2PS_ERROR, "Unknown color mode in gl2psBeginPage"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } if(!title){ gl2ps->title = (char*)gl2psMalloc(sizeof(char)); gl2ps->title[0] = '\0'; } else{ gl2ps->title = (char*)gl2psMalloc((strlen(title)+1)*sizeof(char)); strcpy(gl2ps->title, title); } if(!producer){ gl2ps->producer = (char*)gl2psMalloc(sizeof(char)); gl2ps->producer[0] = '\0'; } else{ gl2ps->producer = (char*)gl2psMalloc((strlen(producer)+1)*sizeof(char)); strcpy(gl2ps->producer, producer); } if(!filename){ gl2ps->filename = (char*)gl2psMalloc(sizeof(char)); gl2ps->filename[0] = '\0'; } else{ gl2ps->filename = (char*)gl2psMalloc((strlen(filename)+1)*sizeof(char)); strcpy(gl2ps->filename, filename); } gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); gl2ps->auxprimitives = gl2psListCreate(100, 100, sizeof(GL2PSprimitive*)); gl2ps->feedback = (GLfloat*)gl2psMalloc(gl2ps->buffersize * sizeof(GLfloat)); glFeedbackBuffer(gl2ps->buffersize, GL_3D_COLOR, gl2ps->feedback); glRenderMode(GL_FEEDBACK); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEndPage(void) { GLint res; if(!gl2ps) return GL2PS_UNINITIALIZED; res = gl2psPrintPrimitives(); if(res != GL2PS_OVERFLOW) (gl2psbackends[gl2ps->format]->printFooter)(); fflush(gl2ps->stream); gl2psListDelete(gl2ps->primitives); gl2psListDelete(gl2ps->auxprimitives); gl2psFreeImagemap(gl2ps->imagemap_head); gl2psFree(gl2ps->colormap); gl2psFree(gl2ps->title); gl2psFree(gl2ps->producer); gl2psFree(gl2ps->filename); gl2psFree(gl2ps->feedback); gl2psFree(gl2ps); gl2ps = NULL; return res; } GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]) { if(!gl2ps) return GL2PS_UNINITIALIZED; (gl2psbackends[gl2ps->format]->beginViewport)(viewport); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEndViewport(void) { GLint res; if(!gl2ps) return GL2PS_UNINITIALIZED; res = (gl2psbackends[gl2ps->format]->endViewport)(); return res; } GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle) { return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, alignment, angle); } GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize) { return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, GL2PS_TEXT_BL, 0.0F); } GL2PSDLL_API GLint gl2psSpecial(GLint format, const char *str) { return gl2psAddText(GL2PS_SPECIAL, str, "", 0, format, 0.0F); } GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height, GLint xorig, GLint yorig, GLenum format, GLenum type, const void *pixels) { int size, i; GLfloat pos[4], *piv; GL2PSprimitive *prim; GLboolean valid; if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED; if((width <= 0) || (height <= 0)) return GL2PS_ERROR; if(gl2ps->options & GL2PS_NO_PIXMAP) return GL2PS_SUCCESS; if((format != GL_RGB && format != GL_RGBA) || type != GL_FLOAT){ gl2psMsg(GL2PS_ERROR, "gl2psDrawPixels only implemented for " "GL_RGB/GL_RGBA, GL_FLOAT pixels"); return GL2PS_ERROR; } glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = GL2PS_PIXMAP; prim->boundary = 0; prim->numverts = 1; prim->verts = (GL2PSvertex*)gl2psMalloc(sizeof(GL2PSvertex)); prim->verts[0].xyz[0] = pos[0] + xorig; prim->verts[0].xyz[1] = pos[1] + yorig; prim->verts[0].xyz[2] = pos[2]; prim->culled = 0; prim->offset = 0; prim->pattern = 0; prim->factor = 0; prim->width = 1; glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba); prim->data.image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); prim->data.image->width = width; prim->data.image->height = height; prim->data.image->format = format; prim->data.image->type = type; switch(format){ case GL_RGBA: if(gl2ps->options & GL2PS_NO_BLENDING || !gl2ps->blending){ /* special case: blending turned off */ prim->data.image->format = GL_RGB; size = height * width * 3; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); piv = (GLfloat*)pixels; for(i = 0; i < size; ++i, ++piv){ prim->data.image->pixels[i] = *piv; if(!((i+1)%3)) ++piv; } } else{ size = height * width * 4; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); memcpy(prim->data.image->pixels, pixels, size * sizeof(GLfloat)); } break; case GL_RGB: default: size = height * width * 3; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); memcpy(prim->data.image->pixels, pixels, size * sizeof(GLfloat)); break; } gl2psListAdd(gl2ps->auxprimitives, &prim); glPassThrough(GL2PS_DRAW_PIXELS_TOKEN); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psDrawImageMap(GLsizei width, GLsizei height, const GLfloat position[3], const unsigned char *imagemap){ int size, i; int sizeoffloat = sizeof(GLfloat); if(!gl2ps || !imagemap) return GL2PS_UNINITIALIZED; if((width <= 0) || (height <= 0)) return GL2PS_ERROR; size = height + height * ((width-1)/8); glPassThrough(GL2PS_IMAGEMAP_TOKEN); glBegin(GL_POINTS); glVertex3f(position[0], position[1],position[2]); glEnd(); glPassThrough((GLfloat)width); glPassThrough((GLfloat)height); for(i = 0; i < size; i += sizeoffloat){ float *value = (float*)imagemap; glPassThrough(*value); imagemap += sizeoffloat; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEnable(GLint mode) { GLint tmp; if(!gl2ps) return GL2PS_UNINITIALIZED; switch(mode){ case GL2PS_POLYGON_OFFSET_FILL : glPassThrough(GL2PS_BEGIN_OFFSET_TOKEN); glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &gl2ps->offset[0]); glGetFloatv(GL_POLYGON_OFFSET_UNITS, &gl2ps->offset[1]); break; case GL2PS_POLYGON_BOUNDARY : glPassThrough(GL2PS_BEGIN_BOUNDARY_TOKEN); break; case GL2PS_LINE_STIPPLE : glPassThrough(GL2PS_BEGIN_STIPPLE_TOKEN); glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &tmp); glPassThrough((GLfloat)tmp); glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &tmp); glPassThrough((GLfloat)tmp); break; case GL2PS_BLEND : glPassThrough(GL2PS_BEGIN_BLEND_TOKEN); break; default : gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psEnable: %d", mode); return GL2PS_WARNING; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psDisable(GLint mode) { if(!gl2ps) return GL2PS_UNINITIALIZED; switch(mode){ case GL2PS_POLYGON_OFFSET_FILL : glPassThrough(GL2PS_END_OFFSET_TOKEN); break; case GL2PS_POLYGON_BOUNDARY : glPassThrough(GL2PS_END_BOUNDARY_TOKEN); break; case GL2PS_LINE_STIPPLE : glPassThrough(GL2PS_END_STIPPLE_TOKEN); break; case GL2PS_BLEND : glPassThrough(GL2PS_END_BLEND_TOKEN); break; default : gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psDisable: %d", mode); return GL2PS_WARNING; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psPointSize(GLfloat value) { if(!gl2ps) return GL2PS_UNINITIALIZED; glPassThrough(GL2PS_POINT_SIZE_TOKEN); glPassThrough(value); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psLineWidth(GLfloat value) { if(!gl2ps) return GL2PS_UNINITIALIZED; glPassThrough(GL2PS_LINE_WIDTH_TOKEN); glPassThrough(value); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psBlendFunc(GLenum sfactor, GLenum dfactor) { if(!gl2ps) return GL2PS_UNINITIALIZED; if(GL_FALSE == gl2psSupportedBlendMode(sfactor, dfactor)) return GL2PS_WARNING; glPassThrough(GL2PS_SRC_BLEND_TOKEN); glPassThrough((GLfloat)sfactor); glPassThrough(GL2PS_DST_BLEND_TOKEN); glPassThrough((GLfloat)dfactor); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psSetOptions(GLint options) { if(!gl2ps) return GL2PS_UNINITIALIZED; gl2ps->options = options; return GL2PS_SUCCESS; } GL2PSDLL_API const char *gl2psGetFileExtension(GLint format) { if(format >= 0 && format < (GLint)(sizeof(gl2psbackends)/sizeof(gl2psbackends[0]))) return gl2psbackends[format]->file_extension; else return "Unknown format"; } GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format) { if(format >= 0 && format < (GLint)(sizeof(gl2psbackends)/sizeof(gl2psbackends[0]))) return gl2psbackends[format]->description; else return "Unknown format"; } qwtplot3d-0.2.7+svn191/3rdparty/gl2ps/gl2ps.h0000644000203200020320000001501010663257610020042 0ustar gudjongudjon/* $Id: gl2ps.h 173 2007-05-20 15:51:51Z krischnamurti $ */ /* * GL2PS, an OpenGL to PostScript Printing Library * Copyright (C) 1999-2006 Christophe Geuzaine * * This program is free software; you can redistribute it and/or * modify it under the terms of either: * * a) the GNU Library General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your * option) any later version; or * * b) the GL2PS License as published by Christophe Geuzaine, either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either * the GNU Library General Public License or the GL2PS License for * more details. * * You should have received a copy of the GNU Library General Public * License along with this library in the file named "COPYING.LGPL"; * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. * * You should have received a copy of the GL2PS License with this * library in the file named "COPYING.GL2PS"; if not, I will be glad * to provide one. * * For the latest info about gl2ps, see http://www.geuz.org/gl2ps/. * Please report all bugs and problems to . */ #ifndef __GL2PS_H__ #define __GL2PS_H__ #include #include /* Define GL2PSDLL at compile time to build a Windows DLL */ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) # if defined(_MSC_VER) # pragma warning(disable:4115) # if (_MSC_VER >= 1400) /* VS8 - not sure about VC7 */ # pragma warning(disable: 4996) /* MS security enhancements */ # endif # endif # include # if defined(GL2PSDLL) # if defined(GL2PSDLL_EXPORTS) # define GL2PSDLL_API __declspec(dllexport) # else # define GL2PSDLL_API __declspec(dllimport) # endif # else # define GL2PSDLL_API # endif #else # define GL2PSDLL_API #endif #if defined(__APPLE__) || defined(HAVE_OPENGL_GL_H) # include #else # include #endif /* Support for compressed PostScript/PDF/SVG and for embedded PNG images in SVG */ #if defined(HAVE_ZLIB) || defined(HAVE_LIBZ) # define GL2PS_HAVE_ZLIB # if defined(HAVE_LIBPNG) || defined(HAVE_PNG) # define GL2PS_HAVE_LIBPNG # endif #endif /* Version number */ #define GL2PS_MAJOR_VERSION 1 #define GL2PS_MINOR_VERSION 3 #define GL2PS_PATCH_VERSION 2 #define GL2PS_EXTRA_VERSION "" #define GL2PS_VERSION (GL2PS_MAJOR_VERSION + \ 0.01 * GL2PS_MINOR_VERSION + \ 0.0001 * GL2PS_PATCH_VERSION) #define GL2PS_COPYRIGHT "(C) 1999-2006 Christophe Geuzaine (geuz@geuz.org)" /* Output file formats (the values and the ordering are important!) */ #define GL2PS_PS 0 #define GL2PS_EPS 1 #define GL2PS_TEX 2 #define GL2PS_PDF 3 #define GL2PS_SVG 4 #define GL2PS_PGF 5 /* Sorting algorithms */ #define GL2PS_NO_SORT 1 #define GL2PS_SIMPLE_SORT 2 #define GL2PS_BSP_SORT 3 /* Message levels and error codes */ #define GL2PS_SUCCESS 0 #define GL2PS_INFO 1 #define GL2PS_WARNING 2 #define GL2PS_ERROR 3 #define GL2PS_NO_FEEDBACK 4 #define GL2PS_OVERFLOW 5 #define GL2PS_UNINITIALIZED 6 /* Options for gl2psBeginPage */ #define GL2PS_NONE 0 #define GL2PS_DRAW_BACKGROUND (1<<0) #define GL2PS_SIMPLE_LINE_OFFSET (1<<1) #define GL2PS_SILENT (1<<2) #define GL2PS_BEST_ROOT (1<<3) #define GL2PS_OCCLUSION_CULL (1<<4) #define GL2PS_NO_TEXT (1<<5) #define GL2PS_LANDSCAPE (1<<6) #define GL2PS_NO_PS3_SHADING (1<<7) #define GL2PS_NO_PIXMAP (1<<8) #define GL2PS_USE_CURRENT_VIEWPORT (1<<9) #define GL2PS_COMPRESS (1<<10) #define GL2PS_NO_BLENDING (1<<11) #define GL2PS_TIGHT_BOUNDING_BOX (1<<12) /* Arguments for gl2psEnable/gl2psDisable */ #define GL2PS_POLYGON_OFFSET_FILL 1 #define GL2PS_POLYGON_BOUNDARY 2 #define GL2PS_LINE_STIPPLE 3 #define GL2PS_BLEND 4 /* Text alignment (o=raster position; default mode is BL): +---+ +---+ +---+ +---+ +---+ +---+ +-o-+ o---+ +---o | o | o | | o | | | | | | | | | | | | +---+ +---+ +---+ +-o-+ o---+ +---o +---+ +---+ +---+ C CL CR B BL BR T TL TR */ #define GL2PS_TEXT_C 1 #define GL2PS_TEXT_CL 2 #define GL2PS_TEXT_CR 3 #define GL2PS_TEXT_B 4 #define GL2PS_TEXT_BL 5 #define GL2PS_TEXT_BR 6 #define GL2PS_TEXT_T 7 #define GL2PS_TEXT_TL 8 #define GL2PS_TEXT_TR 9 typedef GLfloat GL2PSrgba[4]; #if defined(__cplusplus) extern "C" { #endif GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename); GL2PSDLL_API GLint gl2psEndPage(void); GL2PSDLL_API GLint gl2psSetOptions(GLint options); GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]); GL2PSDLL_API GLint gl2psEndViewport(void); GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize); GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize, GLint align, GLfloat angle); GL2PSDLL_API GLint gl2psSpecial(GLint format, const char *str); GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height, GLint xorig, GLint yorig, GLenum format, GLenum type, const void *pixels); GL2PSDLL_API GLint gl2psEnable(GLint mode); GL2PSDLL_API GLint gl2psDisable(GLint mode); GL2PSDLL_API GLint gl2psPointSize(GLfloat value); GL2PSDLL_API GLint gl2psLineWidth(GLfloat value); GL2PSDLL_API GLint gl2psBlendFunc(GLenum sfactor, GLenum dfactor); /* undocumented */ GL2PSDLL_API GLint gl2psDrawImageMap(GLsizei width, GLsizei height, const GLfloat position[3], const unsigned char *imagemap); GL2PSDLL_API const char *gl2psGetFileExtension(GLint format); GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format); #if defined(__cplusplus) } #endif #endif /* __GL2PS_H__ */ qwtplot3d-0.2.7+svn191/3rdparty/gl2ps/COPYING.GL2PS0000644000203200020320000000170010663257610020524 0ustar gudjongudjon GL2PS LICENSE Version 2, November 2003 Copyright (C) 2003, Christophe Geuzaine Permission to use, copy, and distribute this software and its documentation for any purpose with or without fee is hereby granted, provided that the copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Permission to modify and distribute modified versions of this software is granted, provided that: 1) the modifications are licensed under the same terms as this software; 2) you make available the source code of any modifications that you distribute, either on the same media as you distribute any executable or other form of this software, or via a mechanism generally accepted in the software development community for the electronic transfer of data. This software is provided "as is" without express or implied warranty. qwtplot3d-0.2.7+svn191/examples/0000755000203200020320000000000010663257711015666 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/autoswitch/0000755000203200020320000000000010663257711020060 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/autoswitch/autoswitch.h0000644000203200020320000000146510663257610022427 0ustar gudjongudjon#ifndef AUTOSWITCH_H__ #define AUTOSWITCH_H__ #include #include "qwt3d_surfaceplot.h" #include "qwt3d_function.h" typedef Qwt3D::SurfacePlot SurfacePlot; // VC6/moc issue typedef Qwt3D::Function Function; // VC6/moc issue class Saddle : public Function { public: Saddle(SurfacePlot& pw) :Function(pw) { setDomain(-2.5,2.5,-2.5,2.5); setMaxZ(1.5); setMinZ(-1.5); setMesh(31,31); } double operator()(double x, double y) { return x*y; } }; class Hat : public Function { public: Hat(SurfacePlot& pw) :Function(pw) { setDomain(-1.5,1.5,-1.5,1.5); setMesh(41,41); } double operator()(double x, double y) { return 1.0 / (x*x+y*y+0.3); } }; class Plot : public SurfacePlot { Q_OBJECT public: Plot(QWidget* pw, int updateinterval); public slots: void rotate(); }; #endif qwtplot3d-0.2.7+svn191/examples/autoswitch/autoswitch.pro0000644000203200020320000000011210663257610022764 0ustar gudjongudjoninclude( ../common.pro ) SOURCES = autoswitch.cpp HEADERS = autoswitch.h qwtplot3d-0.2.7+svn191/examples/autoswitch/autoswitch.cpp0000644000203200020320000000501610663257610022756 0ustar gudjongudjon#include #include #include #include "autoswitch.h" using namespace Qwt3D; //-------------------------------------------------------------------- // autoswitch.cpp // // Demonstrates autoswitching axes with a cutted saddle as data //-------------------------------------------------------------------- Plot::Plot(QWidget* pw, int updateinterval) :SurfacePlot(pw) { setRotation(30,0,15); setShift(0.1,0,0); setZoom(0.8); coordinates()->setNumberFont("Courier",8); for (unsigned i=0; i!=coordinates()->axes.size(); ++i) { coordinates()->axes[i].setMajors(7); coordinates()->axes[i].setMinors(4); } coordinates()->axes[Qwt3D::X1].setLabelString("x"); coordinates()->axes[Y1].setLabelString("y"); coordinates()->axes[Z1].setLabelString("z"); coordinates()->axes[X2].setLabelString("x"); coordinates()->axes[Y2].setLabelString("y"); coordinates()->axes[Z2].setLabelString("z"); coordinates()->axes[X3].setLabelString("x"); coordinates()->axes[Y3].setLabelString("y"); coordinates()->axes[Z3].setLabelString("z"); coordinates()->axes[X4].setLabelString("x"); coordinates()->axes[Y4].setLabelString("y"); coordinates()->axes[Z4].setLabelString("z"); QTimer* timer = new QTimer( this ); connect( timer, SIGNAL(timeout()), this, SLOT(rotate()) ); timer->start(updateinterval); } void Plot::rotate() { int prec = 3; setRotation( (int(prec*xRotation() + 2) % (360*prec))/double(prec), (int(prec*yRotation() + 2) % (360*prec))/double(prec), (int(prec*zRotation() + 2) % (360*prec))/double(prec) ); } int main(int argc, char **argv) { QApplication a(argc, argv); #if QT_VERSION < 0x040000 QSplitter* spl = new QSplitter(QSplitter::Horizontal); #else QSplitter* spl = new QSplitter(Qt::Horizontal); #endif Plot* plot1 = new Plot(spl,30); plot1->setFloorStyle(FLOORISO); plot1->setCoordinateStyle(BOX); Saddle saddle(*plot1); saddle.create(); plot1->setTitle("Autoswitching axes"); plot1->setBackgroundColor(RGBA(1,1, 157./255)); plot1->makeCurrent(); plot1->updateData(); plot1->updateGL(); Plot* plot2 = new Plot(spl,80); plot2->setZoom(0.8); Hat hat(*plot2); hat.create(); plot2->setPlotStyle(HIDDENLINE); plot2->setFloorStyle(FLOORDATA); plot2->setCoordinateStyle(FRAME); plot2->setBackgroundColor(RGBA(1,1, 157./255)); plot2->makeCurrent(); plot2->updateData(); plot2->updateGL(); #if QT_VERSION < 0x040000 a.setMainWidget(spl); #endif spl->resize(800,400); spl->show(); return a.exec(); } qwtplot3d-0.2.7+svn191/examples/enrichments/0000755000203200020320000000000010663257711020205 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/enrichments/src/0000755000203200020320000000000010663257711020774 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/enrichments/src/enrichmentmainwindow.h0000644000203200020320000000166210663257611025402 0ustar gudjongudjon#include "qwt3d_surfaceplot.h" #include "qwt3d_function.h" #include "qwt3d_plot.h" #include "enrichments.h" #if QT_VERSION < 0x040000 #include "enrichmentmainwindowbase.h" #else #include "ui_enrichmentmainwindowbase4.h" #endif //MOC_SKIP_BEGIN #if QT_VERSION < 0x040000 class DummyBase : public EnrichmentMainWindowBase { public: DummyBase(QWidget* parent = 0) : EnrichmentMainWindowBase(parent) { } }; #else class DummyBase : public QMainWindow, protected Ui::MainWindow { public: DummyBase(QWidget* parent = 0) : QMainWindow(parent) { } }; #endif //MOC_SKIP_END class EnrichmentMainWindow : public DummyBase { Q_OBJECT public: EnrichmentMainWindow( QWidget* parent = 0 ); ~EnrichmentMainWindow(); void setColor(); Bar *bar; Qwt3D::SurfacePlot* plot; public slots: void setLevel(int); void setWidth(int); void barSlot(); private: double level_, width_; }; qwtplot3d-0.2.7+svn191/examples/enrichments/src/enrichmentmainwindowbase.ui0000644000203200020320000002072110663257611026420 0ustar gudjongudjon EnrichmentMainWindowBase EnrichmentMainWindowBase 0 0 843 702 print unnamed 11 6 Layout11 unnamed 0 6 Layout10 unnamed 0 6 TextLabel1_2 false 5 0 0 0 Width widthSlider false 7 0 0 0 0 40 10 200 Horizontal Below 10 Relative psition of slicing plane Layout9 unnamed 0 6 Layout8 unnamed 0 6 levelSlider true 40 0 100 10 Vertical Below 10 Changes the level, where marker are shown TextLabel1 Level AlignCenter frame StyledPanel Sunken menubar qwtplot3d-0.2.7+svn191/examples/enrichments/src/enrichments.cpp0000644000203200020320000001122010663257611024012 0ustar gudjongudjon#include "qbitmap.h" #include "qwt3d_color.h" #include "qwt3d_plot.h" #include "enrichments.h" using namespace Qwt3D; ///////////////////////////////////////////////////////////////// // // Bar // ///////////////////////////////////////////////////////////////// Bar::Bar() { configure(0, 1); } Bar::Bar(double rad, double level) { configure(rad, level); } void Bar::configure(double rad, double level) { plot = 0; radius_ = rad; level_ = level; } void Bar::drawBegin() { diag_ = (plot->hull().maxVertex-plot->hull().minVertex).length() * radius_; glLineWidth( 0 ); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1,1); } void Bar::drawEnd() { } void Bar::draw(Qwt3D::Triple const& pos) { // GLStateBewarer sb(GL_LINE_SMOOTH, true); // sb.turnOn(); double interval = plot->hull().maxVertex.z-plot->hull().minVertex.z; double numlevel = plot->hull().minVertex.z + level_ * interval; interval /=100; if (pos.z > numlevel - interval && pos.z < numlevel + interval ) { Label3D lb; lb.draw(pos, diag_, diag_ * 2); } GLdouble minz = plot->hull().minVertex.z; RGBA rgbat = (*plot->dataColor())(pos); RGBA rgbab = (*plot->dataColor())(pos.x, pos.y, minz); glBegin(GL_QUADS); glColor4d(rgbab.r,rgbab.g,rgbab.b,rgbab.a); glVertex3d(pos.x-diag_,pos.y-diag_,minz); glVertex3d(pos.x+diag_,pos.y-diag_,minz); glVertex3d(pos.x+diag_,pos.y+diag_,minz); glVertex3d(pos.x-diag_,pos.y+diag_,minz); if (pos.z > numlevel - interval && pos.z < numlevel + interval ) glColor3d(0.7,0,0); else glColor4d(rgbat.r,rgbat.g,rgbat.b,rgbat.a); glVertex3d(pos.x-diag_,pos.y-diag_,pos.z); glVertex3d(pos.x+diag_,pos.y-diag_,pos.z); glVertex3d(pos.x+diag_,pos.y+diag_,pos.z); glVertex3d(pos.x-diag_,pos.y+diag_,pos.z); glColor4d(rgbab.r,rgbab.g,rgbat.b,rgbab.a); glVertex3d(pos.x-diag_,pos.y-diag_,minz); glVertex3d(pos.x+diag_,pos.y-diag_,minz); glColor4d(rgbat.r,rgbat.g,rgbat.b,rgbat.a); glVertex3d(pos.x+diag_,pos.y-diag_,pos.z); glVertex3d(pos.x-diag_,pos.y-diag_,pos.z); glColor4d(rgbab.r,rgbab.g,rgbat.b,rgbab.a); glVertex3d(pos.x-diag_,pos.y+diag_,minz); glVertex3d(pos.x+diag_,pos.y+diag_,minz); glColor4d(rgbat.r,rgbat.g,rgbat.b,rgbat.a); glVertex3d(pos.x+diag_,pos.y+diag_,pos.z); glVertex3d(pos.x-diag_,pos.y+diag_,pos.z); glColor4d(rgbab.r,rgbab.g,rgbat.b,rgbab.a); glVertex3d(pos.x-diag_,pos.y-diag_,minz); glVertex3d(pos.x-diag_,pos.y+diag_,minz); glColor4d(rgbat.r,rgbat.g,rgbat.b,rgbat.a); glVertex3d(pos.x-diag_,pos.y+diag_,pos.z); glVertex3d(pos.x-diag_,pos.y-diag_,pos.z); glColor4d(rgbab.r,rgbab.g,rgbat.b,rgbab.a); glVertex3d(pos.x+diag_,pos.y-diag_,minz); glVertex3d(pos.x+diag_,pos.y+diag_,minz); glColor4d(rgbat.r,rgbat.g,rgbat.b,rgbat.a); glVertex3d(pos.x+diag_,pos.y+diag_,pos.z); glVertex3d(pos.x+diag_,pos.y-diag_,pos.z); glEnd(); glColor3d(0,0,0); glBegin(GL_LINES); glVertex3d(pos.x-diag_,pos.y-diag_,minz); glVertex3d(pos.x+diag_,pos.y-diag_,minz); glVertex3d(pos.x-diag_,pos.y-diag_,pos.z); glVertex3d(pos.x+diag_,pos.y-diag_,pos.z); glVertex3d(pos.x-diag_,pos.y+diag_,pos.z); glVertex3d(pos.x+diag_,pos.y+diag_,pos.z); glVertex3d(pos.x-diag_,pos.y+diag_,minz); glVertex3d(pos.x+diag_,pos.y+diag_,minz); glVertex3d(pos.x-diag_,pos.y-diag_,minz); glVertex3d(pos.x-diag_,pos.y+diag_,minz); glVertex3d(pos.x+diag_,pos.y-diag_,minz); glVertex3d(pos.x+diag_,pos.y+diag_,minz); glVertex3d(pos.x+diag_,pos.y-diag_,pos.z); glVertex3d(pos.x+diag_,pos.y+diag_,pos.z); glVertex3d(pos.x-diag_,pos.y-diag_,pos.z); glVertex3d(pos.x-diag_,pos.y+diag_,pos.z); glVertex3d(pos.x-diag_,pos.y-diag_,minz); glVertex3d(pos.x-diag_,pos.y-diag_,pos.z); glVertex3d(pos.x+diag_,pos.y-diag_,minz); glVertex3d(pos.x+diag_,pos.y-diag_,pos.z); glVertex3d(pos.x+diag_,pos.y+diag_,minz); glVertex3d(pos.x+diag_,pos.y+diag_,pos.z); glVertex3d(pos.x-diag_,pos.y+diag_,minz); glVertex3d(pos.x-diag_,pos.y+diag_,pos.z); glEnd(); } void Label3D::draw(Qwt3D::Triple const& pos, double w, double h) { double gap = 0.3; glColor3d(1,1,1); glBegin(GL_QUADS); glVertex3d(pos.x-w,pos.y,pos.z + gap); glVertex3d(pos.x+w,pos.y,pos.z + gap); glVertex3d(pos.x+w,pos.y,pos.z + gap + h); glVertex3d(pos.x-w,pos.y,pos.z + gap + h); glEnd(); glColor3d(0.4,0,0); glBegin(GL_LINE_LOOP); glVertex3d(pos.x-w,pos.y,pos.z + gap); glVertex3d(pos.x+w,pos.y,pos.z + gap); glVertex3d(pos.x+w,pos.y,pos.z + gap + h); glVertex3d(pos.x-w,pos.y,pos.z + gap + h); glEnd(); glBegin(GL_LINES); glVertex3d(pos.x,pos.y,pos.z); glVertex3d(pos.x,pos.y,pos.z + gap); glEnd(); } qwtplot3d-0.2.7+svn191/examples/enrichments/src/enrichmentmainwindowbase4.ui0000644000203200020320000001255510663257611026512 0ustar gudjongudjon MainWindow 0 0 800 600 MainWindow 8 6 0 6 0 6 QFrame::StyledPanel QFrame::Sunken 0 6 5 0 0 0 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Level</p></body></html> 0 7 0 0 100 10 Qt::Vertical true QSlider::TicksBelow 10 0 6 false 0 0 0 0 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Width</p></body></html> false 2 200 20 Qt::Horizontal QSlider::TicksBelow qwtplot3d-0.2.7+svn191/examples/enrichments/src/enrichments.h0000644000203200020320000000107010663257611023461 0ustar gudjongudjon#ifndef enrichments_h__2004_02_25_13_58_begin_guarded_code #define enrichments_h__2004_02_25_13_58_begin_guarded_code #include "qwt3d_plot.h" class Bar : public Qwt3D::VertexEnrichment { public: Bar(); Bar(double rad, double level); Qwt3D::Enrichment* clone() const {return new Bar(*this);} void configure(double rad, double level); void drawBegin(); void drawEnd(); void draw(Qwt3D::Triple const&); private: double level_, radius_; double diag_; }; class Label3D { public: void draw(Qwt3D::Triple const&, double w, double h); }; #endif qwtplot3d-0.2.7+svn191/examples/enrichments/src/main.cpp0000644000203200020320000000115710663257611022427 0ustar gudjongudjon/******************************************************************** created: 2003/09/10 filename: main.cpp author: Micha Bieber *********************************************************************/ #include #include "enrichmentmainwindow.h" int main( int argc, char** argv ) { QApplication app( argc, argv ); if ( !QGLFormat::hasOpenGL() ) { qWarning( "This system has no OpenGL support. Exiting." ); return -1; } EnrichmentMainWindow mainwindow; #if QT_VERSION < 0x040000 app.setMainWidget(&mainwindow); #endif mainwindow.show(); return app.exec(); } qwtplot3d-0.2.7+svn191/examples/enrichments/src/enrichmentmainwindow.cpp0000644000203200020320000000545510663257611025741 0ustar gudjongudjon#include #include #include #include #include "enrichmentmainwindow.h" #include "enrichments.h" #include "../../../include/qwt3d_function.h" using namespace Qwt3D; class Hat : public Function { public: Hat(SurfacePlot& pw) :Function(pw) { } double operator()(double x, double y) { double ret = 1.0 / (x*x+y*y+0.5); return ret; } QString name() const {return "$\\frac{1}{x^2+y^2+\\frac{1}{2}}$";} }; Hat* hat; EnrichmentMainWindow::EnrichmentMainWindow( QWidget* parent ) : DummyBase( parent ) { #if QT_VERSION < 0x040000 setCaption("enrichment"); QGridLayout *grid = new QGridLayout( frame, 0, 0 ); #else setupUi(this); QGridLayout *grid = new QGridLayout( frame); #endif plot = new SurfacePlot(frame); grid->addWidget( plot, 0, 0 ); plot->setTitle("Bar Style (Vertex Enrichment)"); plot->setTitleFont("Arial",12); plot->setZoom(0.8); plot->setRotation(30,0,15); plot->setCoordinateStyle(BOX); bar = (Bar*)plot->setPlotStyle(Bar(0.007,0.5)); hat = new Hat(*plot); hat->setMesh(23,21); hat->setDomain(-1.8,1.7,-1.6,1.7); hat->create(); for (unsigned i=0; i!=plot->coordinates()->axes.size(); ++i) { plot->coordinates()->axes[i].setMajors(5); plot->coordinates()->axes[i].setMinors(4); } //plot->setMeshLineWidth(1); plot->coordinates()->setGridLinesColor(RGBA(0,0,0.5)); plot->coordinates()->setLineWidth(1); plot->coordinates()->setNumberFont("Courier",8); plot->coordinates()->adjustNumbers(5); setColor(); plot->updateData(); plot->updateGL(); levelSlider->setValue(50); level_ = 0.5; width_ = 0.007; connect( levelSlider, SIGNAL(valueChanged(int)), this, SLOT(setLevel(int)) ); //connect( barBtn, SIGNAL(clicked()), this, SLOT(barSlot()) ); //connect( sliceBtn, SIGNAL(clicked()), this, SLOT(sliceSlot()) ); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_LINE_SMOOTH); } EnrichmentMainWindow::~EnrichmentMainWindow() { delete hat; } void EnrichmentMainWindow::setColor() { Qwt3D::ColorVector cv; RGBA rgb; int i = 252; int step = 4; while (i>=0) { rgb.r = i/255.; rgb.g=(i-60>0) ? (i-60)/255.:0;rgb.b=0; // rgb.a = 0.2; cv.push_back(rgb); if (!--step) { i-=4; step=4; } } StandardColor* col = new StandardColor(plot); col->setColorVector(cv); plot->setDataColor(col); } void EnrichmentMainWindow::setLevel(int i) { level_ = 1 - i / 100.; bar->configure(width_,level_); plot->updateData(); plot->updateGL(); } void EnrichmentMainWindow::setWidth(int i) { width_ = i / 20000.; bar->configure(width_,level_); plot->updateData(); plot->updateGL(); } void EnrichmentMainWindow::barSlot() { Bar b(width_,level_); bar = (Bar*)plot->setPlotStyle(b); plot->updateData(); plot->updateGL(); } qwtplot3d-0.2.7+svn191/examples/enrichments/enrichments.pro0000644000203200020320000000050210663257611023242 0ustar gudjongudjoninclude( ../common.pro ) SOURCES = src/main.cpp \ src/enrichmentmainwindow.cpp \ src/enrichments.cpp HEADERS = src/enrichmentmainwindow.h \ src/enrichments.h !isEmpty( ISQT4 ) { FORMS = src/enrichmentmainwindowbase4.ui } isEmpty( ISQT4 ) { FORMS = src/enrichmentmainwindowbase.ui } qwtplot3d-0.2.7+svn191/examples/simpleplot/0000755000203200020320000000000010663257711020056 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/simpleplot/simpleplot.pro0000644000203200020320000000006310663257611022766 0ustar gudjongudjoninclude( ../common.pro ) SOURCES = simpleplot.cpp qwtplot3d-0.2.7+svn191/examples/simpleplot/simpleplot.cpp0000644000203200020320000000323610663257611022755 0ustar gudjongudjon //----------------------------------------------------------------- // simpleplot.cpp // // A simple example which shows how to use SurfacePlot //----------------------------------------------------------------- #include #include #include #include using namespace Qwt3D; class Rosenbrock : public Function { public: Rosenbrock(SurfacePlot& pw) :Function(pw) { } double operator()(double x, double y) { return log((1-x)*(1-x) + 100 * (y - x*x)*(y - x*x)) / 8; } }; class Plot : public SurfacePlot { public: Plot(); }; Plot::Plot() { setTitle("A Simple SurfacePlot Demonstration"); Rosenbrock rosenbrock(*this); rosenbrock.setMesh(41,31); rosenbrock.setDomain(-1.73,1.5,-1.5,1.5); rosenbrock.setMinZ(-10); rosenbrock.create(); setRotation(30,0,15); setScale(1,1,1); setShift(0.15,0,0); setZoom(0.9); for (unsigned i=0; i!=coordinates()->axes.size(); ++i) { coordinates()->axes[i].setMajors(7); coordinates()->axes[i].setMinors(4); } coordinates()->axes[X1].setLabelString("x-axis"); coordinates()->axes[Y1].setLabelString("y-axis"); //coordinates()->axes[Z1].setLabelString(QChar(0x38f)); // Omega - see http://www.unicode.org/charts/ setCoordinateStyle(BOX); updateData(); updateGL(); } int main(int argc, char **argv) { QApplication a(argc, argv); Plot plot; #if QT_VERSION < 0x040000 a.setMainWidget(&plot); #endif plot.resize(800,600); plot.show(); return a.exec(); } qwtplot3d-0.2.7+svn191/examples/axes/0000755000203200020320000000000010663257711016626 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/axes/src/0000755000203200020320000000000010663257711017415 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/axes/src/axesmainwindow.h0000644000203200020320000000211710663257611022623 0ustar gudjongudjon#include #include "qwt3d_surfaceplot.h" #include "qwt3d_function.h" #include "qwt3d_plot.h" #if QT_VERSION < 0x040000 #include "axesmainwindowbase.h" #else #include "ui_axesmainwindowbase4.h" #endif //MOC_SKIP_BEGIN #if QT_VERSION < 0x040000 class DummyBase : public AxesMainWindowBase { public: DummyBase(QWidget* parent = 0) : AxesMainWindowBase(parent) { } }; #else class DummyBase : public QMainWindow, protected Ui::MainWindow { public: DummyBase(QWidget* parent = 0) : QMainWindow(parent) { } }; #endif //MOC_SKIP_END class AxesMainWindow : public DummyBase { Q_OBJECT public: AxesMainWindow( QWidget* parent = 0); ~AxesMainWindow(); Qwt3D::SurfacePlot* plot; Qwt3D::Function *rosenbrock; void resetTics(); public slots: void setNumberGap(int gap); void setLabelGap(int gap); void setSmoothLines(bool); void setTicLength(int val); void setTicNumber(int degree); void standardItems(); void complexItems(); void letterItems(); void timeItems(); void customScale(); private: int tics; }; qwtplot3d-0.2.7+svn191/examples/axes/src/axesmainwindowbase.ui0000644000203200020320000002375010663257611023652 0ustar gudjongudjon AxesMainWindowBase AxesMainWindowBase 0 0 826 608 print unnamed 11 6 frame 7 7 0 0 StyledPanel Sunken layout11 unnamed layout9 unnamed TextLabel1_2 Number gap numbergapslider 7 0 0 0 10 Horizontal Above 1 layout10 unnamed TextLabel1_2_2 Label gap labelgapslider 7 0 0 0 10 Horizontal Above 1 smoothBox Smooth Lines true layout11 unnamed layout9 unnamed ticNumeberLabel true Tics AlignCenter ticLengthSlider 100 10 Vertical Below Tic Length (rel.) ticNumberSlider false 25 0 Vertical Below Change Tic Number (available only for letter example) menubar qwtplot3d-0.2.7+svn191/examples/axes/src/main.cpp0000644000203200020320000000114410663257611021044 0ustar gudjongudjon/******************************************************************** created: 2003/09/10 filename: main.cpp author: Micha Bieber *********************************************************************/ #include #include "axesmainwindow.h" int main( int argc, char** argv ) { QApplication app( argc, argv ); if ( !QGLFormat::hasOpenGL() ) { qWarning( "This system has no OpenGL support. Exiting." ); return -1; } AxesMainWindow mainwindow; #if QT_VERSION < 0x040000 app.setMainWidget(&mainwindow); #endif mainwindow.show(); return app.exec(); } qwtplot3d-0.2.7+svn191/examples/axes/src/axes.h0000644000203200020320000000275210663257611020533 0ustar gudjongudjon#ifndef axes_h__2004_06_07_10_38_begin_guarded_code #define axes_h__2004_06_07_10_38_begin_guarded_code #include "qwt3d_plot.h" using namespace Qwt3D; /***************************** * * Examples for user defined * tic labels * ******************************/ class Letter : public LinearScale { public: explicit Letter(bool uppercase = true) : uc_(uppercase) {} Scale* clone() const {return new Letter(*this);} QString ticLabel(unsigned int idx) const { if (idx 59) { if (h==23) h=0; else h+=1; m = (m+idx) % 60; } else m += idx; return QTime(h,m).toString("hh:mm")+"h"; } return QString(""); } }; #endif /* include guarded */ qwtplot3d-0.2.7+svn191/examples/axes/src/axesmainwindowbase4.ui0000644000203200020320000002275510663257611023742 0ustar gudjongudjon MainWindow 0 0 694 600 MainWindow 8 6 0 6 7 7 0 0 QFrame::StyledPanel QFrame::Sunken 0 6 0 6 0 0 0 0 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Tics</p></body></html> Qt::Horizontal QSizePolicy::Preferred 40 20 0 6 0 7 0 0 100 10 Qt::Vertical true QSlider::TicksBelow 0 7 0 0 25 Qt::Vertical true QSlider::TicksBelow 0 6 0 6 0 6 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Number gap</p></body></html> 7 5 0 0 10 Qt::Horizontal QSlider::TicksAbove 0 6 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Label gap</p></body></html> 7 5 0 0 10 Qt::Horizontal QSlider::TicksAbove 1 5 0 0 Smooth Lines 590 10 61 421 qwtplot3d-0.2.7+svn191/examples/axes/src/axesmainwindow.cpp0000644000203200020320000001607310663257611023164 0ustar gudjongudjon#include #include #include #include #include #include #include #include #include "axes.h" #include "axesmainwindow.h" #include "../../../include/qwt3d_function.h" using namespace std; using namespace Qwt3D; // Example function class Rosenbrock : public Function { public: Rosenbrock(SurfacePlot& pw) :Function(pw) { } double operator()(double x, double y) { return log10((1-x)*(1-x) + 1 * (y - x*x)*(y - x*x)); } }; // Main widget AxesMainWindow::AxesMainWindow( QWidget* parent) : DummyBase(parent) { #if QT_VERSION < 0x040000 setCaption("axes"); QGridLayout *grid = new QGridLayout( frame, 0, 0 ); #else setupUi(this); QGridLayout *grid = new QGridLayout( frame); #endif plot = new SurfacePlot(frame); grid->addWidget( plot, 0, 0 ); plot->setZoom(0.8); plot->setRotation(30,0,15); plot->coordinates()->setGridLines(true,true); plot->setCoordinateStyle(BOX); //plot->setCoordinateStyle(NOCOORD); //plot->setPlotStyle(FILLED); rosenbrock = new Rosenbrock(*plot); rosenbrock->setMesh(31,33); rosenbrock->setDomain(-1.73,1.8,-1.9,1.8); rosenbrock->setMinZ(-100); rosenbrock->create(); for (unsigned i=0; i!=plot->coordinates()->axes.size(); ++i) { plot->coordinates()->axes[i].setMajors(5); plot->coordinates()->axes[i].setMinors(4); plot->coordinates()->axes[i].setLabelColor(RGBA(0,0,0.4)); } //plot->setTitle("Rosenbrock"); plot->setMeshLineWidth(1); plot->coordinates()->setGridLinesColor(RGBA(0,0,0.5)); plot->coordinates()->setLineWidth(1); plot->coordinates()->setNumberColor(RGBA(0,0.5,0)); plot->coordinates()->setNumberFont("Courier",10); plot->setTitleFont("Courier",11); plot->coordinates()->setLabelFont("Courier",12, QFont::Bold); plot->coordinates()->axes[X1].setLabelString("X1"); plot->coordinates()->axes[Y1].setLabelString("Y1"); plot->coordinates()->axes[Z1].setLabelString("Z1"); plot->coordinates()->axes[X2].setLabelString("X2"); plot->coordinates()->axes[Y2].setLabelString("Y2"); plot->coordinates()->axes[Z2].setLabelString("Z2"); plot->coordinates()->axes[X3].setLabelString("X3"); plot->coordinates()->axes[Y3].setLabelString("Y3"); plot->coordinates()->axes[Z3].setLabelString("Z3"); plot->coordinates()->axes[X4].setLabelString("X4"); plot->coordinates()->axes[Y4].setLabelString("Y4"); plot->coordinates()->axes[Z4].setLabelString("Z4"); plot->coordinates()->setLineSmooth(true); smoothBox->setDown(true); #if QT_VERSION < 0x040000 Items->insertItem( "&Standard", this, SLOT(standardItems()), ALT+Key_S ); Items->insertItem( "&Imaginary", this, SLOT(complexItems()), ALT+Key_I ); Items->insertItem( "&Letter", this, SLOT(letterItems()), ALT+Key_L ); Items->insertItem( "&Time", this, SLOT(timeItems()), ALT+Key_T ); Items->insertItem( "&Log", this, SLOT(customScale()), ALT+Key_C ); #else QMenu* Items = menuBar()->addMenu("Item"); Items->addAction( "&Standard", this, SLOT(standardItems()), QKeySequence("ALT+S") ); Items->addAction( "&Imaginary", this, SLOT(complexItems()), QKeySequence("ALT+I") ); Items->addAction( "&Letter", this, SLOT(letterItems()), QKeySequence("ALT+L") ); Items->addAction( "&Time", this, SLOT(timeItems()), QKeySequence("ALT+T") ); Items->addAction( "&Log", this, SLOT(customScale()), QKeySequence("ALT+C") ); #endif plot->makeCurrent(); plot->updateData(); plot->updateGL(); connect(smoothBox, SIGNAL(toggled(bool)), this, SLOT(setSmoothLines(bool)) ); connect(numbergapslider, SIGNAL(valueChanged(int)), this, SLOT(setNumberGap(int)) ); connect(labelgapslider, SIGNAL(valueChanged(int)), this, SLOT(setLabelGap(int)) ); connect(ticLengthSlider, SIGNAL(valueChanged(int)), this, SLOT(setTicLength(int)) ); connect(ticNumberSlider, SIGNAL(valueChanged(int)), this, SLOT(setTicNumber(int)) ); tics = plot->coordinates()->axes[X1].majors(); //resetTics(); customScale(); plot->setPolygonOffset(10); } AxesMainWindow::~AxesMainWindow() { delete rosenbrock; } void AxesMainWindow::setNumberGap(int gap) { plot->coordinates()->adjustNumbers(gap); plot->makeCurrent(); plot->updateGL(); } void AxesMainWindow::setLabelGap(int gap) { plot->coordinates()->adjustLabels(gap); plot->makeCurrent(); plot->updateGL(); } void AxesMainWindow::setSmoothLines(bool val) { plot->coordinates()->setLineSmooth(val); plot->updateGL(); } void AxesMainWindow::setTicLength(int val) { double majl = (plot->coordinates()->second()-plot->coordinates()->first()).length() / 1000.; majl = majl * val; plot->coordinates()->setTicLength(majl,0.6*majl); plot->updateGL(); } void AxesMainWindow::setTicNumber(int degree) { plot->coordinates()->axes[X1].setMajors(tics + degree); plot->updateGL(); } void AxesMainWindow::resetTics() { ticNumberSlider->setEnabled(false); plot->setTitle(""); plot->coordinates()->axes[X1].setMajors(5); plot->coordinates()->setAutoScale(true); plot->coordinates()->setStandardScale(); plot->coordinates()->axes[Z2].setLabelString("Z4"); plot->coordinates()->setGridLines(false,false,Qwt3D::BACK); } void AxesMainWindow::standardItems() { resetTics(); plot->updateGL(); } void AxesMainWindow::letterItems() { resetTics(); ticNumberSlider->setEnabled(true); plot->coordinates()->axes[X1].setAutoScale(false); plot->coordinates()->setStandardScale(); plot->coordinates()->axes[X1].setScale(new Letter); plot->coordinates()->axes[X2].setScale(new Letter); plot->coordinates()->axes[X3].setScale(new Letter); plot->coordinates()->axes[X4].setScale(new Letter); plot->coordinates()->axes[Y1].setScale(new Letter(false)); plot->coordinates()->axes[Y2].setScale(new Letter(false)); plot->coordinates()->axes[Y3].setScale(new Letter(false)); plot->coordinates()->axes[Y4].setScale(new Letter(false)); plot->setTitle("Use the tics slider for this example!"); plot->updateGL(); } void AxesMainWindow::complexItems() { resetTics(); plot->coordinates()->axes[Y1].setScale(new Imaginary); plot->coordinates()->axes[Y2].setScale(new Imaginary); plot->coordinates()->axes[Y3].setScale(new Imaginary); plot->coordinates()->axes[Y4].setScale(new Imaginary); plot->updateGL(); } void AxesMainWindow::timeItems() { resetTics(); plot->coordinates()->axes[Z1].setScale(new TimeItems); plot->coordinates()->axes[Z2].setScale(new TimeItems); plot->coordinates()->axes[Z3].setScale(new TimeItems); plot->coordinates()->axes[Z4].setScale(new TimeItems); plot->updateGL(); } void AxesMainWindow::customScale() { resetTics(); plot->coordinates()->axes[Z1].setScale(LOG10SCALE); plot->coordinates()->axes[Z3].setScale(LOG10SCALE); plot->coordinates()->axes[Z4].setScale(LOG10SCALE); plot->coordinates()->axes[Z2].setLabelString("log10(z)"); // plot->coordinates()->axes[Z4].setScale(new LogScale); // plot->coordinates()->axes[Z1].setAutoScale(false); // plot->coordinates()->axes[Z2].setAutoScale(false); // plot->coordinates()->axes[Z3].setAutoScale(false); // plot->coordinates()->axes[Z4].setAutoScale(false); plot->coordinates()->setGridLines(true,true,Qwt3D::BACK); plot->updateGL(); } qwtplot3d-0.2.7+svn191/examples/axes/axes.pro0000644000203200020320000000040610663257611020307 0ustar gudjongudjoninclude( ../common.pro ) SOURCES = src/main.cpp \ src/axesmainwindow.cpp HEADERS = src/axesmainwindow.h \ src/axes.h !isEmpty( ISQT4 ) { FORMS = src/axesmainwindowbase4.ui } isEmpty( ISQT4 ) { FORMS = src/axesmainwindowbase.ui } qwtplot3d-0.2.7+svn191/examples/mesh2/0000755000203200020320000000000010663257711016704 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/mesh2/src/0000755000203200020320000000000010663257711017473 5ustar gudjongudjonqwtplot3d-0.2.7+svn191/examples/mesh2/src/femreader.h0000644000203200020320000000263310663257611021601 0ustar gudjongudjon#ifndef femreader_h__2004_03_07_14_03_begin_guarded_code #define femreader_h__2004_03_07_14_03_begin_guarded_code #include #include #include "qwt3d_global.h" #include "qwt3d_types.h" class NodeFilter { public: explicit NodeFilter() { values = std::vector(6); } Qwt3D::Triple readLine(std::ifstream& str) { for (unsigned i = 0; i!=values.size(); ++i) str >> values[i]; return Qwt3D::Triple(values[1], values[2], values[5] / 1000); } private: std::vector values; }; class CellFilter { public: Qwt3D::Cell readLine(std::ifstream& str) { Qwt3D::Cell cell(4); str >> cell[0]; // dummy (cell number) - overridden in next step for (unsigned i = 0; i> cell[i]; cell[i] = cell[i] - 1; } return cell; } }; template bool readNodes(Qwt3D::TripleField& v, const char* fname, FILTER fil) { std::ifstream file(fname); v.clear(); Qwt3D::Triple t; while ( file ) { t = fil.readLine( file ); if (!file.good()) break; v.push_back( t ); } return true; } template bool readConnections(Qwt3D::CellField& v, const char* fname, FILTER fil) { std::ifstream file(fname); v.clear(); Qwt3D::Cell cell; while ( file ) { cell = fil.readLine( file ); if (!file.good()) break; v.push_back(cell); } return true; } #endif /* include guarded */ qwtplot3d-0.2.7+svn191/examples/mesh2/src/colormapreader.cpp0000644000203200020320000000266110663257611023202 0ustar gudjongudjon#include #include #include #include #include #include "colormapreader.h" using namespace Qwt3D; using namespace std; #if QT_VERSION < 0x040000 ColorMapPreview::ColorMapPreview( QWidget *parent ) : QFrame( parent ) { label_ = new QLabel(this); setFrameShape( QFrame::StyledPanel ); setFrameShadow( QFrame::Sunken ); QGridLayout* layout = new QGridLayout( this, 1, 1, 10); layout->addWidget( label_, 0, 0, Qt::AlignJustify ); } void ColorMapPreview::previewUrl( const QUrl &u ) { QString path = u.path(); QFileInfo fi( path ); if (fi.extension() != "map" && fi.extension() != "MAP") label_->setText( "No color map" ); else { if ( open(path) ) label_->setPixmap( pix_ ); } } bool ColorMapPreview::open(QString fname) { if (fname.isEmpty()) return false; ifstream file(QWT3DLOCAL8BIT(fname)); RGBA rgb; cv.clear(); while ( file ) { file >> rgb.r >> rgb.g >> rgb.b; file.ignore(10000,'\n'); if (!file.good()) break; else { rgb.a = 1; rgb.r /= 255; rgb.g /= 255; rgb.b /= 255; cv.push_back(rgb); } } pix_.resize(80, cv.size()); QPainter p( &pix_ ); p.translate( 0, cv.size()-1 ); for (unsigned i=0; i!=cv.size(); ++i) { rgb = cv[i]; p.setPen(GL2Qt(rgb.r,rgb.g,rgb.b)); p.drawLine(QPoint(0,0),QPoint(pix_.width(),0)); p.translate( 0, -1 ); } p.end(); return true; } #else #endif qwtplot3d-0.2.7+svn191/examples/mesh2/src/lightingdlg.h0000644000203200020320000000363410663257611022145 0ustar gudjongudjon#ifndef lightingdlg_h__2004_03_07_13_35_begin_guarded_code #define lightingdlg_h__2004_03_07_13_35_begin_guarded_code #include #include #include "../../../include/qwt3d_parametricsurface.h" #include "../../../include/qwt3d_surfaceplot.h" #include "../../../include/qwt3d_enrichment.h" #include "../../../include/qwt3d_color.h" #if QT_VERSION < 0x040000 #include "lightingdlgbase.h" #else #include "ui_lightingdlgbase4.h" #endif class Pointer : public Qwt3D::VertexEnrichment { public: Pointer(double rad); ~Pointer(); Qwt3D::Enrichment* clone() const {return new Pointer(*this);} void configure(double rad); void drawBegin(); void draw(Qwt3D::Triple const&){} void setPos(double x, double y, double z) {pos_ = Qwt3D::Triple(x,y,z);} private: double radius_; Qwt3D::Triple pos_; }; struct SColor : public Qwt3D::Color { Qwt3D::RGBA operator()(double, double, double) const {return Qwt3D::RGBA(0.8,0,0,0.5);} }; typedef Qwt3D::SurfacePlot SPlot; // moc/VC6 issue in Qt 4.0.0 class Plot : public SPlot { Q_OBJECT public: Plot(QWidget* parent); Pointer* stick; void reset(); }; //MOC_SKIP_BEGIN #if QT_VERSION < 0x040000 class LightingBase : public LightingDlgBase { public: LightingBase(QWidget* parent = 0) : LightingDlgBase(parent) { } }; #else class LightingBase : public QDialog, protected Ui::Dialog { public: LightingBase(QWidget* parent = 0) : QDialog(parent) { } }; #endif //MOC_SKIP_END class LightingDlg : public LightingBase { Q_OBJECT public: LightingDlg(QWidget *parent=0); ~LightingDlg(); void assign(Qwt3D::Plot3D* pl); Plot* plot; Qwt3D::Plot3D* dataPlot; public slots: void setDistance(int); void setEmission(int); void setDiff(int); void setSpec(int); void setShin(int); void reset(); void setRotation(double x, double y, double z); }; #endif /* include guarded */ qwtplot3d-0.2.7+svn191/examples/mesh2/src/mesh2mainwindowbase.ui0000644000203200020320000024547610663257611024021 0ustar gudjongudjon Mesh2MainWindowBase Mesh2MainWindowBase 0 0 954 710 5 5 0 0 381 328 Mesh2 false unnamed 11 6 Spacer4 Vertical Fixed 16 50 Layout11 unnamed 0 6 Layout9 unnamed 0 6 projection 0 0 0 0 Ortho true colorlegend true 0 0 0 0 Legend autoscale true 0 0 0 0 Autoscale true Autoscale axes Autoscale axes mouseinput 0 0 0 0 Mouse true Enable mouse input shader true 0 0 0 0 Shading true Checked means Gouraud (smooth) shading, flat else Checked means Gouraud (smooth) shading, flat else Layout7 unnamed 0 6 Layout6 unnamed 0 6 normalsquality 3 32 4 true Vertical Above 1 Quality (Roundness) normalslength 1 100 5 8 true Vertical Above 5 Length TextLabel1 Normals frame StyledPanel Sunken Layout8 unnamed 0 6 normButton 0 0 0 0 50 35 50 35 0 Std Set standard view lighting false 0 0 0 0 60 35 80 35 0 Lighting Calibrate Lighting lightingswitch Turn Lighting on/off. Layout10 unnamed 0 6 TextLabel2 Polygon Offset AlignCenter offsSlider 0 25 30 1 5 5 Horizontal Above 2 Increase surface quality by setting polygon offset (OpenGL specific) Spacer5 Horizontal Preferred 41 16 Layout9 unnamed 0 6 TextLabel1_2 Resolution AlignCenter resSlider 0 25 1 100 1 Horizontal Above 5 Set data resolution (no effect for nonrectangular data) menubar Toolbar true 0 false false false Toolbar png bmp ppm xpm filetypeCB Spacer3 Horizontal Fixed 20 20 --- Hat Rosenbrock Saddle Sombrero Ripple functionCB 150 0 Display function --- Torus Seashell Boy Dini Cone psurfaceCB Display parametric surface. Turn Lighting on for better quality. Toolbar_2 true 0 false false false false Toolbar_2 openFile image0 Open File &Open File Open File Ctrl+O Exit Exit Exit Exit Ctrl+Q coord Coordinates &Coord Coordinates false Box true image1 Box Box Box Box A Frame true image2 Frame &Frame Frame Frame F None true true image3 No Axes No Axes No Axes No Axes animation true image4 Animation Animation Animation Ctrl+A dump image5 Dump Content Dump Content Dump Content Dump Content plotstyle Plot Style Plot Style Plot Style false wireframe true true image6 Wireframe Wireframe Wireframe Wireframe hiddenline true true image7 Hidden Line Hidden Line Hidden Line (EXPERIMENTAL!) Hidden Line (EXPERIMENTAL!) polygon true true image8 Polygon only Polygon only Polygon only Polygon only filledmesh true true image9 Mesh & filled Polygons Mesh & filled Polygons Mesh & filled Polygons Mesh & filled Polygons nodata true false image10 No Data No Data No Data No Data pointstyle true image11 Points Points Points color Color &Color Color Color false false axescolor Axes &Axes Axes Axes backgroundcolor Background &Background Background Background meshcolor Mesh &Mesh Mesh Mesh numbercolor Numbers &Numbers Numbers Numbers labelcolor Label &Label Label Label titlecolor Caption Caption Caption Caption datacolor Data Color Data Color Data Color resetcolor Reset &Reset Reset Reset font Fonts &Fonts Fonts false false numberfont Scale numbering &Scale numbering Scale numbering Scale numbering labelfont Axis label &Axis label Axis label Axis label titlefont Caption &Caption Caption Caption resetfont Reset &Reset Reset Reset floorstyle Floor Style Floor Style Floor Style false floordata true image12 Floor Data Projection Floor Data Projection Floor Data Projection Floor Data Projection flooriso true image13 Floor Isolines Floor Isolines Floor Isolines Floor Isolines floornone true true image14 Empty Floor Empty Floor Empty Floor Empty Floor openMeshFile image15 Open FEM files Open FEM files normals true image16 Show normal vectors Show normal vectors grids true grid grid grid false false front true image17 Action Action Front Grid back true image18 Action_2 Action_2 Back Grid right true image19 Action_3 Action_3 Right Grid left true image20 Action_4 Action_4 Left Grid ceil true image21 Action_5 Action_5 Ceiling Grid floor true image22 Action_6 Action_6 Floor Grid 89504e470d0a1a0a0000000d49484452000000100000000d0806000000a0bbee240000009049444154789c9d92410ac4200c457f4ab65de4429e6c6018989365e1755cf40076a18106621503f2157d21ff23e59c31ab9452b5bdaad2f3ee588155956c5933535a99603491aa12cf461cc156c4ccb55c00500008e41cc351736ed260a0a05ce2cea6724ad8b48718435ee3ea16fce3371b030b1efe7ce7e0ffd732e916f660e091c10e0cf40c803dd83558a9e81fdc37d14cdbb2be9c140000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000009e49444154789c633c76ec1803b5010b2e09df88f7ff3f7efa4d9261ac2c8c0c5c5c2cd80db5f37af5ffd0363146121dc860e7f5eaff8f9f7f1998a869e0a16d628c3f7ffe4335945203617c265c12e41ac8c0008d283baf57ff79785818ecbc5efd27d5506c0e8147d4b6554264b9129b38464451038c1a3a6a2895002c7751cd50e4ec4a1543711628d43290810129ef9353983030e02950c829f2f00100bdf84c6a92a74e8d0000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000006e49444154789c633c76ec1803b5011332c7ceebd57faa1b4a2d306ae8a8a1a3865203c0b239d50cb5f37af5ffd03631460c430f6d1363b4f37af59fd48205d94006060606167405304998c1c88a893110aba1a4188ecd40bc8612321c978144194a8acb493614dd707c8026891f00185139a40ba3f8e90000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000009f49444154789c633c76ec1803b501133e493baf57ff49a19dfd5eff6760606060c4e6523baf57ff0f6d136324c795ae816ffe6375293906c25cbb7bbd08231336097200cc21765eaf505d4a890b91cd801bea15f68ea44881d1e80eb1f37af59ff1d8b16364470c2e7d58639f12000f537223089bbe43dbc418475d3a925dca0463906328b23e640ba8e652640b2876293607a1b8941c9a2e799f81818101000a06a3357133957f0000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000002cb49444154789ced97cd6b134118879f6d420ba5474f62ff0441410f2e054fb9d4a3207ab5a8d05341a95aa546a8c58f2a9e02d2f6e6492f82a41e7a119115f16040a490a326d9cb26fd486c63348c87cd6c6626b3695a68eba12f2c939979dff7f7cce76e1ccff33848eb3b50f54380ff0120a9565cd7153627cff39cdd0a6c97b34f75948d66e9baae884bd44d58c6d8f2ca3ec7f3bc48bc1baddad76d4654d16ed0b23f6906026432f0b7de7e7a496afac87a26038d5af84058de7dd6f6d7f6c0f3c7303109953c08113e08b877159abfedeb192b7c19ca43303eaefbdf3c0fd747e1e95258d700fccf61b99a87be7e48f4436220146f36f4c038e15c3605c08973cbb689eab05d1d4375c3aac2b96c8a522120bff22336b6d90807914ea72d00ad5a62009c44b804cd063c7c054fdee881ea7248e15221c02f06e4577e4629a5bfb4b9b7615bd4de7a1989743add5a71c4ed4b885b1788ea663f2072d994c8655302104b2f4e8ac5e961b1383d2c66c606c5ccd8a000c4dc7d3dd6cc0188e818c64d99464b7b8d4b850080d16b5f599c1ec62f96231fc771b8b3f08b0737e0eca911462e7ed472e6b229de7f5f6662d2d88452cc7c6cc27e3188e24c71c709af8946152ae58d28565aa910b0d50a8900c223988e4064298fa629ac8a4a6159aeaf8587fe4f0d2ac106c96442f3f58b01f58a01b055a68314e0dd87e5aec2e6a8a7e66b5adf6aa54ab3d93400cad4d70c807a251ce5d1634722c752a14d1a3762f95b0aabb7a5dc5836681c0b805f0ca85537239feac66604600aab0053f3b58e0bc9148a834faa8e7eb16ca7b5089b2336df7caeeb0ac7d19747cb65ce40ac393ac076c2aacdbe040898bd32a4b5abfb449b0193d416d48bb0ea17f70695edda45649202acafd578f47a67df04aad940d5b69e3e484cf25e846d10b63c8efc6362be5e6de54e857bb108208ed424de5380bdb433a78f8b4f5fbe750c62dffe17d8c4f71520ce0e01fe01ed94001160906df80000000049454e44ae426082 789cbdd45b4fdb301407f0f77e8a08bfa1e99034899d68da03f7fba5dc61da83e3246d81722db430edbbcfe76f070d08d39e963f48f9d5a7c6764e989b0d4ef7b683d9b9cec3588f872630037d1fcc968fa3d1f3f71fdf7e7666ba61607f940cba335f3a3334084c20425cf0269c71e01538e7c04f70c181e7d951cc81fb70c681c7b0e6c0d7ecaee4c0f7b0e2c0353bd61cf8929de0822b38e3c025ac396c71011749e1f76360c3c138be9f2669e2c70b1817bc066769e6c74fe03ccd9dc510d6a9f6e38b7091367faf0b9bd4784bb84a2bef295b86b239ef235849e5ad1b4b9c87c0fe64269bf5dcc2b9f4eba13d58cb663d5b70219bf59cc246faf508377f294b3f7e0857b259df315ccbda7bc256a16ad67b00472af2de8563157b4770a29af3dd8753957adfc0f6f2eec1996af627e09c03efc04619df8f195ca9caf59f183456158cfe437bb87e4960fb402337df066c0fd4f7e3f2abdd7ce8bface0605cc12633be5f5fe0322b5dbf0af4571e71301ec3499ec4eeefafc3b68162f7fd25d83ec0d8ede70ecef22c467fd2336c72e3fa5de03cf29283f190ad430e8c7ed74aab14fb134563edd647302ed4a770cd81cfd9789ddd7ce86ffbfa24caed27877120f0196c38f036db841c78158e38f0021c73e047981fa87bdf1f603e6037ff08ae38f0155c73d83dfc3f29933274f5bd3109d25490a1b22515d5d4a7416fec7a8b867441977445a3d65cd30dddd2c0bd87b6f28eeee981c62d79a4279ad0d4d716f44c2f344f0b9f6460b3e86b0d2dd132add02a3e7d1ff7e99aaf2d699d3668d37eda9e016db5d47e366f5bedff9a771bf958bbd33a2b6797f63ed4f6de659f0ee8d03e87897d6a7fafbdb1955b7464e73cb6bf27ffb886099dbe3eb7f6da333aa7107791adeefada8a624a5a6a535fdbb3bb93beb62645995ddfdbda5c9010b8e395376be85b4d847e5b2b0a2184c1fdb12845e56b07f64ca6fccd37b5b5e80b773f154371e16aed3bf4d909fc11fb0efdfadaf90db563e86f 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000036249444154789cad955f485b6718c67fc71c63625193e11facc6d6ceaca9b55d7ae18522bd50acb13427548d10e386462c0c7b212d2c92ad7485c2d04ba1174abb9be1dd50a8f462ea5a5c87b8ddc82a6a2f8a7fd0760612ab47433c9e846f17838d4e5775f4b97ebf1fcffb3eeff77dd2d4d4141f5a29c73d70f76ea10804be17efab918f0af3f97c229148c36e7fc2a9534edc6eb7906599919111e97f396d686810555555f4f77f8bc1f09a8a8acfe8ebeb2391481c587f28545114e1f178181c1c241c0e939efe07e1b0896bd7bc381c0e9a9a9af68de250a8244974767602303c3c8cc3616263432299cc201008b0b3b3733ca76eb75b9c3bf73977ee4c73fbf697cccfcf73f1621eba2e989d7d85d56ac566b3d1dcdcfc8edbf706959a6aa2ac2c84ae47989e7e84a669dcbbf70579795f110afd4c3cfe94643289d1683c9a534551c4f5eb01b6b63ec2ebb563b797e072b9387ffe6336379f70f3e6d74c4c4cd0d3d343341a3d1a5492242e5fbe81ae434e4e84999919aaababb15ab3387122055dcf233f3f9ff2f2720c06c3e150455144454525cbcbf99c3d0b2b2bbfa2aa2a4ea7134982e2e24f585e8664126c361bd9d9d98743f7f6f690652b53535bc8f2ef3c7b3641515111369b0d803367f2585b83adad04f1781c8bc582dfefff3b2ce9df77dfe3f188e2e262eedfff81070f72585fbfc1dada530c0603252525689a86c552425a5a3f66f337cccefec4f6f636aaaa323a3a2a1de854d334fc7e3f60c3e13071eb5623b1580c9fcf87dfef27232383a2222b261354567ae9eeeea6a5a5054dd3febbfddcdc5cae5ef5323e0e57ae08c6c646292b2b23140ae1f57a515595c64637a5a599a4a656d0dede4e6b6b2b66b3f960687d7dbde8e8e86075351f21e0f4e930939393288a4266662691488468344a4e4e36972ec1cb97a069505050406161213e9f4fbc03adabab1356ab95b1b15f78f8f00d172eacf2fcf98fa8aa4a4d4d0d009b9b9b689a86d168a4b414c261585901b3d94c5b5b1b1b1b1bff04e5f178444a4a0ac160909327ed3c7ebcca8b178fd8d98922cb32b5b5b5389d4ee6e6e6181f1fa7abab8bc5c57516173b494fff8db76fbf63696989dddd5d2c16cb5fd06030287a7b7bf7bd8b03030362616181582c0640229120994ca2eb3a0059599fa2eb7176775f3134342401b85c2eb16fa53e848efd9d1c457f02e3f74bd7fe3f92e00000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000032f49444154789ccd954b48aa6b14869f5fff3684110a6184a905890e0a0cb1081a841199a24245176c104917880641749b37e832286892831a3588a068e2406ad04428a22b5d402a68521405997929ed3f8320d8b4f7ae7d3883b3868bf53debfdd6fbf12d21140af15f87ec6f0f381c0ec9e9744a7faa11bf0b6b6d6d9592c924e9741abd5e8fcbe592445164757555f8574aebebeba5caca4a666767c9cacaa2a4a48489890952a9d42febbf84badd6ec9e3f1e0f7fbb9bdbd45ad5673717181c3e1c06432d1d8d8f869145f420541a0b3b313809595152c160bd7d7d7c4e3713a3a3a8846a37fa7d4e572494545450c0e0e323030c0c9c909656565bcbebeb2bfbf8f4aa542abd5d2d4d4f493da3f1a258a226363631c1d1db1b0b0403299647a7a9a4422417f7f3f0a8582743acd8f1f3fbea7d4ed764bcdcdcd545555d1d7d787c160c06eb7333f3f4f6e6e2e3d3d3dacafaf333c3cccfdfdfdf7a08220d0d5d5852008dcdcdcb0b7b787cd66c36ab5623018787c7c242f2f0fabd58a5c2eff1aea76bba58a8a0a0a0b0b01d8d9d921128960369b114511bd5ecff1f131a9540aad564b4e4eced7d0979717323232686b6b636969898d8d0d743a1d5aad1680d2d252c2e130f7f7f7c4e371944a255eaff7c3ac4f46793c1ec96432313636462010606a6a8aebeb6be472392d2d2de8f57aeeeeee8846a3f4f6f6120e87797a7a221289f05b683299c4ebf562341a311a8de8f57a7c3e1fdddddd188d4600a2d128e170188bc582d3e9e4fcfc9c999999df43d56a350d0d0d004892442010a0b8b898d1d151b2b3b33ff25b5b5b442211464646383b3bc3eff7ff7aa675757592cfe743a3d100707373c3e6e6266eb7fb0308ef2fc366b3b1bdbd4d2c1643a3d1909f9f4f6b6babf413b4b6b65652a954048341262727d9dddd25180c128944a8aeaefe64667979395757579c9d9d919999497b7b3b0f0f0fef4d43a1101e8f4792c9640c0d0d515050c0f2f232070707c462314451a4a6a606b3d94c4646c6c7f50f0f0f595b5b43a7d3a15028b8bcbc249148a0542adfa1434343d2f8f8f8a77f716e6e4e3a3d3de5f9f9f923f7f6f6462c167b37441449a552c864321617170500bbdd2e09ff8b75f29df8072ad2411c44a7ba050000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000001f149444154789ccd95bf6b5a5114c73fef298d20c14715b120e2f806e990ada34aab0ebe27a2832e85f817b410dedfe01808b45b978810a18180a393e1b5a1b482143a6490fe701031a9b4b12ae8ed906290e7cfd2a107ce70bff7dccffd9e33dc2b99a6c9bf0e79db03d96c56a45229b1aac6be292c97cb89c964422814c2e170904c2685dd6ee7f4f454fa2b683a9d16d16894e3e76f80cb3faa0bcf93fec2fab5ed6b9a26745de778ff037cdf994b5555c964329651ac756ab3d978f9f802ae772c7be7cf6e70edffb4e82ba19aa6897c3e0fd76f97d6288a62d156b66fb3d938f4376e5d2ec9482482aeeb732358eaf4cee5fb55f7f2eac125ca783ca72d854a92c4e1f01c862b99b38ed642354d13e17018ae3eae27021e8f676ebd70a6e3f19893de3bb8fab5512a8a42a15098cdd5e254d775a1aa2af43e6fe41260efd11ed56a75b6b64047a31117df3e6d0c0478715642b9b96bda02f57abdf0a5b51514e09eebfe62682291105ffb7d7e6c8d04bfdf4f2e9713e572599a4163b19870bbddf4fa8b1f8975f1bad1e0e1ee2e0092699ae8ba2e6459c6300c82c120954a8566b3492010c0e7f3e1743a797a743407393938a0d3e900d0ed7669b55a0c87431445b9851a86218ac5a2e55dacd7eba256abd16eb767da743a653018ccd5c9b24ca9549200e2f1b890fe8bef6493f80da5c2b9a2130355fd0000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000002af49444154789ccd953d4c535118869f7b7b2929a505c34fd55aa988112126c41023098383290dd8de188146347132ea6270eaee62181c5c4c18d88418217670c1451773a3c60583160d52498c3f840a2df4f68a2dc7413dd814f9310e9ee44ddeefdcef3cf77cdfb93f8a6118fceba16e77416767a7e8eaea121be5685b855d8844c4c2b76fe4f3791af7ec410f8584aa69c46231e5afa017755d4c8ebb80121a3a05cf6e7f052af00452ebe66f5a7e5f28245edca986c552582ca5c2e391fef3dd5a7ababb8b5ab12934abaab0502ad5d2da4ad3f925192f2f2f6f6fa7a1504834eddbc7c99b2e58b0e3bd32c750db24e97c9ef1c7c7197f72029fcf476f6f6fc16e37eca9db66e361772900fdd7e7d12c8be61b694ccbe2522c46b5c3415e08ec767bc1ba3f42c3e1b0b81c08c0c22c00b51e0fb3915d0034c5e0d5a92a99bbe3d6e4d6ca7702d7caa72099856496b14f9fa46fdcbf5f7a9259ec36dbe6d070382c5adadae04b562abdb424fd3dc70c91d91a19f794956d0e5d5959a14c51389d3b085fb2f47b0354d5d515dce4e5bb77d2dbdc6ece9d3d2b0faba8a7baae8b63f5f58ccc3e05e068898f0f6363b8148533b6dd845329a69c4ed29939faca8f104f2448659749a7d3fc11aa59160fe6decaf819aff16654e2ce5578fff30d5a82fbce9d8c3c7f24f35c5fd79eaaa2f26babab61de94ba10eca1f9d0a18239e64d0eb7b616c4e50ec71ac4300c29afdb2dd250a0030d0d4573bf146a6f97fe6a7dbdf0d7d509c330d6caefe8e810355555247feb0d402e9522b9de69026f3e7e94d7aecccc30e47201a0188681aeeb425555a2d1287ebf9fd1d151262626304d13bba6313c3dbd2eb4d7efc7b7772f4ea7934422816559545656fe8046a35131303050f45d1c1c1c14f1789c4c2623e7565757314d13004dd3c8e572a8aacaf0f0b002100c0685f25ffc4eb632be03f01c3f1b679402620000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000025449444154789cad95bf4b725118809ffb71cda09f46dca1a5fe0169edd2108498e2d022414d91fd030d39b555343605d190181886e020b8b40971c5868c96a2200871b0a0522aaf50be0d1f5e3efbae7dfad1b31ddef33ee73de73d87a31886c14ff3abd3048fc7237ebf5f7e4cbabcbc2c9aa6e176bb191d1d6d296e5b3a313121b95c8e603048575717434343e8ba6e2b6e4baaebba288a42bd5ea756ab717777c7d3d3139148846030f897f89fd29b9b1ba9d56a00c4e3719e9f9f595f5fa7bbbb9bc1c1414cd3ecbcd2442241b95ca6582c128d46098542cccfcf53a954787878a0afaf8f4020d054edb7d2442221b1580c4dd3000887c3e8ba0ec0f1f1313b3b3bf4f7f7333232d294a77c774fabd5aa4c4f4fdbc63e3e3e787b7bc3e17090cfe795b6a4ad3adb8a6c366b895b6e3f9d4ed368d0fbfb3b22cd6b346276d84a2f2e2e646f6f8f72b90cc0fefe3ed168d48a9f9c9cb0b2b2c2ebeb6bfbd2a5a5250e0f0fd1348dfbfb7b76777771381c0098a6c9d1d111e3e3e3389dcef6a46b6b6b522a95e8e9e90160606080adad2d666666005055158fc783d7eb45555500cecfcf595d5db5ce47fd2a9d9b9bb384004ea7d31236a4b3b3b34d39bdbdbd140a05fb4a53a9942c2e2ee272b96cb7d58ab1b131dc6eb7bdf4f4f4d46a4e27a8aacac6c606979797bf8fc0300c0cc3c0344d7979799106f57a5d229188e4f3791111797c7c94838303b9bebeb6e65c5d5d492a95923f310c03756a6a4a32998c727676a67cad20994ccaeded2dd56a5501d8dede96c9c949161616acb99b9b9b323c3c6c8d7d3e9f7cfb4cff978ebf9376f80482fc1c4c4b56a72d0000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000018b49444154789ca595c16ac2401086bf4421822028b2143df80a3dbaf8183ea78fa1b9f424f4d46bcd412c2156c1404c7a48679b351b6ddaff363bb3ffcc3f339b789bcd86b6582e7401b05a879ecbdf6d43a67549f6087e1b524194c3cb7bf47fd2f97c5e9c4e27263e4c7c188d468d95ff8a546b5d789e479ee7e62c8e63e36b4daab52ed2340560301810e5a5fc5eafd778e72ee972a18b890f4992b0dbed2cdff178b412b7aa1440290560fa09309bcd2cbb8abb2b15fdb490e9746af9aed72bd001200ced7d6dacd43500e92740a7d331f6afe44b900c28cbb29a54f1b9e0241539499200d0edd6bb140401e7f3d9495a8b9677fdf6794629c57ebf472965645f2e17b34e411000a24017f22d68ec69bfdf07e0f94931f1e1703898aaa5152e054ed22887d78fb816381e8f0da9eb4e75536a11699a321c0ead0b2e922ab22cb39259956aad0b194e1b484b641e5da80f4756a75a511cc79682bb49aac676bbfd7e19f632974986264918869e1412e5a5bd5adf90defe16c40e433929096e9f63d399f7977fd4237c01356dabc16040cf010000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000000a949444154789cedd4210ec2301886e1b764084e0306f38969041804090acb1948b8010967d805309304fb131cc7014c512c7475ed1024fb64c59357fca93333badea073b1477f8216ed07493e07343317a10093c52609bcd715d02a95e4a7ab35f04a423f8b4a8bd13309ba5627cccc05a8245f6ee7e4560628c030b1f2723c37950d2ac9cf76259086b6d794a656d6fb5b50095048f2cbc31878e4e57dcd01d9c71ea1fd7ffa1fe81b2e1b2dcf4b906cbb0000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000000b549444154789ced94210e843010456736bd018223ec1d8ac490705e120c92b90ba266cdcaa2a6197e0b0858b109dff1075eff6f1b5844e86ebd6e273ed09f401d1adefb780528229c4175609fabb68b611a4f3d0de4d05460d57629317e7ca62ca9c210d4f47524229a8785756edfb5811254cd008b20ace9eb68c1d8aa9814810a38d2fbfbd99c83b329f7aa63624c86da24b575c234f23c2c8cf5f1d4ed5e2668c9b4b2f54bd7a82426a2cb973d833effd3ff80aec3fb78ab235e84730000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000006049444154789ced94410a00310803a3ecabfc3ff9d6eea950aca79a1e169a63846110d148421d97132ff408f4c94544bc1d20495ba063b0031c429ecb5de01cd94e6721afca6e24a659c8abb29bb66925e46a4b003000ed635fa0f79ffe03fa017ed12c22088282610000000049454e44ae426082 89504e470d0a1a0a0000000d49484452000000100000000d0806000000a0bbee24000000b449444154789c9d92b109c3301444ef9b0ba4c94a1ec08517c8162e3580cb6ce1055c6400155e47858a182cf8298284432c47e8e07302f18ee34bb22c0bfea91f1f1acfb319647fd794c0b319244e0c8b2e250d728d66330801a06ddb54d15a2b39700f470949edb68069f5b85f6f785e98858fc21b00099e568f6e0b70defd784e0d80049f795624d5bfbcf68ae4248be770076ac2d91e3fcb1b096bad084975de55c1c0ee156ae01400a00afe0a28d1d13f780395128c0ebcec51330000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000003d349444154789cad955d4c935718c77fefcb8b1d8375654851b4ad4416d88749759822ebdc3242305cf015207cc4cd091931123232b30e2f5d3243e2c7c55822178b81086431d130038b78e1dce21b8dcb00c900d18c0db715c720016d2994becf2eb05860cc64f19f9c9be79cffff3ce7fc9273145dd7791672166549ff455d01d0c285f06478623de5e5e589a2287477772faf8bf40328e14e9f165c515121f3f3f3f87c3e1c0e075eaf974d9aca2d2659ed53230be1e2ea9d8b8b8bc5ed76d3dcdc4c5c5c1c3b76ece0f467c7f8c878c8bcacf42e1f3f5291c18b4083f10285c5959c3c758ad6d656ac562b13f7ee92bfd1c4a449e168289efdab32d4d5a191e1374351442950535303c0850b17c8743aa9fce30eea8d6bdc79ef30edbed01aefbaa100e5626170fbeb7ce2f170e4c811868686c8c8c8e077037e2a39c8424616369b8d4365256b41ad07a9a8a8483a3b3b191c1ce4ecd9b3dcbf7f9fc4c4441e3c7880d96c263636965028446660862f03134f3ad4751d5dd7f12721e1a1eb3a5b3626487d7dbd1886218661486969a954555589aeeb929e9e2ec78f7f2e133775b95e53295713357914e1d5feadc3cd856fca2975036fb876a12c06f1fe3d455f5f1f8d8d8deccec8207fd34becedf91acb77177939c14a833c87e962effaf4014a0c0b1fa624937cee0c0b3f5c66f4d5ddcccecee2743ad114855da62886a682ec3ed38669f3566e65ee793aa8bb0b217aede9d4a91606141377bebf8add6ec766b381a6e12b3bc0c94706d30949cc2d04b199e3682d2f5ce6a2f8935801a9a0a040525252686b6ba3a7a7878e8e0ebc5e2f515151a4a6a6e27038989c9ca4bfbf1f97cbc56fa3a324cd4e73626e826455881663e5f1b71766496dc8c42bd97b49b3db486b68c0e170505d5d4d6d6d2d6969692082e997515efbf9470a1ffe49d28b0662183c3f67a0893ca11fa6766c638c746e35cbecbb4e0994e5c842739334969788dbed969999191111916050825f7d2157766e974b79efc8e2e56fe4dee56ef9d81a27df5a3788aeeb4b771a267f32b8815f0f7f4a5c470fdafb87f0dd1de1af1bd7c9cfcfc76c363f46aba11dac63bcee28a7032af3ee6cac7bdee2da96540ec56c5e092a373757e2e3e3e9edbdc289b6730c6c72d0b5f36d2ef943646767af81e972b9181f1f67646484989818f61ff880a9e9e92550baae53505020aaaae2f178d8b66d1be7cf9f67606000bfdf8fa669e4e4e4e0743a898e8e064044b87dfb365d5d5dd8ed76626363191b1b23100860b15896423d1e8f343535ad79435b5a5a647878189fcfb75c330c03bfdffff82634161717515595f6f6760560dfbe7da23cabef2452fff94afd5ffd032309c5843513f3e00000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000001d649444154789cad94bd6e13411485bf593b71a0c146c2a1020ccf00c52e72401148aca248502081441f3a9078803c000554d0d3514488c2a141518c3c083a1e00cc4f43369158689238b22f0d331acf4c420239cd68eedd337beeb9335769ad396c247b25db7921075967e7d70540c594b6f3426edf9a63e1ce7b75509557ae6f48f4d07f413b2fa4db692af0ca3765003c7d76417ce25e3007b6f3e2ff95ba0a0daa00833495fec4595a3b9ff85c39c599e157bb7eacb43837ec07f17ee534ade117ba5a2bff274a6bcd5a96cb74af6393db692635dd0b9ae4c77d9e4102d090722ca8109e3f3a1278aa180ff93ca3340128d5b12079f3dee65faf538cd7ed345515a02e3ff9955d9629d9b6c9eff377e5f8c6878034485301d85235eacef7aed2aaf963b3b7ac5ce2c9974f02a5833495c93f8d99048aec9a34234a13a3d447cc531f319ef5f487aa07c9fd781ae359a5b12ebe5afc26ae62b377d78694366f5ea0bda765362b0923a622c6ef862d55634442bdf73aa8a80a705436310d587a3892b9a58b76efc26f94b90946e1d84071bdb9f120d9f7b87379eefbb79e1aaf008654a287b8f1179716a521250b57df842f4f6bcdcacc7dc976ded9e1b1969c607ab46ef7bbc5df4e9c6766f57150d9a10d6917bf0149be09d8da731f230000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000022049444154789cbd544d6b1351143d379f6d864ea682465d48d322fe8350c6121424b571ef42a9086ebaf00f7415b7baa94217821604578a6e131a2c81e03c24bf40d1dae2424d049b843469c666ae8b38d397f9282d8a67f378e7bd7bdeb9e732434208fc6b44820e4c5de78fe1699c1f7cc666388d99c1165aa422c96d67bf1d3e87a9c11767dd8ca431b3bf05f2737a7bbec60f07f7a1bd794d32dfd72f725c188772f5b96b1cf273f96c3d4389ee370f4fe0402e9b6f30004c5a3b1811b50f00a0379ef27b2f10d5e22902802625fddb07803d7d8e4d8ac2faf36e0816e26ca24f315808814150b88b7d446086c610e65f600063dc3f709abffe9365b71d52a01a15baa13e85666c5041590681515096a1191b74537d829810c444d0de9669c2a8906a54a849c9a16836dfe0e2cb1324b731c11d0040b19426005829e788415829e7c8e6efccbf63f068ce1ab786a2b6908c9e72c613897b506bebb3e42edc21edc0a95b20b1fbd5376b19f7aebc62f74393dc0c1ed4eea5ab1c35db81825d1a47827b6090d3c11ec5612134fca2b2f906bb23889a6dc48418e14c5d679b8b01b89babf0834e010951753853d73930d3ae72f6f0de01ac962f7beafe7fa6ef6f3de2e94f2f503fad23f55de0472a8393f59ab3da7c4bbb8064f383b3af46f5a1a85fa647c1c2c236974a539e3a4fa68f9f67bc7f8d00c88272849e4c97166b47762cd7c9c61ca7c771280bf90dd971bab458732e1c67f59b45e0f4ff06bf01765c1564eeb8ff4b0000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000018b49444154789cad94bd4e02511085cf6c02283f020df8136da8b4a222e49290d068dc589b6882356fe05368a9f696da8a89da68e426121b5f4134c62d600984c8168c05b98bb8a0bb614f738bbd33fbcd99b943524af82dedaf8f45dd602fe76de9902d21982691167583f7f7765029d7c92d9d25040340478b616252afb284e00e45d198cf60a3f7325ebe2a0300cece73ec0c9f4e18e32eb277a764527c36524b087ed3966184d790edd6d1a330a2dc1d91eabb4d4f4d39d87a6600785d5847fee698340c30c75fe85074485ad40d7ea8a65c3745e9b3a073ba56256541435bc1eae07d483a29a11b4f936cc2286cdbf7328f1764527c98f4678394dc8c539f4288700f412909009a854d4e707b36d210f71191f776acf27426d21625008cc6ea434b23a6baefa7a72d4af8eba9fad1bfa4d3cecb238d43dcc753e90400d00b2fc112826b81bc3f730a8c7c0d4a490e52b76f5e95aa129a14b76d7078ea65dd9914b70953b56b3bce26f542a894e0369a5a72ac5163a495729dbc6e7a19c861f1f1ca51992f4bfab7be019433035af1a435310000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000001b749444154789cad944f4b1b4118879f775bb361ab348945db2248f150f00388cc4a3c94169b43a128bdf7de0fd4bb070f1e7a2901e9a12071ce822741d4937f626b23d8e82ed5d74399ed26ae66433a971766769ff799df0c23d65afef7f0b22663633436463f2c6c2940b5d6cc555fbd3b5100c9323d0e6b1a143c46be7f957e2d5fbfffa1b74c6363b4ac2dfce8b42f98b3fdf6e589744077e79614a060adb483677d41d7eb63e2e00934364627ae0f28582bcdf0ad16db477d19a6e19e03ee0dbd00a031ff494b7ac685041d3fdd559d61ba89586bd9ac7e544faf7979b58322146d432213aa6f37ee3da86aada9dd50808700d37fb639976104c5812e82a7f83db69e054c328dc4a7a897c9426c8c06edc31ec8db79ba461e80af1187de780204888aa33da1f79afe9212538dd5e48382b5e25ffe1cccb4ac2d4ec337c91d05683f7a3e986977a600c1ef83c14cd399c2df5cf7a71601f8bc3ca377d5f5fa9874cf27f7f438ace9f8465ddc21c1bf187a9966459064eac6f9c8642ea0db6aba4107b4258f39091714a0b2b692fbb94b83d20d3c80929ef160b89cdb300dca3a2c0fa031344b656d45f2bef0e99a9569e6cb3fe8b801fd070405ed1b07300000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000018549444154789ced95414b024114c7ff6f152b08db223d98873282fc021dc6f21015e8a50f10de3dd457a83e46f7e8d6d98282c0720e42e782b02e5b9041b9218186be2eedb0ee4eb946dd7a97997d33fffffce6bd852129257e3bc2ba645b080680ebd01ce63b37782113e3dc402d3483d9ce9defdb191bc618ccaeed376d0bc18f460cb5c51d88f226188421b4109192d2005e33cb6cb28d371a41fafc800020fda933bb3676cd6d90fbfa0e2100300804f69ef965d81445ac724c3dd76f0bc1969140eae29000e0617d8b279f2e119192bc87ea728e61365f679252fa363f67d6388c77442b674aaccb79419c50a4f7e124a684e0dbd03452dc846524302c043b4d68191318ed3671b5b4c1aa3980cf5091aee42c3e3d4af62c0689d59cc5271a9d01003ac3bdfd85be5dd21966f375369c8977b158a8f625d7e9caa53819cee427a43add3f697fd2efc672294edebcfa4fb3f93aeb8c8390ea743ed220b574c2ad7397c257d320b5d419b90f50a48310ba8d74cd52a4c542556d1864d4d594fee28dfa001f1808dc614860130000000049454e44ae426082 89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000001b349444154789ced94bf6b144114c73fb3b7779eec9122c64b90588414162a5888e244b7500cdc220111442336da68e79f23889585b6a6486171e081235af9a34825118c928c21a0b9c0b9c7f92c64c6cbdd1073674a1f2cb36fdebcef7ededbc728630c7b6dd14ec134b332c87a61eeab00a810699a5999bf7e893b375fab41292f5e5e97a0e8309666561a8b55053de5bb3200ee3f3a25bd893b99134c33fbefa4dd84ce3c69767563a09fe2d65e414f1afadab0949e3414d84d4f4379696625722fbdc1dd8c5328afb15855ff498727bd3bdb089206873fd75abe4c9ee7d04a1d3b7e9aeada2bb62a87499a9f589bd08caf1ab62a9324cd15ecc419aaab2ffdb9b7f131fae634d75a004ac6047db7d7a1c0e3f2156ed5eff59ddb469a6b2dadf218e5d6fadf2aa74d91226def6faa0a075e3cfb73a1d46a1fe5f3d9390118a92fa86eaa9231aafb71fb8979aeae8d3cf4a24ed08b3efd36cffe2461293e02809da9499ba2f79d6dcccc4a4bedf3ad78f2fd36363ab8ad350031c09bf8382736df532a4cfdee57344a51da942427d75a3e14a698ee2cf3231aa5f2b3c9d2b91b32dd59e65d7c94938d077d53b2679774b7fd0274cf01d1d4dbcbe90000000049454e44ae426082 Exit activated() Mesh2MainWindowBase close() lightingswitch toggled(bool) lighting setEnabled(bool) qwtplot3d-0.2.7+svn191/examples/mesh2/src/colormapreader.h0000644000203200020320000000076510663257611022652 0ustar gudjongudjon#ifndef __colormapreader_2003_06_08_13_23__ #define __colormapreader_2003_06_08_13_23__ #include #include #include #include "../../../include/qwt3d_types.h" #if QT_VERSION < 0x040000 class ColorMapPreview : public QFrame, public QFilePreview { public: ColorMapPreview( QWidget *parent=0 ); void previewUrl( const QUrl &u ); private: Qwt3D::ColorVector cv; QLabel* label_; QPixmap pix_; bool open(QString); }; #else // if present in Qt4 #endif #endif qwtplot3d-0.2.7+svn191/examples/mesh2/src/lightingdlgbase4.ui0000644000203200020320000002246210663257611023252 0ustar gudjongudjon Dialog 0 0 428 330 Dialog 8 6 0 6 QFrame::StyledPanel QFrame::Sunken 0 6 Std Qt::Horizontal 91 31 &Ok 0 6 0 6 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Ambient &amp; Diffuse Part</p></body></html> 100 80 Qt::Horizontal 0 6 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Specular Part</p></body></html> 100 30 30 Qt::Horizontal 0 6 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Shininess</p></body></html> 1000 500 Qt::Horizontal 0 6 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Emission</p></body></html> 100 0 Qt::Horizontal 0 6 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Distance</p></body></html> 1000 100 Qt::Horizontal 10 280 351 33 stdlight clicked() Dialog accept() 278 253 96 254 buttonOk clicked() Dialog reject() 369 253 179 282 qwtplot3d-0.2.7+svn191/examples/mesh2/src/lightingdlgbaseimpl.cpp0000644000203200020320000000112110663257611024202 0ustar gudjongudjon#include "lightingdlgbaseimpl.h" /* * Constructs a lightingdlgbase which is a child of 'parent', with the * name 'name' and widget flags set to 'f' * * The dialog will by default be modeless, unless you set 'modal' to * TRUE to construct a modal dialog. */ lightingdlgbase::lightingdlgbase( QWidget* parent, const char* name, bool modal, WFlags fl ) : lightingdlgbaseBase( parent, name, modal, fl ) { } /* * Destroys the object and frees any allocated resources */ lightingdlgbase::~lightingdlgbase() { // no need to delete child widgets, Qt does it all for us } qwtplot3d-0.2.7+svn191/examples/mesh2/src/mesh2mainwindow.cpp0000644000203200020320000006140410663257611023316 0ustar gudjongudjon#include #include #include #include #include #include #include #include #include #if QT_VERSION < 0x040000 #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mesh2mainwindow.h" #include "functions.h" #include "colormapreader.h" #include "lightingdlg.h" #include "femreader.h" #include "../../../include/qwt3d_io.h" #include "../../../include/qwt3d_io_gl2ps.h" #include "../../../include/qwt3d_io_reader.h" using namespace Qwt3D; using namespace std; bool Mesh2MainWindow::connectA (const QObject* sender, const char * slot) { #if QT_VERSION < 0x040000 return connect( sender, SIGNAL( activated() ), this, slot ); #else return connect( sender, SIGNAL( triggered() ), this, slot ); #endif } bool Mesh2MainWindow::connectAG (const QObject* sender, const char * slot) { #if QT_VERSION < 0x040000 return connect( sender, SIGNAL( selected( QAction* ) ), this, slot ) ; #else return connect( sender, SIGNAL( triggered( QAction* ) ), this, slot ) ; #endif } Mesh2MainWindow::~Mesh2MainWindow() { delete dataWidget; } Mesh2MainWindow::Mesh2MainWindow( QWidget* parent ) : DummyBase( parent ) { #if QT_VERSION < 0x040000 setCaption("Mesh2"); QGridLayout *grid = new QGridLayout( frame, 0, 0 ); #else setupWorkaround(this); setupUi(this); QGridLayout *grid = new QGridLayout( frame ); #endif col_ = 0; legend_ = false; redrawWait = 50; activeCoordSystem = None; dataWidget = new SurfacePlot(frame); grid->addWidget( dataWidget, 0, 0 ); connectAG( coord, SLOT( pickCoordSystem( QAction* ) ) ); connectAG( plotstyle, SLOT( pickPlotStyle( QAction* ) ) ); connectA( axescolor, SLOT( pickAxesColor() ) ); connectA( backgroundcolor, SLOT( pickBgColor() ) ); connectAG( floorstyle, SLOT( pickFloorStyle( QAction* ) ) ); connectA( meshcolor, SLOT( pickMeshColor() ) ); connectA( numbercolor, SLOT( pickNumberColor() ) ); connectA( labelcolor, SLOT( pickLabelColor() ) ); connectA( titlecolor, SLOT( pickTitleColor() ) ); connectA( datacolor, SLOT( pickDataColor() ) ); connect( lighting, SIGNAL( clicked() ), this, SLOT( pickLighting() ) ); connectA( resetcolor, SLOT( resetColors() ) ); connectA( numberfont, SLOT( pickNumberFont() ) ); connectA( labelfont, SLOT( pickLabelFont() ) ); connectA( titlefont, SLOT( pickTitleFont() ) ); connectA( resetfont, SLOT( resetFonts() ) ); connect( animation, SIGNAL( toggled(bool) ) , this, SLOT( toggleAnimation(bool) ) ); connectA( dump, SLOT( dumpImage() ) ); connectA( openFile, SLOT( open() ) ); //connect(openFile, SIGNAL(triggered()), this, SLOT(open())); connectA( openMeshFile, SLOT( openMesh() ) ); // only EXCLUSIVE groups emit selected :-/ connect( left, SIGNAL( toggled( bool ) ), this, SLOT( setLeftGrid( bool ) ) ); connect( right, SIGNAL( toggled( bool ) ), this, SLOT( setRightGrid( bool ) ) ); connect( ceil, SIGNAL( toggled( bool ) ), this, SLOT( setCeilGrid( bool ) ) ); connect( floor, SIGNAL( toggled( bool ) ), this, SLOT( setFloorGrid( bool ) ) ); connect( back, SIGNAL( toggled( bool ) ), this, SLOT( setBackGrid( bool ) ) ); connect( front, SIGNAL( toggled( bool ) ), this, SLOT( setFrontGrid( bool ) ) ); timer = new QTimer( this ); connect( timer, SIGNAL(timeout()), this, SLOT(rotate()) ); resSlider->setRange(1,70); connect( resSlider, SIGNAL(valueChanged(int)), dataWidget, SLOT(setResolution(int)) ); connect( dataWidget, SIGNAL(resolutionChanged(int)), resSlider, SLOT(setValue(int)) ); resSlider->setValue(1); connect( offsSlider, SIGNAL(valueChanged(int)), this, SLOT(setPolygonOffset(int)) ); connect(normButton, SIGNAL(clicked()), this, SLOT(setStandardView())); QString qwtstr(" qwtplot3d "); qwtstr += QString::number(QWT3D_MAJOR_VERSION) + "."; qwtstr += QString::number(QWT3D_MINOR_VERSION) + "."; qwtstr += QString::number(QWT3D_PATCH_VERSION) + " "; QLabel* info = new QLabel(qwtstr, statusBar()); statusBar()->addWidget(info, 0); filenameWidget = new QLabel(" ", statusBar()); statusBar()->addWidget(filenameWidget,0); dimWidget = new QLabel("", statusBar()); statusBar()->addWidget(dimWidget,0); rotateLabel = new QLabel("", statusBar()); statusBar()->addWidget(rotateLabel,0); shiftLabel = new QLabel("", statusBar()); statusBar()->addWidget(shiftLabel,0); scaleLabel = new QLabel("", statusBar()); statusBar()->addWidget(scaleLabel,0); zoomLabel = new QLabel("", statusBar()); statusBar()->addWidget(zoomLabel,0); connect(dataWidget, SIGNAL(rotationChanged(double,double,double)),this,SLOT(showRotate(double,double,double))); connect(dataWidget, SIGNAL(vieportShiftChanged(double,double)),this,SLOT(showShift(double,double))); connect(dataWidget, SIGNAL(scaleChanged(double,double,double)),this,SLOT(showScale(double,double,double))); connect(dataWidget, SIGNAL(zoomChanged(double)),this,SLOT(showZoom(double))); connect(functionCB, SIGNAL(activated(const QString&)), this, SLOT(createFunction(const QString&))); connect(psurfaceCB, SIGNAL(activated(const QString&)), this, SLOT(createPSurface(const QString&))); connect(projection, SIGNAL( toggled(bool) ), this, SLOT( toggleProjectionMode(bool))); connect(colorlegend, SIGNAL( toggled(bool) ), this, SLOT( toggleColorLegend(bool))); connect(autoscale, SIGNAL( toggled(bool) ), this, SLOT( toggleAutoScale(bool))); connect(shader, SIGNAL( toggled(bool) ), this, SLOT( toggleShader(bool))); connect(mouseinput, SIGNAL( toggled(bool) ), dataWidget, SLOT( enableMouse(bool))); connect(lightingswitch, SIGNAL( toggled(bool) ), this, SLOT( enableLighting(bool))); connect(normals, SIGNAL( toggled(bool) ), this, SLOT( showNormals(bool))); connect(normalsquality, SIGNAL(valueChanged(int)), this, SLOT(setNormalQuality(int)) ); connect(normalslength, SIGNAL(valueChanged(int)), this, SLOT(setNormalLength(int)) ); setStandardView(); dataWidget->coordinates()->setLineSmooth(true); dataWidget->coordinates()->setGridLinesColor(RGBA(0.35,0.35,0.35,1)); dataWidget->enableMouse(true); dataWidget->setKeySpeed(15,20,20); lightingdlg_ = new LightingDlg( this ); lightingdlg_->assign( dataWidget); #if QT_VERSION < 0x040000 //todo - restore, when Qt4 re-implements preview functionality datacolordlg_ = new QFileDialog( this ); QDir dir("./../../data/colormaps"); if (dir.exists("./../../data/colormaps")) datacolordlg_->setDir("./../../data/colormaps"); datacolordlg_->setFilter("Colormap files (*.map *.MAP)"); colormappv_ = new ColorMapPreview; datacolordlg_->setContentsPreviewEnabled( TRUE ); datacolordlg_->setContentsPreview( colormappv_, colormappv_ ); datacolordlg_->setPreviewMode( QFileDialog::Contents ); connect(datacolordlg_, SIGNAL(fileHighlighted(const QString&)), this, SLOT(adaptDataColors(const QString&))); #else //connect(datacolordlg_, SIGNAL(filesSelected(const QStringList&)), this, SLOT(adaptDataColors4(const QStringList&))); #endif connect(filetypeCB, SIGNAL(activated(const QString&)), this, SLOT(setFileType(const QString&))); filetypeCB->clear(); QStringList list = IO::outputFormatList(); #if QT_VERSION < 0x040000 filetypeCB->insertStringList(list); #else filetypeCB->insertItems(0,list); #endif filetype_ = filetypeCB->currentText(); dataWidget->setTitleFont( "Arial", 14, QFont::Normal ); grids->setEnabled(false); PixmapWriter* pmhandler = (PixmapWriter*)IO::outputHandler("JPEG"); if (!pmhandler) pmhandler = (PixmapWriter*)IO::outputHandler("jpeg"); //Qt4 naming scheme change if (pmhandler) pmhandler->setQuality(70); VectorWriter* handler = (VectorWriter*)IO::outputHandler("PDF"); handler->setTextMode(VectorWriter::TEX); handler = (VectorWriter*)IO::outputHandler("EPS"); handler->setTextMode(VectorWriter::TEX); handler = (VectorWriter*)IO::outputHandler("EPS_GZ"); if (handler) // with zlib support only handler->setTextMode(VectorWriter::TEX); } void Mesh2MainWindow::open() { #if QT_VERSION < 0x040000 QString s = QFileDialog::getOpenFileName( "../../data", "GridData Files (*.mes *.MES)", this ); #else QString s = QFileDialog::getOpenFileName( this, "", "../../data", "GridData Files (*.mes *.MES)"); #endif if ( s.isEmpty() || !dataWidget) return; QFileInfo fi( s ); #if QT_VERSION < 0x040000 QString ext = fi.extension(); // ext = "gz" QToolTip::add(filenameWidget, s); #else filenameWidget->setToolTip(s); QString ext = fi.suffix(); #endif filenameWidget->setText(fi.fileName()); qApp->processEvents(); // enforces repaint; if (IO::load(dataWidget, s, ext)) { double a = dataWidget->facets().first; double b = dataWidget->facets().second; dimWidget->setText(QString("Cells ") + QString::number(a*b) + " (" + QString::number(a) + "x" + QString::number(b) +")" ); dataWidget->setResolution(3); } for (unsigned i=0; i!=dataWidget->coordinates()->axes.size(); ++i) { dataWidget->coordinates()->axes[i].setMajors(4); dataWidget->coordinates()->axes[i].setMinors(5); dataWidget->coordinates()->axes[i].setLabelString(""); } updateColorLegend(4,5); pickCoordSystem(activeCoordSystem); dataWidget->showColorLegend(legend_); } void Mesh2MainWindow::createFunction(QString const& name) { dataWidget->makeCurrent(); dataWidget->legend()->setScale(LINEARSCALE); for (unsigned i=0; i!=dataWidget->coordinates()->axes.size(); ++i) { dataWidget->coordinates()->axes[i].setMajors(7); dataWidget->coordinates()->axes[i].setMinors(5); } if (name == QString("Rosenbrock")) { Rosenbrock rosenbrock(*dataWidget); rosenbrock.setMesh(50,51); rosenbrock.setDomain(-1.73,1.55,-1.5,1.95); rosenbrock.setMinZ(-100); rosenbrock.create(); dataWidget->coordinates()->axes[Z1].setScale(LOG10SCALE); dataWidget->coordinates()->axes[Z2].setScale(LOG10SCALE); dataWidget->coordinates()->axes[Z3].setScale(LOG10SCALE); dataWidget->coordinates()->axes[Z4].setScale(LOG10SCALE); dataWidget->legend()->setScale(LOG10SCALE); } else if (name == QString("Hat")) { Hat hat(*dataWidget); hat.setMesh(51,72); hat.setDomain(-1.5,1.5,-1.5,1.5); hat.create(); } else if (name == QString("Ripple")) { Ripple ripple(*dataWidget); ripple.setMesh(120,120); ripple.create(); } else if (name == QString("Saddle")) { Saddle saddle; saddle.setMesh(71,71); double dom = 2.5; saddle.setDomain(-dom, dom, -dom, dom); saddle.assign(*dataWidget); saddle.create(); } else if (name == QString("Sombrero")) { Mex mex; mex.setMesh(91,91); double dom = 15; mex.setDomain(-dom, dom, -dom, dom); mex.create(*dataWidget); } double a = dataWidget->facets().first; double b = dataWidget->facets().second; dimWidget->setText(QString("Cells ") + QString::number(a*b) + " (" + QString::number(a) + "x" + QString::number(b) +")" ); updateColorLegend(7,5); dataWidget->coordinates()->axes[X1].setLabelString(QString("X1")); dataWidget->coordinates()->axes[X2].setLabelString(QString("X2")); dataWidget->coordinates()->axes[X3].setLabelString(QString("X3")); dataWidget->coordinates()->axes[X4].setLabelString(QString("X4")); dataWidget->coordinates()->axes[Y1].setLabelString(QString("Y1")); dataWidget->coordinates()->axes[Y2].setLabelString(QString("Y2")); dataWidget->coordinates()->axes[Y3].setLabelString(QString("Y3")); dataWidget->coordinates()->axes[Y4].setLabelString(QString("Y4")); dataWidget->coordinates()->axes[Z1].setLabelString(QString("Z1")); dataWidget->coordinates()->axes[Z2].setLabelString(QString("Z2")); dataWidget->coordinates()->axes[Z3].setLabelString(QString("Z3")); dataWidget->coordinates()->axes[Z4].setLabelString(QString("Z4")); pickCoordSystem(activeCoordSystem); } void Mesh2MainWindow::createPSurface(QString const& name) { dataWidget->makeCurrent(); if (name == QString("Torus")) { Torus sf(*dataWidget); sf.create(); } else if (name == QString("Seashell")) { Seashell ss(*dataWidget); ss.create(); } else if (name == QString("Boy")) { Boy boy(*dataWidget); boy.create(); } else if (name == QString("Dini")) { Dini dini(*dataWidget); dini.create(); } else if (name == QString("Cone")) { TripleField conepos; CellField conecell; createCone(conepos,conecell); dataWidget->loadFromData(conepos, conecell); } for (unsigned i=0; i!=dataWidget->coordinates()->axes.size(); ++i) { dataWidget->coordinates()->axes[i].setMajors(7); dataWidget->coordinates()->axes[i].setMinors(5); } double a = dataWidget->facets().first; double b = dataWidget->facets().second; dimWidget->setText(QString("Cells ") + QString::number(a*b) + " (" + QString::number(a) + "x" + QString::number(b) +")" ); updateColorLegend(7,5); dataWidget->coordinates()->axes[X1].setLabelString(QString("X1")); dataWidget->coordinates()->axes[X2].setLabelString(QString("X2")); dataWidget->coordinates()->axes[X3].setLabelString(QString("X3")); dataWidget->coordinates()->axes[X4].setLabelString(QString("X4")); dataWidget->coordinates()->axes[Y1].setLabelString(QString("Y1")); dataWidget->coordinates()->axes[Y2].setLabelString(QString("Y2")); dataWidget->coordinates()->axes[Y3].setLabelString(QString("Y3")); dataWidget->coordinates()->axes[Y4].setLabelString(QString("Y4")); dataWidget->coordinates()->axes[Z1].setLabelString(QString("Z1")); dataWidget->coordinates()->axes[Z2].setLabelString(QString("Z2")); dataWidget->coordinates()->axes[Z3].setLabelString(QString("Z3")); dataWidget->coordinates()->axes[Z4].setLabelString(QString("Z4")); pickCoordSystem(activeCoordSystem); } void Mesh2MainWindow::pickCoordSystem( QAction* action) { if (!action || !dataWidget) return; activeCoordSystem = action; dataWidget->setTitle("QwtPlot3D (Use Ctrl-Alt-Shift-LeftBtn-Wheel or keyboard)"); if (!dataWidget->hasData()) { double l = 0.6; dataWidget->createCoordinateSystem(Triple(-l,-l,-l), Triple(l,l,l)); for (unsigned i=0; i!=dataWidget->coordinates()->axes.size(); ++i) { dataWidget->coordinates()->axes[i].setMajors(4); dataWidget->coordinates()->axes[i].setMinors(5); } } if (action == Box || action == Frame) { if (action == Box) dataWidget->setCoordinateStyle(BOX); if (action == Frame) dataWidget->setCoordinateStyle(FRAME); grids->setEnabled(true); } else if (action == None) { dataWidget->setTitle("QwtPlot3D (Use Ctrl-Alt-Shift-LeftBtn-Wheel or keyboard)"); dataWidget->setCoordinateStyle(NOCOORD); grids->setEnabled(false); } } void Mesh2MainWindow::pickPlotStyle( QAction* action ) { if (!action || !dataWidget) return; if (action == polygon) { dataWidget->setPlotStyle(FILLED); } else if (action == filledmesh) { dataWidget->setPlotStyle(FILLEDMESH); } else if (action == wireframe) { dataWidget->setPlotStyle(WIREFRAME); } else if (action == hiddenline) { dataWidget->setPlotStyle(HIDDENLINE); } else if (action == pointstyle) { dataWidget->setPlotStyle(Qwt3D::POINTS); // Cone d(len,32); // CrossHair d(0.003,0,true,false); // dataWidget->setPlotStyle(d); } else { dataWidget->setPlotStyle(NOPLOT); } dataWidget->updateData(); dataWidget->updateGL(); } void Mesh2MainWindow::pickFloorStyle( QAction* action ) { if (!action || !dataWidget) return; if (action == floordata) { dataWidget->setFloorStyle(FLOORDATA); } else if (action == flooriso) { dataWidget->setFloorStyle(FLOORISO); } else { dataWidget->setFloorStyle(NOFLOOR); } dataWidget->updateData(); dataWidget->updateGL(); } void Mesh2MainWindow::setLeftGrid(bool b) { setGrid(Qwt3D::LEFT,b); } void Mesh2MainWindow::setRightGrid(bool b) { setGrid(Qwt3D::RIGHT,b); } void Mesh2MainWindow::setCeilGrid(bool b) { setGrid(Qwt3D::CEIL,b); } void Mesh2MainWindow::setFloorGrid(bool b) { setGrid(Qwt3D::FLOOR,b); } void Mesh2MainWindow::setFrontGrid(bool b) { setGrid(Qwt3D::FRONT,b); } void Mesh2MainWindow::setBackGrid(bool b) { setGrid(Qwt3D::BACK,b); } void Mesh2MainWindow::setGrid(Qwt3D::SIDE s, bool b) { if (!dataWidget) return; int sum = dataWidget->coordinates()->grids(); if (b) sum |= s; else sum &= ~s; dataWidget->coordinates()->setGridLines(sum!=Qwt3D::NOSIDEGRID, sum!=Qwt3D::NOSIDEGRID, sum); dataWidget->updateGL(); } void Mesh2MainWindow::resetColors() { if (!dataWidget) return; const RGBA axc = RGBA(0,0,0,1); const RGBA bgc = RGBA(1.0,1.0,1.0,1.0); const RGBA msc = RGBA(0,0,0,1); const RGBA nuc = RGBA(0,0,0,1); const RGBA lbc = RGBA(0,0,0,1); const RGBA tc = RGBA(0,0,0,1); dataWidget->coordinates()->setAxesColor(axc); dataWidget->setBackgroundColor(bgc); dataWidget->setMeshColor(msc); dataWidget->updateData(); dataWidget->coordinates()->setNumberColor(nuc); dataWidget->coordinates()->setLabelColor(lbc); dataWidget->setTitleColor(tc); col_ = new StandardColor(dataWidget); dataWidget->setDataColor(col_); dataWidget->updateData(); dataWidget->updateNormals(); dataWidget->updateGL(); } void Mesh2MainWindow::pickAxesColor() { QColor c = QColorDialog::getColor( Qt::white, this ); if ( !c.isValid() ) return; RGBA rgb = Qt2GL(c); dataWidget->coordinates()->setAxesColor(rgb); dataWidget->updateGL(); } void Mesh2MainWindow::pickBgColor() { QColor c = QColorDialog::getColor( Qt::white, this ); if ( !c.isValid() ) return; RGBA rgb = Qt2GL(c); dataWidget->setBackgroundColor(rgb); dataWidget->updateGL(); } void Mesh2MainWindow::pickMeshColor() { QColor c = QColorDialog::getColor( Qt::white, this ); if ( !c.isValid() ) return; RGBA rgb = Qt2GL(c); dataWidget->setMeshColor(rgb); dataWidget->updateData(); dataWidget->updateGL(); } void Mesh2MainWindow::pickNumberColor() { QColor c = QColorDialog::getColor( Qt::white, this ); if ( !c.isValid() ) return; RGBA rgb = Qt2GL(c); dataWidget->coordinates()->setNumberColor(rgb); dataWidget->updateGL(); } void Mesh2MainWindow::pickLabelColor() { QColor c = QColorDialog::getColor( Qt::white, this ); if ( !c.isValid() ) return; RGBA rgb = Qt2GL(c); dataWidget->coordinates()->setLabelColor(rgb); dataWidget->updateGL(); } void Mesh2MainWindow::pickTitleColor() { QColor c = QColorDialog::getColor( Qt::white, this ); if ( !c.isValid() ) return; RGBA rgb = Qt2GL(c); dataWidget->setTitleColor(rgb); dataWidget->updateGL(); } void Mesh2MainWindow::pickLighting() { lightingdlg_->show(); } void Mesh2MainWindow::pickDataColor() { #if QT_VERSION < 0x040000 datacolordlg_->show(); #else QString s = QFileDialog::getOpenFileName( this, "", "./../../data/colormaps", "Colormap files (*.map *.MAP)"); adaptDataColors(s); #endif } void Mesh2MainWindow::adaptDataColors(const QString& fileName) { ColorVector cv; if (!openColorMap(cv, fileName)) return; col_ = new StandardColor(dataWidget); col_->setColorVector(cv); dataWidget->setDataColor(col_); dataWidget->updateData(); dataWidget->updateNormals(); dataWidget->showColorLegend(legend_); dataWidget->updateGL(); } void Mesh2MainWindow::pickNumberFont() { bool ok; QFont font = QFontDialog::getFont(&ok, this ); if ( !ok ) { return; } dataWidget->coordinates()->setNumberFont(font); dataWidget->updateGL(); } void Mesh2MainWindow::pickLabelFont() { bool ok; QFont font = QFontDialog::getFont(&ok, this ); if ( !ok ) { return; } dataWidget->coordinates()->setLabelFont(font); dataWidget->updateGL(); } void Mesh2MainWindow::pickTitleFont() { bool ok; QFont font = QFontDialog::getFont(&ok, this ); if ( !ok ) { return; } dataWidget->setTitleFont(font.family(), font.pointSize(), font.weight(), font.italic()); } void Mesh2MainWindow::resetFonts() { dataWidget->coordinates()->setNumberFont(QFont("Courier", 12)); dataWidget->coordinates()->setLabelFont(QFont("Courier", 14, QFont::Bold)); dataWidget->setTitleFont( "Arial", 14, QFont::Normal ); dataWidget->updateGL(); } void Mesh2MainWindow::setStandardView() { dataWidget->setRotation(30,0,15); dataWidget->setViewportShift(0.05,0); dataWidget->setScale(1,1,1); dataWidget->setZoom(0.95); } void Mesh2MainWindow::dumpImage() { static int counter = 0; if (!dataWidget) return; QString name; name = QString("dump_") + QString::number(counter++) + "."; if (filetype_ == "PS_GZ") name += "ps.gz"; else if (filetype_ == "EPS_GZ") name += "eps.gz"; else name += filetype_; #if QT_VERSION < 0x040000 IO::save(dataWidget, name.lower(), filetype_); #else VectorWriter* vw = (VectorWriter*)IO::outputHandler("PDF"); if (vw) vw->setSortMode(VectorWriter::BSPSORT); IO::save(dataWidget, name.toLower(), filetype_); #endif } /*! Turns animation on or off */ void Mesh2MainWindow::toggleAnimation(bool val) { if ( val ) { timer->start( redrawWait ); // Wait this many msecs before redraw } else { timer->stop(); } } void Mesh2MainWindow::rotate() { if (!dataWidget) return; dataWidget->setRotation( int(dataWidget->xRotation() + 1) % 360, int(dataWidget->yRotation() + 1) % 360, int(dataWidget->zRotation() + 1) % 360 ); } void Mesh2MainWindow::toggleProjectionMode(bool val) { dataWidget->setOrtho(val); } void Mesh2MainWindow::toggleColorLegend(bool val) { legend_ = val; dataWidget->showColorLegend(val); } void Mesh2MainWindow::toggleAutoScale(bool val) { dataWidget->coordinates()->setAutoScale(val); dataWidget->updateGL(); } void Mesh2MainWindow::toggleShader(bool val) { if (val) dataWidget->setShading(GOURAUD); else dataWidget->setShading(FLAT); } void Mesh2MainWindow::setPolygonOffset(int val) { dataWidget->setPolygonOffset(val / 10.0); dataWidget->updateData(); dataWidget->updateGL(); } void Mesh2MainWindow::showRotate(double x, double y, double z) { rotateLabel->setText(" Angles (" + QString::number(x,'g',3) + " ," + QString::number(y,'g',3) + " ," + QString::number(z,'g',3) + ")"); } void Mesh2MainWindow::showShift(double x, double y) { shiftLabel->setText(" Shifts (" + QString::number(x,'g',3) + " ," + QString::number(y,'g',3) + " )" ); } void Mesh2MainWindow::showScale(double x, double y, double z) { scaleLabel->setText(" Scales (" + QString::number(x,'g',3) + " ," + QString::number(y,'g',3) + " ," + QString::number(z,'g',3) + ")"); } void Mesh2MainWindow::showZoom(double z) { zoomLabel->setText(" Zoom " + QString::number(z,'g',3)); } void Mesh2MainWindow::openMesh() { #if QT_VERSION < 0x040000 QString data(QFileDialog::getOpenFileName( "../../data", "nodes (*.nod)", this ) ); QString edges( QFileDialog::getOpenFileName( "../../data", "connectivities (*.cel)", this ) ); #else QString data( QFileDialog::getOpenFileName( this, "", "../../data", "nodes (*.nod)") ); QString edges( QFileDialog::getOpenFileName( this, "", "../../data", "connectivities (*.cel)") ); #endif if ( data.isEmpty() || edges.isEmpty() || !dataWidget) return; TripleField vdata; CellField vpoly; readNodes(vdata, QWT3DLOCAL8BIT(data), NodeFilter()); readConnections(vpoly, QWT3DLOCAL8BIT(edges), CellFilter()); dataWidget->loadFromData(vdata, vpoly); dimWidget->setText(QString("Cells ") + QString::number(dataWidget->facets().first)); for (unsigned i=0; i!=dataWidget->coordinates()->axes.size(); ++i) { dataWidget->coordinates()->axes[i].setMajors(4); dataWidget->coordinates()->axes[i].setMinors(5); dataWidget->coordinates()->axes[i].setLabelString(QString("")); } updateColorLegend(4,5); pickCoordSystem(activeCoordSystem); } void Mesh2MainWindow::showNormals(bool val) { dataWidget->showNormals(val); dataWidget->updateNormals(); dataWidget->updateGL(); } void Mesh2MainWindow::setNormalLength(int val) { dataWidget->setNormalLength(val / 400.); dataWidget->updateNormals(); dataWidget->updateGL(); } void Mesh2MainWindow::setNormalQuality(int val) { dataWidget->setNormalQuality(val); dataWidget->updateNormals(); dataWidget->updateGL(); } bool Mesh2MainWindow::openColorMap(ColorVector& cv, QString fname) { if (fname.isEmpty()) return false; ifstream file(QWT3DLOCAL8BIT(fname)); if (!file) return false; RGBA rgb; cv.clear(); while ( file ) { file >> rgb.r >> rgb.g >> rgb.b; file.ignore(1000,'\n'); if (!file.good()) break; else { rgb.a = 1; rgb.r /= 255; rgb.g /= 255; rgb.b /= 255; cv.push_back(rgb); } } return true; } void Mesh2MainWindow::updateColorLegend(int majors, int minors) { dataWidget->legend()->setMajors(majors); dataWidget->legend()->setMinors(minors); double start, stop; dataWidget->coordinates()->axes[Z1].limits(start,stop); dataWidget->legend()->setLimits(start, stop); } void Mesh2MainWindow::setFileType(QString const& name) { filetype_ = name; } void Mesh2MainWindow::enableLighting(bool val) { dataWidget->enableLighting(val); dataWidget->illuminate(0); dataWidget->updateGL(); } qwtplot3d-0.2.7+svn191/examples/mesh2/src/designerworkaround.cpp0000644000203200020320000001220010663257611024105 0ustar gudjongudjon#include "designerworkaround.h" namespace{ QString tr(const char* val) { return QObject::tr(val); } void setCheckable(QActionGroup* ag) { QList tmplist = ag->actions(); for (QList::iterator it=tmplist.begin(); it!=tmplist.end(); ++it) (*it)->setCheckable(true); } } void DesignerWorkaround::setupWorkaround(QMainWindow* mw) { // actions openFile = new QAction(QIcon(":/images/fileopen.png"), tr("&Open File"), mw); openFile->setShortcut( QKeySequence(tr("CTRL+O"))); openMeshFile = new QAction(QIcon(":/images/filecell.png"), tr("Open FEM File"), mw); Exit = new QAction(tr("&Exit"), mw); Exit->setShortcut( QKeySequence(tr("CTRL+Q"))); animation = new QAction(QIcon(":/images/movie.png"), tr("Animation"), mw); animation->setCheckable(true); dump = new QAction(QIcon(":/images/savecontent.png"), "", mw); coord = new QActionGroup(mw); Box = new QAction(QIcon(":/images/box.png"), "", coord); Frame = new QAction(QIcon(":/images/frame.png"), "", coord); None = new QAction(QIcon(":/images/grid.png"), "", coord); setCheckable(coord); grids = new QActionGroup(mw); front = new QAction(QIcon(":/images/gridfr.png"), "", grids); back = new QAction(QIcon(":/images/gridb.png"), "", grids); right = new QAction(QIcon(":/images/gridr.png"), "", grids); left = new QAction(QIcon(":/images/gridl.png"), "", grids); ceil = new QAction(QIcon(":/images/gridc.png"), "", grids); floor = new QAction(QIcon(":/images/gridf.png"), "", grids); grids->setExclusive(false); setCheckable(grids); plotstyle = new QActionGroup(mw); pointstyle = new QAction(QIcon(":/images/scattered.png"), "", plotstyle); wireframe = new QAction(QIcon(":/images/wireframe.png"), "", plotstyle); hiddenline = new QAction(QIcon(":/images/hiddenline.png"), "", plotstyle); polygon = new QAction(QIcon(":/images/polygon.png"), "", plotstyle); filledmesh = new QAction(QIcon(":/images/filledmesh.png"), "", plotstyle); nodata = new QAction(QIcon(":/images/nodata.png"), "", plotstyle); setCheckable(plotstyle); floorstyle = new QActionGroup(mw); floordata = new QAction(QIcon(":/images/floordata.png"), "", floorstyle); flooriso = new QAction(QIcon(":/images/flooriso.png"), "", floorstyle); floornone = new QAction(QIcon(":/images/floorempty.png"), "", floorstyle); setCheckable(floorstyle); normals = new QAction(QIcon(":/images/normals.png"), "", mw); normals->setCheckable(true); color = new QActionGroup(mw); axescolor = new QAction(tr("&Axes"), color); backgroundcolor = new QAction(tr("&Background"), color); meshcolor = new QAction(tr("&Mesh"), color); numbercolor = new QAction(tr("&Numbers"), color); labelcolor = new QAction(tr("&Label"), color); titlecolor = new QAction(tr("Caption"), color); datacolor = new QAction(tr("Data color"), color); resetcolor = new QAction(tr("&Reset"), color); font = new QActionGroup(mw); numberfont = new QAction(tr("&Scale numbering"), font); labelfont = new QAction(tr("&Axes label"), font); titlefont = new QAction(tr("&Caption"), font); resetfont = new QAction(tr("&Reset"), font); // toolbars mainToolbar = new QToolBar( QString(""), mw ); mainToolbar->setMovable( false ); mainToolbar->addAction(openFile); mainToolbar->addAction(openMeshFile); mainToolbar->addAction(dump); filetypeCB = new QComboBox; functionCB = new QComboBox; psurfaceCB = new QComboBox; mainToolbar->addWidget(filetypeCB); mainToolbar->addWidget(functionCB); mainToolbar->addWidget(psurfaceCB); mainToolbar->addAction(animation); csToolbar = new QToolBar( QString(""), mw ); csToolbar->setMovable( false ); csToolbar->addActions(coord->actions()); csToolbar->addActions(grids->actions()); csToolbar->addActions(plotstyle->actions()); csToolbar->addActions(floorstyle->actions()); csToolbar->addAction(normals); // menubar menubar = mw->menuBar();//new QMenuBar(); filemenu = menubar->addMenu("&File"); filemenu->addAction(openFile); filemenu->addAction(openMeshFile); filemenu->addAction(animation); filemenu->addAction(Exit); colormenu = menubar->addMenu(tr("&Color")); colormenu->addActions(color->actions()); fontmenu = menubar->addMenu(tr("&Fonts")); fontmenu->addActions(font->actions()); mw->addToolBar(mainToolbar); mw->addToolBar(csToolbar); functionCB->clear(); functionCB->addItem( tr( "---" ) ); functionCB->addItem( tr( "Hat" ) ); functionCB->addItem( tr( "Rosenbrock" ) ); functionCB->addItem( tr( "Saddle" ) ); functionCB->addItem( tr( "Sombrero" ) ); functionCB->addItem( tr( "Ripple" ) ); functionCB->setToolTip(tr( "Display function" ) ); psurfaceCB->clear(); psurfaceCB->addItem( tr( "---" ) ); psurfaceCB->addItem( tr( "Torus" ) ); psurfaceCB->addItem( tr( "Seashell" ) ); psurfaceCB->addItem( tr( "Boy" ) ); psurfaceCB->addItem( tr( "Dini" ) ); psurfaceCB->addItem( tr( "Cone" ) ); psurfaceCB->setToolTip(tr( "Display parametric surface. Turn Lighting on for better quality.")); QObject::connect(Exit, SIGNAL(triggered()), mw, SLOT(close())); } qwtplot3d-0.2.7+svn191/examples/mesh2/src/functions.h0000644000203200020320000000707710663257611021666 0ustar gudjongudjon#ifndef __EXAMPLE_H__ #define __EXAMPLE_H__ #include #include "../../../include/qwt3d_parametricsurface.h" #include "../../../include/qwt3d_function.h" using namespace Qwt3D; class Rosenbrock : public Function { public: Rosenbrock(SurfacePlot& pw) :Function(pw) { } double operator()(double x, double y) { return 0.7 * log10((1-x)*(1-x) + 10 * (y - x*x)*(y - x*x)); } // QString name() const {return "Almost {\\it Rosenbrock}\\,:\\quad$\\frac{\\ln((1-x)^2 + 100(y-x^2)^2)}{8}$";} }; class Hat : public Function { public: Hat(SurfacePlot& pw) :Function(pw) { //setMinZ(0.3); setDomain(0,10,0,10); } double operator()(double x, double y) { return 1.0 / (x*x+y*y+0.5); //return x*x*y/(x*x*x*x+y*y); } }; class Ripple : public Function { public: Ripple(SurfacePlot& pw) :Function(pw) { double l = 12; setDomain(-l,l,-l,l); } double operator()(double x, double y) { return (cos(sqrt(x*x+y*y) + cos(sqrt(((x+.913*2*Qwt3D::PI)*(x+.913*2*Qwt3D::PI))+y*y)) + cos(sqrt(((x-.913*2*Qwt3D::PI)*(x-.913*2*Qwt3D::PI))+(y*y))))*4); } }; class Saddle : public Function { public: Saddle() :Function() { // setMaxZ(0.8); } double operator()(double x, double y) { return x*x - y*y; } // QString name() const {return "$x^2-y^2$";} }; class Mex : public Function { public: Mex() :Function() { // setMaxZ(0.8); } double operator()(double x, double y) { double n = sqrt(x*x+y*y); if (n < DBL_MIN) return 20; return 20 * sin(sqrt(x*x+y*y)) / n; } // QString name() const {return "$\\frac{20\\sin\\sqrt{x^2+y^2}}{\\sqrt{x^2+y^2}}$";} }; class Torus : public ParametricSurface { public: Torus(SurfacePlot& pw) :ParametricSurface(pw) { setMesh(41,31); setDomain(-2*Qwt3D::PI, 0,-2*Qwt3D::PI,0); setPeriodic(true,true); } Triple operator()(double u, double v) { double x,y,z; double c = 1.9; x = (c + cos(v)) * cos(u); y = (c + cos(v)) * sin(u); z = sin(v) + cos(v); return Triple(x,y,z); } }; class Seashell : public ParametricSurface { public: Seashell(SurfacePlot& pw) :ParametricSurface(pw) { setMesh(41,131); setDomain(0,2*Qwt3D::PI,0,2*Qwt3D::PI); setPeriodic(true,true); } Triple operator()(double u, double v) { double x,y,z; double a = 1; double b = 6; double c = 0.5; int n = 3; double f = v/(2*Qwt3D::PI); x = a*(1-f)*cos(n*v)*(1+cos(u)) + c*cos(n*v) ; y = a*(1-f)*sin(n*v)*(1+cos(u)) + c*sin(n*v) ; z = b*f + a*(1-f)*sin(u); return Triple(x,y,z); } }; class Boy : public ParametricSurface { public: Boy(SurfacePlot& pw) :ParametricSurface(pw) { setMesh(141,131); setDomain(0,Qwt3D::PI,0,Qwt3D::PI); setPeriodic(true,true); } Triple operator()(double u, double v) { double x,y,z; double a = 2/3.; double b = sqrt(2.); x = a*(cos(u)*cos(2*v)+b*sin(u)*cos(v))*cos(u) / (b-sin(2*u)*sin(3*v)); y = a*(cos(u)*sin(2*v)-b*sin(u)*sin(v))*cos(u) / (b-sin(2*u)*sin(3*v)); z = b*cos(u)*cos(u) / (b-sin(2*u)*sin(2*v)); return Triple(x,y,z); } }; class Dini : public ParametricSurface { public: Dini(SurfacePlot& pw) :ParametricSurface(pw) { setMesh(141,35); setDomain(0,5*Qwt3D::PI,0.001, 2); setPeriodic(true,true); } Triple operator()(double u, double v) { double x,y,z; double a = 5; double b = 1; x=a*cos(u)*sin(v); y=a*sin(u)*sin(v); z=a*(cos(v)+log(tan(v/2)))+b*u; return Triple(x,y,z); } }; void createCone(Qwt3D::TripleField& conepos, Qwt3D::CellField& conecell); #endif qwtplot3d-0.2.7+svn191/examples/mesh2/src/thesis.tex0000644000203200020320000000024210663257611021511 0ustar gudjongudjon\documentclass{slides} \usepackage[dvips]{color} \usepackage{times} \usepackage{graphicx} \begin{document} \include{dump_0.pdf} %\include{dump3b} \end{document} qwtplot3d-0.2.7+svn191/examples/mesh2/src/lightingdlgbaseimpl.h0000644000203200020320000000047410663257611023661 0ustar gudjongudjon#ifndef LIGHTINGDLGBASE_H #define LIGHTINGDLGBASE_H #include "lightingdlgbase.h" class lightingdlgbase : public lightingdlgbaseBase { Q_OBJECT public: lightingdlgbase( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); ~lightingdlgbase(); }; #endif // LIGHTINGDLGBASE_H qwtplot3d-0.2.7+svn191/examples/mesh2/src/mesh2mainwindow.h0000644000203200020320000000570410663257611022764 0ustar gudjongudjon#ifndef mesh2mainwindow_h__2004_03_07_13_38_begin_guarded_code #define mesh2mainwindow_h__2004_03_07_13_38_begin_guarded_code #include "../../../include/qwt3d_surfaceplot.h" #if QT_VERSION < 0x040000 #include "mesh2mainwindowbase.h" #else #include "ui_mesh2mainwindowbase4.h" #include "designerworkaround.h" #endif //MOC_SKIP_BEGIN #if QT_VERSION < 0x040000 class DummyBase : public Mesh2MainWindowBase { public: DummyBase(QWidget* parent = 0) : Mesh2MainWindowBase(parent) { } }; #else class DummyBase : public QMainWindow, protected Ui::MainWindow, protected DesignerWorkaround { public: DummyBase(QWidget* parent = 0) : QMainWindow(parent) { } }; #endif //MOC_SKIP_END class QLabel; class QTimer; class QAction; class QFileDialog; class LightingDlg; class ColorMapPreview; class Mesh2MainWindow : public DummyBase { Q_OBJECT public: Mesh2MainWindow( QWidget* parent = 0 ); ~Mesh2MainWindow(); Qwt3D::SurfacePlot* dataWidget; public slots: void open(); void openMesh(); void createFunction(QString const& name); void createPSurface(QString const& name); void setFileType(QString const& name); void pickCoordSystem( QAction* ); void pickPlotStyle( QAction* ); void pickFloorStyle( QAction* ); void pickAxesColor(); void pickBgColor(); void pickMeshColor(); void pickNumberColor(); void pickLabelColor(); void pickTitleColor(); void pickDataColor(); void pickLighting(); void resetColors(); void pickNumberFont(); void pickLabelFont(); void pickTitleFont(); void resetFonts(); void setStandardView(); void dumpImage(); void toggleAnimation(bool); void toggleProjectionMode(bool); void toggleColorLegend(bool); void toggleAutoScale(bool val); void toggleShader(bool val); void rotate(); void setPolygonOffset(int); void showRotate(double x, double y, double z); void showShift(double x, double y); void showScale(double x, double y, double z); void showZoom(double z); void showNormals(bool val); void setNormalQuality(int); void setNormalLength(int); bool openColorMap(Qwt3D::ColorVector& cv, QString fname); void adaptDataColors(const QString&); void updateColorLegend(int majors, int minors); void setLeftGrid( bool b ); void setRightGrid( bool b ); void setCeilGrid( bool b ); void setFloorGrid( bool b ); void setFrontGrid( bool b ); void setBackGrid( bool b ); void setGrid( Qwt3D::SIDE, bool ); void enableLighting(bool val); private: QLabel *filenameWidget, *dimWidget, *rotateLabel, *shiftLabel, *scaleLabel, *zoomLabel; QTimer* timer; int redrawWait; QAction* activeCoordSystem; bool legend_; Qwt3D::StandardColor* col_; QFileDialog* datacolordlg_; LightingDlg* lightingdlg_; QString filetype_; // convenience compatib. code bool connectA (const QObject* sender, const char * slot); bool connectAG (const QObject* sender, const char * slot); #if QT_VERSION < 0x040000 ColorMapPreview* colormappv_; #endif }; #endif /* include guarded */ qwtplot3d-0.2.7+svn191/examples/mesh2/src/designerworkaround.h0000644000203200020320000000273510663257611023566 0ustar gudjongudjon#ifndef designerworkaround_h__2005_07_10_10_46_begin_guarded_code #define designerworkaround_h__2005_07_10_10_46_begin_guarded_code #include #include #include #include #include #include #include class DesignerWorkaround { public: QMenuBar *menubar; QMenu *filemenu; QMenu *colormenu; QMenu *fontmenu; QToolBar *mainToolbar; QToolBar *csToolbar; QAction* openFile; QAction* openMeshFile; QAction* animation; QAction* dump; QAction* normals; QAction* Exit; QActionGroup* coord; QAction* Box; QAction* Frame; QAction* None; QActionGroup* plotstyle; QAction* wireframe; QAction* hiddenline; QAction* polygon; QAction* filledmesh; QAction* nodata; QAction* pointstyle; QActionGroup* color; QAction* axescolor; QAction* backgroundcolor; QAction* meshcolor; QAction* numbercolor; QAction* labelcolor; QAction* titlecolor; QAction* datacolor; QAction* resetcolor; QActionGroup* font; QAction* numberfont; QAction* labelfont; QAction* titlefont; QAction* resetfont; QActionGroup* floorstyle; QAction* floordata; QAction* flooriso; QAction* floornone; QActionGroup* grids; QAction* front; QAction* back; QAction* right; QAction* left; QAction* ceil; QAction* floor; QComboBox* filetypeCB, *functionCB, *psurfaceCB; void setupWorkaround(QMainWindow* mw); }; #endif qwtplot3d-0.2.7+svn191/examples/mesh2/src/lightingdlgbase.ui0000644000203200020320000003347710663257611023176 0ustar gudjongudjon LightingDlgBase LightingDlgBase 0 0 450 345 5 5 0 0 450 345 450 345 0 0 Lighting Configuration false unnamed 11 6 frame 290 290 290 290 StyledPanel Sunken Layout11 unnamed 0 6 stdlight Std true true Horizontal Spacing2 Horizontal Expanding 16 0 buttonOk &OK true true Layout8 unnamed 0 6 Layout2 unnamed 0 6 ambdiff Ambient & Diffuse Part ambdiffSL 100 80 Horizontal Layout2_2 unnamed 0 6 spec Specular Part specSL 100 30 Horizontal Layout2_3 unnamed 0 6 shin Shininess shinSL 1000 500 Horizontal Layout2_4 unnamed 0 6 emiss Emission emissSL 100 Horizontal Layout2_4_2 unnamed 0 6 dist Distance distSL 1000 100 Horizontal buttonOk clicked() LightingDlgBase accept() qwtplot3d-0.2.7+svn191/examples/mesh2/src/main.cpp0000644000203200020320000000130010663257611021114 0ustar gudjongudjon/******************************************************************** created: 2003/09/09 filename: main.cpp author: Micha Bieber *********************************************************************/ #include #include "mesh2mainwindow.h" int main( int argc, char **argv ) { QApplication::setColorSpec( QApplication::CustomColor ); QApplication app(argc,argv); if ( !QGLFormat::hasOpenGL() ) { qWarning( "This system has no OpenGL support. Exiting." ); return -1; } Mesh2MainWindow mainwindow; #if QT_VERSION < 0x040000 app.setMainWidget(&mainwindow); #endif mainwindow.resize(1024,768); mainwindow.show(); return app.exec(); } qwtplot3d-0.2.7+svn191/examples/mesh2/src/mesh2mainwindowbase4.ui0000644000203200020320000003527610663257611024100 0ustar gudjongudjon MainWindow 0 0 800 600 Mesh2 8 8 8 8 6 6 6 0 0 0 0 6 0 0 0 0 Std false Lighting 6 0 0 0 0 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Polygon Offset</p></body></html> 30 5 5 Qt::Horizontal QSlider::TicksAbove 2 Qt::Horizontal QSizePolicy::Fixed 40 20 6 0 0 0 0 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Resolution</p></body></html> 1 100 Qt::Horizontal QSlider::TicksAbove 5 Qt::Horizontal QSizePolicy::Fixed 71 20 6 0 0 0 0 0 0 QFrame::StyledPanel QFrame::Sunken 6 0 0 0 0 6 0 0 0 0 Ortho true Legend Autoscale true Mouse true Shading true 6 0 0 0 0 0 0 <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Normals</p></body></html> 6 0 0 0 0 0 0 3 32 4 3 Qt::Vertical true QSlider::TicksAbove 0 0 1 100 5 8 Qt::Vertical true QSlider::TicksAbove lightingswitch toggled(bool) lighting setEnabled(bool) 181 568 144 568 qwtplot3d-0.2.7+svn191/examples/mesh2/src/mesh.cpp0000644000203200020320000000210410663257611021127 0ustar gudjongudjon#include "functions.h" using namespace std; using namespace Qwt3D; void createCone(Qwt3D::TripleField& conepos, Qwt3D::CellField& conecell) { conepos.clear(); conecell.clear(); Cell cell; conepos.push_back(Triple(0,0,0)); const unsigned int count = 17; double r1 = 0.7; double r2 = 0.9 * r1; double h1 = 2; double h2 = 1.03 * h1; unsigned i; Cell c1; // outer top border for (i=0; i #include #include #include #include #include "lightingdlg.h" using namespace Qwt3D; class Sphere : public ParametricSurface { public: Sphere(SurfacePlot& pw) :ParametricSurface(pw) { setMesh(41,31); setDomain(0,2*Qwt3D::PI,0,Qwt3D::PI); setPeriodic(false,false); } Triple operator()(double u, double v) { double x,y,z; double r = 1; x = r*cos(u)*sin(v); y = r*sin(u)*sin(v); z = r*cos(v); return Triple(x,y,z); } }; ///////////////////////////////////////////////////////////////// // // Plot // ///////////////////////////////////////////////////////////////// Plot::Plot(QWidget *parent) : SurfacePlot(parent) { setTitle("A Simple SurfacePlot Demonstration"); Sphere sphere(*this); sphere.create(); reset(); assignMouse(Qt::LeftButton, Qt::RightButton, Qt::LeftButton, Qt::NoButton, Qt::NoButton, Qt::NoButton, Qt::NoButton, Qt::NoButton, Qt::NoButton ); stick = (Pointer*)addEnrichment(Pointer(0.05)); stick->setPos(0,0,1); } void Plot::reset() { makeCurrent(); setRotation(0,0,0); setTitle("Use your mouse buttons and keyboard"); setTitleFont("Arial", 8, QFont::Bold); setTitleColor(RGBA(0.9,0.9,0.9)); setSmoothMesh(true); setZoom(0.9); setCoordinateStyle(NOCOORD); setMeshColor(RGBA(0.6,0.6,0.6,0.3)); setPlotStyle(FILLEDMESH); setBackgroundColor(RGBA(0,0,0)); updateData(); } ///////////////////////////////////////////////////////////////// // // Pointer // ///////////////////////////////////////////////////////////////// Pointer::Pointer(double rad) { configure(rad); } Pointer::~Pointer() { } void Pointer::configure(double rad) { plot = 0; radius_ = rad; } void Pointer::drawBegin() { GLint mode; glGetIntegerv(GL_MATRIX_MODE, &mode); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glColor3d(1,0,0); glBegin(GL_LINES); glVertex3d(pos_.x, pos_.y, pos_.z); glVertex3d(0, 0, 0); glEnd(); glPopMatrix(); glMatrixMode(mode); } LightingDlg::LightingDlg(QWidget *parent) :LightingBase(parent) { #if QT_VERSION < 0x040000 QGridLayout *grid = new QGridLayout( frame, 0, 0 ); #else setupUi(this); QGridLayout *grid = new QGridLayout( frame); #endif dataPlot = 0; plot = new Plot(frame); plot->updateData(); grid->addWidget( plot, 0, 0 ); connect( stdlight, SIGNAL( clicked() ), this, SLOT( reset() ) ); connect( distSL, SIGNAL(valueChanged(int)), this, SLOT(setDistance(int)) ); connect( emissSL, SIGNAL(valueChanged(int)), this, SLOT(setEmission(int)) ); connect( ambdiffSL, SIGNAL(valueChanged(int)), this, SLOT(setDiff(int)) ); connect( specSL, SIGNAL(valueChanged(int)), this, SLOT(setSpec(int)) ); connect( shinSL, SIGNAL(valueChanged(int)), this, SLOT(setShin(int)) ); connect( plot, SIGNAL(rotationChanged(double, double, double)), this, SLOT(setRotation(double, double, double)) ); } LightingDlg::~LightingDlg() { delete plot; } void LightingDlg::setEmission(int val) { if (!dataPlot) return; dataPlot->setMaterialComponent(GL_EMISSION, val / 100.); dataPlot->updateGL(); } void LightingDlg::setDiff(int val) { if (!dataPlot) return; dataPlot->setLightComponent(GL_DIFFUSE, val / 100.); dataPlot->updateGL(); } void LightingDlg::setSpec(int val) { if (!dataPlot) return; dataPlot->setMaterialComponent(GL_SPECULAR, val / 100.); dataPlot->updateGL(); } void LightingDlg::setShin(int val) { if (!dataPlot) return; dataPlot->setShininess( val / 100.); dataPlot->updateGL(); } void LightingDlg::reset() { plot->reset(); if (dataPlot) dataPlot->updateGL(); } void LightingDlg::setDistance(int val) { plot->stick->setPos(0,0,val/100.); plot->updateData(); plot->updateGL(); double drad = (dataPlot->hull().maxVertex-dataPlot->hull().minVertex).length(); drad *= val/20.; dataPlot->setLightShift(drad,drad,drad); dataPlot->updateGL(); } void LightingDlg::assign(Qwt3D::Plot3D* pl) { if (!pl) return; dataPlot = pl; } void LightingDlg::setRotation(double x, double y, double z) { if (!dataPlot) return; setDistance(distSL->value()); dataPlot->setLightRotation(x,y,z); dataPlot->updateGL(); } qwtplot3d-0.2.7+svn191/examples/mesh2/mesh2.pro0000644000203200020320000000102010663257611020434 0ustar gudjongudjoninclude( ../common.pro ) SOURCES = src/main.cpp \ src/mesh2mainwindow.cpp \ src/colormapreader.cpp \ src/lightingdlg.cpp \ src/mesh.cpp HEADERS = src/mesh2mainwindow.h \ src/functions.h \ src/colormapreader.h \ src/lightingdlg.h \ src/femreader.h !isEmpty( ISQT4 ) { SOURCES += src/designerworkaround.cpp HEADERS += src/designerworkaround.h FORMS = src/mesh2mainwindowbase4.ui \ src/lightingdlgbase4.ui } isEmpty( ISQT4 ) { FORMS = src/mesh2mainwindowbase.ui \ src/lightingdlgbase.ui } qwtplot3d-0.2.7+svn191/examples/floorempty.png0000644000203200020320000000032510663257611020573 0ustar gudjongudjonPNG  IHDR+tEXtCreation TimeMo 31 Mrz 2003 20:09:51 +0100!ʶtIME 0=X pHYs B4gAMA a-IDATxc`#0bO3)2?тi++`(#G@YL;IENDB`qwtplot3d-0.2.7+svn191/examples/gridl.png0000644000203200020320000000155510663257611017502 0ustar gudjongudjonPNG  IHDR*tEXtCreation TimeSo 9 Mrz 2003 17:51:17 +0100WbtIME B pHYs B4gAMA aIDATxڕUKQwٙ-],q.!DhFBCaP=?PKQP/$Af` !>TFVUkugwtaiuǁw{{#C`h.R-9w˧glT!Bm$g,b߲6ӂf;֜B,zY|RG2Q ޕWIsAvt)hL vox<EFXesoYRSIENDB`qwtplot3d-0.2.7+svn191/examples/fileopen.png0000644000203200020320000000026210663257611020174 0ustar gudjongudjonPNG  IHDRĴl;yIDATH 0P=6Etӥp(,X}13=?|>b R̾Î>:jj!"FgEsjI2X4NP71U:NwtqF_IENDB`qwtplot3d-0.2.7+svn191/examples/images.qrc0000644000203200020320000000166610663257611017652 0ustar gudjongudjon box.png filecell.png fileopen.png filledmesh.png floordata.png floorempty.png flooriso.png floormesh.png frame.png grid.png gridb.png gridc.png gridf.png gridfr.png gridl.png gridr.png hiddenline.png icon.png movie.png nodata.png none.png normals.png polygon.png qwtplot.png savecontent.png scattered.png wireframe.png qwtplot3d-0.2.7+svn191/examples/gridr.png0000644000203200020320000000143710663257611017507 0ustar gudjongudjonPNG  IHDR*tEXtCreation TimeSo 9 Mrz 2003 17:51:17 +0100WbtIME#,( pHYs B4gAMA axIDATxڭUKhAY7n!JbۓҢՂ*zR-{ǡ"F,R%^ULQi6Km ,i]>doٙe%)aG 6_IyA`j/ʊ#{4V0T9nJ mɤJt8=-U4;^!psqB4oGpõTNd^Z^+BJ_ņygmz ͜Q7H"=4tjT90IA Lǀwvr:}w#}x)b>Z28Ut|Wuj'{W^ ,-u+KWZOg:xVb/KpX9ZE s=|lij;RkVK05+6F]>Sʴ+7sNLuAY:#cfi|/rjkHVO'/?rj'KS?OS=}bUVY.+~PfQA$ьUZp&,2d%)&@CE*AG?}\Ϧ ÖЙMYd y=ec}?|^wONU%H/~FtIr F(px>j Aia|c[+| TaJ7@,DW6zaÊjUUk6EElz{6 t8],EM]ǮCNEIENDB`qwtplot3d-0.2.7+svn191/examples/movie.png0000644000203200020320000000235410663257611017516 0ustar gudjongudjonPNG  IHDR DtIME 2q pHYs B4gAMA aPLTE~rponmf|_bnwSsJuPxV{]еE1'tMwUvQvSxW~c yYd tĨ_eHIENDB`qwtplot3d-0.2.7+svn191/examples/filecell.png0000644000203200020320000000171710663257611020160 0ustar gudjongudjonPNG  IHDR etIME,, pHYs  ~gAMA aPLTEtEm=~pE1:\T\AMWDPIM=NIEMEEmI~p~11\T\AMLDPOM=KIEALE~1\TMeEmpUSERDOmIMp~A1IT\NML=POJ=KEEATLTEE~1U\STEMeREmNpAMUES=EARdDmOiIMn~Ai1Is\NtL=rOJaKEtAToLTrEE~U1US\SETEReRPmNRpAOMFUEIS=LEAERd=DmEOi:Mn\AiDIsoNtk=ruJamEteTonTrtEeU USuSEnERdRP NREAOiMFnEIs=LtAEed=lmEli:un\niDgsoetknru\amAtedonmrtienU iSusEntRdrP aREtOioFnrIsLtwEei=lnEld:ui\nrDg=oeEkn:u\\mAWedInmNtiNenT iusntdr aEtionrstweilnlduinrg=eEn:\\AWdImNiNnTistr atorwindir=E:\WINNT  ~tRNS@fEIDATxU 0 8tGJ͉BBE3Uh ]c>} H7X˾\WCKIENDB`qwtplot3d-0.2.7+svn191/examples/wireframe.png0000644000203200020320000000213710663257611020357 0ustar gudjongudjonPNG  IHDRtIME 8p pHYs B4gAMA aIDATxڭT]L[e~N)?YY :27.)Q sXd1pCSxAb .$4!1\,l颢AY%4i -ok9=9|syNb+i`jΝ_yWOByɤ' T.~ 4&S4?MNg߿__ htUWW2<@UEahhHǝ2:FycccȈA>M(..Vdee>Ajvtt# ANSDѫ# }Gyڏr,,,q De,\^^U[[k;eB$Z ԢxP.,}h1N0Q}&|fff=uVRT?/%#B!;JKKD-z{?Ù3rqݼ$˴'O^"`61;;bՊJ<i2b^UCjEQ666PVVlX]SISP̠Wwww+(?LIRǏp8NFa0TZ~8|f5~~݌p'U"v;vvvN]6 J677SlUTTOLL,gzkmm\3 zVKi2 ---% rRҒ165dZaFl`Slp^*~Msht㱂1a,Pp*>%zZǿo1s]nIo BiMiQ@iD[[4 ^$F`DС۷=IAҀT|7}©CdwxbpDo OAS:fp9DB] R! 1)σhȎA@|Z $PKyPbs)](91.f1%}lKADUr "BO* 4<]SFAbMPއ6Ą%0Na6\l}B@h! m*w*P6 umcG"@]YSE,HIENDB`qwtplot3d-0.2.7+svn191/examples/polygon.png0000644000203200020320000000133510663257611020064 0ustar gudjongudjonPNG  IHDRtIME 1"Ku pHYs B4gAMA alIDATxڵkRaǟc?SŌ.qyE. bѕ7m#bۘw/.j -I DSxq%L/y><0jlV6MmX\$ ǂTiͶjfn7 X˲c<)\G`&ڛ^G{scL/}>ŽjhNQ(t^_̮S:c|TT.2ݣRhƠD@1dE9"PR{^|/&Xv#/}uųPvTR5܈h@ÌtvVJPCB`"baZL62 EDqN*)/9r eD"Wuz`0+ۦ]^\pS*zvң2OhVtP胞eTJW p8(\z}MpU.dc0е Pk@Ձ`>TjD"@@-P /W8 Xʢ/ җaH2_BB__%U+S2IENDB`qwtplot3d-0.2.7+svn191/examples/frame.png0000644000203200020320000000044210663257611017465 0ustar gudjongudjonPNG  IHDR*tEXtCreation TimeSo 9 Mrz 2003 17:51:17 +0100WbtIME &@ pHYs B4gAMA a{IDATxc`2`ĈaR?χ̄VP"EPQCG @̢5 'HȒNzb 'w '@f|Sd #1.OtLЕܻ-֎IENDB`qwtplot3d-0.2.7+svn191/examples/flooriso.png0000644000203200020320000000045110663257611020227 0ustar gudjongudjonPNG  IHDR+tEXtCreation TimeMo 31 Mrz 2003 20:09:51 +0100!ʶtIME x. pHYs B4gAMA aIDATxc`#0bO31 GL/ AFtM?aXd6W0 ER5ذ n03 2¼- ä<@wzKxmo2B(,=F=/HIENDB`qwtplot3d-0.2.7+svn191/examples/floormesh.png0000644000203200020320000000037010663257611020371 0ustar gudjongudjonPNG  IHDR+tEXtCreation TimeMo 31 Mrz 2003 20:09:51 +0100!ʶtIME 4. pHYs B4gAMA aPIDATxc`#0bO3Q eK ? GwB2VSŕ Dܕ0ަi(jhG4VIENDB`qwtplot3d-0.2.7+svn191/examples/none.png0000644000203200020320000000074710663257611017342 0ustar gudjongudjonPNG  IHDR*tEXtCreation TimeSo 9 Mrz 2003 17:51:17 +0100WbtIME #V~_l pHYs B4gAMA a@IDATxcdX60)I @89Ȍ~Csl|]C H3Bx :Cg[|' ]L 9DF}'V r Do O$0!^/^E(PȀ\ -I }D+htGv ̥@v +$Vq u'a\G1Y̥LPS2#CХL09b74\ $aR /S] N n>M5 WR'0 B3Ui;P /WA߆-L`E(l#> E`P/&IENDB`qwtplot3d-0.2.7+svn191/examples/hiddenline.png0000644000203200020320000000176610663257611020510 0ustar gudjongudjonPNG  IHDRtIME \| pHYs B4gAMA aIDATxڭm(aǯs[絍rSjCJlJm3A)_M@RJI>PXFy?8ν}oG,6UOOۅ{w-]m,c)wVh4!!!,^xzz6&jӑ٧䖖^8hZKEyp[Q#DڜLJ)''bbb^^^QT=$)LKATRRUQۈmMM UWW<%''MMM"?fffzJ)""եvZ]]%ooo"%G`i|||^WUUUg6񫰰^1꺍37oeyy;mnn$eddPRREFF>gZoU_: :88xa477G@SBUj0|('9!(88X0LHLv`dC;88H!H Ad#OII⇇㄄l^D `&::EJKKB<B3 ---Qss ܽC6Gkkkw #` _$Չ煅 -{/!  a\^Dp~ V獇Gޞg(S}}7DZ[[)== )S /~T*Z}hhC" PVVlja!;033cA֕bQ p-;f.3P7pJDWzdb{/` } Zٿc1z5IENDB`qwtplot3d-0.2.7+svn191/examples/common.pro0000644000203200020320000000132510663257611017700 0ustar gudjongudjonTEMPLATE = app CONFIG += qt warn_on thread debug UI_DIR = tmp MOC_DIR = tmp OBJECTS_DIR = tmp INCLUDEPATH += ../../include DEPENDPATH = $$INCLUDEPATH DESTDIR = ../bin unix:LIBS += -lqwtplot3d -L../../lib linux-g++:QMAKE_CXXFLAGS += -fno-exceptions win32{ LIBS += ../../lib/qwtplot3d.lib TEMPLATE = vcapp DEFINES += QT_DLL QWT3D_DLL RC_FILE = ../icon.rc contains (CONFIG, debug) { QMAKE_LFLAGS += /NODEFAULTLIB:msvcrt DESTDIR = ../bin/debug } !contains (CONFIG, release) { DESTDIR = ../bin/release } } MYVERSION = $$[QMAKE_VERSION] ISQT4 = $$find(MYVERSION, ^[2-9]) !isEmpty( ISQT4 ) { RESOURCES = ../images.qrc QT += opengl } isEmpty( ISQT4 ) { CONFIG += opengl } qwtplot3d-0.2.7+svn191/examples/nodata.png0000644000203200020320000000147010663257611017643 0ustar gudjongudjonPNG  IHDRtIME, pHYs B4gAMA aIDATxڭUKZqZ+fum/sKk{(|ʇYbł|0b_&!у0X>QdAZv>߻tԶ~^*3 gJ2B#"訣=*L;?-`5|Pdf:==2KkkdY6e,3|AMhxx1c 5553L?y@&lŒ;<5 9@oNK- (z -I'` -Ŝa: \x !n˧=j9E\ۅރ A_P/822 U0#-jiFc齺Ab.Ϡ*ԙohE{WªWG_) i3IENDB`qwtplot3d-0.2.7+svn191/examples/dsp.bat0000644000203200020320000000031510663257611017142 0ustar gudjongudjonREM set QMAKESPEC=win32-msvc.net cd mesh2 qmake mesh2.pro cd ../simpleplot qmake simpleplot.pro cd ../autoswitch qmake autoswitch.pro cd ../enrichments qmake enrichments.pro cd ../axes qmake axes.pro cd ..qwtplot3d-0.2.7+svn191/examples/icon.gif0000644000203200020320000000222010663257611017300 0ustar gudjongudjonGIF89a RZZ!c)k)k1s1s9{9{BBJZBJRRZZccksB{ks{BBs{{{ƄƌƜBƭΌΔΜBέ{֥֔֜Bֵ{ֵޜޥ޵9{Ƅ9BB{Ƅ9B΄{޽Bքބ!P, H*\ȰÇ(# IG9|1DCD"ITL2&1)e.&9{0aGN$>T91 rjqO $PY#5^ !,Xp#&?H8# `{7i8caPhb0|(aRFЃ;=|A 8  8pg Fl#@=TMwn+ps &PPF#h#8P / P= | 8,QP0   -\!B ` ~(PnP 7(`X *E 1 8(S@;qwtplot3d-0.2.7+svn191/examples/normals.png0000644000203200020320000000250010663257611020043 0ustar gudjongudjonPNG  IHDRtIME7iT pHYs B4gAMA aIDATxڭ{LSwϽB(*Aރl52Y1f:'dٲ0njcF Y@B&# l$F 3* ɲ?K>;ߞy1V@a&F?='k/&33SvoG<'wbO\PT*wq{K@JvbH,FP$РFOOh(ʆ{JY'8rU$q!"j$\ZQ^gg/JCbIENDB`qwtplot3d-0.2.7+svn191/examples/filledmesh.png0000644000203200020320000000162610663257611020514 0ustar gudjongudjonPNG  IHDRtIME 6u/}*o2#B !( 6ls'?{؟.Q8;M&Ӣlim?Rs8rT,~? N weĥUY, J!,Ue,#h|f3 Vhw%eYi$ݰ$(Um qoIyLfI~~ڙn }S=R,u0N'󨾾ޢ:һEST w灎Fj0@LQ(k$IHyuAKS k9ՒK>#(߯uQEw2&tq<U?vkz Eط%2jiꪦ0eJt&(ݑO<^NrQ©C<\H>䤦S*Biq1$(G<02?A @IFaAjSTS. ^BO}‚$m9I._z82^}ӾE>˃>H$ Mܶ뱘Z[`_ˁ@@ΌFL o@{{7(JA2rhhH=2>>~ף!r 6|0E e4g?gdHqIENDB`qwtplot3d-0.2.7+svn191/examples/gridfr.png0000644000203200020320000000171110663257611017650 0ustar gudjongudjonPNG  IHDR*tEXtCreation TimeSo 9 Mrz 2003 17:51:17 +0100WbtIME I{M pHYs B4gAMA a"IDATxڍTALQ-*TS" ( ŠUWb0*\>.  #PPPPP; GG/ -PPPPPPPP3 GG*%%!2CPPPPPPPPPPP3 GMGGF>5/7AEPPPPPPPPPPPPPPP3 GMGF%!PPPPPPPPPPPPPPPPPPPPP G5PPPPPPPPPPPPPPPPPPPPPP>G%'PPPPPPPPPPPPPPPPPPPPPPI>5!PPPPPPPPPPPPPPPPPPPPPPPH>*!,PPPPPPPPPPPPPPPPPPPPPPP=4%! ;PPPPPPPPPPPPPPPPPPPPPPK5.%! "PPPPPPPPPPPPPPPPPPPPPPPI5*%! CPPPPPPPPPPPPPPPPPPPPPPPI/)%! "PPPPPPPPPPPPPPPPPPPPPPPP8/)%! PPPPPPPPPPPPPPPPPPPPPPPPP/*%%! CPPPPPPPPPPPPPPPPPPPPPPPPP8*%$!+PPPPPPPPPPPPPPPPPPPPPPPPPPA*%$+PPPPPPPPPPPPPPPPPPPPPPPPPPPP*%:PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP??qwtplot3d-0.2.7+svn191/examples/examples.sln0000644000203200020320000000522610663257611020226 0ustar gudjongudjonMicrosoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "autoswitch", "autoswitch\autoswitch.vcproj", "{C925FD16-FB8D-3C0C-A955-78E37532F05B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "axes", "axes\axes.vcproj", "{9DBB316E-B662-37E5-81FA-F07D1AD5DBF3}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "enrichments", "enrichments\enrichments.vcproj", "{DE9FA224-88EA-3A55-B709-A679DE8B943D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mesh2", "mesh2\mesh2.vcproj", "{8001AE3F-B159-3472-A7B5-E866065C22AE}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qwtplot3d", "..\qwtplot3d.vcproj", "{FCF9D3F3-79A6-3A08-92BE-6DAE29ADC6A5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simpleplot", "simpleplot\simpleplot.vcproj", "{A81FCC17-CCAB-3CEC-9A30-C8F9EDD6F0D3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C925FD16-FB8D-3C0C-A955-78E37532F05B}.Debug|Win32.ActiveCfg = Debug|Win32 {C925FD16-FB8D-3C0C-A955-78E37532F05B}.Debug|Win32.Build.0 = Debug|Win32 {C925FD16-FB8D-3C0C-A955-78E37532F05B}.Release|Win32.ActiveCfg = Release|Win32 {9DBB316E-B662-37E5-81FA-F07D1AD5DBF3}.Debug|Win32.ActiveCfg = Debug|Win32 {9DBB316E-B662-37E5-81FA-F07D1AD5DBF3}.Debug|Win32.Build.0 = Debug|Win32 {9DBB316E-B662-37E5-81FA-F07D1AD5DBF3}.Release|Win32.ActiveCfg = Release|Win32 {DE9FA224-88EA-3A55-B709-A679DE8B943D}.Debug|Win32.ActiveCfg = Debug|Win32 {DE9FA224-88EA-3A55-B709-A679DE8B943D}.Debug|Win32.Build.0 = Debug|Win32 {DE9FA224-88EA-3A55-B709-A679DE8B943D}.Release|Win32.ActiveCfg = Release|Win32 {8001AE3F-B159-3472-A7B5-E866065C22AE}.Debug|Win32.ActiveCfg = Debug|Win32 {8001AE3F-B159-3472-A7B5-E866065C22AE}.Debug|Win32.Build.0 = Debug|Win32 {8001AE3F-B159-3472-A7B5-E866065C22AE}.Release|Win32.ActiveCfg = Release|Win32 {FCF9D3F3-79A6-3A08-92BE-6DAE29ADC6A5}.Debug|Win32.ActiveCfg = Debug|Win32 {FCF9D3F3-79A6-3A08-92BE-6DAE29ADC6A5}.Debug|Win32.Build.0 = Debug|Win32 {FCF9D3F3-79A6-3A08-92BE-6DAE29ADC6A5}.Release|Win32.ActiveCfg = Release|Win32 {A81FCC17-CCAB-3CEC-9A30-C8F9EDD6F0D3}.Debug|Win32.ActiveCfg = Debug|Win32 {A81FCC17-CCAB-3CEC-9A30-C8F9EDD6F0D3}.Debug|Win32.Build.0 = Debug|Win32 {A81FCC17-CCAB-3CEC-9A30-C8F9EDD6F0D3}.Release|Win32.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal qwtplot3d-0.2.7+svn191/examples/gridb.png0000644000203200020320000000175110663257611017466 0ustar gudjongudjonPNG  IHDR*tEXtCreation TimeSo 9 Mrz 2003 17:51:17 +0100WbtIME 2v- pHYs B4gAMA aBIDATxڭT_HSQ?]7TꚑIѿA#1 I+( "?=COFCA" *Ө^be,M67wwκnk҂||9Cws,xg0"%1h32pA=lޡ]$[/LΞNܐ@~n)|^'#SopjjHpi^Gjs_1GS`㣜th1 'B6yr`\ά")xg^[ceLAʃVqz!+ů**C}a"&H9ESU$)1G$%aFa t3MMB&柠sϊn΄\c<0y :F*YH {eMVPspQ Y@-l% .t%U bHsk봭}pڢ(Bla\t3EgTך# !b3j;%)BSFfnb%kZr$6 HNE\Ij 1VLΕPVӧXUBt+9#,@/ಈN÷ޛ1^o1y>㾷mXlZ'jYq-vߩ.cDc$u]‹uQvu(p2. ^xaw˞ x7-b\|GtX,_6n7"_CѮ>@ =IENDB`qwtplot3d-0.2.7+svn191/examples/gridc.png0000644000203200020320000000146410663257611017470 0ustar gudjongudjonPNG  IHDR*tEXtCreation TimeSo 9 Mrz 2003 17:51:17 +0100WbtIME2k pHYs B4gAMA aIDATxcd2 qa14Ƣn3g D#/Le~28YQ@ S/3 p.P o俼 Q{ HkM}'dkS`u(?cwFԈg"̿gT25I  @+/)4 3d<*Znm#Oz`dEDKe@x@F v\ M>=EE@T 47Wa8I10F X $`Y/Ȓ?Y^19OYdvHpJ1̒l@ם /0dMq3>KMgad ).Iȥ ".}Ri9P"\SFa NKn%P!&,)pu u,e7*C`! mygmj@|>B"}J"*P@ BX.,fV!IENDB`qwtplot3d-0.2.7+svn191/examples/savecontent.png0000644000203200020320000000104610663257611020725 0ustar gudjongudjonPNG  IHDRZ*tEXtCreation TimeSa 3 Mai 2003 11:33:33 +0100F[tIME " ʝp pHYsodgAMA aIDATxڽ1n0 tX;0!1΂G@b20tgacЙ"bbǁNiS,+֟O/~T v*t8hD3Ͻt)1nwł!Hn.jb9'a(fc=B۶ p$ٌt: >8<\.R4J?\ hRw{/QƒZlֿ8n<j !b$rV|H*8sFuRȑ'!rtzPDo9LU3(TDͪ|vluj^!3r"1$vyv+|vHl$IENDB`qwtplot3d-0.2.7+svn191/examples/examples.pro0000644000203200020320000000013610663257611020225 0ustar gudjongudjonTEMPLATE = subdirs SUBDIRS = \ simpleplot \ autoswitch \ enrichments \ axes \ mesh2 qwtplot3d-0.2.7+svn191/examples/gridf.png0000644000203200020320000000157210663257611017473 0ustar gudjongudjonPNG  IHDR*tEXtCreation TimeSo 9 Mrz 2003 17:51:17 +0100WbtIMEՓR pHYs B4gAMA aIDATxՔ]HQgfgwgu5,aEt10 BBܴ좛~H‚ 4P(B3-ǔRuvwz?فmpl;g9y9,Mm,jPF̨@& +ObhHnBt蟭#;E9nY{nk~gpj>2bYA{*N-y=6Nqʅ*㑃8H̒qp)F5ُ6pJIROMٯX4 &_>ECWn}+i.^k|mNsӢifS]8a1e>5dfY8q>])tn῜vVBlŠ M<]`4>)8}bFV99 V.C `hgD&hn֘ң-8Ӵղ։ssNX Azi;V\9Q{(z_쩺pmTdoO=ĥO:?e$bos9C-yNg$C?"y\uSܪڔRS+zITcN'#.6~Oe7cLnθ-^LIl;ig>WBǔdӞқggԿ~gǸ@n?OOG xIENDB`qwtplot3d-0.2.7+svn191/qwtplot3d.pro0000644000203200020320000000531510663257611016536 0ustar gudjongudjon# pro file for building the makefile for qwtplot3d # TARGET = qwtplot3d TEMPLATE = lib CONFIG += qt warn_on opengl thread zlib debug MOC_DIR = tmp OBJECTS_DIR = tmp INCLUDEPATH = include DEPENDPATH = include src DESTDIR = lib #DESTDIR = ../../../lib QT += opengl win32:TEMPLATE = vclib win32:CONFIG += dll exceptions win32:dll:DEFINES += QT_DLL QWT3D_DLL QWT3D_MAKEDLL win32:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_STL # Comment the next line, if you have zlib on your windows system win32:CONFIG -= zlib linux-g++:TMAKE_CXXFLAGS += -fno-exceptions unix:VERSION = 0.2.7 # Input SOURCES += src/qwt3d_axis.cpp \ src/qwt3d_color.cpp \ src/qwt3d_coordsys.cpp \ src/qwt3d_drawable.cpp \ src/qwt3d_mousekeyboard.cpp \ src/qwt3d_movements.cpp \ src/qwt3d_lighting.cpp \ src/qwt3d_colorlegend.cpp \ src/qwt3d_plot.cpp \ src/qwt3d_label.cpp \ src/qwt3d_types.cpp \ src/qwt3d_enrichment_std.cpp \ src/qwt3d_autoscaler.cpp \ src/qwt3d_io_reader.cpp \ src/qwt3d_io.cpp \ src/qwt3d_scale.cpp SOURCES += src/qwt3d_gridmapping.cpp \ src/qwt3d_parametricsurface.cpp \ src/qwt3d_function.cpp SOURCES += src/qwt3d_surfaceplot.cpp \ src/qwt3d_gridplot.cpp \ src/qwt3d_meshplot.cpp HEADERS += include/qwt3d_color.h \ include/qwt3d_global.h \ include/qwt3d_types.h \ include/qwt3d_axis.h \ include/qwt3d_coordsys.h \ include/qwt3d_drawable.h \ include/qwt3d_helper.h \ include/qwt3d_label.h \ include/qwt3d_openglhelper.h \ include/qwt3d_colorlegend.h \ include/qwt3d_plot.h \ include/qwt3d_enrichment.h \ include/qwt3d_enrichment_std.h \ include/qwt3d_autoscaler.h \ include/qwt3d_autoptr.h \ include/qwt3d_io.h \ include/qwt3d_io_reader.h \ include/qwt3d_scale.h \ include/qwt3d_portability.h HEADERS += include/qwt3d_mapping.h \ include/qwt3d_gridmapping.h \ include/qwt3d_parametricsurface.h \ include/qwt3d_function.h HEADERS += include/qwt3d_surfaceplot.h \ include/qwt3d_volumeplot.h \ include/qwt3d_graphplot.h \ include/qwt3d_multiplot.h # gl2ps support HEADERS+=3rdparty/gl2ps/gl2ps.h \ include/qwt3d_io_gl2ps.h SOURCES+=src/qwt3d_io_gl2ps.cpp \ 3rdparty/gl2ps/gl2ps.c # zlib support for gl2ps zlib { DEFINES += GL2PS_HAVE_ZLIB win32:LIBS += zlib.lib unix:LIBS += -lz }qwtplot3d-0.2.7+svn191/COPYING0000644000203200020320000000165310663257611015107 0ustar gudjongudjon/* QwtPlot3D license -- January 5th, 2005 Copyright (C) 2003-2005 Michael Bieber This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ qwtplot3d-0.2.7+svn191/dsp.bat0000644000203200020320000000006510663257611015326 0ustar gudjongudjonREM set QMAKESPEC=win32-msvc.net qmake qwtplot3d.pro qwtplot3d-0.2.7+svn191/lingua_de.ts0000644000203200020320000000036110663257611016346 0ustar gudjongudjon NativeReader NativeReader::read: cannot open data file "%s"