4 # Copyright (C) 2006-2011 Michael J. Gruber <conformal@drmicha.warpmail.net>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, version 2 of the License.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 # allow access through module and without
26 from array
import array
29 # try importing typical math modules
42 def conformal_batch(width
, height
, code
, xl
, xr
, yt
, yb
, grid
, gradient
, filename
):
43 conformal_core(width
, height
, code
, xl
, xr
, yt
, yb
, grid
, gradient
, filename
)
46 def conformal(width
, height
, code
, xl
, xr
, yt
, yb
, grid
, gradient
):
47 conformal_core(width
, height
, code
, xl
, xr
, yt
, yb
, grid
, gradient
, None)
50 def conformal_core(width
, height
, code
, xl
, xr
, yt
, yb
, grid
, gradient
, filename
):
51 image
= gimp
.Image(width
, height
, RGB
)
52 drawables
= [ gimp
.Layer(image
, "Argument", width
, height
, RGBA_IMAGE
, 100, NORMAL_MODE
),
53 gimp
.Layer(image
, "Log. modulus", width
, height
, RGBA_IMAGE
, 35, DARKEN_ONLY_MODE
),
54 gimp
.Layer(image
, "Grid", width
, height
, RGBA_IMAGE
, 10, DARKEN_ONLY_MODE
)]
57 for drawable
in drawables
:
58 image
.add_layer(drawable
, l
)
61 bpp
= drawables
[0].bpp
63 gimp
.tile_cache_ntiles(2 * (width
+ 63) / 64)
65 dest_rgns
= [ drawable
.get_pixel_rgn(0, 0, width
, height
, True, False) for drawable
in drawables
]
67 max_progress
= width
* height
69 gimp
.progress_init("Conformally Mapping...")
70 sx
= (width
-1.0)/(xr
-xl
)
71 sy
= (height
-1.0)/(yt
-yb
)
75 ml2
= 2.0*math
.log(2) # no need to do this 500*500 times...
76 compiled
=compile(code
, "compiled code", "exec", 0, 1)
78 for row
in range(0, height
):
82 for col
in range(0, width
):
83 z
= col
/sx
+ xl
+ 1j
*( yt
- row
/sy
)
86 except (OverflowError, ValueError):
88 arg
= math
.atan2(w
.imag
, w
.real
)
91 args
= args
+ ( arg
/(2*math
.pi
) ,)
93 mod
= ( math
.log(w
.imag
**2+w
.real
**2)/ml2
) % 1.0
94 except (OverflowError, ValueError):
96 mods
= mods
+ ( mod
,)
98 sqr
= (int)(w
.imag
/grid
% 2.0) + (int)(w
.real
/grid
% 2.0)
99 except (OverflowError, ValueError):
101 sqrs
= sqrs
+ (bpp
-1)*( 255*(sqr
% 2) ,) + (255, )
103 samples
= gimp
.gradient_get_custom_samples(gradient
, args
)
104 top_p
= array("B", [ ((int)(255*samples
[col
][i
]+0.5)) for col
in range(0, width
) for i
in range(bpp
) ] )
106 dest_rgns
[0][0:width
, row
] = top_p
.tostring()
108 samples
= gimp
.gradient_get_custom_samples("Default", mods
)
109 top_p
= array("B", [ ((int)(255*samples
[col
][i
]+0.5)) for col
in range(0, width
) for i
in range(bpp
) ] )
110 dest_rgns
[1][0:width
, row
] = top_p
.tostring()
112 top_p
= array("B", sqrs
)
113 dest_rgns
[2][0:width
, row
] = top_p
.tostring()
115 progress
= progress
+ width
117 gimp
.progress_update(float(progress
) / max_progress
)
119 for drawable
in drawables
:
121 drawable
.update(0,0,width
,height
)
122 pdb
.plug_in_edge(image
,drawables
[2], 10, 0, 0) # amount, WRAP, SOBEL
123 pdb
.plug_in_vinvert(image
,drawables
[2])
124 if image
.parasite_find("gimp-comment"):
125 image
.parasite
.detach("gimp-comment")
126 image
.attach_new_parasite("gimp-comment", PARASITE_PERSISTENT
, """# conformal %s
137 """ % (confversion
, code
, xl
, xr
, yt
, yb
, grid
, gradient
, width
, height
))
143 if filename
.find('.xcf') > 0:
144 pdb
.gimp_xcf_save(1, image
, drawables
[0], filename
, filename
)
146 flat_layer
= pdb
.gimp_image_flatten(image
)
147 pdb
.gimp_file_save(image
, flat_layer
, filename
, filename
)
152 "Colour representation of a conformal map",
153 "Colour representation of a conformal map",
160 (PF_INT
, "width", "width", 512),
161 (PF_INT
, "height", "height", 512),
162 (PF_TEXT
, "code", "code", "w=z"),
163 (PF_FLOAT
, "xl", "x left", -1.0),
164 (PF_FLOAT
, "xr", "x right", 1.0),
165 (PF_FLOAT
, "yt", "y top", 1.0),
166 (PF_FLOAT
, "yb", "y bottom", -1.0),
167 (PF_FLOAT
, "grid", "grid", 1.0),
168 (PF_GRADIENT
, "gradient", "gradient", "Full saturation spectrum CCW"),
169 (PF_FILE
, "file", "file", "out.xcf.bz2"),
176 "Colour representation of a conformal map",
177 "Colour representation of a conformal map",
181 "<Toolbox>/File/Create/_Conformal ...",
184 (PF_INT
, "width", "width", 512),
185 (PF_INT
, "height", "height", 512),
186 (PF_TEXT
, "code", "code", "w=z"),
187 (PF_FLOAT
, "xl", "x left", -1.0),
188 (PF_FLOAT
, "xr", "x right", 1.0),
189 (PF_FLOAT
, "yt", "y top", 1.0),
190 (PF_FLOAT
, "yb", "y bottom", -1.0),
191 (PF_FLOAT
, "grid", "grid", 1.0),
192 (PF_GRADIENT
, "gradient", "gradient", "Full saturation spectrum CCW"),