Skip to content

Instantly share code, notes, and snippets.

@adam-james-v
Last active July 13, 2022 08:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adam-james-v/9c2a5e97175344b634708980417788ec to your computer and use it in GitHub Desktop.
Save adam-james-v/9c2a5e97175344b634708980417788ec to your computer and use it in GitHub Desktop.
Code for a mario Question Block Model (Clojure compiled to openscad)
;; code related to a youtube video:
;; https://youtu.be/3euk0-JF_tc
(ns qblock.main
(:require [clojure.string :as st]
[scad-clj.model :refer :all]
[scad-clj.scad :refer [write-scad]]))
(fn! 30)
(def PI (Math/PI))
(def ?-sk-a [[2 0] [4 0] [4 2] [7 2]
[8 3] [8 7] [7 8] [1 8]
[0 7] [0 4] [2 4] [2 6]
[6 6] [6 3.75] [3 3.75] [2 2.75]])
(def ?-sk-b [[0 0] [2 0] [2 1.25] [0 1.25]])
(defn ?
[h sc]
(->> (union
(->> (polygon ?-sk-b)
(translate [2 0])
(extrude-linear {:height (/ h sc)}))
(->> (polygon ?-sk-a)
(translate [0 2])
(extrude-linear {:height (/ h sc)})))
(translate [-4 -5])
(#(minkowski % (sphere 0.2)))
(scale [sc sc sc])
(rotate [(* PI 0.5) 0 0])
(color [(/ 247 255)
(/ 238 255)
(/ 234 255)
1])))
(defn block
[w]
(let [w2 (/ w 2.0) ;; half width
chs (/ w 20.0) ;; chamfer size
ch (->> (cube (* w 2) chs chs)
(rotate [(* PI 0.25) 0 0])
(translate [0 w2 w2]))
hpos (- w2 (* 2 chs))
hole (->> (cylinder (/ chs 2) chs)
(translate [hpos hpos w2]))
sch (union
hole
(rotate [0 0 (* PI 1)] hole)
(rotate [0 0 (* PI 0.5)] hole)
(rotate [0 0 (* PI -0.5)] hole)
ch
(rotate [0 0 (* PI 0.5)] ch)
(rotate [0 0 (* PI 1.5)] ch))]
(->> (difference
(cube w w w)
sch
(->> sch (rotate [(* PI 0.5) 0 0]))
(->> sch (rotate [0 (* PI 0.5) 0]))
(->> sch (rotate [(* PI 1) 0 0]))
(->> sch (rotate [(* PI 1.5) 0 0]))
(->> sch (rotate [0 (* PI 1.5) 0])))
(color [(/ 253 255)
(/ 170 255)
(/ 59 255)
1]))))
(defn bolts
[w]
(let [w2 (/ w 2.0) ;; half width
chs (/ w 20.0) ;; chamfer size
hpos (- w2 (* 2 chs))
bolt (->> (cylinder (/ chs 2) 1)
(translate [hpos hpos (- w2 2)]))
bolts (union
bolt
(rotate [0 0 (* PI 1)] bolt)
(rotate [0 0 (* PI 0.5)] bolt)
(rotate [0 0 (* PI -0.5)] bolt))]
(->> (union
bolts
(->> bolts (rotate [(* PI 0.5) 0 0]))
(->> bolts (rotate [0 (* PI 0.5) 0]))
(->> bolts (rotate [(* PI 1) 0 0]))
(->> bolts (rotate [(* PI 1.5) 0 0]))
(->> bolts (rotate [0 (* PI 1.5) 0])))
(color [(/ 30 255)
(/ 30 255)
(/ 30 255)
1]))))
;; assembly
(def asm
(->> (union
(block 100)
(bolts 100)
(apply union
(for [rt [0 0.5 1.0 1.5]]
(->> (? 3 7.25)
(translate [0 -50 0])
(rotate [0 0 (* PI rt)]))))))
(rotate [0 0 (* PI 0.5)]))
;; you can manually create the .scad file with write-scad
#_(spit "out.scad" (write-scad asm))
;; asm needs to be called here for watcher to compile it.
asm
;; watcher code for example.
;; saved in ./src/qblock/watcher.clj
;; run in your terminal with:
;; clj -m qblock.watcher qblock.cljc
(comment
(ns qblock.watcher
(:require [clojure.string :as st]
[scad-clj.model :refer :all]
[scad-clj.scad :refer [write-scad]]
[hawk.core :as hawk]))
(defn design-watch
[f]
(hawk/watch!
[{:paths [f]
:handler
(fn [ctx e]
(require '[scad-clj.model :refer :all]
'[scad-clj.scad :refer [write-scad]])
(->> (slurp f)
(format "[%s]")
load-string
(filter (complement var?))
write-scad
(spit "out.scad"))
ctx)}]))
(defn -main [& args] (design-watch (first args)))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment