diff options
146 files changed, 23541 insertions, 0 deletions
diff --git a/lib/tqwtplot3d/3rdparty/gl2ps/COPYING.GL2PS b/lib/tqwtplot3d/3rdparty/gl2ps/COPYING.GL2PS new file mode 100644 index 0000000..1d03143 --- /dev/null +++ b/lib/tqwtplot3d/3rdparty/gl2ps/COPYING.GL2PS @@ -0,0 +1,25 @@ +
+ 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.
diff --git a/lib/tqwtplot3d/3rdparty/gl2ps/COPYING.LGPL b/lib/tqwtplot3d/3rdparty/gl2ps/COPYING.LGPL new file mode 100644 index 0000000..fc84d1c --- /dev/null +++ b/lib/tqwtplot3d/3rdparty/gl2ps/COPYING.LGPL @@ -0,0 +1,482 @@ +
+ 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.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/lib/tqwtplot3d/3rdparty/gl2ps/gl2ps.c b/lib/tqwtplot3d/3rdparty/gl2ps/gl2ps.c new file mode 100644 index 0000000..46d2a15 --- /dev/null +++ b/lib/tqwtplot3d/3rdparty/gl2ps/gl2ps.c @@ -0,0 +1,5986 @@ +/* $Id: gl2ps.c 173 2007-05-20 15:51:51Z krischnamurti $ */
+/*
+ * GL2PS, an OpenGL to PostScript Printing Library
+ * Copyright (C) 1999-2006 Christophe Geuzaine <geuz@geuz.org>
+ *
+ * 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 <mike@easysw.com>
+ * Marc Ume <marc.ume@digitalgraphics.be>
+ * Jean-Francois Remacle <remacle@gce.ucl.ac.be>
+ * Bart Kaptein <B.L.Kaptein@lumc.nl>
+ * Quy Nguyen-Dai <quy@nguyendai.org>
+ * Sam Buss <sbuss@ucsd.edu>
+ * Shane Hill <Shane.Hill@dsto.defence.gov.au>
+ * Romain Boman <r_boman@yahoo.fr>
+ * Rouben Rostamian <rostamian@umbc.edu>
+ * Diego Santa Cruz <Diego.SantaCruz@epfl.ch>
+ * Shahzad Muzaffar <Shahzad.Muzaffar@cern.ch>
+ * Lassi Tuura <lassi.tuura@cern.ch>
+ * Guy Barrand <barrand@lal.in2p3.fr>
+ * Prabhu Ramachandran <prabhu@aero.iitm.ernet.in>
+ * Micha Bieber <bieber@traits.de>
+ * Olivier Couet <couet@mail.cern.ch>
+ * Shai Ayal <shaiay@gmail.com>
+ * Fabian Wenzel <wenzel@tu-harburg.de>
+ * Ian D. Gay <gay@sfu.ca>
+ * Cosmin Truta <cosmin@cs.toronto.edu>
+ * Baiju Devani <b.devani@gmail.com>
+ * Alexander Danilov <danilov@lanl.gov>
+ *
+ * For the latest info about gl2ps, see http://www.geuz.org/gl2ps/.
+ * Please report all bugs and problems to <gl2ps@geuz.org>.
+ */
+
+#include "gl2ps.h"
+
+#include <math.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <time.h>
+#include <float.h>
+
+#if defined(GL2PS_HAVE_ZLIB)
+#include <zlib.h>
+#endif
+
+#if defined(GL2PS_HAVE_LIBPNG)
+#include <png.h>
+#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.5;
+ prim->verts[0].xyz[1] = prim->verts[0].xyz[1] - (int)(node->image->height / 2) + 0.5;
+ 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.30 * dr + 0.59 * dg + 0.11 * 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("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
+ gl2psPrintf("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
+ gl2psPrintf(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
+ " width=\"%dpx\" height=\"%dpx\" viewBox=\"%d %d %d %d\">\n",
+ width, height, x, y, width, height);
+ gl2psPrintf("<title>%s</title>\n", gl2ps->title);
+ gl2psPrintf("<desc>\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("</desc>\n");
+ gl2psPrintf("<defs>\n");
+ gl2psPrintf("</defs>\n");
+
+ if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
+ gl2psSVGGetColorString(gl2ps->bgcolor, col);
+ gl2psPrintf("<polygon fill=\"%s\" points=\"%d,%d %d,%d %d,%d %d,%d\"/>\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("<g>\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("<polygon fill=\"%s\" ", col);
+ if(rgba[0][3] < 1.0F) gl2psPrintf("fill-opacity=\"%g\" ", rgba[0][3]);
+ gl2psPrintf("points=\"%g,%g %g,%g %g,%g\"/>\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.5 * (xyz[0][i] + xyz[1][i]);
+ xyz2[2][i] = 0.5 * (xyz[0][i] + xyz[2][i]);
+ }
+ for(i = 0; i < 4; i++){
+ rgba2[0][i] = rgba[0][i];
+ rgba2[1][i] = 0.5 * (rgba[0][i] + rgba[1][i]);
+ rgba2[2][i] = 0.5 * (rgba[0][i] + rgba[2][i]);
+ }
+ gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
+ for(i = 0; i < 3; i++){
+ xyz2[0][i] = 0.5 * (xyz[0][i] + xyz[1][i]);
+ xyz2[1][i] = xyz[1][i];
+ xyz2[2][i] = 0.5 * (xyz[1][i] + xyz[2][i]);
+ }
+ for(i = 0; i < 4; i++){
+ rgba2[0][i] = 0.5 * (rgba[0][i] + rgba[1][i]);
+ rgba2[1][i] = rgba[1][i];
+ rgba2[2][i] = 0.5 * (rgba[1][i] + rgba[2][i]);
+ }
+ gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
+ for(i = 0; i < 3; i++){
+ xyz2[0][i] = 0.5 * (xyz[0][i] + xyz[2][i]);
+ xyz2[1][i] = xyz[2][i];
+ xyz2[2][i] = 0.5 * (xyz[1][i] + xyz[2][i]);
+ }
+ for(i = 0; i < 4; i++){
+ rgba2[0][i] = 0.5 * (rgba[0][i] + rgba[2][i]);
+ rgba2[1][i] = rgba[2][i];
+ rgba2[2][i] = 0.5 * (rgba[1][i] + rgba[2][i]);
+ }
+ gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
+ for(i = 0; i < 3; i++){
+ xyz2[0][i] = 0.5 * (xyz[0][i] + xyz[1][i]);
+ xyz2[1][i] = 0.5 * (xyz[1][i] + xyz[2][i]);
+ xyz2[2][i] = 0.5 * (xyz[0][i] + xyz[2][i]);
+ }
+ for(i = 0; i < 4; i++){
+ rgba2[0][i] = 0.5 * (rgba[0][i] + rgba[1][i]);
+ rgba2[1][i] = 0.5 * (rgba[1][i] + rgba[2][i]);
+ rgba2[2][i] = 0.5 * (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("<image x=\"%g\" y=\"%g\" width=\"%d\" height=\"%d\"\n",
+ x, y - pixmap->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("<circle fill=\"%s\" ", col);
+ if(rgba[0][3] < 1.0F) gl2psPrintf("fill-opacity=\"%g\" ", rgba[0][3]);
+ gl2psPrintf("cx=\"%g\" cy=\"%g\" r=\"%g\"/>\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("<polyline fill=\"none\" stroke=\"%s\" stroke-width=\"%g\" ",
+ col, prim->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("<text fill=\"%s\" x=\"%g\" y=\"%g\" "
+ "font-size=\"%d\" font-family=\"%s\">%s</text>\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("</g>\n");
+ gl2psPrintf("</svg>\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("<polygon fill=\"%s\" points=\"%d,%d %d,%d %d,%d %d,%d\"/>\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("<clipPath id=\"cp%d%d%d%d\">\n", x, y, w, h);
+ gl2psPrintf(" <polygon points=\"%d,%d %d,%d %d,%d %d,%d\"/>\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("</clipPath>\n");
+ gl2psPrintf("<g clip-path=\"url(#cp%d%d%d%d)\">\n", x, y, w, h);
+}
+
+static GLint gl2psPrintSVGEndViewport(void)
+{
+ GLint res;
+
+ res = gl2psPrintPrimitives();
+ gl2psPrintf("</g>\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";
+}
diff --git a/lib/tqwtplot3d/3rdparty/gl2ps/gl2ps.h b/lib/tqwtplot3d/3rdparty/gl2ps/gl2ps.h new file mode 100644 index 0000000..60b18c2 --- /dev/null +++ b/lib/tqwtplot3d/3rdparty/gl2ps/gl2ps.h @@ -0,0 +1,199 @@ +/* $Id: gl2ps.h 173 2007-05-20 15:51:51Z krischnamurti $ */
+/*
+ * GL2PS, an OpenGL to PostScript Printing Library
+ * Copyright (C) 1999-2006 Christophe Geuzaine <geuz@geuz.org>
+ *
+ * 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 <gl2ps@geuz.org>.
+ */
+
+#ifndef __GL2PS_H__
+#define __GL2PS_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* 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 <windows.h>
+# 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 <OpenGL/gl.h>
+#else
+# include <GL/gl.h>
+#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__ */
diff --git a/lib/tqwtplot3d/COPYING b/lib/tqwtplot3d/COPYING new file mode 100644 index 0000000..abb97f0 --- /dev/null +++ b/lib/tqwtplot3d/COPYING @@ -0,0 +1,23 @@ +/*
+
+ 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.
+
+*/
diff --git a/lib/tqwtplot3d/doc/Doxyfile.doxygen b/lib/tqwtplot3d/doc/Doxyfile.doxygen new file mode 100644 index 0000000..8910fb7 --- /dev/null +++ b/lib/tqwtplot3d/doc/Doxyfile.doxygen @@ -0,0 +1,227 @@ +# Doxyfile 1.4.3
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "QwtPlot3D API"
+PROJECT_NUMBER = 0.2.7
+OUTPUT_DIRECTORY =
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = YES
+BRIEF_MEMBER_DESC = NO
+REPEAT_BRIEF = NO
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = NO
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = YES
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = YES
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = YES
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = YES
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = NO
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = ../src \
+ . \
+ ../include
+FILE_PATTERNS = *.cpp \
+ *.h \
+ *.dox
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS = moc_*
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH = doxygenimages
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 4
+IGNORE_PREFIX = Qwt3D
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = web/doxygen
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET = web/navigation/doxygen.css
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE = qwtplot3d.chm
+HHC_LOCATION = "c:\Programme\HTML Help Workshop\hhc.exe"
+GENERATE_CHI = NO
+BINARY_TOC = YES
+TOC_EXPAND = YES
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = YES
+PAPER_TYPE = a4
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH = V:/cvs/qwtplot3d/include/
+INCLUDE_FILE_PATTERNS = *.h
+PREDEFINED = QWT3D_NOT_FOR_DOXYGEN \
+ QT_VERSION=0x040000
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = NO
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH = V:/graphviz/Graphviz/bin/
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 974
+MAX_DOT_GRAPH_HEIGHT = 10000
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/lib/tqwtplot3d/doc/footer.html b/lib/tqwtplot3d/doc/footer.html new file mode 100644 index 0000000..2fe3584 --- /dev/null +++ b/lib/tqwtplot3d/doc/footer.html @@ -0,0 +1,7 @@ +<hr><address style="align: right;"><small>
+The documentation for the QwtPlot3D API has been created by <a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53>
+</a> $doxygenversion and is hosted at </small> <a href="http://sourceforge.net">
+<img src="http://sourceforge.net/sflogo.php?group_id=78209&type=1" width="88" height="31" border="0" alt="SourceForge.net Logo" /></a></address>
+</body>
+</html>
diff --git a/lib/tqwtplot3d/doc/web/navigation/doxygen.css b/lib/tqwtplot3d/doc/web/navigation/doxygen.css new file mode 100644 index 0000000..13034f5 --- /dev/null +++ b/lib/tqwtplot3d/doc/web/navigation/doxygen.css @@ -0,0 +1,176 @@ +BODY {
+ 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;
+}
diff --git a/lib/tqwtplot3d/doc/web/navigation/doxygen.png b/lib/tqwtplot3d/doc/web/navigation/doxygen.png Binary files differnew file mode 100644 index 0000000..96ae72c --- /dev/null +++ b/lib/tqwtplot3d/doc/web/navigation/doxygen.png diff --git a/lib/tqwtplot3d/doc/web/navigation/menu.css b/lib/tqwtplot3d/doc/web/navigation/menu.css new file mode 100644 index 0000000..cdf9e67 --- /dev/null +++ b/lib/tqwtplot3d/doc/web/navigation/menu.css @@ -0,0 +1,12 @@ +BODY{ 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}
diff --git a/lib/tqwtplot3d/doc/web/navigation/sflogo.png b/lib/tqwtplot3d/doc/web/navigation/sflogo.png Binary files differnew file mode 100644 index 0000000..b2a9e99 --- /dev/null +++ b/lib/tqwtplot3d/doc/web/navigation/sflogo.png diff --git a/lib/tqwtplot3d/dsp.bat b/lib/tqwtplot3d/dsp.bat new file mode 100644 index 0000000..2cbda93 --- /dev/null +++ b/lib/tqwtplot3d/dsp.bat @@ -0,0 +1,2 @@ +REM set QMAKESPEC=win32-msvc.net
+qmake qwtplot3d.pro
\ No newline at end of file diff --git a/lib/tqwtplot3d/examples/autoswitch/autoswitch.cpp b/lib/tqwtplot3d/examples/autoswitch/autoswitch.cpp new file mode 100644 index 0000000..3efbbc8 --- /dev/null +++ b/lib/tqwtplot3d/examples/autoswitch/autoswitch.cpp @@ -0,0 +1,102 @@ +#include <qapplication.h>
+#include <qsplitter.h>
+#include <qtimer.h>
+
+#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();
+}
diff --git a/lib/tqwtplot3d/examples/autoswitch/autoswitch.h b/lib/tqwtplot3d/examples/autoswitch/autoswitch.h new file mode 100644 index 0000000..f4a6745 --- /dev/null +++ b/lib/tqwtplot3d/examples/autoswitch/autoswitch.h @@ -0,0 +1,58 @@ +#ifndef AUTOSWITCH_H__
+#define AUTOSWITCH_H__
+
+#include <qtimer.h>
+#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
diff --git a/lib/tqwtplot3d/examples/autoswitch/autoswitch.pro b/lib/tqwtplot3d/examples/autoswitch/autoswitch.pro new file mode 100644 index 0000000..38487ee --- /dev/null +++ b/lib/tqwtplot3d/examples/autoswitch/autoswitch.pro @@ -0,0 +1,4 @@ +include( ../common.pro )
+
+SOURCES = autoswitch.cpp
+HEADERS = autoswitch.h
diff --git a/lib/tqwtplot3d/examples/axes/axes.pro b/lib/tqwtplot3d/examples/axes/axes.pro new file mode 100644 index 0000000..185fadb --- /dev/null +++ b/lib/tqwtplot3d/examples/axes/axes.pro @@ -0,0 +1,15 @@ +include( ../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
+}
+
diff --git a/lib/tqwtplot3d/examples/axes/src/axes.h b/lib/tqwtplot3d/examples/axes/src/axes.h new file mode 100644 index 0000000..675ae8b --- /dev/null +++ b/lib/tqwtplot3d/examples/axes/src/axes.h @@ -0,0 +1,75 @@ +#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<majors_p.size() && idx < 26)
+ return (uc_) ? QString(QChar('A'+idx)) : QString(QChar('a'+idx));
+ return QString("-");
+ }
+private:
+ bool uc_;
+};
+
+class Imaginary : public LinearScale
+{
+public:
+ Scale* clone() const {return new Imaginary;}
+ QString ticLabel(unsigned int idx) const
+ {
+ if (idx<majors_p.size())
+ {
+ double val = majors_p[idx];
+ if (val)
+ return QString::number(val) + "*i";
+ return QString::number(val);
+ }
+ return QString("");
+ }
+};
+
+class TimeItems : public LinearScale
+{
+public:
+ Scale* clone() const {return new TimeItems;}
+ QString ticLabel(unsigned int idx) const
+ {
+ if (idx<majors_p.size())
+ {
+ QTime t = QTime::currentTime();
+ int h = t.hour();
+ int m = t.minute();
+ if (m+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 */
diff --git a/lib/tqwtplot3d/examples/axes/src/axesmainwindow.cpp b/lib/tqwtplot3d/examples/axes/src/axesmainwindow.cpp new file mode 100644 index 0000000..d3086bc --- /dev/null +++ b/lib/tqwtplot3d/examples/axes/src/axesmainwindow.cpp @@ -0,0 +1,245 @@ +#include <qsplitter.h>
+#include <qlayout.h>
+#include <qcombobox.h>
+#include <qaction.h>
+#include <qslider.h>
+#include <qcheckbox.h>
+#include <qmenubar.h>
+#include <qdatetime.h>
+
+#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();
+}
+
diff --git a/lib/tqwtplot3d/examples/axes/src/axesmainwindow.h b/lib/tqwtplot3d/examples/axes/src/axesmainwindow.h new file mode 100644 index 0000000..fd99d0d --- /dev/null +++ b/lib/tqwtplot3d/examples/axes/src/axesmainwindow.h @@ -0,0 +1,64 @@ +#include <qmainwindow.h>
+
+#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;
+};
diff --git a/lib/tqwtplot3d/examples/axes/src/axesmainwindowbase.ui b/lib/tqwtplot3d/examples/axes/src/axesmainwindowbase.ui new file mode 100644 index 0000000..92bab56 --- /dev/null +++ b/lib/tqwtplot3d/examples/axes/src/axesmainwindowbase.ui @@ -0,0 +1,243 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>AxesMainWindowBase</class>
+<widget class="QMainWindow">
+ <property name="name">
+ <cstring>AxesMainWindowBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>826</width>
+ <height>608</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>print</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QFrame" row="0" column="0">
+ <property name="name">
+ <cstring>frame</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Number gap</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>numbergapslider</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maxValue">
+ <number>10</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Above</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Label gap</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>labelgapslider</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maxValue">
+ <number>10</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Above</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>smoothBox</cstring>
+ </property>
+ <property name="text">
+ <string>Smooth Lines</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="2" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>ticNumeberLabel</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Tics</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QSlider" row="1" column="0">
+ <property name="name">
+ <cstring>ticLengthSlider</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>10</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Tic Length (rel.)</string>
+ </property>
+ </widget>
+ <widget class="QSlider" row="1" column="1">
+ <property name="name">
+ <cstring>ticNumberSlider</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maxValue">
+ <number>25</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Change Tic Number (available only for letter example)</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<menubar>
+ <property name="name">
+ <cstring>menubar</cstring>
+ </property>
+ <item text="Items" name="Items">
+ </item>
+</menubar>
+<toolbars>
+</toolbars>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/lib/tqwtplot3d/examples/axes/src/axesmainwindowbase4.ui b/lib/tqwtplot3d/examples/axes/src/axesmainwindowbase4.ui new file mode 100644 index 0000000..1e4a0b5 --- /dev/null +++ b/lib/tqwtplot3d/examples/axes/src/axesmainwindowbase4.ui @@ -0,0 +1,295 @@ +<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>694</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="frame" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_4" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Preferred</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QSlider" name="ticLengthSlider" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>10</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="invertedAppearance" >
+ <bool>true</bool>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="ticNumberSlider" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum" >
+ <number>25</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="invertedAppearance" >
+ <bool>true</bool>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QWidget" name="widget_2" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="numbergapslider" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum" >
+ <number>10</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="labelgapslider" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum" >
+ <number>10</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="smoothBox" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Smooth Lines</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ <widget class="QWidget" name="widget" >
+ <property name="geometry" >
+ <rect>
+ <x>590</x>
+ <y>10</y>
+ <width>61</width>
+ <height>421</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/lib/tqwtplot3d/examples/axes/src/main.cpp b/lib/tqwtplot3d/examples/axes/src/main.cpp new file mode 100644 index 0000000..518faf6 --- /dev/null +++ b/lib/tqwtplot3d/examples/axes/src/main.cpp @@ -0,0 +1,31 @@ +/********************************************************************
+ created: 2003/09/10
+ filename: main.cpp
+
+ author: Micha Bieber
+*********************************************************************/
+
+#include <qapplication.h>
+#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();
+}
diff --git a/lib/tqwtplot3d/examples/box.png b/lib/tqwtplot3d/examples/box.png Binary files differnew file mode 100644 index 0000000..1aa8c08 --- /dev/null +++ b/lib/tqwtplot3d/examples/box.png diff --git a/lib/tqwtplot3d/examples/common.pro b/lib/tqwtplot3d/examples/common.pro new file mode 100644 index 0000000..2b7fb83 --- /dev/null +++ b/lib/tqwtplot3d/examples/common.pro @@ -0,0 +1,34 @@ +TEMPLATE = 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
+ }
+
+}
+
+MYVERSION = $$[QMAKE_VERSION]
+ISQT4 = $$find(MYVERSION, ^[2-9])
+
+!isEmpty( ISQT4 ) {
+RESOURCES = ../images.qrc
+QT += opengl
+}
+
+isEmpty( ISQT4 ) {
+CONFIG += opengl
+}
diff --git a/lib/tqwtplot3d/examples/dsp.bat b/lib/tqwtplot3d/examples/dsp.bat new file mode 100644 index 0000000..e0ff0db --- /dev/null +++ b/lib/tqwtplot3d/examples/dsp.bat @@ -0,0 +1,12 @@ +REM 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 ..
\ No newline at end of file diff --git a/lib/tqwtplot3d/examples/enrichments/enrichments.pro b/lib/tqwtplot3d/examples/enrichments/enrichments.pro new file mode 100644 index 0000000..fffbbfd --- /dev/null +++ b/lib/tqwtplot3d/examples/enrichments/enrichments.pro @@ -0,0 +1,16 @@ +include( ../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
+}
+
diff --git a/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindow.cpp b/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindow.cpp new file mode 100644 index 0000000..05bc6f2 --- /dev/null +++ b/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindow.cpp @@ -0,0 +1,147 @@ +#include <qlayout.h>
+#include <qslider.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+
+
+#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();
+}
diff --git a/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindow.h b/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindow.h new file mode 100644 index 0000000..68b97b0 --- /dev/null +++ b/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindow.h @@ -0,0 +1,57 @@ +#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_;
+
+};
+
+
diff --git a/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindowbase.ui b/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindowbase.ui new file mode 100644 index 0000000..b6ff9fc --- /dev/null +++ b/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindowbase.ui @@ -0,0 +1,215 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>EnrichmentMainWindowBase</class>
+<widget class="QMainWindow">
+ <property name="name">
+ <cstring>EnrichmentMainWindowBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>843</width>
+ <height>702</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>print</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>Layout11</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>Layout10</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Width</string>
+ </property>
+ </widget>
+ <widget class="QSlider" row="0" column="1">
+ <property name="name">
+ <cstring>widthSlider</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="minValue">
+ <number>10</number>
+ </property>
+ <property name="maxValue">
+ <number>200</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Relative psition of slicing plane</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>Layout9</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Layout8</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QSlider" row="1" column="0">
+ <property name="name">
+ <cstring>levelSlider</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>40</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>10</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Changes the level, where marker are shown</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Level</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QFrame" row="0" column="0">
+ <property name="name">
+ <cstring>frame</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<menubar>
+ <property name="name">
+ <cstring>menubar</cstring>
+ </property>
+</menubar>
+<toolbars>
+</toolbars>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindowbase4.ui b/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindowbase4.ui new file mode 100644 index 0000000..0ed32e3 --- /dev/null +++ b/lib/tqwtplot3d/examples/enrichments/src/enrichmentmainwindowbase4.ui @@ -0,0 +1,167 @@ +<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget" >
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="frame" >
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="levelSlider" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>10</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="invertedAppearance" >
+ <bool>true</bool>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ <property name="tickInterval" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="widthSlider" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="minimum" >
+ <number>2</number>
+ </property>
+ <property name="maximum" >
+ <number>200</number>
+ </property>
+ <property name="value" >
+ <number>20</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/lib/tqwtplot3d/examples/enrichments/src/enrichments.cpp b/lib/tqwtplot3d/examples/enrichments/src/enrichments.cpp new file mode 100644 index 0000000..7780412 --- /dev/null +++ b/lib/tqwtplot3d/examples/enrichments/src/enrichments.cpp @@ -0,0 +1,150 @@ +#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();
+}
diff --git a/lib/tqwtplot3d/examples/enrichments/src/enrichments.h b/lib/tqwtplot3d/examples/enrichments/src/enrichments.h new file mode 100644 index 0000000..2a47968 --- /dev/null +++ b/lib/tqwtplot3d/examples/enrichments/src/enrichments.h @@ -0,0 +1,31 @@ +#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
diff --git a/lib/tqwtplot3d/examples/enrichments/src/main.cpp b/lib/tqwtplot3d/examples/enrichments/src/main.cpp new file mode 100644 index 0000000..a590d9d --- /dev/null +++ b/lib/tqwtplot3d/examples/enrichments/src/main.cpp @@ -0,0 +1,30 @@ +/********************************************************************
+ created: 2003/09/10
+ filename: main.cpp
+
+ author: Micha Bieber
+*********************************************************************/
+
+#include <qapplication.h>
+#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();
+}
diff --git a/lib/tqwtplot3d/examples/examples.pro b/lib/tqwtplot3d/examples/examples.pro new file mode 100644 index 0000000..1d2a507 --- /dev/null +++ b/lib/tqwtplot3d/examples/examples.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs
+SUBDIRS = \
+ simpleplot \
+ autoswitch \
+ enrichments \
+ axes \
+ mesh2
+
+
+
diff --git a/lib/tqwtplot3d/examples/examples.sln b/lib/tqwtplot3d/examples/examples.sln new file mode 100644 index 0000000..68980b6 --- /dev/null +++ b/lib/tqwtplot3d/examples/examples.sln @@ -0,0 +1,43 @@ +Microsoft 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
diff --git a/lib/tqwtplot3d/examples/filecell.png b/lib/tqwtplot3d/examples/filecell.png Binary files differnew file mode 100644 index 0000000..c2da1fe --- /dev/null +++ b/lib/tqwtplot3d/examples/filecell.png diff --git a/lib/tqwtplot3d/examples/fileopen.png b/lib/tqwtplot3d/examples/fileopen.png Binary files differnew file mode 100644 index 0000000..85dab43 --- /dev/null +++ b/lib/tqwtplot3d/examples/fileopen.png diff --git a/lib/tqwtplot3d/examples/filledmesh.png b/lib/tqwtplot3d/examples/filledmesh.png Binary files differnew file mode 100644 index 0000000..45f0ebd --- /dev/null +++ b/lib/tqwtplot3d/examples/filledmesh.png diff --git a/lib/tqwtplot3d/examples/floordata.png b/lib/tqwtplot3d/examples/floordata.png Binary files differnew file mode 100644 index 0000000..e577276 --- /dev/null +++ b/lib/tqwtplot3d/examples/floordata.png diff --git a/lib/tqwtplot3d/examples/floorempty.png b/lib/tqwtplot3d/examples/floorempty.png Binary files differnew file mode 100644 index 0000000..83d5fd7 --- /dev/null +++ b/lib/tqwtplot3d/examples/floorempty.png diff --git a/lib/tqwtplot3d/examples/flooriso.png b/lib/tqwtplot3d/examples/flooriso.png Binary files differnew file mode 100644 index 0000000..b3b03fd --- /dev/null +++ b/lib/tqwtplot3d/examples/flooriso.png diff --git a/lib/tqwtplot3d/examples/floormesh.png b/lib/tqwtplot3d/examples/floormesh.png Binary files differnew file mode 100644 index 0000000..51e7125 --- /dev/null +++ b/lib/tqwtplot3d/examples/floormesh.png diff --git a/lib/tqwtplot3d/examples/frame.png b/lib/tqwtplot3d/examples/frame.png Binary files differnew file mode 100644 index 0000000..9d1a388 --- /dev/null +++ b/lib/tqwtplot3d/examples/frame.png diff --git a/lib/tqwtplot3d/examples/grid.png b/lib/tqwtplot3d/examples/grid.png Binary files differnew file mode 100644 index 0000000..0745d21 --- /dev/null +++ b/lib/tqwtplot3d/examples/grid.png diff --git a/lib/tqwtplot3d/examples/gridb.png b/lib/tqwtplot3d/examples/gridb.png Binary files differnew file mode 100644 index 0000000..658df52 --- /dev/null +++ b/lib/tqwtplot3d/examples/gridb.png diff --git a/lib/tqwtplot3d/examples/gridc.png b/lib/tqwtplot3d/examples/gridc.png Binary files differnew file mode 100644 index 0000000..37330a3 --- /dev/null +++ b/lib/tqwtplot3d/examples/gridc.png diff --git a/lib/tqwtplot3d/examples/gridf.png b/lib/tqwtplot3d/examples/gridf.png Binary files differnew file mode 100644 index 0000000..f4066e0 --- /dev/null +++ b/lib/tqwtplot3d/examples/gridf.png diff --git a/lib/tqwtplot3d/examples/gridfr.png b/lib/tqwtplot3d/examples/gridfr.png Binary files differnew file mode 100644 index 0000000..c8e8e47 --- /dev/null +++ b/lib/tqwtplot3d/examples/gridfr.png diff --git a/lib/tqwtplot3d/examples/gridl.png b/lib/tqwtplot3d/examples/gridl.png Binary files differnew file mode 100644 index 0000000..02a6a01 --- /dev/null +++ b/lib/tqwtplot3d/examples/gridl.png diff --git a/lib/tqwtplot3d/examples/gridr.png b/lib/tqwtplot3d/examples/gridr.png Binary files differnew file mode 100644 index 0000000..addaebc --- /dev/null +++ b/lib/tqwtplot3d/examples/gridr.png diff --git a/lib/tqwtplot3d/examples/hiddenline.png b/lib/tqwtplot3d/examples/hiddenline.png Binary files differnew file mode 100644 index 0000000..cb9ea63 --- /dev/null +++ b/lib/tqwtplot3d/examples/hiddenline.png diff --git a/lib/tqwtplot3d/examples/icon.gif b/lib/tqwtplot3d/examples/icon.gif Binary files differnew file mode 100644 index 0000000..f59b1ab --- /dev/null +++ b/lib/tqwtplot3d/examples/icon.gif diff --git a/lib/tqwtplot3d/examples/icon.ico b/lib/tqwtplot3d/examples/icon.ico Binary files differnew file mode 100644 index 0000000..f9f5da1 --- /dev/null +++ b/lib/tqwtplot3d/examples/icon.ico diff --git a/lib/tqwtplot3d/examples/icon.png b/lib/tqwtplot3d/examples/icon.png Binary files differnew file mode 100644 index 0000000..c30a5d7 --- /dev/null +++ b/lib/tqwtplot3d/examples/icon.png diff --git a/lib/tqwtplot3d/examples/icon.rc b/lib/tqwtplot3d/examples/icon.rc new file mode 100644 index 0000000..bb10963 --- /dev/null +++ b/lib/tqwtplot3d/examples/icon.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "icon.ico"
\ No newline at end of file diff --git a/lib/tqwtplot3d/examples/images.qrc b/lib/tqwtplot3d/examples/images.qrc new file mode 100644 index 0000000..d7e24d9 --- /dev/null +++ b/lib/tqwtplot3d/examples/images.qrc @@ -0,0 +1,31 @@ +<RCC> + <qresource prefix="/images" > + <file>box.png</file> + <file>filecell.png</file> + <file>fileopen.png</file> + <file>filledmesh.png</file> + <file>floordata.png</file> + <file>floorempty.png</file> + <file>flooriso.png</file> + <file>floormesh.png</file> + <file>frame.png</file> + <file>grid.png</file> + <file>gridb.png</file> + <file>gridc.png</file> + <file>gridf.png</file> + <file>gridfr.png</file> + <file>gridl.png</file> + <file>gridr.png</file> + <file>hiddenline.png</file> + <file>icon.png</file> + <file>movie.png</file> + <file>nodata.png</file> + <file>none.png</file> + <file>normals.png</file> + <file>polygon.png</file> + <file>qwtplot.png</file> + <file>savecontent.png</file> + <file>scattered.png</file> + <file>wireframe.png</file> + </qresource> +</RCC> diff --git a/lib/tqwtplot3d/examples/mesh2/mesh2.pro b/lib/tqwtplot3d/examples/mesh2/mesh2.pro new file mode 100644 index 0000000..8f345a5 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/mesh2.pro @@ -0,0 +1,25 @@ +include( ../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
+}
+
diff --git a/lib/tqwtplot3d/examples/mesh2/src/colormapreader.cpp b/lib/tqwtplot3d/examples/mesh2/src/colormapreader.cpp new file mode 100644 index 0000000..90f7d0c --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/colormapreader.cpp @@ -0,0 +1,81 @@ +#include <fstream>
+
+#include <qfileinfo.h>
+#include <qfiledialog.h>
+#include <qlayout.h>
+#include <qpainter.h>
+
+#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
diff --git a/lib/tqwtplot3d/examples/mesh2/src/colormapreader.h b/lib/tqwtplot3d/examples/mesh2/src/colormapreader.h new file mode 100644 index 0000000..3322846 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/colormapreader.h @@ -0,0 +1,28 @@ +#ifndef __colormapreader_2003_06_08_13_23__
+#define __colormapreader_2003_06_08_13_23__
+
+#include <qlabel.h>
+#include <qframe.h>
+#include <qpixmap.h>
+
+#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
diff --git a/lib/tqwtplot3d/examples/mesh2/src/designerworkaround.cpp b/lib/tqwtplot3d/examples/mesh2/src/designerworkaround.cpp new file mode 100644 index 0000000..433a317 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/designerworkaround.cpp @@ -0,0 +1,146 @@ +#include "designerworkaround.h"
+
+namespace{
+ QString tr(const char* val)
+ {
+ return QObject::tr(val);
+ }
+
+ void setCheckable(QActionGroup* ag)
+ {
+ QList<QAction*> tmplist = ag->actions();
+ for (QList<QAction*>::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()));
+}
diff --git a/lib/tqwtplot3d/examples/mesh2/src/designerworkaround.h b/lib/tqwtplot3d/examples/mesh2/src/designerworkaround.h new file mode 100644 index 0000000..d57418a --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/designerworkaround.h @@ -0,0 +1,76 @@ +#ifndef designerworkaround_h__2005_07_10_10_46_begin_guarded_code
+#define designerworkaround_h__2005_07_10_10_46_begin_guarded_code
+
+#include <QtGui/QMenu>
+#include <QtGui/QToolBar>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QMainWindow>
+#include <QtGui/QComboBox>
+#include <QtGui/QMenuBar>
+
+
+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
diff --git a/lib/tqwtplot3d/examples/mesh2/src/femreader.h b/lib/tqwtplot3d/examples/mesh2/src/femreader.h new file mode 100644 index 0000000..374a181 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/femreader.h @@ -0,0 +1,83 @@ +#ifndef femreader_h__2004_03_07_14_03_begin_guarded_code
+#define femreader_h__2004_03_07_14_03_begin_guarded_code
+
+#include <math.h>
+#include <fstream>
+#include "qwt3d_global.h"
+#include "qwt3d_types.h"
+
+class NodeFilter
+{
+ public:
+ explicit NodeFilter()
+ {
+ values = std::vector<double>(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<double> 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.size(); ++i)
+ {
+ str >> cell[i];
+ cell[i] = cell[i] - 1;
+ }
+ return cell;
+ }
+};
+
+
+template <typename FILTER>
+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 <typename FILTER>
+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 */
diff --git a/lib/tqwtplot3d/examples/mesh2/src/functions.h b/lib/tqwtplot3d/examples/mesh2/src/functions.h new file mode 100644 index 0000000..1a86e0d --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/functions.h @@ -0,0 +1,214 @@ +#ifndef __EXAMPLE_H__
+#define __EXAMPLE_H__
+
+#include <math.h>
+#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
diff --git a/lib/tqwtplot3d/examples/mesh2/src/lightingdlg.cpp b/lib/tqwtplot3d/examples/mesh2/src/lightingdlg.cpp new file mode 100644 index 0000000..0d46b2c --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/lightingdlg.cpp @@ -0,0 +1,220 @@ +#include <qlayout.h>
+#include <qframe.h>
+#include <qslider.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+
+#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();
+}
diff --git a/lib/tqwtplot3d/examples/mesh2/src/lightingdlg.h b/lib/tqwtplot3d/examples/mesh2/src/lightingdlg.h new file mode 100644 index 0000000..2dd79b1 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/lightingdlg.h @@ -0,0 +1,100 @@ +#ifndef lightingdlg_h__2004_03_07_13_35_begin_guarded_code
+#define lightingdlg_h__2004_03_07_13_35_begin_guarded_code
+
+#include <math.h>
+#include <qapplication.h>
+#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 */
diff --git a/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbase.ui b/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbase.ui new file mode 100644 index 0000000..6e5af4b --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbase.ui @@ -0,0 +1,361 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>LightingDlgBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>LightingDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>450</width>
+ <height>345</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>450</width>
+ <height>345</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>450</width>
+ <height>345</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>Lighting Configuration</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>false</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QFrame" row="0" column="0">
+ <property name="name">
+ <cstring>frame</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>290</width>
+ <height>290</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>290</width>
+ <height>290</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>Layout11</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>stdlight</cstring>
+ </property>
+ <property name="caption">
+ <string></string>
+ </property>
+ <property name="text">
+ <string>Std</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="caption">
+ <string></string>
+ </property>
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>Layout8</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>ambdiff</cstring>
+ </property>
+ <property name="text">
+ <string>Ambient & Diffuse Part</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>ambdiffSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>80</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout2_2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>spec</cstring>
+ </property>
+ <property name="text">
+ <string>Specular Part</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>specSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>30</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout2_3</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>shin</cstring>
+ </property>
+ <property name="text">
+ <string>Shininess</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>shinSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="value">
+ <number>500</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout2_4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>emiss</cstring>
+ </property>
+ <property name="text">
+ <string>Emission</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>emissSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout2_4_2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>dist</cstring>
+ </property>
+ <property name="text">
+ <string>Distance</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>distSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>LightingDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbase4.ui b/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbase4.ui new file mode 100644 index 0000000..2102170 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbase4.ui @@ -0,0 +1,293 @@ +<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>428</width>
+ <height>330</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QFrame" name="frame" >
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="stdlight" >
+ <property name="text" >
+ <string>Std</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>91</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonOk" >
+ <property name="text" >
+ <string>&Ok</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="ambdiffSL" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>80</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="specSL" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>30</number>
+ </property>
+ <property name="sliderPosition" >
+ <number>30</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="shinSL" >
+ <property name="maximum" >
+ <number>1000</number>
+ </property>
+ <property name="value" >
+ <number>500</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3_2" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="emissSL" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>0</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3_2_2" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="distSL" >
+ <property name="maximum" >
+ <number>1000</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ <widget class="QWidget" name="layoutWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>280</y>
+ <width>351</width>
+ <height>33</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>stdlight</sender>
+ <signal>clicked()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbaseimpl.cpp b/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbaseimpl.cpp new file mode 100644 index 0000000..25ca438 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbaseimpl.cpp @@ -0,0 +1,22 @@ +#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
+}
+
diff --git a/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbaseimpl.h b/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbaseimpl.h new file mode 100644 index 0000000..4255129 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/lightingdlgbaseimpl.h @@ -0,0 +1,15 @@ +#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
diff --git a/lib/tqwtplot3d/examples/mesh2/src/main.cpp b/lib/tqwtplot3d/examples/mesh2/src/main.cpp new file mode 100644 index 0000000..cce8242 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/main.cpp @@ -0,0 +1,32 @@ +/********************************************************************
+ created: 2003/09/09
+ filename: main.cpp
+
+ author: Micha Bieber
+*********************************************************************/
+
+#include <qapplication.h>
+#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();
+}
diff --git a/lib/tqwtplot3d/examples/mesh2/src/mesh.cpp b/lib/tqwtplot3d/examples/mesh2/src/mesh.cpp new file mode 100644 index 0000000..60683eb --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/mesh.cpp @@ -0,0 +1,57 @@ +#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<count; ++i)
+ {
+ conepos.push_back(Triple(r1*cos(2*i*Qwt3D::PI/count), r1*sin(2*i*Qwt3D::PI/count),h1));
+ }
+ // inner top border
+ for (i=0; i<count; ++i)
+ {
+ conepos.push_back(Triple(r2*cos(2*i*Qwt3D::PI/count), r2*sin(2*i*Qwt3D::PI/count),h2));
+ c1.push_back(count+i+1);
+ }
+ // top polygon
+ conecell.push_back(c1);
+
+ // triangles
+ Cell c2(3);
+ for (i=1; i<count+1; ++i)
+ {
+ c2[0] = 0;
+ c2[1] = i%count +1;
+ c2[2] = i;
+ conecell.push_back(c2);
+ }
+ // quadrangles
+ c2 = Cell(4);
+ for (i=1; i<count+1; ++i)
+ {
+ c2[0] = i;
+ c2[1] = i%count +1;
+ c2[2] = count+i%count +1;
+ c2[3] = count+i;
+ conecell.push_back(c2);
+ }
+}
diff --git a/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindow.cpp b/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindow.cpp new file mode 100644 index 0000000..6e23946 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindow.cpp @@ -0,0 +1,956 @@ +#include <qmetaobject.h>
+
+#include <qframe.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qaction.h>
+#include <qmenubar.h>
+
+#if QT_VERSION < 0x040000
+#include <qpopupmenu.h>
+#endif
+
+#include <qtoolbar.h>
+#include <qimage.h>
+#include <qpixmap.h>
+#include <qfiledialog.h>
+#include <qstatusbar.h>
+#include <qfileinfo.h>
+#include <qslider.h>
+#include <qtimer.h>
+#include <qcombobox.h>
+#include <qstring.h>
+#include <qcheckbox.h>
+#include <qcolordialog.h>
+#include <qfontdialog.h>
+
+#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();
+}
diff --git a/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindow.h b/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindow.h new file mode 100644 index 0000000..435a325 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindow.h @@ -0,0 +1,134 @@ +#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 */
diff --git a/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindowbase.ui b/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindowbase.ui new file mode 100644 index 0000000..49a2625 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindowbase.ui @@ -0,0 +1,1728 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Mesh2MainWindowBase</class>
+<widget class="QMainWindow">
+ <property name="name">
+ <cstring>Mesh2MainWindowBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>954</width>
+ <height>710</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>381</width>
+ <height>328</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>Mesh2</string>
+ </property>
+ <property name="dockWindowsMovable">
+ <bool>false</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>Spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>50</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>Layout11</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout9</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>projection</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Ortho</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>colorlegend</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Legend</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>autoscale</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Autoscale</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Autoscale axes</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Autoscale axes</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>mouseinput</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Mouse</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Enable mouse input</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>shader</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Shading</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Checked means Gouraud (smooth) shading, flat else</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Checked means Gouraud (smooth) shading, flat else</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout7</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>Layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>normalsquality</cstring>
+ </property>
+ <property name="minValue">
+ <number>3</number>
+ </property>
+ <property name="maxValue">
+ <number>32</number>
+ </property>
+ <property name="pageStep">
+ <number>4</number>
+ </property>
+ <property name="tracking">
+ <bool>true</bool>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Above</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Quality (Roundness)</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>normalslength</cstring>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="pageStep">
+ <number>5</number>
+ </property>
+ <property name="value">
+ <number>8</number>
+ </property>
+ <property name="tracking">
+ <bool>true</bool>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Above</enum>
+ </property>
+ <property name="tickInterval">
+ <number>5</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Length</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Normals</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QFrame" row="0" column="0">
+ <property name="name">
+ <cstring>frame</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>Layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>normButton</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="cursor">
+ <cursor>0</cursor>
+ </property>
+ <property name="text">
+ <string>Std</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Set standard view</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>lighting</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="cursor">
+ <cursor>0</cursor>
+ </property>
+ <property name="text">
+ <string>Lighting</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Calibrate Lighting</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>lightingswitch</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Turn Lighting on/off.</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout10</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Polygon Offset</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>offsSlider</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="maxValue">
+ <number>30</number>
+ </property>
+ <property name="lineStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>5</number>
+ </property>
+ <property name="value">
+ <number>5</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Above</enum>
+ </property>
+ <property name="tickInterval">
+ <number>2</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Increase surface quality by setting polygon offset (OpenGL specific)</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout9</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Resolution</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>resSlider</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="lineStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Above</enum>
+ </property>
+ <property name="tickInterval">
+ <number>5</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Set data resolution (no effect for nonrectangular data)</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+</widget>
+<menubar>
+ <property name="name">
+ <cstring>menubar</cstring>
+ </property>
+ <item text="&File" name="file">
+ <action name="openFile"/>
+ <action name="openMeshFile"/>
+ <action name="animation"/>
+ <action name="Exit"/>
+ </item>
+ <item text="&Color" name="PopupMenu_3">
+ <action name="axescolor"/>
+ <action name="backgroundcolor"/>
+ <action name="meshcolor"/>
+ <action name="numbercolor"/>
+ <action name="labelcolor"/>
+ <action name="titlecolor"/>
+ <action name="datacolor"/>
+ <action name="resetcolor"/>
+ </item>
+ <item text="&Font" name="PopupMenu">
+ <action name="numberfont"/>
+ <action name="labelfont"/>
+ <action name="titlefont"/>
+ <action name="resetfont"/>
+ </item>
+</menubar>
+<toolbars>
+ <toolbar dock="2">
+ <property name="name">
+ <cstring>Toolbar</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="cursor">
+ <cursor>0</cursor>
+ </property>
+ <property name="movingEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="horizontallyStretchable">
+ <bool>false</bool>
+ </property>
+ <property name="verticallyStretchable">
+ <bool>false</bool>
+ </property>
+ <property name="label">
+ <string>Toolbar</string>
+ </property>
+ <action name="openFile"/>
+ <action name="openMeshFile"/>
+ <action name="dump"/>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>png</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>bmp</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ppm</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>xpm</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>filetypeCB</cstring>
+ </property>
+ </widget>
+ <widget class="Spacer">
+ <property name="name">
+ <cstring>Spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>---</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Hat</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Rosenbrock</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Saddle</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Sombrero</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Ripple</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>functionCB</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Display function</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>---</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Torus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Seashell</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Boy</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Dini</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Cone</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>psurfaceCB</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Display parametric surface. Turn Lighting on for better quality.</string>
+ </property>
+ </widget>
+ <action name="animation"/>
+ </toolbar>
+ <toolbar dock="2">
+ <property name="name">
+ <cstring>Toolbar_2</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="cursor">
+ <cursor>0</cursor>
+ </property>
+ <property name="resizeEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="movingEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="horizontallyStretchable">
+ <bool>false</bool>
+ </property>
+ <property name="verticallyStretchable">
+ <bool>false</bool>
+ </property>
+ <property name="label">
+ <string>Toolbar_2</string>
+ </property>
+ <action name="Frame"/>
+ <action name="Box"/>
+ <action name="None"/>
+ <separator/>
+ <action name="front"/>
+ <action name="back"/>
+ <action name="right"/>
+ <action name="left"/>
+ <action name="ceil"/>
+ <action name="floor"/>
+ <separator/>
+ <action name="pointstyle"/>
+ <action name="wireframe"/>
+ <action name="hiddenline"/>
+ <action name="polygon"/>
+ <action name="filledmesh"/>
+ <action name="nodata"/>
+ <separator/>
+ <action name="floordata"/>
+ <action name="flooriso"/>
+ <action name="floornone"/>
+ <action name="normals"/>
+ </toolbar>
+</toolbars>
+<actions>
+ <action>
+ <property name="name">
+ <cstring>openFile</cstring>
+ </property>
+ <property name="iconSet">
+ <iconset>image0</iconset>
+ </property>
+ <property name="text">
+ <string>Open File</string>
+ </property>
+ <property name="menuText">
+ <string>&Open File</string>
+ </property>
+ <property name="statusTip">
+ <string>Open File</string>
+ </property>
+ <property name="accel">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>Exit</cstring>
+ </property>
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ <property name="menuText">
+ <string>Exit</string>
+ </property>
+ <property name="statusTip">
+ <string>Exit</string>
+ </property>
+ <property name="accel">
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <actiongroup>
+ <property name="name">
+ <cstring>coord</cstring>
+ </property>
+ <property name="text">
+ <string>Coordinates</string>
+ </property>
+ <property name="menuText">
+ <string>&Coord</string>
+ </property>
+ <property name="statusTip">
+ <string>Coordinates</string>
+ </property>
+ <property name="usesDropDown">
+ <bool>false</bool>
+ </property>
+ <action>
+ <property name="name">
+ <cstring>Box</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image1</iconset>
+ </property>
+ <property name="text">
+ <string>Box</string>
+ </property>
+ <property name="menuText">
+ <string>Box</string>
+ </property>
+ <property name="toolTip">
+ <string>Box</string>
+ </property>
+ <property name="statusTip">
+ <string>Box</string>
+ </property>
+ <property name="accel">
+ <string>A</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>Frame</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image2</iconset>
+ </property>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ <property name="menuText">
+ <string>&Frame</string>
+ </property>
+ <property name="toolTip">
+ <string>Frame</string>
+ </property>
+ <property name="statusTip">
+ <string>Frame</string>
+ </property>
+ <property name="accel">
+ <string>F</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>None</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="on">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image3</iconset>
+ </property>
+ <property name="text">
+ <string>No Axes</string>
+ </property>
+ <property name="menuText">
+ <string>No Axes</string>
+ </property>
+ <property name="toolTip">
+ <string>No Axes</string>
+ </property>
+ <property name="statusTip">
+ <string>No Axes</string>
+ </property>
+ </action>
+ </actiongroup>
+ <action>
+ <property name="name">
+ <cstring>animation</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image4</iconset>
+ </property>
+ <property name="text">
+ <string>Animation</string>
+ </property>
+ <property name="menuText">
+ <string>Animation</string>
+ </property>
+ <property name="statusTip">
+ <string>Animation</string>
+ </property>
+ <property name="accel">
+ <string>Ctrl+A</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>dump</cstring>
+ </property>
+ <property name="iconSet">
+ <iconset>image5</iconset>
+ </property>
+ <property name="text">
+ <string>Dump Content</string>
+ </property>
+ <property name="menuText">
+ <string>Dump Content</string>
+ </property>
+ <property name="toolTip">
+ <string>Dump Content</string>
+ </property>
+ <property name="statusTip">
+ <string>Dump Content</string>
+ </property>
+ </action>
+ <actiongroup>
+ <property name="name">
+ <cstring>plotstyle</cstring>
+ </property>
+ <property name="text">
+ <string>Plot Style</string>
+ </property>
+ <property name="menuText">
+ <string>Plot Style</string>
+ </property>
+ <property name="statusTip">
+ <string>Plot Style</string>
+ </property>
+ <property name="usesDropDown">
+ <bool>false</bool>
+ </property>
+ <action>
+ <property name="name">
+ <cstring>wireframe</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image6</iconset>
+ </property>
+ <property name="text">
+ <string>Wireframe</string>
+ </property>
+ <property name="menuText">
+ <string>Wireframe</string>
+ </property>
+ <property name="toolTip">
+ <string>Wireframe</string>
+ </property>
+ <property name="statusTip">
+ <string>Wireframe</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>hiddenline</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image7</iconset>
+ </property>
+ <property name="text">
+ <string>Hidden Line</string>
+ </property>
+ <property name="menuText">
+ <string>Hidden Line</string>
+ </property>
+ <property name="toolTip">
+ <string>Hidden Line (EXPERIMENTAL!)</string>
+ </property>
+ <property name="statusTip">
+ <string>Hidden Line (EXPERIMENTAL!)</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>polygon</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image8</iconset>
+ </property>
+ <property name="text">
+ <string>Polygon only</string>
+ </property>
+ <property name="menuText">
+ <string>Polygon only</string>
+ </property>
+ <property name="toolTip">
+ <string>Polygon only</string>
+ </property>
+ <property name="statusTip">
+ <string>Polygon only</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>filledmesh</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="on">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image9</iconset>
+ </property>
+ <property name="text">
+ <string>Mesh & filled Polygons</string>
+ </property>
+ <property name="menuText">
+ <string>Mesh & filled Polygons</string>
+ </property>
+ <property name="toolTip">
+ <string>Mesh & filled Polygons</string>
+ </property>
+ <property name="statusTip">
+ <string>Mesh & filled Polygons</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>nodata</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="on">
+ <bool>false</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image10</iconset>
+ </property>
+ <property name="text">
+ <string>No Data</string>
+ </property>
+ <property name="menuText">
+ <string>No Data</string>
+ </property>
+ <property name="toolTip">
+ <string>No Data</string>
+ </property>
+ <property name="statusTip">
+ <string>No Data</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>pointstyle</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image11</iconset>
+ </property>
+ <property name="text">
+ <string>Points</string>
+ </property>
+ <property name="menuText">
+ <string>Points</string>
+ </property>
+ <property name="toolTip">
+ <string>Points</string>
+ </property>
+ </action>
+ </actiongroup>
+ <actiongroup>
+ <property name="name">
+ <cstring>color</cstring>
+ </property>
+ <property name="text">
+ <string>Color</string>
+ </property>
+ <property name="menuText">
+ <string>&Color</string>
+ </property>
+ <property name="toolTip">
+ <string>Color</string>
+ </property>
+ <property name="statusTip">
+ <string>Color</string>
+ </property>
+ <property name="exclusive">
+ <bool>false</bool>
+ </property>
+ <property name="usesDropDown">
+ <bool>false</bool>
+ </property>
+ <action>
+ <property name="name">
+ <cstring>axescolor</cstring>
+ </property>
+ <property name="text">
+ <string>Axes</string>
+ </property>
+ <property name="menuText">
+ <string>&Axes</string>
+ </property>
+ <property name="toolTip">
+ <string>Axes</string>
+ </property>
+ <property name="statusTip">
+ <string>Axes</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>backgroundcolor</cstring>
+ </property>
+ <property name="text">
+ <string>Background</string>
+ </property>
+ <property name="menuText">
+ <string>&Background</string>
+ </property>
+ <property name="toolTip">
+ <string>Background</string>
+ </property>
+ <property name="statusTip">
+ <string>Background</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>meshcolor</cstring>
+ </property>
+ <property name="text">
+ <string>Mesh</string>
+ </property>
+ <property name="menuText">
+ <string>&Mesh</string>
+ </property>
+ <property name="toolTip">
+ <string>Mesh</string>
+ </property>
+ <property name="statusTip">
+ <string>Mesh</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>numbercolor</cstring>
+ </property>
+ <property name="text">
+ <string>Numbers</string>
+ </property>
+ <property name="menuText">
+ <string>&Numbers</string>
+ </property>
+ <property name="toolTip">
+ <string>Numbers</string>
+ </property>
+ <property name="statusTip">
+ <string>Numbers</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>labelcolor</cstring>
+ </property>
+ <property name="text">
+ <string>Label</string>
+ </property>
+ <property name="menuText">
+ <string>&Label</string>
+ </property>
+ <property name="toolTip">
+ <string>Label</string>
+ </property>
+ <property name="statusTip">
+ <string>Label</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>titlecolor</cstring>
+ </property>
+ <property name="text">
+ <string>Caption</string>
+ </property>
+ <property name="menuText">
+ <string>Caption</string>
+ </property>
+ <property name="toolTip">
+ <string>Caption</string>
+ </property>
+ <property name="statusTip">
+ <string>Caption</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>datacolor</cstring>
+ </property>
+ <property name="text">
+ <string>Data Color</string>
+ </property>
+ <property name="menuText">
+ <string>Data Color</string>
+ </property>
+ <property name="toolTip">
+ <string>Data Color</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>resetcolor</cstring>
+ </property>
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ <property name="menuText">
+ <string>&Reset</string>
+ </property>
+ <property name="toolTip">
+ <string>Reset</string>
+ </property>
+ <property name="statusTip">
+ <string>Reset</string>
+ </property>
+ </action>
+ </actiongroup>
+ <actiongroup>
+ <property name="name">
+ <cstring>font</cstring>
+ </property>
+ <property name="text">
+ <string>Fonts</string>
+ </property>
+ <property name="menuText">
+ <string>&Fonts</string>
+ </property>
+ <property name="statusTip">
+ <string>Fonts</string>
+ </property>
+ <property name="exclusive">
+ <bool>false</bool>
+ </property>
+ <property name="usesDropDown">
+ <bool>false</bool>
+ </property>
+ <action>
+ <property name="name">
+ <cstring>numberfont</cstring>
+ </property>
+ <property name="text">
+ <string>Scale numbering</string>
+ </property>
+ <property name="menuText">
+ <string>&Scale numbering</string>
+ </property>
+ <property name="toolTip">
+ <string>Scale numbering</string>
+ </property>
+ <property name="statusTip">
+ <string>Scale numbering</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>labelfont</cstring>
+ </property>
+ <property name="text">
+ <string>Axis label</string>
+ </property>
+ <property name="menuText">
+ <string>&Axis label</string>
+ </property>
+ <property name="toolTip">
+ <string>Axis label</string>
+ </property>
+ <property name="statusTip">
+ <string>Axis label</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>titlefont</cstring>
+ </property>
+ <property name="text">
+ <string>Caption</string>
+ </property>
+ <property name="menuText">
+ <string>&Caption</string>
+ </property>
+ <property name="toolTip">
+ <string>Caption</string>
+ </property>
+ <property name="statusTip">
+ <string>Caption</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>resetfont</cstring>
+ </property>
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ <property name="menuText">
+ <string>&Reset</string>
+ </property>
+ <property name="toolTip">
+ <string>Reset</string>
+ </property>
+ <property name="statusTip">
+ <string>Reset</string>
+ </property>
+ </action>
+ </actiongroup>
+ <actiongroup>
+ <property name="name">
+ <cstring>floorstyle</cstring>
+ </property>
+ <property name="text">
+ <string>Floor Style</string>
+ </property>
+ <property name="menuText">
+ <string>Floor Style</string>
+ </property>
+ <property name="statusTip">
+ <string>Floor Style</string>
+ </property>
+ <property name="usesDropDown">
+ <bool>false</bool>
+ </property>
+ <action>
+ <property name="name">
+ <cstring>floordata</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image12</iconset>
+ </property>
+ <property name="text">
+ <string>Floor Data Projection</string>
+ </property>
+ <property name="menuText">
+ <string>Floor Data Projection</string>
+ </property>
+ <property name="toolTip">
+ <string>Floor Data Projection</string>
+ </property>
+ <property name="statusTip">
+ <string>Floor Data Projection</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>flooriso</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image13</iconset>
+ </property>
+ <property name="text">
+ <string>Floor Isolines</string>
+ </property>
+ <property name="menuText">
+ <string>Floor Isolines</string>
+ </property>
+ <property name="toolTip">
+ <string>Floor Isolines</string>
+ </property>
+ <property name="statusTip">
+ <string>Floor Isolines</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>floornone</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="on">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image14</iconset>
+ </property>
+ <property name="text">
+ <string>Empty Floor</string>
+ </property>
+ <property name="menuText">
+ <string>Empty Floor</string>
+ </property>
+ <property name="toolTip">
+ <string>Empty Floor</string>
+ </property>
+ <property name="statusTip">
+ <string>Empty Floor</string>
+ </property>
+ </action>
+ </actiongroup>
+ <action>
+ <property name="name">
+ <cstring>openMeshFile</cstring>
+ </property>
+ <property name="iconSet">
+ <iconset>image15</iconset>
+ </property>
+ <property name="text">
+ <string>Open FEM files</string>
+ </property>
+ <property name="menuText">
+ <string>Open FEM files</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>normals</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image16</iconset>
+ </property>
+ <property name="text">
+ <string>Show normal vectors</string>
+ </property>
+ <property name="menuText">
+ <string>Show normal vectors</string>
+ </property>
+ </action>
+ <actiongroup>
+ <property name="name">
+ <cstring>grids</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>grid</string>
+ </property>
+ <property name="menuText">
+ <string>grid</string>
+ </property>
+ <property name="statusTip">
+ <string>grid</string>
+ </property>
+ <property name="exclusive">
+ <bool>false</bool>
+ </property>
+ <property name="usesDropDown">
+ <bool>false</bool>
+ </property>
+ <action>
+ <property name="name">
+ <cstring>front</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image17</iconset>
+ </property>
+ <property name="text">
+ <string>Action</string>
+ </property>
+ <property name="menuText">
+ <string>Action</string>
+ </property>
+ <property name="toolTip">
+ <string>Front Grid</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>back</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image18</iconset>
+ </property>
+ <property name="text">
+ <string>Action_2</string>
+ </property>
+ <property name="menuText">
+ <string>Action_2</string>
+ </property>
+ <property name="toolTip">
+ <string>Back Grid</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>right</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image19</iconset>
+ </property>
+ <property name="text">
+ <string>Action_3</string>
+ </property>
+ <property name="menuText">
+ <string>Action_3</string>
+ </property>
+ <property name="toolTip">
+ <string>Right Grid</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>left</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image20</iconset>
+ </property>
+ <property name="text">
+ <string>Action_4</string>
+ </property>
+ <property name="menuText">
+ <string>Action_4</string>
+ </property>
+ <property name="toolTip">
+ <string>Left Grid</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>ceil</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image21</iconset>
+ </property>
+ <property name="text">
+ <string>Action_5</string>
+ </property>
+ <property name="menuText">
+ <string>Action_5</string>
+ </property>
+ <property name="toolTip">
+ <string>Ceiling Grid</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>floor</cstring>
+ </property>
+ <property name="toggleAction">
+ <bool>true</bool>
+ </property>
+ <property name="iconSet">
+ <iconset>image22</iconset>
+ </property>
+ <property name="text">
+ <string>Action_6</string>
+ </property>
+ <property name="menuText">
+ <string>Action_6</string>
+ </property>
+ <property name="toolTip">
+ <string>Floor Grid</string>
+ </property>
+ </action>
+ </actiongroup>
+</actions>
+<images>
+ <image name="image0">
+ <data format="PNG" length="201">89504e470d0a1a0a0000000d49484452000000100000000d0806000000a0bbee240000009049444154789c9d92410ac4200c457f4ab65de4429e6c6018989365e1755cf40076a18106621503f2157d21ff23e59c31ab9452b5bdaad2f3ee588155956c5933535a99603491aa12cf461cc156c4ccb55c00500008e41cc351736ed260a0a05ce2cea6724ad8b48718435ee3ea16fce3371b030b1efe7ce7e0ffd732e916f660e091c10e0cf40c803dd83558a9e81fdc37d14cdbb2be9c140000000049454e44ae426082</data>
+ </image>
+ <image name="image1">
+ <data format="PNG" length="215">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000009e49444154789c633c76ec1803b5010b2e09df88f7ff3f7efa4d9261ac2c8c0c5c5c2cd80db5f37af5ffd0363146121dc860e7f5eaff8f9f7f1998a869e0a16d628c3f7ffe4335945203617c265c12e41ac8c0008d283baf57ff79785818ecbc5efd27d5506c0e8147d4b6554264b9129b38464451038c1a3a6a2895002c7751cd50e4ec4a1543711628d43290810129ef9353983030e02950c829f2f00100bdf84c6a92a74e8d0000000049454e44ae426082</data>
+ </image>
+ <image name="image2">
+ <data format="PNG" length="167">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000006e49444154789c633c76ec1803b5011332c7ceebd57faa1b4a2d306ae8a8a1a3865203c0b239d50cb5f37af5ffd03631460c430f6d1363b4f37af59fd48205d94006060606167405304998c1c88a893110aba1a4188ecd40bc8612321c978144194a8acb493614dd707c8026891f00185139a40ba3f8e90000000049454e44ae426082</data>
+ </image>
+ <image name="image3">
+ <data format="PNG" length="216">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000009f49444154789c633c76ec1803b501133e493baf57ff49a19dfd5eff6760606060c4e6523baf57ff0f6d136324c795ae816ffe6375293906c25cbb7bbd08231336097200cc21765eaf505d4a890b91cd801bea15f68ea44881d1e80eb1f37af59ff1d8b16364470c2e7d58639f12000f537223089bbe43dbc418475d3a925dca0463906328b23e640ba8e652640b2876293607a1b8941c9a2e799f81818101000a06a3357133957f0000000049454e44ae426082</data>
+ </image>
+ <image name="image4">
+ <data format="PNG" length="772">89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000002cb49444154789ced97cd6b134118879f6d420ba5474f62ff0441410f2e054fb9d4a3207ab5a8d05341a95aa546a8c58f2a9e02d2f6e6492f82a41e7a119115f16040a490a326d9cb26fd486c63348c87cd6c6626b3695a68eba12f2c939979dff7f7cce76e1ccff33848eb3b50f54380ff0120a9565cd7153627cff39cdd0a6c97b34f75948d66e9baae884bd44d58c6d8f2ca3ec7f3bc48bc1baddad76d4654d16ed0b23f6906026432f0b7de7e7a496afac87a26038d5af84058de7dd6f6d7f6c0f3c7303109953c08113e08b877159abfedeb192b7c19ca43303eaefbdf3c0fd747e1e95258d700fccf61b99a87be7e48f4436220146f36f4c038e15c3605c08973cbb689eab05d1d4375c3aac2b96c8a522120bff22336b6d90807914ea72d00ad5a62009c44b804cd063c7c054fdee881ea7248e15221c02f06e4577e4629a5bfb4b9b7615bd4de7a1989743add5a71c4ed4b885b1788ea663f2072d994c8655302104b2f4e8ac5e961b1383d2c66c606c5ccd8a000c4dc7d3dd6cc0188e818c64d99464b7b8d4b850080d16b5f599c1ec62f96231fc771b8b3f08b0737e0eca911462e7ed472e6b229de7f5f6662d2d88452cc7c6cc27e3188e24c71c709af8946152ae58d28565aa910b0d50a8900c223988e4064298fa629ac8a4a6159aeaf8587fe4f0d2ac106c96442f3f58b01f58a01b055a68314e0dd87e5aec2e6a8a7e66b5adf6aa54ab3d93400cad4d70c807a251ce5d1634722c752a14d1a3762f95b0aabb7a5dc5836681c0b805f0ca85537239feac66604600aab0053f3b58e0bc9148a834faa8e7eb16ca7b5089b2336df7caeeb0ac7d19747cb65ce40ac393ac076c2aacdbe040898bd32a4b5abfb449b0193d416d48bb0ea17f70695edda45649202acafd578f47a67df04aad940d5b69e3e484cf25e846d10b63c8efc6362be5e6de54e857bb108208ed424de5380bdb433a78f8b4f5fbe750c62dffe17d8c4f71520ce0e01fe01ed94001160906df80000000049454e44ae426082</data>
+ </image>
+ <image name="image5">
+ <data format="XPM.GZ" length="2144">789cbdd45b4fdb301407f0f77e8a08bfa1e99034899d68da03f7fba5dc61da83e3246d81722db430edbbcfe76f070d08d39e963f48f9d5a7c6764e989b0d4ef7b683d9b9cec3588f872630037d1fcc968fa3d1f3f71fdf7e7666ba61607f940cba335f3a3334084c20425cf0269c71e01538e7c04f70c181e7d951cc81fb70c681c7b0e6c0d7ecaee4c0f7b0e2c0353bd61cf8929de0822b38e3c025ac396c71011749e1f76360c3c138be9f2669e2c70b1817bc066769e6c74fe03ccd9dc510d6a9f6e38b7091367faf0b9bd4784bb84a2bef295b86b239ef235849e5ad1b4b9c87c0fe64269bf5dcc2b9f4eba13d58cb663d5b70219bf59cc246faf508377f294b3f7e0857b259df315ccbda7bc256a16ad67b00472af2de8563157b4770a29af3dd8753957adfc0f6f2eec1996af627e09c03efc04619df8f195ca9caf59f183456158cfe437bb87e4960fb402337df066c0fd4f7e3f2abdd7ce8bface0605cc12633be5f5fe0322b5dbf0af4571e71301ec3499ec4eeefafc3b68162f7fd25d83ec0d8ede70ecef22c467fd2336c72e3fa5de03cf29283f190ad430e8c7ed74aab14fb134563edd647302ed4a770cd81cfd9789ddd7ce86ffbfa24caed27877120f0196c38f036db841c78158e38f0021c73e047981fa87bdf1f603e6037ff08ae38f0155c73d83dfc3f29933274f5bd3109d25490a1b22515d5d4a7416fec7a8b867441977445a3d65cd30dddd2c0bd87b6f28eeee981c62d79a4279ad0d4d716f44c2f344f0b9f6460b3e86b0d2dd132add02a3e7d1ff7e99aaf2d699d3668d37eda9e016db5d47e366f5bedff9a771bf958bbd33a2b6797f63ed4f6de659f0ee8d03e87897d6a7fafbdb1955b7464e73cb6bf27ffb886099dbe3eb7f6da333aa7107791adeefada8a624a5a6a535fdbb3bb93beb62645995ddfdbda5c9010b8e395376be85b4d847e5b2b0a2184c1fdb12845e56b07f64ca6fccd37b5b5e80b773f154371e16aed3bf4d909fc11fb0efdfadaf90db563e86f</data>
+ </image>
+ <image name="image6">
+ <data format="PNG" length="923">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000036249444154789cad955f485b6718c67fc71c63625193e11facc6d6ceaca9b55d7ae18522bd50acb13427548d10e386462c0c7b212d2c92ad7485c2d04ba1174abb9be1dd50a8f462ea5a5c87b8ddc82a6a2f8a7fd0760612ab47433c9e846f17838d4e5775f4b97ebf1fcffb3eeff77dd2d4d4141f5a29c73d70f76ea10804be17efab918f0af3f97c229148c36e7fc2a9534edc6eb7906599919111e97f396d686810555555f4f77f8bc1f09a8a8acfe8ebeb2391481c587f28545114e1f178181c1c241c0e939efe07e1b0896bd7bc381c0e9a9a9af68de250a8244974767602303c3c8cc3616263432299cc201008b0b3b3733ca76eb75b9c3bf73977ee4c73fbf697cccfcf73f1621eba2e989d7d85d56ac566b3d1dcdcfc8edbf706959a6aa2ac2c84ae47989e7e84a669dcbbf70579795f110afd4c3cfe94643289d1683c9a534551c4f5eb01b6b63ec2ebb563b797e072b9387ffe6336379f70f3e6d74c4c4cd0d3d343341a3d1a5492242e5fbe81ae434e4e84999919aaababb15ab3387122055dcf233f3f9ff2f2720c06c3e150455144454525cbcbf99c3d0b2b2bbfa2aa2a4ea7134982e2e24f585e8664126c361bd9d9d98743f7f6f690652b53535bc8f2ef3c7b3641515111369b0d803367f2585b83adad04f1781c8bc582dfefff3b2ce9df77dfe3f188e2e262eedfff81070f72585fbfc1dada530c0603252525689a86c552425a5a3f66f337cccefec4f6f636aaaa323a3a2a1de854d334fc7e3f60c3e13071eb5623b1580c9fcf87dfef27232383a2222b261354567ae9eeeea6a5a5054dd3febbfddcdc5cae5ef5323e0e57ae08c6c646292b2b23140ae1f57a515595c64637a5a599a4a656d0dede4e6b6b2b66b3f960687d7dbde8e8e86075351f21e0f4e930939393288a4266662691488468344a4e4e36972ec1cb97a069505050406161213e9f4fbc03adabab1356ab95b1b15f78f8f00d172eacf2fcf98fa8aa4a4d4d0d009b9b9b689a86d168a4b414c261585901b3d94c5b5b1b1b1b1bff04e5f178444a4a0ac160909327ed3c7ebcca8b178fd8d98922cb32b5b5b5389d4ee6e6e6181f1fa7abab8bc5c57516173b494fff8db76fbf63696989dddd5d2c16cb5fd06030287a7b7bf7bd8b03030362616181582c0640229120994ca2eb3a0059599fa2eb7176775f3134342401b85c2eb16fa53e848efd9d1c457f02e3f74bd7fe3f92e00000000049454e44ae426082</data>
+ </image>
+ <image name="image7">
+ <data format="PNG" length="872">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000032f49444154789ccd954b48aa6b14869f5fff3684110a6184a905890e0a0cb1081a841199a24245176c104917880641749b37e832286892831a3588a068e2406ad04428a22b5d402a68521405997929ed3f8320d8b4f7ae7d3883b3868bf53debfdd6fbf12d21140af15f87ec6f0f381c0ec9e9744a7faa11bf0b6b6d6d9592c924e9741abd5e8fcbe592445164757555f8574aebebeba5caca4a666767c9cacaa2a4a48489890952a9d42febbf84badd6ec9e3f1e0f7fbb9bdbd45ad5673717181c3e1c06432d1d8d8f869145f420541a0b3b313809595152c160bd7d7d7c4e3713a3a3a8846a37fa7d4e572494545450c0e0e323030c0c9c909656565bcbebeb2bfbf8f4aa542abd5d2d4d4f493da3f1a258a226363631c1d1db1b0b0403299647a7a9a4422417f7f3f0a8582743acd8f1f3fbea7d4ed764bcdcdcd545555d1d7d787c160c06eb7333f3f4f6e6e2e3d3d3dacafaf333c3cccfdfdfdf7a08220d0d5d5852008dcdcdcb0b7b787cd66c36ab5623018787c7c242f2f0fabd58a5c2eff1aea76bba58a8a0a0a0b0b01d8d9d921128960369b114511bd5ecff1f131a9540aad564b4e4eced7d0979717323232686b6b636969898d8d0d743a1d5aad1680d2d252c2e130f7f7f7c4e371944a255eaff7c3ac4f46793c1ec96432313636462010606a6a8aebeb6be472392d2d2de8f57aeeeeee8846a3f4f6f6120e87797a7a221289f05b683299c4ebf562341a311a8de8f57a7c3e1fdddddd188d4600a2d128e170188bc582d3e9e4fcfc9c999999df43d56a350d0d0d004892442010a0b8b898d1d151b2b3b33ff25b5b5b442211464646383b3bc3eff7ff7aa675757592cfe743a3d100707373c3e6e6266eb7fb0308ef2fc366b3b1bdbd4d2c1643a3d1909f9f4f6b6babf413b4b6b65652a954048341262727d9dddd25180c128944a8aeaefe64667979395757579c9d9d919999497b7b3b0f0f0fef4d43a1101e8f4792c9640c0d0d515050c0f2f232070707c462314451a4a6a606b3d94c4646c6c7f50f0f0f595b5b43a7d3a15028b8bcbc249148a0542adfa1434343d2f8f8f8a77f716e6e4e3a3d3de5f9f9f923f7f6f6462c167b37441449a552c864321617170500bbdd2e09ff8b75f29df8072ad2411c44a7ba050000000049454e44ae426082</data>
+ </image>
+ <image name="image8">
+ <data format="PNG" length="554">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000001f149444154789ccd95bf6b5a5114c73fef298d20c14715b120e2f806e990ada34aab0ebe27a2832e85f817b410dedfe01808b45b978810a18180a393e1b5a1b482143a6490fe701031a9b4b12ae8ed906290e7cfd2a107ce70bff7dccffd9e33dc2b99a6c9bf0e79db03d96c56a45229b1aac6be292c97cb89c964422814c2e170904c2685dd6ee7f4f454fa2b683a9d16d16894e3e76f80cb3faa0bcf93fec2fab5ed6b9a26745de778ff037cdf994b5555c964329651ac756ab3d978f9f802ae772c7be7cf6e70edffb4e82ba19aa6897c3e0fd76f97d6288a62d156b66fb3d938f4376e5d2ec9482482aeeb732358eaf4cee5fb55f7f2eac125ca783ca72d854a92c4e1f01c862b99b38ed642354d13e17018ae3eae27021e8f676ebd70a6e3f19893de3bb8fab5512a8a42a15098cdd5e254d775a1aa2af43e6fe41260efd11ed56a75b6b64047a31117df3e6d0c0478715642b9b96bda02f57abdf0a5b51514e09eebfe62682291105ffb7d7e6c8d04bfdf4f2e9713e572599a4163b19870bbddf4fa8b1f8975f1bad1e0e1ee2e0092699ae8ba2e6459c6300c82c120954a8566b3492010c0e7f3e1743a797a743407393938a0d3e900d0ed7669b55a0c87431445b9851a86218ac5a2e55dacd7eba256abd16eb767da743a653018ccd5c9b24ca9549200e2f1b890fe8bef6493f80da5c2b9a2130355fd0000000049454e44ae426082</data>
+ </image>
+ <image name="image9">
+ <data format="PNG" length="744">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000002af49444154789ccd953d4c535118869f7b7b2929a505c34fd55aa988112126c41023098383290dd8de188146347132ea6270eaee62181c5c4c18d88418217670c1451773a3c60583160d52498c3f840a2df4f68a2dc7413dd814f9310e9ee44ddeefdcef3cf77cdfb93f8a6118fceba16e77416767a7e8eaea121be5685b855d8844c4c2b76fe4f3791af7ec410f8584aa69c46231e5afa017755d4c8ebb80121a3a05cf6e7f052af00452ebe66f5a7e5f28245edca986c552582ca5c2e391fef3dd5a7ababb8b5ab12934abaab0502ad5d2da4ad3f925192f2f2f6f6fa7a1504834eddbc7c99b2e58b0e3bd32c750db24e97c9ef1c7c7197f72029fcf476f6f6fc16e37eca9db66e361772900fdd7e7d12c8be61b694ccbe2522c46b5c3415e08ec767bc1ba3f42c3e1b0b81c08c0c22c00b51e0fb3915d0034c5e0d5a92a99bbe3d6e4d6ca7702d7caa72099856496b14f9fa46fdcbf5f7a9259ec36dbe6d070382c5adadae04b562abdb424fd3dc70c91d91a19f794956d0e5d5959a14c51389d3b085fb2f47b0354d5d515dce4e5bb77d2dbdc6ece9d3d2b0faba8a7baae8b63f5f58ccc3e05e068898f0f6363b8148533b6dd845329a69c4ed29939faca8f104f2448659749a7d3fc11aa59160fe6decaf819aff16654e2ce5578fff30d5a82fbce9d8c3c7f24f35c5fd79eaaa2f26babab61de94ba10eca1f9d0a18239e64d0eb7b616c4e50ec71ac4300c29afdb2dd250a0030d0d4573bf146a6f97fe6a7dbdf0d7d509c330d6caefe8e810355555247feb0d402e9522b9de69026f3e7e94d7aecccc30e47201a0188681aeeb425555a2d1287ebf9fd1d151262626304d13bba6313c3dbd2eb4d7efc7b7772f4ea7934422816559545656fe8046a35131303050f45d1c1c1c14f1789c4c2623e7565757314d13004dd3c8e572a8aacaf0f0b002100c0685f25ffc4eb632be03f01c3f1b679402620000000049454e44ae426082</data>
+ </image>
+ <image name="image10">
+ <data format="PNG" length="653">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000025449444154789cad95bf4b725118809ffb71cda09f46dca1a5fe0169edd2108498e2d022414d91fd030d39b555343605d190181886e020b8b40971c5868c96a2200871b0a0522aaf50be0d1f5e3efbae7dfad1b31ddef33ee73de73d87a31886c14ff3abd3048fc7237ebf5f7e4cbabcbc2c9aa6e176bb191d1d6d296e5b3a313121b95c8e603048575717434343e8ba6e2b6e4baaebba288a42bd5ea756ab717777c7d3d3139148846030f897f89fd29b9b1ba9d56a00c4e3719e9f9f595f5fa7bbbb9bc1c1414cd3ecbcd2442241b95ca6582c128d46098542cccfcf53a954787878a0afaf8f4020d054edb7d2442221b1580c4dd3000887c3e8ba0ec0f1f1313b3b3bf4f7f7333232d294a77c774fabd5aa4c4f4fdbc63e3e3e787b7bc3e17090cfe795b6a4ad3adb8a6c366b895b6e3f9d4ed368d0fbfb3b22cd6b346276d84a2f2e2e646f6f8f72b90cc0fefe3ed168d48a9f9c9cb0b2b2c2ebeb6bfbd2a5a5250e0f0fd1348dfbfb7b76777771381c0098a6c9d1d111e3e3e3389dcef6a46b6b6b522a95e8e9e90160606080adad2d666666005055158fc783d7eb45555500cecfcf595d5db5ce47fd2a9d9b9bb384004ea7d31236a4b3b3b34d39bdbdbd140a05fb4a53a9942c2e2ee272b96cb7d58ab1b131dc6eb7bdf4f4f4d46a4e27a8aacac6c606979797bf8fc0300c0cc3c0344d7979799106f57a5d229188e4f3791111797c7c94838303b9bebeb6e65c5d5d492a95923f310c03756a6a4a32998c727676a67cad20994ccaeded2dd56a5501d8dede96c9c949161616acb99b9b9b323c3c6c8d7d3e9f7cfb4cff978ebf9376f80482fc1c4c4b56a72d0000000049454e44ae426082</data>
+ </image>
+ <image name="image11">
+ <data format="PNG" length="452">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000018b49444154789ca595c16ac2401086bf4421822028b2143df80a3dbaf8183ea78fa1b9f424f4d46bcd412c2156c1404c7a48679b351b6ddaff363bb3ffcc3f339b789bcd86b6582e7401b05a879ecbdf6d43a67549f6087e1b524194c3cb7bf47fd2f97c5e9c4e27263e4c7c188d468d95ff8a546b5d789e479ee7e62c8e63e36b4daab52ed2340560301810e5a5fc5eafd778e72ee972a18b890f4992b0dbed2cdff178b412b7aa1440290560fa09309bcd2cbb8abb2b15fdb490e9746af9aed72bd001200ced7d6dacd43500e92740a7d331f6afe44b900c28cbb29a54f1b9e0241539499200d0edd6bb140401e7f3d9495a8b9677fdf6794629c57ebf472965645f2e17b34e411000a24017f22d68ec69bfdf07e0f94931f1e1703898aaa5152e054ed22887d78fb816381e8f0da9eb4e75536a11699a321c0ead0b2e922ab22cb39259956aad0b194e1b484b641e5da80f4756a75a511cc79682bb49aac676bbfd7e19f632974986264918869e1412e5a5bd5adf90defe16c40e433929096e9f63d399f7977fd4237c01356dabc16040cf010000000049454e44ae426082</data>
+ </image>
+ <image name="image12">
+ <data format="PNG" length="226">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000000a949444154789cedd4210ec2301886e1b764084e0306f38969041804090acb1948b8010967d805309304fb131cc7014c512c7475ed1024fb64c59357fca93333badea073b1477f8216ed07493e07343317a10093c52609bcd715d02a95e4a7ab35f04a423f8b4a8bd13309ba5627cccc05a8245f6ee7e4560628c030b1f2723c37950d2ac9cf76259086b6d794a656d6fb5b50095048f2cbc31878e4e57dcd01d9c71ea1fd7ffa1fe81b2e1b2dcf4b906cbb0000000049454e44ae426082</data>
+ </image>
+ <image name="image13">
+ <data format="PNG" length="238">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000000b549444154789ced94210e843010456736bd018223ec1d8ac490705e120c92b90ba266cdcaa2a6197e0b0858b109dff1075eff6f1b5844e86ebd6e273ed09f401d1adefb780528229c4175609fabb68b611a4f3d0de4d05460d57629317e7ca62ca9c210d4f47524229a8785756edfb5811254cd008b20ace9eb68c1d8aa9814810a38d2fbfbd99c83b329f7aa63624c86da24b575c234f23c2c8cf5f1d4ed5e2668c9b4b2f54bd7a82426a2cb973d833effd3ff80aec3fb78ab235e84730000000049454e44ae426082</data>
+ </image>
+ <image name="image14">
+ <data format="PNG" length="153">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000006049444154789ced94410a00310803a3ecabfc3ff9d6eea950aca79a1e169a63846110d148421d97132ff408f4c94544bc1d20495ba063b0031c429ecb5de01cd94e6721afca6e24a659c8abb29bb66925e46a4b003000ed635fa0f79ffe03fa017ed12c22088282610000000049454e44ae426082</data>
+ </image>
+ <image name="image15">
+ <data format="PNG" length="237">89504e470d0a1a0a0000000d49484452000000100000000d0806000000a0bbee24000000b449444154789c9d92b109c3301444ef9b0ba4c94a1ec08517c8162e3580cb6ce1055c6400155e47858a182cf8298284432c47e8e07302f18ee34bb22c0bfea91f1f1acfb319647fd794c0b319244e0c8b2e250d728d66330801a06ddb54d15a2b39700f470949edb68069f5b85f6f785e98858fc21b00099e568f6e0b70defd784e0d80049f795624d5bfbcf68ae4248be770076ac2d91e3fcb1b096bad084975de55c1c0ee156ae01400a00afe0a28d1d13f780395128c0ebcec51330000000049454e44ae426082</data>
+ </image>
+ <image name="image16">
+ <data format="PNG" length="1036">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000003d349444154789cad955d4c935718c77fefcb8b1d8375654851b4ad4416d88749759822ebdc3242305cf015207cc4cd091931123232b30e2f5d3243e2c7c55822178b81086431d130038b78e1dce21b8dcb00c900d18c0db715c720016d2994becf2eb05860cc64f19f9c9be79cffff3ce7fc9273145dd7791672166549ff455d01d0c285f06478623de5e5e589a2287477772faf8bf40328e14e9f165c515121f3f3f3f87c3e1c0e075eaf974d9aca2d2659ed53230be1e2ea9d8b8b8bc5ed76d3dcdc4c5c5c1c3b76ece0f467c7f8c878c8bcacf42e1f3f5291c18b4083f10285c5959c3c758ad6d656ac562b13f7ee92bfd1c4a449e168289efdab32d4d5a191e1374351442950535303c0850b17c8743aa9fce30eea8d6bdc79ef30edbed01aefbaa100e5626170fbeb7ce2f170e4c811868686c8c8c8e077037e2a39c8424616369b8d4365256b41ad07a9a8a8483a3b3b191c1ce4ecd9b3dcbf7f9fc4c4441e3c7880d96c263636965028446660862f03134f3ad4751d5dd7f12721e1a1eb3a5b3626487d7dbd1886218661486969a954555589aeeb929e9e2ec78f7f2e133775b95e53295713357914e1d5feadc3cd856fca2975036fb876a12c06f1fe3d455f5f1f8d8d8deccec8207fd34becedf91acb77177939c14a833c87e962effaf4014a0c0b1fa624937cee0c0b3f5c66f4d5ddcccecee2743ad114855da62886a682ec3ed38669f3566e65ee793aa8bb0b217aede9d4a91606141377bebf8add6ec766b381a6e12b3bc0c94706d30949cc2d04b199e3682d2f5ce6a2f8935801a9a0a040525252686b6ba3a7a7878e8e0ebc5e2f515151a4a6a6e27038989c9ca4bfbf1f97cbc56fa3a324cd4e73626e826455881663e5f1b71766496dc8c42bd97b49b3db486b68c0e170505d5d4d6d6d2d6969692082e997515efbf9470a1ffe49d28b0662183c3f67a0893ca11fa6766c638c746e35cbecbb4e0994e5c842739334969788dbed969999191111916050825f7d2157766e974b79efc8e2e56fe4dee56ef9d81a27df5a3788aeeb4b771a267f32b8815f0f7f4a5c470fdafb87f0dd1de1af1bd7c9cfcfc76c363f46aba11dac63bcee28a7032af3ee6cac7bdee2da96540ec56c5e092a373757e2e3e3e9edbdc289b6730c6c72d0b5f36d2ef943646767af81e972b9181f1f67646484989818f61ff880a9e9e92550baae53505020aaaae2f178d8b66d1be7cf9f67606000bfdf8fa669e4e4e4e0743a898e8e064044b87dfb365d5d5dd8ed76626363191b1b23100860b15896423d1e8f343535ad79435b5a5a647878189fcfb75c330c03bfdffff82634161717515595f6f6760560dfbe7da23cabef2452fff94afd5ffd032309c5843513f3e00000000049454e44ae426082</data>
+ </image>
+ <image name="image17">
+ <data format="PNG" length="527">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000001d649444154789cad94bd6e13411485bf593b71a0c146c2a1020ccf00c52e72401148aca248502081441f3a9078803c000554d0d3514488c2a141518c3c083a1e00cc4f43369158689238b22f0d331acf4c420239cd68eedd337beeb9335769ad396c247b25db7921075967e7d70540c594b6f3426edf9a63e1ce7b75509557ae6f48f4d07f413b2fa4db692af0ca3765003c7d76417ce25e3007b6f3e2ff95ba0a0daa00833495fec4595a3b9ff85c39c599e157bb7eacb43837ec07f17ee534ade117ba5a2bff274a6bcd5a96cb74af6393db692635dd0b9ae4c77d9e4102d090722ca8109e3f3a1278aa180ff93ca3340128d5b12079f3dee65faf538cd7ed345515a02e3ff9955d9629d9b6c9eff377e5f8c6878034485301d85235eacef7aed2aaf963b3b7ac5ce2c9974f02a5833495c93f8d99048aec9a34234a13a3d447cc531f319ef5f487aa07c9fd781ae359a5b12ebe5afc26ae62b377d78694366f5ea0bda765362b0923a622c6ef862d55634442bdf73aa8a80a705436310d587a3892b9a58b76efc26f94b90946e1d84071bdb9f120d9f7b87379eefbb79e1aaf008654a287b8f1179716a521250b57df842f4f6bcdcacc7dc976ded9e1b1969c607ab46ef7bbc5df4e9c6766f57150d9a10d6917bf0149be09d8da731f230000000049454e44ae426082</data>
+ </image>
+ <image name="image18">
+ <data format="PNG" length="601">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000022049444154789cbd544d6b1351143d379f6d864ea682465d48d322fe8350c6121424b571ef42a9086ebaf00f7415b7baa94217821604578a6e131a2c81e03c24bf40d1dae2424d049b843469c666ae8b38d397f9282d8a67f378e7bd7bdeb9e732434208fc6b44820e4c5de78fe1699c1f7cc666388d99c1165aa422c96d67bf1d3e87a9c11767dd8ca431b3bf05f2737a7bbec60f07f7a1bd794d32dfd72f725c188772f5b96b1cf273f96c3d4389ee370f4fe0402e9b6f30004c5a3b1811b50f00a0379ef27b2f10d5e22902802625fddb07803d7d8e4d8ac2faf36e0816e26ca24f315808814150b88b7d446086c610e65f600063dc3f709abffe9365b71d52a01a15baa13e85666c5041590681515096a1191b74537d829810c444d0de9669c2a8906a54a849c9a16836dfe0e2cb1324b731c11d0040b19426005829e788415829e7c8e6efccbf63f068ce1ab786a2b6908c9e72c613897b506bebb3e42edc21edc0a95b20b1fbd5376b19f7aebc62f74393dc0c1ed4eea5ab1c35db81825d1a47827b6090d3c11ec5612134fca2b2f906bb23889a6dc48418e14c5d679b8b01b89babf0834e010951753853d73930d3ae72f6f0de01ac962f7beafe7fa6ef6f3de2e94f2f503fad23f55de0472a8393f59ab3da7c4bbb8064f383b3af46f5a1a85fa647c1c2c236974a539e3a4fa68f9f67bc7f8d00c88272849e4c97166b47762cd7c9c61ca7c771280bf90dd971bab458732e1c67f59b45e0f4ff06bf01765c1564eeb8ff4b0000000049454e44ae426082</data>
+ </image>
+ <image name="image19">
+ <data format="PNG" length="452">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000018b49444154789cad94bd4e02511085cf6c02283f020df8136da8b4a222e49290d068dc589b6882356fe05368a9f696da8a89da68e426121b5f4134c62d600984c8168c05b98bb8a0bb614f738bbd33fbcd99b943524af82dedaf8f45dd602fe76de9902d21982691167583f7f7765029d7c92d9d25040340478b616252afb284e00e45d198cf60a3f7325ebe2a0300cece73ec0c9f4e18e32eb277a764527c36524b087ed3966184d790edd6d1a330a2dc1d91eabb4d4f4d39d87a6600785d5847fee698340c30c75fe85074485ad40d7ea8a65c3745e9b3a073ba56256541435bc1eae07d483a29a11b4f936cc2286cdbf7328f1764527c98f4678394dc8c539f4288700f412909009a854d4e707b36d210f71191f776acf27426d21625008cc6ea434b23a6baefa7a72d4af8eba9fad1bfa4d3cecb238d43dcc753e90400d00b2fc112826b81bc3f730a8c7c0d4a490e52b76f5e95aa129a14b76d7078ea65dd9914b70953b56b3bce26f542a894e0369a5a72ac5163a495729dbc6e7a19c861f1f1ca51992f4bfab7be019433035af1a435310000000049454e44ae426082</data>
+ </image>
+ <image name="image20">
+ <data format="PNG" length="496">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000001b749444154789cad944f4b1b4118879f775bb361ab348945db2248f150f00388cc4a3c94169b43a128bdf7de0fd4bb070f1e7a2901e9a12071ce822741d4937f626b23d8e82ed5d74399ed26ae66433a971766769ff799df0c23d65afef7f0b22663633436463f2c6c2940b5d6cc555fbd3b5100c9323d0e6b1a143c46be7f957e2d5fbfffa1b74c6363b4ac2dfce8b42f98b3fdf6e589744077e79614a060adb483677d41d7eb63e2e00934364627ae0f28582bcdf0ad16db477d19a6e19e03ee0dbd00a031ff494b7ac685041d3fdd559d61ba89586bd9ac7e544faf7979b58322146d432213aa6f37ee3da86aada9dd50808700d37fb639976104c5812e82a7f83db69e054c328dc4a7a897c9426c8c06edc31ec8db79ba461e80af1187de780204888aa33da1f79afe9212538dd5e48382b5e25ffe1cccb4ac2d4ec337c91d05683f7a3e986977a600c1ef83c14cd399c2df5cf7a71601f8bc3ca377d5f5fa9874cf27f7f438ace9f8465ddc21c1bf187a9966459064eac6f9c8642ea0db6aba4107b4258f39091714a0b2b692fbb94b83d20d3c80929ef160b89cdb300dca3a2c0fa031344b656d45f2bef0e99a9569e6cb3fe8b801fd070405ed1b07300000000049454e44ae426082</data>
+ </image>
+ <image name="image21">
+ <data format="PNG" length="446">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a5960000018549444154789ced95414b024114c7ff6f152b08db223d98873282fc021dc6f21015e8a50f10de3dd457a83e46f7e8d6d98282c0720e42e782b02e5b9041b9218186be2eedb0ee4eb946dd7a97997d33fffffce6bd852129257e3bc2ba645b080680ebd01ce63b37782113e3dc402d3483d9ce9defdb191bc618ccaeed376d0bc18f460cb5c51d88f226188421b4109192d2005e33cb6cb28d371a41fafc800020fda933bb3676cd6d90fbfa0e2100300804f69ef965d81445ac724c3dd76f0bc1969140eae29000e0617d8b279f2e119192bc87ea728e61365f679252fa363f67d6388c77442b674aaccb79419c50a4f7e124a684e0dbd03452dc846524302c043b4d68191318ed3671b5b4c1aa3980cf5091aee42c3e3d4af62c0689d59cc5271a9d01003ac3bdfd85be5dd21966f375369c8977b158a8f625d7e9caa53819cee427a43add3f697fd2efc672294edebcfa4fb3f93aeb8c8390ea743ed220b574c2ad7397c257d320b5d419b90f50a48310ba8d74cd52a4c542556d1864d4d594fee28dfa001f1808dc614860130000000049454e44ae426082</data>
+ </image>
+ <image name="image22">
+ <data format="PNG" length="492">89504e470d0a1a0a0000000d4948445200000015000000150806000000a917a596000001b349444154789ced94bf6b144114c73fb3b7779eec9122c64b90588414162a5888e244b7500cdc220111442336da68e79f23889585b6a6486171e081235af9a34825118c928c21a0b9c0b9c7f92c64c6cbdd1073674a1f2cb36fdebcef7ededbc728630c7b6dd14ec134b332c87a61eeab00a810699a5999bf7e893b375fab41292f5e5e97a0e8309666561a8b55053de5bb3200ee3f3a25bd893b99134c33fbefa4dd84ce3c69767563a09fe2d65e414f1afadab0949e3414d84d4f4379696625722fbdc1dd8c5328afb15855ff498727bd3bdb089206873fd75abe4c9ee7d04a1d3b7e9aeada2bb62a87499a9f589bd08caf1ab62a9324cd15ecc419aaab2ffdb9b7f131fae634d75a004ac6047db7d7a1c0e3f2156ed5eff59ddb469a6b2dadf218e5d6fadf2aa74d91226def6faa0a075e3cfb73a1d46a1fe5f3d9390118a92fa86eaa9231aafb71fb8979aeae8d3cf4a24ed08b3efd36cffe2461293e02809da9499ba2f79d6dcccc4a4bedf3ad78f2fd36363ab8ad350031c09bf8382736df532a4cfdee57344a51da942427d75a3e14a698ee2cf3231aa5f2b3c9d2b91b32dd59e65d7c94938d077d53b2679774b7fd0274cf01d1d4dbcbe90000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>Exit</sender>
+ <signal>activated()</signal>
+ <receiver>Mesh2MainWindowBase</receiver>
+ <slot>close()</slot>
+ </connection>
+ <connection>
+ <sender>lightingswitch</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lighting</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindowbase4.ui b/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindowbase4.ui new file mode 100644 index 0000000..7da1ef5 --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/mesh2mainwindowbase4.ui @@ -0,0 +1,479 @@ +<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Mesh2</string>
+ </property>
+ <widget class="QWidget" name="centralWidget" >
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>8</number>
+ </property>
+ <property name="topMargin" >
+ <number>8</number>
+ </property>
+ <property name="rightMargin" >
+ <number>8</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>8</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="normButton" >
+ <property name="text" >
+ <string>Std</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="lighting" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Lighting</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="lightingswitch" >
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="offsSlider" >
+ <property name="maximum" >
+ <number>30</number>
+ </property>
+ <property name="pageStep" >
+ <number>5</number>
+ </property>
+ <property name="value" >
+ <number>5</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ <property name="tickInterval" >
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="resSlider" >
+ <property name="minimum" >
+ <number>1</number>
+ </property>
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ <property name="tickInterval" >
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>71</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="frame" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="projection" >
+ <property name="text" >
+ <string>Ortho</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="colorlegend" >
+ <property name="text" >
+ <string>Legend</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="autoscale" >
+ <property name="text" >
+ <string>Autoscale</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="mouseinput" >
+ <property name="text" >
+ <string>Mouse</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="shader" >
+ <property name="text" >
+ <string>Shading</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string><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></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSlider" name="normalsquality" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <number>32</number>
+ </property>
+ <property name="pageStep" >
+ <number>4</number>
+ </property>
+ <property name="value" >
+ <number>3</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="invertedAppearance" >
+ <bool>true</bool>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="normalslength" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum" >
+ <number>1</number>
+ </property>
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="pageStep" >
+ <number>5</number>
+ </property>
+ <property name="value" >
+ <number>8</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="invertedAppearance" >
+ <bool>true</bool>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources>
+ <include location="../../images.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>lightingswitch</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lighting</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>181</x>
+ <y>568</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>144</x>
+ <y>568</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/lib/tqwtplot3d/examples/mesh2/src/thesis.tex b/lib/tqwtplot3d/examples/mesh2/src/thesis.tex new file mode 100644 index 0000000..cde629b --- /dev/null +++ b/lib/tqwtplot3d/examples/mesh2/src/thesis.tex @@ -0,0 +1,9 @@ +\documentclass{slides}
+\usepackage[dvips]{color}
+\usepackage{times}
+\usepackage{graphicx}
+
+\begin{document}
+\include{dump_0.pdf}
+%\include{dump3b}
+\end{document}
diff --git a/lib/tqwtplot3d/examples/movie.png b/lib/tqwtplot3d/examples/movie.png Binary files differnew file mode 100644 index 0000000..cf57682 --- /dev/null +++ b/lib/tqwtplot3d/examples/movie.png diff --git a/lib/tqwtplot3d/examples/nodata.png b/lib/tqwtplot3d/examples/nodata.png Binary files differnew file mode 100644 index 0000000..9279c36 --- /dev/null +++ b/lib/tqwtplot3d/examples/nodata.png diff --git a/lib/tqwtplot3d/examples/none.png b/lib/tqwtplot3d/examples/none.png Binary files differnew file mode 100644 index 0000000..9a50ce9 --- /dev/null +++ b/lib/tqwtplot3d/examples/none.png diff --git a/lib/tqwtplot3d/examples/normals.png b/lib/tqwtplot3d/examples/normals.png Binary files differnew file mode 100644 index 0000000..427574a --- /dev/null +++ b/lib/tqwtplot3d/examples/normals.png diff --git a/lib/tqwtplot3d/examples/polygon.png b/lib/tqwtplot3d/examples/polygon.png Binary files differnew file mode 100644 index 0000000..1b0bacf --- /dev/null +++ b/lib/tqwtplot3d/examples/polygon.png diff --git a/lib/tqwtplot3d/examples/qwtplot.png b/lib/tqwtplot3d/examples/qwtplot.png Binary files differnew file mode 100644 index 0000000..8e1ca4e --- /dev/null +++ b/lib/tqwtplot3d/examples/qwtplot.png diff --git a/lib/tqwtplot3d/examples/savecontent.png b/lib/tqwtplot3d/examples/savecontent.png Binary files differnew file mode 100644 index 0000000..06e0d8b --- /dev/null +++ b/lib/tqwtplot3d/examples/savecontent.png diff --git a/lib/tqwtplot3d/examples/scattered.png b/lib/tqwtplot3d/examples/scattered.png Binary files differnew file mode 100644 index 0000000..a23a865 --- /dev/null +++ b/lib/tqwtplot3d/examples/scattered.png diff --git a/lib/tqwtplot3d/examples/simpleplot/simpleplot.cpp b/lib/tqwtplot3d/examples/simpleplot/simpleplot.cpp new file mode 100644 index 0000000..e21ca26 --- /dev/null +++ b/lib/tqwtplot3d/examples/simpleplot/simpleplot.cpp @@ -0,0 +1,83 @@ + //-----------------------------------------------------------------
+ // simpleplot.cpp
+ //
+ // A simple example which shows how to use SurfacePlot
+ //-----------------------------------------------------------------
+
+ #include <math.h>
+ #include <qapplication.h>
+ #include <qwt3d_surfaceplot.h>
+ #include <qwt3d_function.h>
+
+
+ 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();
+ }
diff --git a/lib/tqwtplot3d/examples/simpleplot/simpleplot.pro b/lib/tqwtplot3d/examples/simpleplot/simpleplot.pro new file mode 100644 index 0000000..836dc60 --- /dev/null +++ b/lib/tqwtplot3d/examples/simpleplot/simpleplot.pro @@ -0,0 +1,3 @@ +include( ../common.pro )
+
+SOURCES = simpleplot.cpp
diff --git a/lib/tqwtplot3d/examples/wireframe.png b/lib/tqwtplot3d/examples/wireframe.png Binary files differnew file mode 100644 index 0000000..8628429 --- /dev/null +++ b/lib/tqwtplot3d/examples/wireframe.png diff --git a/lib/tqwtplot3d/include/qwt3d_autoptr.h b/lib/tqwtplot3d/include/qwt3d_autoptr.h new file mode 100644 index 0000000..15d46e5 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_autoptr.h @@ -0,0 +1,75 @@ +#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 <typename T>
+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<T>& 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 */
diff --git a/lib/tqwtplot3d/include/qwt3d_autoscaler.h b/lib/tqwtplot3d/include/qwt3d_autoscaler.h new file mode 100644 index 0000000..31c7497 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_autoscaler.h @@ -0,0 +1,51 @@ +#ifndef __qwt3d_autoscaler_2003_08_18_12_05__
+#define __qwt3d_autoscaler_2003_08_18_12_05__
+
+#include <vector>
+#include "qwt3d_global.h"
+#include "qwt3d_autoptr.h"
+
+namespace Qwt3D
+{
+
+//! ABC for autoscaler
+class QWT3D_EXPORT AutoScaler
+{
+friend class qwt3d_ptr<AutoScaler>;
+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<double>& 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<double> mantissi_;
+};
+
+} // ns
+
+
+#endif
diff --git a/lib/tqwtplot3d/include/qwt3d_axis.h b/lib/tqwtplot3d/include/qwt3d_axis.h new file mode 100644 index 0000000..08c2928 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_axis.h @@ -0,0 +1,131 @@ +#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<Qwt3D::Label> 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<Qwt3D::Scale> scale_;
+};
+
+} // ns
+
+#endif
diff --git a/lib/tqwtplot3d/include/qwt3d_color.h b/lib/tqwtplot3d/include/qwt3d_color.h new file mode 100644 index 0000000..23daf3f --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_color.h @@ -0,0 +1,63 @@ +#ifndef __COLORGENERATOR_H__
+#define __COLORGENERATOR_H__
+
+#include <qstring.h>
+#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
diff --git a/lib/tqwtplot3d/include/qwt3d_colorlegend.h b/lib/tqwtplot3d/include/qwt3d_colorlegend.h new file mode 100644 index 0000000..186840c --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_colorlegend.h @@ -0,0 +1,77 @@ +#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
diff --git a/lib/tqwtplot3d/include/qwt3d_coordsys.h b/lib/tqwtplot3d/include/qwt3d_coordsys.h new file mode 100644 index 0000000..8d536c1 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_coordsys.h @@ -0,0 +1,100 @@ +#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<Axis> 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
diff --git a/lib/tqwtplot3d/include/qwt3d_drawable.h b/lib/tqwtplot3d/include/qwt3d_drawable.h new file mode 100644 index 0000000..4324d6c --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_drawable.h @@ -0,0 +1,66 @@ +#ifndef __DRAWABLE_H__
+#define __DRAWABLE_H__
+
+
+#include <list>
+#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<Drawable*> dlist;
+};
+
+} // ns
+
+#endif
diff --git a/lib/tqwtplot3d/include/qwt3d_enrichment.h b/lib/tqwtplot3d/include/qwt3d_enrichment.h new file mode 100644 index 0000000..e4d427a --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_enrichment.h @@ -0,0 +1,62 @@ +#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
diff --git a/lib/tqwtplot3d/include/qwt3d_enrichment_std.h b/lib/tqwtplot3d/include/qwt3d_enrichment_std.h new file mode 100644 index 0000000..a17bf58 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_enrichment_std.h @@ -0,0 +1,116 @@ +#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
diff --git a/lib/tqwtplot3d/include/qwt3d_function.h b/lib/tqwtplot3d/include/qwt3d_function.h new file mode 100644 index 0000000..4351920 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_function.h @@ -0,0 +1,41 @@ +#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 */
diff --git a/lib/tqwtplot3d/include/qwt3d_global.h b/lib/tqwtplot3d/include/qwt3d_global.h new file mode 100644 index 0000000..d759107 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_global.h @@ -0,0 +1,58 @@ +#ifndef QWT3D_GLOBAL_H
+#define QWT3D_GLOBAL_H
+
+#include <qglobal.h>
+#if QT_VERSION < 0x040000
+#include <qmodules.h>
+#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
diff --git a/lib/tqwtplot3d/include/qwt3d_graphplot.h b/lib/tqwtplot3d/include/qwt3d_graphplot.h new file mode 100644 index 0000000..a1ded9f --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_graphplot.h @@ -0,0 +1,24 @@ +#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
diff --git a/lib/tqwtplot3d/include/qwt3d_gridmapping.h b/lib/tqwtplot3d/include/qwt3d_gridmapping.h new file mode 100644 index 0000000..c7893e5 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_gridmapping.h @@ -0,0 +1,34 @@ +#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 */
diff --git a/lib/tqwtplot3d/include/qwt3d_helper.h b/lib/tqwtplot3d/include/qwt3d_helper.h new file mode 100644 index 0000000..0c1bfd7 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_helper.h @@ -0,0 +1,36 @@ +#ifndef __HELPER_H__
+#define __HELPER_H__
+
+#include <math.h>
+#include <float.h>
+#include <vector>
+#include <algorithm>
+
+namespace
+{
+ inline double Min_(double a, double b)
+ {
+ return (a<b) ? a : b;
+ }
+}
+
+namespace Qwt3D
+{
+
+inline bool isPracticallyZero(double a, double b = 0)
+{
+ if (!b)
+ return (fabs (a) <= DBL_MIN);
+
+ return (fabs (a - b) <= Min_(fabs(a), fabs(b))*DBL_EPSILON);
+}
+
+inline int round(double d)
+{
+ return (d>0) ? int(d+0.5) : int(d-0.5);
+}
+
+
+} //ns
+
+#endif
diff --git a/lib/tqwtplot3d/include/qwt3d_io.h b/lib/tqwtplot3d/include/qwt3d_io.h new file mode 100644 index 0000000..aa2cd1f --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_io.h @@ -0,0 +1,141 @@ +#ifndef __qwt3d_io_2003_07_04_23_27__
+#define __qwt3d_io_2003_07_04_23_27__
+
+#include <vector>
+#include <algorithm>
+
+#include <qstring.h>
+#include <qstringlist.h>
+#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<Entry> 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
diff --git a/lib/tqwtplot3d/include/qwt3d_io_gl2ps.h b/lib/tqwtplot3d/include/qwt3d_io_gl2ps.h new file mode 100644 index 0000000..2bbeb43 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_io_gl2ps.h @@ -0,0 +1,91 @@ +#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 <time.h>
+
+#if QT_VERSION < 0x040000
+#include <qgl.h>
+#else
+#include <QtOpenGL/qgl.h>
+#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 */
diff --git a/lib/tqwtplot3d/include/qwt3d_io_reader.h b/lib/tqwtplot3d/include/qwt3d_io_reader.h new file mode 100644 index 0000000..772946c --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_io_reader.h @@ -0,0 +1,35 @@ +#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
diff --git a/lib/tqwtplot3d/include/qwt3d_label.h b/lib/tqwtplot3d/include/qwt3d_label.h new file mode 100644 index 0000000..debff42 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_label.h @@ -0,0 +1,80 @@ +#ifndef __LABELPIXMAP_H__
+#define __LABELPIXMAP_H__
+
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qfont.h>
+#include <qpainter.h>
+#include <qfontmetrics.h>
+
+#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 (<tt> QChar(0x3c0) </tt> etc.) please look at <a href="http://www.unicode.org/charts/">www.unicode.org</a>.
+ */
+ 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
diff --git a/lib/tqwtplot3d/include/qwt3d_mapping.h b/lib/tqwtplot3d/include/qwt3d_mapping.h new file mode 100644 index 0000000..be10b87 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_mapping.h @@ -0,0 +1,27 @@ +#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 <qstring.h>
+#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 */
diff --git a/lib/tqwtplot3d/include/qwt3d_multiplot.h b/lib/tqwtplot3d/include/qwt3d_multiplot.h new file mode 100644 index 0000000..1678b70 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_multiplot.h @@ -0,0 +1,24 @@ +#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
diff --git a/lib/tqwtplot3d/include/qwt3d_openglhelper.h b/lib/tqwtplot3d/include/qwt3d_openglhelper.h new file mode 100644 index 0000000..e5499c2 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_openglhelper.h @@ -0,0 +1,130 @@ +#ifndef __openglhelper_2003_06_06_15_49__
+#define __openglhelper_2003_06_06_15_49__
+
+#include "qglobal.h"
+#if QT_VERSION < 0x040000
+#include <qgl.h>
+#else
+#include <QtOpenGL/qgl.h>
+#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
diff --git a/lib/tqwtplot3d/include/qwt3d_parametricsurface.h b/lib/tqwtplot3d/include/qwt3d_parametricsurface.h new file mode 100644 index 0000000..9bcdb9f --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_parametricsurface.h @@ -0,0 +1,44 @@ +#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 */
diff --git a/lib/tqwtplot3d/include/qwt3d_plot.h b/lib/tqwtplot3d/include/qwt3d_plot.h new file mode 100644 index 0000000..668b29c --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_plot.h @@ -0,0 +1,315 @@ +#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<Qwt3D::Enrichment*> 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<GLuint> displaylists_p;
+ Qwt3D::Data* actualData_p;
+
+
+private:
+ struct Light
+ {
+ Light() : unlit(true){}
+ bool unlit;
+ Qwt3D::Triple rot;
+ Qwt3D::Triple shift;
+ };
+ std::vector<Light> 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
diff --git a/lib/tqwtplot3d/include/qwt3d_portability.h b/lib/tqwtplot3d/include/qwt3d_portability.h new file mode 100644 index 0000000..e6a6d9d --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_portability.h @@ -0,0 +1,91 @@ +#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 <qnamespace.h>
+#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 <QMouseEvent>
+
+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
diff --git a/lib/tqwtplot3d/include/qwt3d_scale.h b/lib/tqwtplot3d/include/qwt3d_scale.h new file mode 100644 index 0000000..d6619ec --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_scale.h @@ -0,0 +1,87 @@ +#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 <qstring.h>
+#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<Scale>;
+
+ 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<double> 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<Scale>;
+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<Scale>;
+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 */
diff --git a/lib/tqwtplot3d/include/qwt3d_surfaceplot.h b/lib/tqwtplot3d/include/qwt3d_surfaceplot.h new file mode 100644 index 0000000..f84f2df --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_surfaceplot.h @@ -0,0 +1,132 @@ +#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<int,int> 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
diff --git a/lib/tqwtplot3d/include/qwt3d_types.h b/lib/tqwtplot3d/include/qwt3d_types.h new file mode 100644 index 0000000..63f27d1 --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_types.h @@ -0,0 +1,455 @@ +#if defined(_MSC_VER) /* MSVC Compiler */
+#pragma warning ( disable : 4786 )
+#endif
+
+#ifndef __DATATYPES_H__
+#define __DATATYPES_H__
+
+#ifdef _DEBUG
+ #include <fstream>
+#endif
+
+#include <string>
+
+#include "qwt3d_global.h"
+
+#if defined(Q_WS_WIN)
+ #include <windows.h>
+#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 <tt>[x,y]</tt>
+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 <tt>[x,y,z]</tt>
+/**
+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<FreeVector> FreeVectorField;
+
+//! A point field in R^3
+typedef std::vector<Triple> TripleField;
+//! Holds indices in a TripleField interpreted as counterclockwise node numbering for a convex polygon
+typedef std::vector<unsigned> Cell;
+//! Vector of convex polygons. You need a TripleField as base for the node data
+typedef std::vector<Cell> 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<RGBA> 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<Vertex> DataRow;
+typedef std::vector<DataRow> 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<unsigned>& idx, const std::vector<Qwt3D::Tuple>& src );
+
+
+#endif // QWT3D_NOT_FOR_DOXYGEN
+
+} // ns
+
+#endif
diff --git a/lib/tqwtplot3d/include/qwt3d_volumeplot.h b/lib/tqwtplot3d/include/qwt3d_volumeplot.h new file mode 100644 index 0000000..da2dcbe --- /dev/null +++ b/lib/tqwtplot3d/include/qwt3d_volumeplot.h @@ -0,0 +1,24 @@ +#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
diff --git a/lib/tqwtplot3d/lingua_de.ts b/lib/tqwtplot3d/lingua_de.ts new file mode 100644 index 0000000..d553d3b --- /dev/null +++ b/lib/tqwtplot3d/lingua_de.ts @@ -0,0 +1,10 @@ +<!DOCTYPE TS><TS>
+<context>
+ <name>NativeReader</name>
+ <message>
+ <source>NativeReader::read: cannot open data file "%s"
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/lib/tqwtplot3d/qwtplot3d.pro b/lib/tqwtplot3d/qwtplot3d.pro new file mode 100644 index 0000000..d4fa0c1 --- /dev/null +++ b/lib/tqwtplot3d/qwtplot3d.pro @@ -0,0 +1,95 @@ +# 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.6
+
+# 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
+}
\ No newline at end of file diff --git a/lib/tqwtplot3d/scripts/fixvc7.py b/lib/tqwtplot3d/scripts/fixvc7.py new file mode 100644 index 0000000..968337a --- /dev/null +++ b/lib/tqwtplot3d/scripts/fixvc7.py @@ -0,0 +1,16 @@ +sourcedir = '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();
diff --git a/lib/tqwtplot3d/scripts/makedistro.py b/lib/tqwtplot3d/scripts/makedistro.py new file mode 100644 index 0000000..4af5ce5 --- /dev/null +++ b/lib/tqwtplot3d/scripts/makedistro.py @@ -0,0 +1,67 @@ +import 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()
diff --git a/lib/tqwtplot3d/scripts/makedocu.py b/lib/tqwtplot3d/scripts/makedocu.py new file mode 100644 index 0000000..b6a233d --- /dev/null +++ b/lib/tqwtplot3d/scripts/makedocu.py @@ -0,0 +1,36 @@ +import 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()
diff --git a/lib/tqwtplot3d/scripts/qwtplot3d.supp b/lib/tqwtplot3d/scripts/qwtplot3d.supp new file mode 100644 index 0000000..ebe0720 --- /dev/null +++ b/lib/tqwtplot3d/scripts/qwtplot3d.supp @@ -0,0 +1,17 @@ +{
+ 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*
+}
\ No newline at end of file diff --git a/lib/tqwtplot3d/scripts/valgr.sh b/lib/tqwtplot3d/scripts/valgr.sh new file mode 100644 index 0000000..6c3090a --- /dev/null +++ b/lib/tqwtplot3d/scripts/valgr.sh @@ -0,0 +1 @@ +valgrind --logfile=valog --suppressions=qwtplot3d.supp --error-limit=no $1
\ No newline at end of file diff --git a/lib/tqwtplot3d/src/qwt3d_autoscaler.cpp b/lib/tqwtplot3d/src/qwt3d_autoscaler.cpp new file mode 100644 index 0000000..6e785cf --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_autoscaler.cpp @@ -0,0 +1,253 @@ +#include "qwt3d_helper.h"
+#include "qwt3d_autoscaler.h"
+
+using namespace Qwt3D;
+
+namespace
+{
+
+double floorExt( int& exponent, double x, std::vector<double>& 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<double> 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<double>(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<double>& mantisse)
+{
+ init(0,1,1);
+ if (mantisse.empty())
+ {
+ mantissi_ = std::vector<double>(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_;
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_axis.cpp b/lib/tqwtplot3d/src/qwt3d_axis.cpp new file mode 100644 index 0000000..fe45f37 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_axis.cpp @@ -0,0 +1,386 @@ +#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<Scale>(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<Scale>(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;
+ }
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_color.cpp b/lib/tqwtplot3d/src/qwt3d_color.cpp new file mode 100644 index 0000000..5543a8a --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_color.cpp @@ -0,0 +1,63 @@ +#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];
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_colorlegend.cpp b/lib/tqwtplot3d/src/qwt3d_colorlegend.cpp new file mode 100644 index 0000000..2b114aa --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_colorlegend.cpp @@ -0,0 +1,223 @@ +#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();
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_coordsys.cpp b/lib/tqwtplot3d/src/qwt3d_coordsys.cpp new file mode 100644 index 0000000..2aae28d --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_coordsys.cpp @@ -0,0 +1,633 @@ +#include "qwt3d_coordsys.h"
+
+using namespace std;
+using namespace Qwt3D;
+
+
+CoordinateSystem::CoordinateSystem(Triple first, Triple second, COORDSTYLE st)
+{
+ autodecoration_ = true;
+ axes = std::vector<Axis>(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<Triple> beg(axes.size());
+ vector<Triple> end(axes.size());
+ vector<Tuple> 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<unsigned> 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);
+ }
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_dataviews.cpp b/lib/tqwtplot3d/src/qwt3d_dataviews.cpp new file mode 100644 index 0000000..7a022dd --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_dataviews.cpp @@ -0,0 +1,10 @@ +#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;
+
diff --git a/lib/tqwtplot3d/src/qwt3d_drawable.cpp b/lib/tqwtplot3d/src/qwt3d_drawable.cpp new file mode 100644 index 0000000..4025817 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_drawable.cpp @@ -0,0 +1,140 @@ +#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<Drawable*>::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<Drawable*>::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;
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_enrichment_std.cpp b/lib/tqwtplot3d/src/qwt3d_enrichment_std.cpp new file mode 100644 index 0000000..d20ffc2 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_enrichment_std.cpp @@ -0,0 +1,347 @@ +#include <math.h>
+#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;
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_function.cpp b/lib/tqwtplot3d/src/qwt3d_function.cpp new file mode 100644 index 0000000..28d874e --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_function.cpp @@ -0,0 +1,101 @@ +#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();
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_gridmapping.cpp b/lib/tqwtplot3d/src/qwt3d_gridmapping.cpp new file mode 100644 index 0000000..4de521b --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_gridmapping.cpp @@ -0,0 +1,32 @@ +#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;
+}
+
diff --git a/lib/tqwtplot3d/src/qwt3d_gridplot.cpp b/lib/tqwtplot3d/src/qwt3d_gridplot.cpp new file mode 100644 index 0000000..6543785 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_gridplot.cpp @@ -0,0 +1,596 @@ +#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 (i<columns-1 && j<rows-1)
+ {
+ /* get two vectors to cross */
+ 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]
+ );
+ /* get the normalized cross product */
+ n += normalizedcross(u,v); // right hand system here !
+ }
+
+ if (i>0 && j<rows-1)
+ {
+ 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);
+ }
+
+ if (i>0 && 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 (i<columns-1 && j>0)
+ {
+ 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<Triple> 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();
+
+
+}*/
+
diff --git a/lib/tqwtplot3d/src/qwt3d_io.cpp b/lib/tqwtplot3d/src/qwt3d_io.cpp new file mode 100644 index 0000000..c9ce46b --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_io.cpp @@ -0,0 +1,355 @@ +#include <time.h>
+
+#include "qwt3d_plot.h"
+#include "qwt3d_io_gl2ps.h"
+#include "qwt3d_io_reader.h"
+#if QT_VERSION < 0x040000
+#else
+ #include <QImageWriter>
+#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<QByteArray> list = QImageWriter::supportedImageFormats();
+ QList<QByteArray>::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);
+
+ 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"or "PDF".
+ If zlib has been configured this will be extended by "EPS_GZ" and "PS_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 text, VectorWriter::SORTMODE sortmode)
+{
+ if (format == "EPS" || format == "EPS_GZ" || format == "PS"
+ || format == "PS_GZ" || format == "PDF")
+ {
+ VectorWriter* gl2ps = (VectorWriter*)IO::outputHandler(format);
+ if (gl2ps)
+ {
+ gl2ps->setSortMode(sortmode);
+ gl2ps->setTextMode(text);
+ }
+ 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")
+ 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);
+}
+
diff --git a/lib/tqwtplot3d/src/qwt3d_io_gl2ps.cpp b/lib/tqwtplot3d/src/qwt3d_io_gl2ps.cpp new file mode 100644 index 0000000..be94e51 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_io_gl2ps.cpp @@ -0,0 +1,387 @@ +#if defined(_MSC_VER) /* MSVC Compiler */
+#pragma warning ( disable : 4786 )
+#endif
+
+#include <time.h>
+#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", "EPS",
+"PS", "PDF" (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
+ {
+ formaterror_ = true;
+ return false;
+ }
+ formaterror_ = false;
+ return true;
+}
+
+//! Performs actual output
+bool VectorWriter::operator()(Plot3D* plot, QString const& fname)
+{
+ if (formaterror_)
+ return false;
+
+ 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 +
+ " (beta) , (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);
+
+ producer += " Micha Bieber <krischnamurti@users.sourceforge.net>";
+
+ FILE *fp = fopen(QWT3DLOCAL8BIT(fname), "wb");
+ if (!fp)
+ {
+ Label::useDeviceFonts(false);
+ return false;
+ }
+ while( state == GL2PS_OVERFLOW )
+ {
+ bufsize += 2*1024*1024;
+ gl2psBeginPage ( "---", 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);
+ 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(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);
+
+ 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);
+}
+
diff --git a/lib/tqwtplot3d/src/qwt3d_io_reader.cpp b/lib/tqwtplot3d/src/qwt3d_io_reader.cpp new file mode 100644 index 0000000..2cc57a7 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_io_reader.cpp @@ -0,0 +1,225 @@ +#if defined(_MSC_VER) /* MSVC Compiler */
+#pragma warning ( disable : 4786 )
+#endif
+
+#include <float.h>
+#include <stdio.h>
+#include <qtextstream.h>
+
+#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;
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_label.cpp b/lib/tqwtplot3d/src/qwt3d_label.cpp new file mode 100644 index 0000000..eb8b8c0 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_label.cpp @@ -0,0 +1,262 @@ +#include <qbitmap.h>
+#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());
+ 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();
+#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();
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_lighting.cpp b/lib/tqwtplot3d/src/qwt3d_lighting.cpp new file mode 100644 index 0000000..2f368a0 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_lighting.cpp @@ -0,0 +1,192 @@ +#if defined(_MSC_VER) /* MSVC Compiler */
+#pragma warning ( disable : 4305 )
+#pragma warning ( disable : 4786 )
+#endif
+
+#include <float.h>
+#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();
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_meshplot.cpp b/lib/tqwtplot3d/src/qwt3d_meshplot.cpp new file mode 100644 index 0000000..0c975fe --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_meshplot.cpp @@ -0,0 +1,320 @@ +#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;
+}
+
+
diff --git a/lib/tqwtplot3d/src/qwt3d_mousekeyboard.cpp b/lib/tqwtplot3d/src/qwt3d_mousekeyboard.cpp new file mode 100644 index 0000000..800bc06 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_mousekeyboard.cpp @@ -0,0 +1,387 @@ +#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_;
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_movements.cpp b/lib/tqwtplot3d/src/qwt3d_movements.cpp new file mode 100644 index 0000000..73ff9b1 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_movements.cpp @@ -0,0 +1,106 @@ +#if defined(_MSC_VER) /* MSVC Compiler */
+#pragma warning ( disable : 4305 )
+#pragma warning ( disable : 4786 )
+#endif
+
+#include <float.h>
+#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);
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_parametricsurface.cpp b/lib/tqwtplot3d/src/qwt3d_parametricsurface.cpp new file mode 100644 index 0000000..c3103c9 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_parametricsurface.cpp @@ -0,0 +1,104 @@ +#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();
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_plot.cpp b/lib/tqwtplot3d/src/qwt3d_plot.cpp new file mode 100644 index 0000000..e61b125 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_plot.cpp @@ -0,0 +1,498 @@ +#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<GLuint>(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<Light>(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();
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_scale.cpp b/lib/tqwtplot3d/src/qwt3d_scale.cpp new file mode 100644 index 0000000..ecac454 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_scale.cpp @@ -0,0 +1,304 @@ +#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 (idx<majors_p.size())
+ {
+ return QString::number(majors_p[idx]);
+ }
+ return QString("");
+}
+
+//! Sets start and stop value for the scale;
+void Scale::setLimits(double start, double stop)
+{
+ if (start < stop)
+ {
+ start_p = start;
+ stop_p = stop;
+ return;
+ }
+ start_p = stop;
+ stop_p = start;
+}
+
+//! Sets value of first major tic
+void Scale::setMajorLimits(double start, double stop)
+{
+ if (start < stop)
+ {
+ mstart_p = start;
+ mstop_p = stop;
+ return;
+ }
+ mstart_p = stop;
+ mstop_p = start;
+}
+
+/*!
+ \param a First major tic after applying autoscaling
+ \param b Last major tic after applying autoscaling
+ \param start Scale begin
+ \param stop Scale end
+ \param ivals Requested number of major intervals
+ \return Number of major intervals after autoscaling\n
+
+ The default implementation sets a=start, b=stop and returns ivals.
+*/
+int Scale::autoscale(double& a, double& b, double start, double stop, int ivals)
+{
+ a = start;
+ b = stop;
+ return ivals;
+}
+
+/***************************
+*
+* linear scales
+*
+***************************/
+
+
+//! Applies LinearAutoScaler::execute()
+int LinearScale::autoscale(double& a, double& b, double start, double stop, int ivals)
+{
+ return autoscaler_p.execute(a, b, start, stop, ivals);
+}
+
+//! Creates the major and minor vector for the scale
+void LinearScale::calculate()
+{
+ majors_p.clear();
+ minors_p.clear();
+
+ double interval = mstop_p-mstart_p;
+
+ double runningval;
+ int i=0;
+
+ // majors
+
+ // first tic
+// if (mstart_p<start_p || mstop_p>stop_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<stop_p)
+ {
+ minors_p.push_back(runningval);
+ runningval += step;
+ }
+}
+
+void LogScale::setupCounter(double& k, int& step)
+{
+ switch(minorintervals_p)
+ {
+ case 9:
+ k=9;
+ step=1;
+ break;
+ case 5:
+ k=8;
+ step=2;
+ break;
+ case 3:
+ k=5;
+ step=3;
+ break;
+ case 2:
+ k=5;
+ step=5;
+ break;
+ default:
+ k=9;
+ step=1;
+ }
+}
+
+/*! Creates major and minor vectors for the scale.
+\warning If the interval is too small, the scale becomes empty
+or will contain only a single major tic. There is no automatism
+(also not planned for now) for an 'intelligent' guess, what to do.
+Better switch manually to linear to scales in such cases.
+*/
+void LogScale::calculate()
+{
+ majors_p.clear();
+ minors_p.clear();
+
+ if (start_p < DBL_MIN_10_EXP)
+ start_p = DBL_MIN_10_EXP;
+ if (stop_p > 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<majors_p.size())
+ {
+ double val = majors_p[idx];
+ return QString::number(pow(double(10), val));
+ }
+ return QString("");
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_surfaceplot.cpp b/lib/tqwtplot3d/src/qwt3d_surfaceplot.cpp new file mode 100644 index 0000000..3caae31 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_surfaceplot.cpp @@ -0,0 +1,183 @@ +#include "qwt3d_surfaceplot.h"
+
+using namespace std;
+using namespace Qwt3D;
+
+/**
+Initializes with dataNormals()==false, NOFLOOR, resolution() == 1
+*/
+#if QT_VERSION < 0x040000
+SurfacePlot::SurfacePlot( QWidget* parent, const char* name )
+ : Plot3D( parent, name )
+#else
+SurfacePlot::SurfacePlot( QWidget * parent, const QGLWidget * shareWidget)
+ : Plot3D( parent, shareWidget)
+#endif
+{
+ datanormals_p = false;
+ normalLength_p = 0.02;
+ normalQuality_p = 3;
+
+ resolution_p = 1;
+ actualDataG_ = new GridData();
+ actualDataC_ = new CellData();
+
+ actualData_p = actualDataG_;
+
+ floorstyle_ = NOFLOOR;
+}
+
+SurfacePlot::~SurfacePlot()
+{
+ delete actualDataG_;
+ delete actualDataC_;
+}
+
+void SurfacePlot::showNormals(bool b)
+{
+ datanormals_p = b;
+}
+
+/**
+Values < 0 or > 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<int,int> SurfacePlot::facets() const
+{
+ if (!hasData())
+ return pair<int,int>(0,0);
+
+ if (actualData_p->datatype == Qwt3D::POLYGON)
+ return pair<int,int>(int(actualDataC_->cells.size()), 1);
+ else if (actualData_p->datatype == Qwt3D::GRID)
+ return pair<int,int>(actualDataG_->columns(), actualDataG_->rows());
+ else
+ return pair<int,int>(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();
+}
diff --git a/lib/tqwtplot3d/src/qwt3d_types.cpp b/lib/tqwtplot3d/src/qwt3d_types.cpp new file mode 100644 index 0000000..b6f3a4d --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_types.cpp @@ -0,0 +1,222 @@ +#if defined(_MSC_VER) /* MSVC Compiler */
+#pragma warning ( disable : 4786 )
+#endif
+
+#include <stdlib.h> // qsort
+#include <algorithm>
+#include <float.h>
+#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<n; i++) {
+ for (j=s; j>=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<DataRow>(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<DataRow>(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<unsigned>& idx, const std::vector<Tuple>& 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<m; ++i)
+ {
+ idx[i] = (points[i] - start)/2;
+ }
+ delete [] points;
+ delete [] P;
+}
+
+unsigned Qwt3D::tesselationSize(CellField const& t)
+{
+ unsigned ret = 0;
+
+ for (unsigned i=0; i!=t.size(); ++i)
+ ret += t[i].size();
+
+ return ret;
+}
+
+#endif // QWT3D_NOT_FOR_DOXYGEN
|