This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-25
Channels
- # announcements (16)
- # babashka (110)
- # babashka-sci-dev (11)
- # beginners (50)
- # biff (3)
- # calva (1)
- # clj-commons (19)
- # clj-kondo (1)
- # clojure (17)
- # clojure-art (19)
- # clojure-austin (5)
- # clojure-berlin (2)
- # clojure-denmark (3)
- # clojure-europe (101)
- # clojurescript (84)
- # clr (1)
- # core-async (2)
- # emacs (3)
- # helix (5)
- # honeysql (4)
- # hyperfiddle (8)
- # introduce-yourself (2)
- # jobs (1)
- # lsp (18)
- # membrane (3)
- # reagent (5)
- # releases (3)
- # shadow-cljs (10)
- # tools-deps (24)
I'm having a lot of fun generating Lego models with Clojure and then rendering them with http://Stud.io, here's my two favorite gifs that I've made so far.
That is fantastic. Had no idea there were tools to help (but of course there are, on the internet… 🙂 ) Care to explain the process a bit more?
I'm really flattered! So the way this is done is that I wrote a little program that writes an https://www.ldraw.org/article/218.html file, the details of the format are in the link but basically it's the open standard for modeling with Legos. I write each part as its own line in the ldraw file, (keeping in mind the dimensions of the lego brick, 20 x 20 x 24 Lego Draw Units). In the conventions of the ldraw file format, one part out of a lego model looks like this:
1 4 0.0 0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0 -1.0 0.0 0.0 18654.dat
where which is generalized as
1 <colour> x y z a b c d e f g h i <file>
The leading 1
declares that this is a lego part, the color is represented by an integer, and the x y z a b c d e f g h i
represent a transformation matrix in either of the following forms:
/ a d g 0 \ / a b c x \
| b e h 0 | | d e f y |
| c f i 0 | | g h i z |
\ x y z 1 / \ 0 0 0 1 /
And here is my code snippet that does the magic:(ns greenbeam.core
(:gen-class)
(:require [clojure.string :as str]
[ :as io]
[clojure.core.matrix :as matrix]))
(defn part [color [[a b c x] [d e f y] [g h i z] _] file]
[1 color x y z a b c d e f g h i file])
(defn pin-connector-perpendicular-3L-with-4-pins
[color x y z a b c d e f g h i]
(part color x y z a b c d e f g h i "3005.dat"))
(def origin (matrix/identity-matrix 4))
;; 90 degree in y direction
(def xm1 [[0 0 1 0]
[0 1 0 0]
[-1 0 0 0]
[0 0 0 1]])
;; 90 degree in x direction
(def xm2 [[1 0 0 0]
[0 0 -1 0]
[0 1 0 0]
[0 0 0 1]])
(def intervals-of-twenty (iterate #(+ % 20) 0))
(defn xmf [x y z]
[[1 0 0 x]
[0 1 0 y]
[0 0 1 z]
[0 0 0 1]])
(defn brick18654
[color xm]
(part color xm "18654.dat")
)
(defn get-locations [n]
(for [x (take n intervals-of-twenty)
y (take n intervals-of-twenty)
z (take n intervals-of-twenty)]
(xmf x y z)))
(defn write-file
[filename & _]
(let [locations (get-locations 30)
rotated-locations (map #(matrix/transform % (rand-nth [xm1 xm2 origin])) locations)
parts (map #(brick18654 %1 %2) (repeatedly #(rand-int 7)) rotated-locations)]
(spit filename (str/join " " ["0" "FILE" filename "\n"]))
(doseq [part parts]
(spit filename (str/join " " part) :append true)
(spit filename "\n" :append true))))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(let [filename "model.ldr"]
(write-file filename)))
As implemented, this will generate quite a large (30x30) block of 1L techic liftarms in random colors.
Then I open the .ldr file with http://stud.io and I render it
The code above is a bit crufty, not really ready for the gaze of the world, but such as it is, I give it to you 😁
That's a great idea
I'm interested in writing a technic-focused CAD tool, with physics and stuff
@USDPTD3FY some time ago, I had a shelved project that was basically a limited LEGO editor that was modal and keyboard-focused and could be scripted, as well!
@U04S798T3GW that sounds awesome! Is that project open source?
No, it's not, sorry! I didn't get too far beyond the conceptual, but I did find a good base to start on: there's this ANCIENT program buried in LDraw called LEdit and then there's also https://deeice.github.io/ldglite/
My idea was, until I became more proficient at 3D rendering and such, to use the C rendering part of the above and simply pass the ldraw output generated by the Lisp side along each time. I couldn't settle on which Lisp to use.
Inspired somewhat by https://nunnstudio.com/gallery/