Codebase list evolvotron / 9f44cf5
Imported Upstream version 0.6.1 Axel Beckert 11 years ago
83 changed file(s) with 1487 addition(s) and 1455 deletion(s). Raw diff Collapse all Expand all
00 [Most recent at top]
1
2 From release 0.6.0:
3 - Version to 0.6.1
4 - Fix bug in saved functions: quotes missing around version attribute
5
6 From release 0.5.1:
7 - Version to 0.6.0
8 - Switch to Qt4.
9 - (Qt4 related) keyboard shortcuts rationalized
10 many removed, ctrl-modifiers dropped
11 - (Qt4 related) image displays now have a frame around them
12 - (Qt4 related) Remove non-standard Qt animated PNG support
13 - evolvotron_match removed
14 - Platform specific code (e.g number of processors identification)
15 isolated in libevolvotron/platform_specific.[h|cpp]
16 and selected by PLATFORM_LINUX or PLATFORM_BSD
17 (Fink Qt's __DARWIN_X11__ also detected and used to select PLATFORM_BSD).
18 - Repository migrated to svn
119
220 From release 0.5.0:
321 - Version to 0.5.1
9797 you probably need to install a Qt development tools package
9898 of some sort before you can build evolvotron.
9999
100 The 0.5.0 code is believed to build against Boost 1.33 or 1.34.
100 The 0.6.0 code builds against Boost 1.35
101
102 Non-linux platform issues
103 -------------------------
104 On the whole, Qt does an excellent job of insulating code from
105 platform specific details. However, there is a little bit of
106 linux-specific code in evolvotron.
107
108 If you don't have a PLATFORM_... define set, you'll get some warnings
109 about no default implementations of functions in platform_specific.cpp,
110 but should still get a working evolvotron (although missing some functionality
111 with regard to automatically choosing how many threads to run and controlling
112 thread priority).
113
114 All the platform specific code should live in
115 libevolvtron/platform_specific.cpp
116 and is selected by compile options
117 -DPLATFORM_LINUX or -DPLATFORM_BSD
118 (with more potentially addable for other platforms).
119
120 Setting the appropriate build options is most easily set by editing
121 an appropriate
122 DEFINES+=PLATFORM_LINUX
123 or
124 DEFINES+=PLATFORM_BSD
125 near the top of the
126 common.pro
127 file. Qt doesn't make a fine enough distinction between unix platforms
128 to decide completely automatically, and the situation is further complicated
129 by e.g Fink's Qt not considering itself to be a Qt 'macx' build.
101130
102131 Long story
103132 ----------
104133 [These days the author primarily develops on Debian stable
105134 or testing. The comments below re RedHat are based on experience
106 with RH8&9; they may or may not be applicable to Fedora.]
135 with the now very old RH 8 & 9; they may or may not be applicable
136 to Fedora.]
107137
108138 QTDIR should point to your Qt installation. Your Qt installation
109139 should be a directory somewhere (it might be /usr/share/qt3, it
166196
167197 BUILDING ON OTHER PLATFORMS
168198 ===========================
199 [Very old information now!]
169200
170201 Linc Davis reports:
171202 "I built it on a Mac with Qt installed via Fink (if you know what that is.)
221252 An unsuccessful experiment:
222253 ./evolvotron_match/evolvotron_match
223254
224 There are NO extra supporting files
225 (e.g libraries, config files, resource files)
255 There are NO extra supporting files built
256 (e.g shared libraries, config files, "resource" files)
226257 which need to be in special places for the software to work.
258
259 PACKAGING
260 =========
261 There are a few things which might be useful to packagers:
262
263 mkdeb
264 - script to build .deb files (using the strangely unpopular
265 "yada", and pbuilder). This is used to build the .debs put
266 up on sourceforge, but the "official" Debian ones (and Ubuntu
267 derivatives) are more conventionally packaged by Gurkan Sengun.
268
269 rpm/
270 - directory for contributed RPM related resources.
227271
228272 BUILDING CODE DOCUMENTATION
229273 ===========================
234278 The code documentation then appears in ./doc/html/
235279 This hasn't been tested in a long while now, although the
236280 doxygen commenting style has been kept up.
237
00 Proximity to one end or the other of this list does not necessarily
11 imply it will be done sooner or later than other items!
22
3 Consequences of Qt4 port
4 ------------------------
5 mutableimagedisplay actions need attention - hmmm shorcuts would need to be installed for the grid, then dispatched.
6 Margins in display grid - add command line option to control size ?
7 Why was DialogMutatableImageDisplay created with :QDialog(parent,0,TRUE) ?
8 EvolvotronMain destructor called on close ?
9 statusbar needs right justification ?
10 New-style include files; move to common
11 Lots of Qthingy* stuff needn't be declared in headers; clean up
12
313 Conventional Mode
414 -----------------
15 - Use "headache" to manage all copyright notices
16 - Just make "fullscreen mode support" be the default (and remove text in USAGE).
17 - Link on webpage to gallery http://gigrafx.110mb.com/evolvotron/index.html
18 - Mouse manipulations: frame rate should be clamped to allow some time to produce a nice image
19 - At least split out evolvotron_main_history.cpp, even if the class remains nested in .h
20 - Smaller fragments for big enlargements; seeing unused processors.
521 - More feedback on when enlargements are ready for saving (have split tasks count now... need more ? yes)
22
23 - Enlargement menu: submenus for square, 4:3, 8:5, 16:9. 5:4 SXGA 1024x1024 is a bit of an oddball.
24 And name them, see http://en.wikipedia.org/wiki/Computer_display_standard
625
726 - Friezegroups:
827 Cut taken out for 0.5.0 release.
+36
-41
USAGE less more
6262 evolvotron actions which bring up dialog boxes (e.g save) seem
6363 to generally behave fairly sensibly but child windows
6464 (e.g enlargements or dialogs) can show some "interesting" behaviour.
65 Fullscreen mode can be toggled within the application using ctrl-f.
66 The Esc key will also exit it.
65 Fullscreen mode can be toggled within the application using "F" key.
66 The "Esc" key will also exit it.
6767
6868 -g <cols> <rows>
6969 Sets number of image display cells (defaults to 6 by 5)
104104
105105 -t <threads>
106106 Sets number of compute threads.
107 If this is not specified, as many compute threads are created
107 If this is not specified, then as many compute threads are created
108108 as there are processors on the system (unless this cannot be
109 discovered, in which case only a single compute thread is created).
109 discovered in which case only a single compute thread is created).
110 Non-linux builds will likely not include code to determine processor count
111 (suitable patches gratefully received).
110112
111113 ANIMATION OPTIONS
112114 -----------------
205207 mode is probably what you want in this case as the image will
206208 automatically be rendered at the correct resolution).
207209
208 - "Save image" to save the image in a file (.ppm, .png or .qt-mng
209 format; qt-mng is Qt's proprietary version of MNG and not very
210 useful). You generally want to save an enlarged image: if you
210 - "Save image" to save the image in a file (.ppm or .png).
211 You generally want to save an enlarged image: if you
211212 save a small image from the grid, the size you see on the screen
212213 is the size you get in the file. Save isn't allowed until the
213214 full resolution image has been generated; if you try to save too
234235
235236 MIDDLE MOUSE BUTTON
236237 -------------------
237 [NB This feature will probably only be of practical use to those with multi-GHz machines].
238 [NB This feature will probably only be of practical use to those with high-end machines].
238239
239240 You can use the middle mouse button to drag-adjust individual images.
240241 This is useful for "final composition" type tweaks, e.g centering an
274275 KEYBOARD CONTROL
275276 ================
276277
278 There are some keyboard shortcuts.
279
277280 MAIN WINDOW
278281 -----------
279282
280 - Ctrl-f [NB only available with fullscreen build option] toggles
283 - "r"/"t"/"x" perform various starts of reset/restart.
284
285 - "q" quits the application.
286
287 - "u" (and also Ctrl-z) does an undo.
288
289 - "f": [NB only available with fullscreen build option] toggles
281290 full-screen mode (on X11, Qt does this by asking the
282291 window manager for a screen-filling undecorated window, and the
283292 documentation contains some dire warnings about problems with broken
286295 NB The application may completely disappear from the screen for
287296 a brief interval while switching mode.
288297
289 - Ctrl-m [NB only available with fullscreen build option]
290 toggles status and menu-bar hiding, which can be nice
291 when in full-screen or window-maximised mode. See also "-M"
292 command line option.
293
294 - Esc [NB only available with fullscreen build option] kills
298 - "m" : [NB only available with fullscreen build option]
299 hides status and menu-bar hiding, which can be nice when
300 in full-screen or window-maximised mode. See also "-M"
301 command line option. Also note that while the menu bar
302 is hidden, most of these keyboard shortcuts won't function
303 as they're tied to the menu system.
304
305 - Esc : [NB only available with fullscreen build option] kills
295306 full-screen and/or menu-hiding, putting the application
296307 into its normal default state.
297
298 - Ctrl-r does a restart (for convenience when the menu bar
299 is hidden, because this is such a common operation).
300
301 - Ctrl-z does an undo.
302308
303309 ENLARGEMENT WINDOWS
304310 -------------------
305311 The image display windows created by selecting "Enlarge" from a
306312 context menu also have a couple of keyboard operations:
307313
308 - Ctrl-f [NB only available with fullscreen build option] toggles
314 - "f" : [NB only available with fullscreen build option] toggles
309315 full-screen mode. When returning to normal mode, if the main app
310316 window was fullscreen then it will also drop back to normal mode.
311317
312 - Esc [NB only available with fullscreen build option]
318 - Esc : [NB only available with fullscreen build option]
313319 completely closes a fullscreen-mode enlargement window.
314320
315321 GUI ELEMENTS
423429 an animated GIF playing at approx. 8 frames per second with:
424430 $ convert -delay 12 foo.f??????.ppm foo.gif
425431
426 If you save an animation as "QT-MNG" a single file will be
427 generated. NB THIS IS IN A PROPRIETARY QT FORMAT WHICH PREDATES
428 MULTI-FRAME PNG (also known as MNG) AND IS UNLIKELY TO BE
429 READABLE BY ANYTHING OTHER THAN QT PROGRAMS. So it's not
430 actually very useful. Image viewers will generally recognise
431 it as PNG and display the first frame, but that's all.
432
433432 ADVANCED USAGE
434433 ==============
435434 Evolvotron's idea of an image is a function which converts
541540 as evolvotron in its default state) and writes the new function's XML
542541 representation to the standard output.
543542
544 $ evolvotron_match [-v] image[.ppm | .png]
545 An experiment in replacing the human operator with a simple scoring function
546 (minimise sum-of-squares of pixel value differences between evolvotron
547 image and image specified on command line). Outputs f??????.png whenever
548 it finds a better match. Terminates after 10000000 iterations and writes
549 match.png. However, all it has ever done so far is to converge with the
550 average colour of the target image.
551
552543 EXAMPLES
553544 --------
554545
586577 - Goetz Waschk
587578 - Forrest Walter
588579
580 And to the anonymous Linspire reviewer who perhaps came up with the best
581 summary of evolvotron yet: "Fascinating. Utterly pointless, but fascinating."
582
589583 The friezegroups wouldn't have been possible without
590584 http://michaelshepperd.tripod.com/resources/groups.html
591585
592 And to www.di.fm, www.somafm.com and Trance4Ever for music to code to.
593
594 But especially to a SIGGRAPH conference panel many years ago (likely
595 including Karl Sims) who first got me interested in this kind of thing.
586 Thanks to www.di.fm, www.somafm.com and Trance4Ever for music to code to.
587
588 Thanks especially to a SIGGRAPH conference panel many years ago (likely
589 including Karl Sims, the pioneer in this area) who first got me interested
590 in this stuff.
596591
597592 WHY ?
598593 =====
44
55 # NB If you edit this, "make distclean" and then rebuild (./BUILD) as there is no dependency checking
66
7 echo "0.5.1"
7 echo "0.6.1"
22
33 # append debug or release
44 CONFIG+= qt thread stl precompile_header exceptions release #release #debug
5 QT += xml
6
7 #######################################
8 # Control platform specific code
9 # (the Qt platform scopes don't seem that useful; might be easier to just add DEFINES+=... explicitly
10
11 unix {
12 DEFINES+=PLATFORM_LINUX # of course PLATFORM_BSD is more appropriate to some unices
13 }
14
15 macx {
16 # NB This doesn't actually seem to be selected on Fink builds
17 # (presumably it applies to Quartz builds instead)
18 # Fink does seem to have a useful __DARWIN_X11__ define though,
19 # which is used to set PLATFORM_BSD in libevolvotron/platform_specific.cpp
20 DEFINES+=PLATFORM_BSD
21 }
22
23 win32 {
24 # You might want to add some appropriate code to libevolvotron/platform_specific.cpp
25 # and set a #define here to select it
26 }
527
628 #######################################
729 # Version numbering. VERSION_NUMBER should have been set on the qmake command line (see .configure script)
2648 # NB We don't use the corresponding -DQT_NO_CAST_ASCII because it breaks QString("...") which is used all over the place
2749 # This probably wouldn't be usable until all the strings were moved out of the app - see Qt I18N docs.
2850 # Also add gcc threading option (not entirely clear whether this is needed but it doesn't seem to hurt)
29
30 QMAKE_CXXFLAGS_RELEASE += -DQT_NO_ASCII_CAST -pthread
31 QMAKE_CXXFLAGS_DEBUG += -DQT_NO_ASCII_CAST -pthread
51 # -DBOOST_SP_USE_PTHREADS is a workround for debian bug 485434 (maybe only needed on sparc?)
52 QMAKE_CXXFLAGS_RELEASE += -DQT_NO_ASCII_CAST -pthread -DBOOST_SP_USE_PTHREADS
53 QMAKE_CXXFLAGS_DEBUG += -DQT_NO_ASCII_CAST -pthread -DBOOST_SP_USE_PTHREADS
3254
3355 ######################################
3456 # Hide those crufty moc_ files away
1111 # TODO?: Should perhaps test "which qmake" here.
1212 # If not found, add $(QTDIR)/bin to path. But the ./BUILD script does that.
1313 echo "Your qmake version is:"
14 qmake --version
14 qmake-qt4 --version
1515
1616 echo
1717 echo "Your gcc version is (unless qmake is set up to use a different one):"
2828 VERSION_NUMBER=`./VERSION`
2929
3030 echo
31 echo "Running qmake with CONFIG_OPTS=$CONFIG_OPTS VERSION_NUMBER=$VERSION_NUMBER..."
31 echo "Running qmake-qt4 with CONFIG_OPTS=$CONFIG_OPTS VERSION_NUMBER=$VERSION_NUMBER..."
3232
33 qmake "CONFIG_OPTS=$CONFIG_OPTS" "VERSION_NUMBER=$VERSION_NUMBER" main.pro
33 qmake-qt4 "CONFIG_OPTS=$CONFIG_OPTS" "VERSION_NUMBER=$VERSION_NUMBER" main.pro
3434
3535 echo "...configuration completed - ready to do 'make' now"
3434 #include "evolvotron_precompiled.h"
3535
3636 #include "args.h"
37 #include "platform_specific.h"
38
3739 #include "evolvotron_main.h"
3840
3941 //! Application code
6264 exit(1);
6365 }
6466
65 uint threads=1;
67 uint threads=get_number_of_processors();
6668
6769 if (args.option("-t",1))
6870 {
6971 args.after() >> threads;
7072 if (threads<1)
7173 {
72 std::cerr << "Must specify at least one compute thread (option: -t <threads>)\n";
74 std::cerr << "Must specify at least one thread for option -t <threads>)\n";
7375 exit(1);
7476 }
7577 }
76 else
77 {
78 /*! \todo: People porting to non-Linux (BSD, MacOS, Fink etc) please send
79 a suitable #ifdef-able patch if you need something different here.
80 */
81 cpu_set_t cpus;
82 if (sched_getaffinity(0,sizeof(cpu_set_t),&cpus)!=0)
83 {
84 std::cerr << "Could not determine number of CPUs; defaulting to " << threads << " compute thread\n";
85 }
86 else
87 {
88 threads=0;
89 for (int i=0;i<CPU_SETSIZE;i++)
90 {
91 if (CPU_ISSET(i,&cpus)) threads++;
92 }
93 }
94 }
78
9579 std::clog << "Using " << threads << " threads\n";
9680
9781 int niceness_grid=4;
144128
145129 std::clog
146130 << "Evolvotron version "
147 << EVOLVOTRON_BUILD
131 << stringify(EVOLVOTRON_BUILD)
148132 << " starting with "
149133 << cols
150134 << " by "
194178 main_widget->favourite_function_unwrapped(favourite_function_unwrapped);
195179 }
196180
197 app.setMainWidget(main_widget);
198181 main_widget->show();
199
182
200183 // NB Do this here rather than in constructor so that compute threads aren't being fired off during general GUI set-up
201184
202185 std::clog << "Resetting main widget...\n";
203186 main_widget->reset_cold();
204
187
205188 // NB No need to worry about deleting EvolvotronMain... QApplication seems to do it for us.
206189 std::clog << "Commencing main loop...\n";
207190 return app.exec();
2424
2525 #include "libevolvotron_precompiled.h"
2626
27 // Used for determining number of processors.
28 #include <sched.h>
29
3027 #endif
+0
-222
evolvotron_match/evolvotron_match.cpp less more
0 // Source file for evolvotron
1 // Copyright (C) 2004 Tim Day
2 /*! \page License License
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /*! \file
20 \brief Mutate functions searching for a match to a given image.
21 */
22
23 #include "evolvotron_match_precompiled.h"
24
25 #include "args.h"
26 #include "mutatable_image.h"
27 #include "mutation_parameters.h"
28
29 //! A QImage which deletes it's data on destruction
30 class QImageWithData
31 {
32 public:
33 QImageWithData(uchar* data,int w,int h,int depth,QRgb* colortable,int numColors,QImage::Endian bitOrder)
34 :_image(new QImage(data,w,h,depth,colortable,numColors,bitOrder))
35 ,_data(data)
36 {}
37
38 virtual ~QImageWithData()
39 {}
40
41 QImage*const image()
42 {
43 return _image.get();
44 }
45 const QImage*const image() const
46 {
47 return _image.get();
48 }
49
50 protected:
51 const std::auto_ptr<QImage> _image;
52 const std::auto_ptr<uchar> _data;
53 };
54
55 //! Render a new QImage of the given mutatable image
56 QImageWithData*const render_image(const MutatableImage*const imagefn,int width,int height)
57 {
58 uint*const image_data=new uint[width*height];
59 uint* pixel=image_data;
60
61 for (int row=0;row<height;row++)
62 for (int col=0;col<width;col++,pixel++)
63 {
64 // xy co-ords vary over -1.0 to 1.0. In the one frame case z will be 0
65 const XYZ p(
66 -1.0+2.0*(col+0.5)/width,
67 1.0-2.0*(row+0.5)/height,
68 0.0
69 );
70
71 const XYZ c(imagefn->get_rgb(p));
72
73 const uint col0=lrint(clamped(c.x(),0.0,255.0));
74 const uint col1=lrint(clamped(c.y(),0.0,255.0));
75 const uint col2=lrint(clamped(c.z(),0.0,255.0));
76
77 *pixel=((col0<<16)|(col1<<8)|(col2));
78 }
79
80 return new QImageWithData
81 (
82 reinterpret_cast<uchar*>(image_data),
83 width,
84 height,
85 32,
86 0,
87 0,
88 QImage::LittleEndian
89 );
90 }
91
92 const double compare_images(const QImage* src0,const QImage* src1)
93 {
94 double t=0.0;
95
96 assert(src0->width()==src1->width() && src0->height()==src1->height());
97
98 for (int y=0;y<src0->height();y++)
99 {
100 for (int x=0;x<src0->width();x++)
101 {
102 //! \todo Optimise pixel accesses.
103 const QRgb col0(src0->pixel(x,y));
104 const QRgb col1(src1->pixel(x,y));
105
106 const real r0=qRed(col0);
107 const real r1=qRed(col1);
108 const real g0=qGreen(col0);
109 const real g1=qGreen(col1);
110 const real b0=qBlue(col0);
111 const real b1=qBlue(col1);
112 t+=sqr(r0-r1)+sqr(g0-g1)+sqr(b0-b1);
113 }
114 }
115
116 return t/(255.0*src0->width()*src0->height());
117 }
118
119 //! Application code
120 int main(int argc,char* argv[])
121 {
122 {
123 Args args(argc,argv);
124
125 if (args.option("-v"))
126 std::clog.rdbuf(std::cerr.rdbuf());
127 else
128 std::clog.rdbuf(sink_ostream.rdbuf());
129
130 // Normally would use time(0) to seed random number generator
131 // but can imagine several of these starting up virtually simultaneously
132 // so need something with higher resolution.
133 // Adding the process id too to keep things unique.
134
135 QTime t(QTime::currentTime());
136 uint seed=getpid()+t.msec()+1000*t.second()+60000*t.minute()+3600000*t.hour();
137 std::clog << "Random seed is " << seed << "\n";
138
139 MutationParameters mutation_parameters(seed,false,false);
140
141 if (argc<2)
142 {
143 std::cerr << "Must supply a filename\n";
144 exit(1);
145 }
146
147 QImage target_image(args.last(1).c_str());
148 if (target_image.isNull())
149 {
150 std::cerr << "Couldn't load target image\n";
151 exit(1);
152 }
153
154 const uint fresh=10;
155 const uint reset=100;
156 const real cooling=0.9;
157 const uint iterations=10000000;
158
159 std::clog << "Cumulative cooling effect is " << pow(cooling,reset) << " over cycle\n";
160
161 double best_score=0.0;
162 boost::shared_ptr<const QImageWithData> best_image;
163 boost::shared_ptr<const MutatableImage> best_imagefn;
164
165 for (uint i=0,output_frame=0;i<iterations;i++)
166 {
167 if (i%reset==0)
168 {
169 mutation_parameters.reset();
170 }
171 else
172 {
173 mutation_parameters.general_cool(cooling);
174 }
175
176 boost::shared_ptr<const MutatableImage> new_imagefn;
177
178 if (best_imagefn==0 || i%fresh==0)
179 {
180 do
181 {
182 new_imagefn=boost::shared_ptr<const MutatableImage>(new MutatableImage(mutation_parameters,true,true,false));
183 }
184 while (new_imagefn->is_constant());
185 }
186 else
187 {
188 new_imagefn=boost::shared_ptr<const MutatableImage>(best_imagefn->mutated(mutation_parameters));
189 }
190
191
192 boost::shared_ptr<const QImageWithData> new_image
193 =boost::shared_ptr<const QImageWithData>(render_image(new_imagefn.get(),target_image.width(),target_image.height()));
194
195 const double score=compare_images(new_image->image(),&target_image);
196
197 if (best_image.get()==0 || score<best_score)
198 {
199 best_score=score;
200 best_image=new_image;
201 best_imagefn=new_imagefn;
202 std::stringstream filename;
203 filename << "f" << std::setw(6) << std::setfill('0') << output_frame++ << ".png";
204 best_image->image()->save(filename.str().c_str(),"PNG");
205 std::clog << "[" << best_score << "]";
206 }
207 else
208 {
209 std::clog << ".";
210 }
211 }
212
213 best_image->image()->save("match.png","PNG");
214 }
215
216 #ifndef NDEBUG
217 assert(InstanceCounted::is_clear());
218 #endif
219
220 exit(0);
221 }
+0
-13
evolvotron_match/evolvotron_match.pro less more
0 TEMPLATE = app
1
2 include (../common.pro)
3
4 PRECOMPILED_HEADER = evolvotron_match_precompiled.h
5
6 SOURCES += evolvotron_match.cpp
7
8 DEPENDPATH += ../libevolvotron ../libfunction
9 INCLUDEPATH += ../libevolvotron ../libfunction
10
11 TARGETDEPS += ../libevolvotron/libevolvotron.a ../libfunction/libfunction.a
12 LIBS += ../libevolvotron/libevolvotron.a ../libfunction/libfunction.a
+0
-28
evolvotron_match/evolvotron_match_precompiled.h less more
0 // Source file for evolvotron
1 // Copyright (C) 2007 Tim Day
2 /*
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version 2
6 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 /*! \file
19 \brief Precompiled header for evolvotron_match
20 */
21
22 #ifndef _evolvotron_match_precompiled_h_
23 #define _evolvotron_match_precompiled_h_
24
25 #include "libevolvotron_precompiled.h"
26
27 #endif
108108 QString save_filename(QString::fromLocal8Bit(args.last(1).c_str()));
109109
110110 const char* save_format="PPM";
111 if (save_filename.upper().endsWith(".PPM"))
111 if (save_filename.toUpper().endsWith(".PPM"))
112112 {
113113 save_format="PPM";
114114 }
115 else if (save_filename.upper().endsWith(".PNG"))
115 else if (save_filename.toUpper().endsWith(".PNG"))
116116 {
117117 save_format="PNG";
118118 }
128128 {
129129 QString frame_component;
130130 frame_component.sprintf(".f%06d",frame);
131 int insert_point=save_filename.findRev(QString("."));
131 int insert_point=save_filename.lastIndexOf(QString("."));
132132 if (insert_point==-1)
133133 {
134134 save_filename.append(frame_component);
140140 }
141141
142142 QImage image(
143 (uchar*)&(image_data[0]),
143 reinterpret_cast<uchar*>(&(image_data[0])),
144144 width,
145145 height,
146 32,
147 0,
148 0,
149 QImage::LittleEndian
146 QImage::Format_RGB32
150147 );
151148
152149 if (!image.save(save_filename,save_format))
153150 {
154151 std::cerr
155152 << "evolvotron_render: Error: Couldn't save file "
156 << save_filename.local8Bit()
153 << save_filename.toLocal8Bit().data()
157154 << "\n";
158155 exit(1);
159156 }
160157
161158 std::clog
162159 << "Wrote file "
163 << save_filename.local8Bit()
160 << save_filename.toLocal8Bit().data()
164161 << "\n";
165162 }
166163 }
0 #include <stdexcept>
1
2 #include <QApplication>
3 #include <QGLWidget>
4 #include <QSvgRenderer>
5
6 #include <QtOpenGL/qgl.h>
7
8 #include <QtSvg>
9
10 // Following file:///usr/share/doc/qt4-doc-html/html/opengl-overpainting.html
11 // for combining OpenGL with 2D
12
13 // Looks nicer run with e.g __GL_FSAA_MODE=13 ./svg
14
15 // TODO: Benchmark. Try and capture SVG rendering in a display list.
16
17 class View : public QGLWidget
18 {
19 public:
20 View()
21 :QGLWidget()
22 ,_renderer(this)
23 {
24 setAutoFillBackground(false);
25
26 if (!_renderer.load(QString("drawing.svg")))
27 throw std::runtime_error(__PRETTY_FUNCTION__+std::string(": loading SVG file failed\n"));
28 }
29
30 void initializeGL()
31 {}
32
33 //Don't use paintGL when combining 2D/3D
34 //void paintGL()
35 //{}
36
37 void paintEvent(QPaintEvent*)
38 {
39 glViewport(0,0,static_cast<GLint>(width()),static_cast<GLint>(height()));
40
41 glClearColor(1.0f,1.0f,1.0f,1.0f);
42 glClear(GL_COLOR_BUFFER_BIT);
43
44 //glEnable(GL_MULTISAMPLE);
45
46 QPainter painter(this);
47 painter.setRenderHint(QPainter::Antialiasing);
48 _renderer.render(&painter);
49 painter.end();
50 }
51 protected:
52 void resizeGL(int width,int height)
53 {
54 glViewport(0,0,static_cast<GLint>(width),static_cast<GLint>(height));
55 }
56 private:
57 QSvgRenderer _renderer;
58 };
59
60 int main(int argc,char** argv)
61 {
62 QApplication app(argc,argv);
63
64 QWidget*const w=new View();
65
66 w->show();
67
68 return app.exec();
69 }
70
0 TEMPLATE = app
1
2 CONFIG+= qt opengl stl exceptions release # release debug
3 QT += opengl svg
4
5 SOURCES += svg.cpp
6
7 #######################################
8 # Disable assertions in release version
9
10 QMAKE_CXXFLAGS_RELEASE += -DNDEBUG
11 QMAKE_CFLAGS_RELEASE += -DNDEBUG
12
13 ######################################
14 # Other stuff:
15 # Disable implicit cast from QString to char*
16
17 QMAKE_CXXFLAGS_RELEASE += -DQT_NO_ASCII_CAST
18 QMAKE_CXXFLAGS_DEBUG += -DQT_NO_ASCII_CAST
19
20 ######################################
21 # Hide those crufty moc_ files away
22
23 MOC_DIR = moc
24 OBJECTS_DIR = obj
2828 DialogAbout::DialogAbout(QWidget* parent,int n_threads,bool separate_farm_for_enlargements)
2929 :QDialog(parent)
3030 {
31 setCaption("About evolvotron");
32 setMinimumSize(400,300);
31 assert(parent!=0);
3332
34 _vbox=new QVBox(this);
33 setWindowTitle("About evolvotron");
34 setMinimumSize(480,360);
35 setSizeGripEnabled(true);
3536
36 QTabWidget* tabs=new QTabWidget(_vbox);
37 QVBox* vbox_info=new QVBox(tabs);
38 tabs->addTab(vbox_info,"Info");
39 QVBox* vbox_license=new QVBox(tabs);
40 tabs->addTab(vbox_license,"License");
37 setLayout(new QVBoxLayout);
38
39 QTabWidget*const tabs=new QTabWidget;
40 layout()->addWidget(tabs);
41
42 QWidget*const tab_info=new QWidget;
43 tab_info->setLayout(new QVBoxLayout);
44 tabs->addTab(tab_info,"Info");
45
46 QWidget*const tab_license=new QWidget;
47 tab_license->setLayout(new QVBoxLayout);
48 tabs->addTab(tab_license,"License");
4149
4250 std::ostringstream about_string;
4351 about_string
4452 << "Evolvotron "
45 << EVOLVOTRON_BUILD
53 << stringify(EVOLVOTRON_BUILD)
4654 << "\n\n"
4755 << "Using "
4856 << (separate_farm_for_enlargements ? "2 pools" : "1 pool")
5563 << "Home page: http://evolvotron.sourceforge.net\n"
5664 << "Project page: http://sourceforge.net/projects/evolvotron\n";
5765
58 _label=new QLabel(about_string.str().c_str(),vbox_info);
59 _label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter|_label->alignment());
66 QLabel*const label=new QLabel(about_string.str().c_str());
67 tab_info->layout()->addWidget(label);
68 label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter|label->alignment());
6069
61 _license=new QTextEdit(vbox_license);
62 _license->setReadOnly(true);
63 _license->setTextFormat(PlainText);
64 _license->setText((std::string("License:\n")+std::string(license_string)).c_str());
70 QTextEdit*const license=new QTextEdit;
71 tab_license->layout()->addWidget(license);
72 license->setReadOnly(true);
73 license->setPlainText((std::string("License:\n")+std::string(license_string)).c_str());
6574
66 _ok=new QPushButton("OK",_vbox);
67 _ok->setDefault(true);
75 QPushButton* ok=new QPushButton("OK");
76 layout()->addWidget(ok);
77 ok->setDefault(true);
6878
69 connect(
70 _ok,SIGNAL(clicked()),
71 this,SLOT(hide())
72 );
79 connect
80 (
81 ok,SIGNAL(clicked()),
82 this,SLOT(hide())
83 );
7384 }
7485
75 void DialogAbout::resizeEvent(QResizeEvent* e)
76 {
77 Superclass::resizeEvent(e);
78 _vbox->resize(size());
79 }
86 DialogAbout::~DialogAbout()
87 {}
3030 private:
3131 Q_OBJECT
3232
33 typedef QDialog Superclass;
33 public:
3434
35 public:
3635 //! Constructor.
3736 DialogAbout(QWidget* parent,int n_threads,bool separate_farm_for_enlargements);
3837
3938 //! Destructor.
40 virtual ~DialogAbout()
41 {}
42
43 protected:
44 //! Vertical layout.
45 QVBox* _vbox;
46
47 //! Label for name/release/author etc
48 QLabel* _label;
49
50 //! Scrolling text area for GPL.
51 QTextEdit* _license;
52
53 //! Button to close dialog.
54 QPushButton* _ok;
55
56 //! Need to pass resizes on to vbox or things just get chopped.
57 virtual void resizeEvent(QResizeEvent*);
39 ~DialogAbout();
5840 };
5941
60
61
6242 #endif
3131 ,_parent(parent)
3232 ,_favourite_function_unwrapped(false)
3333 {
34 setCaption("Favourite");
34 setWindowTitle("Favourite");
35 setSizeGripEnabled(true);
36
37 setLayout(new QVBoxLayout);
3538
36 _dialog_content=new QVBox(this);
37
38 QVGroupBox* group0=new QVGroupBox("Function",_dialog_content);
39 QGroupBox*const group0=new QGroupBox("Function");
40 group0->setLayout(new QVBoxLayout);
41 layout()->addWidget(group0);
3942
40 new QLabel("Root node for new image functions:",group0,0,Qt::WordBreak);
41 _favourite=new QComboBox(false,group0);
43 group0->layout()->addWidget(new QLabel("Root node for new image functions:"));
44 _favourite=new QComboBox;
45 group0->layout()->addWidget(_favourite);
4246 _favourite_fn_to_index[""]=_favourite->count();
4347 _index_to_favourite_fn[_favourite->count()]="";
44 _favourite->insertItem("- No preference -");
48 _favourite->addItem("- No preference -");
4549
4650 for (FunctionRegistry::Registrations::const_iterator it=_parent->mutation_parameters().function_registry().registrations().begin();
4751 it!=_parent->mutation_parameters().function_registry().registrations().end();
5660 #endif
5761 _favourite_fn_to_index[fn.name()]=_favourite->count();
5862 _index_to_favourite_fn[_favourite->count()]=fn.name();
59 _favourite->insertItem(fn.name());
63 _favourite->addItem(fn.name().c_str());
6064 }
6165
62 QVGroupBox* group1=new QVGroupBox("Wrapping",_dialog_content);
66 QGroupBox*const group1=new QGroupBox("Wrapping");
67 group1->setLayout(new QVBoxLayout);
68 layout()->addWidget(group1);
6369
64 _unwrapped=new QCheckBox("Disable additional space/colour transforms\n",group1);
70 _unwrapped=new QCheckBox("Disable additional space/colour transforms");
71 group1->layout()->addWidget(_unwrapped);
6572
6673 //! \todo: Add OK & reset/restart versions ?
67 QPushButton* ok=new QPushButton("OK",_dialog_content);
74 QPushButton*const ok=new QPushButton("OK");
75 layout()->addWidget(ok);
6876 ok->setDefault(true);
6977
7078 update_gui_from_state();
97105 update_gui_from_state();
98106 }
99107
100
101108 void DialogFavourite::update_gui_from_state()
102109 {
103110 const std::map<std::string,unsigned int>::const_iterator it=_favourite_fn_to_index.find(_favourite_function);
104111 if (it!=_favourite_fn_to_index.end())
105 _favourite->setCurrentItem((*it).second);
112 _favourite->setCurrentIndex((*it).second);
106113 else
107 _favourite->setCurrentItem(0);
114 _favourite->setCurrentIndex(0);
108115
109116 _unwrapped->setChecked(_favourite_function_unwrapped);
110117
111118 _unwrapped->setEnabled(!_favourite_function.empty());
112119 }
113120
114 void DialogFavourite::resizeEvent(QResizeEvent* e)
115 {
116 Superclass::resizeEvent(e);
117 _dialog_content->resize(size());
118 }
119
120 const bool DialogFavourite::favourite_function(const std::string& f)
121 bool DialogFavourite::favourite_function(const std::string& f)
121122 {
122123 if (_parent->mutation_parameters().function_registry().lookup(f))
123124 {
3030 private:
3131 Q_OBJECT
3232
33 typedef QDialog Superclass;
34
3533 protected:
3634 //! Owner.
3735 EvolvotronMain* _parent;
4240 //! Flag specifying whether favourite function should be exposed
4341 bool _favourite_function_unwrapped;
4442
45 //! Top level holder of all the dialog content.
46 QVBox* _dialog_content;
47
48 //! Select favourite function, if any.
49 QComboBox* _favourite;
50
5143 //! Map function names to combo box entries.
5244 std::map<std::string,unsigned int> _favourite_fn_to_index;
5345
5446 //! Look up function names from combo box.
5547 std::map<unsigned int,std::string> _index_to_favourite_fn;
48
49 //! Select favourite function, if any.
50 QComboBox* _favourite;
5651
5752 //! Controls unwrapped state.
5853 QCheckBox* _unwrapped;
7368 DialogFavourite(EvolvotronMain* parent);
7469
7570 //! Destructor.
76 virtual ~DialogFavourite();
71 ~DialogFavourite();
7772
7873 //! Accessor
7974 const std::string& favourite_function() const
8277 }
8378
8479 //! Accessor. Returns true if function name recognised.
85 const bool favourite_function(const std::string& f);
80 bool favourite_function(const std::string& f);
8681
8782 //! Accessor.
88 const bool favourite_function_unwrapped() const
83 bool favourite_function_unwrapped() const
8984 {
9085 return _favourite_function_unwrapped;
9186 }
9287
9388 //! Accessor.
9489 void favourite_function_unwrapped(bool v);
95
96 //! Handle resizes.
97 virtual void resizeEvent(QResizeEvent* e);
98
9990 };
10091
10192 #endif
00 // Source file for evolvotron
1 // Copyright (C) 2002,2003,2004 Tim Day
1 // Copyright (C) 2009 Tim Day
22 /*
33 This program is free software; you can redistribute it and/or
44 modify it under the terms of the GNU General Public License
2323
2424 #include "dialog_functions.h"
2525
26 #include <qtooltip.h>
27 #include <qtabwidget.h>
28
2926 #include "evolvotron_main.h"
3027 #include "function_registry.h"
31 #include "vbox_scrollview.h"
32
33 /*! About dialog displays author info, web addresses and license info.
28
29 /*! Dialog controls function weightings and related parameters.
3430 */
3531 DialogFunctions::DialogFunctions(EvolvotronMain* parent,MutationParametersQObject* mp)
3632 :QDialog(parent)
3935 {
4036 assert(_parent!=0);
4137
42 setCaption("Functions");
43
44 _dialog_content=new QVBox(this);
45
46 QTabWidget* tabs=new QTabWidget(_dialog_content);
47 _ok=new QPushButton("OK",_dialog_content);
48 _ok->setDefault(true);
38 setWindowTitle("Functions");
39 setMinimumSize(480,360); // Have to scroll through tabs if don't set this
40 setSizeGripEnabled(true);
41
42 setLayout(new QVBoxLayout);
43
44 QTabWidget*const tabs=new QTabWidget;
45 layout()->addWidget(tabs);
46
47 QPushButton*const ok=new QPushButton("OK");
48 layout()->addWidget(ok);
49 ok->setDefault(true);
4950
5051 for (int c=-1;c<FnClassifications;c++)
5152 {
52 QVBox*const tab_content=new QVBox(_dialog_content);
53 QWidget*const tab_content=new QWidget;
54 QVBoxLayout*const tab_content_layout=new QVBoxLayout;
55 tab_content->setLayout(tab_content_layout);
5356 tabs->addTab(tab_content,(c==-1 ? "All" : function_classification_name[c]));
5457
55 QHBox*const buttons=new QHBox(tab_content);
56 QPushButton*const button_less=new QPushButton("Less",buttons);
57 QPushButton*const button_rand=new QPushButton("Randomize",buttons);
58 QPushButton*const button_more=new QPushButton("More",buttons);
58 QWidget*const buttons=new QWidget;
59 buttons->setLayout(new QHBoxLayout);
60 tab_content->layout()->addWidget(buttons);
61 QPushButton*const button_less=new QPushButton("Less");
62 QPushButton*const button_rand=new QPushButton("Randomize");
63 QPushButton*const button_more=new QPushButton("More");
64 buttons->layout()->addWidget(button_less);
65 buttons->layout()->addWidget(button_rand);
66 buttons->layout()->addWidget(button_more);
5967
6068 SignalExpanderClickedUint*const bx_rand=new SignalExpanderClickedUint(this,(c==-1 ? 0xffffffff : (1<<c)));
6169
6270 connect(button_rand,SIGNAL(clicked()),bx_rand,SLOT(clicked()));
6371 connect(bx_rand,SIGNAL(clicked(uint)),this,SLOT(clicked_button_rand(uint)));
6472
65 VBoxScrollView* scrollview=new VBoxScrollView(tab_content);
66 tab_content->setStretchFactor(scrollview,1);
73 QScrollArea*const scrollarea=new QScrollArea;
74 scrollarea->setWidgetResizable(true);
75 tab_content->layout()->addWidget(scrollarea);
76 tab_content_layout->setStretchFactor(scrollarea,1);
77
78 QWidget*const scrollcontent=new QWidget;
79 scrollcontent->setLayout(new QVBoxLayout);
80 scrollarea->setWidget(scrollcontent);
6781
6882 for (FunctionRegistry::Registrations::const_iterator it=_parent->mutation_parameters().function_registry().registrations().begin();
6983 it!=_parent->mutation_parameters().function_registry().registrations().end();
7791 #endif
7892 if (c==-1 || fn.classification()&(1<<c))
7993 {
80 QGroupBox* g=new QGroupBox(3,Qt::Horizontal,fn.name(),scrollview->contentParent());
94 QGroupBox*const g=new QGroupBox(fn.name().c_str());
95 scrollarea->widget()->layout()->addWidget(g);
96 g->setLayout(new QHBoxLayout);
8197
8298 QSizePolicy spx(QSizePolicy::Expanding,QSizePolicy::Preferred);
8399 g->setSizePolicy(spx);
84100
85 new QLabel("2^-10",g);
86 QSlider* s=new QSlider(-10,0,1,0,Qt::Horizontal,g);
101 g->layout()->addWidget(new QLabel("2^-10"));
102 QSlider*const s=new QSlider(Qt::Horizontal);
103 g->layout()->addWidget(s);
104 s->setMinimum(-10);
105 s->setMaximum(0);
106 s->setValue(0);
107 s->setTickInterval(1);
108 s->setTickPosition(QSlider::TicksBothSides);
87109 s->setSizePolicy(spx);
88 new QLabel("1",g);
110 g->layout()->addWidget(new QLabel("1"));
89111
90112 _slider_to_function.insert(std::make_pair(s,&fn));
91113
113135
114136 // And add another tab for all the branching-ratio/dilution controls
115137 {
116 QVBox* vbox=new QVBox(this);
138 QWidget*const vbox=new QWidget;
139 vbox->setLayout(new QVBoxLayout);
117140 tabs->addTab(vbox,"Dilution");
118141
119 _branching_ratio=new QLabel(vbox);
142 _branching_ratio=new QLabel;
143 vbox->layout()->addWidget(_branching_ratio);
120144
121 QGroupBox* c0=new QGroupBox(3,Qt::Horizontal,"Required branching ratio after dilution",vbox);
122 new QLabel("0.1",c0);
123 _slider_target_branching_ratio=new QSlider(10,90,1,50,Qt::Horizontal,c0);
124 QToolTip::add(_slider_target_branching_ratio,"The branching ratio must be diluted to <1.0 to prevent formation of infinitely large function-trees.\nWarning: setting a high value results in complex function trees taking a long time to compute.\nSetting a low value results in very simple images.");
125 new QLabel("0.9",c0);
126
127 QGroupBox* c1=new QGroupBox(3,Qt::Horizontal,"Of diluting nodes, proportion constant:",vbox);
128 new QLabel("0.0",c1);
129 _slider_proportion_constant=new QSlider(0,100,1,50,Qt::Horizontal,c1);
130 new QLabel("1.0",c1);
131 QToolTip::add(_slider_proportion_constant,"This specifies the proportion of diluting nodes which will be constant.");
145 QGroupBox*const c0=new QGroupBox("Required branching ratio after dilution");
146 c0->setLayout(new QHBoxLayout);
147 vbox->layout()->addWidget(c0);
148
149 c0->layout()->addWidget(new QLabel("0.1"));
150 _slider_target_branching_ratio=new QSlider(Qt::Horizontal);
151 c0->layout()->addWidget(_slider_target_branching_ratio);
152 _slider_target_branching_ratio->setMinimum(10);
153 _slider_target_branching_ratio->setMaximum(90);
154 _slider_target_branching_ratio->setValue(50);
155 _slider_target_branching_ratio->setTickInterval(10);
156 _slider_target_branching_ratio->setTickPosition(QSlider::TicksBothSides);
157 _slider_target_branching_ratio->setToolTip("The branching ratio must be diluted to <1.0 to prevent formation of infinitely large function-trees.\nWarning: setting a high value results in complex function trees taking a long time to compute.\nSetting a low value results in very simple images.");
158 c0->layout()->addWidget(new QLabel("0.9"));
159
160 QGroupBox*const c1=new QGroupBox("Of diluting nodes, proportion constant:");
161 c1->setLayout(new QHBoxLayout);
162 vbox->layout()->addWidget(c1);
163 c1->layout()->addWidget(new QLabel("0.0"));
164 _slider_proportion_constant=new QSlider(Qt::Horizontal,c1);
165 c1->layout()->addWidget(_slider_proportion_constant);
166 _slider_proportion_constant->setMinimum(0);
167 _slider_proportion_constant->setMaximum(100);
168 _slider_proportion_constant->setValue(50);
169 _slider_proportion_constant->setTickInterval(10);
170 _slider_proportion_constant->setTickPosition(QSlider::TicksBothSides);
171 _slider_proportion_constant->setToolTip("This specifies the proportion of diluting nodes which will be constant.");
172 c1->layout()->addWidget(new QLabel("1.0"));
132173
133 QGroupBox* c2=new QGroupBox(3,Qt::Horizontal,"Of non-constant diluting nodes, proportion transforms",vbox);
134 new QLabel("0.0",c2);
135 _slider_identity_supression=new QSlider(0,100,1,50,Qt::Horizontal,c2);
136 QToolTip::add(_slider_identity_supression,"This specifies the proportion of non-constant diluting nodes which will be transforms (c.f identity nodes).");
137 new QLabel("1.0",c2);
174 QGroupBox*const c2=new QGroupBox("Of non-constant diluting nodes, proportion transforms");
175 c2->setLayout(new QHBoxLayout);
176 vbox->layout()->addWidget(c2);
177 c2->layout()->addWidget(new QLabel("0.0"));
178 _slider_identity_supression=new QSlider(Qt::Horizontal,c2);
179 c2->layout()->addWidget(_slider_identity_supression);
180 _slider_identity_supression->setMinimum(0);
181 _slider_identity_supression->setMaximum(100);
182 _slider_identity_supression->setValue(50);
183 _slider_identity_supression->setTickInterval(10);
184 _slider_identity_supression->setTickPosition(QSlider::TicksBothSides);
185 _slider_identity_supression->setToolTip("This specifies the proportion of non-constant diluting nodes which will be transforms (c.f identity nodes).");
186 c2->layout()->addWidget(new QLabel("1.0"));
138187
139188 connect(
140189 _slider_target_branching_ratio,SIGNAL(valueChanged(int)),
142191 );
143192
144193 connect(
145 _ok,SIGNAL(clicked()),
194 ok,SIGNAL(clicked()),
146195 this,SLOT(hide())
147196 );
148197
167216
168217 DialogFunctions::~DialogFunctions()
169218 {}
170
171 void DialogFunctions::resizeEvent(QResizeEvent* e)
172 {
173 Superclass::resizeEvent(e);
174 _dialog_content->resize(size());
175 }
176219
177220 void DialogFunctions::setup_from_mutation_parameters()
178221 {
261304 //std::clog << "[DialogFunctions::mutation_parameters_changed()]\n";
262305 setup_from_mutation_parameters();
263306 }
264
2121
2222 #ifndef _dialog_functions_h_
2323 #define _dialog_functions_h_
24
25 #include <qgrid.h>
26 #include <qspinbox.h>
27 #include <qslider.h>
28 #include <qcheckbox.h>
29 #include <qmainwindow.h>
30 #include <qstatusbar.h>
3124
3225 #include "mutation_parameters_qobject.h"
3326
8578 private:
8679 Q_OBJECT
8780
88 typedef QDialog Superclass;
89
9081 protected:
9182 //! Owner of dialog
9283 EvolvotronMain*const _parent;
9788 MutationParametersQObject*const _mutation_parameters;
9889
9990 //! Top level holder of all the dialog content.
100 QVBox* _dialog_content;
91 QWidget* _dialog_content;
10192
10293 //! Notification of undiluted branching ratio.
10394 QLabel* _branching_ratio;
114105 //! Lookup from each slider in the weighting controls area to corresponding function.
115106 std::map<QSlider*,const FunctionRegistration*> _slider_to_function;
116107
117 //! Button to close dialog.
118 QPushButton* _ok;
119
120 //! Need to pass resizes on to vbox or things just get chopped.
121 virtual void resizeEvent(QResizeEvent*);
122
123108 public:
124109 //! Constructor.
125110 DialogFunctions(EvolvotronMain* parent,MutationParametersQObject* mp);
126111
127112 //! Destructor.
128 virtual ~DialogFunctions();
113 ~DialogFunctions();
129114
130115 //! Reload from _mutation_parameters
131116 void setup_from_mutation_parameters();
5252 "<h2>Mouse</h2>"
5353 "<h3>Left-click</h3>"
5454 "<p>Spawns mutant offspring.</p>"
55 "<h3>Middle-drag</h2>"
55 "<h3>Middle-drag</h3>"
5656 "<ul>"
5757 " <li>"
5858 " Unmodified - pan"
146146 DialogHelp::DialogHelp(QWidget* parent,bool full)
147147 :QDialog(parent)
148148 {
149 setCaption(full ? "Evolvotron User Manual" : "Evolvotron Quick Reference");
150 setMinimumSize(300,200);
149 setWindowTitle(full ? "Evolvotron User Manual" : "Evolvotron Quick Reference");
150 setMinimumSize(480,360);
151 setSizeGripEnabled(true);
151152
152 _vbox=new QVBox(this);
153
154 _browser=new QTextBrowser(_vbox);
155 _browser->setText(full ? helptext_long : helptext_short);
153 setLayout(new QVBoxLayout);
156154
157 _ok=new QPushButton("OK",_vbox);
158 // Setting this button to default doesn't seem to have an effect (it does in other browsers).
159 // Something to do with sharing with a QTextBrowser ?
160 _ok->setDefault(true);
155 QTextBrowser*const browser=new QTextBrowser;
156 layout()->addWidget(browser);
157 browser->setText(full ? helptext_long : helptext_short);
161158
162 connect(
163 _ok,SIGNAL(clicked()),
164 this,SLOT(hide())
165 );
159 QPushButton*const ok=new QPushButton("OK");
160 layout()->addWidget(ok);
161 ok->setDefault(true);
162
163 connect
164 (
165 ok,SIGNAL(clicked()),
166 this,SLOT(hide())
167 );
166168 }
167169
168 void DialogHelp::resizeEvent(QResizeEvent*)
169 {
170 _vbox->resize(size());
171 }
170 DialogHelp::~DialogHelp()
171 {}
2222 #ifndef _dialog_help_h_
2323 #define _dialog_help_h_
2424
25 #include <qtextbrowser.h>
26
2725 //! Provides a dialog box with some user documentation.
2826 /*! More of a quick reference guide than a manual.
2927 */
3331 Q_OBJECT
3432
3533 public:
34
3635 //! Constructor.
3736 DialogHelp(QWidget* parent,bool full);
3837
3938 //! Destructor.
40 virtual ~DialogHelp()
41 {}
42
43 protected:
44 //! Vertical layout.
45 QVBox* _vbox;
46
47 //! Label for name/release/author etc
48 QTextBrowser* _browser;
49
50 //! Button to close dialog.
51 QPushButton* _ok;
52
53 //! Need to pass resizes on to vbox or things just get chopped.
54 virtual void resizeEvent(QResizeEvent*);
39 ~DialogHelp();
5540 };
5641
57
58
5942 #endif
2424 #include "dialog_mutatable_image_display.h"
2525
2626 DialogMutatableImageDisplay::DialogMutatableImageDisplay(QWidget* parent)
27 :QDialog(parent,0,TRUE)
27 :QDialog(parent)
2828 {
29 setCaption("Image Properties");
30 setMinimumSize(320,240);
29 setWindowTitle("Image Properties");
30 setSizeGripEnabled(true);
3131
32 _vbox=new QVBox(this);
32 setLayout(new QVBoxLayout);
3333
34 _tabs=new QTabWidget(_vbox);
34 _tabs=new QTabWidget;
35 layout()->addWidget(_tabs);
3536
36 _label_info=new QLabel(QString(""),_tabs);
37 _label_info=new QLabel(QString(""));
3738 _tabs->addTab(_label_info,"Summary");
3839
39 _textedit_xml=new QTextEdit(_tabs);
40 _textedit_xml=new QTextEdit;
4041 _textedit_xml->setReadOnly(true);
41 _textedit_xml->setTextFormat(PlainText);
4242 _tabs->addTab(_textedit_xml,"Detail");
4343
44 _ok=new QPushButton("OK",_vbox);
44 _ok=new QPushButton("OK");
4545 _ok->setDefault(true);
46 layout()->addWidget(_ok);
4647
4748 connect(
4849 _ok,SIGNAL(clicked()),
5051 );
5152 }
5253
53 void DialogMutatableImageDisplay::resizeEvent(QResizeEvent*)
54 {
55 _vbox->resize(size());
56 }
54 DialogMutatableImageDisplay::~DialogMutatableImageDisplay()
55 {}
5756
5857 void DialogMutatableImageDisplay::set_content(const std::string& m,const std::string& x)
5958 {
6059 _label_info->setText(QString(m.c_str()));
6160 _label_info->adjustSize();
6261
63 _textedit_xml->setText(x);
62 _textedit_xml->setPlainText(x.c_str());
6463
6564 adjustSize();
6665 updateGeometry();
6766 }
68
3434
3535 protected:
3636
37 //! Vertical layout.
38 QVBox* _vbox;
39
4037 //! Tabs for info and xml (summary and detail)
4138 QTabWidget* _tabs;
4239
5451 DialogMutatableImageDisplay(QWidget* parent);
5552
5653 //! Destructor.
57 virtual ~DialogMutatableImageDisplay()
58 {}
59
60 //! Need to pass resizes on to vbox or things just get chopped.
61 virtual void resizeEvent(QResizeEvent*);
54 ~DialogMutatableImageDisplay();
6255
6356 //! Set content of main text and scrolling area.
6457 void set_content(const std::string& m,const std::string& x);
00 // Source file for evolvotron
1 // Copyright (C) 2002,2003,2004 Tim Day
1 // Copyright (C) 2009 Tim Day
22 /*
33 This program is free software; you can redistribute it and/or
44 modify it under the terms of the GNU General Public License
3131 {
3232 assert(_parent!=0);
3333
34 setCaption("Mutation Parameters");
35
36 _dialog_content=new QVBox(this);
37
38 _tabs=new QTabWidget(_dialog_content);
39
40 _vbox_base_mutation=new QVBox(_tabs);
34 setWindowTitle("Mutation Parameters");
35 setSizeGripEnabled(true);
36
37 setLayout(new QVBoxLayout);
38
39 _tabs=new QTabWidget();
40 layout()->addWidget(_tabs);
41
42 _vbox_base_mutation=new QWidget;
43 _vbox_base_mutation->setLayout(new QVBoxLayout);
4144 _tabs->addTab(_vbox_base_mutation,"Base");
4245
43 _grid_buttons=new QGrid(5,Qt::Horizontal,_vbox_base_mutation);
44
45 _button_reset=new QPushButton("&Reset",_grid_buttons);
46 _button_cool=new QPushButton("&Cool",_grid_buttons);
47 _button_shield=new QPushButton("&Shield",_grid_buttons);
48 _button_heat=new QPushButton("&Heat",_grid_buttons);
49 _button_irradiate=new QPushButton("&Irradiate",_grid_buttons);
50
51 QToolTip::add(_button_cool,"Decrease size of constant perturbations during mutation.");
52 QToolTip::add(_button_heat,"Increase size of constant perturbations during mutation.");
53 QToolTip::add(_button_shield,"Decrease probability of function tree structural mutations.");
54 QToolTip::add(_button_irradiate,"Increase probability of function tree structural mutations.");
46 _grid_buttons=new QWidget;
47 _vbox_base_mutation->layout()->addWidget(_grid_buttons);
48
49 QGridLayout*const grid_buttons_layout=new QGridLayout();
50 _grid_buttons->setLayout(grid_buttons_layout);
51
52 grid_buttons_layout->addWidget(_button_reset=new QPushButton("&Reset",_grid_buttons),0,0);
53 grid_buttons_layout->addWidget(_button_cool=new QPushButton("&Cool",_grid_buttons),0,1);
54 grid_buttons_layout->addWidget(_button_shield=new QPushButton("&Shield",_grid_buttons),0,2);
55 grid_buttons_layout->addWidget(_button_heat=new QPushButton("&Heat",_grid_buttons),0,3);
56 grid_buttons_layout->addWidget(_button_irradiate=new QPushButton("&Irradiate",_grid_buttons),0,4);
57
58 _button_cool->setToolTip("Decrease size of constant perturbations during mutation.");
59 _button_heat->setToolTip("Increase size of constant perturbations during mutation.");
60 _button_shield->setToolTip("Decrease probability of function tree structural mutations.");
61 _button_irradiate->setToolTip("Increase probability of function tree structural mutations.");
5562
5663 connect(_button_reset, SIGNAL(clicked()),this,SLOT(reset()));
5764 connect(_button_cool, SIGNAL(clicked()),this,SLOT(cool()));
5966 connect(_button_shield, SIGNAL(clicked()),this,SLOT(shield()));
6067 connect(_button_irradiate,SIGNAL(clicked()),this,SLOT(irradiate()));
6168
62 _vbox_autocool=new QVBox(_tabs);
69 _vbox_autocool=new QWidget;
70 _vbox_autocool->setLayout(new QVBoxLayout);
6371 _tabs->addTab(_vbox_autocool,"Autocool");
6472
65 _grid_base_mutation=new QGrid(2,Qt::Horizontal,_vbox_base_mutation);
66 _grid_autocool=new QGrid(2,Qt::Horizontal,_vbox_autocool);
73 _grid_base_mutation=new QWidget;
74 _vbox_base_mutation->layout()->addWidget(_grid_base_mutation);
75
76 QGridLayout*const grid_base_mutation_layout=new QGridLayout();
77 _grid_base_mutation->setLayout(grid_base_mutation_layout);
78
79 grid_base_mutation_layout->addWidget(new QLabel("Perturbation magnitude:"),0,0);
80 grid_base_mutation_layout->addWidget(_spinbox_magnitude=new QSpinBox,0,1);
81 _spinbox_magnitude->setRange(0,_scale);
82 _spinbox_magnitude->setSingleStep(maximum(1,_scale/1000));
83 _spinbox_magnitude->setSuffix(QString("/%1").arg(_scale));
84 _spinbox_magnitude->setToolTip("Scale of function parameter perturbations.");
6785
68 new QLabel("Perturbation magnitude:",_grid_base_mutation);
69 _spinbox_magnitude=new QSpinBox(0,_scale,maximum(1,_scale/100),_grid_base_mutation);
70 _spinbox_magnitude->setSuffix(QString("/%1").arg(_scale));
71 QToolTip::add(_spinbox_magnitude,"Scale of function parameter perturbations.");
72
73 new QLabel("p(Parameter reset)",_grid_base_mutation);
74 _spinbox_parameter_reset=new QSpinBox(0,_scale,maximum(1,_scale/1000),_grid_base_mutation);
86 grid_base_mutation_layout->addWidget(new QLabel("p(Parameter reset)"),1,0);
87 grid_base_mutation_layout->addWidget(_spinbox_parameter_reset=new QSpinBox,1,1);
88 _spinbox_parameter_reset->setRange(0,_scale);
89 _spinbox_parameter_reset->setSingleStep(maximum(1,_scale/1000));
7590 _spinbox_parameter_reset->setSuffix(QString("/%1").arg(_scale));
76 QToolTip::add(_spinbox_parameter_reset,"Probability of function parameters being completely reset.");
77
78 new QLabel("p(Glitch)",_grid_base_mutation);
79 _spinbox_glitch=new QSpinBox(0,_scale,maximum(1,_scale/1000),_grid_base_mutation);
91 _spinbox_parameter_reset->setToolTip("Probability of function parameters being completely reset.");
92
93 grid_base_mutation_layout->addWidget(new QLabel("p(Glitch)"),2,0);
94 grid_base_mutation_layout->addWidget(_spinbox_glitch=new QSpinBox,2,1);
95 _spinbox_glitch->setRange(0,_scale);
96 _spinbox_glitch->setSingleStep(maximum(1,_scale/1000));
8097 _spinbox_glitch->setSuffix(QString("/%1").arg(_scale));
81 QToolTip::add(_spinbox_glitch,"Probability of function branch being replaced by new random stub.");
82
83 new QLabel("p(Shuffle)",_grid_base_mutation);
84 _spinbox_shuffle=new QSpinBox(0,_scale,maximum(1,_scale/1000),_grid_base_mutation);
98 _spinbox_glitch->setToolTip("Probability of function branch being replaced by new random stub.");
99
100 grid_base_mutation_layout->addWidget(new QLabel("p(Shuffle)"),3,0);
101 grid_base_mutation_layout->addWidget(_spinbox_shuffle=new QSpinBox,3,1);
102 _spinbox_shuffle->setRange(0,_scale);
103 _spinbox_shuffle->setSingleStep(maximum(1,_scale/1000));
85104 _spinbox_shuffle->setSuffix(QString("/%1").arg(_scale));
86 QToolTip::add(_spinbox_shuffle,"Probability of function branches being reordered.");
87
88 new QLabel("p(Insert)",_grid_base_mutation);
89 _spinbox_insert=new QSpinBox(0,_scale,maximum(1,_scale/1000),_grid_base_mutation);
105 _spinbox_shuffle->setToolTip("Probability of function branches being reordered.");
106
107 grid_base_mutation_layout->addWidget(new QLabel("p(Insert)"),4,0);
108 grid_base_mutation_layout->addWidget(_spinbox_insert=new QSpinBox,4,1);
109 _spinbox_insert->setRange(0,_scale);
110 _spinbox_insert->setSingleStep(maximum(1,_scale/1000));
90111 _spinbox_insert->setSuffix(QString("/%1").arg(_scale));
91 QToolTip::add(_spinbox_insert,"Probability of function branch having random stub inserted.");
92
93 new QLabel("p(Substitute)",_grid_base_mutation);
94 _spinbox_substitute=new QSpinBox(0,_scale,maximum(1,_scale/1000),_grid_base_mutation);
112 _spinbox_insert->setToolTip("Probability of function branch having random stub inserted.");
113
114 grid_base_mutation_layout->addWidget(new QLabel("p(Substitute)"),5,0);
115 grid_base_mutation_layout->addWidget(_spinbox_substitute=new QSpinBox,5,1);
116 _spinbox_substitute->setRange(0,_scale);
117 _spinbox_substitute->setSingleStep(maximum(1,_scale/1000));
95118 _spinbox_substitute->setSuffix(QString("/%1").arg(_scale));
96 QToolTip::add(_spinbox_substitute,"Probability of function node's type being changed.");
97
98 new QLabel("Enable",_grid_autocool);
99 _checkbox_autocool_enable=new QCheckBox(_grid_autocool);
100 QToolTip::add(_checkbox_autocool_enable,"Autocooling reduces the strength and probablility of mutations with increasing numbers of generations.");
101
102 new QLabel("Half-life",_grid_autocool);
103 _spinbox_autocool_halflife=new QSpinBox(1,1000,1,_grid_autocool);
104 QToolTip::add(_spinbox_autocool_halflife,"Number of generations needed to halve mutation influence when autocooling.");
105
106 _label_autocool_generations=new QLabel("",_grid_autocool);
107
108 _button_autocool_reheat=new QPushButton("Reheat",_grid_autocool);
119 _spinbox_substitute->setToolTip("Probability of function node's type being changed.");
120
121 _grid_autocool=new QWidget;
122 _vbox_autocool->layout()->addWidget(_grid_autocool);
123 QGridLayout*const grid_autocool_layout=new QGridLayout();
124 _grid_autocool->setLayout(grid_autocool_layout);
125
126 grid_autocool_layout->addWidget(_checkbox_autocool_enable=new QCheckBox("Enable autocool"),0,1);
127 _checkbox_autocool_enable->setToolTip("Autocooling reduces the strength and probablility of mutations with increasing numbers of generations.");
128
129 grid_autocool_layout->addWidget(new QLabel("Half-life"),1,0);
130 grid_autocool_layout->addWidget(_spinbox_autocool_halflife=new QSpinBox,1,1);
131 _spinbox_autocool_halflife->setRange(1,1000);
132 _spinbox_autocool_halflife->setSingleStep(1);
133 _spinbox_autocool_halflife->setToolTip("Number of generations needed to halve mutation influence when autocooling.");
134
135 grid_autocool_layout->addWidget(_label_autocool_generations=new QLabel(""),2,0);
136
137 grid_autocool_layout->addWidget(_button_autocool_reheat=new QPushButton("Reheat"),2,1);
109138 connect(_button_autocool_reheat,SIGNAL(clicked()),this,SLOT(reheat()));
110139
111140 setup_from_mutation_parameters();
122151 connect(_checkbox_autocool_enable,SIGNAL(stateChanged(int)),this,SLOT(changed_autocool_enable(int)));
123152 connect(_spinbox_autocool_halflife,SIGNAL(valueChanged(int)),this,SLOT(changed_autocool_halflife(int)));
124153
125 _ok=new QPushButton("OK",_dialog_content);
154 _ok=new QPushButton("OK");
155 layout()->addWidget(_ok);
126156 _ok->setDefault(true);
127157
128158 connect(
136166 );
137167 }
138168
139 void DialogMutationParameters::resizeEvent(QResizeEvent* e)
140 {
141 Superclass::resizeEvent(e);
142 _dialog_content->resize(size());
143 }
169 DialogMutationParameters::~DialogMutationParameters()
170 {}
144171
145172 void DialogMutationParameters::setup_from_mutation_parameters()
146173 {
201228
202229 void DialogMutationParameters::changed_autocool_enable(int buttonstate)
203230 {
204 if (buttonstate==QButton::On) _mutation_parameters->autocool_enable(true);
205 else if (buttonstate==QButton::Off) _mutation_parameters->autocool_enable(false);
231 if (buttonstate==Qt::Checked) _mutation_parameters->autocool_enable(true);
232 else if (buttonstate==Qt::Unchecked) _mutation_parameters->autocool_enable(false);
206233 }
207234
208235 void DialogMutationParameters::changed_magnitude(int v)
4545 */
4646 MutationParametersQObject*const _mutation_parameters;
4747
48 //! Top level holder of all the dialog content.
49 QVBox* _dialog_content;
50
5148 //! Tabs for base parameters and autocool
5249 QTabWidget* _tabs;
5350
5451 //! Tab for base mutation parameter controls
55 QVBox* _vbox_base_mutation;
52 QWidget* _vbox_base_mutation;
5653
5754 //! Grid for buttons;
58 QGrid* _grid_buttons;
55 QWidget* _grid_buttons;
5956
6057 //! Grid for base parameter control spinners
61 QGrid* _grid_base_mutation;
58 QWidget* _grid_base_mutation;
6259
6360 //! Group for autocool parameters
64 QVBox* _vbox_autocool;
61 QWidget* _vbox_autocool;
6562
6663 //! Grid for autocool parameters
67 QGrid* _grid_autocool;
64 QWidget* _grid_autocool;
6865
6966 //! Label to show number of generations
7067 QLabel* _label_autocool_generations;
9895 //! Button to close dialog.
9996 QPushButton* _ok;
10097
101 //! Need to pass resizes on to vbox or things just get chopped.
102 virtual void resizeEvent(QResizeEvent*);
103
10498 //! Reload spinboxes from _mutation_parameters.
10599 void setup_from_mutation_parameters();
106100
109103 DialogMutationParameters(QMainWindow* parent,MutationParametersQObject* mp);
110104
111105 //! Destructor.
112 virtual ~DialogMutationParameters()
113 {}
106 ~DialogMutationParameters();
114107
115108 public slots:
116109
2727 :QDialog(parent)
2828 ,_render_parameters(rp)
2929 {
30 setCaption("Render Parameters");
30 setWindowTitle("Render Parameters");
31 setSizeGripEnabled(true);
3132
32 _dialog_content=new QVBox(this);
33 setLayout(new QVBoxLayout);
3334
34 _grid=new QGrid(2,Qt::Horizontal,_dialog_content);
35 layout()->addWidget(_checkbox_jittered_samples=new QCheckBox("Jittered samples"));
36 _checkbox_jittered_samples->setToolTip("Jitter moves sampling positions randomly within a pixel. This helps to break up aliasing and moire patterns.");
3537
36 new QLabel("Jittered samples",_grid);
37 _checkbox_jittered_samples=new QCheckBox(_grid);
38 QToolTip::add(_checkbox_jittered_samples,"Jitter moves sampling positions randomly within a pixel. This helps to break up aliasing and moire patterns.");
38 _buttonvbox=new QGroupBox("Oversampling (antialiasing)");
39 _buttonvbox->setLayout(new QVBoxLayout);
40 layout()->addWidget(_buttonvbox);
41
42 QRadioButton* button[4];
43 _buttonvbox->layout()->addWidget(button[0]=new QRadioButton("1x1"));
44 _buttonvbox->layout()->addWidget(button[1]=new QRadioButton("2x2"));
45 _buttonvbox->layout()->addWidget(button[2]=new QRadioButton("3x3"));
46 _buttonvbox->layout()->addWidget(button[3]=new QRadioButton("4x4"));
3947
40 _buttongroup=new QVButtonGroup("Oversampling (antialiasing)",_dialog_content);
41 _buttongroup->insert(new QRadioButton("1x1",_buttongroup),1);
42 _buttongroup->insert(new QRadioButton("2x2",_buttongroup),2);
43 _buttongroup->insert(new QRadioButton("3x3",_buttongroup),3);
44 _buttongroup->insert(new QRadioButton("4x4",_buttongroup),4);
45 _buttongroup->setRadioButtonExclusive(true);
46 QToolTip::add(_buttongroup->find(1),"No oversampling");
47 QToolTip::add(_buttongroup->find(2),"Enables a final antialiased rendering with 4 samples per pixel");
48 QToolTip::add(_buttongroup->find(3),"Enables a final antialiased rendering with 3 samples per pixel");
49 QToolTip::add(_buttongroup->find(4),"Enables a final antialiased rendering with 16 samples per pixel");
48 button[0]->setToolTip("No oversampling");
49 button[1]->setToolTip("Enables a final antialiased rendering with 4 samples per pixel");
50 button[2]->setToolTip("Enables a final antialiased rendering with 9 samples per pixel");
51 button[3]->setToolTip("Enables a final antialiased rendering with 16 samples per pixel");
52
53 _buttongroup=new QButtonGroup(_buttonvbox);
54 _buttongroup->addButton(button[0],1);
55 _buttongroup->addButton(button[1],2);
56 _buttongroup->addButton(button[2],3);
57 _buttongroup->addButton(button[3],4);
5058
5159 setup_from_render_parameters();
5260
5361 connect(_checkbox_jittered_samples,SIGNAL(stateChanged(int)),this,SLOT(changed_jittered_samples(int)));
54 connect(_buttongroup,SIGNAL(clicked(int)),this,SLOT(changed_oversampling(int)));
62 connect(_buttongroup,SIGNAL(buttonClicked(int)),this,SLOT(changed_oversampling(int)));
5563
56 _ok=new QPushButton("OK",_dialog_content);
64 _ok=new QPushButton("OK");
5765 _ok->setDefault(true);
66 layout()->addWidget(_ok);
5867
5968 connect(
6069 _ok,SIGNAL(clicked()),
6776 );
6877 }
6978
70 void DialogRenderParameters::resizeEvent(QResizeEvent* e)
71 {
72 Superclass::resizeEvent(e);
73 _dialog_content->resize(size());
74 }
79 DialogRenderParameters::~DialogRenderParameters()
80 {}
7581
7682 void DialogRenderParameters::setup_from_render_parameters()
7783 {
7884 _checkbox_jittered_samples->setChecked(_render_parameters->jittered_samples());
7985
80 QButton*const which_button=_buttongroup->find(_render_parameters->multisample_grid());
86 QAbstractButton*const which_button=_buttongroup->button(_render_parameters->multisample_grid());
8187 if (which_button)
8288 {
83 _buttongroup->setButton(_buttongroup->id(which_button));
89 which_button->click();
8490 }
8591 }
8692
8793 void DialogRenderParameters::changed_jittered_samples(int buttonstate)
8894 {
89 if (buttonstate==QButton::On) _render_parameters->jittered_samples(true);
90 else if (buttonstate==QButton::Off) _render_parameters->jittered_samples(false);
95 if (buttonstate==Qt::Checked) _render_parameters->jittered_samples(true);
96 else if (buttonstate==Qt::Unchecked) _render_parameters->jittered_samples(false);
9197 }
9298
9399 void DialogRenderParameters::changed_oversampling(int id)
3030 private:
3131 Q_OBJECT
3232
33 typedef QDialog Superclass;
34
3533 protected:
3634
3735 //! Instance of MutationParameters under dialog control.
4038 */
4139 RenderParameters*const _render_parameters;
4240
43 //! Top level holder of all the dialog content.
44 QVBox* _dialog_content;
45
46 //! Grid for buttons etc;
47 QGrid* _grid;
48
4941 //! Enables jittered samples.
5042 QCheckBox* _checkbox_jittered_samples;
5143
5244 //! Chooses between multisampling levels.
53 QVButtonGroup* _buttongroup;
45 QWidget* _buttonvbox;
46
47 //! Chooses between multisampling levels.
48 QButtonGroup* _buttongroup;
5449
5550 //! Button to close dialog.
5651 QPushButton* _ok;
57
58 //! Need to pass resizes on to vbox or things just get chopped.
59 virtual void resizeEvent(QResizeEvent*);
6052
6153 //! Reload from _render_parameters.
6254 void setup_from_render_parameters();
6658 DialogRenderParameters(QMainWindow* parent,RenderParameters* rp);
6759
6860 //! Destructor.
69 virtual ~DialogRenderParameters()
70 {}
61 ~DialogRenderParameters();
7162
7263 public slots:
7364
192192 uint multisample_level,
193193 bool function_debug_mode
194194 )
195 :QMainWindow(parent,0,Qt::WType_TopLevel|Qt::WDestructiveClose)
195 :QMainWindow(parent)
196196 ,_history(new EvolvotronMain::History(this))
197197 ,_mutation_parameters(time(0),autocool,function_debug_mode,this)
198198 ,_render_parameters(jitter,multisample_level,this)
200200 ,_statusbar_tasks_enlargement(0)
201201 ,_last_spawn_method(&EvolvotronMain::spawn_normal)
202202 {
203 setMinimumSize(600,400);
203 setAttribute(Qt::WA_DeleteOnClose,true);
204 setAttribute(Qt::WA_QuitOnClose,true);
205
206 setMinimumSize(640,480);
204207
205208 // Need to create this first or DialogMutationParameters might cause one to be created too.
206 _statusbar=new QStatusBar(this);
207 _statusbar->setSizeGripEnabled(false);
208
209 _statusbar_tasks_label=new QLabel("Ready",_statusbar);
210 _statusbar->addWidget(_statusbar_tasks_label,0,true);
209 _statusbar=new QStatusBar;
210 _statusbar->setSizeGripEnabled(true);
211 setStatusBar(_statusbar);
212
213 _statusbar->addWidget(_statusbar_tasks_label=new QLabel("Ready"));
211214
212215 _dialog_about=new DialogAbout(this,n_threads,separate_farm_for_enlargements);
213216 _dialog_help_short=new DialogHelp(this,false);
221224
222225 _dialog_favourite=new DialogFavourite(this);
223226
224 _menubar=new QMenuBar(this);
225
226 _popupmenu_file=new QPopupMenu;
227 _popupmenu_file->insertItem("Re&set (Reset mutation parameters, clear locks)",this,SLOT(reset_cold()));
228 _popupmenu_file->insertItem("&Restart (Preserve mutation parameters and locks)",this,SLOT(reset_warm()));
229 _popupmenu_file->insertItem("Remi&x (Randomize function weights and restart)",this,SLOT(reset_randomized()));
230 _popupmenu_file->insertSeparator();
231 _popupmenu_file->insertItem("&Quit",qApp,SLOT(quit()));
232 _menubar->insertItem("&File",_popupmenu_file);
233
234 _popupmenu_edit=new QPopupMenu;
235 _popupmenu_edit_undo_id=_popupmenu_edit->insertItem("&Undo",this,SLOT(undo()));
236 _popupmenu_edit->setItemEnabled(_popupmenu_edit_undo_id,false);
237 _popupmenu_edit->insertSeparator();
238 _popupmenu_edit->insertItem("&Simplify all functions",this,SLOT(simplify_constants()));
239 _menubar->insertItem("&Edit",_popupmenu_edit);
240
241 _popupmenu_settings=new QPopupMenu;
242
243 // We want to use a checkmark on some items
244 _popupmenu_settings->setCheckable(true);
245
246 _popupmenu_settings->insertItem("Mutation &parameters...",_dialog_mutation_parameters,SLOT(show()));
247 _popupmenu_settings->insertItem("&Function weightings...",_dialog_functions,SLOT(show()));
248 _popupmenu_settings->insertItem("Fa&vourite function...",_dialog_favourite,SLOT(show()));
249
250 _popupmenu_settings->insertSeparator();
251
252 _popupmenu_settings->insertItem("Ren&der parameters...",_dialog_render_parameters,SLOT(show()));
253
254 _popupmenu_settings->insertSeparator();
255
256 _menu_item_number_fullscreen=_popupmenu_settings->insertItem("Full&screen",this,SLOT(toggle_fullscreen()));
257 _menu_item_number_hide_menu=_popupmenu_settings->insertItem("Hide &menu and statusbar",this,SLOT(toggle_hide_menu()));
258
259 _popupmenu_settings->setItemChecked(_menu_item_number_fullscreen,start_fullscreen);
260 _popupmenu_settings->setItemChecked(_menu_item_number_hide_menu,start_menuhidden);
261
262 _menubar->insertItem("Se&ttings",_popupmenu_settings);
227 _popupmenu_file=menuBar()->addMenu("&File");
228 _popupmenu_file->addAction("Reset (Reset mutation parameters, clear locks)",this,SLOT(reset_cold()),QKeySequence("r"));
229 _popupmenu_file->addAction("Restart (Preserve mutation parameters and locks)",this,SLOT(reset_warm()),QKeySequence("t"));
230 _popupmenu_file->addAction("Remix (Randomize function weights and restart)",this,SLOT(reset_randomized()),QKeySequence("x"));
231 _popupmenu_file->addSeparator();
232 _popupmenu_file->addAction("Quit",qApp,SLOT(quit()),QKeySequence("q"));
233
234 _popupmenu_edit=menuBar()->addMenu("&Edit");
235 _popupmenu_edit_undo_action=_popupmenu_edit->addAction("Undo",this,SLOT(undo()),QKeySequence("u"));
236 _popupmenu_edit_undo_action->setEnabled(false);
237 _popupmenu_edit->addSeparator();
238 _popupmenu_edit->addAction("Simplify all functions",this,SLOT(simplify_constants()));
239
240 _popupmenu_settings=menuBar()->addMenu("Se&ttings");
241 _popupmenu_settings->addAction("Mutation parameters...",_dialog_mutation_parameters,SLOT(show()));
242 _popupmenu_settings->addAction("Function weightings...",_dialog_functions,SLOT(show()));
243 _popupmenu_settings->addAction("Favourite function...",_dialog_favourite,SLOT(show()));
244
245 _popupmenu_settings->addSeparator();
246
247 _popupmenu_settings->addAction("Render parameters...",_dialog_render_parameters,SLOT(show()));
248
249 _popupmenu_settings->addSeparator();
250
251 _menu_action_fullscreen=_popupmenu_settings->addAction("Fullscreen",this,SLOT(toggle_fullscreen()),QKeySequence("f"));
252 _menu_action_fullscreen->setCheckable(true);
253 _menu_action_fullscreen->setChecked(start_fullscreen);
254 _menu_action_hide_menu=_popupmenu_settings->addAction("Hide menu and statusbar",this,SLOT(toggle_hide_menu()),QKeySequence("m"));
255 _menu_action_hide_menu->setCheckable(true);
256 _menu_action_hide_menu->setChecked(start_menuhidden);
263257
264258 //! This doesn't seem to do anything (supposed to push help menu over to far end ?)
265 _menubar->insertSeparator();
266
267 _popupmenu_help=new QPopupMenu;
268 _popupmenu_help->insertItem("Quick &Reference",_dialog_help_short,SLOT(show()));
269 _popupmenu_help->insertItem("User &Manual",_dialog_help_long,SLOT(show()));
270 _popupmenu_help->insertSeparator();
271 _popupmenu_help->insertItem("&About",_dialog_about,SLOT(show()));
272
273 _menubar->insertItem("&Help",_popupmenu_help);
274
275 _grid=new QGrid(grid_size.width(),this);
276
277 _label_autocool_enable=new QLabel("",_statusbar);
278 _checkbox_autocool_enable=new QCheckBox("Autocool",_statusbar);
279 QToolTip::add(_checkbox_autocool_enable,"Autocooling gradually reduces the chance and magnitude of mutations with time.");
280 _button_autocool_reheat=new QPushButton("Reheat",_statusbar);
281 QToolTip::add(_button_autocool_reheat,"Reheat restarts the autocooling generation count, restoring the full strength of mutations.");
259 menuBar()->addSeparator();
260
261 _popupmenu_help=menuBar()->addMenu("&Help");
262 _popupmenu_help->addAction("Quick Reference",_dialog_help_short,SLOT(show()));
263 _popupmenu_help->addAction("User Manual",_dialog_help_long,SLOT(show()));
264 _popupmenu_help->addSeparator();
265 _popupmenu_help->addAction("About",_dialog_about,SLOT(show()));
266
267 _checkbox_autocool_enable=new QCheckBox("Autocool");
268 _checkbox_autocool_enable->setToolTip("Autocooling gradually reduces the chance and magnitude of mutations with time.");
269 _label_autocool_enable=new QLabel(""); // Used to display generation count
270 _button_autocool_reheat=new QPushButton("Reheat");
271 _button_autocool_reheat->setToolTip("Reheat restarts the autocooling generation count, restoring the full strength of mutations.");
282272
283273 connect(_checkbox_autocool_enable,SIGNAL(stateChanged(int)),_dialog_mutation_parameters,SLOT(changed_autocool_enable(int)));
284274 connect(_button_autocool_reheat,SIGNAL(clicked()),_dialog_mutation_parameters,SLOT(reheat()));
285275
286 _statusbar->addWidget(new QHBox(_statusbar),1,true);
287 _statusbar->addWidget(_checkbox_autocool_enable,0,true);
288 _statusbar->addWidget(_label_autocool_enable,0,true);
289 _statusbar->addWidget(_button_autocool_reheat,0,true);
276 _statusbar->addPermanentWidget(_checkbox_autocool_enable);
277 _statusbar->addPermanentWidget(_label_autocool_enable);
278 _statusbar->addPermanentWidget(_button_autocool_reheat);
290279
291280 connect(
292281 &_render_parameters,SIGNAL(changed()),
298287 this,SLOT(mutation_parameters_changed())
299288 );
300289
301 // We need to make sure the display grid gets all the space it can
290
291 _farm[0]=std::auto_ptr<MutatableImageComputerFarm>(new MutatableImageComputerFarm(n_threads,niceness_grid));
292 if (separate_farm_for_enlargements)
293 {
294 _farm[1]=std::auto_ptr<MutatableImageComputerFarm>(new MutatableImageComputerFarm(n_threads,niceness_enlargements));
295 }
296
297 _grid=new QWidget;
298 QGridLayout*const grid_layout=new QGridLayout;
299 _grid->setLayout(grid_layout);
302300 setCentralWidget(_grid);
303301
302 //! \todo frames and framerate should be retained and modifiable from the GUI
303 for (int r=0;r<grid_size.height();r++)
304 for (int c=0;c<grid_size.width();c++)
305 {
306 MutatableImageDisplay*const d=new MutatableImageDisplay(this,true,false,QSize(0,0),frames,framerate);
307 grid_layout->addWidget(d,r,c);
308 displays().push_back(d);
309 }
310
304311 _timer=new QTimer(this);
305
306312 connect(
307313 _timer,SIGNAL(timeout()),
308314 this, SLOT(tick())
309315 );
310
311 _farm[0]=std::auto_ptr<MutatableImageComputerFarm>(new MutatableImageComputerFarm(n_threads,niceness_grid));
312 if (separate_farm_for_enlargements)
313 {
314 _farm[1]=std::auto_ptr<MutatableImageComputerFarm>(new MutatableImageComputerFarm(n_threads,niceness_enlargements));
315 }
316
317 //! \todo frames and framerate should be retained and modifiable from the GUI
318 for (int r=0;r<grid_size.height();r++)
319 for (int c=0;c<grid_size.width();c++)
320 {
321 displays().push_back(new MutatableImageDisplay(_grid,this,true,false,QSize(0,0),frames,framerate));
322 }
323
324316 // Run tick() at 100Hz
325317 _timer->start(10);
326318
372364 std::clog << "...completed Evolvotron shutdown\n";
373365 }
374366
375 const bool EvolvotronMain::favourite_function(const std::string& f)
367 bool EvolvotronMain::favourite_function(const std::string& f)
376368 {
377369 return _dialog_favourite->favourite_function(f);
378370 }
426418
427419 void EvolvotronMain::set_undoable(bool v,const std::string& action_name)
428420 {
429 _popupmenu_edit->changeItem(_popupmenu_edit_undo_id,QString(("&Undo "+action_name).c_str()));
430 _popupmenu_edit->setItemEnabled(_popupmenu_edit_undo_id,v);
421 _popupmenu_edit_undo_action->setText(QString(("Undo "+action_name).c_str()));
422 _popupmenu_edit_undo_action->setEnabled(v);
431423 }
432424
433425 void EvolvotronMain::respawn(MutatableImageDisplay* display)
614606 showNormal();
615607 menuBar()->show();
616608 statusBar()->show();
617 _popupmenu_settings->setItemChecked(_menu_item_number_fullscreen,false);
618 _popupmenu_settings->setItemChecked(_menu_item_number_hide_menu,false);
619 }
620 else if (e->key()==Qt::Key_F && !(e->state()^Qt::ControlButton))
621 {
622 //Ctrl-F toggles fullscreen mode
623 toggle_fullscreen();
624 }
625 else if (e->key()==Qt::Key_M && !(e->state()^Qt::ControlButton))
626 {
627 //Ctrl-M toggles menu and status-bar display
628 toggle_hide_menu();
629 }
630 else if (e->key()==Qt::Key_R && !(e->state()^Qt::ControlButton))
631 {
632 //Ctrl-R does a restart mainly because that's most useful in full-screen mode
633 reset_warm();
634 }
635 else if (e->key()==Qt::Key_Z && !(e->state()^Qt::ControlButton))
636 {
637 //Ctrl-Z does an undo
638 undo();
639 }
640 else
641 {
642 // Perhaps it's for someone else
643 e->ignore();
644 }
609 _menu_action_fullscreen->setChecked(false);
610 _menu_action_hide_menu->setChecked(false);
611 }
612 else if (e->key()==Qt::Key_Z && !(e->modifiers()^Qt::ControlModifier))
613 {
614 //Ctrl-Z does an undo
615 undo();
616 }
617 else
618 {
619 // Perhaps it's for someone else
620 e->ignore();
621 }
645622 }
646623
647624
650627 if (isFullScreen())
651628 {
652629 showNormal();
653 _popupmenu_settings->setItemChecked(_menu_item_number_fullscreen,false);
630 _menu_action_fullscreen->setChecked(false);
654631 }
655632 else
656633 {
657634 showFullScreen();
658 _popupmenu_settings->setItemChecked(_menu_item_number_fullscreen,true);
635 _menu_action_fullscreen->setChecked(true);
659636 }
660637 }
661638
664641 if (menuBar()->isHidden())
665642 {
666643 menuBar()->show();
667 _popupmenu_settings->setItemChecked(_menu_item_number_hide_menu,false);
668 }
669 else if (menuBar()->isShown())
644 _menu_action_hide_menu->setChecked(false);
645 }
646 else if (menuBar()->isVisible())
670647 {
671648 menuBar()->hide();
672 _popupmenu_settings->setItemChecked(_menu_item_number_hide_menu,true);
649 _menu_action_hide_menu->setChecked(true);
673650 }
674651
675652 if (statusBar()->isHidden())
676653 statusBar()->show();
677 else if (statusBar()->isShown())
654 else if (statusBar()->isVisible())
678655 statusBar()->hide();
679656 }
680657
2121
2222 #ifndef _evolvotron_main_h_
2323 #define _evolvotron_main_h_
24
25 #include <qcheckbox.h>
26 #include <qmenubar.h>
27 #include <qstatusbar.h>
28 #include <qmainwindow.h>
29 #include <qgrid.h>
30 #include <qtimer.h>
3124
3225 #include "function_registry.h"
3326 #include "transform_factory.h"
7770 protected:
7871
7972 //! Class encapsulating everything needed for undo functionality.
73 /*! \todo This is too big to be a nested class.
74 */
8075 class History
8176 {
8277 protected:
181176 //! Dialog for selecting a favourite function (also holds the state for favourite stuff)
182177 DialogFavourite* _dialog_favourite;
183178
184 //! The menubar.
185 QMenuBar* _menubar;
186
187179 //! The file menu.
188 QPopupMenu* _popupmenu_file;
180 QMenu* _popupmenu_file;
189181
190182 //! The edit menu.
191 QPopupMenu* _popupmenu_edit;
183 QMenu* _popupmenu_edit;
192184
193185 //! ID for the undo item (so we can disable it).
194 int _popupmenu_edit_undo_id;
186 QAction* _popupmenu_edit_undo_action;
195187
196188 //! The settings menu
197 QPopupMenu* _popupmenu_settings;
198
199 //! Item number for setting check mark
200 int _menu_item_number_fullscreen;
201
202 //! Item number for setting check mark
203 int _menu_item_number_hide_menu;
189 QMenu* _popupmenu_settings;
190
191 //! Action for setting fullscreen
192 QAction* _menu_action_fullscreen;
193
194 //! Action for hiding menubar
195 QAction* _menu_action_hide_menu;
204196
205197 //! The help menu.
206 QPopupMenu* _popupmenu_help;
198 QMenu* _popupmenu_help;
207199
208200 //! Select autocooling (also serves to reset the generation count).
209201 QCheckBox* _checkbox_autocool_enable;
215207 QPushButton* _button_autocool_reheat;
216208
217209 //! Grid for image display areas
218 QGrid* _grid;
210 QWidget* _grid;
219211
220212 //! Timer to drive tick() slot
221213 QTimer* _timer;
250242 }
251243
252244 //! Accessor.
253 const SpawnMemberFn last_spawn_method() const
245 SpawnMemberFn last_spawn_method() const
254246 {
255247 return _last_spawn_method;
256248 }
307299 ~EvolvotronMain();
308300
309301 //! Accessor. Returns true if function name recognised. Forwards to DialogFavourite.
310 const bool favourite_function(const std::string& f);
302 bool favourite_function(const std::string& f);
311303
312304 //! Accessor. Forwards to DialogFavourite.
313305 void favourite_function_unwrapped(bool v);
2727 mutatable_image_display.h \
2828 mutatable_image_display_big.h \
2929 mutation_parameters_qobject.h \
30 platform_specific.h \
3031 render_parameters.h \
3132 transform_factory.h \
32 usage_text.h \
33 vbox_scrollview.h
33 usage_text.h
3434
3535 SOURCES += \
3636 args.cpp \
5050 mutatable_image_display.cpp \
5151 mutatable_image_display_big.cpp \
5252 mutation_parameters_qobject.cpp \
53 platform_specific.cpp \
5354 render_parameters.cpp \
54 transform_factory.cpp \
55 vbox_scrollview.cpp
55 transform_factory.cpp
5656
2525
2626 #include "libfunction_precompiled.h"
2727
28 #include <qapplication.h>
29 #include <qcheckbox.h>
30 #include <qcombobox.h>
31 #include <qcursor.h>
32 #include <qdatetime.h>
33 #include <qdialog.h>
34 #include <qgrid.h>
35 #include <qgroupbox.h>
36 #include <qhbox.h>
37 #include <qhgroupbox.h>
38 #include <qimage.h>
39 #include <qlabel.h>
40 #include <qlayout.h>
41 #include <qmainwindow.h>
42 #include <qmessagebox.h>
43 #include <qobject.h>
44 #include <qpushbutton.h>
45 #include <qradiobutton.h>
46 #include <qregexp.h>
47 #include <qslider.h>
48 #include <qspinbox.h>
49 #include <qstatusbar.h>
50 #include <qstring.h>
51 #include <qtabwidget.h>
52 #include <qtextedit.h>
53 #include <qtooltip.h>
54 #include <qvbox.h>
55 #include <qvbuttongroup.h>
56 #include <qvgroupbox.h>
57 #include <qwidget.h>
28 #include <stack>
29
30 #include <boost/optional.hpp>
31
32 #include <QtXml>
33
34 #include <QApplication>
35 #include <QButtonGroup>
36 #include <QCheckBox>
37 #include <QComboBox>
38 #include <QCursor>
39 #include <QDateTime>
40 #include <QDialog>
41 #include <QFileDialog>
42 #include <QGroupBox>
43 #include <QImage>
44 #include <QKeyEvent>
45 #include <QLabel>
46 #include <QList>
47 #include <QLayout>
48 #include <QMainWindow>
49 #include <QMenuBar>
50 #include <QMessageBox>
51 #include <QMutex>
52 #include <QObject>
53 #include <QPixmap>
54 #include <QPainter>
55 #include <QPushButton>
56 #include <QRadioButton>
57 #include <QRegExp>
58 #include <QScrollArea>
59 #include <QSize>
60 #include <QSlider>
61 #include <QSpinBox>
62 #include <QStatusBar>
63 #include <QString>
64 #include <QTabWidget>
65 #include <QTextBrowser>
66 #include <QTextEdit>
67 #include <QThread>
68 #include <QTimer>
69 #include <QToolTip>
70 #include <QWaitCondition>
71 #include <QWidget>
72
73 #define stringify(S) __STRING(S)
5874
5975 #endif
2222 #include "libevolvotron_precompiled.h"
2323
2424 #include "mutatable_image.h"
25
26 #include <stack>
27
28 #include <qxml.h>
2925
3026 #include "function_node_info.h"
3127 #include "function_top.h"
8783 return boost::shared_ptr<const MutatableImage>(new MutatableImage(root,sinusoidal_z(),spheremap(),lock));
8884 }
8985
90 const bool MutatableImage::is_constant() const
86 bool MutatableImage::is_constant() const
9187 {
9288 return top().is_constant();
9389 }
9490
95 const bool MutatableImage::ok() const
91 bool MutatableImage::ok() const
9692 {
9793 return top().ok();
9894 }
205201 {
206202 out
207203 << "<?xml version=\"1.0\"?>\n"
208 << "<evolvotron-image-function version=\""
209 << EVOLVOTRON_VERSION
204 << "<evolvotron-image-function version="
205 << "\""
206 << stringify(EVOLVOTRON_VERSION)
210207 << "\""
211208 << " zsweep=\""
212209 << (_sinusoidal_z ? "sinusoidal" : "linear")
283280
284281 //! Called for start elements.
285282 /*! Don't know anything about namespaces - parameters ignored.
286 Stick with latin1() conversion because we shouldn't have put anything fancy in the file
287283 */
288284 bool startElement(const QString&,const QString& localName,const QString&,const QXmlAttributes& atts)
289285 {
290 const std::string element(localName.latin1());
286 const std::string element(localName.toLocal8Bit().data());
291287
292288 if (_expect_characters)
293289 {
309305 else
310306 {
311307 const QString version=atts.value(idx);
312 if (version!=QString(EVOLVOTRON_VERSION))
308 if (version!=QString(stringify(EVOLVOTRON_VERSION)))
313309 {
314310 QString tmp;
315 tmp="Warning: File saved from a different evolvotron version: "+version+"\n(This is version "+QString(EVOLVOTRON_VERSION)+")\n";
316 _report+=tmp.latin1();
311 tmp="Warning: File saved from a different evolvotron version: "+version+"\n(This is version "+QString(stringify(EVOLVOTRON_VERSION))+")\n";
312 _report+=tmp.toLocal8Bit().data();
317313 }
318314 }
319315
333329 {
334330 QString tmp;
335331 tmp="Error: zsweep attribute expected \"sinusoidal\" or \"linear\", but got \""+zsweep+"\"\n";
336 _report+=tmp.latin1();
332 _report+=tmp.toLocal8Bit().data();
337333 return false;
338334 }
339335 }
354350 {
355351 QString tmp;
356352 tmp="Error: projection attribute expected \"spheremap\" or \"planar\", but got \""+projection+"\"\n";
357 _report+=tmp.latin1();
353 _report+=tmp.toLocal8Bit().data();
358354 return false;
359355 }
360356 }
418414
419415 //! We don't need to check this matches startElement
420416 /*! Don't know anything about namespaces - parameter ignored.
421 Stick with latin1() conversion because we shouldn't have put anything fancy in the file
422417 */
423418 bool endElement(const QString&, const QString& localName, const QString&)
424419 {
425 const std::string element(localName.latin1());
420 const std::string element(localName.toLocal8Bit().data());
426421
427422 if (_expect_characters)
428423 {
440435
441436 bool characters(const QString& s)
442437 {
443 QString stripped=s.stripWhiteSpace();
438 QString stripped=s.simplified();
444439
445440 if (stripped.isEmpty())
446441 {
451446 {
452447 if (!_expect_characters)
453448 {
454 QString tmp;
455 tmp = "Error: Unexpected character data : \""+s+"\"\n";
456 _report += tmp.latin1();
449 QString tmp;
450 tmp = "Error: Unexpected character data : \""+s+"\"\n";
451 _report += tmp.toLocal8Bit().data();
457452 return false;
458453 }
459454 }
462457
463458 if (_expect_characters_type)
464459 {
465 _stack.top()->type(s.latin1());
460 _stack.top()->type(s.toLocal8Bit().data());
466461 _expect_characters_type=false;
467462 }
468463 else if (_expect_characters_iterations)
472467 _expect_characters_iterations=false;
473468 if (!ok)
474469 {
475 QString tmp;
476 tmp = "Error: Couldn't parse \""+s+"\" as an integer\n";
477 _report += tmp.latin1();
470 QString tmp;
471 tmp = "Error: Couldn't parse \""+s+"\" as an integer\n";
472 _report += tmp.toLocal8Bit().data();
478473 return false;
479 }
474 }
480475 }
481476 else if (_expect_characters_parameter)
482477 {
485480 _expect_characters_parameter=false;
486481 if (!ok)
487482 {
488 QString tmp;
489 tmp = "Error: Couldn't parse \""+s+"\" as a real\n";
490 _report+=tmp.latin1();
483 QString tmp;
484 tmp = "Error: Couldn't parse \""+s+"\" as a real\n";
485 _report+=tmp.toLocal8Bit().data();
491486 return false;
492487 }
493488
533528 if (ok)
534529 {
535530 // Might be a warning message in there.
536 report=load_handler.errorString().latin1();
531 report=load_handler.errorString().toLocal8Bit().data();
537532
538533 assert(info.get());
539534 std::auto_ptr<FunctionNode> root(FunctionNode::create(function_registry,*info,report));
569564 {
570565 QString tmp;
571566 tmp = "Parse error: "+load_handler.errorString()+"\n";
572 report=tmp.latin1();
567 report=tmp.toLocal8Bit().data();
573568 return boost::shared_ptr<const MutatableImage>();
574569 }
575570 }
7979 const FunctionTop& top() const;
8080
8181 //! Accessor.
82 const bool sinusoidal_z() const
82 bool sinusoidal_z() const
8383 {
8484 return _sinusoidal_z;
8585 }
8686
8787 //! Accessor.
88 const bool spheremap() const
88 bool spheremap() const
8989 {
9090 return _spheremap;
9191 }
9292
9393 //! Accessor.
94 const bool locked() const
94 bool locked() const
9595 {
9696 return _locked;
9797 }
103103 }
104104
105105 //! Accessor.
106 const unsigned long long serial() const
106 unsigned long long serial() const
107107 {
108108 return _serial;
109109 }
127127 const XYZ get_rgb(uint x,uint y,uint f,uint width,uint height,uint frames,Random01* r01,uint multisample) const;
128128
129129 //! Return whether image value is independent of position.
130 const bool is_constant() const;
130 bool is_constant() const;
131131
132132 //! Save the function-tree to the stream
133133 std::ostream& save_function(std::ostream& out) const;
139139 void get_stats(uint& total_nodes,uint& total_parameters,uint& depth,uint& width,real& proportion_constant) const;
140140
141141 //! Check the function tree is ok.
142 const bool ok() const;
142 bool ok() const;
143143 };
144144
145145 #endif
2323
2424 #include "mutatable_image_computer.h"
2525
26 // Needed for getpriority/setprioirty
27 #include <sys/resource.h>
28
2926 #include "mutatable_image.h"
3027 #include "mutatable_image_computer_farm.h"
3128 #include "mutatable_image_computer_task.h"
29
30 #include "platform_specific.h"
3231
3332 MutatableImageComputer::MutatableImageComputer(MutatableImageComputerFarm* frm,int niceness)
3433 :
5453 std::clog << "...deleted a computer\n";
5554 }
5655
57 /*! Compute threads run this method untill killed (probably by the destructor being invoked by the original spawning thread.
56 /*! Compute threads run this method until killed (probably by the destructor being invoked by the original spawning thread.
5857 */
5958 void MutatableImageComputer::run()
6059 {
6160 std::clog << "Thread starting\n";
6261
63 // Lower compute thread priority slightly;
64 // computing yet more stuff is less important than displaying the results we've got.
65 /*! \todo: People porting to non-Linux (BSD, MacOS, Fink etc) please send
66 a suitable #ifdef-able patch if you need something different here.
67 Note that this code relies on Linux NPTL's non-Posix-compliant
68 thread-specific nice value (although without a suitable replacement
69 per-thread priority mechanism it's just as well it's that way).
70 \todo: Should check some error codes, but it's pretty harmless if it doesn't work.
71 */
72 const int current_priority=getpriority(PRIO_PROCESS,0);
73 setpriority(PRIO_PROCESS,0,std::min(19,current_priority+_niceness));
62 // Lower compute thread priority slightly; computing yet more stuff
63 // is less important than displaying the results we've got so far.
64 add_thread_niceness(_niceness);
7465
7566 // Run until something sets the kill flag
7667 while(!communications().kill())
2121
2222 #ifndef _mutatable_image_computer_h_
2323 #define _mutatable_image_computer_h_
24
25 #include <qthread.h>
26 #include <qmutex.h>
2724
2825 #include "mutatable_image.h"
2926 #include "random.h"
8380 /*! Mutex is recursive to allow nesting.
8481 */
8582 Communications()
86 :_mutex(true)
83 :_mutex()
8784 ,_defer(false)
8885 ,_abort(false)
8986 ,_kill(false)
9693 _defer=v;
9794 }
9895 //! Mutex-protected accessor.
99 const bool defer() const
96 bool defer() const
10097 {
10198 QMutexLocker lock(&_mutex);
10299 const bool ret=_defer;
109106 _abort=v;
110107 }
111108 //! Mutex-protected accessor.
112 const bool abort() const
109 bool abort() const
113110 {
114111 QMutexLocker lock(&_mutex);
115112 const bool ret=_abort;
122119 _kill=v;
123120 }
124121 //! Mutex-protected accessor.
125 const bool kill() const
122 bool kill() const
126123 {
127124 QMutexLocker lock(&_mutex);
128125 const bool ret=_kill;
129126 return ret;
130127 }
131128 //! Check union of all flags with only one mutex lock.
132 const bool kill_or_abort_or_defer() const
129 bool kill_or_abort_or_defer() const
133130 {
134131 QMutexLocker lock(&_mutex);
135132 const bool ret=(_kill || _abort || _defer);
161158 }
162159
163160 //! Accessor.
164 MutatableImageComputerFarm*const farm() const
161 MutatableImageComputerFarm* farm() const
165162 {
166163 return _farm;
167164 }
6161 }
6262
6363 //! Predicate function to test whether a task has been aborted
64 static const bool predicate_aborted(const boost::shared_ptr<const MutatableImageComputerTask> t)
64 static bool predicate_aborted(const boost::shared_ptr<const MutatableImageComputerTask> t)
6565 {
6666 return t->aborted();
6767 }
236236 }
237237 }
238238
239 const uint MutatableImageComputerFarm::tasks() const
239 uint MutatableImageComputerFarm::tasks() const
240240 {
241241 uint ret=0;
242242
2121
2222 #ifndef _mutatable_image_computer_farm_h_
2323 #define _mutatable_image_computer_farm_h_
24
25 #include <qthread.h>
2624
2725 #include "useful.h"
2826
106104 ~MutatableImageComputerFarm();
107105
108106 //! Accessor.
109 const uint num_threads() const
107 uint num_threads() const
110108 {
111109 return _computers.size();
112110 }
133131 void abort_for(const MutatableImageDisplay* disp);
134132
135133 //! Number of tasks in queues
136 const uint tasks() const;
134 uint tasks() const;
137135 };
138136
139137 #endif
8383 {
8484 for (uint f=0;f<frames();f++)
8585 {
86 _images.push_back(QImage(fragment_size(),32));
86 _images.push_back(QImage(fragment_size(),QImage::Format_RGB32));
8787 }
8888 }
8989
2121
2222 #ifndef _mutatable_image_computer_task_h_
2323 #define _mutatable_image_computer_task_h_
24
25 #include <qsize.h>
2624
2725 #include "mutatable_image.h"
2826 #include "mutatable_image_display.h"
144142 }
145143
146144 //! Accessor.
147 MutatableImageDisplay*const display() const
145 MutatableImageDisplay* display() const
148146 {
149147 return _display;
150148 }
174172 }
175173
176174 //! Accessor.
177 const uint frames() const
175 uint frames() const
178176 {
179177 return _frames;
180178 }
181179
182180 //! Accessor.
183 const uint level() const
181 uint level() const
184182 {
185183 return _level;
186184 }
187185
188186 //! Accessor.
189 const uint fragment() const
187 uint fragment() const
190188 {
191189 return _fragment;
192190 }
193191
194192 //! Accessor.
195 const uint number_of_fragments() const
193 uint number_of_fragments() const
196194 {
197195 return _number_of_fragments;
198196 }
199197
200198 //! Accessor.
201 const bool jittered_samples() const
199 bool jittered_samples() const
202200 {
203201 return _jittered_samples;
204202 }
205203
206204 //! Accessor.
207 const uint multisample_grid() const
205 uint multisample_grid() const
208206 {
209207 return _multisample_grid;
210208 }
211209
212210 //! Serial number
213 const unsigned long long int serial() const
211 unsigned long long int serial() const
214212 {
215213 return _serial;
216214 }
217215
218216 //! Accessor.
219 const uint priority() const
217 uint priority() const
220218 {
221219 return _priority;
222220 }
236234 }
237235
238236 //! Accessor.
239 const uint current_col() const
237 uint current_col() const
240238 {
241239 return _current_col;
242240 }
243241
244242 //! Accessor.
245 const uint current_row() const
243 uint current_row() const
246244 {
247245 return _current_row;
248246 }
249247
250248 //! Accessor.
251 const uint current_frame() const
249 uint current_frame() const
252250 {
253251 return _current_frame;
254252 }
255253
256254 //! Accessor.
257 const uint current_pixel() const
255 uint current_pixel() const
258256 {
259257 return _current_pixel;
260258 }
261259
262260 //!Accessor.
263 const bool completed() const
261 bool completed() const
264262 {
265263 return _completed;
266264 }
2323 #include "libevolvotron_precompiled.h"
2424
2525 #include "mutatable_image_display.h"
26
27 #include <qscrollview.h>
28 #include <qmessagebox.h>
29 #include <qfiledialog.h>
30 #include <qpngio.h>
3126
3227 #include "mutatable_image_display_big.h"
3328 #include "evolvotron_main.h"
4439 - and the size of the offscreen buffer (only used if fixed_size is true).
4540 Note that we use Qt's WDestructiveCode flag to ensure the destructor is called on close
4641 */
47 MutatableImageDisplay::MutatableImageDisplay(QWidget* parent,EvolvotronMain* mn,bool full,bool fixed_size,const QSize& sz,uint f,uint fr)
48 :QWidget(parent,0,Qt::WDestructiveClose)
49 ,_main(mn)
50 ,_full_functionality(full)
51 ,_fixed_size(fixed_size)
52 ,_image_size(sz)
53 ,_frames(f)
54 ,_framerate(fr)
55 ,_current_frame(0)
56 ,_animate_reverse(false)
57 ,_timer(0)
58 ,_resize_in_progress(false)
59 ,_current_display_level(0)
60 ,_current_display_multisample_grid(0)
61 ,_icon_serial(0LL)
62 ,_properties(0)
63 ,_menu(0)
64 ,_menu_big(0)
65 ,_serial(0LL)
66 {
67 setWFlags(getWFlags()|Qt::WNoAutoErase);
68 setBackgroundMode(Qt::NoBackground);
42 MutatableImageDisplay::MutatableImageDisplay(EvolvotronMain* mn,bool full_functionality,bool fixed_size,const QSize& sz,uint f,uint fr)
43 :_main(mn)
44 ,_full_functionality(full_functionality)
45 ,_fixed_size(fixed_size)
46 ,_image_size(sz)
47 ,_frames(f)
48 ,_framerate(fr)
49 ,_current_frame(0)
50 ,_animate_reverse(false)
51 ,_timer(0)
52 ,_resize_in_progress(false)
53 ,_current_display_level(0)
54 ,_current_display_multisample_grid(0)
55 ,_icon_serial(0LL)
56 ,_properties(0)
57 ,_menu(0)
58 ,_menu_big(0)
59 ,_menu_item_action_lock(0)
60 ,_serial(0LL)
61 {
62 setAttribute(Qt::WA_DeleteOnClose,true);
63
64 setFocusPolicy(Qt::StrongFocus);
6965
7066 _properties=new DialogMutatableImageDisplay(this);
7167
72 _menu=new QPopupMenu(this);
68 _menu=new QMenu(this);
7369
7470 // Most items on the context menu aren't appropriate for a window displaying a single big image
7571 if (_full_functionality)
7672 {
77 // We want to use a checkmark for "Locked"
78 _menu->setCheckable(true);
79
80 _menu->insertItem("&Respawn",this,SLOT(menupick_respawn()));
81
82 _menu->insertSeparator();
83
84 _menu->insertItem("&Spawn",this,SLOT(menupick_spawn()));
85 _menu->insertItem("Spawn re&coloured",this,SLOT(menupick_spawn_recoloured()));
86
87 _menu_warped=new QPopupMenu(this);
88 _menu_warped->insertItem("Random &Mix",this,SLOT(menupick_spawn_warped_random()));
89 _menu_warped->insertItem("Zoom &In",this,SLOT(menupick_spawn_warped_zoom_in()));
90 _menu_warped->insertItem("Zoom &Out",this,SLOT(menupick_spawn_warped_zoom_out()));
91 _menu_warped->insertItem("&Rotate",this,SLOT(menupick_spawn_warped_rotate()));
92 _menu_warped->insertItem("&Pan XY",this,SLOT(menupick_spawn_warped_pan_xy()));
93 _menu_warped->insertItem("Pan &X",this,SLOT(menupick_spawn_warped_pan_x()));
94 _menu_warped->insertItem("Pan &Y",this,SLOT(menupick_spawn_warped_pan_y()));
95 _menu_warped->insertItem("Pan &Z",this,SLOT(menupick_spawn_warped_pan_z()));
96
97 _menu->insertItem("Spawn &warped",_menu_warped);
98
99 _menu->insertSeparator();
100
101 _menu_item_number_lock =_menu->insertItem("&Lock",this,SLOT(menupick_lock()));
102
103 _menu->insertSeparator();
73 _menu->addAction("Respawn",this,SLOT(menupick_respawn()));
74
75 _menu->addSeparator();
76
77 _menu->addAction("Spawn",this,SLOT(menupick_spawn()));
78 _menu->addAction("Spawn recoloured",this,SLOT(menupick_spawn_recoloured()));
79
80 _menu_warped=_menu->addMenu("Spawn warped");
81 _menu_warped->addAction("Random Mix",this,SLOT(menupick_spawn_warped_random()) );
82 _menu_warped->addAction("Zoom In" ,this,SLOT(menupick_spawn_warped_zoom_in()) );
83 _menu_warped->addAction("Zoom Out" ,this,SLOT(menupick_spawn_warped_zoom_out()));
84 _menu_warped->addAction("Rotate" ,this,SLOT(menupick_spawn_warped_rotate()) );
85 _menu_warped->addAction("Pan XY" ,this,SLOT(menupick_spawn_warped_pan_xy()) );
86 _menu_warped->addAction("Pan X" ,this,SLOT(menupick_spawn_warped_pan_x()) );
87 _menu_warped->addAction("Pan Y" ,this,SLOT(menupick_spawn_warped_pan_y()) );
88 _menu_warped->addAction("Pan Z" ,this,SLOT(menupick_spawn_warped_pan_z()) );
89
90 _menu->addSeparator();
91
92 _menu_item_action_lock=_menu->addAction("Lock",this,SLOT(menupick_lock()));
93 _menu_item_action_lock->setCheckable(true);
94
95 _menu->addSeparator();
10496 }
10597
106 _menu_big=new QPopupMenu(this);
107 _menu_big->insertItem("&Resizable",this,SLOT(menupick_big_resizable()));
108 _menu_big->insertSeparator();
109 _menu_big->insertItem("&256x256",this,SLOT(menupick_big_256x256()));
110 _menu_big->insertItem("&512x512",this,SLOT(menupick_big_512x512()));
111 _menu_big->insertItem("&768x768",this,SLOT(menupick_big_768x768()));
112 _menu_big->insertItem("&1024x1024",this,SLOT(menupick_big_1024x1024()));
113 _menu_big->insertItem("&2048x2048",this,SLOT(menupick_big_2048x2048()));
114 _menu_big->insertItem("&4096x4096",this,SLOT(menupick_big_4096x4096()));
115 _menu_big->insertSeparator();
116 _menu_big->insertItem("640x&480",this,SLOT(menupick_big_640x480()));
117 _menu_big->insertItem("1024x&768",this,SLOT(menupick_big_1024x768()));
118 _menu_big->insertItem("1280x&960",this,SLOT(menupick_big_1280x960()));
119 _menu_big->insertItem("1&600x1200",this,SLOT(menupick_big_1600x1200()));
120
121 _menu->insertItem("&Enlarge",_menu_big);
122
123 _menu->insertSeparator();
98 _menu_big=_menu->addMenu("Enlarge");
99 _menu_big->addAction("Resizable",this,SLOT(menupick_big_resizable()));
100 _menu_big->addSeparator();
101 _menu_big->addAction("256x256" ,this,SLOT(menupick_big_256x256()));
102 _menu_big->addAction("512x512" ,this,SLOT(menupick_big_512x512()) );
103 _menu_big->addAction("768x768" ,this,SLOT(menupick_big_768x768()) );
104 _menu_big->addAction("1024x1024",this,SLOT(menupick_big_1024x1024()));
105 _menu_big->addAction("2048x2048",this,SLOT(menupick_big_2048x2048()));
106 _menu_big->addAction("4096x4096",this,SLOT(menupick_big_4096x4096()));
107 _menu_big->addSeparator();
108 _menu_big->addAction("640x480" ,this,SLOT(menupick_big_640x480()) );
109 _menu_big->addAction("1024x768" ,this,SLOT(menupick_big_1024x768()) );
110 _menu_big->addAction("1280x960" ,this,SLOT(menupick_big_1280x960()) );
111 _menu_big->addAction("1600x1200",this,SLOT(menupick_big_1600x1200()));
112
113 _menu->addSeparator();
124114
125 _menu->insertItem("Save &image",this,SLOT(menupick_save_image()));
126 _menu->insertItem("Save &function",this,SLOT(menupick_save_function()));
115 _menu->addAction("Save image",this,SLOT(menupick_save_image()));
116 _menu->addAction("Save function",this,SLOT(menupick_save_function()));
127117
128118 if (_full_functionality)
129119 {
130 _menu->insertItem("L&oad function",this,SLOT(menupick_load_function()));
131 }
132
133 _menu->insertSeparator();
134 _menu->insertItem("Simplif&y function",this,SLOT(menupick_simplify()));
135 _menu->insertItem("&Properties...",this,SLOT(menupick_properties()));
120 _menu->addAction("Load function",this,SLOT(menupick_load_function()));
121 }
122
123 _menu->addSeparator();
124 _menu->addAction("Simplify function",this,SLOT(menupick_simplify()));
125 _menu->addAction("Properties...",this,SLOT(menupick_properties()));
136126
137127 main().hello(this);
138128
175165 _offscreen_images.clear();
176166 }
177167
178 const uint MutatableImageDisplay::simplify_constants(bool single_action)
168 uint MutatableImageDisplay::simplify_constants(bool single_action)
179169 {
180170 if (single_action) main().history().begin_action("simplify");
181171
203193
204194 if (single_action)
205195 {
206 if (_icon.get()) _main->setIcon(*_icon);
196 if (_icon.get()) _main->setWindowIcon(*_icon);
207197
208198 std::stringstream msg;
209199 msg << "Eliminated " << nodes_eliminated << " redundant function nodes\n";
233223 _animate_reverse=true;
234224 }
235225 }
236 repaint(false); // Use repaint rather than update because we really do want this to happen immediately.
226 repaint(); // Use repaint rather than update because we really do want this to happen immediately.
237227 }
238228
239229 void MutatableImageDisplay::image_function(const boost::shared_ptr<const MutatableImage>& i,bool one_of_many)
259249 {
260250 // Clear any existing image data - stops old animations continuing to play
261251 for (uint f=0;f<_offscreen_pixmaps.size();f++)
262 _offscreen_pixmaps[f].fill(black);
252 _offscreen_pixmaps[f].fill(QColor(0,0,0));
263253
264254 // Queue a redraw
265255 update();
274264 _offscreen_images_inbox.clear();
275265
276266 // Update lock status displayed in menu
277 _menu->setItemChecked(_menu_item_number_lock,(_image_function.get() ? _image_function->locked() : false));
267 if (_menu_item_action_lock)
268 _menu_item_action_lock->setChecked(_image_function.get() ? _image_function->locked() : false);
278269
279270 if (_image_function.get())
280271 {
395386 _offscreen_images.resize(0);
396387 for (uint f=0;f<_frames;f++)
397388 {
398 _offscreen_images.push_back(QImage(render_size,32));
389 _offscreen_images.push_back(QImage(render_size,QImage::Format_RGB32));
399390
400391 for (OffscreenImageInbox::mapped_type::const_iterator it=inbox_level.begin();it!=inbox_level.end();++it)
401392 {
402 bitBlt
393 QPainter painter(&_offscreen_images.back());
394 painter.drawImage
403395 (
404 &_offscreen_images.back(),
405 (*it).second->fragment_origin().width(),(*it).second->fragment_origin().height(),
406 &(*it).second->images()[f],
407 0,0,
408 (*it).second->fragment_size().width(),(*it).second->fragment_size().height(),
409 0
396 QPoint((*it).second->fragment_origin().width(),(*it).second->fragment_origin().height()),
397 (*it).second->images()[f]
410398 );
411399 }
412400 }
414402
415403 for (uint f=0;f<_frames;f++)
416404 {
417 //! \todo Pick a scaling mode: smooth or not (or put it under GUI control).
418 // Curiously, although smoothscale seems to be noticeably slower, it doesn't look any better.
419 _offscreen_pixmaps[f].convertFromImage(_offscreen_images[f].scale(image_size()));
405 //! \todo Pick a scaling mode: Qt::SmoothTransformation vs Qt::FastTransformation (default) (and put it under GUI control).
406 //! \todo Expose dither mode control: Qt::DiffuseDither vs Qt::ThresholdDither
407 _offscreen_pixmaps[f]=QPixmap::fromImage(_offscreen_images[f].scaled(image_size()),(Qt::ColorOnly|Qt::ThresholdDither));
420408 }
421409
422410 //! Note the resolution we've displayed so out-of-order low resolution images are dropped
424412 _current_display_multisample_grid=task->multisample_grid();
425413
426414 // For an icon, take the first image big enough to (hopefully) be filtered down nicely.
427 // The converter seems to auto-create an alpha mask sometimes (images with const-color areas), which is quite cool.
415 // The (Qt3) converter seems to auto-create an alpha mask sometimes (images with const-color areas), which is quite cool.
428416 const QSize icon_size(32,32);
429417 if (task->serial()!=_icon_serial && (task->level()==0 || (render_size.width()>=2*icon_size.width() && render_size.height()>=2*icon_size.height())))
430418 {
431 const QImage icon_image(_offscreen_images[_offscreen_images.size()/2].smoothScale(icon_size));
419 const QImage icon_image(_offscreen_images[_offscreen_images.size()/2].scaled(icon_size));
432420
433 _icon=std::auto_ptr<QPixmap>(new QPixmap(icon_size));
434 _icon->convertFromImage(icon_image,QPixmap::Color);
421 if (!_icon.get()) _icon=std::auto_ptr<QPixmap>(new QPixmap(icon_size));
422 (*_icon)=QPixmap::fromImage(icon_image,Qt::ColorOnly);
435423
436424 _icon_serial=task->serial();
437425 }
458446 }
459447 }
460448
461 _menu->setItemChecked(_menu_item_number_lock,l);
449 _menu_item_action_lock->setChecked(l);
462450 }
463451
464452 /*! Enlargements are implied by a non-full-functionality displays.
471459 void MutatableImageDisplay::paintEvent(QPaintEvent*)
472460 {
473461 // Repaint the screen from the offscreen pixmaps
474 // (If there have been resizes they will be black)
475 bitBlt(this,0,0,&_offscreen_pixmaps[_current_frame]);
462 QPainter painter(this);
463 painter.drawPixmap(0,0,_offscreen_pixmaps[_current_frame]);
476464
477465 // If this is the first paint event after a resize we can start computing images for the new size.
478466 if (_resize_in_progress)
500488 // Resize and reset our offscreen pixmap (something to do while we wait)
501489 for (uint f=0;f<_offscreen_pixmaps.size();f++)
502490 {
503 _offscreen_pixmaps[f].resize(image_size()); // resize destroys contents
504 _offscreen_pixmaps[f].fill(black); // so set it
491 _offscreen_pixmaps[f]=QPixmap(image_size());
492 _offscreen_pixmaps[f].fill(QColor(0,0,0));
505493 }
506494
507495 // Flag for the next paintEvent to tell it a recompute can be started now.
511499
512500 void MutatableImageDisplay::mousePressEvent(QMouseEvent* event)
513501 {
514 if (event->button()==RightButton)
502 if (event->button()==Qt::RightButton)
515503 {
516504 _menu->exec(QCursor::pos());
517505 }
518 else if (event->button()==MidButton)
506 else if (event->button()==Qt::MidButton)
519507 {
520508 // Take a snapshot to undo back to.
521509 main().history().begin_action("middle-button drag");
525513 _mid_button_adjust_start_pos=event->pos();
526514 _mid_button_adjust_last_pos=event->pos();
527515 }
528 else if (_full_functionality && event->button()==LeftButton)
529 {
530 if (_icon.get()) _main->setIcon(*_icon);
516 else if (_full_functionality && event->button()==Qt::LeftButton)
517 {
518 if (_icon.get()) _main->setWindowIcon(*_icon);
531519
532520 menupick_spawn();
533521 }
535523
536524 void MutatableImageDisplay::mouseMoveEvent(QMouseEvent* event)
537525 {
538 if (event->state()&MidButton)
526 if (event->buttons()&Qt::MidButton)
539527 {
540528 if (locked())
541529 {
549537 Transform transform=TransformIdentity();
550538
551539 // Shift button (no ctrl) is various zooms
552 if (event->state()&ShiftButton && !(event->state()&ControlButton))
540 if (event->modifiers()&Qt::ShiftModifier && !(event->modifiers()&Qt::ControlModifier))
553541 {
554542 // Alt-Shift is anisotropic
555 if (event->state()&AltButton)
543 if (event->modifiers()&Qt::AltModifier)
556544 {
557545 // Only scale in non-degenerate cases
558546 if (
600588 }
601589 }
602590 }
603 else if (event->state()&ControlButton)
591 else if (event->modifiers()&Qt::ControlModifier)
604592 {
605593 // Control-alt is shear
606 if (event->state()&AltButton)
594 if (event->modifiers()&Qt::AltModifier)
607595 {
608596 const real cx=image_size().width()/2.0;
609597 const real cy=image_size().width()/2.0;
765753 */
766754 void MutatableImageDisplay::menupick_save_image()
767755 {
768 if (_icon.get()) _main->setIcon(*_icon);
756 if (_icon.get()) _main->setWindowIcon(*_icon);
769757
770758 std::clog << "Save requested...\n";
771759
775763 }
776764 else
777765 {
778 QString save_filename=QFileDialog::getSaveFileName(".","Images (*.ppm *.png *.qt-mng)",this,"Save image","Save image to a PPM, PNG or QT-MNG file");
766 const QString save_filename=QFileDialog::getSaveFileName
767 (
768 this,
769 "Save image to a PNG or PPM file",
770 ".",
771 "Images (*.png *.ppm)"
772 );
773
779774 if (!save_filename.isEmpty())
780775 {
781 const char* save_format="PPM";
782 if (save_filename.upper().endsWith(".PPM"))
776 QString save_format="PNG";
777 if (save_filename.toUpper().endsWith(".PPM"))
783778 {
784779 save_format="PPM";
785780 }
786 else if (save_filename.upper().endsWith(".PNG"))
781 else if (save_filename.toUpper().endsWith(".PNG"))
787782 {
788783 save_format="PNG";
789 }
790 else if (save_filename.upper().endsWith(".QT-MNG"))
791 {
792 save_format="QT-MNG";
793784 }
794785 else
795786 {
797788 (
798789 this,
799790 "Evolvotron",
800 QString("Unrecognised file suffix.\nFile will be written in ")+QString(save_format)+QString(" format.")
791 QString("Unrecognised file suffix.\nFile will be written in ")+save_format+QString(" format.")
801792 );
802793 }
803794
804 if (!save_filename.isEmpty())
795 for (uint f=0;f<_offscreen_images.size();f++)
805796 {
806 std::auto_ptr<QFile> mng_file;
807 if (save_format=="QT-MNG")
797 QString actual_save_filename(save_filename);
798
799 if (_offscreen_images.size()>1)
808800 {
809 mng_file=std::auto_ptr<QFile>(new QFile(save_filename));
810 if (!mng_file->open(IO_WriteOnly|IO_Truncate))
801 QString frame_component;
802 frame_component.sprintf(".f%06d",f);
803 int insert_point=save_filename.lastIndexOf(QString("."));
804 if (insert_point==-1)
811805 {
812 QMessageBox::critical(this,"Evolvotron","Failed to open file "+save_filename);
806 actual_save_filename.append(frame_component);
813807 }
814 else
808 else
815809 {
816 QPNGImagePacker packer(mng_file.get(),32,0);
817
818 for (uint f=0;f<_offscreen_images.size();f++)
819 {
820 if (!packer.packImage(_offscreen_images[f]))
821 {
822 QMessageBox::critical(this,"Evolvotron","Failed while writing file "+save_filename+"\nFile will be removed");
823 mng_file->close();
824 if (!mng_file->remove())
825 {
826 QMessageBox::critical(this,"Evolvotron","Failed to remove file "+save_filename);
827 }
828 break;
829 }
830 std::clog << "Appended frame " << f << " to " << save_filename.local8Bit() << "\n";
831 }
832
833 mng_file->close();
834 if (mng_file->status()!=IO_Ok)
835 {
836 QMessageBox::critical(this,"Evolvotron","Failed while closing file "+save_filename+"\nFile will be removed");
837 if (!mng_file->remove())
838 {
839 QMessageBox::critical(this,"Evolvotron","Failed to remove file "+save_filename);
840 }
841 }
810 actual_save_filename.insert(insert_point,frame_component);
842811 }
843812 }
844 else
813
814 if (!_offscreen_images[f].save(actual_save_filename,save_format.toLocal8Bit()))
845815 {
846 for (uint f=0;f<_offscreen_images.size();f++)
816 QMessageBox::critical(this,"Evolvotron","Failed to write file "+actual_save_filename);
817 if (f<_offscreen_images.size()-1)
847818 {
848 QString actual_save_filename(save_filename);
849
850 if (_offscreen_images.size()>1)
851 {
852 QString frame_component;
853 frame_component.sprintf(".f%06d",f);
854 int insert_point=save_filename.findRev(QString("."));
855 if (insert_point==-1)
856 {
857 actual_save_filename.append(frame_component);
858 }
859 else
860 {
861 actual_save_filename.insert(insert_point,frame_component);
862 }
863 }
864
865 if (!_offscreen_images[f].save(actual_save_filename.local8Bit(),save_format))
866 {
867 QMessageBox::critical(this,"Evolvotron","Failed to write file "+actual_save_filename);
868 if (f<_offscreen_images.size()-1)
869 {
870 QMessageBox::critical(this,"Evolvotron","Not attempting to save remaining images in animation");
871 }
872 break;
873 }
819 QMessageBox::critical(this,"Evolvotron","Not attempting to save remaining images in animation");
874820 }
821 break;
875822 }
876823 }
877824 }
881828
882829 void MutatableImageDisplay::menupick_save_function()
883830 {
884 if (_icon.get()) _main->setIcon(*_icon);
885
886 QString save_filename=QFileDialog::getSaveFileName(".","Functions (*.xml)",this,"Save function","Save image function to an XML file");
831 if (_icon.get()) _main->setWindowIcon(*_icon);
832
833 const QString save_filename=QFileDialog::getSaveFileName
834 (
835 this,
836 "Save image function to an XML file",
837 ".",
838 "Functions (*.xml)"
839 );
840
887841 if (!save_filename.isEmpty())
888842 {
889 std::ofstream file(save_filename.local8Bit());
843 std::ofstream file(save_filename.toLocal8Bit());
890844 _image_function->save_function(file);
891845 file.flush();
892846 if (!file)
898852
899853 void MutatableImageDisplay::menupick_load_function()
900854 {
901 QString load_filename=QFileDialog::getOpenFileName(".","Functions (*.xml)",this,"Load function","Load image function from an XML file");
855 const QString load_filename=QFileDialog::getOpenFileName
856 (
857 this,
858 "Load image function from an XML file",
859 ".",
860 "Functions (*.xml)"
861 );
862
902863 if (!load_filename.isEmpty())
903864 {
904 std::ifstream file(load_filename.local8Bit());
865 std::ifstream file(load_filename.toLocal8Bit());
905866 std::string report;
906867 boost::shared_ptr<const MutatableImage> new_image_function(MutatableImage::load_function(_main->mutation_parameters().function_registry(),file,report));
907868 if (new_image_function.get()==0)
999960 image_function()->save_function(xml);
1000961
1001962 _properties->set_content(msg.str(),xml.str());
1002 if (_icon.get()) _properties->setIcon(*_icon);
963 if (_icon.get()) _properties->setWindowIcon(*_icon);
1003964 _properties->exec();
1004965 }
1005966
1008969 */
1009970 void MutatableImageDisplay::spawn_big(bool scrollable,const QSize& sz)
1010971 {
1011 MutatableImageDisplayBig*const top_level_widget=new MutatableImageDisplayBig(0,&main());
1012 if (_icon.get()) top_level_widget->setIcon(*_icon);
972 MutatableImageDisplayBig*const top_level_widget=new MutatableImageDisplayBig(&main());
973 top_level_widget->setLayout(new QVBoxLayout);
974 if (_icon.get()) top_level_widget->setWindowIcon(*_icon);
1013975
1014976 MutatableImageDisplay* display=0;
1015
977
1016978 if (scrollable)
1017979 {
1018 QScrollView*const scrollview=new QScrollView(top_level_widget,0,Qt::WDestructiveClose);
1019 display=new MutatableImageDisplay(scrollview->viewport(),&main(),false,true,sz,_frames,_framerate);
1020 scrollview->addChild(display);
1021 top_level_widget->hold(scrollview);
980 QScrollArea*const scrollview=new QScrollArea;
981 top_level_widget->layout()->addWidget(scrollview);
982 display=new MutatableImageDisplay(&main(),false,true,sz,_frames,_framerate);
983 scrollview->setWidget(display);
1022984 }
1023985 else
1024986 {
1025 display=new MutatableImageDisplay(top_level_widget,&main(),false,false,QSize(0,0),_frames,_framerate);
1026 top_level_widget->hold(display);
987 display=new MutatableImageDisplay(&main(),false,false,QSize(0,0),_frames,_framerate);
988 top_level_widget->layout()->addWidget(display);
1027989 }
1028990
1029991 top_level_widget->show();
2222 #ifndef _mutatable_image_display_h_
2323 #define _mutatable_image_display_h_
2424
25 #include <qpixmap.h>
26 #include <qpopupmenu.h>
27
2825 #include "mutatable_image.h"
2926 #include "mutatable_image_computer.h"
3027 #include "dialog_mutatable_image_display.h"
4542 EvolvotronMain* _main;
4643
4744 //! Flag for whether context menu should display all options.
45 /*! false also implies a standalone window
46 */
4847 const bool _full_functionality;
4948
5049 //! Flag for whether the offscreen buffer has fixed size
113112 DialogMutatableImageDisplay* _properties;
114113
115114 //! Context (right-click) menu.
116 QPopupMenu* _menu;
115 QMenu* _menu;
117116
118117 //! Submenu for spawn warped options.
119 QPopupMenu* _menu_warped;
118 QMenu* _menu_warped;
120119
121120 //! Submenu for Big image options.
122 QPopupMenu* _menu_big;
121 QMenu* _menu_big;
123122
124123 //! Position of item in menu.
125124 /*! This is the only menu item we need to retain this information for becuase we need it to set the lock check-mark.
126125 */
127 uint _menu_item_number_lock;
126 QAction* _menu_item_action_lock;
128127
129128 //! Coordinate of mouse event which started mid-button adjustment
130129 QPoint _mid_button_adjust_start_pos;
137136
138137 public:
139138 //! Constructor.
140 MutatableImageDisplay(QWidget* parent,EvolvotronMain* mn,bool full,bool fixed_size,const QSize& image_size,uint f,uint fr);
139 MutatableImageDisplay(EvolvotronMain* mn,bool full_functionality,bool fixed_size,const QSize& image_size,uint f,uint fr);
141140
142141 //! Destructor.
143142 virtual ~MutatableImageDisplay();
149148 }
150149
151150 //! Accessor.
152 const bool locked() const
151 bool locked() const
153152 {
154153 return (_image_function.get()!=0 ? _image_function->locked() : false);
155154 }
205204 public slots:
206205
207206 //! Simplify the held image, return the number of nodes eliminated
208 const uint simplify_constants(bool single);
207 uint simplify_constants(bool single);
209208
210209 protected slots:
211210
2626
2727 #include "evolvotron_main.h"
2828
29 /*! The constructor is passed:
30 - the owning widget (expected to be null but it might get used somewhere else one day)
31 - the EvolvotronMain providing spawn and farm services,
32 - the MutatableImageDisplay to be held
33 */
34 MutatableImageDisplayBig::MutatableImageDisplayBig(QWidget* parent,EvolvotronMain* mn)
35 :QWidget(parent,0,Qt::WDestructiveClose)
36 ,_main(mn)
37 ,_held(0)
38 {}
29 MutatableImageDisplayBig::MutatableImageDisplayBig(EvolvotronMain* mn)
30 :QWidget(mn,Qt::Window) // We're a window, but with a parent
31 ,_main(mn)
32 {
33 setAttribute(Qt::WA_DeleteOnClose,true);
34
35 setWindowTitle("Evolvotron");
36 setMinimumSize(256,256);
37
38 //setSizeGripEnabled(true); // Only an option if we give the window a statusbar, or make it a dialog
39 }
3940
4041 /*! Don't think destructor needs to do anything to _display... Qt takes care of it
4142 */
4243 MutatableImageDisplayBig::~MutatableImageDisplayBig()
43 {}
44 {
45 std::clog << "An enlargement was deleted\n";
46 }
4447
4548 /*! There's not much point in dropping back to normal mode (from fullscreen) if the main
4649 app is fullscreen because we'll just be hidden, so close instead under such circumstances.
5558 else
5659 showNormal();
5760 }
58 else if (e->key()==Qt::Key_F && !(e->state()^Qt::ControlButton))
61 else if (e->key()==Qt::Key_F && !e->modifiers())
5962 {
6063 if (isFullScreen())
6164 {
7275 e->ignore();
7376 }
7477 }
75
76 void MutatableImageDisplayBig::resizeEvent(QResizeEvent*)
77 {
78 _held->resize(size());
79 }
00 // Source file for evolvotron
1 // Copyright (C) 2002,2003 Tim Day
1 // Copyright (C) 2009 Tim Day
22 /*
33 This program is free software; you can redistribute it and/or
44 modify it under the terms of the GNU General Public License
2727 //! Intended to be used as a top-level widget holding a single MutatableImageDisplay
2828 /*! We just used to use a display or scroll view itself as a top-level widget,
2929 but need this to get some specific keyboard effects.
30 As a MutatableImageDisplayHolder it actually has more in common with EvolvotronMain.
3130 \todo class name is a bit misleading. This is really just a slightly modified top-level holder.
3231 */
3332 class MutatableImageDisplayBig : public QWidget
3534 Q_OBJECT
3635
3736 protected:
38 //! Pointer back to the application object to access services.
37 //! Pointer back to the application object to access fullscreen state
3938 EvolvotronMain* _main;
40
41 //! The widget being held. Probably be a QScrollView or MutatableImageDisplay.
42 QWidget* _held;
4339
4440 public:
4541 //! Constructor.
46 MutatableImageDisplayBig(QWidget* parent,EvolvotronMain* mn);
42 MutatableImageDisplayBig(EvolvotronMain* mn);
4743
4844 //! Destructor.
4945 virtual ~MutatableImageDisplayBig();
5046
5147 //! Accessor.
52 EvolvotronMain*const main() const
48 EvolvotronMain* main() const
5349 {
5450 assert(_main!=0);
5551 return _main;
5652 }
5753
58 //! Accessor.
59 void hold(QWidget* w)
60 {
61 _held=w;
62 }
63
6454 protected:
6555 //! Handle key-presses
6656 void keyPressEvent(QKeyEvent* e);
67
68 //! Need to propagate resizes to held widget
69 virtual void resizeEvent(QResizeEvent*);
7057 };
7158
7259 #endif
0 // Source file for evolvotron
1 // Copyright (C) 2008 Tim Day
2 /*! \page License License
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /*! \file
20 \brief Implementation of platform specific functions.
21 */
22
23 #include "libevolvotron_precompiled.h"
24
25 #include "platform_specific.h"
26
27 #ifdef PLATFORM_LINUX
28 #include <sched.h> // for CPU count
29 #include <sys/resource.h> // for getpriority/setprioirty
30 #endif
31
32 #ifdef PLATFORM_BSD
33 #include <sys/param.h> // for CPU count
34 #include <sys/sysctl.h> // for CPU count
35 #include <sys/resource.h> // for getpriority/setprioirty
36 #endif
37
38 uint get_number_of_processors()
39 {
40 boost::optional<uint> num_processors;
41
42 #ifdef PLATFORM_LINUX
43 {
44 cpu_set_t cpus;
45 if (sched_getaffinity(0,sizeof(cpu_set_t),&cpus)==0)
46 {
47 uint bits=0;
48 for (int i=0;i<CPU_SETSIZE;i++)
49 {
50 if (CPU_ISSET(i,&cpus)) bits++;
51 }
52 num_processors=bits;
53 }
54 }
55 #endif
56
57 #ifdef PLATFORM_BSD
58 {
59 // Code contributed by Linc Davis
60 int count;
61 size_t size=sizeof(count);
62 if (!sysctlbyname("hw.ncpu",&count,&size,NULL,0))
63 num_processors=count;
64 }
65 #endif
66
67 #if !defined(PLATFORM_LINUX) && !defined(PLATFORM_BSD)
68 #warning "No platform-specific implementation of get_number_of_processors selected"
69 #endif
70
71 if (!num_processors)
72 {
73 // If we can't find out... well, 2 is not uncommon these days.
74 num_processors=2;
75 std::cerr
76 << "Could not determine number of CPUs; guessing "
77 << num_processors.get()
78 << "\n";
79 //! todo For real fun, test the system and see what it scales to.
80 }
81
82 return num_processors.get();
83 }
84
85 void add_thread_niceness(uint n)
86 {
87 #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
88 /*! \todo: People porting to non-Linux (BSD, MacOS, Fink etc) please send
89 a suitable #ifdef-able patch if you need something different here.
90 Note that this code relies on Linux NPTL's non-Posix-compliant
91 thread-specific nice value (although without a suitable replacement
92 per-thread priority mechanism it's just as well it's that way).
93 \todo: Should check some error codes, but it's probably pretty harmless if it doesn't work.
94 */
95 const int current_priority=getpriority(PRIO_PROCESS,0);
96 setpriority(PRIO_PROCESS,0,std::min(19u,current_priority+n));
97 #else
98 #warning "No platform-specific implementation of add_thread_niceness available"
99 #endif
100 }
0 // Source file for evolvotron
1 // Copyright (C) 2008 Tim Day
2 /*! \page License License
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /*! \file
20 \brief Try to isolate platform specific code here (or rather, in the .cpp implementations)
21 */
22
23 #ifndef _platform_specific_h_
24 #define _platform_specific_h_
25
26 // qt3 for Darwin appears to define this, so use it to definitely select the PLATFORM_BSD option
27 #ifdef __DARWIN_X11__
28 #define PLATFORM_BSD
29 #undef PLATFORM_LINUX
30 #endif
31
32 //! Return the number of processors on the system
33 extern uint get_number_of_processors();
34
35 //! Lower the priority of the calling thread by increasing its "niceness" (unix 0-19 'nice' scale used)
36 extern void add_thread_niceness(uint);
37
38 #endif
2222 #ifndef _render_parameters_h_
2323 #define _render_parameters_h_
2424
25 template <typename T> bool change(T& dst,const T& src)
26 {
27 const T previous=dst;
28 dst=src;
29 return (dst!=previous);
30 }
31
2532 //! Class encapsulating things affecting rendering
2633 class RenderParameters : public QObject
2734 {
3239 ~RenderParameters();
3340
3441 //! Accessor.
35 const bool jittered_samples() const
42 bool jittered_samples() const
3643 {
3744 return _jittered_samples;
3845 }
4047 //! Accessor.
4148 void jittered_samples(bool v)
4249 {
43 _jittered_samples=v;
44 report_change();
50 if (change(_jittered_samples,v)) report_change();
4551 }
4652
4753 //! Accessor.
48 const uint multisample_grid() const
54 uint multisample_grid() const
4955 {
5056 assert(_multisample_grid>=1);
5157 return _multisample_grid;
5460 //! Accessor.
5561 void multisample_grid(uint v)
5662 {
57 _multisample_grid=v;
58 assert(_multisample_grid>=1);
59 report_change();
63 assert(v>=1);
64 if (change(_multisample_grid,v)) report_change();
6065 }
6166
6267 signals:
+0
-57
libevolvotron/vbox_scrollview.cpp less more
0 // Source file for evolvotron
1 // Copyright (C) 2002,2003,2004 Tim Day
2 /*
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version 2
6 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 /*! \file
19 \brief Implementation of class VBoxScrollView.
20 */
21
22 #include "libevolvotron_precompiled.h"
23
24 #include "vbox_scrollview.h"
25
26 VBoxScrollView::VBoxScrollView(QWidget* parent)
27 :QScrollView(parent)
28 {
29 setHScrollBarMode(QScrollView::AlwaysOff);
30 enableClipper(true);
31
32 QSizePolicy spx(QSizePolicy::Expanding,QSizePolicy::Preferred);
33 setSizePolicy(spx);
34
35 _vbox=new QVBox(viewport());
36 _vbox->setSizePolicy(spx);
37
38 addChild(_vbox);
39 }
40
41 /*! The contained VBox is resized so it's width tracks the visible width of the scrollview.
42 */
43 void VBoxScrollView::resizeEvent(QResizeEvent* e)
44 {
45 Superclass::resizeEvent(e);
46
47 std::clog
48 << "VBoxScrollView::ResizeEvent : with size "
49 << size().width() << "x" << size().height()
50 << " and contents size "
51 << contentsWidth() << "x" << contentsHeight()
52 << "\n";
53
54 _vbox->resize(visibleWidth(),_vbox->size().height());
55 }
56
+0
-51
libevolvotron/vbox_scrollview.h less more
0 // Source file for evolvotron
1 // Copyright (C) 2002,2003,2004 Tim Day
2 /*
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version 2
6 of the License, or (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 /*! \file
19 \brief Interface for class VBoxScrollView.
20 */
21
22 #ifndef _vbox_scrollview_h_
23 #define _vbox_scrollview_h_
24
25 #include <qscrollview.h>
26 #include <qobjectlist.h>
27
28 //! Scrollview containing a vbox, with the vbox width tracking the visible width of the scrolled area (height behaves as normal).
29 class VBoxScrollView : public QScrollView
30 {
31 typedef QScrollView Superclass;
32 public:
33
34 //! Constructor.
35 VBoxScrollView(QWidget* parent);
36
37 //! Handle resizes.
38 virtual void resizeEvent(QResizeEvent* e);
39
40 //! Returns the VBox. Widgets which want to be managed by this component should use this as their parent.
41 QWidget*const contentParent()
42 {
43 return _vbox;
44 }
45 protected:
46 //! Vbox for layout within scroll area
47 QVBox* _vbox;
48 };
49
50 #endif
2525 //! Functor implementing a pass-through Z coordinate policy
2626 struct FreeZ
2727 {
28 const float operator()(float z) const
28 float operator()(float z) const
2929 {
3030 return z;
3131 }
3737 ClampZ(float z)
3838 :_z(z)
3939 {}
40 const float operator()(float) const
40 float operator()(float) const
4141 {
4242 return _z;
4343 }
109109 assert(_width>0.0f);
110110 }
111111
112 const real width() const
112 real width() const
113113 {
114114 return _width;
115115 }
4343 virtual ~FunctionBoilerplate();
4444
4545 //! Accessor providing function name
46 virtual const char*const thisname() const
46 virtual const char* thisname() const
4747 =0;
4848
4949 //! Registration member returns a reference to class meta-information.
5050 static const FunctionRegistration get_registration(const char* fn_name);
5151
5252 //! Bits give some classification of the function type
53 static const uint type_classification() {return CLASSIFICATION;}
53 static uint type_classification() {return CLASSIFICATION;}
5454
5555 //! Bits give some classification of the function type
56 virtual const uint self_classification() const;
56 virtual uint self_classification() const;
5757
5858 //! Factory method to create a stub node for this type
5959 static std::auto_ptr<FunctionNode> stubnew(const MutationParameters& mutation_parameters,bool exciting);
7070 std::auto_ptr<FUNCTION> typed_deepclone() const;
7171
7272 //! Internal self-consistency check. We can add some extra checks.
73 virtual const bool ok() const;
73 virtual bool ok() const;
7474
7575 //! Save this node.
7676 virtual std::ostream& save_function(std::ostream& out,uint indent) const;
106106 }
107107
108108 template <typename FUNCTION,uint PARAMETERS,uint ARGUMENTS,bool ITERATIVE,uint CLASSIFICATION>
109 const uint FunctionBoilerplate<FUNCTION,PARAMETERS,ARGUMENTS,ITERATIVE,CLASSIFICATION>::self_classification() const
109 uint FunctionBoilerplate<FUNCTION,PARAMETERS,ARGUMENTS,ITERATIVE,CLASSIFICATION>::self_classification() const
110110 {
111111 return CLASSIFICATION;
112112 }
155155 }
156156
157157 template <typename FUNCTION,uint PARAMETERS,uint ARGUMENTS,bool ITERATIVE,uint CLASSIFICATION>
158 const bool FunctionBoilerplate<FUNCTION,PARAMETERS,ARGUMENTS,ITERATIVE,CLASSIFICATION>::ok() const
158 bool FunctionBoilerplate<FUNCTION,PARAMETERS,ARGUMENTS,ITERATIVE,CLASSIFICATION>::ok() const
159159 {
160160 return (
161161 params().size()==PARAMETERS
180180 #define FN_DTOR_DCL(FN) virtual ~FN();
181181 #define FN_DTOR_IMP(FN) FN::~FN() {}
182182
183 #define FN_VNAME_DCL(FN) virtual const char*const thisname() const;
184 #define FN_VNAME_IMP(FN) const char*const FN::thisname() const {return FN::classname();}
185
186 #define FN_SNAME_DCL(FN) static const char*const classname();
187 #define FN_SNAME_IMP(FN) const char*const FN::classname() {return #FN;}
183 #define FN_VNAME_DCL(FN) virtual const char* thisname() const;
184 #define FN_VNAME_IMP(FN) const char* FN::thisname() const {return FN::classname();}
185
186 #define FN_SNAME_DCL(FN) static const char* classname();
187 #define FN_SNAME_IMP(FN) const char* FN::classname() {return #FN;}
188188
189189 #define FUNCTION_BEGIN(FN,NP,NA,IT,CL) \
190190 class FN : public FunctionBoilerplate<FN,NP,NA,IT,CL> \
3333 //! Is constant if any (rather than default "all") function is constant.
3434 /*! One of the few cases it's worth overriding this method
3535 */
36 virtual const bool is_constant() const
36 virtual bool is_constant() const
3737 {
3838 return (arg(0).is_constant() || arg(1).is_constant());
3939 }
3333 //! Is constant if any (rather than default "all") function is constant.
3434 /*! One of the few cases it's worth overriding this method
3535 */
36 virtual const bool is_constant() const
36 virtual bool is_constant() const
3737 {
3838 return (arg(0).is_constant() || arg(1).is_constant() || arg(2).is_constant());
3939 }
2222 #ifndef _function_constant_h_
2323 #define _function_constant_h_
2424
25
26
2725 //------------------------------------------------------------------------------------------
2826
2927 //! Function class representing a constant value.
3836 //! Returns true, obviously.
3937 /*! One of the few cases this method is overriden; most (all?) other no-argument functions should return false
4038 */
41 virtual const bool is_constant() const
39 virtual bool is_constant() const
4240 {
4341 return true;
4442 }
2323 #ifndef _function_identity_h_
2424 #define _function_identity_h_
2525
26 //------------------------------------------------------------------------------------------
2627
2728 //! Function class simply returning the position argument.
2829 FUNCTION_BEGIN(FunctionIdentity,0,0,false,FnCore)
9797 }
9898 }
9999
100 const bool FunctionNode::verify_info(const FunctionNodeInfo& info,unsigned int np,unsigned int na,bool it,std::string& report)
100 bool FunctionNode::verify_info(const FunctionNodeInfo& info,unsigned int np,unsigned int na,bool it,std::string& report)
101101 {
102102 if (info.params().size()!=np)
103103 {
130130 return true;
131131 }
132132
133 const bool FunctionNode::is_constant() const
133 bool FunctionNode::is_constant() const
134134 {
135135 if (args().empty()) return false;
136136 for (unsigned int i=0;i<args().size();i++)
140140 return true;
141141 }
142142
143 const bool FunctionNode::ok() const
143 bool FunctionNode::ok() const
144144 {
145145 bool good=true;
146146 for (boost::ptr_vector<FunctionNode>::const_iterator it=args().begin();good && it!=args().end();it++)
151151 return good;
152152 }
153153
154 const bool FunctionNode::create_args(const FunctionRegistry& function_registry,const FunctionNodeInfo& info,boost::ptr_vector<FunctionNode>& args,std::string& report)
154 bool FunctionNode::create_args(const FunctionRegistry& function_registry,const FunctionNodeInfo& info,boost::ptr_vector<FunctionNode>& args,std::string& report)
155155 {
156156 for (boost::ptr_vector<FunctionNodeInfo>::const_iterator it=info.args().begin();it!=info.args().end();it++)
157157 {
188188 v.push_back((parameters.r01() < 0.5f ? -1.0f : 1.0f)*parameters.rnegexp());
189189 }
190190
191 const uint FunctionNode::stubiterations(const MutationParameters& parameters)
191 uint FunctionNode::stubiterations(const MutationParameters& parameters)
192192 {
193193 return 1+static_cast<uint>(floor(parameters.r01()*parameters.max_initial_iterations()));
194194 }
398398 return ret;
399399 }
400400
401 const FunctionTop*const FunctionNode::is_a_FunctionTop() const
401 const FunctionTop* FunctionNode::is_a_FunctionTop() const
402402 {
403403 return 0;
404404 }
405405
406 FunctionTop*const FunctionNode::is_a_FunctionTop()
406 FunctionTop* FunctionNode::is_a_FunctionTop()
407407 {
408408 return 0;
409409 }
8989 /*! Return true on success, false on fail with reasons in report string.
9090 Mainly for use by derived FunctionBoilerplate template to avoid duplicate code proliferation.
9191 */
92 static const bool verify_info(const FunctionNodeInfo& info,unsigned int np,unsigned int na,bool it,std::string& report);
92 static bool verify_info(const FunctionNodeInfo& info,unsigned int np,unsigned int na,bool it,std::string& report);
9393
9494 //! Build argument list.
9595 /*! Return true on success, false on fail with reasons in report string.
9696 Mainly for use by derived FunctionBoilerplate template to avoid duplicate code proliferation.
9797 */
98 static const bool create_args(const FunctionRegistry&,const FunctionNodeInfo& info,boost::ptr_vector<FunctionNode>& args,std::string& report);
98 static bool create_args(const FunctionRegistry&,const FunctionNodeInfo& info,boost::ptr_vector<FunctionNode>& args,std::string& report);
9999
100100 public:
101101
106106 Default implementation (and probably the only sensible one)
107107 is constant if all args are constant; no args returns false.
108108 */
109 virtual const bool is_constant() const;
109 virtual bool is_constant() const;
110110
111111 //! Internal self consistency check.
112 virtual const bool ok() const;
112 virtual bool ok() const;
113113
114114 //! Bits give some classification of the function type
115 virtual const uint self_classification() const
115 virtual uint self_classification() const
116116 =0;
117117
118118 //@{
119119 //! Query the node as to whether it is a FunctionTop (return null if not).
120 virtual const FunctionTop*const is_a_FunctionTop() const;
121 virtual FunctionTop*const is_a_FunctionTop();
120 virtual const FunctionTop* is_a_FunctionTop() const;
121 virtual FunctionTop* is_a_FunctionTop();
122122 //@}
123123
124124 //! This returns a new random bit of tree. Setting the "exciting" flag avoids basic node types, but only at the top level of the stub tree.
131131 static void stubargs(boost::ptr_vector<FunctionNode>&,const MutationParameters& parameters,uint n,bool exciting=false);
132132
133133 //! Return a suitable starting value for a node's iteration count (assuming it's iterative).
134 static const uint stubiterations(const MutationParameters& parameters);
134 static uint stubiterations(const MutationParameters& parameters);
135135
136136 //! Constructor given an array of params and args and an iteration count.
137137 /*! These MUST be provided; there are no alterative constructors.
157157 }
158158
159159 //! Accessor.
160 const real param(uint n) const
160 real param(uint n) const
161161 {
162162 assert(n<params().size());
163163 return params()[n];
164164 }
165165
166166 //! Accessor.
167 const uint iterations() const
167 uint iterations() const
168168 {
169169 return _iterations;
170170 }
231231 protected:
232232 //@{
233233 //! Useful constants used when some small sampling step is required (e.g gradient operators).
234 static const real epsilon() {return 1e-6;}
235 static const real epsilon2() {return 2.0*epsilon();}
236 static const real inv_epsilon() {return 1.0/epsilon();}
237 static const real inv_epsilon2() {return 1.0/epsilon2();}
238 static const real big_epsilon() {return sqrt(epsilon());}
234 static real epsilon() {return 1e-6;}
235 static real epsilon2() {return 2.0*epsilon();}
236 static real inv_epsilon() {return 1.0/epsilon();}
237 static real inv_epsilon2() {return 1.0/epsilon2();}
238 static real big_epsilon() {return sqrt(epsilon());}
239239 //@}
240240 };
241241
7373 }
7474
7575 //! Accessor.
76 const uint iterations() const
76 uint iterations() const
7777 {
7878 return _iterations;
7979 }
8989 }
9090
9191 //! Accessor.
92 const FunctionNodeStubNewFnPtr stubnew_fn() const
92 FunctionNodeStubNewFnPtr stubnew_fn() const
9393 {
9494 return _stubnew_fn;
9595 }
9696
9797 //! Accessor.
98 const FunctionNodeCreateFnPtr create_fn() const
98 FunctionNodeCreateFnPtr create_fn() const
9999 {
100100 return _create_fn;
101101 }
102102
103103 //! Accessor.
104 const uint params() const
104 uint params() const
105105 {
106106 return _params;
107107 }
108108
109109 //! Accessor.
110 const uint args() const
110 uint args() const
111111 {
112112 return _args;
113113 }
114114
115115 //! Accessor.
116 const bool iterative() const
116 bool iterative() const
117117 {
118118 return _iterative;
119119 }
120120
121121 //! Accessor.
122 const uint classification() const
122 uint classification() const
123123 {
124124 return _classification;
125125 }
3838 }
3939
4040 //! Return the registration for the function named (returns 0 if unknown)
41 const FunctionRegistration*const FunctionRegistry::lookup(const std::string& f) const
41 const FunctionRegistration* FunctionRegistry::lookup(const std::string& f) const
4242 {
4343 Registrations::const_iterator it=_registry_by_name.find(f);
4444 if (it==_registry_by_name.end())
3838 ~FunctionRegistry();
3939
4040 //! Return the registration for the function named (returns 0 if unknown)
41 const FunctionRegistration*const lookup(const std::string& f) const;
41 const FunctionRegistration* lookup(const std::string& f) const;
4242
4343 //! typedefed for convenience
4444 typedef boost::ptr_map<std::string,FunctionRegistration> Registrations;
159159 t.concatenate_on_right(TransformScale(2.0));
160160 }
161161 while (parameters.r01()<0.125);
162 while (parameters.r01()<0.125);
162
163 while (parameters.r01()<0.125)
163164 {
164165 t.concatenate_on_right(TransformScale(0.5));
165166 }
3838
3939 virtual const XYZ evaluate(const XYZ& p) const;
4040
41 virtual FunctionTop*const is_a_FunctionTop()
41 virtual FunctionTop* is_a_FunctionTop()
4242 {
4343 return this;
4444 }
4545
46 virtual const FunctionTop*const is_a_FunctionTop() const
46 virtual const FunctionTop* is_a_FunctionTop() const
4747 {
4848 return this;
4949 }
2121
2222 #ifndef _function_transform_h_
2323 #define _function_transform_h_
24
2524
2625 #include "transform.h"
2726
2323 #ifndef _functions_juliabrot_h_
2424 #define _functions_juliabrot_h_
2525
26
27
2826 //------------------------------------------------------------------------------------------
2927
3028 //! Mandelbrot/Julia iterator for fractal functions.
3129 /*! Returns i in 0 to iterations inclusive. i==iterations implies "in" set.
3230 */
33 inline const uint brot(const real z0r,const real z0i,const real cr,const real ci,const uint iterations)
31 inline uint brot(const real z0r,const real z0i,const real cr,const real ci,const uint iterations)
3432 {
3533 real zr=z0r;
3634 real zi=z0i;
6060 function_boilerplate.cpp \
6161 function_compose_pair.cpp \
6262 function_compose_triple.cpp \
63 function_constant.h \
64 function_identity.h \
63 function_constant.cpp \
64 function_identity.cpp \
6565 function_node.cpp \
6666 function_node_info.cpp \
6767 function_pre_transform.cpp \
104104 report_change();
105105 }
106106
107 const real MutationParameters::decay_factor() const
107 real MutationParameters::decay_factor() const
108108 {
109109 assert(_autocool_halflife!=0);
110110 return (_autocool_enable ? pow(0.5,_autocool_generations/static_cast<double>(_autocool_halflife)) : 1.0);
159159
160160 std::auto_ptr<FunctionNode> MutationParameters::random_function() const
161161 {
162 const FunctionRegistration*const fn_reg=random_weighted_function_registration();
162 const FunctionRegistration* fn_reg=random_weighted_function_registration();
163163 return (*(fn_reg->stubnew_fn()))(*this,false);
164164 }
165165
166 const FunctionRegistration*const MutationParameters::random_weighted_function_registration() const
166 const FunctionRegistration* MutationParameters::random_weighted_function_registration() const
167167 {
168168 const real r=r01();
169169
180180 }
181181 }
182182
183 const real MutationParameters::random_function_branching_ratio() const
183 real MutationParameters::random_function_branching_ratio() const
184184 {
185185 real weighted_args=0.0;
186186
222222 report_change();
223223 }
224224
225 const real MutationParameters::get_weighting(const FunctionRegistration* fn)
225 real MutationParameters::get_weighting(const FunctionRegistration* fn)
226226 {
227227 std::map<const FunctionRegistration*,real>::const_iterator it=_function_weighting.find(fn);
228228 assert(it!=_function_weighting.end());
142142 }
143143
144144 //! Return a number in the range [0,1)
145 const real r01() const
145 real r01() const
146146 {
147147 return _r01();
148148 }
149149
150 const real rnegexp() const
150 real rnegexp() const
151151 {
152152 return _r_negexp();
153153 }
154154
155155 //! Accessor, with decay.
156 const real effective_magnitude_parameter_variation() const
156 real effective_magnitude_parameter_variation() const
157157 {
158158 return base_magnitude_parameter_variation()*decay_factor();
159159 }
160160 //! Accessor.
161 const real base_magnitude_parameter_variation() const
161 real base_magnitude_parameter_variation() const
162162 {
163163 return _base_magnitude_parameter_variation;
164164 }
170170 }
171171
172172 //! Accessor, with decay.
173 const real effective_probability_parameter_reset() const
173 real effective_probability_parameter_reset() const
174174 {
175175 return base_probability_parameter_reset()*decay_factor();
176176 }
177177 //! Accessor.
178 const real base_probability_parameter_reset() const
178 real base_probability_parameter_reset() const
179179 {
180180 return _base_probability_parameter_reset;
181181 }
187187 }
188188
189189 //! Accessor, with decay.
190 const real effective_probability_glitch() const
190 real effective_probability_glitch() const
191191 {
192192 return base_probability_glitch()*decay_factor();
193193 }
194194 //! Accessor.
195 const real base_probability_glitch() const
195 real base_probability_glitch() const
196196 {
197197 return _base_probability_glitch;
198198 }
204204 }
205205
206206 //! Accessor, with decay.
207 const real effective_probability_shuffle() const
207 real effective_probability_shuffle() const
208208 {
209209 return base_probability_shuffle()*decay_factor();
210210 }
211211 //! Accessor.
212 const real base_probability_shuffle() const
212 real base_probability_shuffle() const
213213 {
214214 return _base_probability_shuffle;
215215 }
221221 }
222222
223223 //! Accessor, with decay.
224 const real effective_probability_insert() const
224 real effective_probability_insert() const
225225 {
226226 return base_probability_insert()*decay_factor();
227227 }
228228 //! Accessor.
229 const real base_probability_insert() const
229 real base_probability_insert() const
230230 {
231231 return _base_probability_insert;
232232 }
238238 }
239239
240240 //! Accessor.
241 const real effective_probability_substitute() const
241 real effective_probability_substitute() const
242242 {
243243 return base_probability_substitute()*decay_factor();
244244 }
245245 //! Accessor.
246 const real base_probability_substitute() const
246 real base_probability_substitute() const
247247 {
248248 return _base_probability_substitute;
249249 }
255255 }
256256
257257 //! Accessor.
258 const real proportion_constant() const
258 real proportion_constant() const
259259 {
260260 return _proportion_constant;
261261 }
267267 }
268268
269269 //! Accessor.
270 const real identity_supression() const
270 real identity_supression() const
271271 {
272272 return _identity_supression;
273273 }
279279 }
280280
281281 //! Accessor.
282 const uint max_initial_iterations() const
282 uint max_initial_iterations() const
283283 {
284284 return _max_initial_iterations;
285285 }
291291 }
292292
293293 //! Accessor, with decay.
294 const real effective_probability_iterations_change_step() const
294 real effective_probability_iterations_change_step() const
295295 {
296296 return base_probability_iterations_change_step()*decay_factor();
297297 }
298298 //! Accessor.
299 const real base_probability_iterations_change_step() const
299 real base_probability_iterations_change_step() const
300300 {
301301 return _base_probability_iterations_change_step;
302302 }
308308 }
309309
310310 //! Accessor, with decay.
311 const real effective_probability_iterations_change_jump() const
311 real effective_probability_iterations_change_jump() const
312312 {
313313 return base_probability_iterations_change_jump()*decay_factor();
314314 }
315315 //! Accessor.
316 const real base_probability_iterations_change_jump() const
316 real base_probability_iterations_change_jump() const
317317 {
318318 return _base_probability_iterations_change_jump;
319319 }
325325 }
326326
327327 //! Accessor.
328 const real proportion_basic() const
328 real proportion_basic() const
329329 {
330330 return _proportion_basic;
331331 }
337337 }
338338
339339 //! Accessor.
340 const bool autocool_enable() const
340 bool autocool_enable() const
341341 {
342342 return _autocool_enable;
343343 }
350350 }
351351
352352 //! Accessor.
353 const int autocool_halflife() const
353 int autocool_halflife() const
354354 {
355355 return _autocool_halflife;
356356 }
362362 }
363363
364364 //! Accessor
365 const int autocool_generations() const
365 int autocool_generations() const
366366 {
367367 return _autocool_generations;
368368 }
382382 //! Calculate branching ratio for above calls
383383 /* Call user should be checking this and diluting with boring nodes to keep it under control
384384 */
385 const real random_function_branching_ratio() const;
385 real random_function_branching_ratio() const;
386386
387387 //! This returns a new random bit of tree.
388388 /*! Setting the "exciting" flag avoids the most basic node types, but only at the top level of the stub tree.
393393
394394 void randomize_function_weightings_for_classifications(uint classification_mask);
395395
396 const real get_weighting(const FunctionRegistration* fn);
396 real get_weighting(const FunctionRegistration* fn);
397397
398398 protected:
399399
400400 //! Compute current decay factor
401 const real decay_factor() const;
401 real decay_factor() const;
402402
403403 //! Return a random function appropriately biased by current settings
404404 std::auto_ptr<FunctionNode> random_function() const;
405405
406406 //! Return a random function registration, appropriately biased by current settings
407 const FunctionRegistration*const random_weighted_function_registration() const;
407 const FunctionRegistration* random_weighted_function_registration() const;
408408
409409 //! Intended for Qt-world subclass to override to emit signal.
410410 virtual void report_change();
5959 }
6060 }
6161
62 inline const real value(const XYZ& q,real rx,real ry,real rz)
62 inline real value(const XYZ& q,real rx,real ry,real rz)
6363 {
6464 return rx*q.x()+ry*q.y()+rz*q.z();
6565 }
6666
67 inline const real surve(real t)
67 inline real surve(real t)
6868 {
6969 return t*t*(3.0-2.0*t);
7070 }
7171
72 inline const real lerp(real t,real a,real b)
72 inline real lerp(real t,real a,real b)
7373 {
7474 return a+t*(b-a);
7575 }
7676
77 const real Noise::operator()(const XYZ& p) const
77 real Noise::operator()(const XYZ& p) const
7878 {
7979 // Crank up the frequency a bit otherwise don't see much variation in base case
8080 const real tx=2.0*p.x()+10000.0;
3030 Noise(uint seed);
3131
3232 //! Return noise value at a point.
33 const real operator()(const XYZ& p) const;
34
33 real operator()(const XYZ& p) const;
34
3535 protected:
3636 //! Number of table entries.
3737 enum {N=256};
3333 Random01::~Random01()
3434 {}
3535
36 const double Random01::operator()()
36 double Random01::operator()()
3737 {
3838 return _gen();
3939 }
3838 //! Return a random number.
3939 /*! \warning Returns double instead of real because suspect NegExp can return Inf otherwise.
4040 */
41 virtual const double operator()()
41 virtual double operator()()
4242 =0;
4343 };
4444
5353 virtual ~Random01();
5454
5555 //! Return next number in sequence.
56 virtual const double operator()();
56 virtual double operator()();
5757 private:
5858
5959 //! Base generator
9090 {}
9191
9292 //! Return next number in sequence.
93 virtual const double operator()()
93 virtual double operator()()
9494 {
9595 return -_mean*log(1.0-_generator());
9696 }
1212 REGISTER_DCL(FunctionIdentity);
1313 REGISTER_DCL(FunctionPostTransform);
1414 REGISTER_DCL(FunctionPreTransform);
15 REGISTER_DCL(FunctionTop);
16 REGISTER_DCL(FunctionTransform);
17 REGISTER_DCL(FunctionTransformGeneralised);
1815 REGISTER_DCL(FunctionAdd);
1916 REGISTER_DCL(FunctionMultiply);
2017 REGISTER_DCL(FunctionDivide);
113110 REGISTER_DCL(FunctionPostTransformGeneralised);
114111 REGISTER_DCL(FunctionTransformQuadratic);
115112 REGISTER_DCL(FunctionRotate);
113 REGISTER_DCL(FunctionTop);
114 REGISTER_DCL(FunctionTransformGeneralised);
115 REGISTER_DCL(FunctionTransform);
116116
117117 void register_all_functions(FunctionRegistry& r)
118118 {
122122 register_FunctionIdentity(r);
123123 register_FunctionPostTransform(r);
124124 register_FunctionPreTransform(r);
125 register_FunctionTop(r);
126 register_FunctionTransform(r);
127 register_FunctionTransformGeneralised(r);
128125 register_FunctionAdd(r);
129126 register_FunctionMultiply(r);
130127 register_FunctionDivide(r);
223220 register_FunctionPostTransformGeneralised(r);
224221 register_FunctionTransformQuadratic(r);
225222 register_FunctionRotate(r);
223 register_FunctionTop(r);
224 register_FunctionTransformGeneralised(r);
225 register_FunctionTransform(r);
226226 }
7777 if (_verbose) std::clog << "[-" << _what << ":" << (*_instance_counts)[_what] << "]" << ( (*_instance_counts)[_what]==0 ? "\n" : "");
7878 }
7979
80 const bool InstanceCounted::is_clear()
80 bool InstanceCounted::is_clear()
8181 {
8282 bool ok=true;
8383 for (std::map<std::string,uint>::const_iterator it=(*_instance_counts).begin();it!=(*_instance_counts).end();it++)
2323 #define _useful_h_
2424
2525 #include <algorithm>
26 #include <boost/ptr_container/ptr_map.hpp>
27 #include <boost/ptr_container/ptr_vector.hpp>
28 #include <boost/random.hpp>
29 #include <boost/shared_array.hpp>
30 #include <boost/shared_ptr.hpp>
31 #include <boost/tuple/tuple.hpp>
32 #include <boost/utility.hpp>
33 #include <boost/version.hpp>
3426 #include <cassert>
3527 #include <ctime>
3628 #include <cmath>
4537 #include <string>
4638 #include <sstream>
4739 #include <vector>
40
41 #include <boost/ptr_container/ptr_map.hpp>
42 #include <boost/ptr_container/ptr_vector.hpp>
43 #include <boost/random.hpp>
44 #include <boost/shared_array.hpp>
45 #include <boost/shared_ptr.hpp>
46 #include <boost/tuple/tuple.hpp>
47 #include <boost/utility.hpp>
48 #include <boost/version.hpp>
4849
4950 //! Convenience typedef.
5051 typedef unsigned int uint;
149150 InstanceCounted(const std::string& what,bool verbose);
150151 virtual ~InstanceCounted();
151152
152 static const bool is_clear();
153 static bool is_clear();
153154
154155 private:
155156 const std::string _what;
3434
3535 //@{
3636 //! Accessor.
37 const real x() const
37 real x() const
3838 {
3939 return rep[0];
4040 }
41 const real y() const
41 real y() const
4242 {
4343 return rep[1];
4444 }
121121 }
122122
123123 //! Return the square of the magnitude.
124 const real magnitude2() const
124 real magnitude2() const
125125 {
126126 return x()*x()+y()*y();
127127 }
128128
129129 //! Return the magnitude.
130 const real magnitude() const
130 real magnitude() const
131131 {
132132 return sqrt(magnitude2());
133133 }
134134
135135 //! Returns sum of x and y components.
136 const real sum_of_components() const
136 real sum_of_components() const
137137 {
138138 return x()+y();
139139 }
145145 void normalise();
146146
147147 //! Returns true if an origin centred rectangle with this vectors' semi-axes contains the argument.
148 const bool origin_centred_rect_contains(const XY& p) const
148 bool origin_centred_rect_contains(const XY& p) const
149149 {
150150 return (-x()<=p.x() && p.x()<=x() && -y()<=p.y() && p.y()<=y());
151151 }
164164 //! Dot product.
165165 /*! Perhaps a curious choice of operator but it works for me.
166166 */
167 inline const real operator%(const XY& a,const XY& b)
167 inline real operator%(const XY& a,const XY& b)
168168 {
169169 return a.x()*b.x()+a.y()*b.y();
170170 }
224224 return v.write(out);
225225 }
226226
227
228227 #endif
3636
3737 //@{
3838 //! Accessor.
39 const real x() const
39 real x() const
4040 {
4141 return rep[0];
4242 }
43 const real y() const
43 real y() const
4444 {
4545 return rep[1];
4646 }
47 const real z() const
47 real z() const
4848 {
4949 return rep[2];
5050 }
149149 }
150150
151151 //! Return the square of the magnitude.
152 const real magnitude2() const
152 real magnitude2() const
153153 {
154154 return x()*x()+y()*y()+z()*z();
155155 }
156156
157157 //! Return the magnitude.
158 const real magnitude() const
158 real magnitude() const
159159 {
160160 return sqrt(magnitude2());
161161 }
162162
163163 //! Returns sum of x, y and z components.
164 const real sum_of_components() const
164 real sum_of_components() const
165165 {
166166 return x()+y()+z();
167167 }
173173 void normalise();
174174
175175 //! Returns true if an origin centred cuboid with this vectors semi-axes contains the argument.
176 const bool origin_centred_rect_contains(const XYZ& p) const
176 bool origin_centred_rect_contains(const XYZ& p) const
177177 {
178178 return (-x()<=p.x() && p.x()<=x() && -y()<=p.y() && p.y()<=y() && -z()<=p.z() && p.z()<=z());
179179 }
186186 {
187187 return XYZ(v,v,v);
188188 }
189
190189 };
191190
192191 //! Cross product.
202201 //! Dot product.
203202 /*! Perhaps a curious choice of operator but it works for me.
204203 */
205 inline const real operator%(const XYZ& a,const XYZ& b)
204 inline real operator%(const XYZ& a,const XYZ& b)
206205 {
207206 return a.x()*b.x()+a.y()*b.y()+a.z()*b.z();
208207 }
294293 RandomXYZSphereNormal(Random01& rng);
295294 };
296295
297
298296 //! Generates a random point in or on an origin-centred ellipsoid with semi-axes of the specified size.
299297 class RandomXYZInEllipsoid : public XYZ
300298 {
00 TEMPLATE = subdirs
11
2 SUBDIRS = libfunction libevolvotron evolvotron evolvotron_render evolvotron_mutate evolvotron_match
2 SUBDIRS = libfunction libevolvotron evolvotron evolvotron_render evolvotron_mutate
33
+123
-0
mkdeb less more
0 #!/bin/bash
1
2 # Before using this you probably need to install
3 # sudo pbuilder yada devscripts lintian linda cdebootstrap
4 # and maybe dpkg-sig. Also:
5 # set up for sudo
6 # set up pbuilder with
7 # sudo emacs -nw /etc/pbuilderrc
8 # ...change MIRRORSITE & DEBSECSERVER
9 # sudo pbuilder create --distribution sarge/etch/whatever
10 # and/or update with
11 # sudo pbuilder update
12 # Expect a lot of warnings re LOGNAME - see Debian bug Bug#275118
13
14 # TODO: DEBEMAIL
15
16 VER=`./VERSION`
17
18 TARBALL=evolvotron-${VER}.tar.gz
19
20 if [ ! -s ${TARBALL} ] ; then
21 echo "Could't find ${TARBALL}" ;
22 exit ;
23 fi
24
25 export DISTRIBUTION=`lsb_release -s -c`
26
27
28 echo "*** Will package ${TARBALL} for distribution \"${DISTRIBUTION}\""
29 echo -n "*** Starting in 10 seconds..."
30 for t in 10 9 8 7 6 5 4 3 2 1 ; do sleep 1 ; echo -n "." ; done
31
32 PROJECT=`echo $TARBALL | sed 's/-.*//'`
33 TARBALLORIG="${PROJECT}_${VER}.orig.tar.gz"
34 REV="1${DISTRIBUTION}1"
35
36 WORKDIR=pkg_${VER}-${REV}
37 rm -r -f ${WORKDIR}
38 mkdir ${WORKDIR}
39 cd ${WORKDIR}
40
41 cp ../${TARBALL} ${TARBALLORIG}
42 tar xvfz ${TARBALLORIG}
43 mv ${PROJECT} ${PROJECT}-${VER}
44 cd ${PROJECT}-${VER}
45 mv CHANGES changelog # As per policy manual
46 sed -i "s/${VER}/${VER}-${REV}/g" VERSION
47
48 mkdir debian
49 echo "${PROJECT} (${VER}-${REV}) ${DISTRIBUTION}; urgency=low" > debian/changelog
50 echo >> debian/changelog
51 echo " * Package created by ${PROJECT}'s mkdeb script." >> debian/changelog
52 echo >> debian/changelog
53 DATE=`822-date`
54 echo " -- $USER <$EMAIL> $DATE" >> debian/changelog
55
56 # Presumably a dch -i here would increment revision
57
58 cat << EOF > debian/packages
59 Source: evolvotron
60 Section: graphics
61 Priority: extra
62 Maintainer: Tim Day <timday@bottlenose.demon.co.uk>
63 Standards-Version: 3.6.1
64 Upstream-Source: <URL:http://sourceforge.net/projects/evolvotron/index.htm>
65 Home-Page: <URL:http://www.bottlenose.demon.co.uk/share/evolvotron>
66 Description: Interactive evolutionary texture generator
67 Copyright: GPL
68 Copyright 2007 Tim Day
69 Build-Depends: qt4-qmake,qt4-dev-tools,libqt4-core,libqt4-dev,libqt4-xml,libboost1.35-dev,python,yada
70 Build: sh
71 export QTDIR=/usr/share/qt4
72 # Note: yada install deals with DEB_BUILD_OPTIONS 'nostrip'
73 if [ "${DEB_BUILD_OPTIONS#*noopt}" != "$DEB_BUILD_OPTIONS" ]; then
74 ./configure "CONFIG -= release" "CONFIG += debug"
75 else
76 ./configure # No noticeable advantage in overriding qt optimisation options
77 fi
78 make
79 Clean: sh
80 make distclean || make clean || true
81
82 Package: evolvotron
83 Architecture: any
84 Depends: []
85 Suggests: gimp
86 Description: Interactive evolutionary texture generator
87 A "generative art" application to evolve images/textures/patterns through an
88 iterative process of random mutation and user-selection driven evolution.
89 If you like lava lamps, and never got bored with the Mandelbrot Set,
90 this could be the software for you.
91 Install: sh
92 yada install -bin evolvotron/evolvotron
93 yada install -bin evolvotron_mutate/evolvotron_mutate
94 yada install -bin evolvotron_render/evolvotron_render
95 yada install -bin evolvotron/evolvotron
96 yada install -doc evolvotron.html
97 yada install -doc BUGS TODO changelog
98 yada install -man man/man1/evolvotron.1
99 yada install -man man/man1/evolvotron_mutate.1
100 yada install -man man/man1/evolvotron_render.1
101 Menu: ?package(evolvotron): needs="X11" section="Applications/Graphics" title="Evolvotron" hints="Bitmap" command="/usr/bin/evolvotron" longtitle="Evolutionary art program"
102 EOF
103
104 yada rebuild
105
106 cd ..
107 dpkg-source -b ${PROJECT}-${VER} ${TARBALLORIG}
108
109 # Alternative but inferior approach is apparently to do
110 # dpkg-buildpackage -rfakeroot
111
112 mkdir result
113 echo "Building package"
114 sudo pbuilder build --buildresult ./result ${PROJECT}_${VER}-${REV}.dsc
115
116 sudo chown ${USER}:${USER} result/*
117
118 RESULT=`(cd .. ; find ${WORKDIR} -name '*.deb')`
119 echo "Results: ${RESULT}"
120 echo "Don't forget to lintian and linda"
121 echo 'Also dpkg-sig --sign builder -k $DPKGSIG_KEYID any .deb files'
122
88 # NB Don't ship automatically generated .h file or contents of pkg
99 PRUNE='-name moc -prune -o -name obj -prune -o -name pkg_* -prune -o -name usage_text.h -prune'
1010
11 FILES_MISC=`ls evolvotron/{README,BUILD,LICENSE,TODO,CHANGES,VERSION,USAGE,BUGS,configure,doxygen.cfg,mktgz,mkdoc,text_to_markup.py} evolvotron/libfunction/update_register_all_functions`
12 FILES_EXTRAS=`ls evolvotron/extras/{README,spheremap.pov,spheremap.sh}`
11 FILES_MISC=`ls evolvotron/{README,BUILD,LICENSE,TODO,CHANGES,VERSION,USAGE,BUGS,configure,doxygen.cfg,mktgz,mkdeb,mkdoc,text_to_markup.py} evolvotron/libfunction/update_register_all_functions`
12 FILES_EXTRAS="`ls evolvotron/extras/{README,spheremap.pov,spheremap.sh}` `ls evolvotron/rpm/{README,evolvotron.spec}`"
1313
1414 FILES_H=`find evolvotron ${PRUNE} -o -name '*.h' -print`
1515 FILES_CPP=`find evolvotron ${PRUNE} -o -name '*.cpp' -print`
2323 echo "***"
2424 echo "*** Suggestion: mv evolvotron.tar.gz evolvotron-$VERSION.tar.gz"
2525 echo "***"
26
27
0 This directory contains contributed RPM packaging related resources.
1
2 -----
3
4 evolvotron.spec
5 - Karl Robillard's .spec file to build RPM packages on Mandriva, Fedora and Suse.
6
7 -----
8 See
9 http://www.bottlenose.demon.co.uk/share/evolvotron/download.htm
10 for up-to-date news re downloadable packages.
0 Summary: Evolvotron Interactive Art Generator
1 Name: evolvotron
2 Version: 0.5.1
3 Release: 1
4 License: GPL
5 URL: http://sourceforge.net/projects/evolvotron
6 Packager: <wickedsmoke@users.sf.net>
7 Group: Applications/Graphics
8 Source: %{name}-%{version}.tar.gz
9 BuildRoot: %{_tmppath}/%{name}-%{version}-build
10 %if 0%{?fedora_version}
11 BuildRequires: gcc-c++ boost-devel python qt-devel
12 %else
13 BuildRequires: gcc-c++ boost-devel python qt3-devel
14 %endif
15
16 %description
17 Evolvotron is interactive "generative art" software to evolve images/textures/patterns through an iterative process of random mutation and user-selection driven evolution.
18
19 %prep
20 %setup -q -n %{name}
21
22 %build
23 %if 0%{?fedora_version}
24 source /etc/profile.d/qt.sh
25 %endif
26 %if 0%{?mandriva_version}
27 export QTDIR=%{_prefix}/lib/qt3
28 export PATH=$QTDIR/bin:$PATH
29 %endif
30 %if 0%{?suse_version}
31 export QTDIR=/usr/%{_lib}/qt3
32 export PATH=$QTDIR/bin:$PATH
33 %endif
34 ./configure
35 make
36
37 %install
38 # make install
39 mkdir -p $RPM_BUILD_ROOT/usr/bin
40 install -s -m 755 evolvotron/evolvotron $RPM_BUILD_ROOT/usr/bin
41
42 %clean
43 rm -rf $RPM_BUILD_ROOT
44
45 %files
46 %defattr(-,root,root)
47 /usr/bin/evolvotron
48 %doc README USAGE CHANGES
49
50 %changelog
51 * Fri Mar 28 2008 Karl Robillard <wickedsmoke@users.sf.net>
52 - Initial package release.