Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2012
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Implements
  2. ; http://learnfobia.com/category-Computers-47/tutorial-Painting-A-Spaceship-Hull-Texture-2126.html
  3. (define (script-fu-render-greebles
  4.     img drw
  5.     layers size num
  6.     aspect-limit change-factor smudge-density
  7.     fuzz exposure)
  8.   (list
  9.     (loop 0 layers (lambda (x)
  10.       (with-selection img (lambda ()
  11.         (with-color (lambda ()
  12.           (let*
  13.             (
  14.               (w (car (gimp-image-width img)))
  15.               (h (car (gimp-image-height img))))
  16.             (list
  17.               (random-blend)
  18.               (greeblestep
  19.                 img (list w h) drw
  20.                 (= x 0)
  21.                 (list size num aspect-limit (* (+ x 1) change-factor))
  22.                 smudge-density fuzz exposure)
  23.               (gimp-drawable-update drw 0 0 w h)
  24.               (gimp-displays-flush)))))))))))
  25. (script-fu-register
  26.   "script-fu-render-greebles"
  27.   "G_reebles"
  28.   "Renders greebles"
  29.   "FeepingCreature"
  30.   ""
  31.   ""
  32.   "*"
  33.   SF-IMAGE  "The Image" 0
  34.   SF-DRAWABLE   "The Layer" 0
  35.   SF-VALUE  "Layers"    "2"
  36.   SF-VALUE  "Base size" "200"
  37.   SF-VALUE  "numGreebles per layer" "35"
  38.   SF-VALUE  "Base aspect limiter"   "2"
  39.   SF-VALUE  "Aspect change factor"  "3"
  40.   SF-VALUE  "Smudge Density"    "7"
  41.   SF-VALUE  "Edge Fuzz Spread"  "4"
  42.   SF-VALUE  "Smudge Exposure"   "20")
  43. (script-fu-menu-register "script-fu-render-greebles" "<Image>/Filters/Render")
  44.  
  45. ; call f with numbers from 'from' to 'to', end-exclusive
  46. (define loop (lambda (from to f)
  47.   (while (< from to)
  48.     (f from)
  49.     (set! from (+ from 1)))))
  50. ; call f, then restore foreground/background color
  51. (define with-color (lambda (f)
  52.   (let*
  53.     (
  54.       (bg (car (gimp-context-get-background)))
  55.       (fg (car (gimp-context-get-foreground))))
  56.     (list
  57.       (f)
  58.       (gimp-context-set-background bg)
  59.       (gimp-context-set-foreground fg)))))
  60. ; set context color to a random mix of foreground and background
  61. (define random-blend (lambda ()
  62.   (let*
  63.     (
  64.       (blend (blend (/ (random 1000) 1000)))
  65.       (fg (car (gimp-context-get-foreground)))
  66.       (bg (car (gimp-context-get-background))))
  67.     (gimp-context-set-foreground (list
  68.       (blend (car fg) (car bg))
  69.       (blend (cadr fg) (cadr bg))
  70.       (blend (caddr fg) (caddr bg)))))))
  71. ; generate a blender function that blends between two numbers with factor 'f'.
  72. (define blend (lambda (f)
  73.   (lambda (a b)
  74.     (+
  75.       (* a (- 1 f))
  76.       (* b f)))))
  77. ; adds one layer of greebles
  78. (define greeblestep (lambda (img img-size drawable overwrite-background select-args steps fuzz exposure)
  79.   ((with-undo-group img (lambda ()
  80.     (with-selection img (lambda ()
  81.       (list
  82.         ; build our random-rectangles selection
  83.         (apply (curry reselect img img-size) select-args)
  84.         ; paint the foreground/background
  85.         (swap-and-do drawable img
  86.           (combine
  87.             (curry2 gimp-edit-fill FOREGROUND-FILL)
  88.             (curry (thing-it drawable (curry2 gimp-dodgeburn exposure BURN MIDTONES)) steps))
  89.           (combine
  90.             (if overwrite-background (curry2 gimp-edit-fill BACKGROUND-FILL) (lambda (d) #t))
  91.             (curry (thing-it drawable (curry2 gimp-dodgeburn exposure DODGE MIDTONES)) steps)))
  92.         ; grab the border of our selection
  93.         (border-select img fuzz)
  94.         (with-color (lambda ()
  95.           (list
  96.             (gimp-context-set-foreground (list 0 0 0)) ; draw border in black
  97.             (gimp-edit-fill drawable FOREGROUND-FILL))))))))))))
  98. ; treats f as a single undo group
  99. (define with-undo-group (lambda (img f)
  100.   (guard
  101.     (curry gimp-image-undo-group-start img)
  102.     (curry gimp-image-undo-group-end img)
  103.     f)))
  104. ; executes 'first', then 'f', then 'last'. TODO: make error safe.
  105. (define guard (lambda (first last f)
  106.   (lambda x
  107.     (list (first) (apply f x) (last)))))
  108. ; partial application
  109. (define (curry fun . args) (lambda x
  110.   (apply fun (append args x))))
  111. ; 2.6 compatibility stub
  112. (define rectselect (if
  113.   (string=? (substring (car (gimp-version)) 0 3) "2.6")
  114.     (lambda (image operation x y width height) (gimp-rect-select image x y width height operation 0 0))
  115.     gimp-image-select-rectangle))
  116. ; select a bunch of rectangles at random
  117. (define reselect (lambda (img img-size size num range ratio)
  118.   (let*
  119.     (
  120.       (ch (car (gimp-selection-save img))))
  121.     (list
  122.       (gimp-selection-none img)
  123.       (loop 0 num (lambda (x)
  124.         (let*
  125.           (
  126.             (x (random (car img-size)))
  127.             (y (random (cadr img-size)))
  128.             (pair (random-one ratio)))
  129.           (my-select-rectangle-helper
  130.             x
  131.             y
  132.             (/ (random2n (/ size range) size) (car pair))
  133.             (/ (random2n (/ size range) size) (cadr pair))
  134.             (curry rectselect img CHANNEL-OP-ADD)))))
  135.       (script-fu-channel-grab img ch CHANNEL-OP-INTERSECT)))))
  136. ; randomly append or prepend a 1.
  137. ; used for vertical or horizontally scaled rectangles.
  138. (define random-one (lambda (n)
  139.   (if (= (random 2) 0)
  140.     (list n 1)
  141.     (list 1 n))))
  142. ; a select-rectangle wrapper that handles negative width/height
  143. (define my-select-rectangle-helper (lambda (x y w h f)
  144.   (let*
  145.     (
  146.       (xx (if (< w 0) (+ x w) x))
  147.       (yy (if (< h 0) (+ y h) y)))
  148.     (f xx yy (abs w) (abs h)))))
  149. ; random number from [-to..-from], [from..to]
  150. (define random2n (lambda (from to)
  151.   (let*
  152.     (
  153.       (tmp (+ (random (- to from)) from)))
  154.     (if (= (random 2) 0)
  155.       tmp
  156.       (- 0 tmp)))))
  157. ; execute f1, invert selection, execute f2, invert selection
  158. (define swap-and-do (lambda (d img f1 f2)
  159.   (let*
  160.     (
  161.       (w (car (gimp-drawable-width d)))
  162.       (h (car (gimp-drawable-height d))))
  163.     (list
  164.       (f1 d)
  165.       (gimp-selection-invert img)
  166.       (f2 d)
  167.       (gimp-selection-invert img)))))
  168. ; takes a bunch of functions and combines them into one that has the
  169. ; same arguments as each of them and calls them in turn
  170. (define combine (lambda x
  171.   (lambda y
  172.     (if (= (length x) 0)
  173.       ()
  174.       (append
  175.         (list (apply (car x) y))
  176.         (apply (apply combine (cdr x)) y))))))
  177. ; like curry, except it keeps the first argument
  178. (define (curry2 fun . args) (lambda x
  179.   (apply fun (append (list (car x)) args (cdr x)))))
  180. ; execute some action 'fn' over the entire image in subdivisions of 'divs'.
  181. (define thing-it (lambda (d fn)
  182.   (lambda (divs)
  183.     ((with-undo-group
  184.       (car (gimp-item-get-image d))
  185.       (lambda ()
  186.         (let*
  187.           (
  188.             (w (car (gimp-drawable-width d)))
  189.             (h (car (gimp-drawable-height d))))
  190.           (loop 0 (+ divs 1) (lambda (y)
  191.             (loop 0 (+ divs 1) (lambda (x)
  192.               (fn
  193.                 d
  194.                 2
  195.                 (floatarray (* (/ w divs) y) (* (/ h divs) x))))))))))))))
  196. ; source for floatarray:
  197. ; http://www.math.grinnell.edu/~rebelsky/Glimmer/Summer2006/GIMP/sam.scm
  198. ; coerce a list into a float-array
  199. (define floatarray (lambda floats
  200.   (let*
  201.     (
  202.       (len (length floats))
  203.       (vec (cons-array len 'double)))
  204.     (letrec
  205.       ((kernel (lambda (pos rest)
  206.         (if
  207.           (= pos len)
  208.           vec
  209.           (begin
  210.             (vector-set! vec pos (car rest))
  211.             (kernel (+ pos 1) (cdr rest)))))))
  212.       (kernel 0 floats)))))
  213. ; saves/restores active selection after 'f' is executed
  214. (define with-selection (lambda (img f)
  215.   (let*
  216.     (
  217.       (ch (car (gimp-selection-save img))))
  218.     (list
  219.       (f)
  220.       (script-fu-channel-grab img ch CHANNEL-OP-REPLACE)))))
  221. ; select the border of our selection using feather
  222. (define border-select (lambda (img fuzz)
  223.   (let*
  224.     (
  225.       (ch1 (car (gimp-selection-save img))))
  226.     (list
  227.       (gimp-selection-feather img fuzz)
  228.       (let*
  229.         (
  230.           (ch2 (car (gimp-selection-save img))))
  231.         (list
  232.           (script-fu-channel-grab img ch1 CHANNEL-OP-REPLACE)
  233.           (gimp-selection-invert img)
  234.           (gimp-selection-feather img fuzz)
  235.           (script-fu-channel-grab img ch2 CHANNEL-OP-INTERSECT)))))))
  236. ; remove a (temporary) channel after applying it as a selection
  237. (define script-fu-channel-grab (lambda (img ch op)
  238.   (list
  239.     (gimp-image-select-item img op ch)
  240.     (gimp-image-remove-channel img ch))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement