diff options
-rw-r--r-- | MANIFEST | 3 | ||||
-rw-r--r-- | ep_colorgamut_analogous.py | 91 | ||||
-rw-r--r-- | ep_colorgamut_complement.py | 82 | ||||
-rw-r--r-- | ep_colorgamut_monchrome.py | 81 | ||||
-rw-r--r-- | ep_colorgamut_splitcomplementary.py | 97 | ||||
-rw-r--r-- | ep_colorgamut_triadic.py | 95 | ||||
-rw-r--r-- | ep_layer_filledspline.py | 61 | ||||
-rw-r--r-- | ep_layer_markovchain.py | 96 | ||||
-rw-r--r-- | ep_layer_voronoidiagram.py | 59 | ||||
-rw-r--r-- | exon_color.py | 15 | ||||
-rw-r--r-- | ka_debug.py | 1 | ||||
-rw-r--r-- | model_constraintpool.py | 2 | ||||
-rw-r--r-- | po/Kandid.pot | 2 |
13 files changed, 611 insertions, 74 deletions
@@ -110,6 +110,9 @@ ep_buzzwordconstraint_sugar.py ep_colorconstraint_bw.py ep_colorconstraint_gray.py ep_colorconstraint_none.py +ep_colorgamut_complement.py +ep_colorgamut_monchrome.py +ep_colorgamut_similar.py ep_directionconstraint_vector.py ep_exporter_png.py ep_formater_html.py diff --git a/ep_colorgamut_analogous.py b/ep_colorgamut_analogous.py new file mode 100644 index 0000000..8d48004 --- /dev/null +++ b/ep_colorgamut_analogous.py @@ -0,0 +1,91 @@ +# coding: UTF-8 +# Copyright 2009 Thomas Jourdan +# +# 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import random +import colorsys +import model_random +import model_locus +import exon_color +from gettext import gettext as _ + +class AnalogousColorGamut(model_locus.Locus): + """Manages a series of similar colors.""" + + def __init__(self, trunk): + """Color gamut constructor.""" + super(AnalogousColorGamut, self).__init__(trunk) + self.hue = 0.0 + self.range = 0.1 + + def __eq__(self, other): + """Equality based on the gamuts components.""" + equal = isinstance(other, AnalogousColorGamut) \ + and self.hue == other.hue \ + and self.range == other.range + return equal + + def randomize(self): + """Set hue. + """ + self.hue = random.random() + self.range = (60.0 / 360.0) * random.random() + + def get_randomized_color(self, path): + """Set red, green, blue and alpha to random values. + """ + deviate = self.range * (random.random() - 0.5) + hue = model_random.cyclic_limit(self.hue + deviate) + lightness = random.random() + saturation = random.random() + alpha = random.random() + rgb = colorsys.hls_to_rgb(hue, lightness, saturation) + color = exon_color.Color(path, rgb[0], rgb[1], rgb[2], alpha) + color.set_base_color(deviate, 0.0, 0.0) + return color + + def mutate(self): + """Make small random changes in hue. + """ + self.hue = model_random.cyclic_limit(self.hue + model_random.jitter(0.1)) + self.range += model_random.jitter(0.1) + + def mutate_color(self, color): + """Adjust rgba value to mutated hue and similarity range. + pre: len(color.rgba) == 4 + """ + rgba = color.rgba + dummy, lightness, saturation = colorsys.rgb_to_hls( + rgba[0], rgba[1], rgba[2]) + deviate = color.base_diff_hue + rgb = colorsys.hls_to_rgb(self.hue + deviate, lightness, saturation) + color.rgba = (rgb[0], rgb[1], rgb[2], rgba[3]) + + def explain(self, formater): + formater.text_item('Analogous color scheme') + + def copy(self): + """The AnalogousColorGamut copy constructor + # check for distinct references, needs to copy content, not references + post: __return__ is not self + """ + new_one = AnalogousColorGamut(self.get_trunk()) + new_one.hue = self.hue + new_one.range = self.range +# new_one.angle = {} +# for key, value in self.angle.items(): +# new_one.angle[key] = value + return new_one diff --git a/ep_colorgamut_complement.py b/ep_colorgamut_complement.py new file mode 100644 index 0000000..bff2334 --- /dev/null +++ b/ep_colorgamut_complement.py @@ -0,0 +1,82 @@ +# coding: UTF-8 +# Copyright 2009 Thomas Jourdan +# +# 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import random +import colorsys +import model_random +import model_locus +import exon_color +from gettext import gettext as _ + +class ComplementaryColorGamut(model_locus.Locus): + """Manages a series of complementary colors.""" + + def __init__(self, trunk): + """Color gamut constructor.""" + super(ComplementaryColorGamut, self).__init__(trunk) + self.hue = 0.0 + + def __eq__(self, other): + """Equality based on the gamuts components.""" + equal = isinstance(other, ComplementaryColorGamut) \ + and self.hue == other.hue + return equal + + def randomize(self): + """Set hue. + """ + self.hue = random.random() + + def get_randomized_color(self, path): + """Set red, green, blue and alpha to random values. + """ + lightness = random.random() + saturation = random.random() + alpha = random.random() + deviate = 0.0 if random.randint(0,1) == 0 else 0.5 + rgb = colorsys.hls_to_rgb(self.hue+deviate, lightness, saturation) + color = exon_color.Color(path, rgb[0], rgb[1], rgb[2], alpha) + color.set_base_color(deviate, 0.0, 0.0) + return color + + def mutate(self): + """Make small random changes in hue. + """ + self.hue = model_random.cyclic_limit(self.hue + model_random.jitter(0.1)) + + def mutate_color(self, color): + """Adjust rgba value to mutated hue. + pre: len(color.rgba) == 4 + """ + rgba = color.rgba + dummy, lightness, saturation = colorsys.rgb_to_hls( \ + rgba[0], rgba[1], rgba[2]) + deviate = color.base_diff_hue + rgb = colorsys.hls_to_rgb(self.hue+deviate, lightness, saturation) + color.rgba = (rgb[0], rgb[1], rgb[2], rgba[3]) + + def explain(self, formater): + formater.text_item('Complementary color scheme') + + def copy(self): + """The ComplementaryColorGamut copy constructor + # check for distinct references, needs to copy content, not references + post: __return__ is not self + """ + new_one = ComplementaryColorGamut(self.get_trunk()) + new_one.hue = self.hue + return new_one diff --git a/ep_colorgamut_monchrome.py b/ep_colorgamut_monchrome.py new file mode 100644 index 0000000..8bef90b --- /dev/null +++ b/ep_colorgamut_monchrome.py @@ -0,0 +1,81 @@ +# coding: UTF-8 +# Copyright 2009 Thomas Jourdan +# +# 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +"""Extension point for color constraints. +This module handles a continuous red, green, blue and alpha color space.""" + +import random +import colorsys +import model_random +import model_locus +import exon_color +from gettext import gettext as _ + +class MonochromeColorGamut(model_locus.Locus): + """Manages a series of monochromatic colors.""" + + def __init__(self, trunk): + """Color gamut constructor.""" + super(MonochromeColorGamut, self).__init__(trunk) + self.hue = 0.0 + + def __eq__(self, other): + """Equality based on the gamuts components.""" + equal = isinstance(other, MonochromeColorGamut) \ + and self.hue == other.hue + return equal + + def randomize(self): + """Set hue. + """ + self.hue = random.random() + + def get_randomized_color(self, path): + """Set red, green, blue and alpha to random values. + """ + lightness = random.random() + saturation = random.random() + alpha = random.random() + rgb = colorsys.hls_to_rgb(self.hue, lightness, saturation) + return exon_color.Color(path, rgb[0], rgb[1], rgb[2], alpha) + + def mutate(self): + """Make small random changes in hue. + """ + self.hue = model_random.cyclic_limit(self.hue + model_random.jitter(0.1)) + + def mutate_color(self, color): + """Adjust rgba value to mutated hue. + pre: len(color.rgba) == 4 + """ + rgba = color.rgba + dummy, lightness, saturation = colorsys.rgb_to_hls( \ + rgba[0], rgba[1], rgba[2]) + rgb = colorsys.hls_to_rgb(self.hue, lightness, saturation) + color.rgba = (rgb[0], rgb[1], rgb[2], rgba[3]) + + def explain(self, formater): + formater.text_item('Monochromatic color scheme') + + def copy(self): + """The MonochromeColorGamut copy constructor + # check for distinct references, needs to copy content, not references + post: __return__ is not self + """ + new_one = MonochromeColorGamut(self.get_trunk()) + new_one.hue = self.hue + return new_one diff --git a/ep_colorgamut_splitcomplementary.py b/ep_colorgamut_splitcomplementary.py new file mode 100644 index 0000000..4ef3cc0 --- /dev/null +++ b/ep_colorgamut_splitcomplementary.py @@ -0,0 +1,97 @@ +# coding: UTF-8 +# Copyright 2009 Thomas Jourdan +# +# 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import random +import colorsys +import model_random +import model_locus +import exon_color +from gettext import gettext as _ + +class SplitComplementaryColorGamut(model_locus.Locus): + """Manages split complementary colors.""" + + def __init__(self, trunk): + """Color gamut constructor.""" + super(SplitComplementaryColorGamut, self).__init__(trunk) + self.hue = 0.0 + self.hue_deviate = (30.0 / 360.0) + + def __eq__(self, other): + """Equality based on the gamuts components.""" + equal = isinstance(other, SplitComplementaryColorGamut) \ + and self.hue == other.hue \ + and self.hue_deviate == other.hue_deviate + return equal + + def randomize(self): + """Set hue. + """ + self.hue = random.random() + self.hue_deviate = (45.0 / 360.0) * random.random() + + def get_randomized_color(self, path): + """Set red, green, blue and alpha to random values. + """ + hue_dircetion = random.choice([-1, 0, 1]) + hue = self._get_hue(hue_dircetion) + lightness = random.random() + saturation = random.random() + alpha = random.random() + rgb = colorsys.hls_to_rgb(hue, lightness, saturation) + color = exon_color.Color(path, rgb[0], rgb[1], rgb[2], alpha) + color.set_base_color(hue_dircetion, 0, 0) + return color + + def mutate(self): + """Make small random changes in hue. + """ + self.hue = model_random.cyclic_limit(self.hue + model_random.jitter(0.1)) + self.hue_deviate += model_random.jitter(0.1) + + def mutate_color(self, color): + """Adjust rgba value to mutated hue and similarity range. + pre: len(color.rgba) == 4 + """ + rgba = color.rgba + dummy, lightness, saturation = colorsys.rgb_to_hls( + rgba[0], rgba[1], rgba[2]) + hue = self._get_hue(color.base_diff_hue) + rgb = colorsys.hls_to_rgb(hue, lightness, saturation) + color.rgba = (rgb[0], rgb[1], rgb[2], rgba[3]) + + def explain(self, formater): + formater.text_item('Split complementary color scheme') + + def copy(self): + """The SplitComplementaryColorGamut copy constructor + # check for distinct references, needs to copy content, not references + post: __return__ is not self + """ + new_one = SplitComplementaryColorGamut(self.get_trunk()) + new_one.hue = self.hue + new_one.hue_deviate = self.hue_deviate + return new_one + + def _get_hue(self, hue_dircetion): + if hue_dircetion < 0: + hue = model_random.cyclic_limit(self.hue - 0.5 + self.hue_deviate) + elif hue_dircetion > 0: + hue = model_random.cyclic_limit(self.hue + 0.5 + self.hue_deviate) + else: + hue = self.hue + return hue diff --git a/ep_colorgamut_triadic.py b/ep_colorgamut_triadic.py new file mode 100644 index 0000000..222e49d --- /dev/null +++ b/ep_colorgamut_triadic.py @@ -0,0 +1,95 @@ +# coding: UTF-8 +# Copyright 2009 Thomas Jourdan +# +# 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +"""Extension point for color constraints. +This module handles a continuous red, green, blue and alpha color space.""" + +import random +import colorsys +import model_random +import model_locus +import exon_color +from gettext import gettext as _ + +class TriadicColorGamut(model_locus.Locus): + """Manages a series of monochromatic colors.""" + + def __init__(self, trunk): + """Color gamut constructor.""" + super(TriadicColorGamut, self).__init__(trunk) + self.hue = 0.0 + + def __eq__(self, other): + """Equality based on the gamuts components.""" + equal = isinstance(other, TriadicColorGamut) \ + and self.hue == other.hue + return equal + + def randomize(self): + """Set hue. + """ + self.hue = random.random() + + def get_randomized_color(self, path): + """Set red, green, blue and alpha to random values. + """ + hue_dircetion = random.choice([-1, 0, 1]) + hue = self._get_hue(hue_dircetion) + lightness = random.random() + saturation = random.random() + alpha = random.random() + rgb = colorsys.hls_to_rgb(hue, lightness, saturation) + color = exon_color.Color(path, rgb[0], rgb[1], rgb[2], alpha) + color.set_base_color(hue_dircetion, 0, 0) + return color + + def mutate(self): + """Make small random changes in hue. + """ + self.hue = model_random.cyclic_limit(self.hue + model_random.jitter(0.1)) + + def mutate_color(self, color): + """Adjust rgba value to mutated hue. + pre: len(color.rgba) == 4 + """ + rgba = color.rgba + dummy, lightness, saturation = colorsys.rgb_to_hls( \ + rgba[0], rgba[1], rgba[2]) + hue = self._get_hue(color.base_diff_hue) + rgb = colorsys.hls_to_rgb(hue, lightness, saturation) + color.rgba = (rgb[0], rgb[1], rgb[2], rgba[3]) + + def explain(self, formater): + formater.text_item('Triadic color scheme') + + def copy(self): + """The TriadicColorGamut copy constructor + # check for distinct references, needs to copy content, not references + post: __return__ is not self + """ + new_one = TriadicColorGamut(self.get_trunk()) + new_one.hue = self.hue + return new_one + + def _get_hue(self, hue_dircetion): + if hue_dircetion < 0: + hue = model_random.cyclic_limit(self.hue - (120.0 / 360.0)) + elif hue_dircetion > 0: + hue = model_random.cyclic_limit(self.hue + (120.0 / 360.0)) + else: + hue = self.hue + return hue diff --git a/ep_layer_filledspline.py b/ep_layer_filledspline.py index 314bbb6..656213a 100644 --- a/ep_layer_filledspline.py +++ b/ep_layer_filledspline.py @@ -21,11 +21,11 @@ import ka_factory import model_locus import model_layer import model_constraintpool -import exon_color import exon_position from gettext import gettext as _ SAMPLERTYPE_CONSTRAINT = 'samplertypeconstraint' +COLORGAMUTTYPE_CONSTRAINT = 'colorgamuttypeconstraint' class FilledSpline(model_layer.Layer): """FilledSpline @@ -45,16 +45,23 @@ class FilledSpline(model_layer.Layer): 'min' : 0.1, 'max': 20.0}, {'bind' : SAMPLERTYPE_CONSTRAINT, 'name' : 'Permitted sampler types', - 'domain': model_constraintpool.STRING_1_OF_N, + 'domain': model_constraintpool.STRING_M_OF_N, 'enum' : ka_factory.get_factory('sampler').keys()}, + {'bind' : COLORGAMUTTYPE_CONSTRAINT, + 'name' : 'Permitted color gamut', + 'domain': model_constraintpool.STRING_M_OF_N, + 'enum' : ka_factory.get_factory('colorgamut').keys()}, ] def __init__(self, trunk): """FilledSpline diagram layer constructor""" super(FilledSpline, self).__init__(trunk) cpool = model_constraintpool.ConstraintPool.get_pool() - self.linecolor = exon_color.Color(self.path, 0, 0, 0, 1) - self.fillcolor = exon_color.Color(self.path, 0, 0, 0, 1) + colorgamut_factory = ka_factory.get_factory('colorgamut') + colorgamut_key = colorgamut_factory.keys()[0] + self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path) + self.linecolor = self.colorgamut.get_randomized_color(self.path) + self.fillcolor = self.colorgamut.get_randomized_color(self.path) self.line_width = cpool.get(self, 'line_width')[0] self.roundness = cpool.get(self, 'roundness')[0] self.center = exon_position.Position(self.path, 0.0, 0.0) @@ -65,7 +72,7 @@ class FilledSpline(model_layer.Layer): def dot(self): result = "" anchor = ka_debug.dot_id(self) + ' -> ' - for ref in [self.linecolor, self.fillcolor, self.center, self.sampler]: + for ref in [self.colorgamut, self.linecolor, self.fillcolor, self.center, self.sampler]: result += ka_debug.dot_ref(anchor, ref) return result @@ -78,7 +85,8 @@ class FilledSpline(model_layer.Layer): and self.line_width == other.line_width \ and self.roundness == other.roundness \ and self.center == other.center \ - and self.sampler == other.sampler + and self.sampler == other.sampler \ + and self.colorgamut == other.colorgamut return equal def randomize(self): @@ -87,8 +95,12 @@ class FilledSpline(model_layer.Layer): cpool = model_constraintpool.ConstraintPool.get_pool() line_width_constraint = cpool.get(self, 'line_width') roundness_constraint = cpool.get(self, 'roundness') - self.linecolor.randomize() - self.fillcolor.randomize() + colorgamut_factory = ka_factory.get_factory('colorgamut') + colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT) + self.colorgamut = colorgamut_factory.create_random(colorgamuttype_constraint, + self.path) + self.linecolor = self.colorgamut.get_randomized_color(self.path) + self.fillcolor = self.colorgamut.get_randomized_color(self.path) self.line_width = model_random.uniform_constrained(line_width_constraint) self.roundness = model_random.uniform_constrained(roundness_constraint) self.center.randomize() @@ -104,8 +116,9 @@ class FilledSpline(model_layer.Layer): cpool = model_constraintpool.ConstraintPool.get_pool() line_width_constraint = cpool.get(self, 'line_width') roundness_constraint = cpool.get(self, 'roundness') - self.linecolor.mutate() - self.fillcolor.mutate() + self.colorgamut.mutate() + self.colorgamut.mutate_color(self.linecolor) + self.colorgamut.mutate_color(self.fillcolor) self.line_width = model_random.jitter_constrained(self.line_width, line_width_constraint) self.roundness = model_random.jitter_constrained(self.roundness, roundness_constraint) self.center.mutate() @@ -126,14 +139,20 @@ class FilledSpline(model_layer.Layer): post: model_locus.unique_check(__return__, self, other) == '' """ new_one = FilledSpline(self.get_trunk()) - crossing = self.crossingover_base(new_one, other, 2) - new_one.linecolor = self.linecolor.crossingover(other.linecolor) - new_one.fillcolor = self.fillcolor.crossingover(other.fillcolor) - new_one.line_width = self.line_width if crossing[0] else other.line_width - new_one.roundness = self.roundness if crossing[1] else other.roundness + crossing = self.crossingover_base(new_one, other, 3) + if crossing[0]: + new_one.colorgamut = other.colorgamut.copy() + new_one.linecolor = other.linecolor.copy() + new_one.fillcolor = other.fillcolor.copy() + else: + new_one.colorgamut = self.colorgamut.copy() + new_one.linecolor = self.linecolor.copy() + new_one.fillcolor = self.fillcolor.copy() + new_one.line_width = other.line_width if crossing[1] else self.line_width + new_one.roundness = other.roundness if crossing[2] else self.roundness new_one.center = self.center.crossingover(other.center) new_one.sampler = model_random.crossingover_elem(self.sampler, - other.sampler) + other.sampler) return new_one def render(self, task, ctx, width, height): @@ -184,6 +203,7 @@ class FilledSpline(model_layer.Layer): def explain(self, formater): super(FilledSpline, self).explain(formater) + self.colorgamut.explain(formater) formater.color_item(self.linecolor, 'line color:') formater.text_item('line width: ' + str(self.line_width)) formater.text_item('roundness: ' + str(self.roundness)) @@ -208,4 +228,13 @@ class FilledSpline(model_layer.Layer): new_one.roundness = self.roundness new_one.center = self.center.copy() new_one.sampler = self.sampler.copy() + # upgrade from a release older than 'v4' + if self.__dict__.has_key('colorgamut'): + new_one.colorgamut = self.colorgamut.copy() + else: + cpool = model_constraintpool.ConstraintPool.get_pool() + colorgamut_factory = ka_factory.get_factory('colorgamut') + colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT) + new_one.colorgamut = colorgamut_factory.create_random(colorgamuttype_constraint, + new_one.path) return new_one diff --git a/ep_layer_markovchain.py b/ep_layer_markovchain.py index 93f4c36..8b491e5 100644 --- a/ep_layer_markovchain.py +++ b/ep_layer_markovchain.py @@ -16,7 +16,6 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import random -import exon_color import model_locus import model_layer import model_constraintpool @@ -25,49 +24,50 @@ import model_random import ka_factory from gettext import gettext as _ -#NUMBER_OF_TILES_CONSTRAINT = 'number_of_tilesconstraint' NUMBER_OF_STATES_CONSTRAINT = 'number_of_statesconstraint' SAMPLERTYPE_CONSTRAINT = 'samplertypeconstraint' STAMPTYPE_CONSTRAINT = 'stamptypeconstraint' +COLORGAMUTTYPE_CONSTRAINT = 'colorgamuttypeconstraint' class MarkovChainLayer(model_layer.Layer): """Markov chain layer inv: self.cell_colors is not None and len(self.cell_colors) == self.states inv: self.probability is not None and len(self.probability) == self.states - #inv: 1 <= self.number_of_tiles - inv: 1 <= self.states + inv: 0 <= self.states inv: self.sampler is not None inv: self.stamp is not None """ - cdef = [#{'bind' : NUMBER_OF_TILES_CONSTRAINT, -# 'name' : 'Number of tiles per axis', -# 'domain': model_constraintpool.INT_RANGE, -# 'min' : 2, 'max': 10}, - {'bind' : NUMBER_OF_STATES_CONSTRAINT, + cdef = [{'bind' : NUMBER_OF_STATES_CONSTRAINT, 'name' : 'Number of states', 'domain': model_constraintpool.INT_RANGE, 'min' : 2, 'max': 8}, {'bind' : SAMPLERTYPE_CONSTRAINT, 'name' : 'Permitted sampler types', - 'domain': model_constraintpool.STRING_1_OF_N, + 'domain': model_constraintpool.STRING_M_OF_N, 'enum' : ka_factory.get_factory('sampler').keys()}, {'bind' : STAMPTYPE_CONSTRAINT, 'name' : 'Permitted stamp types', - 'domain': model_constraintpool.STRING_1_OF_N, + 'domain': model_constraintpool.STRING_M_OF_N, 'enum' : ka_factory.get_factory('stamp').keys()}, + {'bind' : COLORGAMUTTYPE_CONSTRAINT, + 'name' : 'Permitted color gamut', + 'domain': model_constraintpool.STRING_M_OF_N, + 'enum' : ka_factory.get_factory('colorgamut').keys()}, ] def __init__(self, trunk): """Markov chain layer constructor""" super(MarkovChainLayer, self).__init__(trunk) - self.states = 1 - self.cell_colors = [exon_color.Color(self.path, 0, 0, 0, 1)] - self.probability = [[1.0 / self.states] * self.states + self.states = 0 + colorgamut_factory = ka_factory.get_factory('colorgamut') + colorgamut_key = colorgamut_factory.keys()[0] + self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path) + self.cell_colors = [] + + self.probability = [[1.0] * self.states for dummy in range(self.states)] - self._init_states(2) -# self.number_of_tiles = 2 sampler_factory = ka_factory.get_factory('sampler') sampler_key = sampler_factory.keys()[0] self.sampler = sampler_factory.create(sampler_key, self.path) @@ -83,7 +83,7 @@ class MarkovChainLayer(model_layer.Layer): result += ka_debug.dot_ref(anchor, ref) for ref in self.probability: result += ka_debug.dot_ref(anchor, ref) - for ref in [self.sampler, self.stamp]: + for ref in [self.sampler, self.stamp, self.colorgamut]: result += ka_debug.dot_ref(anchor, ref) return result @@ -105,24 +105,23 @@ class MarkovChainLayer(model_layer.Layer): def _append_states(self, number_of_states): """ pre: self.states < number_of_states + pre: number_of_states > 0 """ - diff = number_of_states - self.states - # append random colors - for dummy in range(diff): - color = exon_color.Color(self.path, 0, 0, 0, 1) - color.randomize() - self.cell_colors.append(color) + for dummy in range(self.states, number_of_states): + self.cell_colors.append( + self.colorgamut.get_randomized_color(self.path)) # completely recalculate probabilities self.probability = [[1.0 / number_of_states] * number_of_states for dummy in range(number_of_states)] for row, row_probabilities in enumerate(self.probability): for col in range(len(row_probabilities)): - self.probability[row][col] = random.random() / self.states + self.probability[row][col] = random.random() / number_of_states self._normalize_row(row) def _shrink_states(self, number_of_states): """ pre: self.states > number_of_states + pre: number_of_states > 0 """ # copy remaining cell colors copy_cell_colors = [None] * number_of_states @@ -148,12 +147,13 @@ class MarkovChainLayer(model_layer.Layer): self.probability[row][column] *= normalize def __eq__(self, other): - """Equality based on the cells color components.""" + """Equality based on the layers components.""" equal = isinstance(other, MarkovChainLayer) \ and super(MarkovChainLayer, self).__eq__(other) \ and self.states == other.states \ and self.sampler == other.sampler \ - and self.stamp == other.stamp + and self.stamp == other.stamp \ + and self.colorgamut == other.colorgamut if equal: for cix, cell_color in enumerate(self.cell_colors): equal = equal and cell_color == other.cell_colors[cix] @@ -168,14 +168,15 @@ class MarkovChainLayer(model_layer.Layer): """Randomize the layers components.""" super(MarkovChainLayer, self).randomize() cpool = model_constraintpool.ConstraintPool.get_pool() + colorgamut_factory = ka_factory.get_factory('colorgamut') + colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT) + self.colorgamut = colorgamut_factory.create_random(colorgamuttype_constraint, + self.path) + number_of_states_constraint = cpool.get(self, NUMBER_OF_STATES_CONSTRAINT) self._init_states(model_random.randint_constrained( number_of_states_constraint)) -# number_of_tiles_constraint = cpool.get(self, NUMBER_OF_TILES_CONSTRAINT) -# self.number_of_tiles = model_random.randint_constrained( -# number_of_tiles_constraint) - sampler_factory = ka_factory.get_factory('sampler') samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT) self.sampler = sampler_factory.create_random(samplertype_constraint, @@ -196,9 +197,6 @@ class MarkovChainLayer(model_layer.Layer): changed = self._init_states(model_random.jitter_discret_constrained( self.states, number_of_states_constraint)) - for cix in range(len(self.cell_colors)): - self.cell_colors[cix].mutate() - if not changed: for row, row_probabilities in enumerate(self.probability): for col in range(len(row_probabilities)): @@ -208,6 +206,9 @@ class MarkovChainLayer(model_layer.Layer): self.sampler.mutate() self.stamp.mutate() + self.colorgamut.mutate() + for cix in range(len(self.cell_colors)): + self.colorgamut.mutate_color(self.cell_colors[cix]) def swap_places(self): """Shuffle similar components.""" @@ -229,29 +230,32 @@ class MarkovChainLayer(model_layer.Layer): post: model_locus.unique_check(__return__, self, other) == '' """ new_one = MarkovChainLayer(self.get_trunk()) - cross_sequence = self.crossingover_base(new_one, other, \ - 2 + len(self.cell_colors)) + cross_sequence = self.crossingover_base(new_one, other, 2) new_one.sampler = model_random.crossingover_elem(self.sampler, other.sampler) new_one.stamp = model_random.crossingover_elem(self.stamp, other.stamp) - if cross_sequence[1]: - probability = self.probability - cell_colors = self.cell_colors - new_one.states = self.states - else: probability = other.probability cell_colors = other.cell_colors new_one.states = other.states + else: + probability = self.probability + cell_colors = self.cell_colors + new_one.states = self.states new_one.probability = [[1.0 / new_one.states] * new_one.states for dummy in range(new_one.states)] for row, row_probabilities in enumerate(probability): for col, cell_probability in enumerate(row_probabilities): new_one.probability[row][col] = cell_probability + + new_one.colorgamut = other.colorgamut.copy() if cross_sequence[0] \ + else self.colorgamut.copy() new_one.cell_colors = [] for cix in range(len(cell_colors)): - new_one.cell_colors.append(cell_colors[cix].copy()) + color = cell_colors[cix].copy() + new_one.colorgamut.mutate_color(color) + new_one.cell_colors.append(color) return new_one def render(self, task, ctx, width, height): @@ -285,6 +289,7 @@ class MarkovChainLayer(model_layer.Layer): def explain(self, formater): super(MarkovChainLayer, self).explain(formater) + self.colorgamut.explain(formater) formater.color_array(self.cell_colors, 'cell colors:') formater.text_item('number of states: ' + str(self.states)) text, surface, descr = self.sampler.explain() @@ -316,4 +321,13 @@ class MarkovChainLayer(model_layer.Layer): new_one.probability[row][col] = cell_probability new_one.sampler = self.sampler.copy() new_one.stamp = self.stamp.copy() + # upgrade from a release older than 'v4' + if self.__dict__.has_key('colorgamut'): + new_one.colorgamut = self.colorgamut.copy() + else: + cpool = model_constraintpool.ConstraintPool.get_pool() + colorgamut_factory = ka_factory.get_factory('colorgamut') + colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT) + new_one.colorgamut = colorgamut_factory.create_random(colorgamuttype_constraint, + new_one.path) return new_one diff --git a/ep_layer_voronoidiagram.py b/ep_layer_voronoidiagram.py index 4f43373..44a2bc3 100644 --- a/ep_layer_voronoidiagram.py +++ b/ep_layer_voronoidiagram.py @@ -23,13 +23,13 @@ import model_locus import model_layer import model_constraintpool import exon_position -import exon_color from gettext import gettext as _ ORDER_CONSTRAINT = 'order_constaint' SAMPLERTYPE_CONSTRAINT = 'samplertypeconstraint' STAMPTYPE_CONSTRAINT = 'stamptypeconstraint' NUMBER_OF_SITES_CONSTRAINT = 'sitenumberofconstraint' +COLORGAMUTTYPE_CONSTRAINT = 'colorgamuttypeconstraint' class VoronoiDiagramLayer(model_layer.Layer): """VoronoiDiagramLayer @@ -55,13 +55,21 @@ class VoronoiDiagramLayer(model_layer.Layer): 'name' : 'Permitted stamp types', 'domain': model_constraintpool.STRING_1_OF_N, 'enum' : ka_factory.get_factory('stamp').keys()}, + {'bind' : COLORGAMUTTYPE_CONSTRAINT, + 'name' : 'Permitted color gamut', + 'domain': model_constraintpool.STRING_M_OF_N, + 'enum' : ka_factory.get_factory('colorgamut').keys()}, ] def __init__(self, trunk): """Voronoi diagram layer constructor""" super(VoronoiDiagramLayer, self).__init__(trunk) - self.sites_point = [ exon_position.Position(self.path, 0.0, 0.0) ] - self.sites_color = [ exon_color.Color(self.path, 0.0, 0.0, 0.0, 0.0) ] + colorgamut_factory = ka_factory.get_factory('colorgamut') + colorgamut_key = colorgamut_factory.keys()[0] + self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path) + + self.sites_point = [exon_position.Position(self.path, 0.0, 0.0)] + self.sites_color = [self.colorgamut.get_randomized_color(self.path)] # self._distance = VoronoiDiagramLayer._euclidean_square_distance self.order = 2 # euclidean distance sampler_factory = ka_factory.get_factory('sampler') @@ -121,8 +129,7 @@ class VoronoiDiagramLayer(model_layer.Layer): self.sites_point.append(site_point) self.sites_color = [] for dummy in range(model_random.randint_constrained(number_of_constraint)): - site_color = exon_color.Color(self.path, 0.0, 0.0, 0.0, 0.0) - site_color.randomize() + site_color = self.colorgamut.get_randomized_color(self.path) self.sites_color.append(site_color) stamp_factory = ka_factory.get_factory('stamp') @@ -136,16 +143,21 @@ class VoronoiDiagramLayer(model_layer.Layer): super(VoronoiDiagramLayer, self).mutate() cpool = model_constraintpool.ConstraintPool.get_pool() number_of_constraint = cpool.get(self, NUMBER_OF_SITES_CONSTRAINT) - site_point = exon_position.Position(self.path, 0.0, 0.0) - site_point.randomize() + new_site_point = exon_position.Position(self.path, 0.0, 0.0) + new_site_point.randomize() model_random.mutate_list(self.sites_point, - number_of_constraint, site_point) - site_color = exon_color.Color(self.path, 0.0, 0.0, 0.0, 0.0) - site_color.randomize() + number_of_constraint, new_site_point) + + self.colorgamut.mutate() + new_site_color = self.colorgamut.get_randomized_color(self.path) model_random.mutate_list(self.sites_color, - number_of_constraint, site_color) + number_of_constraint, new_site_color) + for cix in range(len(self.sites_color)): + self.colorgamut.mutate_color(self.sites_color[cix]) + order_constraint = cpool.get(self, ORDER_CONSTRAINT) self.order = model_random.jitter_constrained(self.order, order_constraint) + self.sampler.mutate() self.stamp.mutate() @@ -166,12 +178,18 @@ class VoronoiDiagramLayer(model_layer.Layer): post: model_locus.unique_check(__return__, self, other) == '' """ new_one = VoronoiDiagramLayer(self.get_trunk()) + cross_sequence = model_random.crossing_sequence(2) new_one.sites_point = model_random.crossingover_list(self.sites_point, - other.sites_point) + other.sites_point) + + new_one.colorgamut = other.colorgamut.copy() if cross_sequence[0] \ + else self.colorgamut.copy() new_one.sites_color = model_random.crossingover_list(self.sites_color, - other.sites_color) - cross_sequence = model_random.crossing_sequence(1) - new_one.order = self.order if cross_sequence[0] else other.order + other.sites_color) + for cix in range(len(new_one.sites_color)): + new_one.colorgamut.mutate_color(new_one.sites_color[cix]) + + new_one.order = self.order if cross_sequence[1] else other.order new_one.sampler = model_random.crossingover_elem(self.sampler, other.sampler) new_one.stamp = model_random.crossingover_elem(self.stamp, @@ -248,9 +266,11 @@ class VoronoiDiagramLayer(model_layer.Layer): def explain(self, formater): super(VoronoiDiagramLayer, self).explain(formater) + self.colorgamut.explain(formater) formater.text_item('Natural logarithm of order p used in Minkowski distance: ' + str(self.order)) formater.position_array(self.sites_point, 'center points for sites:') + self.colorgamut.explain(formater) formater.color_array(self.sites_color, 'site colors:') text, surface, descr = self.sampler.explain() if surface is not None: @@ -275,4 +295,13 @@ class VoronoiDiagramLayer(model_layer.Layer): new_one.order = self.order new_one.sampler = self.sampler.copy() new_one.stamp = self.stamp.copy() + # upgrade from a release older than 'v4' + if self.__dict__.has_key('colorgamut'): + new_one.colorgamut = self.colorgamut.copy() + else: + cpool = model_constraintpool.ConstraintPool.get_pool() + colorgamut_factory = ka_factory.get_factory('colorgamut') + colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT) + new_one.colorgamut = colorgamut_factory.create_random(colorgamuttype_constraint, + new_one.path) return new_one diff --git a/exon_color.py b/exon_color.py index 247b28e..bd8e192 100644 --- a/exon_color.py +++ b/exon_color.py @@ -54,6 +54,9 @@ class Color(model_allele.Allele): constraint_name = cpool.get(self, COLOR_CONSTRAINT)[0] self.constraint = ka_extensionpoint.create(constraint_name, self.path) self.rgba = self.constraint.filter((red, green, blue, alpha)) + self.base_diff_hue = 0 + self.base_diff_lightness = 0 + self.base_diff_saturation = 0 def __eq__(self, other): """Equality based on color components.""" @@ -63,6 +66,13 @@ class Color(model_allele.Allele): and abs(self.rgba[2] - other.rgba[2]) < EPSILON \ and abs(self.rgba[3] - other.rgba[3]) < EPSILON + def set_base_color(self, diff_hue, diff_lightness, diff_saturation): + """Set optional base color. + Only if this color depends on a 'leading' color.""" + self.base_diff_hue = diff_hue + self.base_diff_lightness = diff_lightness + self.base_diff_saturation = diff_saturation + def randomize(self): """Set red, green, blue and alpha to random values.""" cpool = model_constraintpool.ConstraintPool.get_pool() @@ -104,6 +114,11 @@ class Color(model_allele.Allele): new_one = Color(self.get_trunk(), 0.0, 0.0, 0.0, 0.0) new_one.rgba = (self.rgba[0], self.rgba[1], self.rgba[2], self.rgba[3]) new_one.constraint = self.constraint + # upgrade from a release older than 'v4' + if self.__dict__.has_key('base_diff_hue'): + new_one.base_diff_hue = self.base_diff_hue + new_one.base_diff_lightness = self.base_diff_lightness + new_one.base_diff_saturation = self.base_diff_saturation return new_one def explain(self, alpha=True): diff --git a/ka_debug.py b/ka_debug.py index b2a6f3e..fcf7492 100644 --- a/ka_debug.py +++ b/ka_debug.py @@ -33,7 +33,6 @@ _last_clock = 0.0 _try_once, _locale_testrun= False, False if os.path.exists(DEBUG_ACTIVITY_PATH): _locale_testrun = True - _locale_testrun = False _try_once = True is_DbC_activated = False diff --git a/model_constraintpool.py b/model_constraintpool.py index e2aa09e..c683159 100644 --- a/model_constraintpool.py +++ b/model_constraintpool.py @@ -134,6 +134,8 @@ class ConstraintPool(object): def _my_defaults(self): #TODO read from persistence, provide an constraint editor +# self.set('*', 'layertypeconstraint', ['markovchain', ]) +# self.set('*', 'colorconstraint', ['colorconstraint_none', ]) # self.set('*', 'layertypeconstraint', ['voronoidiagram', 'markovchain', ]) # self.set('*', 'stamptypeconstraint', ['svg',]) # self.set('*', 'stamptypeconstraint', ['glyph',]) diff --git a/po/Kandid.pot b/po/Kandid.pot index 35e2bd6..5252b2a 100644 --- a/po/Kandid.pot +++ b/po/Kandid.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-01-24 09:23+0100\n" +"POT-Creation-Date: 2010-01-26 21:27+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" |