Restrict gcode api surface to gcode-seq and scene->gcode-seq
This commit is contained in:
parent
96caa61987
commit
c88a4bedc8
1 changed files with 106 additions and 49 deletions
|
|
@ -2,48 +2,44 @@
|
|||
"Provides functions to move from geometry types provided by thi.ng to gcode
|
||||
so you can plot them."
|
||||
(:require [thi.ng.geom.core :as g]
|
||||
[thi.ng.geom.types]
|
||||
[thi.ng.geom.vector :as v]
|
||||
[thi.ng.geom.circle :as c])
|
||||
(:import [thi.ng.geom.types Line2 LineStrip2 Circle2]))
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defprotocol GCode
|
||||
"Convert thi.ng.geom types into sequences of GCode to plot them. The GCode
|
||||
instructions are given as a sequence of vectors, where each vector is given
|
||||
as [x y z]."
|
||||
(->gcode [_] [_ r]
|
||||
"Returns G01 movements on the x, y, and z axis. Z is constantly 1000 in the
|
||||
current implementation, but this might change in the future. The optional
|
||||
parameter `r` can be used to adjust the resolution."))
|
||||
;; scroll down for a rich comment with usage examples
|
||||
|
||||
(defn- point-seq->gcode [pts]
|
||||
(let [vertices pts
|
||||
(defn- vertices->gcode-verts [vertices]
|
||||
(let [[f-x f-y] (first vertices)
|
||||
[l-x l-y] (last vertices)]
|
||||
(conj (mapv (fn [[x y]]
|
||||
[x y 0]) vertices)
|
||||
[l-x l-y 1000])))
|
||||
(concat
|
||||
[[f-x f-y 1000]]
|
||||
(mapv (fn [[x y]] [x y 0]) vertices)
|
||||
[[l-x l-y 1000]])))
|
||||
|
||||
(defn gcode-seq->str [gcode-seq]
|
||||
(defn- gcode-verts->gcode-seq [gcode-verts]
|
||||
(map (fn [[x y z]]
|
||||
(str "G01 X" x " Y" y " Z" z)) gcode-seq))
|
||||
(str "G01 X" x " Y" y " Z" z)) gcode-verts))
|
||||
|
||||
(extend-protocol GCode
|
||||
Line2
|
||||
(->gcode
|
||||
([_] (point-seq->gcode (:points _)))
|
||||
([_ r] (->gcode _)))
|
||||
(defn- ->gcode-verts
|
||||
([geom]
|
||||
(vertices->gcode-verts (g/vertices geom)))
|
||||
([geom r]
|
||||
(vertices->gcode-verts (g/vertices geom r))))
|
||||
|
||||
LineStrip2
|
||||
(->gcode
|
||||
([_] (point-seq->gcode (:points _)))
|
||||
([_ r] (->gcode _)))
|
||||
(def gcode-seq
|
||||
"Convert thi.ng.geom types into a sequence of G-Code to plot them. The G-Code
|
||||
instructions are given as a sequence of vectors, where each vector is given
|
||||
as [x y z].
|
||||
|
||||
Circle2
|
||||
(->gcode
|
||||
([_] (point-seq->gcode (:points (g/as-polygon _))))
|
||||
([_ r] (point-seq->gcode (:points (g/as-polygon _ r))))))
|
||||
Returns G01 movements on the x, y, and z axis. Z is constantly 1000 in the
|
||||
current implementation, but this might change in the future. The optional
|
||||
parameter `r` can be used to adjust the resolution."
|
||||
(comp gcode-verts->gcode-seq ->gcode-verts))
|
||||
|
||||
(defn scene->gcode
|
||||
(defn geom? [x]
|
||||
(str/starts-with? (pr-str x) "#thi.ng.geom."))
|
||||
|
||||
;; (pr-str (c/circle 20)) ;; => "#thi.ng.geom.types.Circle2{:p [0.0 0.0], :r 20.0}"
|
||||
|
||||
(defn scene->gcode-seq
|
||||
"Converts a scene into a sequence of gcode instructions. A scene is an
|
||||
arbitrarily nested vector of geom instances.
|
||||
|
||||
|
|
@ -52,25 +48,86 @@
|
|||
object."
|
||||
[scene]
|
||||
(loop [[el & rs] scene
|
||||
res []]
|
||||
result []]
|
||||
(cond
|
||||
(vector? el) (recur (scene->gcode el) res)
|
||||
(map? el) (recur rs res)
|
||||
:else (if (seq rs)
|
||||
(recur rs (conj res (gcode-seq->str (->gcode el))))
|
||||
(flatten res)))))
|
||||
(nil? el) result
|
||||
(sequential? el) (recur rs (concat result (scene->gcode-seq el))) ;; recursively convert sequences
|
||||
(geom? el) (recur rs (conj result (gcode-seq el))) ;; convert geoms
|
||||
(map? el) (recur rs result)))) ;; ignore attribute maps
|
||||
|
||||
;; TODO: Resolution for scenes?
|
||||
;; `g/vertices` fails when called with a second arg for `r/rect`
|
||||
|
||||
(comment
|
||||
;; example usage:
|
||||
(require '[thi.ng.geom.line :as l])
|
||||
(require '[thi.ng.geom.circle :as c])
|
||||
(require '[thi.ng.geom.rect :as r])
|
||||
|
||||
;; convert a single element
|
||||
(->
|
||||
(->gcode (c/circle) 10)
|
||||
(gcode-seq->str))
|
||||
;; `gcode-seq`` returns a sequence of gcode strings, where z=0 means "down"
|
||||
(gcode-seq (l/line2 [100 100] [200 200]))
|
||||
;; => ("G01 X100.0 Y100.0 Z1000"
|
||||
;; "G01 X100.0 Y100.0 Z0"
|
||||
;; "G01 X200.0 Y200.0 Z0"
|
||||
;; "G01 X200.0 Y200.0 Z1000")
|
||||
|
||||
;; convert a tree of elements
|
||||
(scene->gcode
|
||||
[(c/circle 10)
|
||||
[(c/circle [0 20] 10)
|
||||
(c/circle [0 40] 10)]])
|
||||
;; you can pass a second argument to increase or decrease resolution
|
||||
(gcode-seq (c/circle) 10)
|
||||
;; => ("G01 X1.0 Y0.0 Z1000"
|
||||
;; "G01 X1.0 Y0.0 Z0"
|
||||
;; "G01 X0.8090169943749475 Y0.5877852522924731 Z0"
|
||||
;; "G01 X0.30901699437494745 Y0.9510565162951535 Z0"
|
||||
;; "G01 X-0.30901699437494734 Y0.9510565162951536 Z0"
|
||||
;; "G01 X-0.8090169943749473 Y0.5877852522924732 Z0"
|
||||
;; "G01 X-1.0 Y1.2246467991473532E-16 Z0"
|
||||
;; "G01 X-0.8090169943749476 Y-0.587785252292473 Z0"
|
||||
;; "G01 X-0.30901699437494756 Y-0.9510565162951535 Z0"
|
||||
;; "G01 X0.30901699437494723 Y-0.9510565162951536 Z0"
|
||||
;; "G01 X0.8090169943749473 Y-0.5877852522924734 Z0"
|
||||
;; "G01 X0.8090169943749473 Y-0.5877852522924734 Z1000")
|
||||
|
||||
;; `scene->gcode-seq` converts a tree of elements into a sequence of gcode drawing instructions
|
||||
(scene->gcode-seq
|
||||
[[(r/rect [0 0] [10 10]) {:attributes/ignored? true}]
|
||||
(r/rect [0 0] [10 10])
|
||||
[(r/rect [5 5] [15 15])
|
||||
(r/rect [20 20] [40 40])
|
||||
[(r/rect [5 5] [15 15])]
|
||||
(r/rect [20 20] [40 40])]])
|
||||
;; => (("G01 X0.0 Y0.0 Z1000"
|
||||
;; "G01 X0.0 Y0.0 Z0"
|
||||
;; "G01 X10.0 Y0.0 Z0"
|
||||
;; "G01 X10.0 Y10.0 Z0"
|
||||
;; "G01 X0.0 Y10.0 Z0"
|
||||
;; "G01 X0.0 Y10.0 Z1000")
|
||||
;; ("G01 X0.0 Y0.0 Z1000"
|
||||
;; "G01 X0.0 Y0.0 Z0"
|
||||
;; "G01 X10.0 Y0.0 Z0"
|
||||
;; "G01 X10.0 Y10.0 Z0"
|
||||
;; "G01 X0.0 Y10.0 Z0"
|
||||
;; "G01 X0.0 Y10.0 Z1000")
|
||||
;; ("G01 X20.0 Y20.0 Z1000"
|
||||
;; "G01 X20.0 Y20.0 Z0"
|
||||
;; "G01 X40.0 Y20.0 Z0"
|
||||
;; "G01 X40.0 Y40.0 Z0"
|
||||
;; "G01 X20.0 Y40.0 Z0"
|
||||
;; "G01 X20.0 Y40.0 Z1000")
|
||||
;; ("G01 X5.0 Y5.0 Z1000"
|
||||
;; "G01 X5.0 Y5.0 Z0"
|
||||
;; "G01 X15.0 Y5.0 Z0"
|
||||
;; "G01 X15.0 Y15.0 Z0"
|
||||
;; "G01 X5.0 Y15.0 Z0"
|
||||
;; "G01 X5.0 Y15.0 Z1000")
|
||||
;; ("G01 X20.0 Y20.0 Z1000"
|
||||
;; "G01 X20.0 Y20.0 Z0"
|
||||
;; "G01 X40.0 Y20.0 Z0"
|
||||
;; "G01 X40.0 Y40.0 Z0"
|
||||
;; "G01 X20.0 Y40.0 Z0"
|
||||
;; "G01 X20.0 Y40.0 Z1000")
|
||||
;; ("G01 X5.0 Y5.0 Z1000"
|
||||
;; "G01 X5.0 Y5.0 Z0"
|
||||
;; "G01 X15.0 Y5.0 Z0"
|
||||
;; "G01 X15.0 Y15.0 Z0"
|
||||
;; "G01 X5.0 Y15.0 Z0"
|
||||
;; "G01 X5.0 Y15.0 Z1000"))
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue