Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST3
-rw-r--r--ep_colorgamut_analogous.py91
-rw-r--r--ep_colorgamut_complement.py82
-rw-r--r--ep_colorgamut_monchrome.py81
-rw-r--r--ep_colorgamut_splitcomplementary.py97
-rw-r--r--ep_colorgamut_triadic.py95
-rw-r--r--ep_layer_filledspline.py61
-rw-r--r--ep_layer_markovchain.py96
-rw-r--r--ep_layer_voronoidiagram.py59
-rw-r--r--exon_color.py15
-rw-r--r--ka_debug.py1
-rw-r--r--model_constraintpool.py2
-rw-r--r--po/Kandid.pot2
13 files changed, 611 insertions, 74 deletions
diff --git a/MANIFEST b/MANIFEST
index ee1ca65..d60e088 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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"