annotate src/laser/rasterize.clj @ 15:8ad629298649

major refactoring
author Robert McIntyre <rlm@mit.edu>
date Sun, 29 Aug 2010 19:02:26 -0400
parents db745c95aabd
children 52f544d05414
rev   line source
rlm@15 1 (ns laser.rasterize
rlm@15 2 (:use [rlm
rlm@15 3 image-utils
rlm@15 4 map-utils]
rlm@15 5 [clojure.contrib
rlm@15 6 [str-utils :only [str-join re-gsub]]
rlm@15 7 [seq :only [indexed]]
rlm@15 8 [math]])
rlm@15 9 (:import [ij ImagePlus IJ]))
rlm@0 10
rlm@15 11 ;(import '(java.io File))
rlm@15 12 ;(import '(org.apache.commons.io FileUtils))
rlm@15 13 ;(import '(javax.imageio ImageIO) )
rlm@0 14
rlm@0 15
rlm@15 16 (set! *print-length* 20)
rlm@1 17 (def feed 120)
rlm@1 18 (def dpi [500, 500])
rlm@8 19
rlm@8 20
rlm@15 21 ;;; this process is divided into two tasks,
rlm@15 22 ;;; creating the raster g-code, which sweeps back and forth
rlm@15 23 ;;; and creating the gmask, which turns the laser on and off.
rlm@1 24
rlm@1 25
rlm@15 26 ;;; we'll be using frame-hashes, which represent picutres as
rlm@15 27 ;;; a 3D vector field over 2D space, with the vectors representing
rlm@15 28 ;;; the rgb values at that particulat point.
rlm@2 29
rlm@15 30 (defn select-row
rlm@15 31 "returns a frame hash that is just a single line at the chosen y"
rlm@15 32 [y window]
rlm@15 33 (filter-keys (comp (partial = y) last) window))
rlm@1 34
rlm@15 35 (defn make-rows [pic]
rlm@15 36 (map (partial sort #(< (first %1) (first %2)))
rlm@15 37 (partition-by last
rlm@15 38 (sort (fn [[x1 y1][x2 y2]] (> y2 y1))
rlm@15 39 (map first (filter-vals (partial = black) pic))))))
rlm@1 40
rlm@0 41
rlm@15 42 ;;; generate rastering g-code
rlm@1 43
rlm@3 44 (defn raster-preamble []
rlm@3 45 (str-join \newline
rlm@3 46 ["M63 P0\nG61"
rlm@15 47 (str "F" feed)
rlm@3 48 "M101"
rlm@8 49 "M3 S1\n"]))
rlm@3 50
rlm@4 51 (defn raster-epilogue []
rlm@4 52 (str-join \newline
rlm@8 53 ["M63 P0"
rlm@4 54 "M5"
rlm@8 55 "M2\n"]))
rlm@3 56
rlm@4 57 (defn raster-comment [string]
rlm@4 58 (str "(" (re-gsub #"[()]" "" string) ")"))
rlm@1 59
rlm@5 60
rlm@7 61 ;this is a sequence of rows
rlm@7 62
rlm@7 63 ;(defn span [row]
rlm@7 64 ; (let [sorted-row (sort #(< (first %1) (first %2)) row)]
rlm@7 65 ; (vector (first sorted-row) (last sorted-row))))
rlm@7 66
rlm@7 67
rlm@14 68
rlm@14 69 (defn row->gcode [[x-dpi y-dpi] forward? row]
rlm@14 70
rlm@14 71 (let [[x1 y1] (if forward? (last row) (first row))
rlm@14 72 [x2 y2] (if forward? (first row) (last row))]
rlm@14 73
rlm@14 74
rlm@14 75 ; (let [[x1 y1] (first row)
rlm@14 76 ; [x2 y2] (last row)
rlm@14 77 ; x2 (+ x2 (* x-dpi 0.318))]
rlm@13 78
rlm@13 79
rlm@13 80 ; (println x2)
rlm@8 81 (str (format "G0 X%.3f Y%.3f\n"
rlm@7 82 (float (* x1 (/ x-dpi)))
rlm@7 83 (float (* y1 (/ y-dpi))))
rlm@7 84
rlm@7 85 (format "G1 X%.3f Y%.3f\n"
rlm@7 86 (float (* x2 (/ x-dpi)))
rlm@7 87 (float (* y2 (/ y-dpi)))))))
rlm@7 88
rlm@15 89
rlm@15 90 (defn generate-gcode [pic]
rlm@15 91 (str (raster-preamble)
rlm@15 92 (str-join ""
rlm@15 93 (map
rlm@15 94 (fn [[index row]]
rlm@15 95 (row->gcode dpi (even? index) row))
rlm@15 96 (indexed (make-rows pic))))
rlm@15 97 (raster-epilogue)))
rlm@15 98
rlm@15 99
rlm@15 100
rlm@15 101
rlm@15 102
rlm@15 103
rlm@15 104
rlm@15 105
rlm@15 106
rlm@15 107
rlm@15 108
rlm@15 109
rlm@15 110
rlm@15 111
rlm@15 112
rlm@15 113
rlm@15 114
rlm@15 115
rlm@15 116
rlm@7 117 (defn gather-row [row]
rlm@7 118 (let [base [[(first (first row)) (first (first row))]]]
rlm@7 119 ; (println base)
rlm@7 120 (reduce
rlm@7 121 (fn colapse [collection new-n]
rlm@7 122
rlm@7 123 (let [collection (apply vector collection)
rlm@7 124 prevoius (last (last collection))
rlm@7 125 range-start (first (last collection))]
rlm@7 126 ; (println new-n)
rlm@7 127 ; (println prevoius)
rlm@7 128 ; (println range-start)
rlm@7 129 (if (<= new-n (+ prevoius 1))
rlm@11 130 (do ;(println "join")
rlm@7 131 ;(println (butlast collection))
rlm@11 132 (conj (apply vector (butlast collection))
rlm@11 133 (vector range-start new-n)))
rlm@11 134 (conj collection (vector new-n new-n)))))
rlm@7 135
rlm@7 136 base
rlm@11 137 (map first row))))
rlm@11 138
rlm@7 139
rlm@7 140
rlm@7 141
rlm@7 142 (defn row->gmask [[x-dpi y-dpi] forward? row]
rlm@11 143 (let [start (float (* (/ x-dpi) (first (first
rlm@11 144 (if forward?
rlm@11 145 (reverse row) row)))))]
rlm@11 146 (let [preamble (if-not forward?
rlm@7 147 (format "0 0 0 %.3f\n" start)
rlm@11 148 (format "0 0 1 %.3f\n" start))
rlm@7 149 body
rlm@11 150 (for [[x y]
rlm@11 151 (if forward?
rlm@11 152 (reverse (gather-row row))
rlm@11 153 (gather-row row))]
rlm@7 154 (let [x (float (* x (/ x-dpi)))
rlm@15 155 y (float (* y (/ x-dpi)))]
rlm@14 156 ;; x (+ x 0.159)];; shift by a small margin.
rlm@11 157 (if-not forward?
rlm@7 158 (str (format "0 0 1 %.3f\n" x)
rlm@7 159 (format "0 1 1 %.3f\n" y))
rlm@7 160
rlm@11 161 (str (format "0 0 0 %.3f\n" y)
rlm@11 162 (format "0 1 0 %.3f\n" x)))))]
rlm@7 163
rlm@7 164 (str preamble (str-join "" body)))))
rlm@7 165
rlm@7 166
rlm@7 167 (defn generate-gmask [pic]
rlm@7 168 (str "1 0 0 0\n"
rlm@8 169 (str-join "" (map (fn [[index row]]
rlm@11 170 (row->gmask dpi (even? index) row))
rlm@8 171 (indexed (make-rows pic))))))
rlm@8 172
rlm@11 173
rlm@11 174
rlm@8 175
rlm@8 176 ;;;; testing
rlm@8 177
rlm@15 178 (defn generate-files [pic]
rlm@15 179 (println "made-image")
rlm@15 180 (spit "/home/r/kevin/out.ngc" (generate-gcode pic))
rlm@15 181 (println "/home/r/kevin/out.ngc")
rlm@15 182 (spit "/home/r/kevin/out.gmask" (generate-gmask pic))
rlm@15 183 (println "/home/r/kevin/out.gmask")
rlm@15 184 pic)
rlm@8 185
rlm@15 186 (defn update-state []
rlm@15 187 (def sing "/home/r/kevin/sing.png")
rlm@15 188 (def pic (frame-hash (ImagePlus. sing)))
rlm@15 189 (def pic (b&w pic)))
rlm@8 190
rlm@15 191 (defn compare-gen-fn [n f cmp]
rlm@15 192 (let [theirs (re-split #"\n" (slurp cmp))
rlm@15 193 ours (re-split #"\n" (f pic))]
rlm@15 194 (println (format "%1$-25s%2$s" "OURS" "THEIRS"))
rlm@15 195 (println "_______________________________________")
rlm@15 196 (dorun (map (fn [[us them]] (println
rlm@15 197 (format "%1$-25s%2$s" us them)))
rlm@15 198 (take n (partition 2 (interleave ours theirs)))))))
rlm@8 199
rlm@15 200 (defn compare-gcode [n]
rlm@15 201 (compare-gen-fn n generate-gcode "/home/r/kevin/reference.ngc"))
rlm@15 202 (defn compare-gmask [n]
rlm@15 203 (compare-gen-fn n generate-gmask "/home/r/kevin/reference.gmask"))
rlm@15 204
rlm@8 205
rlm@8 206
rlm@8 207
rlm@8 208