mirror of
https://github.com/stevenrobertson/cuburn.git
synced 2025-02-05 03:30:05 -05:00
Update the genome specs a bit
This commit is contained in:
parent
ee2d571e9d
commit
a4178c60fb
@ -118,7 +118,4 @@ class ColorClip(Filter, ClsMod):
|
||||
filter_map = dict(bilateral=Bilateral, logscale=Logscale, haloclip=HaloClip,
|
||||
colorclip=ColorClip)
|
||||
def create(gprof):
|
||||
# TODO: redesign this (should not have to care about internals of
|
||||
# use.Wrapper in order to find types from TypedList elements)
|
||||
filts = gprof._val.get('filters') or gprof.spec['filters'].defaults
|
||||
return [filter_map[f['type']]() for f in filts]
|
||||
return [filter_map[f]() for f in gprof.filter_order]
|
||||
|
@ -105,9 +105,7 @@ def convert_xforms(flame):
|
||||
xfs.update(make_symm_xforms(float(flame['symmetry']), len(xfs)))
|
||||
return xfs
|
||||
|
||||
split_to_dict = lambda keys: lambda v: dict(zip(keys, map(float, v.split())))
|
||||
pair = split_to_dict('xy')
|
||||
rgb_triple = split_to_dict('rgb')
|
||||
pair = lambda v: dict(zip('xy', map(float, v.split())))
|
||||
|
||||
xform_structure = (
|
||||
('pre_affine', 'coefs', convert_affine),
|
||||
@ -125,22 +123,20 @@ xform_structure = (
|
||||
# (dst, cvt_dict) for properties that are built from multiple source keys.
|
||||
# If a function returns 'None', its key is dropped from the result.
|
||||
flame_structure = (
|
||||
('info.author', 'nick', str),
|
||||
('info.author_url', 'url', lambda s: 'http://' + str(s)),
|
||||
('info.name', 'name', str),
|
||||
('author.name', 'nick', str),
|
||||
('author.url', 'url', lambda s: 'http://' + str(s)),
|
||||
('name', 'name', str),
|
||||
|
||||
('camera.center', 'center', pair),
|
||||
('camera.rotation', 'rotate', float),
|
||||
('camera.dither_width', 'filter', float),
|
||||
('camera.center', 'center', pair),
|
||||
('camera.rotation', 'rotate', float),
|
||||
('camera.dither_width', 'filter', float),
|
||||
('camera.scale',
|
||||
lambda d: float(d['scale']) / float(d['size'].split()[0])),
|
||||
|
||||
('filters.colorclip.gamma', 'filter', float),
|
||||
('filters.colorclip.gamma', 'gamma', float),
|
||||
('filters.colorclip.gamma_threshold', 'gamma_threshold', float),
|
||||
('filters.colorclip.highlight_power', 'highlight_power', float),
|
||||
('filters.colorclip.vibrance', 'vibrancy', float),
|
||||
# Not sure about putting this one on colorclip
|
||||
('filters.colorclip.background', 'background', rgb_triple),
|
||||
|
||||
('filters.de.curve', 'estimator_curve', float),
|
||||
('filters.de.radius', 'estimator_radius', float),
|
||||
@ -149,6 +145,8 @@ flame_structure = (
|
||||
float(d.get('estimator_radius', 11)))
|
||||
if 'estimator_minimum' in d else None),
|
||||
|
||||
('filters.logscale.brightness', 'brightness', float),
|
||||
|
||||
('palette', 'palette', util.palette_encode),
|
||||
('xforms', convert_xforms),
|
||||
('final_xform', 'finalxform', convert_xform),
|
||||
|
@ -18,12 +18,16 @@ xform = (
|
||||
, 'variations': var_params
|
||||
})
|
||||
|
||||
# Since the structure of the info element differs between anims, nodes and
|
||||
# edges, we pull out some of the common elements here
|
||||
author = String('Attribution in the form: "Name [<email>][, url]"')
|
||||
name = String('A human-readable name for this entity')
|
||||
src = String('The identifier of the source node')
|
||||
dst = String('The identifier of the destination node')
|
||||
author = (
|
||||
{ 'name': String("Human-readable name of author")
|
||||
, 'user': String("Email or other unique identifier")
|
||||
, 'url': String("Website or other link provided by author")
|
||||
})
|
||||
|
||||
link = (
|
||||
{ 'src': String("Origin node ID and temporal offset")
|
||||
, 'dst': String("Destination node ID and temporal offset")
|
||||
})
|
||||
|
||||
filters = (
|
||||
{ 'bilateral':
|
||||
@ -39,7 +43,7 @@ filters = (
|
||||
, 'colorclip':
|
||||
{ 'gamma': scalespline(4)
|
||||
, 'gamma_threshold': spline(0.01, 0, 1)
|
||||
, 'highlight_power': spline(-1, -1, 1)
|
||||
, 'highlight_power': spline(-1, -1)
|
||||
, 'vibrance': scalespline()
|
||||
}
|
||||
, 'de':
|
||||
@ -65,37 +69,33 @@ time = (
|
||||
})
|
||||
|
||||
base = (
|
||||
{ 'camera': camera
|
||||
{ 'name': String("Human-readable name of this work")
|
||||
, 'camera': camera
|
||||
, 'filters': filters
|
||||
, 'palette': list_(Palette())
|
||||
, 'xforms': map_(xform)
|
||||
, 'final_xform': xform
|
||||
})
|
||||
|
||||
anim = dict(base)
|
||||
anim.update(type='animation', time=time,
|
||||
info=dict(authors=list_(author), name=name, src=src, dst=dst,
|
||||
origin=string_()))
|
||||
|
||||
# TODO
|
||||
node = dict(base)
|
||||
node.update(type='node', info=dict(author=author, author_url=string_(),
|
||||
id=string_(), name=name))
|
||||
node.update(type='node', blend=blend, author=author)
|
||||
|
||||
# TODO
|
||||
edge = dict(anim)
|
||||
edge.update(type='edge',
|
||||
info=dict(author=author, id=string_(), src=src, dst=dst),
|
||||
edge = dict(base)
|
||||
edge.update(type='edge', author=author, blend=blend, link=link, time=time,
|
||||
xforms=dict(src=map_(xform), dst=map_(xform)))
|
||||
|
||||
anim = dict(base)
|
||||
anim.update(type='animation', authors=list_(author), link=link, time=time)
|
||||
|
||||
default_filters = ['bilateral', 'logscale', 'colorclip']
|
||||
# Yeah, now I'm just messing around.
|
||||
prof_filters = dict([(fk, dict([(k, refscalar(1, '.'.join(['filters', fk, k])))
|
||||
for k in fv])) for fk, fv in filters.items()])
|
||||
# And here's a completely stupid hack to drag scale into the logscale filter
|
||||
prof_filters['logscale']['scale'] = refscalar(1, 'camera.scale')
|
||||
|
||||
default_filters = [{'type': k} for k in ['bilateral', 'logscale', 'colorclip']]
|
||||
|
||||
profile = (
|
||||
{ 'duration': RefScalar(30, 'time.duration', 'Base duration in seconds')
|
||||
, 'fps': Scalar(24, 'Frames per second')
|
||||
@ -104,8 +104,8 @@ profile = (
|
||||
, 'frame_width': refscalar(1, 'time.frame_width')
|
||||
, 'spp': RefScalar(2000, 'camera.spp', 'Base samples per pixel')
|
||||
, 'skip': Scalar(0, 'Skip this many frames between each rendered frame')
|
||||
, 'filters': TypedList(prof_filters, default_filters,
|
||||
'Ordered list of filters to apply')
|
||||
, 'filter_order': list_(enum(filters.keys()), default_filters)
|
||||
, 'filters': prof_filters
|
||||
})
|
||||
|
||||
# Types recognized as independent units with a 'type' key
|
||||
|
@ -3,13 +3,8 @@ from collections import namedtuple
|
||||
Map = namedtuple('Map', 'type doc')
|
||||
map_ = lambda type, d=None: Map(type, d)
|
||||
|
||||
List = namedtuple('List', 'type doc')
|
||||
list_ = lambda type, d=None: List(type, d)
|
||||
|
||||
# A list as above, but where each element is a dict with a 'type' parameter
|
||||
# corresponding to one of the specs listed in the 'types' dict on this spec.
|
||||
TypedList = namedtuple('TypedList', 'types defaults doc')
|
||||
typedlist = lambda types, defaults=[], d=None: TypedList(types, defaults, d)
|
||||
List = namedtuple('List', 'type default doc')
|
||||
list_ = lambda type, default=(), d=None: List(type, default, d)
|
||||
|
||||
Spline = namedtuple('Spline', 'default min max interp period doc var')
|
||||
def spline(default=0, min=None, max=None, interp='linear', period=None, d=None):
|
||||
@ -37,9 +32,11 @@ refscalar = lambda default, ref, d=None: RefScalar(default, ref, d)
|
||||
String = namedtuple('String', 'doc')
|
||||
def string_(d=None):
|
||||
return String(d)
|
||||
Enum = namedtuple('Enum', 'choices doc')
|
||||
def enum(choices, d=None):
|
||||
"""Enum helper. 'choices' is a space-separated string."""
|
||||
return Enum(choices.split(), d)
|
||||
Enum = namedtuple('Enum', 'choices default doc')
|
||||
def enum(choices, default=None, d=None):
|
||||
"""Enum helper. 'choices' is a list or a space-separated string."""
|
||||
if isinstance(choices, basestring):
|
||||
choices = choices.split()
|
||||
return Enum(choices, default, d)
|
||||
|
||||
Palette = namedtuple('Palette', '')
|
||||
|
@ -1,18 +1,26 @@
|
||||
import numpy as np
|
||||
|
||||
from spectypes import Spline, Scalar, RefScalar, Map, List, TypedList
|
||||
from spectypes import Enum, Spline, Scalar, RefScalar, Map, List
|
||||
from specs import toplevels
|
||||
|
||||
class Wrapper(object):
|
||||
"""
|
||||
Weird reverse visitor. Traversals of the tree are normally done externally
|
||||
(via property accessors, in a lot of cases). This class alters the
|
||||
returned representation of the underlying genome according to the provided
|
||||
spec without imposing flow control.
|
||||
"""
|
||||
def __init__(self, val, spec=None, path=()):
|
||||
if spec is None:
|
||||
assert val.get('type') in toplevels, 'Unrecognized dict type'
|
||||
spec = toplevels[val['type']]
|
||||
# plain 'val' would conflict with some variation property names
|
||||
self._val, self.spec, self.path = val, spec, path
|
||||
|
||||
def wrap(self, name, spec, val):
|
||||
# Oh, a visitor. How... pedestrian.
|
||||
path = self.path + (name,)
|
||||
if isinstance(spec, Enum):
|
||||
return self.wrap_enum(path, spec, val)
|
||||
if isinstance(spec, Spline):
|
||||
return self.wrap_spline(path, spec, val)
|
||||
elif isinstance(spec, Scalar):
|
||||
@ -25,13 +33,14 @@ class Wrapper(object):
|
||||
return self.wrap_Map(path, spec, val)
|
||||
elif isinstance(spec, List):
|
||||
return self.wrap_List(path, spec, val)
|
||||
elif isinstance(spec, TypedList):
|
||||
return self.wrap_TypedList(path, spec, val)
|
||||
return self.wrap_default(path, spec, val)
|
||||
|
||||
def wrap_default(self, path, spec, val):
|
||||
return val
|
||||
|
||||
def wrap_enum(self, path, spec, val):
|
||||
return val or spec.default
|
||||
|
||||
def wrap_spline(self, path, spec, val):
|
||||
return val
|
||||
|
||||
@ -45,12 +54,8 @@ class Wrapper(object):
|
||||
return self.wrap_dict(path, spec, val)
|
||||
|
||||
def wrap_List(self, path, spec, val):
|
||||
return [self.wrap(spec.type, v) for v in val]
|
||||
|
||||
def wrap_TypedList(self, path, spec, val):
|
||||
val = val if val is not None else spec.defaults
|
||||
return [self.wrap(path+(str(i),), spec.types[v['type']], v)
|
||||
for i, v in enumerate(val)]
|
||||
val = val if val is not None else spec.default
|
||||
return [self.wrap(path, spec.type, v) for v in val]
|
||||
|
||||
def get_spec(self, name):
|
||||
if isinstance(self.spec, Map):
|
||||
@ -73,7 +78,6 @@ class Wrapper(object):
|
||||
def __getitem__(self, name):
|
||||
return getattr(self, str(name))
|
||||
|
||||
|
||||
class RefWrapper(Wrapper):
|
||||
"""
|
||||
Wrapper that handles RefScalars, as with profile objects.
|
||||
|
@ -210,7 +210,6 @@ class Renderer(object):
|
||||
del self._modrefs[:]
|
||||
self._modrefs.append(self.mod)
|
||||
|
||||
# TODO: make these customizable
|
||||
self.filts = filters.create(gprof)
|
||||
self.out = output.PILOutput()
|
||||
|
||||
@ -359,7 +358,8 @@ class RenderManager(ClsMod):
|
||||
self._iter(rdr, gnm, gprof, dim, tc)
|
||||
if self.copy_evt:
|
||||
self.stream_a.wait_for_event(self.copy_evt)
|
||||
for filt, params in zip(rdr.filts, gprof.filters):
|
||||
for filt, name in zip(rdr.filts, gprof.filter_order):
|
||||
params = getattr(gprof.filters, name)
|
||||
filt.apply(self.fb, gprof, params, dim, tc, self.stream_a)
|
||||
rdr.out.convert(self.fb, gprof, dim, self.stream_a)
|
||||
self.filt_evt = cuda.Event().record(self.stream_a)
|
||||
|
Loading…
Reference in New Issue
Block a user