evolvotron/BUGS 0000644 0001751 0001751 00000005301 13202652325 013317 0 ustar timday timday Known bugs:
- Enlargements seem to need silly amount of memory. Where's it all going ?
- Middle mouse drags sometimes don't seem to have any effect other than
triggering redisplay. Thought to be fixed by MutatableImage serial numbers
(was using pointer value as substitute for object identity before).
- Build dependencies don't seem to be very good; crashes and bad linkage
can sometimes be cleared by touching files or rebuild from clean.
(precompiled headers something to do with this?)
We're at the mercy of qmake here really.
- Simplifying functions sometimes changes their appearance
(implies "is_constant" probably buggy for some functions).
Some random testing of functions before and after simplify would help.
- When using -spheremap mode, middle mouse-button adjustments don't work
as expected (this is because they're not compensated for the projection).
Live with it.
- Gradient type operators produce a real mess when applied to
noise functions. High frequencies in the noise produce big derivatives.
Enlarging up to 4096x4096 sometimes looks a bit more sensible.
- Have yet to find a tool which can display anything other than the
first frame of a Qt-generated MNG format. (Apparently Qt's MNG
actually has nothing to do with the multi-frame PNG format).
- Very rarely image calculations appear to arrive seriously out-of-order.
May be a more of a problem on slower hardware ?
If this is causing trouble, try using "-t 1" command-line option to fix it.
- Example of "interesting" fullscreen bahaviour (Metacity on RedHat9):
Run app fullscreen.
Fire off a fullscreen "Big" display.
Open the properties dialog for the "big" window.
This results in metacity showing the task bar.
Use the task bar to select the main app window into the foreground.
Watch both fullscreen windows battle for supremacy!
This sort of thing is unlikely to be fixed.
- Resizing the evolvotron window queues up crazy numbers of tasks.
This didn't matter too much in 2D mode, but with animations the
memory reserved for each task's render target is considerably larger.
- Undo doesn't always work how you'd expect.
e.g respawn after undo doesn't respawn from what you'd expect.
Undo of a reset or restart doesn't put the mutation parameters & function weightings back how they were.
- Moire patterns & undersampling mean small images can show structures
not actually present in larger resolution versions.
- Once image colours become saturated there's not much which will cause
them to scale back down to sensible ranges, unless you're lucky.
- Recolour behaves strangely sometimes (?)
(e.g spawns all-black images or subtly warped images)
Not seen recently; may be fixed.
evolvotron/BUILD.sh 0000755 0001751 0001751 00000000614 13202652325 014034 0 ustar timday timday #!/bin/sh
echo "***"
echo "*** This script assumes Debian's Qt setup with a qtchooser supporting the -qt=5 option."
echo "*** On Debian Squeeze, change to use -qt=4 instead."
echo "*** Other Qt setups may require removing the -qt=5 option from qmake and setting QTDIR and PATH as usual."
echo "***"
VERSION_NUMBER=`./VERSION`
qmake -qt=5 "VERSION_NUMBER=$VERSION_NUMBER" main.pro && make -j 4
evolvotron/LICENSE 0000644 0001751 0001751 00000043131 13202652325 013644 0 ustar timday timday GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This 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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
evolvotron/NEWS 0000644 0001751 0001751 00000026752 13202652325 013350 0 ustar timday timday [Most recent at top]
Release 0.7.1:
- Uses `CONFIG += ordered` in `main.pro`; enables parallelised make.
Release 0.7.0:
- Got to compile vs Qt5.9.1 on Debian Stretch & Jessie; preparing for Qt5-only on Buster.
- Get rid of precompiled header use (more trouble than it's worth these days).
- Upgrade std::auto_ptr use to std::unique_ptr - cleans up compiler's deprecated warning spew.
From release 0.6.3:
- Version to 0.6.4
From release 0.6.2:
- Version to 0.6.3
- Files derived from USAGE (evolvotron.html and usage_text.h) are now under
svn control and no longer need to be generated as part of the build of a
fresh checkout.
- Migrated to new SourceForge platform.
Needed: svn switch --relocate https://evolvotron.svn.sourceforge.net/svnroot/evolvotron "svn+ssh://timday@svn.code.sf.net/p/evolvotron/code/"
From release 0.6.1:
- Version to 0.6.2
- CHANGES renamed to NEWS
- License boilerplate managed using "headache"
- Add some "tartan" inspired functions.
- Add pixel/voxel/hex grid quantizing functions.
- Port command line options to boost::program_options,
rationalize commandline options.
- Fix to evolvotron_mutate from Pedro Gimeno.
- Update mkdeb script to work on squeeze
- Functions to be loaded on startup can be specified on the commandline.
- Add option to shuffle startup functions.
From release 0.6.0:
- Version to 0.6.1
- Fix bug in saved functions: quotes missing around version attribute
From release 0.5.1:
- Version to 0.6.0
- Switch to Qt4.
- (Qt4 related) keyboard shortcuts rationalized
many removed, ctrl-modifiers dropped
- (Qt4 related) image displays now have a frame around them
- (Qt4 related) Remove non-standard Qt animated PNG support
- evolvotron_match removed
- Platform specific code (e.g number of processors identification)
isolated in libevolvotron/platform_specific.[h|cpp]
and selected by PLATFORM_LINUX or PLATFORM_BSD
(Fink Qt's __DARWIN_X11__ also detected and used to select PLATFORM_BSD).
- Repository migrated to svn
From release 0.5.0:
- Version to 0.5.1
- Replace not often used frontside heating/cooling buttons with autocooling mechanism.
- Separate tabs for info & license on "About" dialog.
- Better formatting of function properties dialog, and also shows XML function tree.
- Dialog with rendering controls
- Multisampling (antialiasing) options
- -a/-j/-s command line options for autocool/jitter/multisample
- evolvotron_render adds -j/-s to control jitter & multisampling
- Option (-E) of separate thread pool (with different nices: -n/-N) for enlargements.
Task totals for each reported separately.
- Enlargement and solo renderings are fragmented into multiple smaller
jobs to better utilize multiprocessor systems.
- Generally better use of ref-counted QImage and QPixmap.
- Middle-mouse drag adjustments flicker less.
From release 0.4.0:
- Version to 0.5.0
- Lists of functions in alphabetic order.
- New FunctionTop always at top level.
- New functions: Frieze groups.
- Constantness of functions more conservative (less overrides) and hopefully less buggy.
- Final colour space transform range more constrained to keep colours sane.
- More sensible mutation of top level spatial transform (less arbitrary shearing).
- Note that above changes mean old saved functions will appear different.
- New mutation parameter: probability of a function's parameters being reset.
- Code clean up:
- More std::auto_ptr, boost::shared_ptr, boost::ptr_vector. Code is now delete free.
- Get rid of hacked static function registration; uses auto-generated register_all_functions.
- Compute threads use QWaitCondition, not polling.
- Default number of threads is number of processors.
- Compute threads run at lower priority.
- -n command line option to control compute thread priority.
(NB assumes Linux NPTL's non-Posix compliant behaviour of threads NOT sharing a common nice value;
see "man pthreads" on Linux.)
- About dialog displays number of threads.
- Use precompiled headers (build time 2m45s down to 1m45s).
- code_review script
- Set an icon on various dialogs and main frame.
- Add -D (function debug) massively weighting in favour of FunctionNoiseOneChannel. Useful with -x/-X.
- Believed to fix Debian bug #436231 and gentoo #144160
- MutatableImage has serial number (fix problems caused by pointer value being wrongly used as equivalent)
From release 0.3.1:
- Version to 0.4.0
- Lock state moved to mutatable image so is stored in undo history
- Mandelbrot & Julia set only in x,y plane. Julia set uses fixed parameters.
- Add Juliabrot.
- Fix "Randomize" button on "All" functions tab.
- "Favourite" function dialog provides access to -x/-X command-line functionality
- Undo after reset works better
- Fix broken FunctionGradient.
Replace with GradientOfMagnitude, DivergenceOfMagnitude, Divergence, Curl
- Migrate float->double via typedef real
- Always builds with fullscreen option.
From release 0.3.0:
- Version to 0.3.1
- Fix for gcc 3.4
- ./configure made (slightly) more robust
From release 0.2.3:
- Version to 0.3.0
- Get rid of troublesome system call to ../VERSION
in common.pro and pass settings from configure script instead
- Add not-very-useful .qt-mng image file output format
- Add function stats to Properties dialog
- Add function simplification (more useful for debugging than anything)
- Don't use True and False in doc-building python script
(seems to be quite new thing, not in 2.1.x ?). Use 0 and 1 instead.
- Internal changes
- Add pkg/debian .deb builder script (still under development)
- Fix buggy Y rotation matrix
- Eliminate template-tastic Tuple and Matrix classes.
Fix XYZ and Transform to not require them.
- evolvotron_mutate - -g option more likely to generate insteresting functions
- -linz and -spheremap options where appropriate
- evolvotron_match utility.
- New dialog for function weightings (not fully implemented)
From release 0.2.2:
- Version to 0.2.3
- Break out USAGE file from README
- Add text_to_markup.py script to prettify USAGE file, used from configure
- Add quick reference and user manual accessible from help menu
From release 0.2.1:
- Version to 0.2.2
- CPU type an option to ./configure (p3,p4,xp supported)
- Build option for fullscreen & menu-hiding modes (from keyboard or command-line)
- Fullscreen mode for "Big" image displays
- Change default grid to 6x5 (would sooner have fat than thin images)
From release 0.2.0:
- Bump version to 0.2.1
- Display (not compute) priority to higher resolution images
(saves time enlarging low res images unnecessarily)
- Blank images on replacement (above change makes this more necessary)
- Round-robin dispatch of done tasks to displays means redisplay more balanced.
- -x and -X command line options to specify specifc top level function types.
- FunctionKaleidoscope*, FunctionWindmill*, FunctionSeparateZ added.
- More iterative functions also added: FunctionStreak Function*Ring
- Added -f option to evolvotron_render
- Internals: function framework changed (avoids FunctionNodeUsing::evaluate wrapper), speed improvement ?
- Internals: Type of top-level node can mutate, MutatableImage more sane.
- "Undo" keyboard accelerator works
- Per-image display "Properties" dialog added (placeholder)
From release 0.1.4:
- Bump version to 0.2.0
- Filenames converted to/from QString using Qt's "local8Bit" codec.
- -f option specifies number of frames (default 1, which is the non-animated behaviour of previous versions)
- -r option specifies framerate of full-resolution animation (default 8, about the minimum to look smooth)
- Animations save to multiple files
From release 0.1.3:
- Bump version to 0.1.4
- Function tree growth rate restored to pre-0.1.2 rates
- Both multiscale noise types counted as iterative as originally intended.
- "Substitute" mutation type added.
From release 0.1.2:
- Bump version to 0.1.3
- Build lib and separate executables. Use qmake "subdirs" at top level, move code into subdirs.
- Add evolvotron_render executable.
- Add evolvotron_mutate executable.
- Better Args class.
- Fix bug in FunctionAverageSamples
- Add noise class
- Add more functions.
- Use better random number generator (MT)
- Changes to initial setup probabilities, add chance of identity nodes front and back
From release 0.1.1:
- Bump version to 0.1.2. This is purely a bug-fix release.
- Gentoo compile bug fix (Karl Robillard)
- Disable implicit QString conversion (use explicit latin1() method).
- Workround "C++ static initializer fiasco" by moving problem static members
into instance-get methods.
From release 0.1.0:
- Bump version to 0.1.1
- Grid size now defaults to 7x5
- More functions!
From release 0.0.5:
- Bump version to 0.1.0
- Fix nasty bug in computers where a task could be delivered and deleted while
the compute thread was still setting state in it
(timing related so it never happened with ccmalloc and valgrind).
- Massive internal changes necessary for file save/load
(also makes adding functions easier)
- Save/load individual functions to XML
- configure checks QTDIR defined (biggest cause of build problems)
From release 0.0.4
- Bump version to 0.0.5
- configure script #!/bin/* changed to sh from csh
- Release tar files now unpack to a ./evolvotron directory
- More "Big" size options
- Big image can create big images
- Big image's initial window size decided by Qt
- Spawn warped offers more specific controls (zoom/pan/rotate)
- Middle mouse button does stuff (pan/zoom/rotate/shear)
- Undo menu entry describes type of action which will be undone
- Closing a big image cleans up undo history appropriately
- Bug with assumed EvolotronMain/MutableImageDisplay destructor order fixed.
From release 0.0.3:
- Bump version to 0.0.4
- More interesting start up functions
- More functions (e.g rotation and spirals, geometric inverse, iterated fns, fractals...)
- Controls to enable/disable expensive/ugly iterative and fractal functions (default off).
- Fix dumb bug in xy range of image
(makes everything generally behave a lot better; most noticeable with warp)
- "Identity supression" control which helps eliminate/reduces obvious origin centering.
- "Proportion constant" control (doesn't seem to have that much effect).
- Separate reset/restart functionality (reset also resets mutation parameters).
- Move Cool/Shield buttons to be adjacent (commonly used together).
- "is_constant" query method used to eliminate boring constant images.
- x&y co-ordinate alignment fixed (not something users would notice)
- Spawn warped made less messy: just generates translate/scale/rotate... no shearing.
- Reset clears locks / restart doesn't
- Gratuitously templatized tuple/matrix class added to help geometric transforms.
- Add "configure" script 'cos thats how lots of other apps do it. Apparently.
From release 0.0.2:
- Bump version to 0.0.3
- Add command line arg control of grid size and threads, don't override -geometry
- GUI control of mutation parameters
- "Respawn" regenerates a single display area using spawn/recolour/warp as appropriate.
- "Cancel" in file save dialog obeyed.
- "Insert" mutation type.
- "Undo" functionality.
From release 0.0.1:
- Bump version to 0.0.2
- Switch to QMainWindow base in anticipation of toolbar.
- Save as PPM or PNG
- Scrollable fixed-size image "Big" windows.
- Improvements to app response under load.
From release 0.0.0:
- Bump version to 0.0.1
- Add volatile to inter-thread communication flags
- Added a few more image node function types
- Add "spawn_recoloured"
- Add "spawn_warped"
evolvotron/README 0000644 0001751 0001751 00000013743 13202652325 013525 0 ustar timday timday 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+Boost) & Qt (which is Qt Group's GUI
toolkit; it's ABSOLUTELY NOTHING TO DO WITH APPLE'S QUICKTIME!).
It's multithreaded (using Qt's threading API).
Home page: http://www.bottlenose.net/share/evolvotron
Author: timday at timday dot com
This file describes how to build evolvotron.
See the USAGE file for details of what the built executable can do.
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 (there is no install stage).
In the top level directory, you can either do
qmake "VERSION_NUMBER=x.x.x" main.pro
make
or just have both done for you by doing
./BUILD.sh
which will pick up the VERSION_NUMBER from the file VERSION in this directory.
Make will recurse into and build the libfunction & libevolvotron directories
(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 (there are no shared libs or "resource files"
needing additional attention).
See the USAGE file (or in-app manual) for instructions.
The author mainly tracks Debian stable.
Non-linux platform issues
-------------------------
On the whole, Qt does an excellent job of insulating code from
platform specific details. However, there is a little bit of
linux-specific code in evolvotron.
If you don't have a PLATFORM_... define set, you'll get some warnings
about no default implementations of functions in platform_specific.cpp,
but should still get a working evolvotron (although missing some functionality
with regard to automatically choosing how many threads to run and controlling
thread priority).
All the platform specific code should live in
libevolvtron/platform_specific.cpp
and is selected by compile options
-DPLATFORM_LINUX or -DPLATFORM_BSD
(with more potentially addable for other platforms).
Setting the appropriate build options is most easily set by editing
an appropriate
DEFINES+=PLATFORM_LINUX
or
DEFINES+=PLATFORM_BSD
near the top of the
common.pro
file. Qt doesn't make a fine enough distinction between unix platforms
to decide completely automatically, and the situation is further complicated
by e.g Fink's Qt not considering itself to be a Qt 'macx' build.
Debugging builds
----------------
Many build failures are simply because the necessary Qt build tools
aren't in your path:
which qmake
which moc
should both find something.
If you have gcc/c++ compile problems problems:
If you have to change anything, the chances are it should be changed in
common.pro. Remember that any Makefiles you can see are generated
by qmake from .pro files and therefore hacking on the Makefiles is
generally a fruitless exercise.
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, then patches would be even better!
INSTALL
=======
The evolvotron sources don't try to provide an installer.
The assumption is that packagers will have a better idea of where
files should be copied to on their systems, and the tools to do it.
Doing
make install
will recursively descend into the various build directories, but
does nothing in each one.
The things you're likely to want to install are
(in order of interest):
The main executable and man page:
./evolvotron/evolvotron
./man/man1/evolvotron.1
User documentation (standalone version of the builtin manual):
USAGE
An HTML version of the above:
./evolvotron.html
Command-line driven tools and their man pages:
./evolvotron_render/evolvotron_render
./man/man1/evolvotron_render.1
./evolvotron_mutate/evolvotron_mutate
./man/man1/evolvotron_mutate.1
There are NO extra supporting files built
(e.g shared libraries, config files, "resource" files)
which need to be in special places for the software to work.
PACKAGING
=========
There are a few things which might be useful to packagers:
mkdeb
- script to build .deb files (using the strangely unpopular
"yada", and pbuilder). This is used to build the .debs put
up on sourceforge, but the "official" Debian ones (and Ubuntu
derivatives) are more conventionally packaged by Gurkan Sengun.
Yada is obsoleted as of Debian's "Wheezy" release however.
rpm/
- directory for contributed RPM related resources.
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/
This hasn't been tested in a long while now, although the
doxygen commenting style has been kept up.
evolvotron/TODO 0000644 0001751 0001751 00000035475 13202652325 013343 0 ustar timday timday Proximity to one end or the other of this list does not necessarily
imply it will be done sooner or later than other items!
Infrastructure
--------------
- Update mkdeb as per fracplanet's debhelper experiment
Conventional Mode
----------------
- Commandline option/control for grid spacing.
- Migrate to a stock threading/thread pool/futures lib.
- Just make "fullscreen mode support" be the default (and remove text in USAGE).
- Link on webpage to gallery http://gigrafx.110mb.com/evolvotron/index.html
- ...also flickr stuff (xargs?)
- Mouse manipulations: frame rate should be clamped to allow some time to produce a nice image
- At least split out evolvotron_main_history.cpp, even if the class remains nested in .h
- Smaller fragments for big enlargements; seeing unused processors.
- More feedback on when enlargements are ready for saving (have split tasks count now... need more ? yes)
- Triangles quantization mode (c.f hexes, pixels and voxels)
- Linear and cubic interpolation for pixel and voxel mode quantizer
- Enlargement menu: submenus for square, 4:3, 8:5, 16:9. 16x10. 5:4 SXGA 1024x1024 is a bit of an oddball.
And name them, see http://en.wikipedia.org/wiki/Computer_display_standard
- Friezegroups:
Cut taken out for 0.5.0 release.
Want cut and blend for those that support it.
Blend should use two functions in some cases.
Can't see how to blend cuts; needs something more like old warp approach.
- Work out how to add warping/blending to the (frieze) symmetry groups so they dont look so "cut".
Hop - Basic, Blend and Cut done. Cut needs attn to fit in with spinhop.
Jump - Basic, Blend and Cut done. (Is just Hop with y=0 reflection). Cut needs attn to fit in with spinhop.
Sidle - Basic. Can't be blended or cut as there are only reflection lines. (Could be blended, but doesn't hide much).
Spinjump - Basic. No blend or cut as there are only reflection lines. (Is just Sidle with y=0 reflection). (Again, could blend but not much point).
Spinhop - Basic. Blend done. Cut done.
Spinsidle - todo
Step - todo
- Not entirely convinced by separate thread pool for enlargements.
On the other hand, do need some mechanism to progress enlargements
while working on main grid.
- Add functions for the 17 "wallpaper" symmetry groups.
ref: http://www.scienceu.com/geometry/articles/tiling/wallpaper.html
Wikipedia http://en.wikipedia.org/wiki/Wallpaper_group is good.
Presumably there are 3D versions too.
See also http://www.mi.sanu.ac.yu/vismath/ana/ana5.htm
- The function properties dialog could construct a QListView instead of just displaying the XML.
But then you'd want full editing capabilities too (and why not?)
- When mutating parameters, have a chance of a "special" reset to "interesting" values, and maybe even patterns of values.
- Debian transitioning Apps to Applications (post Etch) see bug #361418
- GPLv3 ? Don't understand what else needs to be (e.g Qt3 etc)
- Maybe icon setting could do with some more attention; probably there are more things which should set it
(e.g respawn coloured) and loading could set a flag defering icon setting until that view is ready.
- MutatableImageComputer::push_todo could handle defer a bit better.
Actually, complete overhaul of queue/computer kill/defer/abort would be better.
Computers should check priority on head of queue periodically and switch if there's
something better to work on.
- Move InstanceCounted out of useful.h (and #include
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 more interesting
images. 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 a context 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
The following are equivalent:
- evolvotron --grid 12x8
- evolvotron --grid=12x8
- evolvotron -g 12x8
General Options
- -a, --autocool
Enable autocooling by default, and cause resets of mutation
parameters to re-enable autocooling if it was disabled.
- -F, --fullscreen
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 enlargements or dialogs) can show some "interesting" behaviour.
Fullscreen mode can be toggled within the application using "F" key.
The "Esc" key will also exit it.
- -g, --grid colsxrows
Sets size of the grid of image display cells in the main application area (defaults to 5x6)
- -h, --help
Print summary of command line options and exit.
- -j, --jitter
Enable sample jittering. Samples will be made at a random position
within a pixel instead of on a regular grid, providing some antialiasing.
- -m, --multisample multisample grid
Enables additional antialiasing passes.
Specifying 2 or 3 will provide an additional pass with 2x2 or 3x3 samples per pixel.
Specifying 4 (or higher) will provide a 2x2 and a final 4x4 pass.
Specifying 1 provides the default behaviour of one sample per pixel.
For best rendering quality also specify -j.
- -M, --menuhide
Start with menu and status bar hidden. Nice with --fullscreen.
Hiding can be toggled within the application using ctrl-m.
The Esc key will also bring them back.
- -p, --spheremap
Images are produced by sampling the underlying 3D function on the
latitude-longitude grid of a sphere. The resulting images should be
usable as spheremaps/spherical environment maps. Animations vary
the radius of the sphere. NB when in spheremap mode,
middle mouse button adjustments do not yet behave like you'd expect.
- -S, --startup function_filename
Specify a function filename (evolvotron's XML format) to load on startup
(or reset). The option can be provided multiple times, and this is
also the interpretation of any positional arguments. Startup functions
are placed in the grid from left to right, top to bottom.
- -U, --shuffle
Use in conjunction with -S / --startup options, to display the specified
functions in random order, both on application startup and on each
reset of the application.
Animation Options
- -f, --frames frames
Number of frames in animations (defaults to 1 i.e no animation)
- -l, --linear
Vary z linearly with time rather than sinusoidally.
Sinusoidal variation generally looks better when animations are "bounced"
forwards and backwards, but this option is useful when generating slices to
use as volumetric textures.
- -s, --fps framerate
Rate at which frames are displayed per second (integer). (Defaults to 8).
Power-user & Debug Options
Note that the usual Qt/X11 options
(for example, -geometry widthxheight option to set on-screen size in pixels)
are processed and removed before evolvotron options are checked.
- -D, --debug
Puts the certain aspects of the app into a more debug oriented mode.
Currently (ie this may change) it simply changes function weightings
so virtually all function nodes are FunctionNoiseOneChannel. By itself
this is a pretty pointless thing to do, but in conjunction with the -X
options it's useful for examining the behaviour of specific functions.
- -E, --enlargement-threadpool
Use a separate thread pool for computing enlargements.
Using this option ensures computation of enlargements
continue to make some progress even while the main grid
is being actively worked on. However, this will be at
the expense of main grid rendering performance.
Without this option, enlargements' final high-resolution
renderings are invariably lower priority than computation
for images in the main grid.
See also the -N option to control the priority of threads
in this pool.
- -n, --nice niceness
Sets additional niceness (relative to the main application thread)
of the compute (rendering) thread(s).
It's useful to run compute threads at a slightly lower priority
("nice 4" is the default without this option) than the main (GUI)
part of the program (but note that this means other normal/lowish
priority tasks running on your machine may slow evolvotron down
a bit more than expected).
- -N, --Nice enlargement niceness
Sets additional niceness (relative to the main application thread)
of the compute thread(s) computing enlargements (default value is 8).
Only effective in conjunction with -E option.
- -t, --threads threads
Sets number of compute threads.
If this is not specified, then as many compute threads are created
as there are processors on the system (unless this cannot be
discovered in which case only a single compute thread is created).
Non-linux builds will likely not include code to determine processor count
(suitable patches gratefully received).
- -u, --unwrapped
Modifies -F behaviour so that the specified "favourite" 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.
Function name recognition is case sensitive.
Example:
evolvotron -F FunctionKaleidoscope -u
- -v, --verbose
Verbose mode, writes various things to application stderr.
This is primarily intended to assist debugging.
This option used to be useful for getting a list of supported function
names for use with the -F option, but those can also be inspected
via the Settings dialogs.
- -x, --favourite functionname
Force a specific "favourite" function type to be used at the top level
of all function trees. The specified 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. Function name recognition is case sensitive.
Example:
evolvotron -F FunctionSpiralLinear
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).
- "Enlarge" 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 a simply "maximised" window) then the enlarged
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).
You generally want to save an enlarged image: if you
save a small image from the grid, the size you see on the screen
is the size you get in the file. Save isn't allowed until the
full resolution image has been generated; if you try to save too
early a dialog box will be displayed telling you to try again later.
- "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.
- "Simplify" prunes the function tree of redundant branches where
possible (the same action can be applied to all images from
the main "Edit" menu). This doesn't change the appearance of
the image, but may make it recompute faster.
- "Properties" brings up a dialog box containing some information
about the image (e.g the number of function nodes it contains).
Middle Mouse Button
[NB This feature will probably only be of practical use to those with high-end 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 enlarged 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
There are some keyboard shortcuts.
Main Window
- "r"/"t"/"x" perform various starts of reset/restart.
- "q" quits the application.
- "u" (and also Ctrl-z) does an undo.
- "f": 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 enlarged image display windows.
NB The application may completely disappear from the screen for
a brief interval while switching mode.
- "m" : hides status and menu-bar hiding, which can be nice when
in full-screen or window-maximised mode. See also "-M"
command line option. Also note that while the menu bar
is hidden, most of these keyboard shortcuts won't function
as they're tied to the menu system.
- Esc : exits full-screen and/or menu-hiding mode, putting the
application into its normal default state.
Enlargement Windows
The image display windows created by selecting "Enlarge" from a
context menu also have a couple of keyboard operations:
- "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 enlargement window.
Gui Elements
Main Menu Bar
- File menu:
Items to restart, reset and quit the application.
The difference between restart and reset is that reset
sets the mutation parameters back the their default values.
The "randomize function weights" version of restart scrambles
the relative probability of the various function types (if you
think evolvotron just keeps generating the same kinds of
images give it a try). The "restart with specific function"
item duplicates the functionality of the "-x" and "-X" command-line
options.
- Edit menu:
"Undo" lets you undo certain actions: e.g spawn,
middle-button adjustment, simplification and lock/unlock.
There is a large but limited number of levels of undo.
"Simplify" is of curiosity value only: it prunes redundant
branches from images ("junk DNA"); this may help them recompute
faster but at the cost of there being less mutatable material.
- Settings menu:
"Mutations" brings up a dialog to modify the amount
of change spawned images are subject to.
(See "advanced usage" below.)
"Functions" brings up a dialog to modify the relative probability
of functions being used. By default all functions are equally
likely except for iterative functions and fractals, which are
almost but not completely suppressed. But if you think there
are too many spirals or grids (or not enough fractals) then this
is the place to adjust the frequency with which they appear.
If the software was built with the fullscreen option,
that can also be controlled from this menu.
"Favourite" brings up a dialog which allows you to select a specific
function type to always be used as the root node of any new functions.
The function can be wrapped by some other random stuff, or unwrapped.
See also the -X and -x command line options.
- Help menu:
Items to bring up documentation, and the usual "About" box
(which includes the license).
Status Bar
An area on the status bar shows how many compute "tasks" are
outstanding (or "Ready" when there are none). When two task
totals are reported, the first is for the main grid and the
second for any enlargements being computed.
Each "task" is the recomputation of an image at some resolution.
Tasks are prioritised by their number of pixels (small image
implies higher priority). This is why, if the main grid is still
recomputing, recalculations of enlargements will appear to freeze
after they have reached a certain resolution, at least until other
lower resolution tasks have completed.
The status bar also provides some control over the "autocool"
mechanism which reduces mutation strength with time.
See the advanced usage section below.
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 Ctrl-r to
repeatedly restart.
- To add variety to an image's mutations, nudge it with a small
middle-mouse drag. This introduces a top level transform, and
therefore more parameters to be varied.
- Enlargements take a long time to complete their final
high-resolution rendering pass (especially with multisampling
enabled). Most convenient practice seems to be to go away and
leave them to complete, then come back and save them later.
Continuing to click away on the main grid effectively starves
them of CPU, unless the -E command-line option is used.
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 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 -s framerate option (default 8). So "evolvotron -s 24"
will generate 3 second long animations. Animations reverse direction
at each end to avoid a sudden jump.
If you save an animation as PPM or PNG, multiple files will
be saved with .fnnnnnn (where nnnnnn is the zero-filled frame
number) inserted in each filename before the filetype qualifier.
For example, if you enter foo.ppm as the filename to save,
files foo.f000000.ppm, foo.f000001.ppm... will be saved.
If you have the ImageMagick tools you can convert these to
an animated GIF playing at approx. 8 frames per second with:
convert -delay 12 foo.f??????.ppm foo.gif
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 dialogs accessible
via the Settings menu, and the "autocool" mechanism exposed in the
status bar also has some influence.
There are two kinds of mutation: perturbations to the magnitude of constants,
and structural mutations which re-arrange 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 sub-nodes
- insertion of random nodes between a node and it's sub-nodes
- the substitution of a node with one of a different type,
with sub-nodes unaffected where possible).
The probability (per function node) of these mutations is controlled
from spinboxes on the "Mutation Parameters" dialog (expressed as
chances-in-a-hundred), as is the size of perturbations to constants.
It is useful to think of the perturbations to constant parameters 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 structural 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.
The "autocool" mechanism (enabled from the statusbar or mutation parameters
dialog) automatically reduces the strength of mutations from the base
values with successive generations. The cooling can be cancelled by
disabling autocooling or pressing the "Reheat" button to zero the number
of generations counted for cooling. The effect of the cooling is a compound
halving of the mutation strength after some number of generations (this number
is the "half-life" controllable from the mutation parameters dialog).
Note that if autocooling is enabled then eventually, after a number of
iterations more than many multiples of the half-life has passes, spawned
images will differ very little from their parents (hence the need for "reheat").
There is also a dialog accessible from "Functions..." on the "Settings" menu.
This allows control over the relative proportions in which functions occur.
There is a tab showing the relative weighting of all functions (log-2 scale: each
tick halves the probability of the function occurring), and additional tabs
for various classifications of function for quicker access.
The "Randomize" button on each tab assigns random weightings and helps
increase the uniqueness of your session.
The "Functions" dialog also has a "Dilution" tab which allows the average
function-tree branching ratio to be controlled (by changing the proportion
of trivial zero-branch functions added): note that using a high branching
ratio results in very complex images which will take a long time to compute,
while reducing the ratio results in simple, boring images.
3 types of function node are considered fundamental: constant nodes
(which return a constant), identity nodes (which return their
position argument) and transform nodes (which transform their position
argument by random parameters). On the "Dilution" tab of the "Functions"
dialog there are two slider controls to affect things related to these:
- "proportion constant" controls the proportion of diluting fundamental nodes
which are constants. Changing this from its default value of 0.5 doesn't
actually seem to have much effect.
- "proportion transforms" sets the proportion of non-constant nodes diluting
which are transforms (as opposed to identity nodes).
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
the value is at 1.0 by default.
Other Executables
This release also builds some other command-line driven (non-GUI, non-interactive) utilities.
Consult the man pages for full details.
evolvotron_render reads a XML function description from its standard input and renders it to the
file specified.
evolvotron_mutate reads an XML function description from its standard input and outputs a mutated version.
A command line option allows the "genesis" situation of creating a random function description with no input.
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 -j -m 4 /tmp/xxx.ppm ; display /tmp/xxx.ppm
Animating a function ani.xml saved from evolvotron in animation mode:
cat ani.xml | evolvotron_render -f 100 -v -s 256 256 ani.ppm ; animate ani.f??????.ppm
Future Developments
Please 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 read
http://www.fefe.de/nowindows/
first.
Thanks
To those who have contributed feedback, suggestions and patches:
- Dmitry Kirsanov
- Jonathan Melhuish
- Karl Robillard
- Linc Davis
- Paolo Greppi
- Marcin Wojtczuk
- Michael Sterrett
- Massimiliano Guastafierro
- Goetz Waschk
- Forrest Walter
- "chr_bl" at web.de
And to the anonymous Linspire reviewer who perhaps came up with the best
summary of evolvotron yet: "Fascinating. Utterly pointless, but fascinating."
The friezegroups wouldn't have been possible without
http://michaelshepperd.tripod.com/resources/groups.html
Thanks to www.di.fm, www.somafm.com and Trance4Ever for music to code to.
Thanks especially to a SIGGRAPH conference panel many years ago (likely
including Karl Sims, the pioneer in this area) who first got me interested
in this stuff.
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 several 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 Day
evolvotron/libfunction/update_register_all_functions 0000755 0001751 0001751 00000001734 13202652325 023212 0 ustar timday timday #!/bin/bash
rm -f register_all_functions.cpp
cat <> register_all_functions.cpp
/* AUTO GENERATED FILE. DO NOT EDIT */
/* Should be updated by update_register_all_functions script when new functions are added */
#include "libfunction_precompiled.h"
#include "register_all_functions.h"
#include "function_boilerplate.h"
EOF
HEADERS=`grep -l FUNCTION_BEGIN *.h | sed 's/function_boilerplate.h//'`
for f in $HEADERS ; do
sed -f stripcomments.sed "$f" \
| grep FUNCTION_BEGIN \
| sed 's/FUNCTION_BEGIN(//' \
| sed 's/,.*//' \
| awk '{printf("REGISTER_DCL(%s);\n",$0);}' \
>> register_all_functions.cpp
done
cat <> register_all_functions.cpp
void register_all_functions(FunctionRegistry& r)
{
EOF
for f in $HEADERS ; do
sed -f stripcomments.sed "$f" \
| grep FUNCTION_BEGIN \
| sed 's/FUNCTION_BEGIN(//' \
| sed 's/,.*//' \
| awk '{printf(" register_%s(r);\n",$0);}' \
>> register_all_functions.cpp
done
cat <> register_all_functions.cpp
}
EOF
evolvotron/mkdeb 0000755 0001751 0001751 00000006773 13202652325 013662 0 ustar timday timday #!/bin/bash
# Before using this you probably need to install
# sudo pbuilder yada devscripts lintian cdebootstrap
# and maybe dpkg-sig. Also:
# set up for sudo
# set up pbuilder's /etc/pbuilderrc (maybe no attention needed these days)
# sudo pbuilder create --distribution squeeze
# and/or update with
# sudo pbuilder update
# Expect a lot of warnings re LOGNAME - see Debian bug Bug#275118
# TODO: DEBEMAIL
VER=`./VERSION`
TARBALL=evolvotron-${VER}.tar.gz
if [ ! -s ${TARBALL} ] ; then
echo "Could't find ${TARBALL}" ;
exit ;
fi
export DISTRIBUTION=`lsb_release -s -c`
echo "*** Will package ${TARBALL} for distribution \"${DISTRIBUTION}\""
echo -n "*** Starting in 5 seconds..."
for t in 5 4 3 2 1 ; do sleep 1 ; echo -n "." ; done
PROJECT=`echo $TARBALL | sed 's/-.*//'`
TARBALLORIG="${PROJECT}_${VER}.orig.tar.gz"
REV="1${DISTRIBUTION}1"
WORKDIR=pkg_${VER}-${REV}
rm -r -f ${WORKDIR}
mkdir ${WORKDIR}
cd ${WORKDIR}
cp ../${TARBALL} ${TARBALLORIG}
tar xvfz ${TARBALLORIG}
mv ${PROJECT} ${PROJECT}-${VER}
cd ${PROJECT}-${VER}
sed -i "s/${VER}/${VER}-${REV}/g" VERSION
mkdir debian
dch --create --package evolvotron --distribution stable --newversion ${VER}-${REV} "Created by mkdeb script"
cat << EOF > debian/packages
Source: evolvotron
Section: graphics
Priority: extra
Maintainer: Tim Day
Standards-Version: 3.6.1
Upstream-Source:
Home-Page:
Description: Interactive evolutionary texture generator
Copyright: GPL
Copyright 2009 Tim Day
Build-Depends: qt4-qmake,qt4-dev-tools,libqt4-dev,libqt4-xml,libboost-dev,libboost-program-options-dev,yada
Build: sh
export QTDIR=/usr/share/qt4
# Note: yada install deals with DEB_BUILD_OPTIONS 'nostrip'
if [ "${DEB_BUILD_OPTIONS#*noopt}" != "$DEB_BUILD_OPTIONS" ]; then
./configure "CONFIG -= release" "CONFIG += debug"
else
./configure # No noticeable advantage in overriding qt optimisation options
fi
make
Clean: sh
make distclean || make clean || true
Package: evolvotron
Architecture: any
Depends: []
Suggests: gimp
Description: Interactive evolutionary texture generator
A "generative art" application to evolve images/textures/patterns through an
iterative process of random mutation and user-selection driven evolution.
If you like lava lamps, and never got bored with the Mandelbrot Set,
this could be the software for you.
Install: sh
yada install -bin evolvotron/evolvotron
yada install -bin evolvotron_mutate/evolvotron_mutate
yada install -bin evolvotron_render/evolvotron_render
yada install -bin evolvotron/evolvotron
yada install -doc evolvotron.html
yada install -doc BUGS TODO NEWS USAGE
yada install -man man/man1/evolvotron.1
yada install -man man/man1/evolvotron_mutate.1
yada install -man man/man1/evolvotron_render.1
Menu: ?package(evolvotron): needs="X11" section="Applications/Graphics" title="Evolvotron" hints="Bitmap" command="/usr/bin/evolvotron" longtitle="Evolutionary art program"
EOF
yada rebuild
cd ..
dpkg-source -b ${PROJECT}-${VER} ${TARBALLORIG}
# Alternative but inferior approach is apparently to do
# dpkg-buildpackage -rfakeroot
mkdir result
echo "Building package"
sudo pbuilder build --allow-untrusted --buildresult ./result ${PROJECT}_${VER}-${REV}.dsc
sudo chown ${USER}:${USER} result/*
RESULT=`(cd .. ; find ${WORKDIR} -name '*.deb')`
echo "Results: ${RESULT}"
echo "Don't forget to lintian ${RESULT}"
echo 'Also dpkg-sig --sign builder -k $DPKGSIG_KEYID any .deb files'
evolvotron/mkdoc 0000755 0001751 0001751 00000000061 13202652325 013655 0 ustar timday timday #!/bin/sh -v
mkdir -p doc
doxygen doxygen.cfg
evolvotron/mktgz 0000755 0001751 0001751 00000002003 13202653036 013712 0 ustar timday timday #!/bin/bash
# Execute this to package up evolvotron as a .tar.gz
VERSION=`./VERSION`
DIR=${PWD##*/}
cd ..
# NB Don't ship contents of pkg
PRUNE='-name moc -prune -o -name obj -prune -o -name pkg_* -prune'
FILES_MISC=`ls ${DIR}/{README,BUILD.sh,LICENSE,TODO,NEWS,VERSION,USAGE,USAGE-update.sh,BUGS,doxygen.cfg,mktgz,mkdeb,mkdoc,text_to_markup.py,evolvotron.html} ${DIR}/libfunction/update_register_all_functions`
FILES_EXTRAS="`ls ${DIR}/extras/{README,spheremap.pov,spheremap.sh}` `ls ${DIR}/rpm/{README,evolvotron.spec}`"
FILES_H=`find ${DIR} ${PRUNE} -o -name '*.h' -print`
FILES_CPP=`find ${DIR} ${PRUNE} -o -name '*.cpp' -print`
FILES_PRO=`find ${DIR} ${PRUNE} -o -name '*.pro' -print`
FILES_MAN=`find ${DIR}/man ${PRUNE} -o -name '*.1' -print`
FILES="$FILES_MISC $FILES_EXTRAS $FILES_H $FILES_CPP $FILES_PRO $FILES_MAN"
tar --transform "s:^${DIR}/:evolvotron/:" -cz -f ${DIR}/evolvotron.tar.gz $FILES
echo "***"
echo "*** Suggestion: mv evolvotron.tar.gz evolvotron-$VERSION.tar.gz"
echo "***"
evolvotron/text_to_markup.py 0000755 0001751 0001751 00000014641 13202652325 016265 0 ustar timday timday #!/usr/bin/env python
# Convert Tim-style text to html or qml
#
# The Rules:
# - Lines with all upper case words to h2 or h3 capwords depending on next line underlining (first to h1/title though)
# (must be 3 chars or more)
# (todo: relax to not all upper case... no need to capwords if not)
# - Other text to p, blank lines break a p
# - Lines beginning with "- " (NB space) to ul/li (bulleted)
# - Lines beginning with "-?" (no space) to ul/li (?) with
at end of first line
# - Words delim to xxx
# "$ " at start of line indicates one line of code (add
too)
import sys
import string
import re
def line_of_dashes(n):
r=""
for i in xrange(n):
r+="-"
return r
def line_of_equals(n):
r=""
for i in xrange(n):
r+="="
return r
class TextToMarkup:
def __init__(self,m,s):
self.startup=1 # True
self.scope_p=0 # False
self.scope_ul=0 # False
self.scope_li=0 # False
self.done_title=0 # False
self.skipnextline=0 # False
self.mode=m
self.stringify=s
def dispose(self,l):
if self.stringify:
self.output.write("\"") # Actually, they should all have been "-ed anyway
for c in l:
if c=="\"":
self.output.write("\\\"")
else:
self.output.write(c)
self.output.write("\\n\"\n")
else:
self.output.write(l+"\n")
def process_word(self,w):
r=""
if len(w)<3: # Special case allows "<" or "<>" without turning italic
for i in xrange(len(w)):
if w[i]=="<":
r+="<"
elif w[i]==">":
r+=">"
else:
r+=w[i]
else:
for i in xrange(len(w)):
if w[i]=="<":
r+=""
elif w[i]==">":
r+=""
elif w[i]=='"':
r+="""
elif w[i]=="&":
r+="&"
else:
r+=w[i]
return r
def process_paragraph_text(self,txt):
is_code=0 # False
specialbreak=0 # False
r=" "
if txt[0]=="-":
if txt[1]==" ":
txt=txt[2:]
else:
specialbreak=1 # True
if self.scope_ul and self.scope_li:
r+=""
self.scope_li=0 # False
if not self.scope_ul:
r+=""
self.scope_ul=1 # True
if not self.scope_li:
r+="- "
self.scope_li=1 # True
elif txt[0]=="$":
is_code=1 # True
r+="
"
txt=txt[2:]
for w in txt.split():
r+=self.process_word(w)
r+=" "
if is_code:
r+="
"
if specialbreak:
r+="
"
return r
def process(self,in_stream,out_stream):
self.output=out_stream
self.input=in_stream
if self.mode=="html":
self.dispose("")
while 1: # True
if self.startup:
self.currline_raw=in_stream.readline()
self.nextline_raw=in_stream.readline()
self.startup=0 # False
else:
self.currline_raw=self.nextline_raw
self.nextline_raw=in_stream.readline()
if not self.currline_raw:
break
if self.skipnextline:
self.skipnextline=0 # False
continue
# Should track last line too
self.currline=self.currline_raw.strip()
self.nextline=self.nextline_raw.strip()
if len(self.currline)>2 and self.nextline==line_of_equals(len(self.currline)):
if self.done_title:
self.dispose(""+string.capwords(self.currline)+"
")
self.skipnextline=1 # True
continue
else:
if (self.mode=="html"):
self.dispose("")
self.dispose("")
self.dispose(""+string.capwords(self.currline)+"")
self.dispose("")
self.dispose("")
elif (self.mode=="qml"):
self.dispose("")
self.dispose(""+string.capwords(self.currline)+"
")
self.done_title=1 # True
self.skipnextline=1 # True
continue
elif len(self.currline)>2 and self.nextline==line_of_dashes(len(self.currline)):
self.dispose(""+string.capwords(self.currline)+"
")
self.skipnextline=1 # True
continue
elif self.scope_p:
if (len(self.currline)):
self.dispose(self.process_paragraph_text(self.currline))
else:
if self.scope_li:
self.dispose(" ")
self.scope_li=0 # False
if self.scope_ul:
self.dispose("
")
self.scope_ul=0 # False
self.dispose("
")
self.scope_p=0 # False
elif len(self.currline):
self.dispose("")
self.dispose(self.process_paragraph_text(self.currline))
self.scope_p=1 # True
else:
self.dispose("")
if self.mode=="html":
self.dispose("")
self.dispose("")
#########################################
if __name__=='__main__':
mode=None
stringify=0 # False
for i in xrange(1,len(sys.argv)):
if sys.argv[i]=="-qml":
mode="qml"
if sys.argv[i]=="-html":
mode="html"
elif sys.argv[i]=="-s":
stringify=1 # True
t2m=TextToMarkup(mode,stringify) # "html" and "qml" are alternatives. Should be stringify option.
t2m.process(sys.stdin,sys.stdout)
evolvotron/extras/README 0000644 0001751 0001751 00000000453 13202652325 015025 0 ustar timday timday
---
spheremap.sh is a script to animate a spheremap applied to a rotating sphere.
The scene description is in spheremap.pov.
It assumes the existence of a file called spheremap.png, which you
should create by saving an (enlarged, probably) image from evolvotron
running in -spheremap mode.
---
evolvotron/extras/spheremap.pov 0000644 0001751 0001751 00000000360 13202652325 016654 0 ustar timday timday #include "colors.inc"
camera {perspective location <0,1,-4.5> look_at <0,0,0> angle 45}
light_source {<100,100,-100> color White}
sphere
{
<0,0,0>,1 pigment { image_map {png "spheremap.png" map_type 1} }
rotate <0,clock*360,0.0>
}
evolvotron/extras/spheremap.sh 0000755 0001751 0001751 00000000232 13202652325 016463 0 ustar timday timday #!/bin/bash
# Disclaimer: I'm using povray version "3.5 Unix". Which is probably quite old now.
povray spheremap.pov +KFI1 +KFF100 +H240 +W320 +Of.png
evolvotron/rpm/README 0000644 0001751 0001751 00000000455 13202652325 014317 0 ustar timday timday This directory contains contributed RPM packaging related resources.
-----
evolvotron.spec
- Karl Robillard's .spec file to build RPM packages on Mandriva, Fedora and Suse.
-----
See
http://www.bottlenose.demon.co.uk/share/evolvotron/download.htm
for up-to-date news re downloadable packages.
evolvotron/rpm/evolvotron.spec 0000644 0001751 0001751 00000002347 13202652325 016532 0 ustar timday timday Summary: Evolvotron Interactive Art Generator
Name: evolvotron
Version: 0.5.1
Release: 1
License: GPL
URL: http://sourceforge.net/projects/evolvotron
Packager:
Group: Applications/Graphics
Source: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%if 0%{?fedora_version}
BuildRequires: gcc-c++ boost-devel python qt-devel
%else
BuildRequires: gcc-c++ boost-devel python qt3-devel
%endif
%description
Evolvotron is interactive "generative art" software to evolve images/textures/patterns through an iterative process of random mutation and user-selection driven evolution.
%prep
%setup -q -n %{name}
%build
%if 0%{?fedora_version}
source /etc/profile.d/qt.sh
%endif
%if 0%{?mandriva_version}
export QTDIR=%{_prefix}/lib/qt3
export PATH=$QTDIR/bin:$PATH
%endif
%if 0%{?suse_version}
export QTDIR=/usr/%{_lib}/qt3
export PATH=$QTDIR/bin:$PATH
%endif
./configure
make
%install
# make install
mkdir -p $RPM_BUILD_ROOT/usr/bin
install -s -m 755 evolvotron/evolvotron $RPM_BUILD_ROOT/usr/bin
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
/usr/bin/evolvotron
%doc README USAGE CHANGES
%changelog
* Fri Mar 28 2008 Karl Robillard
- Initial package release.
evolvotron/libevolvotron/dialog_render_parameters.h 0000644 0001751 0001751 00000005317 13202652325 022741 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class DialogRenderParameters.
*/
#ifndef _dialog_render_parameters_h_
#define _dialog_render_parameters_h_
#include "common.h"
#include "render_parameters.h"
//! Provides an dialog box for controlling RenderParameters.
class DialogRenderParameters : public QDialog
{
private:
Q_OBJECT
protected:
//! Instance of MutationParameters under dialog control.
/*! NB it's fairly important no-one modifies this except through methods of this class
(or another class responsible for another part), else GUI components will get out of sync
*/
RenderParameters*const _render_parameters;
//! Enables jittered samples.
QCheckBox* _checkbox_jittered_samples;
//! Chooses between multisampling levels.
QWidget* _buttonvbox;
//! Chooses between multisampling levels.
QButtonGroup* _buttongroup;
//! Button to close dialog.
QPushButton* _ok;
//! Reload from _render_parameters.
void setup_from_render_parameters();
public:
//! Constructor.
DialogRenderParameters(QMainWindow* parent,RenderParameters* rp);
//! Destructor.
~DialogRenderParameters();
public slots:
//! Signalled by checkbox.
void changed_jittered_samples(int buttonstate);
//! Signalled by radio buttons.
void changed_oversampling(int id);
//! Signalled by mutation parameters
void render_parameters_changed();
};
#endif
evolvotron/libevolvotron/obsolete/tuple.h 0000644 0001751 0001751 00000012666 13202652325 020672 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class Tuple.
*/
#ifndef _tuple_h_
#define _tuple_h_
#include "useful.h"
//! Class to hold a fixed size tuple of elements
/*! Maybe Array would have been a better name.
NB No destructor defined because gcc generates less efficient code for matrices.
*/
template class Tuple
{
protected:
//! The elements.
T _element[N];
public:
//! Null constructor.
Tuple()
{}
//! Copy constructor.
Tuple(const Tuple& t)
{
for (uint i=0;i()
// {}
//! Accessor.
T& operator[](uint i)
{
assert(i& t)
{
for (uint i=0;i& t)
{
for (uint i=0;i fill(T v)
{
Tuple ret;
for (uint i=0;i inline const bool operator==(const Tuple& a,const Tuple& b)
{
for (uint i=0;i inline const bool operator!=(const Tuple& a,const Tuple& b)
{
return !(a==b);
}
//! Element-wise addition.
template inline const Tuple operator+(const Tuple& a,const Tuple& b)
{
Tuple r(a);
r+=b;
return r;
}
//! Element-wise subtraction.
template inline const Tuple operator-(const Tuple& a,const Tuple& b)
{
Tuple r(a);
r-=b;
return r;
}
//! Test whether this will expand to sensible straight-through code.
/*! Call TupleHelperCopyEliminate::compute(Tuple& m_to,const Tuple& m_from);
This _does_ seem to generate a nice straight-through run of move instructions.
*/
template class TupleHelperCopyEliminate
{
public:
static void execute(Tuple& m_to,const Tuple& m_from)
{
m_to[I]=m_from[(I>=SKIP ? I+1 : I)];
TupleHelperCopyEliminate::execute(m_to,m_from);
}
};
//! Specialisation to end recursion
template class TupleHelperCopyEliminate<0,SKIP,N,T>
{
public:
static void execute(Tuple& m_to,const Tuple& m_from)
{
m_to[0]=m_from[(SKIP==0 ? 1 : 0)];
}
};
//! Development of class TupleHelperCopyEliminate to provide elimination of a row and column.
/*! Used by matrix class to generate minor matrices efficiently
*/
template class TupleHelperDoubleCopyEliminate
{
public:
static void execute(Tuple >& m_to,const Tuple >& m_from)
{
TupleHelperCopyEliminate::execute(m_to[I],m_from[(I>=SKIP_R ? I+1 : I)]);
TupleHelperDoubleCopyEliminate::execute(m_to,m_from);
}
};
//! Specialisation to end recursion
template class TupleHelperDoubleCopyEliminate<0,SKIP_R,SKIP_C,N_R,N_C,T>
{
public:
static void execute(Tuple >& m_to,const Tuple >& m_from)
{
TupleHelperCopyEliminate::execute(m_to[0],m_from[(SKIP_R==0 ? 1 : 0)]);
}
};
#endif
evolvotron/libevolvotron/obsolete/matrix.h 0000644 0001751 0001751 00000030054 13202652325 021034 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class Matrix.
*/
#ifndef _matrix_h_
#define _matrix_h_
#include "useful.h"
#include "tuple.h"
// Fwd declaration of helper class.
template class MatrixHelperSumCofactorDeterminantProducts;
template class MatrixHelperInvert;
//! Common base for general and specialised cases.
/*! Avoids having to reimplement some functions in Matrix<1,1,T> specialisation.
*/
template class MatrixBase : public Tuple >
{
public:
//! Null constructor.
MatrixBase()
{}
//! Copy constructor.
MatrixBase(const MatrixBase& t)
:Tuple >(t)
{}
////! Destructor.
//~MatrixBase()
// {}
uint rows() const
{
return R;
}
uint cols() const
{
return C;
}
static int cofactor_sign(uint mr,uint mc)
{
return ( ((mr+mc)&1) ? -1 : 1);
}
static const T cofactor_sign(uint mr,uint mc,const T v)
{
return ( ((mr+mc)&1) ? -v : v);
}
std::ostream& write(std::ostream& out) const
{
for (uint r=0;r class Matrix : public MatrixBase
{
protected:
public:
//! Null constructor.
Matrix()
:MatrixBase()
{}
//! Copy constructor.
Matrix(const Matrix& m)
:MatrixBase(m)
{}
//! Construct minor matrix (from a larger matrix)
Matrix(uint mr,uint mc,const Matrix& m)
:MatrixBase()
{
m.extract_minor(mr,mc,*this);
}
////! Destructor.
//~Matrix()
// {}
void operator*=(const T& v)
{
for (uint r=0;r transposed() const
{
Matrix ret;
for (uint r=0;r& m) const
{
assert(mr void extract_minor(Matrix& m) const
{
TupleHelperDoubleCopyEliminate::execute(m,*this);
}
T determinant() const
{
/* Old code calls runtime minor generator: not efficient code.
T ret(0);
for (uint c=0;c(0,c,*this).determinant());
}
return ret;
*/
// Better version uses metaprogramming to expand to straight-line code.
return MatrixHelperSumCofactorDeterminantProducts::execute(*this);
}
Matrix inverted() const
{
Matrix ret;
/* Old code calls runtime minor generator: not efficient code.
for (uint r=0;r(r,c,(*this)).determinant());
}
}
*/
// Better version uses metaprogramming to expand to straight-line code.
MatrixHelperInvert::execute(ret,(*this));
ret*=(T(1.0)/determinant());
return ret;
}
};
//! Matrix multiplication
/*! \todo Check assembler code. Want loops to unroll - use template recursion ?
*/
template inline const Matrix operator*(const Matrix& a,const Matrix& b)
{
Matrix ret;
for (uint r=0;r inline const Tuple operator*(const Matrix& m,const Tuple& v)
{
Tuple ret;
for (uint r=0;r class Matrix<1,1,T> : public MatrixBase<1,1,T>
{
protected:
public:
//! Null constructor.
Matrix<1,1,T>()
:MatrixBase<1,1,T>()
{}
//! Copy constructor.
Matrix<1,1,T>(const Matrix<1,1,T>& t)
:MatrixBase<1,1,T>(t)
{}
//! Construct minor matrix
Matrix<1,1,T>(uint mr,uint mc,const Matrix<2,2,T>& m)
:MatrixBase()
{
m.extract_minor(mr,mc,*this);
}
//! Convenient constructor
Matrix<1,1,T>(T v00)
:MatrixBase<1,1,T>()
{
(*this)[0][0]=v00;
}
////! Destructor.
//~Matrix<1,1,T>()
// {}
Matrix<1,1,T> transposed() const
{
return (*this);
}
//NB minor of 1x1 matrix makes no sense.
//void extract_minor(uint mr,uint mc,Matrix& m) const
T determinant() const
{
return (*this)[0][0];
}
Matrix<1,1,T> inverted() const
{
return Matrix<1,1,T>(T(1.0)/(*this)[0][0]);
}
};
//! (Partial) specialisation for 2x2 matrix
template class Matrix<2,2,T> : public MatrixBase<2,2,T>
{
protected:
public:
//! Null constructor.
Matrix<2,2,T>()
:MatrixBase<2,2,T>()
{}
//! Copy constructor.
Matrix<2,2,T>(const Matrix<2,2,T>& t)
:MatrixBase<2,2,T>(t)
{}
//! Construct minor matrix
Matrix<2,2,T>(uint mr,uint mc,const Matrix<3,3,T>& m)
:MatrixBase<2,2,T>()
{
m.extract_minor(mr,mc,*this);
}
//! Convenient constructor
Matrix<2,2,T>(T v00,T v01,T v10,T v11)
:MatrixBase<2,2,T>()
{
(*this)[0][0]=v00;
(*this)[0][1]=v01;
(*this)[1][0]=v10;
(*this)[1][1]=v11;
}
////! Destructor.
//~Matrix<1,1,T>()
// {}
Matrix<2,2,T> transposed() const
{
return Matrix<2,2,T>((*this)[0][0],(*this)[1][0],(*this)[0][1],(*this)[1][1]);
}
void extract_minor(uint mr,uint mc,Matrix<1,1,T>& m) const
{
assert(mr==0 || mr==1);
assert(mc==0 || mc==1);
m[0][0]=(*this)[1-mr][1-mc];
}
//! Template member for extracting minors when row and column to be eliminated are known at compile time.
template void extract_minor(Matrix<1,1,T>& m) const
{
assert(SKIP_R==0 || SKIP_R==1);
assert(SKIP_C==0 || SKIP_C==1);
m[0][0]=(*this)[1-SKIP_R][1-SKIP_C];
}
T determinant() const
{
return (*this)[0][0]*(*this)[1][1]-(*this)[0][1]*(*this)[1][0];
}
Matrix<2,2,T> inverted() const
{
Matrix<2,2,T> ret((*this)[1][1],-(*this)[0][1],-(*this)[1][0],(*this)[0][0]);
ret*=(T(1.0)/determinant());
return ret;
}
};
template class MatrixHelperSumCofactorDeterminantProducts
{
public:
static T execute(const Matrix& m)
{
Matrix minor_matrix;
// Would prefer to use
//m.extract_minor<0,FC>(minor_matrix);
// but compiler doesn't seem to like it (problem with partial specialisation?)
TupleHelperDoubleCopyEliminate::execute(minor_matrix,m);
return
m[0][FC]*((FC&1) ? -1.0f : 1.0f)*minor_matrix.determinant()
+
MatrixHelperSumCofactorDeterminantProducts::execute(m);
;
}
};
template class MatrixHelperSumCofactorDeterminantProducts<0,R,C,T>
{
public:
static float execute(const Matrix& m)
{
Matrix minor_matrix;
TupleHelperDoubleCopyEliminate::execute(minor_matrix,m);
return m[0][0]*minor_matrix.determinant();
}
};
template class MatrixHelperInvert
{
public:
static void execute(Matrix& m_out,const Matrix& m_in)
{
Matrix minor_matrix;
TupleHelperDoubleCopyEliminate::execute(minor_matrix,m_in);
m_out[C][R]=Matrix::cofactor_sign(R,C,minor_matrix.determinant());
MatrixHelperInvert::execute(m_out,m_in);
}
};
template class MatrixHelperInvert
{
public:
static void execute(Matrix& m_out,const Matrix& m_in)
{
Matrix minor_matrix;
TupleHelperDoubleCopyEliminate::execute(minor_matrix,m_in);
m_out[0][R]=Matrix::cofactor_sign(R,0,minor_matrix.determinant());
MatrixHelperInvert::execute(m_out,m_in);
}
};
template class MatrixHelperInvert<0,0,ROWS,COLS,T>
{
public:
static void execute(Matrix& m_out,const Matrix& m_in)
{
Matrix minor_matrix;
TupleHelperDoubleCopyEliminate::execute(minor_matrix,m_in);
m_out[0][0]=Matrix::cofactor_sign(0,0,minor_matrix.determinant());
}
};
//! 3x3 matrix class
class Matrix33 : public Matrix<3,3,float>
{
public:
Matrix33()
{}
Matrix33(const Matrix33& m)
:Matrix<3,3,float>(m)
{}
};
class Matrix33RotateX : public Matrix33
{
public:
Matrix33RotateX(float a)
{
const float sa=sin(a);
const float ca=cos(a);
(*this)[0][0]=1.0f;(*this)[0][1]=0.0f;(*this)[0][2]=0.0f;
(*this)[1][0]=0.0f;(*this)[1][1]= ca;(*this)[1][2]= -sa;
(*this)[2][0]=0.0f;(*this)[2][1]= sa;(*this)[2][2]= ca;
}
};
class Matrix33RotateY : public Matrix33
{
public:
Matrix33RotateY(float a)
{
const float sa=sin(a);
const float ca=cos(a);
(*this)[0][0]= ca;(*this)[0][1]=0.0f;(*this)[0][2]= sa;
(*this)[1][0]= -sa;(*this)[1][1]=1.0f;(*this)[1][2]= ca;
(*this)[2][0]=0.0f;(*this)[2][1]=0.0f;(*this)[2][2]=0.0f;
}
};
class Matrix33RotateZ : public Matrix33
{
public:
Matrix33RotateZ(float a)
{
const float sa=sin(a);
const float ca=cos(a);
(*this)[0][0]= ca;(*this)[0][1]= -sa;(*this)[0][2]=0.0f;
(*this)[1][0]= sa;(*this)[1][1]= ca;(*this)[1][2]=0.0f;
(*this)[2][0]=0.0f;(*this)[2][1]=0.0f;(*this)[2][2]=1.0f;
}
};
//! Tests basic matrix functionality.
extern void testmatrix();
#endif
evolvotron/libevolvotron/dialog_help.h 0000644 0001751 0001751 00000003407 13202652325 020165 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class DialogHelp.
*/
#ifndef _dialog_help_h_
#define _dialog_help_h_
#include "common.h"
//! Provides a dialog box with some user documentation.
/*! More of a quick reference guide than a manual.
*/
class DialogHelp : public QDialog
{
private:
Q_OBJECT
public:
//! Constructor.
DialogHelp(QWidget* parent,bool full);
//! Destructor.
~DialogHelp();
};
#endif
evolvotron/libevolvotron/common.h 0000644 0001751 0001751 00000004701 13202652325 017204 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Precompiled header for libevolvotron
Could load this up with Qt headers maybe.
*/
#ifndef _libevolvotron_precompiled_h_
#define _libevolvotron_precompiled_h_
#include "../libfunction/common.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define stringify(S) __STRING(S)
#endif
evolvotron/libevolvotron/mutatable_image_computer.h 0000644 0001751 0001751 00000013553 13202652325 022757 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class MutatableImageComputer.
*/
#ifndef _mutatable_image_computer_h_
#define _mutatable_image_computer_h_
#include "common.h"
#include "mutatable_image.h"
#include "random.h"
class MutatableImageDisplay;
class MutatableImageComputerFarm;
class MutatableImageComputerTask;
//! Class to handle computing of MutatableImages in a separate thread.
/*! A compute task starts up and fetches work from it's parent farm.
The parent farm thread can communicate when necessary using the public methods of the class.
*/
class MutatableImageComputer : public QThread
{
protected:
//! Pointer to compute farm of which this thread is part.
MutatableImageComputerFarm*const _farm;
//! Priority offset applied to compute threads.
const int _niceness;
//! The current task. Can't be a const MutatableImageComputerTask because the task holds the calculated result.
boost::shared_ptr _task;
//! Randomness for sampling jitter
Random01 _r01;
//! Class encapsulating mutex-protected flags used for communicating between farm and worker.
/*! The Mutex is of dubious value (could certainly be eliminated for reads).
*/
class Communications
{
protected:
//! Mutex protecting access to members (mutable to enable const-ness of accessors).
mutable QMutex _mutex;
//! Flag to indicate we should put our current task back on the todo queue and take another one.
/*! volatile because used for inter-thread communication.
*/
volatile bool _defer;
//! Flag to indicate we should abort the current compute.
/*! volatile because used for inter-thread communication.
*/
volatile bool _abort;
//! Flag to indicate the thread should shut down and exit.
/*! volatile because used for inter-thread communication.
*/
volatile bool _kill;
public:
//! Constructor.
/*! Mutex is recursive to allow nesting.
*/
Communications()
:_mutex()
,_defer(false)
,_abort(false)
,_kill(false)
{}
//! Mutex-protected accessor.
void defer(bool v)
{
QMutexLocker lock(&_mutex);
_defer=v;
}
//! Mutex-protected accessor.
bool defer() const
{
QMutexLocker lock(&_mutex);
const bool ret=_defer;
return ret;
}
//! Mutex-protected accessor.
void abort(bool v)
{
QMutexLocker lock(&_mutex);
_abort=v;
}
//! Mutex-protected accessor.
bool abort() const
{
QMutexLocker lock(&_mutex);
const bool ret=_abort;
return ret;
}
//! Mutex-protected accessor.
void kill(bool v)
{
QMutexLocker lock(&_mutex);
_kill=v;
}
//! Mutex-protected accessor.
bool kill() const
{
QMutexLocker lock(&_mutex);
const bool ret=_kill;
return ret;
}
//! Check union of all flags with only one mutex lock.
bool kill_or_abort_or_defer() const
{
QMutexLocker lock(&_mutex);
const bool ret=(_kill || _abort || _defer);
return ret;
}
};
//! Instance of communications flags.
Communications _communications;
//! The actual compute code, launched by invoking start() in the constructor.
virtual void run();
//! Accessor.
Communications& communications()
{
return _communications;
}
//! Accessor.
const Communications& communications() const
{
return _communications;
}
//! Accessor.
const boost::shared_ptr& task() const
{
return _task;
}
//! Accessor.
MutatableImageComputerFarm* farm() const
{
return _farm;
}
public:
//! Constructor
MutatableImageComputer(MutatableImageComputerFarm* frm,int niceness);
//! Destructor
~MutatableImageComputer();
//! Defer the current task if it's priority is less important than specified. Returns true if deferrment occurred.
bool defer_if_less_important_than(uint pri);
//! This method called by an external threads to shut down the current task
void abort();
//! This method called by an external threads to shut down the current task if it's for a particular display
void abort_for(const MutatableImageDisplay* disp);
//! This method called by external thread to kill the thread.
void kill();
//! Return kill state.
/*! Needs external visibility for deciding what to do when woken from wait for task.
*/
bool killed() const;
//! Indicate whether computation us taking place (only intended for counting outstanding threads).
bool active() const
{
return (_task!=0);
}
};
#endif
evolvotron/libevolvotron/dialog_about.h 0000644 0001751 0001751 00000003465 13202652325 020353 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class DialogAbout.
*/
#ifndef _dialog_about_h_
#define _dialog_about_h_
#include "common.h"
//! Provides an "About" dialog box.
/*! About dialog displays author info, web addresses and license info.
*/
class DialogAbout : public QDialog
{
private:
Q_OBJECT
public:
//! Constructor.
DialogAbout(QWidget* parent,int n_threads,bool separate_farm_for_enlargements);
//! Destructor.
~DialogAbout();
};
#endif
evolvotron/libevolvotron/license.h 0000644 0001751 0001751 00000003033 13202652325 017333 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Header for license boilerplate.
*/
#ifndef _license_h
#define _license_h_
//! String containing GPL text.
extern const char*const license_string;
#endif
evolvotron/libevolvotron/mutatable_image_computer_farm.h 0000644 0001751 0001751 00000013110 13202652325 023751 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class MutatableImageComputerFarm.
*/
#ifndef _mutatable_image_computer_farm_h_
#define _mutatable_image_computer_farm_h_
#include "common.h"
#include "useful.h"
#include "mutatable_image_computer.h"
#include "mutatable_image_computer_task.h"
class MutatableImageComputer;
class MutatableImageDisplay;
//! Class encapsulating some compute threads and queues of tasks to be done and tasks completed.
/*! Priority queues are implemented using multiset becase we want to be able to iterate over all members.
*/
class MutatableImageComputerFarm
{
protected:
//! Comparison class for STL template.
class CompareTaskPriorityLoResFirst : public std::binary_function,boost::shared_ptr,bool>
{
public:
//! Compare task priorities.
bool operator()(const boost::shared_ptr& t0,const boost::shared_ptr& t1)
{
return (t0->priority() < t1->priority());
}
};
//! Comparison class for STL template.
class CompareTaskPriorityHiResFirst : public std::binary_function,boost::shared_ptr,bool>
{
public:
//! Compare task priorities.
bool operator()(const boost::shared_ptr& t0,const boost::shared_ptr& t1)
{
return (t0->priority() > t1->priority());
}
};
//! Mutex for locking. This is the ONLY thing the compute threads should ever block on.
mutable QMutex _mutex;
//! Wait condition for threads waiting for a new task.
QWaitCondition _wait_condition;
//! The compute threads
boost::ptr_vector _computers;
//! Convenience typedef.
typedef std::multiset,CompareTaskPriorityLoResFirst> TodoQueue;
//! Queue of tasks to be performed, lowest resolution first
TodoQueue _todo;
//! Conveniencetypedef.
typedef std::multiset,CompareTaskPriorityHiResFirst> DoneQueue;
//! Convenience typedef.
/*! const because never needs to do anything other than compare pointers
*/
typedef std::map DoneQueueByDisplay;
//! Queue of tasks completed awaiting display.
/*! We reverse the compute priority so that highest resolution images get displayed first.
Lower resolution ones arriving later should be discarded by the displays.
This mainly makes a difference for animation where enlarging multiple low resolution
images to screen res takes a lot of time. May help low-bandwidth X11 connections
by minimising redraws too.
We now also sort by display and do round-robin delivery (ithout this one display can run way ahead of the others)
*/
DoneQueueByDisplay _done;
//! Points to the next display queue to be returned (could be .end())
DoneQueueByDisplay::iterator _done_position;
public:
//! Constructor.
MutatableImageComputerFarm(uint n_threads,int niceness);
//! Destructor cleans up threads.
~MutatableImageComputerFarm();
//! Accessor.
uint num_threads() const
{
return _computers.size();
}
//! Move aborted tasks from todo queue to done queue.
void fasttrack_aborted();
//! Enqueue a task for computing.
void push_todo(const boost::shared_ptr&);
//! Remove a task from the head of the todo queue (returns null if none).
const boost::shared_ptr pop_todo(MutatableImageComputer& requester);
//! Enqueue a task for display.
void push_done(const boost::shared_ptr&);
//! Remove a task from the head of the display queue (returns null if none).
const boost::shared_ptr pop_done();
//! Flags all tasks in all queues as aborted, and signals the compute threads to abort their current task.
void abort_all();
//! Flags all tasks for a particular display as aborted (including compute threads)
void abort_for(const MutatableImageDisplay* disp);
//! Number of tasks in queues
uint tasks() const;
};
#endif
evolvotron/libevolvotron/dialog_mutatable_image_display.h 0000644 0001751 0001751 00000004536 13202652325 024106 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class DialogMutatableImageDisplay.
*/
#ifndef _dialog_mutatable_image_display_h_
#define _dialog_mutatable_image_display_h_
#include "common.h"
//! Provides a "Properties" style dialog box for manipulating
/*! Make this modal for simplicity:
avoids spawned images changing underneath us,
and the possibility of opening one for every display.
*/
class DialogMutatableImageDisplay : public QDialog
{
private:
Q_OBJECT
protected:
//! Tabs for info and xml (summary and detail)
QTabWidget* _tabs;
//! Message displaying some info about the image.
QLabel* _label_info;
//! Scrolling text area for XML description.
QTextEdit* _textedit_xml;
//! Button to close dialog.
QPushButton* _ok;
public:
//! Constructor.
DialogMutatableImageDisplay(QWidget* parent);
//! Destructor.
~DialogMutatableImageDisplay();
//! Set content of main text and scrolling area.
void set_content(const std::string& m,const std::string& x);
};
#endif
evolvotron/libevolvotron/mutatable_image_display.h 0000644 0001751 0001751 00000022341 13202652325 022561 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class MutatableImageDisplay
*/
#ifndef _mutatable_image_display_h_
#define _mutatable_image_display_h_
#include "common.h"
#include "mutatable_image.h"
#include "mutatable_image_computer.h"
#include "dialog_mutatable_image_display.h"
class EvolvotronMain;
class MutatableImageComputerTask;
//! Widget responsible for displaying a MutatableImage.
/*! A MutatableImageDisplay is responsible for displaying the image computed from the MutatableImage it owns.
Computations are split off into separate threads to take advantage of multiprocessor machines.
*/
class MutatableImageDisplay : public QWidget
{
Q_OBJECT
protected:
//! Pointer back to the application object to access services.
EvolvotronMain* _main;
//! Flag for whether context menu should display all options.
/*! false also implies a standalone window
*/
const bool _full_functionality;
//! Flag for whether the offscreen buffer has fixed size
const bool _fixed_size;
//! Size of offscreen buffer
QSize _image_size;
//! Number of frames in image
uint _frames;
//! Framerate for animation.
uint _framerate;
//! Currently displaying frame.
uint _current_frame;
//! Direction to play
bool _animate_reverse;
//! Timer for animating frames
QTimer* _timer;
//! Flag indicating resize is in progress (between resizeEvent and subsequent paintEvent).
/*! Used to supress unnecessary task spawning.
*/
bool _resize_in_progress;
//! The resolution level currently displaying (0=1-for-1 pixels, 1=half resolution etc).
/*! Needed to handle possible out of order task returns from multiple compute threads.
*/
uint _current_display_level;
//! Similar to _current_display_level, but for tracking multisample grids within a resolution level.
uint _current_display_multisample_grid;
//! An image suitable for setting as an icon.
std::unique_ptr _icon;
//! Track which image the icon is actually of.
unsigned long long int _icon_serial;
//! Offscreen image buffer.
std::vector _offscreen_pixmaps;
//! Offscreen image buffer in sensible image format (used for save, as pixmap is in display format which might be less bits).
std::vector _offscreen_images;
//! Type for staging area for incoming fragments.
/*! Key is level and multisampling, mapped type is also itself a map from fragment number to tasks.
*/
typedef std::map,std::map > > OffscreenImageInbox;
//! Staging area for incoming fragments.
/*! Fragments are accumulated for each (level,multisample) key, and completed levels passed on for display
*/
OffscreenImageInbox _offscreen_images_inbox;
//! The image function being displayed (its root node).
/*! The held image is const because references to it could be held by history archive, compute tasks etc,
so it should be completely replaced rather than manipulated.
*/
boost::shared_ptr _image_function;
//! Properties dialog.
DialogMutatableImageDisplay* _properties;
//! Context (right-click) menu.
QMenu* _menu;
//! Submenu for spawn warped options.
QMenu* _menu_warped;
//! Submenu for Big image options.
QMenu* _menu_big;
//! Position of item in menu.
/*! This is the only menu item we need to retain this information for becuase we need it to set the lock check-mark.
*/
QAction* _menu_item_action_lock;
//! Coordinate of mouse event which started mid-button adjustment
QPoint _mid_button_adjust_start_pos;
//! Coordinate of last mouse event when mid-button adjusting
QPoint _mid_button_adjust_last_pos;
//! Serial number to kill some rare problems with out-of-order tasks being returned
unsigned long long int _serial;
public:
//! Constructor.
MutatableImageDisplay(EvolvotronMain* mn,bool full_functionality,bool fixed_size,const QSize& image_size,uint f,uint fr);
//! Destructor.
virtual ~MutatableImageDisplay();
//! Accessor.
const boost::shared_ptr& image_function()
{
return _image_function;
}
//! Accessor.
bool locked() const
{
return (_image_function.get()!=0 ? _image_function->locked() : false);
}
//! Accessor.
EvolvotronMain& main() const
{
assert(_main!=0);
return *_main;
}
//! Accessor.
void main(EvolvotronMain* m)
{
_main=m;
}
//! Accessor.
const QSize& image_size() const
{
return _image_size;
}
//! Load a new image (clears up old image, starts new compute tasks).
/*! When the one_of_many parameter is true, it implies many other images are also being updated
(affects fragmentation strategy for multithreading).
*/
void image_function(const boost::shared_ptr& image_fn,bool one_of_many);
//! Evolvotron main calls this with completed (but possibly aborted) tasks.
void deliver(const boost::shared_ptr& task);
//! Set the lock state.
void lock(bool l,bool record_in_history);
protected:
//! Which farm this display should use.
MutatableImageComputerFarm& farm() const;
//! Usual handler for repaint events.
virtual void paintEvent(QPaintEvent* event);
//! Usual handler for resize events.
virtual void resizeEvent(QResizeEvent* event);
//! Handler for mouse events.
virtual void mousePressEvent(QMouseEvent* event);
//! Handler for mouse events.
virtual void mouseMoveEvent(QMouseEvent* event);
public slots:
//! Simplify the held image, return the number of nodes eliminated
uint simplify_constants(bool single);
//! Load a function from the given filename.
void load_function_file(const QString&);
protected slots:
//! Called by timer
void frame_advance();
//! Called from context menu.
void menupick_respawn();
//! Called from context menu and also by click event.
void menupick_spawn();
//! Called from context menu.
void menupick_spawn_recoloured();
//! Called from context menu.
void menupick_spawn_warped_random();
//! Called from context menu.
void menupick_spawn_warped_zoom_in();
//! Called from context menu.
void menupick_spawn_warped_zoom_out();
//! Called from context menu.
void menupick_spawn_warped_rotate();
//! Called from context menu.
void menupick_spawn_warped_pan_xy();
//! Called from context menu.
void menupick_spawn_warped_pan_x();
//! Called from context menu.
void menupick_spawn_warped_pan_y();
//! Called from context menu.
void menupick_spawn_warped_pan_z();
//! Called from context menu.
void menupick_lock();
//! Trivial wrapper for simplify_constants
void menupick_simplify();
//! Called from context menu.
void menupick_save_image();
//! Called from context menu.
void menupick_save_function();
//! Called from context menu.
void menupick_load_function();
//! Called from "Big" submenu of context menu.
void menupick_big_resizable();
//! Called from "Big" submenu of context menu.
void menupick_big_256x256();
//! Called from "Big" submenu of context menu.
void menupick_big_512x512();
//! Called from "Big" submenu of context menu.
void menupick_big_768x768();
//! Called from "Big" submenu of context menu.
void menupick_big_1024x1024();
//! Called from "Big" submenu of context menu.
void menupick_big_640x480();
//! Called from "Big" submenu of context menu.
void menupick_big_1024x768();
//! Called from "Big" submenu of context menu.
void menupick_big_1280x960();
//! Called from "Big" submenu of context menu.
void menupick_big_1600x1200();
//! Called from "Big" submenu of context menu.
void menupick_big_2048x2048();
//! Called from "Big" submenu of context menu.
void menupick_big_4096x4096();
//! Called from "Properties" on context menu
void menupick_properties();
protected:
//! Common code for big slots.
void spawn_big(bool scrollable,const QSize& sz);
};
#endif
evolvotron/libevolvotron/mutatable_image.h 0000644 0001751 0001751 00000012401 13202652325 021030 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces for class MutatableImage.
*/
#ifndef _mutatable_image_h_
#define _mutatable_image_h_
#include "common.h"
#include "xyz.h"
class FunctionNull;
class FunctionRegistry;
class FunctionTop;
class MutationParameters;
//! Class to hold the base FunctionNode of an image.
/*! Once it owns a root FunctionNode* the whole structure should be fixed (mutate isn't available, only mutated).
\todo Do reference counting on this object ? Maybe not: have to worry about stateful nodes,
\todo Generally tighten up const-ness of interfaces.
*/
class MutatableImage
{
protected:
//! The top level FunctionNode of the image.
/*! This is partly here because FunctionNode::mutate can't change the type of
the node it is invoked on (only child nodes can be zapped), partly so we
can keep colour and space transforms under control.
*/
std::unique_ptr _top;
//! Whether to sweep z sinusoidally (vs linearly)
bool _sinusoidal_z;
//! Whether xyz should be interpreted as long/lat/radius
bool _spheremap;
//! Whether this image is locked \todo Should be a property of display, not image.
bool _locked;
//! Serial number for identity tracking (used by display to discover whether a recompute is needed)
unsigned long long _serial;
//! Object count to generate serial numbers
static unsigned long long _count;
public:
//! Take ownership of the image tree with the specified root node.
MutatableImage(std::unique_ptr&,bool sinz,bool sm,bool lock);
//! Create a new random image tree.
MutatableImage(const MutationParameters& parameters,bool exciting,bool sinz,bool sm);
//! Destructor. NB Deletes owned image function tree.
virtual ~MutatableImage();
//! Returns the sampling co-ordinate given a (sub)pixel position in the given frame of an animation.
/*! This depends on things like sinusoidal_z and spheremap
*/
const XYZ sampling_coordinate(real x,real y,uint z,uint sx,uint sy,uint sz) const;
//! Accessor.
const FunctionTop& top() const;
//! Accessor.
bool sinusoidal_z() const
{
return _sinusoidal_z;
}
//! Accessor.
bool spheremap() const
{
return _spheremap;
}
//! Accessor.
bool locked() const
{
return _locked;
}
//! Accessor.
void locked(bool l)
{
_locked=l;
}
//! Accessor.
unsigned long long serial() const
{
return _serial;
}
//! Clone this image. The cloned image will not have locked state.
boost::shared_ptr deepclone() const;
//! Clone this image, setting locked state to that specified.
boost::shared_ptr deepclone(bool lock) const;
//! Return a mutated version of this image
boost::shared_ptr mutated(const MutationParameters& p) const;
//! Return a simplified version of this image
boost::shared_ptr simplified() const;
//! Return the a 0-255-scaled RGB value at the specified location.
const XYZ get_rgb(const XYZ& p) const;
//! Return the a 0-255-scaled RGB value at the specified pixel of an image/animation taking jitter (if random number generator provided) and multisampling into account
const XYZ get_rgb(uint x,uint y,uint f,uint width,uint height,uint frames,Random01* r01,uint multisample) const;
//! Return whether image value is independent of position.
bool is_constant() const;
//! Save the function-tree to the stream
std::ostream& save_function(std::ostream& out) const;
//! Obtain some statistics about the image function
void get_stats(uint& total_nodes,uint& total_parameters,uint& depth,uint& width,real& proportion_constant) const;
//! Check the function tree is ok.
bool ok() const;
//! Read a new function tree from the given stream.
static boost::shared_ptr load_function(const FunctionRegistry& function_registry,std::istream& in,std::string& report);
};
#endif
evolvotron/libevolvotron/transform_factory.h 0000644 0001751 0001751 00000011200 13202652325 021446 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class TransformFactory.
*/
#ifndef _transform_factory_h_
#define _transform_factory_h_
#include "common.h"
class Random01;
#include "transform.h"
//! Abstract base class for classes creating Transforms
class TransformFactory
{
public:
TransformFactory()
{}
virtual ~TransformFactory()
{}
//! Clone functionality needed to retain typed copies of factories.
virtual std::unique_ptr clone() const
=0;
//! Method to build a Transform.
virtual const Transform operator()(Random01&) const
=0;
protected:
};
//! Factory for creating random warps
/*! These are the mixed scale/rotate/translate ones used by the combo warp.
*/
class TransformFactoryRandomWarpXY : public TransformFactory
{
public:
//! Constructor accepts power-of-2 specifiers, so -1 & 1 would generate scalings between 0.5 and 2, half zooming in and half zooming out.
// Constructor.
/*! \todo Should be parameterised with parameters specified at point of usage in MutatableImageDisplay
*/
TransformFactoryRandomWarpXY()
{}
//! Clone.
virtual std::unique_ptr clone() const
{
return std::unique_ptr(new TransformFactoryRandomWarpXY());
}
//! Return a random transform.
virtual const Transform operator()(Random01& rng) const;
protected:
};
//! Factory for creating random scaling transforms
class TransformFactoryRandomScaleXY : public TransformFactory
{
public:
//! Constructor accepts power-of-2 specifiers, so -1 & 1 would generate scalings between 0.5 and 2, half zooming in and half zooming out.
TransformFactoryRandomScaleXY(real lopow2,real hipow2)
:_lopow2(lopow2),_hipow2(hipow2)
{}
//! Clone method.
virtual std::unique_ptr clone() const
{
return std::unique_ptr(new TransformFactoryRandomScaleXY(_lopow2,_hipow2));
}
//! Return a random scaling transform.
virtual const Transform operator()(Random01& rng) const;
protected:
//! The low end of the scaling as a power of 2
real _lopow2;
//! The high end of the scaling as a power of 2
real _hipow2;
};
//! Factory for creating random z-axis rotation transforms
class TransformFactoryRandomRotateZ : public TransformFactory
{
public:
//! Constructor
TransformFactoryRandomRotateZ()
{}
//! Clone method.
virtual std::unique_ptr clone() const
{
return std::unique_ptr(new TransformFactoryRandomRotateZ());
}
//! Create a transform.
virtual const Transform operator()(Random01& rng) const;
protected:
};
//! Factory for creating random translation transforms
class TransformFactoryRandomTranslateXYZ : public TransformFactory
{
public:
//! Constructor accepts XYZ origin (centre) and range (+/-)
TransformFactoryRandomTranslateXYZ(const XYZ& o,const XYZ& r)
:_origin(o)
,_range(r)
{}
//! Clone method.
virtual std::unique_ptr clone() const
{
return std::unique_ptr(new TransformFactoryRandomTranslateXYZ(_origin,_range));
}
//! Return a random Transform
virtual const Transform operator()(Random01& rng) const;
protected:
//! Base value for translations
XYZ _origin;
//! Range for translations
XYZ _range;
};
#endif
evolvotron/libevolvotron/render_parameters.h 0000644 0001751 0001751 00000005072 13202652325 021420 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class RenderParameters
*/
#ifndef _render_parameters_h_
#define _render_parameters_h_
#include "common.h"
template bool change(T& dst,const T& src)
{
const T previous=dst;
dst=src;
return (dst!=previous);
}
//! Class encapsulating things affecting rendering
class RenderParameters : public QObject
{
Q_OBJECT;
public:
RenderParameters(bool jitter,uint multisample,QObject* parent);
~RenderParameters();
//! Accessor.
bool jittered_samples() const
{
return _jittered_samples;
}
//! Accessor.
void jittered_samples(bool v)
{
if (change(_jittered_samples,v)) report_change();
}
//! Accessor.
uint multisample_grid() const
{
assert(_multisample_grid>=1);
return _multisample_grid;
}
//! Accessor.
void multisample_grid(uint v)
{
assert(v>=1);
if (change(_multisample_grid,v)) report_change();
}
signals:
void changed();
protected:
void report_change();
private:
//! Whether sample points should be randomized.
bool _jittered_samples;
//! Grid for multisampling.
/*! Default is 1. 4 would be 16 samples in a 4x4 grid.
*/
uint _multisample_grid;
};
#endif
evolvotron/libevolvotron/dialog_mutation_parameters.h 0000644 0001751 0001751 00000010335 13202652325 023316 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class DialogMutationParameters.
*/
#ifndef _dialog_mutation_parameters_h_
#define _dialog_mutation_parameters_h_
#include "common.h"
#include "mutation_parameters_qobject.h"
//! Provides an dialog box for controlling MutationParameters.
class DialogMutationParameters : public QDialog
{
private:
Q_OBJECT
typedef QDialog Superclass;
protected:
//! Scale to spinbox's integer values.
const int _scale;
//! Owner of dialog (probably EvolvotronMain), used to access a statusbar.
QMainWindow*const _parent;
//! Instance of MutationParameters under dialog control.
/*! NB it's fairly important no-one modifies this except through methods of this class
(or another class responsible for another part), else GUI components will get out of sync
*/
MutationParametersQObject*const _mutation_parameters;
//! Tabs for base parameters and autocool
QTabWidget* _tabs;
//! Tab for base mutation parameter controls
QWidget* _vbox_base_mutation;
//! Grid for buttons;
QWidget* _grid_buttons;
//! Grid for base parameter control spinners
QWidget* _grid_base_mutation;
//! Group for autocool parameters
QWidget* _vbox_autocool;
//! Grid for autocool parameters
QWidget* _grid_autocool;
//! Label to show number of generations
QLabel* _label_autocool_generations;
//! Button to reheeat autocooling
QPushButton* _button_autocool_reheat;
//@{
//! Button for quick adjustment of MutationParameters
QPushButton* _button_reset;
QPushButton* _button_cool;
QPushButton* _button_heat;
QPushButton* _button_shield;
QPushButton* _button_irradiate;
//@}
//@{
//! Spinners for detailed control of specific parameters
QSpinBox* _spinbox_magnitude;
QSpinBox* _spinbox_parameter_reset;
QSpinBox* _spinbox_glitch;
QSpinBox* _spinbox_shuffle;
QSpinBox* _spinbox_insert;
QSpinBox* _spinbox_substitute;
QSpinBox* _spinbox_autocool_halflife;
//@}
//! Control autocooling
QCheckBox* _checkbox_autocool_enable;
//! Button to close dialog.
QPushButton* _ok;
//! Reload spinboxes from _mutation_parameters.
void setup_from_mutation_parameters();
public:
//! Constructor.
DialogMutationParameters(QMainWindow* parent,MutationParametersQObject* mp);
//! Destructor.
~DialogMutationParameters();
public slots:
//@{
//! Signalled by button.
void reset();
void heat();
void cool();
void irradiate();
void shield();
void reheat();
//@}
//! Signalled by checkbox.
void changed_autocool_enable(int buttonstate);
//@{
//! Signalled by spinbox.
void changed_magnitude(int v);
void changed_parameter_reset(int v);
void changed_glitch(int v);
void changed_shuffle(int v);
void changed_insert(int v);
void changed_substitute(int v);
void changed_autocool_halflife(int v);
//@}
//! Signalled by mutation parameters
void mutation_parameters_changed();
};
#endif
evolvotron/libevolvotron/dialog_functions.h 0000644 0001751 0001751 00000010351 13202652325 021241 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class DialogFunctions.
*/
#ifndef _dialog_functions_h_
#define _dialog_functions_h_
#include "common.h"
#include "mutation_parameters_qobject.h"
class EvolvotronMain;
//! Utility class for DialogFunctions. Expands changed(int) to changed(src,int)
/*! Would ideally live in dialog_functions.cpp, but that causes (moc-related?) problems with linking;
seems to need wider visibility. \todo Move to own file and only include in dialog_functions.cpp
*/
class SignalExpanderValueChangedQSlider : public QObject
{
private:
Q_OBJECT
QSlider*const _src;
public:
SignalExpanderValueChangedQSlider(QObject* parent,QSlider* src)
:QObject(parent)
,_src(src)
{}
public slots:
void valueChanged(int v)
{
emit valueChanged(_src,v);
}
signals:
void valueChanged(QSlider*,int);
};
//! Similar to SignalExpanderQSlider except attaches an integer argument to the clicked signal
class SignalExpanderClickedUint : public QObject
{
private:
Q_OBJECT
uint _arg;
public:
SignalExpanderClickedUint(QObject* parent,uint arg)
:QObject(parent)
,_arg(arg)
{}
public slots:
void clicked()
{
emit clicked(_arg);
}
signals:
void clicked(uint);
};
//! Provides a dialog for controlling which functions are available.
class DialogFunctions : public QDialog
{
private:
Q_OBJECT
protected:
//! Owner of dialog
EvolvotronMain*const _parent;
//! Instance of MutationParameters under dialog control.
/*! \warning Careful of modifying things which might make DialogMutationParameters get out of sync
*/
MutationParametersQObject*const _mutation_parameters;
//! Top level holder of all the dialog content.
QWidget* _dialog_content;
//! Notification of undiluted branching ratio.
QLabel* _branching_ratio;
//! Required branching ratio after dilution
QSlider* _slider_target_branching_ratio;
//! Proportion of diluting nodes which are pure constants
QSlider* _slider_proportion_constant;
//! Proportion of non-constant nodes which are 12-parameter transforms
QSlider* _slider_identity_supression;
//! Lookup from each slider in the weighting controls area to corresponding function.
std::map _slider_to_function;
public:
//! Constructor.
DialogFunctions(EvolvotronMain* parent,MutationParametersQObject* mp);
//! Destructor.
~DialogFunctions();
//! Reload from _mutation_parameters
void setup_from_mutation_parameters();
protected slots:
//@{
//! Signalled by sliders.
void changed_target_branching_ratio(int v);
void changed_proportion_constant(int v);
void changed_identity_supression(int v);
void changed_function_weighting(QSlider*,int v);
//@}
//! Signalled by randomization methods
void clicked_button_rand(uint mask);
public slots:
//! Signalled by mutation parameters
void mutation_parameters_changed();
};
#endif
evolvotron/libevolvotron/usage_text.h 0000644 0001751 0001751 00000101434 13202652325 020065 0 ustar timday timday "\n"
"Evolvotron User Manual
\n"
"\n"
"\n"
" Evolvotron is interactive "generative art" software to evolve \n"
" images/textures/patterns through an iterative process of random \n"
" mutation and user-selection driven evolution. \n"
"
\n"
"\n"
" On starting the application, a grid of images is displayed. \n"
" Resize or maximise the application if you like, but the more \n"
" pixels have to be calculated, the slower it will be. \n"
" (For the default 2D image mode, you will need a fast machine or patience. \n"
" For the optional animation mode, you will need both.) \n"
"
\n"
"\n"
" Simply repeat the following until bored: \n"
"
- Click (singleclick) on an image you like to \n"
" spawn the next generation of its mutant offspring. \n"
"
- Wait until variations on it are regenerated in sufficient \n"
" detail that you can decide which one you like best again. \n"
"
\n"
"
\n"
"
\n"
"\n"
" IMPORTANT: Initially you should select images with some sort of variation. \n"
" If you select a uniform image, you may get stuck in a degenerate zone with \n"
" little to mutate and therefore little chance of escape to more interesting \n"
" images. You can always reset/restart from the "File" menu (the difference is \n"
" that "reset" also resets the mutation parameters to their default values). \n"
" Selecting one of the "warp" options from a context menu (right-click on \n"
" an image) can also help by introducing an additional opportunity for \n"
" mutation on subsequent spawns. \n"
"
\n"
"\n"
" Note that various spirals, grids and tiles, although complex looking, \n"
" are actually implemented by a single function node and may leave you stuck too. \n"
"
\n"
"Command Line Options
\n"
"\n"
" The following are equivalent: \n"
"
- evolvotron --grid 12x8 \n"
"
- evolvotron --grid=12x8 \n"
"
- evolvotron -g 12x8 \n"
"
\n"
"
\n"
"\n"
"General Options
\n"
"\n"
"\n"
"
- -a, --autocool
\n"
" Enable autocooling by default, and cause resets of mutation \n"
" parameters to re-enable autocooling if it was disabled. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -F, --fullscreen
\n"
" Start in "fullscreen" mode (NB for Qt on X11 this means \n"
" a screen-filling borderless/undecorated window is used; \n"
" it's not simply maximising the window, and it's not the \n"
" sort of framebuffer hijacking used by SDL games). The Qt \n"
" documentation claims some window managers may not be entirely \n"
" cooperative with this (in which case sorry, you're on your own). \n"
" evolvotron actions which bring up dialog boxes (e.g save) seem \n"
" to generally behave fairly sensibly but child windows \n"
" (e.g enlargements or dialogs) can show some "interesting" behaviour. \n"
" Fullscreen mode can be toggled within the application using "F" key. \n"
" The "Esc" key will also exit it. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -g, --grid colsxrows
\n"
" Sets size of the grid of image display cells in the main application area (defaults to 5x6) \n"
" \n"
"
\n"
"\n"
"\n"
"
- -h, --help
\n"
" Print summary of command line options and exit. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -j, --jitter
\n"
" Enable sample jittering. Samples will be made at a random position \n"
" within a pixel instead of on a regular grid, providing some antialiasing. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -m, --multisample multisample grid
\n"
" Enables additional antialiasing passes. \n"
" Specifying 2 or 3 will provide an additional pass with 2x2 or 3x3 samples per pixel. \n"
" Specifying 4 (or higher) will provide a 2x2 and a final 4x4 pass. \n"
" Specifying 1 provides the default behaviour of one sample per pixel. \n"
" For best rendering quality also specify -j. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -M, --menuhide
\n"
" Start with menu and status bar hidden. Nice with --fullscreen. \n"
" Hiding can be toggled within the application using ctrl-m. \n"
" The Esc key will also bring them back. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -p, --spheremap
\n"
" Images are produced by sampling the underlying 3D function on the \n"
" latitude-longitude grid of a sphere. The resulting images should be \n"
" usable as spheremaps/spherical environment maps. Animations vary \n"
" the radius of the sphere. NB when in spheremap mode, \n"
" middle mouse button adjustments do not yet behave like you'd expect. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -S, --startup function_filename
\n"
" Specify a function filename (evolvotron's XML format) to load on startup \n"
" (or reset). The option can be provided multiple times, and this is \n"
" also the interpretation of any positional arguments. Startup functions \n"
" are placed in the grid from left to right, top to bottom. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -U, --shuffle
\n"
" Use in conjunction with -S / --startup options, to display the specified \n"
" functions in random order, both on application startup and on each \n"
" reset of the application. \n"
" \n"
"
\n"
"\n"
"Animation Options
\n"
"\n"
"\n"
"
- -f, --frames frames
\n"
" Number of frames in animations (defaults to 1 i.e no animation) \n"
" \n"
"
\n"
"\n"
"\n"
"
- -l, --linear
\n"
" Vary z linearly with time rather than sinusoidally. \n"
" Sinusoidal variation generally looks better when animations are "bounced" \n"
" forwards and backwards, but this option is useful when generating slices to \n"
" use as volumetric textures. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -s, --fps framerate
\n"
" Rate at which frames are displayed per second (integer). (Defaults to 8). \n"
" \n"
"
\n"
"\n"
"Power-user & Debug Options
\n"
"\n"
"\n"
" Note that the usual Qt/X11 options \n"
" (for example, -geometry widthxheight option to set on-screen size in pixels) \n"
" are processed and removed before evolvotron options are checked. \n"
"
\n"
"\n"
"
- -D, --debug
\n"
" Puts the certain aspects of the app into a more debug oriented mode. \n"
" Currently (ie this may change) it simply changes function weightings \n"
" so virtually all function nodes are FunctionNoiseOneChannel. By itself \n"
" this is a pretty pointless thing to do, but in conjunction with the -X \n"
" options it's useful for examining the behaviour of specific functions. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -E, --enlargement-threadpool
\n"
" Use a separate thread pool for computing enlargements. \n"
" Using this option ensures computation of enlargements \n"
" continue to make some progress even while the main grid \n"
" is being actively worked on. However, this will be at \n"
" the expense of main grid rendering performance. \n"
" Without this option, enlargements' final high-resolution \n"
" renderings are invariably lower priority than computation \n"
" for images in the main grid. \n"
" See also the -N option to control the priority of threads \n"
" in this pool. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -n, --nice niceness
\n"
" Sets additional niceness (relative to the main application thread) \n"
" of the compute (rendering) thread(s). \n"
" It's useful to run compute threads at a slightly lower priority \n"
" ("nice 4\" is the default without this option) than the main (GUI) \n"
" part of the program (but note that this means other normal/lowish \n"
" priority tasks running on your machine may slow evolvotron down \n"
" a bit more than expected). \n"
" \n"
"
\n"
"\n"
"\n"
"
- -N, --Nice enlargement niceness
\n"
" Sets additional niceness (relative to the main application thread) \n"
" of the compute thread(s) computing enlargements (default value is 8). \n"
" Only effective in conjunction with -E option. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -t, --threads threads
\n"
" Sets number of compute threads. \n"
" If this is not specified, then as many compute threads are created \n"
" as there are processors on the system (unless this cannot be \n"
" discovered in which case only a single compute thread is created). \n"
" Non-linux builds will likely not include code to determine processor count \n"
" (suitable patches gratefully received). \n"
" \n"
"
\n"
"\n"
"\n"
"
- -u, --unwrapped
\n"
" Modifies -F behaviour so that the specified "favourite" function \n"
" is NOT wrapped by space/colour transforms. NB For functions without leaf nodes \n"
" or parameters (e.g FunctionSphericalToCartesian) this doesn't \n"
" leave any scope for variation or future mutation. \n"
" Function name recognition is case sensitive. \n"
" Example: \n"
" evolvotron -F FunctionKaleidoscope -u
\n"
" \n"
"
\n"
"\n"
"\n"
"
- -v, --verbose
\n"
" Verbose mode, writes various things to application stderr. \n"
" This is primarily intended to assist debugging. \n"
" This option used to be useful for getting a list of supported function \n"
" names for use with the -F option, but those can also be inspected \n"
" via the Settings dialogs. \n"
" \n"
"
\n"
"\n"
"\n"
"
- -x, --favourite functionname
\n"
" Force a specific "favourite" function type to be used at the top level \n"
" of all function trees. The specified function is still wrapped \n"
" by spatial and colour warping functions which may disguise \n"
" it considerably. A list of all the function names understood \n"
" by evolvotron is output during app startup when the -v option \n"
" is specified. Function name recognition is case sensitive. \n"
" Example: \n"
" evolvotron -F FunctionSpiralLinear
\n"
" \n"
"
\n"
"\n"
"Mouse Control
\n"
"\n"
"Left-click
\n"
"\n"
" A left-click on an image in the main window spawns the mutant offspring \n"
" of that image to all the other (non-locked) displays in the grid. \n"
"
\n"
"Right-click Context Menu
\n"
"\n"
" Right clicking on an image gets you a few more options: \n"
"
\n"
"\n"
"
- "Respawn" regenerates just the current image from whatever it was \n"
" spawned from (and using recolour or warp, if that's what was used \n"
" to produce it). \n"
" The main use of this is to make your grid of images look nice \n"
" for screendumps, by regenerating any which aren't up to scratch. \n"
" NB May not work as expected after an "undo". \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Spawn" is the same as clicking an image. It generates mutated \n"
" images to all unlocked images in the grid. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Recolour" to produce different coloured variants of the selected image \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Warp"'s sub-options produce variants of the image which have been \n"
" zoomed/rotated/panned. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Lock" to prevent an image from being overwritten by spawns from other \n"
" images (select again to toggle). \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Enlarge" to produce a blow-up of the image in a single window. \n"
" Submenu items select either a freely resizable window or \n"
" a scrollable view of a fixed size image. \n"
" If the application is running in fullscreen mode (NB this is \n"
" NOT the same as a simply "maximised" window) then the enlarged \n"
" image will also be fullscreen (the "Resizeable" mode is probably \n"
" what you want in this case as the image will automatically be \n"
" rendered at the correct resolution). \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Save image" to save the image in a file (.ppm or .png). \n"
" You generally want to save an enlarged image: if you \n"
" save a small image from the grid, the size you see on the screen \n"
" is the size you get in the file. Save isn't allowed until the \n"
" full resolution image has been generated; if you try to save too \n"
" early a dialog box will be displayed telling you to try again later. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Save function" to store the function to an XML file. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Load function" to load a stored function from an XML file. \n"
" NB if the file was saved from a different version numbered \n"
" evolvotron, a warning message will be generated. \n"
" Save/load of functions is an experimental feature and you should \n"
" not count on future versions of evolvotron being able to load \n"
" files saved from old versions, or producing the same image \n"
" from a loaded function. Attempting to load functions from later \n"
" versions into earlier versions is even less likely to succeed. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Simplify" prunes the function tree of redundant branches where \n"
" possible (the same action can be applied to all images from \n"
" the main "Edit" menu). This doesn't change the appearance of \n"
" the image, but may make it recompute faster. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "Properties" brings up a dialog box containing some information \n"
" about the image (e.g the number of function nodes it contains). \n"
"
\n"
"
\n"
"\n"
"Middle Mouse Button
\n"
"\n"
" [NB This feature will probably only be of practical use to those with high-end machines]. \n"
"
\n"
"\n"
" You can use the middle mouse button to drag-adjust individual images. \n"
" This is useful for "final composition" type tweaks, e.g centering an \n"
" image's most interesting feature, or just for satisfying your curiosity \n"
" about what's off the edge of the image. \n"
"
\n"
"\n"
" It also works on enlarged images, although it's virtually unusable without \n"
" a bit of practice on smaller, faster ones (just boldly make the adjustment \n"
" you want, release the button... and wait). \n"
"
\n"
"\n"
" Changes made can be rolled-back on the main Edit/Undo menu item, \n"
" one drag-action at a time. \n"
"
\n"
"\n"
" An unmodified middle-mouse drag pans the image around following \n"
" the mouse motion. \n"
"
\n"
"\n"
" A SHIFT-middle drag zooms the image in and out with scaling \n"
" proportional to the distance from the centre of the image. Beware of \n"
" generating huge zooms by clicking too near the centre of the image. \n"
"
\n"
"\n"
" An ALT-SHIFT-middle drag is similar but anisotropic: the scaling \n"
" may be different in X and Y. Warning: this technique is very \n"
" sensitive and can be quite tricky to use! In particular, \n"
" if you initially click near the centre axes of the image the zoom factor \n"
" can be HUGE, so the best way to start using this is to click about halfway \n"
" on a diagonal between the image centre and a corner and gently move in and \n"
" out radially. Dragging from one side of the image to the other flips it over \n"
" (the degenerate case of infinite zoom at the centre is handled cleanly I think). \n"
" If it all goes horribly wrong, undo and try again. \n"
"
\n"
"\n"
" A CTRL-middle drag rotates the image about its centre. \n"
"
\n"
"\n"
" A CTRL-ALT-middle drag shears the image (the best way to see what \n"
" this does is to click in the corner of an image and move the mouse \n"
" horizontally or vertically). \n"
"
\n"
"Keyboard Control
\n"
"\n"
"\n"
" There are some keyboard shortcuts. \n"
"
\n"
"Main Window
\n"
"\n"
"\n"
"
- "r"/"t"/"x" perform various starts of reset/restart. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "q" quits the application. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "u" (and also Ctrl-z) does an undo. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "f": full-screen mode (on X11, Qt does this by asking the \n"
" window manager for a screen-filling undecorated window, and the \n"
" documentation contains some dire warnings about problems with broken \n"
" window managers). See also "-F" command line option. \n"
" Fullscreen mode propagates to enlarged image display windows. \n"
" NB The application may completely disappear from the screen for \n"
" a brief interval while switching mode. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- "m" : hides status and menu-bar hiding, which can be nice when \n"
" in full-screen or window-maximised mode. See also "-M" \n"
" command line option. Also note that while the menu bar \n"
" is hidden, most of these keyboard shortcuts won't function \n"
" as they're tied to the menu system. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- Esc : exits full-screen and/or menu-hiding mode, putting the \n"
" application into its normal default state. \n"
"
\n"
"
\n"
"\n"
"Enlargement Windows
\n"
"\n"
" The image display windows created by selecting "Enlarge" from a \n"
" context menu also have a couple of keyboard operations: \n"
"
\n"
"\n"
"
- "f" : [NB only available with fullscreen build option] toggles \n"
" full-screen mode. When returning to normal mode, if the main app \n"
" window was fullscreen then it will also drop back to normal mode. \n"
"
\n"
"
\n"
"\n"
"\n"
"
- Esc : [NB only available with fullscreen build option] \n"
" completely closes a fullscreen-mode enlargement window. \n"
"
\n"
"
\n"
"\n"
"Gui Elements
\n"
"\n"
"Main Menu Bar
\n"
"\n"
"
- File menu: \n"
" Items to restart, reset and quit the application. \n"
" The difference between restart and reset is that reset \n"
" sets the mutation parameters back the their default values. \n"
" The "randomize function weights" version of restart scrambles \n"
" the relative probability of the various function types (if you \n"
" think evolvotron just keeps generating the same kinds of \n"
" images give it a try). The "restart with specific function" \n"
" item duplicates the functionality of the "-x" and "-X" command-line \n"
" options. \n"
"
- Edit menu: \n"
" "Undo" lets you undo certain actions: e.g spawn, \n"
" middle-button adjustment, simplification and lock/unlock. \n"
" There is a large but limited number of levels of undo. \n"
" "Simplify" is of curiosity value only: it prunes redundant \n"
" branches from images ("junk DNA"); this may help them recompute \n"
" faster but at the cost of there being less mutatable material. \n"
"
- Settings menu: \n"
" "Mutations" brings up a dialog to modify the amount \n"
" of change spawned images are subject to. \n"
" (See "advanced usage" below.) \n"
" "Functions" brings up a dialog to modify the relative probability \n"
" of functions being used. By default all functions are equally \n"
" likely except for iterative functions and fractals, which are \n"
" almost but not completely suppressed. But if you think there \n"
" are too many spirals or grids (or not enough fractals) then this \n"
" is the place to adjust the frequency with which they appear. \n"
" If the software was built with the fullscreen option, \n"
" that can also be controlled from this menu. \n"
" "Favourite" brings up a dialog which allows you to select a specific \n"
" function type to always be used as the root node of any new functions. \n"
" The function can be wrapped by some other random stuff, or unwrapped. \n"
" See also the -X and -x command line options. \n"
"
- Help menu: \n"
" Items to bring up documentation, and the usual "About" box \n"
" (which includes the license). \n"
"
\n"
"
\n"
"\n"
"Status Bar
\n"
"\n"
" An area on the status bar shows how many compute "tasks" are \n"
" outstanding (or "Ready" when there are none). When two task \n"
" totals are reported, the first is for the main grid and the \n"
" second for any enlargements being computed. \n"
" Each "task" is the recomputation of an image at some resolution. \n"
" Tasks are prioritised by their number of pixels (small image \n"
" implies higher priority). This is why, if the main grid is still \n"
" recomputing, recalculations of enlargements will appear to freeze \n"
" after they have reached a certain resolution, at least until other \n"
" lower resolution tasks have completed. \n"
"
\n"
"\n"
" The status bar also provides some control over the "autocool" \n"
" mechanism which reduces mutation strength with time. \n"
" See the advanced usage section below. \n"
"
\n"
"Tips
\n"
"\n"
"
- Don't start a session with any preconceived ideas about the kind \n"
" of image you want to get out of it. You will be disappointed. \n"
"
- I get the best results when I click the image which most \n"
" immediately catches my eye as they start appearing. If you stop \n"
" to think about it too much then things seem to go downhill. \n"
"
- If you seem to be just getting the same old spirals and grids \n"
" all the time, stop clicking on spirals and grids! \n"
" (The same goes for random mush). \n"
"
- Don't get too hung up on using the warp and middle-mouse drag \n"
" adjustments every iteration... use those tools for final \n"
" polishing of your masterpiece. \n"
"
- You can quickly cycle through a lot of initial images (until \n"
" you find one with real potential) by bashing on Ctrl-r to \n"
" repeatedly restart. \n"
"
- To add variety to an image's mutations, nudge it with a small \n"
" middle-mouse drag. This introduces a top level transform, and \n"
" therefore more parameters to be varied. \n"
"
- Enlargements take a long time to complete their final \n"
" high-resolution rendering pass (especially with multisampling \n"
" enabled). Most convenient practice seems to be to go away and \n"
" leave them to complete, then come back and save them later. \n"
" Continuing to click away on the main grid effectively starves \n"
" them of CPU, unless the -E command-line option is used. \n"
"
\n"
"
\n"
"\n"
"Animation
\n"
"\n"
" As of version 0.2.0 evolvotron contains some experimental support \n"
" for generation of animations (although so far the results have been \n"
" pretty disappointing IMHO, but it's still early days). \n"
"
\n"
"\n"
" NB THIS IS EVEN MORE COMPUTATIONALLY AND MEMORY INTENSIVE THAN \n"
" THE STATIC IMAGE MODE. \n"
"
\n"
"\n"
" Simply supply a -f frames command line option and evolvotron will \n"
" generate animated sequences with the specified number of frames. \n"
" These will be displayed at the frame rate specified by the \n"
" optional -s framerate option (default 8). So "evolvotron -s 24" \n"
" will generate 3 second long animations. Animations reverse direction \n"
" at each end to avoid a sudden jump. \n"
"
\n"
"\n"
" If you save an animation as PPM or PNG, multiple files will \n"
" be saved with .fnnnnnn (where nnnnnn is the zero-filled frame \n"
" number) inserted in each filename before the filetype qualifier. \n"
"
\n"
"\n"
" For example, if you enter foo.ppm as the filename to save, \n"
" files foo.f000000.ppm, foo.f000001.ppm... will be saved. \n"
" If you have the ImageMagick tools you can convert these to \n"
" an animated GIF playing at approx. 8 frames per second with: \n"
"
\n"
"\n"
" convert -delay 12 foo.f??????.ppm foo.gif
\n"
"
\n"
"Advanced Usage
\n"
"\n"
" Evolvotron's idea of an image is a function which converts \n"
" XYZ co-ordinates to an RGB colour (however we can only display \n"
" a 2D plane for now so the input Z is fixed to zero, or varied \n"
" with time when animating). \n"
"
\n"
"\n"
" The image functions are constructed from trees of function nodes. \n"
" (In the mathematical expression 1+(2*x) the "+" and the "*" would \n"
" be function nodes.) Evolvotron's functions tend to correspond to \n"
" geometric or colour-space operations or anything else which can be \n"
" applied to a 3D vector. \n"
"
\n"
"\n"
" By mutating the structure of the function tree (adding random \n"
" branches, for example) and the values of the constant embedded \n"
" within it, the image can be changed. \n"
"
\n"
"\n"
" The mutation parameters are under control from the dialogs accessible \n"
" via the Settings menu, and the "autocool" mechanism exposed in the \n"
" status bar also has some influence. \n"
"
\n"
"\n"
" There are two kinds of mutation: perturbations to the magnitude of constants, \n"
" and structural mutations which re-arrange the function tree of an image. \n"
" Four types of structural mutations are currently implemented: \n"
"
- replacement of a function branch by a new random stub (a "Glitch" mutation). \n"
"
- a random shuffle of a node's sub-nodes \n"
"
- insertion of random nodes between a node and it's sub-nodes \n"
"
- the substitution of a node with one of a different type, \n"
" with sub-nodes unaffected where possible). \n"
"
\n"
"
\n"
"\n"
"\n"
" The probability (per function node) of these mutations is controlled \n"
" from spinboxes on the "Mutation Parameters" dialog (expressed as \n"
" chances-in-a-hundred), as is the size of perturbations to constants. \n"
"
\n"
"\n"
" It is useful to think of the perturbations to constant parameters as \n"
" being a thermal effect (hence the "heat" and "cool" buttons), while \n"
" structural alterations are more drastic and are caused by high energy \n"
" gamma rays or something (hence "irradiate" and "shield" buttons to \n"
" adjust the probability of structural mutations). \n"
"
\n"
"\n"
" So why would you want to change the mutation parameters from the initial \n"
" defaults ? Basically, if you're getting too much variation in spawned images \n"
" (this tends to happen after many generations of images, by which time the \n"
" function trees have grown quite large and therefore are experiencing a lot \n"
" of mutations) then cool and/or shield. \n"
" If all the images look too similar, heat and/or irradiate. \n"
"
\n"
"\n"
" The "autocool" mechanism (enabled from the statusbar or mutation parameters \n"
" dialog) automatically reduces the strength of mutations from the base \n"
" values with successive generations. The cooling can be cancelled by \n"
" disabling autocooling or pressing the "Reheat" button to zero the number \n"
" of generations counted for cooling. The effect of the cooling is a compound \n"
" halving of the mutation strength after some number of generations (this number \n"
" is the "half-life" controllable from the mutation parameters dialog). \n"
" Note that if autocooling is enabled then eventually, after a number of \n"
" iterations more than many multiples of the half-life has passes, spawned \n"
" images will differ very little from their parents (hence the need for "reheat"). \n"
"
\n"
"\n"
" There is also a dialog accessible from "Functions..." on the "Settings" menu. \n"
" This allows control over the relative proportions in which functions occur. \n"
" There is a tab showing the relative weighting of all functions (log-2 scale: each \n"
" tick halves the probability of the function occurring), and additional tabs \n"
" for various classifications of function for quicker access. \n"
" The "Randomize" button on each tab assigns random weightings and helps \n"
" increase the uniqueness of your session. \n"
"
\n"
"\n"
" The "Functions" dialog also has a "Dilution" tab which allows the average \n"
" function-tree branching ratio to be controlled (by changing the proportion \n"
" of trivial zero-branch functions added): note that using a high branching \n"
" ratio results in very complex images which will take a long time to compute, \n"
" while reducing the ratio results in simple, boring images. \n"
"
\n"
"\n"
" 3 types of function node are considered fundamental: constant nodes \n"
" (which return a constant), identity nodes (which return their \n"
" position argument) and transform nodes (which transform their position \n"
" argument by random parameters). On the "Dilution" tab of the "Functions" \n"
" dialog there are two slider controls to affect things related to these: \n"
"
- "proportion constant" controls the proportion of diluting fundamental nodes \n"
" which are constants. Changing this from its default value of 0.5 doesn't \n"
" actually seem to have much effect. \n"
"
- "proportion transforms" sets the proportion of non-constant nodes diluting \n"
" which are transforms (as opposed to identity nodes). \n"
" The main effect of this is that images are less commonly obviously centred \n"
" on the origin or aligned with the axes. I think this is a good thing, so \n"
" the value is at 1.0 by default. \n"
"
\n"
"
\n"
"\n"
"Other Executables
\n"
"\n"
" This release also builds some other command-line driven (non-GUI, non-interactive) utilities. \n"
" Consult the man pages for full details. \n"
"
\n"
"\n"
" evolvotron_render reads a XML function description from its standard input and renders it to the \n"
" file specified. \n"
"
\n"
"\n"
" evolvotron_mutate reads an XML function description from its standard input and outputs a mutated version. \n"
" A command line option allows the "genesis" situation of creating a random function description with no input. \n"
"
\n"
"Examples
\n"
"\n"
"\n"
" Evolving and mutating on the command line: \n"
"
\n"
"\n"
" evolvotron_mutate -g | tee fn.xml | evolvotron_render /tmp/xxx.ppm ; display /tmp/xxx.ppm
\n"
"
\n"
"\n"
" cat fn.xml | evolvotron_mutate | evolvotron_render -j -m 4 /tmp/xxx.ppm ; display /tmp/xxx.ppm
\n"
"
\n"
"\n"
" Animating a function ani.xml saved from evolvotron in animation mode: \n"
"
\n"
"\n"
" cat ani.xml | evolvotron_render -f 100 -v -s 256 256 ani.ppm ; animate ani.f??????.ppm
\n"
"
\n"
"Future Developments
\n"
"\n"
" Please check the TODO file first before you send me suggestions! \n"
"
\n"
"\n"
" Please don't ask me to port evolvotron to proprietary platforms. \n"
" You are of course Free under the terms of the GPL to do so yourself, \n"
" but please read \n"
" http://www.fefe.de/nowindows/ \n"
" first. \n"
"
\n"
"Thanks
\n"
"\n"
" To those who have contributed feedback, suggestions and patches: \n"
"
- Dmitry Kirsanov \n"
"
- Jonathan Melhuish \n"
"
- Karl Robillard \n"
"
- Linc Davis \n"
"
- Paolo Greppi \n"
"
- Marcin Wojtczuk \n"
"
- Michael Sterrett \n"
"
- Massimiliano Guastafierro \n"
"
- Goetz Waschk \n"
"
- Forrest Walter \n"
"
- "chr_bl" at web.de \n"
"
\n"
"
\n"
"\n"
"\n"
" And to the anonymous Linspire reviewer who perhaps came up with the best \n"
" summary of evolvotron yet: "Fascinating. Utterly pointless, but fascinating." \n"
"
\n"
"\n"
" The friezegroups wouldn't have been possible without \n"
" http://michaelshepperd.tripod.com/resources/groups.html \n"
"
\n"
"\n"
" Thanks to www.di.fm, www.somafm.com and Trance4Ever for music to code to. \n"
"
\n"
"\n"
" Thanks especially to a SIGGRAPH conference panel many years ago (likely \n"
" including Karl Sims, the pioneer in this area) who first got me interested \n"
" in this stuff. \n"
"
\n"
"Why ?
\n"
"\n"
" I have always admired those who have the skill to wield a pen or paintbrush \n"
" and fill a sheet of paper or a canvas with some striking image from their \n"
" imagination. Unfortunately I lack the patience to learn such skills, \n"
" and probably the necessary manual dexterity and imagination too. \n"
"
\n"
"\n"
" Evolvotron, and several predecessors developed on and off over a decade \n"
" since I first came across the idea, are an attempt to compensate for \n"
" this using the skills I do have i.e some mathematical sensibility \n"
" and the ability to write working code (well, sometimes). If you like \n"
" an image it produces, then as far as I'm concerned that's as satisfying \n"
" a result as if you liked something I'd drawn myself. \n"
"
\n"
"\n"
" Tim Day \n"
evolvotron/libevolvotron/mutation_parameters_qobject.h 0000644 0001751 0001751 00000003660 13202652325 023511 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class MutationParametersQObject.
*/
#ifndef _mutation_parameters_qobject_h_
#define _mutation_parameters_qobject_h_
#include "common.h"
#include "mutation_parameters.h"
//! class extending MutationParameters to emit changed signal when appropriate.
class MutationParametersQObject : public QObject, public MutationParameters
{
Q_OBJECT;
public:
MutationParametersQObject(uint seed,bool autocool,bool debug_mode,QObject* parent);
~MutationParametersQObject();
signals:
void changed();
protected:
void report_change();
};
#endif
evolvotron/libevolvotron/evolvotron_main.h 0000644 0001751 0001751 00000033125 13202652325 021137 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class EvolvotronMain.
*/
#ifndef _evolvotron_main_h_
#define _evolvotron_main_h_
#include "common.h"
#include "function_registry.h"
#include "transform_factory.h"
#include "mutatable_image.h"
#include "mutatable_image_display.h"
#include "mutatable_image_computer_farm.h"
#include "mutation_parameters_qobject.h"
#include "render_parameters.h"
class DialogAbout;
class DialogHelp;
class DialogMutationParameters;
class DialogRenderParameters;
class DialogFunctions;
class DialogFavourite;
//! Utility class to expand "restart with" menu picks
/*! A boost::bind kind of thing
*/
class SignalExpanderRestartWith : public QObject
{
private:
Q_OBJECT
const FunctionRegistration*const _fn;
public:
SignalExpanderRestartWith(QObject* parent,const FunctionRegistration* fn)
:QObject(parent)
,_fn(fn)
{}
public slots:
void restart_with()
{
emit restart_with(_fn);
}
signals:
void restart_with(const FunctionRegistration*);
};
//! Top level GUI component for evolvotron application
class EvolvotronMain : public QMainWindow
{
private:
Q_OBJECT
protected:
//! Class encapsulating everything needed for undo functionality.
/*! \todo This is too big to be a nested class.
*/
class History
{
protected:
//! Pointer to main app.
EvolvotronMain*const _main;
typedef std::map > ArchiveRecordEntries;
typedef std::pair ArchiveRecord;
typedef std::deque Archive;
//! Each deque slot contains the collection of display-image pairs replaced by an single action (and a string naming that action).
/*! We use a deque rather than a stack because we want to clean up the tail end (limited number of Undos).
*/
Archive _archive;
//! Number of slots retained for history.
const uint max_slots;
//! Clean up the last slot in the queue.
void purge();
//! Write some info to std::clog.
void log_status() const;
public:
//! Constructor.
History(EvolvotronMain*);
//! Destructor.
~History();
//! Eliminate any references to the display (and clean up any undo actions which are empty as a result).
void goodbye(MutatableImageDisplay*);
//! Record that we are overwriting the given display.
void replacing(MutatableImageDisplay* display);
//! Starts a new action slot
void begin_action(const std::string& action_name);
//! Ends an action slot and updates the undoable state.
void end_action();
//! Returns true if there is stuff to undo
bool undoable();
//! Implements an undo.
void undo();
};
protected:
//! Convenience typedef for pointer to member function implementing a kind of spawn.
typedef void (EvolvotronMain::* SpawnMemberFn)(const boost::shared_ptr& image,MutatableImageDisplay* display,bool one_of_many);
//! Instance of History object to track activity.
std::unique_ptr _history;
//! Sweep z linearly through animations
/*! \todo Move to mutation or render paraemeters ?
*/
const bool _linear_zsweep;
//! Generate spheremaps
/*! \todo Move to mutation or render paraemeters ?
*/
const bool _spheremap;
//! Name of files to load on a reset.
std::vector _startup_filenames;
//! Whether to shuffle startup files (if any).
const bool _startup_shuffle;
//! Instance of mutation parameters for the app
/*! This used to be held by DialogMutationParameters, but now we want to share it around a bit
(although modifications should always be via the dialog slots, to keep the dialogs up to date)
*/
MutationParametersQObject _mutation_parameters;
//! Instance of render parameters for the app
RenderParameters _render_parameters;
//! Somewhere to report what's going on
QStatusBar* _statusbar;
//! Label for displaying number of tasks running (more permanent than StatusBar's message method).
QLabel* _statusbar_tasks_label;
//! Number of main tasks the statusbar is currently reporting as active
/*! Cached to avoid unnecessarily regenerating message
*/
uint _statusbar_tasks_main;
//! Number of enlargement tasks the statusbar is currently reporting as active
/*! Cached to avoid unnecessarily regenerating message
*/
uint _statusbar_tasks_enlargement;
//! The "About" dialog widget.
DialogAbout* _dialog_about;
//! The "Help" dialog widget (quick reference text)
DialogHelp* _dialog_help_short;
//! The "Help" dialog widget (full manual text)
DialogHelp* _dialog_help_long;
//! The dialog for adjusting MutationParameters.
DialogMutationParameters* _dialog_mutation_parameters;
//! The dialog for adjusting RenderParameters.
DialogRenderParameters* _dialog_render_parameters;
//! Dialog for controlling which functions are in use.
DialogFunctions* _dialog_functions;
//! Dialog for selecting a favourite function (also holds the state for favourite stuff)
DialogFavourite* _dialog_favourite;
//! The file menu.
QMenu* _popupmenu_file;
//! The edit menu.
QMenu* _popupmenu_edit;
//! ID for the undo item (so we can disable it).
QAction* _popupmenu_edit_undo_action;
//! The settings menu
QMenu* _popupmenu_settings;
//! Action for setting fullscreen
QAction* _menu_action_fullscreen;
//! Action for hiding menubar
QAction* _menu_action_hide_menu;
//! The help menu.
QMenu* _popupmenu_help;
//! Select autocooling (also serves to reset the generation count).
QCheckBox* _checkbox_autocool_enable;
//! Report number of generations.
QLabel* _label_autocool_enable;
//! Button to reheat
QPushButton* _button_autocool_reheat;
//! Grid for image display areas
QWidget* _grid;
//! Timer to drive tick() slot
QTimer* _timer;
//! Two farms of compute threads. One for the main display, one for enlargements.
std::unique_ptr _farm[2];
//! All the displays in the grid.
std::vector _displays;
//! Keeps track of which displays are still available for display (they might have been destroyed while an image was computing).
/*! Non-const because we might need to notify them about various things
*/
std::set _known_displays;
//! Keeps track of which displays are still resizing
std::set _resizing;
//! The last image spawned (used to regenerate single displays).
boost::shared_ptr _last_spawned_image;
//! Pointer to member function used for last spawn.
SpawnMemberFn _last_spawn_method;
//! An owned pointer to the current transform factory (needed for Respawn).
std::unique_ptr _transform_factory;
//! Accessor.
const boost::shared_ptr last_spawned_image() const
{
return _last_spawned_image;
}
//! Accessor.
SpawnMemberFn last_spawn_method() const
{
return _last_spawn_method;
}
//! Not just an accessor. Takes ownership of a deepclone of the image
void last_spawned_image(const boost::shared_ptr& image,SpawnMemberFn method);
//! Accessor
const TransformFactory& transform_factory() const
{
// We shouldn't be here unless transform_factory has been set to something.
assert(_transform_factory.get()!=0);
return *_transform_factory;
}
//! Not just an accessor. Takes ownership of a deepclone of the argument.
void transform_factory(const TransformFactory& tfactory)
{
_transform_factory=tfactory.clone();
}
//@{
//! Perform a particular type of spawn from an individiual image to an individual display. (Locking not checked).
void spawn_normal(const boost::shared_ptr& image,MutatableImageDisplay* display,bool one_of_many);
void spawn_recoloured(const boost::shared_ptr& image,MutatableImageDisplay* display,bool one_of_many);
void spawn_warped(const boost::shared_ptr& image,MutatableImageDisplay* display,bool one_of_many);
//@}
//! Spawn the specified display using the specified method.
void spawn_all(MutatableImageDisplay* display,SpawnMemberFn method,const std::string& action_name);
public:
//! Constructor.
EvolvotronMain
(
QWidget* parent,
const QSize& grid_size,
uint frames,
uint framerate,
uint n_threads,
bool separate_farm_for_enlargements,
int niceness_grid,
int niceness_enlargements,
bool start_fullscreen,
bool start_menuhidden,
bool autocool,
bool jitter,
uint multisample_level,
bool function_debug_mode,
bool linear_zsweep,
bool spheremap,
const std::vector& startup_filenames,
bool startup_shuffle
);
//! Destructor.
~EvolvotronMain();
//! Accessor. Returns true if function name recognised. Forwards to DialogFavourite.
bool favourite_function(const std::string& f);
//! Accessor. Forwards to DialogFavourite.
void favourite_function_unwrapped(bool v);
//! Accessor.
std::vector& displays()
{
return _displays;
}
//! Accessor.
/*! NB Only const version made available publicly as modifications should be through an appropriate dialog slot.
*/
const MutationParameters& mutation_parameters() const
{
return _mutation_parameters;
}
//! Accessor.
/*! NB Only const version made available publicly as modifications should be through an appropriate dialog slot.
*/
const RenderParameters& render_parameters() const
{
return _render_parameters;
}
//! Returns which farm to use for purpose.
MutatableImageComputerFarm& farm(bool enlargement)
{
return *_farm[enlargement && _farm[1].get()];
}
//! Accessor.
History& history()
{
return *_history;
}
//! Called by History when performing undo.
void restore(MutatableImageDisplay* display,const boost::shared_ptr&,bool one_of_many);
//! Called by History to change undo menu status.
void set_undoable(bool v,const std::string& name);
//! Regenerates a single display using last spawn method and source.
void respawn(MutatableImageDisplay* display);
//! Mutates the image held by the given display to all the other displays owned.
void spawn_normal(MutatableImageDisplay* spawning_display);
//! Similar to spawn except just changes the colouration of the image.
void spawn_recoloured(MutatableImageDisplay* spawning_display);
//! Similar to spawn except just changes the input co-ordinates to the image.
void spawn_warped(MutatableImageDisplay* spawning_display,const TransformFactory& tfactory);
//! Called from display constructor to indicate the display is available for the disposal of its completed tasks.
void hello(MutatableImageDisplay*);
//! Called from display destructor to indicate the display is no longer available for the disposal of its completed tasks.
void goodbye(MutatableImageDisplay*);
//! Returns true if the display is known.
bool is_known(MutatableImageDisplay* disp) const;
//! Write a list of known displays (for debugging)
void list_known(std::ostream& out) const;
protected:
//! Handle key-presses
void keyPressEvent(QKeyEvent* e);
//! Reset the specified display.
void reset(MutatableImageDisplay* display);
protected slots:
//! Signalled by timer.
void tick();
//! Signalled by menu item. Forwards to History object.
void undo();
//! Signalled by menu item. Simplifies all functions.
void simplify_constants();
public slots:
//! Signalled by menu item.
void toggle_hide_menu();
//! Signalled by menu item
void toggle_fullscreen();
//! Signalled by menu item. Public because called from evolvotron app wrapper.
void reset(bool reset_mutation_parameters,bool reset_locks);
//! Forwards to reset(false)
void reset_warm();
//! Forwards to reset(true)
void reset_cold();
//! Resets and randomizes function weightings
void reset_randomized();
//! So we can update any exposed mutation parameters (e.g autocool enable, generation count)
void mutation_parameters_changed();
//! So we can re-render when render parameters change
void render_parameters_changed();
};
#endif
evolvotron/libevolvotron/dialog_favourite.h 0000644 0001751 0001751 00000006054 13202652325 021242 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class DialogFavourite.
*/
#ifndef _dialog_favourite_h_
#define _dialog_favourite_h_
#include "common.h"
class EvolvotronMain;
//! Provides a dialog for controlling which functions are available.
class DialogFavourite : public QDialog
{
private:
Q_OBJECT
protected:
//! Owner.
EvolvotronMain* _parent;
//! Function name to be used as the root node of new image function tres (no favourite if empty)
std::string _favourite_function;
//! Flag specifying whether favourite function should be exposed
bool _favourite_function_unwrapped;
//! Map function names to combo box entries.
std::map _favourite_fn_to_index;
//! Look up function names from combo box.
std::map _index_to_favourite_fn;
//! Select favourite function, if any.
QComboBox* _favourite;
//! Controls unwrapped state.
QCheckBox* _unwrapped;
//! Make GUI match _favourite_function and _favourite_function_unwrapped state
void update_gui_from_state();
protected slots:
//! Invoked on combo-box selection.
void changed_favourite(int i);
//! Invoked on checkbox toggle.
void changed_unwrapped(bool b);
public:
//! Constructor.
DialogFavourite(EvolvotronMain* parent);
//! Destructor.
~DialogFavourite();
//! Accessor
const std::string& favourite_function() const
{
return _favourite_function;
}
//! Accessor. Returns true if function name recognised.
bool favourite_function(const std::string& f);
//! Accessor.
bool favourite_function_unwrapped() const
{
return _favourite_function_unwrapped;
}
//! Accessor.
void favourite_function_unwrapped(bool v);
};
#endif
evolvotron/libevolvotron/mutatable_image_display_big.h 0000644 0001751 0001751 00000004536 13202652325 023410 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class MutatableImageDisplayBig
*/
#ifndef _mutatable_image_display_big_h_
#define _mutatable_image_display_big_h_
#include "common.h"
class EvolvotronMain;
//! Intended to be used as a top-level widget holding a single MutatableImageDisplay
/*! We just used to use a display or scroll view itself as a top-level widget,
but need this to get some specific keyboard effects.
\todo class name is a bit misleading. This is really just a slightly modified top-level holder.
*/
class MutatableImageDisplayBig : public QWidget
{
Q_OBJECT
protected:
//! Pointer back to the application object to access fullscreen state
EvolvotronMain* _main;
public:
//! Constructor.
MutatableImageDisplayBig(EvolvotronMain* mn);
//! Destructor.
virtual ~MutatableImageDisplayBig();
//! Accessor.
EvolvotronMain* main() const
{
assert(_main!=0);
return _main;
}
protected:
//! Handle key-presses
void keyPressEvent(QKeyEvent* e);
};
#endif
evolvotron/libevolvotron/platform_specific.h 0000644 0001751 0001751 00000003723 13202652325 021410 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Try to isolate platform specific code here (or rather, in the .cpp implementations)
*/
#ifndef _platform_specific_h_
#define _platform_specific_h_
#include "../libfunction/useful.h"
// qt3 for Darwin appears to define this, so use it to definitely select the PLATFORM_BSD option
#ifdef __DARWIN_X11__
#define PLATFORM_BSD
#undef PLATFORM_LINUX
#endif
//! Return the number of processors on the system
extern uint get_number_of_processors();
//! Lower the priority of the calling thread by increasing its "niceness" (unix 0-19 'nice' scale used)
extern void add_thread_niceness(uint);
#endif
evolvotron/libevolvotron/mutatable_image_computer_task.h 0000644 0001751 0001751 00000015607 13202652325 024003 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class MutatableImageComputerTask.
*/
#ifndef _mutatable_image_computer_task_h_
#define _mutatable_image_computer_task_h_
#include "common.h"
#include "mutatable_image.h"
#include "mutatable_image_display.h"
//! Class encapsulating all the parameters of, and output from, a single image generation run.
class MutatableImageComputerTask
{
protected:
//! Flag indicating (to compute thread) that this task should be aborted. Also indicates to MutatableImageDisplay that it's a dud and shouldn't be displayed..
/*! \todo Think more about whether this needs to be mutex protected for sanity.
*/
bool _aborted;
//! The display originating the task, and to which the output will be returned.
MutatableImageDisplay*const _display;
//! The root node of the image tree to be generated.
/*! Constness of the MutatableImage referenced is important as the instance is shared between all tasks and the original display.
*/
const boost::shared_ptr _image_function;
//! Task priority.
/*! Low numbers go to the head of the queue.
The total number of samples in the complete (non-fragmented) image is used,
so small low resolution images which can be quickly completed are run first.
*/
const uint _priority;
//! The origin (on the display) of the image being generated.
const QSize _fragment_origin;
//! The size of the image to be generated.
const QSize _fragment_size;
//! The full size of the image of which this is a fragment.
const QSize _whole_image_size;
//! Number of animation frames to be rendered
const uint _frames;
//! The resolution level of this image (0=1-for-1 pixels, 1=half res etc)
/*! This is tracked because multiple compute threads could return the completed tasks out of order
(Unlikely given the huge difference in the amount of compute between levels, but possible).
*/
const uint _level;
//! The fragment number, used when a rendering job is split into multiple fragments.
const uint _fragment;
//! The number of fragments in the rendering job
const uint _number_of_fragments;
//! Whether samples should be jittered.
const bool _jittered_samples;
//! Multisampling grid resolution e.g 4 implies a 4x4 grid
const uint _multisample_grid;
//@{
//! Track pixels computed, so tasks can be restarted after defer. Row and column are relative to the fragment origin.
uint _current_pixel;
int _current_col;
int _current_row;
uint _current_frame;
//@}
//! The image data generated for the fragments.
/*! This is lazily created to avoid multiple high resolution
images (especially with multisampling) being unnecessarily
concurrently allocated.
*/
mutable std::vector _images;
//! Lazy allocator for _images (which is mutable)
void allocate_images() const;
//! Set true by pixel_advance when it advances off the last frame.
bool _completed;
//! Serial number, to fix some occasional out-of-order display problems
unsigned long long int _serial;
public:
//! Constructor.
MutatableImageComputerTask
(
MutatableImageDisplay*const disp,
const boost::shared_ptr& fn,
uint pri,
const QSize& fo,
const QSize& fs,
const QSize& wis,
uint f,
uint lev,
uint frag,
uint nfrag,
bool j,
uint ms,
unsigned long long int n
);
//! Destructor.
~MutatableImageComputerTask();
//! Accessor.
bool aborted() const
{
return _aborted;
}
//! Mark task as aborted.
void abort()
{
_aborted=true;
}
//! Accessor.
MutatableImageDisplay* display() const
{
return _display;
}
//! Accessor.
const boost::shared_ptr& image_function() const
{
return _image_function;
}
//! Accessor.
const QSize& fragment_origin() const
{
return _fragment_origin;
}
//! Accessor.
const QSize& fragment_size() const
{
return _fragment_size;
}
//! Accessor.
const QSize& whole_image_size() const
{
return _whole_image_size;
}
//! Accessor.
uint frames() const
{
return _frames;
}
//! Accessor.
uint level() const
{
return _level;
}
//! Accessor.
uint fragment() const
{
return _fragment;
}
//! Accessor.
uint number_of_fragments() const
{
return _number_of_fragments;
}
//! Accessor.
bool jittered_samples() const
{
return _jittered_samples;
}
//! Accessor.
uint multisample_grid() const
{
return _multisample_grid;
}
//! Serial number
unsigned long long int serial() const
{
return _serial;
}
//! Accessor.
uint priority() const
{
return _priority;
}
//! Accessor, with lazy creation.
std::vector& images()
{
if (_images.empty()) allocate_images();
return _images;
}
//! Accessor.
const std::vector& images() const
{
if (_images.empty()) allocate_images();
return _images;
}
//! Accessor.
uint current_col() const
{
return _current_col;
}
//! Accessor.
uint current_row() const
{
return _current_row;
}
//! Accessor.
uint current_frame() const
{
return _current_frame;
}
//! Accessor.
uint current_pixel() const
{
return _current_pixel;
}
//!Accessor.
bool completed() const
{
return _completed;
}
//! Increment pixel count, set completed flag if advanced off end of last frame.
void pixel_advance();
};
#endif
evolvotron/libfunction/function_transform.h 0000644 0001751 0001751 00000004162 13202652325 021245 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function class.
*/
#ifndef _function_transform_h_
#define _function_transform_h_
#include "common.h"
#include "function_boilerplate.h"
#include "transform.h"
//------------------------------------------------------------------------------------------
//! Function class returning position transfomed by a 12-component linear transform.
FUNCTION_BEGIN(FunctionTransform,12,0,false,FnCore)
//! Return the transformed position argument.
virtual const XYZ evaluate(const XYZ& p) const
{
const Transform transform(params());
return transform.transformed(p);
}
FUNCTION_END(FunctionTransform)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/functions_friezegroup_sidle.h 0000644 0001751 0001751 00000004576 13202652325 023147 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
*/
#ifndef _functions_friezegroup_sidle_h_
#define _functions_friezegroup_sidle_h_
#include "common.h"
#include "function_boilerplate.h"
#include "friezegroup.h"
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupSidleFreeZ,0,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Sidle(1.0),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupSidleFreeZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupSidleClampZ,1,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Sidle(1.0),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupSidleClampZ)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/xy.h 0000644 0001751 0001751 00000011554 13202652325 015770 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class XY.
*/
#ifndef _xy_h_
#define _xy_h_
#include "common.h"
//! Class to hold vectors in 2D cartesian co-ordinates.
/*! Direct access to the x,y members is not permitted.
*/
class XY
{
protected:
boost::array _rep;
public:
//@{
//! Accessor.
real x() const
{
return _rep[0];
}
real y() const
{
return _rep[1];
}
void x(real v)
{
_rep[0]=v;
}
void y(real v)
{
_rep[1]=v;
}
//@}
//! Null constructor.
/*! NB The components are not cleared to zero.
*/
XY()
{}
//! Copy constructor.
XY(const XY& v)
{
_rep[0]=v._rep[0];
_rep[1]=v._rep[1];
}
//! Initialise from separate components.
XY(real vx,real vy)
{
_rep[0]=vx;
_rep[1]=vy;
}
//! Trivial destructor.
~XY()
{}
//! Subtract a vector
void operator-=(const XY& v)
{
_rep[0]-=v._rep[0];
_rep[1]-=v._rep[1];
}
//! Add a vector
void operator+=(const XY& v)
{
_rep[0]+=v._rep[0];
_rep[1]+=v._rep[1];
}
//! Multiply by scalar
void operator*=(real k)
{
_rep[0]*=k;
_rep[1]*=k;
}
//! Divide by scalar.
/*! Implemented assuming one divide and two multiplies is faster than two divides.
*/
void operator/=(real k)
{
const real ik(1.0/k);
(*this)*=ik;
}
//! Assignment.
void assign(const XY& v)
{
x(v.x());
y(v.y());
}
//! Negation.
const XY operator-() const
{
return XY(-x(),-y());
}
//! Return the square of the magnitude.
real magnitude2() const
{
return x()*x()+y()*y();
}
//! Return the magnitude.
real magnitude() const
{
return sqrt(magnitude2());
}
//! Returns sum of x and y components.
real sum_of_components() const
{
return x()+y();
}
//! Return the vector normalised.
const XY normalised() const;
//! Normalise this vector.
void normalise();
//! Returns true if an origin centred rectangle with this vectors' semi-axes contains the argument.
bool origin_centred_rect_contains(const XY& p) const
{
return (-x()<=p.x() && p.x()<=x() && -y()<=p.y() && p.y()<=y());
}
//! Write the vector.
std::ostream& write(std::ostream&) const;
//! Helper for common case of creating an instance filled with a common value.
static const XY fill(real v)
{
return XY(v,v);
}
};
//! Dot product.
/*! Perhaps a curious choice of operator but it works for me.
*/
inline real operator%(const XY& a,const XY& b)
{
return a.x()*b.x()+a.y()*b.y();
}
//! Vector addition.
inline const XY operator+(const XY& a,const XY& b)
{
return XY(a.x()+b.x(),a.y()+b.y());
}
//! Vector subtraction.
inline const XY operator-(const XY& a,const XY& b)
{
return XY(a.x()-b.x(),a.y()-b.y());
}
//! Multiplication by scalar.
inline const XY operator*(real k,const XY& v)
{
XY ret(v);
ret*=k;
return ret;
}
//! Multiplication by scalar.
inline const XY operator*(const XY& v,real k)
{
XY ret(v);
ret*=k;
return ret;
}
//! Division by scalar.
inline const XY operator/(const XY& v,real k)
{
return v*(1.0/k);
}
/*! If magnitude is zero we return zero vector.
*/
inline const XY XY::normalised() const
{
const real m=magnitude();
return (m==0.0 ? XY(0.0,0.0) : (*this)/m);
}
inline void XY::normalise()
{
(*this)=normalised();
}
//! Stream output operator.
/*! Calls write().
*/
inline std::ostream& operator<<(std::ostream& out,const XY& v)
{
return v.write(out);
}
#endif
evolvotron/libfunction/transform.h 0000644 0001751 0001751 00000012363 13202652325 017342 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class Transform.
*/
#ifndef _transform_h_
#define _transform_h_
#include "common.h"
#include "xyz.h"
//! Class representing 3d linear transforms.
/*! Not much functionality currently because is used mainly to pass info around for warp functionality
*/
class Transform
{
public:
//! Default constructor. NB Doesn't set up identity or anything.
Transform();
//! Copy constructor.
Transform(const Transform&);
//! Constructor specifying column vectors.
Transform(const XYZ& t,const XYZ& x,const XYZ& y,const XYZ& z);
//! Constructor specifying column-wise elements.
Transform(const std::vector& v,uint starting_element=0);
//! virtual destructor in case of extension
virtual ~Transform();
//@{
//! Accessor
const XYZ& translate() const
{
return _translate;
}
const XYZ& basis_x() const
{
return _basis_x;
}
const XYZ& basis_y() const
{
return _basis_y;
}
const XYZ& basis_z() const
{
return _basis_z;
}
void translate(const XYZ &t)
{
_translate=t;
}
void basis_x(const XYZ &x)
{
_basis_x=x;
}
void basis_y(const XYZ &y)
{
_basis_y=y;
}
void basis_z(const XYZ &z)
{
_basis_z=z;
}
//@}
//! Get column-wise element values as a vector
const std::vector get_columns() const;
//! Transform a point
const XYZ transformed(const XYZ& p) const;
//! Transform a point with no translation
const XYZ transformed_no_translate(const XYZ& p) const;
//! Concatenate transforms
Transform& concatenate_on_right(const Transform& t);
//! Concatenate transforms
Transform& concatenate_on_left(const Transform& t);
protected:
//@{
//! Translation component (column vector in matrix).
XYZ _translate;
XYZ _basis_x;
XYZ _basis_y;
XYZ _basis_z;
};
inline const XYZ operator*(const Transform& t,const XYZ& p)
{
return
t.basis_x()*p.x()
+t.basis_y()*p.y()
+t.basis_z()*p.z()
+t.translate();
}
inline std::ostream& operator<<(std::ostream& out,const Transform& t)
{
return out << t.translate() << ";" << t.basis_x() << "," << t.basis_y() << "," << t.basis_z();
}
class TransformIdentity : public Transform
{
public:
TransformIdentity()
{
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ(1.0,0.0,0.0));
basis_y(XYZ(0.0,1.0,0.0));
basis_z(XYZ(0.0,0.0,1.0));
}
};
class TransformTranslate : public Transform
{
public:
TransformTranslate(const XYZ& t)
{
translate(t);
basis_x(XYZ(1.0,0.0,0.0));
basis_y(XYZ(0.0,1.0,0.0));
basis_z(XYZ(0.0,0.0,1.0));
}
};
class TransformScale : public Transform
{
public:
TransformScale(const XYZ& s)
{
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ(s.x(),0.0,0.0));
basis_y(XYZ(0.0,s.y(),0.0));
basis_z(XYZ(0.0,0.0,s.z()));
}
TransformScale(real s)
{
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ(s,0.0,0.0));
basis_y(XYZ(0.0,s,0.0));
basis_z(XYZ(0.0,0.0,s));
}
};
class TransformRotateX : public Transform
{
public:
TransformRotateX(real a)
{
const real sa=sin(a);
const real ca=cos(a);
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ(1.0,0.0,0.0));
basis_y(XYZ(0.0, ca , sa ));
basis_z(XYZ(0.0,-sa , ca ));
}
};
class TransformRotateY : public Transform
{
public:
TransformRotateY(real a)
{
const real sa=sin(a);
const real ca=cos(a);
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ( ca ,0.0,-sa ));
basis_y(XYZ(0.0,1.0,0.0));
basis_z(XYZ( sa ,0.0, ca ));
}
};
class TransformRotateZ : public Transform
{
public:
TransformRotateZ(real a)
{
const real sa=sin(a);
const real ca=cos(a);
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ( ca , sa ,0.0));
basis_y(XYZ(-sa , ca ,0.0));
basis_z(XYZ(0.0,0.0,1.0));
}
};
#endif
evolvotron/libfunction/functions_choose.h 0000644 0001751 0001751 00000025026 13202652325 020677 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
As much as possible of the implementation should be pushed into the FunctionBoilerplate template.
*/
#ifndef _functions_choose_h_
#define _functions_choose_h_
#include "common.h"
#include "function_boilerplate.h"
#include "hex.h"
//------------------------------------------------------------------------------------------
// Strip of one function across another
FUNCTION_BEGIN(FunctionChooseStrip,3,3,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
if (fabs(p.y()) > fabs(arg(2)(p)%XYZ(param(0),param(1),param(2)))) return arg(1)(p);
else return arg(0)(p);
}
FUNCTION_END(FunctionChooseStrip)
//------------------------------------------------------------------------------------------
// Strip of one function across another
FUNCTION_BEGIN(FunctionChooseStripBlend,6,4,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const real r0=fabs(arg(2)(p)%XYZ(param(0),param(1),param(2)));
const real r1=fabs(arg(3)(p)%XYZ(param(3),param(4),param(5)));
const real inner=std::min(r0,r1);
const real outer=std::max(r0,r1);
const real ay=fabs(p.y());
if (ay<=inner) return arg(0)(p);
if (ay>=outer) return arg(1)(p);
const XYZ v0(arg(0)(p));
const XYZ v1(arg(1)(p));
return v0+(v1-v0)*(ay-inner)/(outer-inner);
}
FUNCTION_END(FunctionChooseStripBlend)
//------------------------------------------------------------------------------------------
//! Function implements selection between 2 functions based on the relative magnitudes of 2 other functions
FUNCTION_BEGIN(FunctionChooseSphere,0,4,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
if ((arg(0)(p)).magnitude2()<(arg(1)(p)).magnitude2())
return arg(2)(p);
else
return arg(3)(p);
}
FUNCTION_END(FunctionChooseSphere)
//------------------------------------------------------------------------------------------
//! Function implements selection between 2 functions based on whether a rectangle contains a point
FUNCTION_BEGIN(FunctionChooseRect,0,4,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ p0(arg(0)(p));
const XYZ p1(arg(1)(p));
if (p1.origin_centred_rect_contains(p0))
return arg(2)(p);
else
return arg(3)(p);
}
FUNCTION_END(FunctionChooseRect)
//------------------------------------------------------------------------------------------
//! Function implements selection between 2 functions based on position in 3d mesh
FUNCTION_BEGIN(FunctionChooseFrom2InCubeMesh,0,2,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const int x=static_cast(floorf(p.x()));
const int y=static_cast(floorf(p.y()));
const int z=static_cast(floorf(p.z()));
if ((x+y+z)&1)
return arg(0)(p);
else
return arg(1)(p);
}
FUNCTION_END(FunctionChooseFrom2InCubeMesh);
//------------------------------------------------------------------------------------------
//! Function implements selection between 2 functions based on position in 3d mesh
FUNCTION_BEGIN(FunctionChooseFrom3InCubeMesh,0,3,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const int x=static_cast(floorf(p.x()));
const int y=static_cast(floorf(p.y()));
const int z=static_cast(floorf(p.z()));
return arg(modulusi(x+y+z,3))(p);
}
FUNCTION_END(FunctionChooseFrom3InCubeMesh)
//------------------------------------------------------------------------------------------
//! Function implements selection between 2 functions based on position in 2d grid
FUNCTION_BEGIN(FunctionChooseFrom2InSquareGrid,0,2,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const int x=static_cast(floorf(p.x()));
const int y=static_cast(floorf(p.y()));
if ((x+y)&1)
return arg(0)(p);
else
return arg(1)(p);
}
FUNCTION_END(FunctionChooseFrom2InSquareGrid)
//------------------------------------------------------------------------------------------
//! Function implements selection between 3 functions based on position in 2d grid
FUNCTION_BEGIN(FunctionChooseFrom3InSquareGrid,0,3,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const int x=static_cast(floorf(p.x()));
const int y=static_cast(floorf(p.y()));
return arg(modulusi(x+y,3))(p);
}
FUNCTION_END(FunctionChooseFrom3InSquareGrid)
//------------------------------------------------------------------------------------------
//! Function implements selection between 2 functions based on position in grid of triangles
FUNCTION_BEGIN(FunctionChooseFrom2InTriangleGrid,0,2,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
static const XYZ d0(1.0 ,0.0 ,0.0);
static const XYZ d1(cos( M_PI/3),sin( M_PI/3),0.0);
static const XYZ d2(cos(2*M_PI/3),sin(2*M_PI/3),0.0);
const int a=static_cast(floorf(p%d0));
const int b=static_cast(floorf(p%d1));
const int c=static_cast(floorf(p%d2));
if ((a+b+c)&1)
return arg(0)(p);
else
return arg(1)(p);
}
FUNCTION_END(FunctionChooseFrom2InTriangleGrid)
//------------------------------------------------------------------------------------------
//! Function implements selection between 2 functions based on position in grid of triangles
/*! Not entirely sure this one produces a sensible pattern. Needs explicitly testing.
*/
FUNCTION_BEGIN(FunctionChooseFrom3InTriangleGrid,0,3,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
static const XYZ d0(1.0 ,0.0 ,0.0);
static const XYZ d1(cos( M_PI/3),sin( M_PI/3),0.0);
static const XYZ d2(cos(2*M_PI/3),sin(2*M_PI/3),0.0);
const int a=static_cast(floorf(p%d0));
const int b=static_cast(floorf(p%d1));
const int c=static_cast(floorf(p%d2));
return arg(modulusi(a+b+c,3))(p);
}
FUNCTION_END(FunctionChooseFrom3InTriangleGrid)
//------------------------------------------------------------------------------------------
//! Function implements selection between 3 functions based on position in grid of hexagons
/*! Don't entirely understand how this works, but it looks nice.
*/
FUNCTION_BEGIN(FunctionChooseFrom3InDiamondGrid,0,3,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
// Basis vectors for hex grid
static const XYZ d0(1.0 ,0.0 ,0.0);
static const XYZ d1(cos( M_PI/3),sin( M_PI/3),0.0);
static const XYZ d2(cos(2*M_PI/3),sin(2*M_PI/3),0.0);
// Dot with basis
const real p0=p%d0;
const real p1=p%d1;
const real p2=p%d2;
// Find nearest on-grid point
const int i0=(int)floorf(p0+0.5);
const int i1=(int)floorf(p1+0.5);
const int i2=(int)floorf(p2+0.5);
// Measure distance
const real m0=fabsf(p0-i0);
const real m1=fabsf(p1-i1);
const real m2=fabsf(p2-i2);
// Closest one decides which function
if (m0<=m1 && m0<=m2)
return arg(0)(p);
else if (m1<=m0 && m1<=m2)
return arg(1)(p);
else
return arg(2)(p);
}
FUNCTION_END(FunctionChooseFrom3InDiamondGrid)
//------------------------------------------------------------------------------------------
//! Function implements selection between 3 functions based on position in grid of hexagons
FUNCTION_BEGIN(FunctionChooseFrom3InHexagonGrid,0,3,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const std::pair h=nearest_hex(p.x(),p.y());
const uint which=h.second+((h.first&1)? 2 : 0);
return arg(modulusi(which,3))(p);
}
FUNCTION_END(FunctionChooseFrom3InHexagonGrid)
//------------------------------------------------------------------------------------------
//! Function implements selection between 2 functions based on position in grid of hexagons
FUNCTION_BEGIN(FunctionChooseFrom2InBorderedHexagonGrid,1,2,false,FnStructure)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const std::pair h=nearest_hex(p.x(),p.y());
bool in_border=false;
// Hex centres are separated by 1.0 so limit border size
const real b=modulusf(param(0),0.5);
// Step along grid co-ordinates in various directions. If there's a nearer point, we're in the border.
for (uint i=0;i<6;i++)
{
const real dx=b*sin(i*M_PI/3.0);
const real dy=b*cos(i*M_PI/3.0);
const std::pair a=nearest_hex(p.x()+dx,p.y()+dy);
if (h!=a)
{
in_border=true;
break;
}
}
return arg(in_border)(p);
}
FUNCTION_END(FunctionChooseFrom2InBorderedHexagonGrid)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/functions_spherical.h 0000644 0001751 0001751 00000007432 13202652325 021372 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
As much as possible of the implementation should be pushed into the FunctionBoilerplate template.
*/
#ifndef _functions_spherical_h_
#define _functions_spherical_h_
#include "common.h"
#include "function_boilerplate.h"
//------------------------------------------------------
//! Transforms cartesian coordinates to spherical
FUNCTION_BEGIN(FunctionCartesianToSpherical,0,0,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const real r=p.magnitude();
// Angles are normalised (-1 to +1) over their usual possible range.
const real theta=atan2(p.y(),p.x())*(1.0/M_PI);
const real phi=(r== 0.0 ? 0.0 : asin(p.z()/r)*(1.0/(0.5*M_PI)));
return XYZ(r,theta,phi);
}
FUNCTION_END(FunctionCartesianToSpherical)
//------------------------------------------------------------------------------------------
//! Transforms spherical coordinates to cartesian
FUNCTION_BEGIN(FunctionSphericalToCartesian,0,0,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const real r=p.x();
const real theta=M_PI*p.y();
const real phi=0.5*M_PI*p.z();
const real x=r*cos(theta)*sin(phi);
const real y=r*sin(theta)*sin(phi);
const real z=r*cos(phi);
return XYZ(x,y,z);
}
FUNCTION_END(FunctionSphericalToCartesian)
//------------------------------------------------------------------------------------------
// Converts the position argument to spherical coords, pass these through the leaf node, and convert the result back to cartesian.
FUNCTION_BEGIN(FunctionEvaluateInSpherical,0,1,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const real in_r=p.magnitude();
const real in_theta=atan2(p.y(),p.x())*(1.0/M_PI);
const real in_phi=(in_r== 0.0 ? 0.0 : asin(p.z()/in_r)*(1.0/(0.5*M_PI)));
const XYZ v(arg(0)(XYZ(in_r,in_theta,in_phi)));
const real out_r=v.x();
const real out_theta=M_PI*v.y();
const real out_phi=0.5*M_PI*v.z();
const real x=out_r*cos(out_theta)*sin(out_phi);
const real y=out_r*sin(out_theta)*sin(out_phi);
const real z=out_r*cos(out_phi);
return XYZ(x,y,z);
}
FUNCTION_END(FunctionEvaluateInSpherical)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/function_identity.h 0000644 0001751 0001751 00000004106 13202652325 021061 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for certain core Function classes.
Split out from functions.h as included in mutation_parameters.cpp
*/
#ifndef _function_identity_h_
#define _function_identity_h_
#include "common.h"
#include "function_boilerplate.h"
//------------------------------------------------------------------------------------------
//! Function class simply returning the position argument.
FUNCTION_BEGIN(FunctionIdentity,0,0,false,FnCore)
//! Simply return the position argument.
virtual const XYZ evaluate(const XYZ& p) const
{
return p;
}
FUNCTION_END(FunctionIdentity)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/functions_geometry.h 0000644 0001751 0001751 00000006447 13202652325 021260 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
As much as possible of the implementation should be pushed into the FunctionBoilerplate template.
*/
#ifndef _functions_geometry_h_
#define _functions_geometry_h_
#include "common.h"
#include "function_boilerplate.h"
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionCross,0,2,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ v0(arg(0)(p));
const XYZ v1(arg(1)(p));
return v0*v1;
}
FUNCTION_END(FunctionCross)
//------------------------------------------------------------------------------------------
//! Invert the leaf function using a radius-one origin centred sphere.
FUNCTION_BEGIN(FunctionGeometricInversion,0,1,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const real radius2=p.magnitude2();
const XYZ ip(p/radius2);
return arg(0)(ip);
}
FUNCTION_END(FunctionGeometricInversion)
//------------------------------------------------------------------------------------------
//! Implements reflection of sampling point about a plane
FUNCTION_BEGIN(FunctionReflect,0,3,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ pt_in_plane(arg(0)(p));
const XYZ normal(arg(1)(p).normalised());
XYZ pos(arg(2)(p));
const real distance_from_plane=(pos-pt_in_plane)%normal;
// If pos is on the wrong side of the plane, reflect it over
// Check: normal (0,0,1), pos (0,0,-1) => distance -1, pos-=(2*-1)*(0,0,1) => pos-=(0,0,-2)
if (distance_from_plane<0.0)
{
pos-=(2.0*distance_from_plane)*normal;
}
return pos;
}
FUNCTION_END(FunctionReflect)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/functions_tartan.h 0000644 0001751 0001751 00000012674 13202652325 020715 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Functions inspired by tartan patterns.
*/
#ifndef _functions_tartan_h_
#define _functions_tartan_h_
#include "common.h"
#include "function_boilerplate.h"
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanSelectFree,10,6,false,FnStructure)
//! Evaluate function.
/*! Sign of one 1D function's dot product determines one bit, ditto for another bit.
2 bits used to select from 4 possibilities.
There's no guarantee of a repetitive pattern unless the generator functions are.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ p0(p.x(),param(0),param(1));
const XYZ p1(param(2),p.y(),param(3));
const XYZ d0(param(4),param(5),param(6));
const XYZ d1(param(7),param(8),param(9));
const int b0=(arg(0)(p0)%XYZ(d0)>0.0);
const int b1=(arg(1)(p1)%XYZ(d1)>0.0);
const int which=2+b0+2*b1;
assert(2<=which && which<6);
return arg(which)(p);
}
FUNCTION_END(FunctionTartanSelectFree)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanSelect,14,6,false,FnStructure)
//! Evaluate function.
/*! Similar to function free except the generators repeat.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const real x=(param(0)>0.0 ? modulusf(p.x(),param(1)) : trianglef(p.x(),param(1)));
const real y=(param(2)>0.0 ? modulusf(p.y(),param(3)) : trianglef(p.y(),param(3)));
const XYZ p0(x,param(4),param(5));
const XYZ p1(param(6),y,param(7));
const XYZ d0(param(8),param(9),param(10));
const XYZ d1(param(11),param(12),param(13));
const int b0=(arg(0)(p0)%XYZ(d0)>0.0);
const int b1=(arg(1)(p1)%XYZ(d1)>0.0);
const int which=2+b0+2*b1;
assert(2<=which && which<6);
return arg(which)(p);
}
FUNCTION_END(FunctionTartanSelect)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanSelectRepeat,14,6,false,FnStructure)
//! Evaluate function.
/*! Similar to above function except the invoked functions repeat too.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const real x=(param(0)>0.0 ? modulusf(p.x(),param(1)) : trianglef(p.x(),param(1)));
const real y=(param(2)>0.0 ? modulusf(p.y(),param(3)) : trianglef(p.y(),param(3)));
const XYZ p0(x,param(4),param(5));
const XYZ p1(param(6),y,param(7));
const XYZ d0(param(8),param(9),param(10));
const XYZ d1(param(11),param(12),param(13));
const int b0=(arg(0)(p0)%XYZ(d0)>0.0);
const int b1=(arg(1)(p1)%XYZ(d1)>0.0);
const int which=2+b0+2*b1;
assert(2<=which && which<6);
return arg(which)(XYZ(x,y,p.z()));
}
FUNCTION_END(FunctionTartanSelectRepeat)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanMixFree,4,2,false,0)
//! Evaluate function.
/*! As above, but mix 2 functions.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ p0(p.x(),param(0),param(1));
const XYZ p1(param(2),p.y(),param(3));
const XYZ warp(arg(0)(p0));
const XYZ weft(arg(1)(p1));
return 0.5*(warp+weft);
}
FUNCTION_END(FunctionTartanMixFree)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanMixRepeat,8,2,false,0)
//! Evaluate function.
/*! As above, but mix 2 functions.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const real x=(param(0)>0.0 ? modulusf(p.x(),param(1)) : trianglef(p.x(),param(1)));
const real y=(param(2)>0.0 ? modulusf(p.y(),param(3)) : trianglef(p.y(),param(3)));
const XYZ p0(x,param(4),param(5));
const XYZ p1(param(6),y,param(7));
const XYZ warp(arg(0)(p0));
const XYZ weft(arg(1)(p1));
return 0.5*(warp+weft);
}
FUNCTION_END(FunctionTartanMixRepeat)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/common.h 0000644 0001751 0001751 00000002775 13202652325 016625 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Common headers for libfunction
*/
#ifndef _libfunction_common_h_
#define _libfunction_common_h_
#include "useful.h"
#endif
evolvotron/libfunction/functions_friezegroup_hop.h 0000644 0001751 0001751 00000007545 13202652325 022634 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
*/
#ifndef _functions_friezegroup_hop_h_
#define _functions_friezegroup_hop_h_
#include "common.h"
#include "function_boilerplate.h"
#include "friezegroup.h"
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupHopFreeZ,0,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Hop(1.0),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupHopFreeZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupHopClampZ,1,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Hop(1.0),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupHopClampZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupHopBlendClampZ,1,2,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupBlend(arg(0),arg(1),p,HopBlend(1.0),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupHopBlendClampZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupHopBlendFreeZ,0,2,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupBlend(arg(0),arg(1),p,HopBlend(1.0),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupHopBlendFreeZ)
//------------------------------------------------------------------------------------------
/*
FUNCTION_BEGIN(FunctionFriezeGroupHopCutClampZ,2,2,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
const int d=FriezegroupCut(arg(1),p,HopCut(1.0),ClampZ(param(1)));
return FriezegroupEvaluate(arg(0),p,Hop(1.0,d),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupHopCutClampZ)
*/
//------------------------------------------------------------------------------------------
/*
FUNCTION_BEGIN(FunctionFriezeGroupHopCutFreeZ,0,2,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
const int d=FriezegroupCut(arg(1),p,HopCut(1.0),FreeZ());
return FriezegroupEvaluate(arg(0),p,Hop(1.0,d),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupHopCutFreeZ)
*/
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/useful.h 0000644 0001751 0001751 00000011654 13202652325 016634 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 3 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief File containing all the author's favourite little helpers.
*/
#ifndef _useful_h_
#define _useful_h_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include