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
, constraint
, xl
, xr
, yt
, yb
, grid
, checkboard
, gradient
, filename
):
43 conformal_core(width
, height
, code
, constraint
, xl
, xr
, yt
, yb
, grid
, checkboard
, gradient
, filename
)
46 def conformal(width
, height
, code
, constraint
, xl
, xr
, yt
, yb
, grid
, checkboard
, gradient
):
47 conformal_core(width
, height
, code
, constraint
, xl
, xr
, yt
, yb
, grid
, checkboard
, gradient
, None)
50 def conformal_core(width
, height
, code
, constraint
, xl
, xr
, yt
, yb
, grid
, checkboard
, 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, VALUE_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 mp2
= 2.0*math
.pi
# no need to do this 500*500 times...
76 ml2
= 2.0*math
.log(2) # no need to do this 500*500 times...
77 ml
= math
.log(2) # no need to do this 500*500 times...
78 compiled
=compile(code
, "compiled code", "exec", 0, 1)
79 compiledconstraint
=compile(constraint
, "compiled constraint code", "exec", 0, 1)
81 dests
= [ array("B", "\x00" * width
*height
*bpp
) for i
in range(3) ]
84 args
= [ i
/(QUANT
-1.0) for i
in range(QUANT
) ]
85 arggradsamples
= list(gimp
.gradient_get_custom_samples(gradient
, args
)) + [[0,]*bpp
]
86 modgradsamples
= list(gimp
.gradient_get_custom_samples("Default", args
)) + [[0,]*bpp
]
87 sqrsamples
= [ [0,]*(bpp
-1) + [255,], [255,]*(bpp
-1) + [255,] , [0,]*bpp
]
88 for col
in range(QUANT
+1):
89 arggradsamples
[col
] = [ ((int)(255*arggradsamples
[col
][i
]+0.5)) for i
in range(bpp
)]
90 modgradsamples
[col
] = [ ((int)(255*modgradsamples
[col
][i
]+0.5)) for i
in range(bpp
)]
91 qinf
= 1.0 + 1.0/(QUANT
-1) # uggely uggely
97 for row
in range(0, height
):
98 for col
in range(0, width
):
99 z
= col
/sx
+ xl
+ 1j
*( yt
- row
/sy
)
102 exec(compiledconstraint
)
103 except (OverflowError, ValueError):
110 except (OverflowError, ValueError):
112 if not p
or isnan(w
) or isinf(w
):
118 if isnan(arg
) or isinf(arg
):
123 mod
= ( logw
.real
/ml
) % 1.0
124 if isnan(mod
) or isinf(mod
):
127 except (OverflowError, ValueError):
134 sqr
= int(w
.imag
/grid
% 2.0) + int(w
.real
/grid
% 2.0)
135 if isnan(sqr
) or isinf(sqr
):
138 except (OverflowError, ValueError):
153 dests
[0][row
*width
*bpp
: (row
+1)*width
*bpp
] = array("B", [ arggradsamples
[int((QUANT
-1)*args
[col
]+0.5)][i
] for col
in range(0, width
) for i
in range(bpp
) ] )
155 dests
[1][row
*width
*bpp
: (row
+1)*width
*bpp
] = array("B", [ modgradsamples
[int((QUANT
-1)*mods
[col
]+0.5)][i
] for col
in range(0, width
) for i
in range(bpp
) ] )
157 dests
[2][row
*width
*bpp
: (row
+1)*width
*bpp
]= array("B", [ sqrsamples
[sqrs
[col
]][i
] for col
in range(0,width
) for i
in range(bpp
) ] )
159 progress
= progress
+ width
161 gimp
.progress_update(float(progress
) / max_progress
)
164 dest_rgns
[i
][0:width
, 0:height
] = dests
[i
].tostring()
166 for drawable
in drawables
:
168 drawable
.update(0,0,width
,height
)
170 pdb
.plug_in_edge(image
,drawables
[2], 10, 0, 0) # amount, WRAP, SOBEL
171 pdb
.plug_in_vinvert(image
,drawables
[2])
172 if image
.parasite_find("gimp-comment"):
173 image
.parasite
.detach("gimp-comment")
174 image
.attach_new_parasite("gimp-comment", PARASITE_PERSISTENT
, """# conformal %s
190 """ % (confversion
, code
, constraint
, xl
, xr
, yt
, yb
, grid
, checkboard
, gradient
, width
, height
))
196 if filename
.find('.xcf') > 0:
197 pdb
.gimp_xcf_save(1, image
, drawables
[0], filename
, filename
)
199 flat_layer
= pdb
.gimp_image_flatten(image
)
200 pdb
.gimp_file_save(image
, flat_layer
, filename
, filename
)
205 "Colour representation of a conformal map",
206 "Colour representation of a conformal map",
213 (PF_INT
, "width", "width", 512),
214 (PF_INT
, "height", "height", 512),
215 (PF_TEXT
, "code", "code", "w=z"),
216 (PF_TEXT
, "constraint", "constraint", "p=True"),
217 (PF_FLOAT
, "xl", "x left", -1.0),
218 (PF_FLOAT
, "xr", "x right", 1.0),
219 (PF_FLOAT
, "yt", "y top", 1.0),
220 (PF_FLOAT
, "yb", "y bottom", -1.0),
221 (PF_FLOAT
, "grid", "grid spacing", 1.0),
222 (PF_BOOL
, "checkboard", "checker board grid", 0),
223 (PF_GRADIENT
, "gradient", "gradient", "Full saturation spectrum CCW"),
224 (PF_FILE
, "file", "file", "out.xcf.bz2"),
231 "Colour representation of a conformal map",
232 "Colour representation of a conformal map",
236 "<Toolbox>/File/Create/_Conformal ...",
239 (PF_INT
, "width", "width", 512),
240 (PF_INT
, "height", "height", 512),
241 (PF_TEXT
, "code", "code", "w=z"),
242 (PF_TEXT
, "constraint", "constraint", "p=True"),
243 (PF_FLOAT
, "xl", "x left", -1.0),
244 (PF_FLOAT
, "xr", "x right", 1.0),
245 (PF_FLOAT
, "yt", "y top", 1.0),
246 (PF_FLOAT
, "yb", "y bottom", -1.0),
247 (PF_FLOAT
, "grid", "grid spacing", 1.0),
248 (PF_BOOL
, "checkboard", "checker board grid", 0),
249 (PF_GRADIENT
, "gradient", "gradient", "Full saturation spectrum CCW"),