Add support for variations.

--HG--
rename : cuburn/variations.py => cuburn/code/variations.py
This commit is contained in:
Steven Robertson 2011-05-01 09:36:29 -04:00
parent 088299423e
commit a7900f187d
6 changed files with 69 additions and 50 deletions

View File

@ -7,7 +7,7 @@ from pycuda.driver import In, Out, InOut
from pycuda.compiler import SourceModule
import numpy as np
from cuburn.code import mwc
from cuburn.code import mwc, variations
from cuburn.code.util import *
import tempita
@ -32,10 +32,18 @@ void apply_xf{{xfid}}(float *ix, float *iy, float *icolor,
float tx, ty, ox = *ix, oy = *iy;
{{apply_affine('ox', 'oy', 'tx', 'ty', px, 'xf.c', 'pre')}}
// tiny little TODO: variations
ox = 0;
oy = 0;
*ix = tx;
*iy = ty;
{{for v in xform.vars}}
if (1) {
float w = {{px.get('xf.var[%d]' % v)}};
{{variations.var_code[variations.var_nos[v]]()}}
}
{{endfor}}
*ix = ox;
*iy = oy;
float csp = {{px.get('xf.color_speed')}};
*icolor = *icolor * (1.0f - csp) + {{px.get('xf.color')}} * csp;
@ -64,7 +72,7 @@ void iter(mwc_st *msts, const iter_info *infos, float *accbuf, float *denbuf) {
float xfsel = mwc_next_01(&rctx);
{{for xfid, xform in enumerate(features.xforms)}}
if (xfsel < {{packer.get('cp.norm_density[%d]' % xfid)}}) {
if (xfsel <= {{packer.get('cp.norm_density[%d]' % xfid)}}) {
apply_xf{{xfid}}(&x, &y, &color, info);
} else
{{endfor}}
@ -78,9 +86,9 @@ void iter(mwc_st *msts, const iter_info *infos, float *accbuf, float *denbuf) {
continue;
}
if (x <= -1.0f || x >= 1.0f || y <= -1.0f || y >= 1.0f
|| consec_bad < 0) {
nsamps--;
if (x <= -1.0f || x >= 1.0f || y <= -1.0f || y >= 1.0f) {
consec_bad++;
if (consec_bad > {{features.max_oob}}) {
x = mwc_next_11(&rctx);
@ -92,8 +100,8 @@ void iter(mwc_st *msts, const iter_info *infos, float *accbuf, float *denbuf) {
}
// TODO: dither?
int i = ((int)((y + 1.0f) * 256.0f) * 512)
+ (int)((x + 1.0f) * 256.0f);
int i = ((int)((y + 1.0f) * 255.0f) * 512)
+ (int)((x + 1.0f) * 255.0f);
accbuf[i*4] += color < 0.5f ? (1.0f - 2.0f * color) : 0.0f;
accbuf[i*4+1] += 1.0f - 2.0f * fabsf(0.5f - color);
accbuf[i*4+2] += color > 0.5f ? color * 2.0f - 1.0f : 0.0f;
@ -101,7 +109,6 @@ void iter(mwc_st *msts, const iter_info *infos, float *accbuf, float *denbuf) {
denbuf[i] += 1.0f;
nsamps--;
}
}
""")
@ -118,7 +125,7 @@ def silly(features, cp):
iter = IterCode(features)
code = assemble_code(BaseCode, mwc.MWC, iter, iter.packer)
print code
mod = SourceModule(code)
mod = SourceModule(code, options=['-use_fast_math'], keep=True)
info = iter.packer.pack(cp=cp)
print info

View File

@ -3,7 +3,6 @@ The multiply-with-carry random number generator.
"""
import numpy as np
import tempita
from cuburn.code.util import *

40
cuburn/code/variations.py Normal file
View File

@ -0,0 +1,40 @@
var_nos = {}
var_code = {}
def _var(num, name = None):
def _var1(func):
if name:
namelo = name
else:
namelo = func.__name__
var_nos[num] = namelo
var_code[namelo] = func
return _var1
# Variables note: all functions will have their weights as 'w',
# input variables 'tx' and 'ty', and output 'ox' and 'oy' available
# from the calling context. Each statement will be placed inside brackets,
# to avoid namespace pollution.
@_var(0)
def linear():
return """
ox += tx * w;
oy += ty * w;
"""
@_var(1)
def sinusoidal():
return """
ox += w * sin(tx);
oy += w * sin(ty);
"""
@_var(2)
def spherical():
return """
float r2 = w / (tx*tx + ty*ty);
ox += tx * r2;
oy += ty * r2;
"""

View File

@ -219,12 +219,11 @@ class Features(object):
self.non_box_temporal_filter = genomes[0].temporal_filter_type
self.palette_mode = genomes[0].palette_mode and "linear" or "nearest"
xforms = [XForm.parse(cp) for cp in genomes]
assert len(xforms[0]) == len(xforms[-1]), ("genomes must have same "
"number of xforms! (try running through flam3-genome first)")
self.xforms = [XFormFeatures([x[i] for x in xforms], i)
for i in range(len(xforms[0]))]
self.nxforms = len(self.xforms)
assert len(set([len(cp.xforms) for cp in genomes])) == 1, ("genomes "
"must have same number of xforms! (use flam3-genome first)")
self.nxforms = len(genomes[0].xforms)
self.xforms = [XFormFeatures([cp.xforms[i] for cp in genomes], i)
for i in range(self.nxforms)]
if any(lambda cp: cp.final_xform_enable):
raise NotImplementedError("Final xform")
@ -242,8 +241,10 @@ class XFormFeatures(object):
self.id = xform_id
any = lambda l: bool(filter(None, map(l, xforms)))
self.has_post = any(lambda xf: getattr(xf, 'post', None))
self.vars = set([n for x in xforms for n in Variations.names
if getattr(x, n, None)])
self.vars = set()
for x in xforms:
self.vars = (
self.vars.union(set([i for i, v in enumerate(x.var) if v])))
class Camera(object):
"""Viewport and exposure."""

View File

@ -1,28 +0,0 @@
class Variations(object):
"""
You know it.
"""
# TODO: precalc
shortname = "variations"
def __init__(self, features):
self.features = features
names = [ "linear", "sinusoidal", "spherical", "swirl", "horseshoe",
"polar", "handkerchief", "heart", "disc", "spiral", "hyperbolic",
"diamond", "ex", "julia", "bent", "waves", "fisheye", "popcorn",
"exponential", "power", "cosine", "rings", "fan", "blob", "pdj",
"fan2", "rings2", "eyefish", "bubble", "cylinder", "perspective",
"noise", "julian", "juliascope", "blur", "gaussian_blur",
"radial_blur", "pie", "ngon", "curl", "rectangles", "arch", "tangent",
"square", "rays", "blade", "secant2", "twintrian", "cross", "disc2",
"super_shape", "flower", "conic", "parabola", "bent2", "bipolar",
"boarders", "butterfly", "cell", "cpow", "curve", "edisc", "elliptic",
"escher", "foci", "lazysusan", "loonie", "pre_blur", "modulus",
"oscilloscope", "polar2", "popcorn2", "scry", "separation", "split",
"splits", "stripes", "wedge", "wedge_julia", "wedge_sph", "whorl",
"waves2", "exp", "log", "sin", "cos", "tan", "sec", "csc", "cot",
"sinh", "cosh", "tanh", "sech", "csch", "coth", "auger", "flux", ]

View File

@ -45,8 +45,8 @@ def main(args):
bins = np.minimum(bins, 255)
bins = bins.astype(np.uint8)
#if '-g' not in args:
# return
if '-g' not in args:
return
imgbuf = (accum * 255).astype(np.uint8)