INTRODUCTION ============ Evolvotron is interactive "generative art" software to evolve images/textures/patterns through an iterative process of random mutation and user-selection driven evolution. If you like lava-lamps, and still think the Mandelbrot set is cool, this could be the software for you. It uses C++ (and STL) & Qt, and is multithreaded (using Qt's threading API). Home page: http://www.bottlenose.demon.co.uk/share/evolvotron Author: timday at timday dot com If you manage to make practical use of evolvotron, especially if evolvotron derived imagery makes it into print or other mass media, I'd love to hear about it: please email! Have fun Tim LICENSE ======= This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. [The license should be in the LICENSE file in the same directory as this README] BUILDING ======== There's no reason it shouldn't work on any platform with a correctly set up qmake. You do NOT need to be root until the (optional) final install stage. In the top level directory, you can either do the "traditional" ./configure make or just have both done for you by doing ./BUILD [Note that BUILD also adds $QTDIR/bin to the path while it runs the commands, and is probably the easiest way to build if your PATH doesn't include a directory containing qmake and you like it that way.] Make will recurse into and build the libevolvotron directory (which is 99% of the work) and some additional subdirectories with executables. Among other things, this will give you an "evolvotron" executable which you can run immediately with ./evolvotron/evolvotron and/or copy where you like (see INSTALL section). BUILD PROBLEMS ============== Short story: 1. Check you have your QTDIR environment variable defined correctly. 2. Check your PATH will find qmake (i.e do "which qmake") (adding $QTDIR/bin to your path will fix this on most distros; note that the BUILD script does this while it runs). Long story: Check you have your QTDIR environment defined, and possibly also your QMAKESPEC too. The former should point to your Qt installation. The latter will be something like "linux-g++" if needed; check the Qt docs for other architectures or perhaps look in your QT installation's mkspecs directory. (RedHat defines QTDIR for the normal user environment, and seems to work fine without explicitly setting QMAKESPEC. A Mandrake user reports having to set both.) The author develops on RedHat 8 (gcc 3.2, qt 3.0.5), RedHat 9 (gcc 3.2.2, qt 3.1.1) and sometimes also tests on on RedHat 7.3 (gcc 2.96, qt 3.0.5). (So the closer your system is to these, the less likely you are to have problems). Most build failures are simply because the necessary Qt build tools aren't in your path: which qmake which moc should both find something. RedHat makes things easy by putting these binaries in /usr/bin, but many distros leave them in $QTDIR/bin. You should either add this to your path or use the BUILD script (which sets it for the commands it runs). A Debian (3.0r1) user reports Debian's Qt package not including qmake. They eventually got hold of a version from somewhere (Trolltech?). Attempting a regular build they apparently encountered a header/library version incompatibility (old headers, new library) which was solved by hand editing the qmake-generated Makefile and adding "-I- -I. " in front of the other -I paths. If you have gcc/c++ problems: If you have to change anything, the chances are it should be changed in common.pro. Remember that any Makefiles are generated by qmake from .pro files and therefore hacking on Makefiles is a fruitless excercise. Some source releases have had problems with other versions of gcc than the ones I test on. A COMPLETE record of a failed build would be appreciated (including the initial display of the gcc version). If you can fix it, the patches would be even better! BUILD OPTIONS ============= A few things are available through the configure script. Usage: ./configure [p4|p3|xp] [fs] (Any command line arguments given to ./BUILD are passed through to configure, so you can do e.g "./BUILD fs p4"). If you rerun configure or build with a different option to the last time you almost certainly need to do a "make distclean" to clean up old code and Makefiles. FUNCTIONALITY ------------- Specify 'fs' on the ./configure commandline to enable fullscreen support (which is off by default). I don't know which version of Qt this appeared with, but it works on RH9 and fails to build on RH8. If you select fullscreen support but your version of Qt is too old, the build will fail. PERFORMANCE ----------- There are already some generally effective overrides for Qt's fairly conservative (at least on RedHat) compile options in the fracplanet.pro file (where QMAKE_CXXFLAGS_RELEASE is modified). If you change them, do a "make distclean" before you rebuild to make sure Makefiles are rebuilt. The easiest way to get some additional CPU-specific optimisations is to use the configuration option: ./configure <cpu> where <cpu> is p3,p4 or xp as appropriate e.g ./configure p4 and rebuild from clean (again, "make distclean" is a good idea). If you attempt to run the resulting executable on incompatible hardware, it will probably crash horribly. So you can judge for yourself whether this is worth bothering with here's the times for a 2.4GHz P4 to run a 2048x2048 evolvotron_render (gcc 3.2 compiled) on a benchmark image function: Qt defaults -march=i386 -mcpu=i686 -O2 30.6s With evolvotron's overrides (now applied by default): -O2 -> -O3: 28.6s add -fomit-frame-pointer 28.2s add -funroll-loops 26.8s add -ffast-math 26.5s With 'p4' configure option: arch/cpu -> -march=pentium4 -mfpmath=sse -msse2 23.6s With modification to common.pro: add -finline-limit=4000 19.4s (but that last one involves a 32m build time (!!!), cf ~2m for the others) [NB This was done a while ago; things have probably changed a bit, especially after some major changes to the function code around version 0.2.0] BUILDING ON OTHER PLATFORMS =========================== Linc Davis reports: "I built it on a Mac with Qt installed via Fink (if you know what that is.) All I had to do is add '$(QTDIR)/include/qt' to the include path and then run make." Paolo Greppi built it on OSX like this: - get qt for osx http://www.trolltech.com/download/qt/mac.html - configure qt with -thread to compile threading support (takes a lot of time) - remember to: sudo ln -sf /usr/local/qt/lib/libqt-mt.3.dylib /usr/lib - and add this to .tcshrc in your home directory: setenv QTDIR /usr/local/qt setenv PATH $QTDIR/bin:$PATH setenv DYLD_LIBRARY_PATH $QTDIR/lib - modify the Makefile in evolvotron adding -lqt-mt at the end of LIBS - cd libevolvotron mv mutatable_image_computer_farm.c mutatable_image_computer_farm.cpp mv mutatable_image_computer_task.c mutatable_image_computer_task.cpp - make ... while compiling, it keeps saying c++: unrecognized option `-pthread' (but this doesn't seem to matter) INSTALL ======= Doing make install will attempt to install the executable in the INSTALLPATH directory defined in common.pro. This is set to ~/bin by default (which will give you a "personal install" of evolvotron assuming you have such a directory in your PATH). If you change INSTALLPATH to /usr/local/bin then you'll need to "su" before the make install. NB If you change a ".pro" file, you'll need to ./configure again to make changes take effect. INSTALL PROBLEMS ================ Users of some distros (Mandrake?) report problems with the install code generated by qmake. If you'd rather just do it by hand, all you need to do is copy the executables ./evolvotron/evolvotron ./evolvotron_render/evolvotron_render ./evolvotron_mutate/evolvotron_mutate to wherever you like (e.g ~/bin, /usr/local/bin). There are no extra supporting files which need to be in special places. USAGE ===== For the default 2D image mode, you will need a fast machine or patience. For the optional animation mode, you will need both. (If you're desperate, a little more performance can be obtained by messing with the compile flags: see the BUILD OPTIONS section above). On starting the application, a grid of images is displayed. (Resize or maximise the application if you like, but the more pixels have to be calculated, the slower it will be.) Simply repeat the following until bored: - Click (singleclick) on an image you like to spawn the next generation of its mutant offspring. - Wait until variations on it are regenerated in sufficient detail that you can decide which one you like best again. IMPORTANT: Initially you should select images with some sort of variation. If you select a uniform image, you may get stuck in a degenerate zone with little to mutate and therefore little chance of escape to a more interesting area. You can always reset/restart from the "File" menu (the difference is that "reset" also resets the mutation parameters to their default values). Selecting one of the "warp" options from the contect menu (right-click on an image) can also help by introducing an additional opportunity for mutation on subsequent spawns. Note that various spirals, grids and tiles, although complex looking, are actually implemented by a single function node and may leave you stuck too. COMMAND LINE OPTIONS ==================== NB You cannot simply munge single character options into one big string (i.e "-FM" is not the same as "-F -M") and space IS required between options and numeric arguments (ie use "-t 4" not "-t4") USER OPTIONS ------------ -geometry <width>x<height> The usual Qt/X11 option to set on-screen size in pixels -g <cols> <rows> Sets number of image display cells (defaults to 6 by 5) -t <threads> Sets number of compute threads (defaults to 2) -F [NB Only available with fullscreen build option; ignored otherwise] Start in "fullscreen" mode (NB for Qt on X11 this means a screen-filling borderless/undecorated window is used; it's not simply maximising the window, and it's not the sort of framebuffer hijacking used by SDL games). The Qt documentation claims some window managers may not be entirely cooperative with this (in which case sorry, you're on your own). evolvotron actions which bring up dialog boxes (e.g save) seem to generally behave fairly sensibly but child windows (e.g from "Big") can show some "interesting" behaviour. Fullscreen mode can be toggled within the application using ctrl-f. The Esc key will also exit it. -M [NB Only available with fullscreen build option; ignored otherwise] Start with menu and status bar hidden. Nice with -F. Hiding can be toggled within the application using ctrl-m. The Esc key will also bring them back. ANIMATION OPTIONS ----------------- -f <frames> Number of frames in animations (defaults to 1 i.e no animation) -r <framerate> Rate at which frames are displayed (integer). (Defaults to 8). POWER-USER & DEBUG OPTIONS -------------------------- -v Verbose mode, writes various things to application stderr (mainly to assist debugging). Probably most useful for getting a list of supported function names for use with the -x/-X options. -x <functionname> Force a specific function type to be used at the top level of all function trees. The specifed function is still wrapped by spatial and colour warping functions which may disguise it considerably. A list of all the function names understood by evolvotron is output during app startup when the -v option is specified. Example: evolvotron -x FunctionSpiralLinear -X <functionname> Similar to -x except that the specified function is NOT wrapped by space/colour transforms. NB For functions without leaf nodes or parameters (e.g FunctionSphericalToCartesian) this doesn't leave any scope for variation or future mutation. Example: evolvotron -X FunctionKaleidoscope Note that you can also specify iterative & fractal function types as an argument to -x/-X, even when they are disabled (as they are by default) in the mutation parameters. MOUSE CONTROL ============= LEFT-CLICK ---------- A left-click on an image in the main window spawns the mutant offspring of that image to all the other (non-locked) displays in the grid. RIGHT-CLICK CONTEXT MENU ------------------------ Right clicking on an image gets you a few more options: - "Respawn" regenerates just the current image from whatever it was spawned from (and using recolour or warp, if that's what was used to produce it). The main use of this is to make your grid of images look nice for screendumps, by regenerating any which aren't up to scratch. NB May not work as expected after an "undo". - "Spawn" is the same as clicking an image. It generates mutated images to all unlocked images in the grid. - "Recolour" to produce different coloured variants of the selected image - "Warp"'s sub-options produce variants of the image which have been zoomed/rotated/panned. - "Lock" to prevent an image from being overwritten by spawns from other images (select again to toggle). - "Big" to produce a blow-up of the image in a single window. Submenu items select either a freely resizable window or a scrollable view of a fixed size image. If the application is running in fullscreen mode (NB this is NOT the same as "Maximised": see the -F command line option) then the "Big" image will also be fullscreen (the "Resizeable" mode is probably what you want in this case as the image will automatically be rendered at the correct resolution). - "Save image" to save the image in a file (.ppm or .png format). Note that this is most useful on a "Big" blown-up image: if you save a small grid image, the size you see on the screen is the size you get in the file. Note that the save won't be allowed until the full resolution image has been generated. - "Save function" to store the function to an XML file. - "Load function" to load a stored function from an XML file. NB if the file was saved from a different version numbered evolvotron, a warning message will be generated. Save/load of functions is an experimental feature and you should not count on future versions of evolvotron being able to load files saved from old versions, or producing the same image from a loaded function. Attempting to load functions from later versions into earlier versions is even less likely to succeed. MIDDLE MOUSE BUTTON ------------------- [NB This feature will probably only be of practical use to those with multi-GHz machines]. You can use the middle mouse button to drag-adjust individual images. This is useful for "final composition" type tweaks, e.g centering an image's most interesting feature, or just for satisfying your curiosity about what's off the edge of the image. It also works on "Big" images, although it's virtually unusable without a bit of practice on smaller, faster ones (just boldly make the adjustment you want, release the button... and wait). Changes made can be rolled-back on the main Edit->Undo menu item, one drag-action at a time. An unmodified middle-mouse drag pans the image around following the mouse motion. A SHIFT-middle drag zooms the image in and out with scaling proportional to the distance from the centre of the image. Beware of generating huge zooms by clicking too near the centre of the image. An ALT-SHIFT-middle drag is similar but anisotropic: the scaling may be different in X and Y. Warning: this technique is very sensitive and can be quite tricky to use! In particular, if you initially click near the centre axes of the image the zoom factor can be HUGE, so the best way to start using this is to click about halfway on a diagonal between the image centre and a corner and gently move in and out radially. Dragging from one side of the image to the other flips it over (the degenerate case of infinite zoom at the centre is handled cleanly I think). If it all goes horribly wrong, undo and try again. A CTRL-middle drag rotates the image about its centre. A CTRL-ALT-middle drag shears the image (the best way to see what this does is to click in the corner of an image and move the mouse horizontally or vertically). KEYBOARD CONTROL ================ MAIN WINDOW ----------- Ctrl-f [NB only available with fullscreen build option] toggles full-screen mode (on X11, Qt does this by asking the window manager for a screen-filling undecorated window, and the documentation contains some dire warnings about problems with broken window managers). See also "-F" command line option. Fullscreen mode propagates to "Big" image display windows. NB The application may completely disappear from the screen for a brief interval while switching mode. Ctrl-m [NB only available with fullscreen build option] toggles status and menu-bar hiding, which can be nice when in full-screen or window-maximised mode. See also "-M" command line option. Esc [NB only available with fullscreen build option] kills full-screen and/or menu-hiding, putting the application into its normal default state. Ctrl-r does a restart (for convenience when the menu bar is hidden, because this is such a common operation). Ctrl-z does an undo. "BIG IMAGE" WINDOWS ------------------- The image display windows created by selecting "Big" from a context menu also have a couple of keyboard operations: Ctrl-f [NB only available with fullscreen build option] toggles full-screen mode. When returning to normal mode, if the main app window was fullscreen then it will also drop back to normal mode. Esc [NB only available with fullscreen build option] completely closes a fullscreen-mode "big" window. GUI ELEMENTS ============ MAIN MENU BAR ------------- On the application's main menu-bar, the Edit menu lets you undo previous full-grid spawns and middle-button adjustments. There is a large but limited number of levels of undo; note that locking is overriden, and that locking/unlocking a display is not currently recorded in the undo history), and bring up a dialog to modify the mutation parameters (see "useful tips" and "advanced usage" below). STATUS BAR ---------- An area on the status bar shows how many "tasks" are outstanding. Each "task" is the recomputation of an image at some resolution. Tasks are prioritised by their number of pixels (small image =>higher priority). This is why, if the main grid is still recomputing, recalculationa of a "big" image will appear to freeze after it has reached a certain resolution, at least until other lower resolution tasks have completed. TIPS ==== - Don't start a session with any preconceived ideas about the kind of image you want to get out of it. You will be disappointed. - I get the best results when I click the image which most immediately catches my eye as they start appearing. If you stop to think about it too much then things seem to go downhill. - If you seem to be just getting the same old spirals and grids all the time, stop clicking on spirals and grids! (The same goes for random mush). - Don't get too hung up on using the warp and middle-mouse drag adjustments every iteration... use those tools for final polishing of your masterpiece. - You can quickly cycle through a lot of initial images (until you find one with real potential) by bashing on the menu accelerator keys Alt-f,Alt-r to repeatedly restart. (ctrl-r also does this now). ANIMATION ========= As of version 0.2.0 evolvotron contains some experimental support for generation of animations (although so far the results have been pretty disappointing IMHO, but it's still early days). NB THIS IS EVEN MORE COMPUTATIONALLY AND MEMORY INTENSIVE THAN THE CONVENTIONAL STATIC IMAGE MODE. Simply supply a -f <frames> command line option and evolvotron will generate animated sequences with the specified number of frames. These will be displayed at the frame rate specified by the optional -r <framerate> option (default 8). So "evolvotron -f 24" will generate 3 second long animations. Animations reverse direction at each end to avoid a sudden jump. If you save an animation, multiple files will be saved with .fnnnnnn (where nnnnnn is the zero-filled frame number) inserted in each filename before the filetype qualifier. This is a bit awkward, but is a consequence of Qt lacking support for saving movie format files, so I suggest you use the ImageMagick tools to convert to a more usable format (GIF or MNG) for now. For example, if you enter foo.ppm as the filename to save, files foo.f000000.ppm, foo.f000001.ppm... will be saved. You can convert these to a MNG (a multi-frame PNG) playing at approx. 8 frames per second with: convert -delay 12 foo.f??????.ppm foo.mng (I have had some problems with .mng format; try .gif instead if this is the case). ADVANCED USAGE ============== Evolvotron's idea of an image is a function which converts XYZ co-ordinates to an RGB colour (however we can only display a 2D plane for now so the input Z is fixed to zero, or varied with time when animating). The image functions are constructed from trees of function nodes. (In the mathematical expression 1+(2*x) the "+" and the "*" would be function nodes.) Evolvotron's functions tend to correspond to geometric or colour-space operations or anything else which can be applied to a 3D vector. By mutating the structure of the function tree (adding random branches, for example) and the values of the constant embedded within it, the image can be changed. The mutation parameters are under control from the dialog accessible via the Edit->Mutation Parameters... menu, and also from buttons on the status bar). There are two kinds of mutation: perturbations to the magnitude of constants, and structural mutations which rearrage the function tree of an image. Four types of structural mutations are currently implemented: replacement of a function branch by a new random stub (a "Glitch" mutation), a random shuffle of a node's arguments, the insertion of random nodes between a node and it's children and the substitution of a node with one of a different type (but with child nodes unaffected where possible). The probability (per function node) of these mutations is controlled from spinboxes on the dialog (expressed as chances-in-a-million), as is the size of perturbations to constants. It is useful to think of the constant perturbations as being a thermal effect (hence the "heat" and "cool" buttons), while structural alterations are more drastic and are caused by high energy gamma rays or something (hence "irradiate" and "shield" buttons to adjust the probability of structual mutations). So why would you want to change the mutation parameters from the initial defaults ? Basically, if you're getting too much variation in spawned images (this tends to happen after many generations of images, by which time the function trees have grown quite large and therefore are experiencing a lot of mutations) then cool and/or shield. If all the images look too similar, heat and/or irradiate. 2 types of function node are considered fundamental: constant nodes (which return a constant) and position nodes (which should really be called identity nodes) which return their position argument. There are two slider controls to affect things realted to these: - "proportion constant" controls the proportion of fundamental nodes which are constants. Changing this from its default value of 0.5 doesn't actually seem to have much effect. - "identity supression" causes all identity nodes to actually include a random transform; the main effect of this is that images are less commonly obviously centred on the origin or aligned with the axes. I think this is a good thing, so identity supression is at 1.0 by default. OTHER OPTIONS ============= On the mutation parameters dialog there are tick boxes to enable two classes of function which are disabled by default. These are "iterative" functions and "fractal" functions (Mandelbrot and Julia set type things). The main reason for their being optional is that, in the former case they're expensive, and in the latter case they're expensive and ugly. Note that if fractal functions are enabled, then iterative functions are enabled too. OTHER EXECUTABLES ================= This release also builds two other executables: - evolvotron_render Usage: evolvotron_render [-v] [-s <width> <height>] [-f <frames>] [<file.ppm>|<file.png>] < <file.xml> Reads a XML function description from it's standard input and renders it to the file specified (suffix determines type, defaults to ppm if not recognised) at the specified resolution. Image size is specified by -s option and defaults to 512x512. The -f option generates multi-frame animations. .fnnnnnn is inserted/appended to the specified filename in the same way as animations saved from evolvotron. (You can use this on functions which weren't evolved in animation mode, but there's no guarantee they have any interesting time/z variation). Use the -v option to monitor the progress of a long animation run. [NB This app does not use multiple compute threads]. - evolvotron_mutate Usage: evolvotron_mutate [-g | < <file.xml>] > <file.xml> With the -g (generate, genesis?) option, creates a new random evolvotron function and writes its XML description to standard out. Without the -g option, reads an XML function description from standard input, mutates it (using the same algorithm and parameters as evolvotron in its default state) and writes the new function's XML representation to the standard output. Examples: Evolving and mutating on the command line: evolvotron_mutate -g | tee fn.xml | evolvotron_render /tmp/xxx.ppm ; display /tmp/xxx.ppm cat fn.xml | evolvotron_mutate | evolvotron_render /tmp/xxx.ppm ; display /tmp/xxx.ppm Animating a function ani.xml produced from evolvotron in animation mode: cat ani.xml | evolvotron_render -f 100 -v -s 256 256 ani.ppm ; animate ani.f??????.ppm FUTURE DEVELOPMENTS =================== Check the TODO file first before you send me suggestions! Please don't ask me to port evolvotron to proprietary platforms. You are of course Free under the terms of the GPL to do so yourself, but please reed http://www.fefe.de/nowindows/ first. BUILDING CODE DOCUMENTATION =========================== If you have doxygen (and graphviz too) and want to build the source code documentation, execute ./mkdoc at the top level. The code documentation then appears in ./doc/html/ THANKS ====== ...to Dmitry Kirsanov Jonathan Melhuish Karl Robillard Linc Davis Paolo Greppi Marcin Wojtczuk for feedback, suggestions and patches. ...to the participants in a SIGGRAPH conference panel many years ago who first got me interested in this kind of thing. ...to www.di.fm, www.somafm.com and Trance4Ever for music to code to. WHY ? ===== I have always admired those who have the skill to wield a pen or paintbrush and fill a sheet of paper or a canvas with some striking image from their imagination. Unfortunately I lack the patience to learn such skills, and probably the necessary manual dexterity and imagination too. Evolvotron, and its predecessors developed on and off over a decade since I first came across the idea, are an attempt to compensate for this using the skills I do have i.e some mathematical sensibility and the ability to write working code (well, sometimes). If you like an image it produces, then as far as I'm concerned that's as satisfying a result as if you liked something I'd drawn myself. Tim