GNOME Bugzilla – Bug 389004
Update to gimp-flame, 22 ifs types added (from flame)
Last modified: 2008-04-26 07:21:17 UTC
Hi I've been playing with flame for quite some time, and noticed there were (and are) lots of ifs types (and other options) missing from the gimp flame plugin, so i made a quick patch that implements 22 extra ifs presets (that exist in flame), perhaps is of interest to someone else (specially since there seems to be no progress in libflame, not that i know of at least, i might be wrong...). Anyway, patch follows, best regards. Luis Barrancos diff -uNd gimp-2.2.13/plug-ins/flame_orig/flame.c gimp-2.2.13/plug-ins/flame/flame.c --- gimp-2.2.13/plug-ins/flame_orig/flame.c 2006-12-20 18:39:19.000000000 +0000 +++ gimp-2.2.13/plug-ins/flame/flame.c 2006-12-23 15:30:44.000000000 +0000 @@ -44,7 +44,7 @@ #define SCALE_WIDTH 150 #define PREVIEW_SIZE 150 #define EDIT_PREVIEW_SIZE 85 -#define NMUTANTS 9 +#define NMUTANTS 31 #define BLACK_DRAWABLE (-2) #define GRADIENT_DRAWABLE (-3) @@ -737,6 +737,28 @@ _("Horseshoe"), 4, _("Polar"), 5, _("Bent"), 6, + _("Handkerchief"), 7, + _("Heart"), 8, + _("Disc"), 9, + _("Spiral"), 10, + _("Hyperbolic"), 11, + _("Diamond"), 12, + _("Ex"), 13, + _("Julia"), 14, + _("Waves"), 15, + _("Fisheye"), 16, + _("Popcorn"), 17, + _("Exponential"), 18, + _("Power"), 19, + _("Cosine"), 20, + _("Rings"), 21, + _("Fan"), 22, + _("Eyefish"), 23, + _("Bubble"), 24, + _("Cylinder"), 25, + _("Noise"), 26, + _("Blur"), 27, + _("Gaussian"), 28, NULL); gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), diff -uNd gimp-2.2.13/plug-ins/flame_orig/libifs.c gimp-2.2.13/plug-ins/flame/libifs.c --- gimp-2.2.13/plug-ins/flame_orig/libifs.c 2006-12-20 18:39:19.000000000 +0000 +++ gimp-2.2.13/plug-ins/flame/libifs.c 2006-12-23 18:53:28.000000000 +0000 @@ -26,8 +26,9 @@ #include "libifs.h" -#define CHOOSE_XFORM_GRAIN 100 +#include "randombit.h" +#define CHOOSE_XFORM_GRAIN 10000 /* * run the function system described by CP forward N generations. @@ -115,6 +116,7 @@ v = vari[2]; if (v > 0.0) { /* complex */ + /* spherical */ double nx, ny; double r2 = tx * tx + ty * ty + 1e-6; nx = tx / r2; @@ -154,6 +156,7 @@ v = vari[5]; if (v > 0.0) { + /* polar */ double nx, ny; if (tx < -EPS || tx > EPS || ty < -EPS || ty > EPS) @@ -178,6 +181,318 @@ p[1] += v * ny; } + v = vari[7]; + if (v > 0.0) { + /* folded handkerchief */ + double theta, r2, nx, ny; + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + r2 = sqrt( tx * tx + ty * ty); + nx = sin(theta + r2) * r2; + ny = cos(theta - r2) * r2; + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[8]; + if (v > 0.0) { + /* heart */ + double theta, r2, nx, ny; + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + r2 = sqrt( tx * tx + ty * ty ); + theta *= r2; + nx = sin(theta) * r2; + ny = cos(theta) * -r2; + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[9]; + if (v > 0.0) { + /* disc */ + double theta, r2, nx, ny; + if ( tx < -EPS || tx > EPS || + ty < - EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + nx = tx * G_PI; + ny = ty * G_PI; + r2 = sqrt( nx * nx * ny * ny ); + p[0] += v * sin(r2) * theta / G_PI; + p[1] += v * cos(r2) * theta / G_PI; + } + + v = vari[10]; + if ( v > 0.0 ) { + /* spiral */ + double theta, r2; + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + r2 = sqrt( tx * tx + ty * ty ) + 1e-6; + p[0] += v * ( cos(theta) + sin(r2)) / r2; + p[1] += v * ( cos(theta) + cos(r2)) / r2; + } + + v = vari[11]; + if (v > 0.0) { + /* hyperbolic */ + double theta, r2; + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + r2 = sqrt( tx * tx + ty * ty) + 1e-6; + p[0] += v * sin(theta) / r2; + p[1] += v * cos(theta) * r2; + } + + v = vari[12]; + if (v > 0.0 ) { + double theta, r2; + /* diamond */ + if ( tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + r2 = sqrt( tx * tx + ty * ty ); + p[0] += v * sin(theta) * cos(r2); + p[1] += v * cos(theta) * sin(r2); + } + + v = vari[13]; + if ( v > 0.0 ) { + /* ex */ + double theta, r2, n0, n1, m0, m1; + if ( tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + r2 = sqrt( tx * tx + ty * ty ); + n0 = sin(theta + r2); + n1 = cos(theta - r2); + m0 = n0 * n0 * n0 * r2; + m1 = n1 * n1 * n1 * r2; + p[0] += v * (m0 + m1); + p[1] += v * (m0 - m1); + } + + v = vari[14]; + if ( v > 0.0) { + double theta, r2, nx, ny; + /* julia */ + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + if (flam3_random_bit()) theta += G_PI; + r2 = pow( tx * tx + ty * ty, 0.25); + nx = r2 * cos(theta); + ny = r2 * sin(theta); + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[15]; + if ( v > 0.0 ) { + /* waves */ + double dx, dy, nx, ny; + dx = coef[2][0]; + dy = coef[2][1]; + nx = tx + coef[1][0] * sin(ty / ((dx*dx)+EPS)); + ny = ty + coef[1][1] * sin(tx / ((dy*dy)+EPS)); + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[16]; + if ( v > 0.0 ) { + /* fisheye */ + double theta, r2, nx, ny; + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + r2 = sqrt( tx * tx + ty * ty ); + r2 = 2 * r2 / (r2 + 1); + nx = r2 * cos(theta); + ny = r2 * sin(theta); + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[17]; + if (v > 0.0) { + /* popcorn */ + double dx, dy, nx, ny; + dx = tan(3*ty); + dy = tan(3*tx); + nx = tx + coef[2][0] * sin(dx); + ny = ty + coef[2][1] * sin(dy); + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[18]; + if (v > 0.0) { + /* exponential */ + double dx, dy, nx, ny; + dx = exp( tx - 1.0); + dy = G_PI * ty; + nx = cos(dy) * dx; + ny = sin(dy) * dx; + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[19]; + if (v > 0.0) { + /* power */ + double theta, r2, tsin, tcos, nx, ny; + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + tsin = sin(theta); + tcos = cos(theta); + r2 = sqrt( tx * tx + ty * ty ); + r2 = pow( r2, tsin); + nx = r2 * tcos;; + ny = r2 * tsin; + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[20]; + if (v > 0.0) { + /* cosine */ + double nx, ny; + nx = cos(tx * G_PI) * cosh(ty); + ny = -sin(tx * G_PI) * sinh(ty); + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[21]; + if (v > 0.0) { + /* rings */ + double theta, r2, dx, nx, ny; + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0; + dx = coef[2][0]; + dx = dx * dx + EPS; + r2 = sqrt( tx * tx + ty * ty ); + r2 = fmod( r2 + dx, 2 * dx) - dx + r2 * (1-dx); + nx = cos(theta) * r2; + ny = sin(theta) * r2; + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[22]; + if (v > 0.0) { + /* fan */ + double theta, r2, dx, dy, dx2, nx, ny; + if (tx < -EPS || tx > EPS || + ty < -EPS || ty > EPS) + theta = atan2( tx, ty ); + else + theta = 0.0; + dx = coef[2][0]; + dy = coef[2][1]; + dx = G_PI * (dx * dx + EPS); + dx2 = dx / 2; + r2 = sqrt( tx * tx + ty * ty ); + theta += (fmod(theta + dy, dx) > dx2) ? -dx2: dx2; + nx = cos(theta) * r2; + ny = sin(theta) * r2; + p[0] += v * nx; + p[1] += v * ny; + } + + v = vari[23]; + if (v > 0.0) { + /* eyefish */ + double r2; + r2 = 2.0 * v / ( sqrt( tx * tx + ty * ty ) + 1.0 ); + p[0] += r2 * tx; + p[1] += r2 * ty; + } + + v = vari[24]; + if (v > 0.0) { + /* bubble */ + double r2; + r2 = v / ( (tx * tx + ty * ty) / 4 + 1 ); + p[0] += r2 * tx; + p[1] += r2 * ty; + } + + v = vari[25]; + if (v > 0.0) { + /* cylinder */ + double nx; + nx = sin(tx); + p[0] += v * nx; + p[1] += v * ty; + } + + v = vari[26]; + if (v > 0.0) { + /* noise */ + double rx, sinr, cosr, nois; + rx = flam3_random01() * 2 * G_PI; + sinr = sin(rx); + cosr = cos(rx); + nois = flam3_random01(); + p[0] += v * nois * tx * cosr; + p[1] += v * nois * ty * sinr; + } + + v = vari[27]; + if (v > 0.0) { + /* blur */ + double rx, sinr, cosr, nois; + rx = flam3_random01() * 2 * G_PI; + sinr = sin(rx); + cosr = cos(rx); + nois = flam3_random01(); + p[0] += v * nois * cosr; + p[1] += v * nois * sinr; + } + + v = vari[28]; + if (v > 0.0) { + /* gaussian */ + double ang, sina, cosa, r2; + ang = flam3_random01() * 2 * G_PI; + sina = sin(ang); + cosa = cos(ang); + r2 = v * ( flam3_random01() + flam3_random01() + flam3_random01() + + flam3_random01() - 2.0 ); + p[0] += r2 * cosa; + p[1] += r2 * sina; + } + /* if fuse over, store it */ if (i >= 0) { points[i][0] = p[0]; diff -uNd gimp-2.2.13/plug-ins/flame_orig/libifs.h gimp-2.2.13/plug-ins/flame/libifs.h --- gimp-2.2.13/plug-ins/flame_orig/libifs.h 2006-12-20 18:39:19.000000000 +0000 +++ gimp-2.2.13/plug-ins/flame/libifs.h 2006-12-23 15:20:16.000000000 +0000 @@ -31,8 +31,8 @@ #define variation_random (-1) -#define NVARS 7 -#define NXFORMS 6 +#define NVARS 29 +#define NXFORMS 12 typedef double point[3]; diff -uNd gimp-2.2.13/plug-ins/flame_orig/randombit.h gimp-2.2.13/plug-ins/flame/randombit.h --- gimp-2.2.13/plug-ins/flame_orig/randombit.h 1970-01-01 01:00:00.000000000 +0100 +++ gimp-2.2.13/plug-ins/flame/randombit.h 2006-12-23 17:13:46.000000000 +0000 @@ -0,0 +1,22 @@ +int flam3_random_bit() { + static int n = 0; + static int l; + if (0 == n) { + l = random(); + n = 20; + } + else { + l = l >> 1; + n--; + } + return l & 1; +} + +double flam3_random01() { + return (random() & 0xfffffff) / (double) 0xfffffff; +} + +double flam3_random11() { + return ((random() & 0xfffffff) - 0x7ffffff) / (double) 0x7ffffff; +} +
Created attachment 78838 [details] [review] Gimp-flame update patch
That's a duplicate of bug #153346, isn't it? We are still waiting for Scott to package libflam3 in a way that makes it usable for the GIMP plug-in. I don't think we want to maintain all this code in our source tree.
Hi Well, it wasn't a duplicate of bug 153346, i only found out about that yesterday, but still, it has some extra ifs presets that weren't in Scott Drave's patch. Just thought it would be a good idea to share the changes, altough i definitively agree that Scott would be the ideal person to deal with all this. In any case, the changes are small and pretty straightforward, and since development on this/libflam3 seems a bit slow, it would keep everyone busy playing with flames. In any case, just thought it would be a good idea to share the changes made. Best regards Luis Barrancos
Let's consider this after 2.4 is out. We are in tentative string freeze now and can't accept this patch for 2.4.
Hi Sure, i understand that perfectly, can't wait for 2.4 myself :) In the mean time, i'll see if i can add some extra ifs types, and extra options, like filtering types, etc... Best regards Luis Barrancos
I also made a patch which is in the duplicated bug #153346, which also adds extra types.. it also wasnt accepted..... so forget it to get the patch accepted I guess :/ I hope there will be a flam3 based version then...
You didn't read the comments in that bug, did you?
I did, .. "The right thing to do is to use libflame and now is the best time to do this." - of course it is! But in the meantime applying my patch, or Luis patch doesn't hurt at all! My patch was there 2004, until now nothing has improved! So adding my patch would've been at least a minor improvement...
It might have been an improvement, or it might have made things worse. There's always a risk in changing code. And in this particular point there is a much better alternative so we decided not to accept the patch. But this discussion doesn't belong here.
Doesn't seem to be much happening on the libflame front, and I don't forecast that to change. I have commited a modified version of the patch for now (rev 25527) 2008-04-26 Martin Nordholts <martinn@svn.gnome.org> * plug-ins/flame/flame.c * plug-ins/flame/libifs.[ch]: Applied modified patch by Luis Barrancos that adds 22 new variations to the flame plugin (bug #389004).