Create a piece of art using code
Clojure CSS Other
Switch branches/tags
Nothing to show
Clone or download

README.md

DevArt Co(de)Factory

CodeFactory @ Barbican

Photo credit: Andrew Meredith

This project was commissioned by Google & Barbican as part of DevArt at the Digital Revolutions exhibition.

Visit devartcodefactory.com to view the live project, learn more about it, browse the online gallery and create your own piece...

This repository contains all source code and relevant assets created between January - August 2014, which I hope might be valuable for others interested in studying a complete & non-trivial Clojure/ClojureScript project (6200+ LOC). Furthermore, this project serves as the first public realworld use case of the various libraries of the thi.ng collection. You're very welcome to submit bug fixes & patches, but this release is primarily meant for educational purposes.

Building this project

Module overview

The project uses multiple source folders to group its various modules:

/assets

Contains sketches, screenshots, renders, 3d models and technical drawings created during development. The /lcd subdir contains the Fritzing source file for the daisy chaining LCD PCB, controlled via Raspberry PI. Use Fritzing to re-generate the PCB fabrication files.

/src-cljs

This folder contains the entire frontend source code, written in ClojureScript. It requires no 3rd party libraries apart from those listed (and automatically downloaded by Leiningen) in project.clj. The main application and entry point is in the codefactory.app namespace.

The frontend is a single page application and makes heavy use of core.async's pub-sub bus/mechanism to deal with event handling and communicate between its various modules. Each module stores its state in a local atom. Furthermore, there's an extensive configuration to customize module & routing behavior. See codefactory.config namespace for further details.

At the heart of the app's functionality are two libraries: thi.ng/geom & thi.ng/morphogen. All WebGL related functionality is provided by the geom-webgl module, whereas the actual shape operations are realized by the Morphogen DSL on top of the geom-core libs.

/src-fabricate

This folder contains a complete Leiningen project and the source code to generate 3d models & render scenes (for LuxRender) of the physical exhibit plan, as well as the generator for the 446 3D printed tiles used to create the 2.4 x 3.0 metres large flute structure and the cladding for the plinths holding the Nexus 10 tablets in the gallery. These structures are created from a 2D bezier curve used as lathe to form a tubular quad mesh, and each quad then taken as seed for a Morphogen shape transformation, using only the same 8 shape operations as offered by the Web UI. The generated 3D STL files and technical drawings for these structures are located in the /assets folder.

structure

panels

/src-gae

Contains the complete Clojure backend and wrapper for the Google AppEngine API & core services. The main app itself is written as a standard Ring handler using Compojure. The AppEngine wrapper started out using some ideas & snippets from the outdated appengine-magic project, but ended up differing quite substantially and might be developed further...

At the heart of the backend is a simple REST style API, which supports both JSON and EDN formats (though the web UI is only using EDN, since it's native to Clojure). Each API handler defines a number of validators which are defined in this file: /src-gae/codefactory/config.clj and executed via the thi.ng/validate library (similarily this library is also used by the frontend router).

3D objects created with the Co(de)Factory UI are only defined & stored as abstract syntax trees (ASTs). However, as part of the object submission process, the backend is generating 3D STL files of the uploaded code structures (ASTs) and uses the geom-svg module to render 3D SVG previews and thi.ng/luxor to create a render scene bundle incl. camera, lights & materials for LuxRender. Only selected objects will receive an HD LuxRender-rendered asset (generated on Google Compute Engine instances), which will be featured on the website's homepage. All generated assets can be downloaded via these REST API handlers:

curl -X GET http://devartcodefactory.com/api/1.0/objects/{{OBJECT-UUID}}/stl > foo.stl
curl -X GET http://devartcodefactory.com/api/1.0/objects/{{OBJECT-UUID}}/preview > foo.svg
curl -X GET http://devartcodefactory.com/api/1.0/objects/{{OBJECT-UUID}}/lux > foo.zip

Example SVG render & Luxrendered version of piece submitted by Mathew Boor:

SVG Luxrender
cell svg render cell lux render

Here's also an example how to use the API to download the AST of an object and use it with Morphogen from the REPL to generate a PLY mesh file:

(ns user
  (:require
    [thi.ng.morphogen.core :as mg]
    [clj-http.client :as http]
    [clojure.edn :as edn]))

(def base-url "http://devartcodefactory.com/api/1.0/objects/")

(defn codefactory-ply-mesh
  "Downloads AST for given object UUID and saves PLY mesh in project root dir.
  Note: This example only works for objects with box seeds (for brevity)."
  [id]
  (let [response (http/get (str base-url id) {:accept "application/edn"})
        body     (edn/read-string (:body response))
        ast      (get-in body [:body :tree])]
    (mg/save-mesh (mg/seed-box 1) ast (str id ".ply"))))

(codefactory-ply-mesh "788ecd4a-712c-4eee-9014-b1ed99ad6708")

meshlab

Amazing object submitted by Dianne N., transformed from a single cube...

/src-html

The source versions of the various HTML files used for the online version, Barbican gallery kiosks & workshops run with teenagers as part of Google & Barbican's Young Creators initiative. There're only minor differences between each version (mainly config settings). All development is supposed to only happen with the staging.html file and then changes applied to others later.

/src-less

All stylesheets used by the webapp, defined using LESS. The file minxins.less contains various reusable snippets.

/src-rpi

Python source code for the Raspberry PI to control the DMX gallery lighting & LCD panels displaying object credits.

Build requirements

  • Google AppEngine 1.9.8
  • Java 1.7
  • Leiningen 2.4.0
  • Clojure 1.6.0
  • ClojureScript 0.0-2280
  • lein-cljsbuild 1.0.3
  • NPM 1.4.x
  • Grunt 0.4.x

Running locally

cd devart-codefactory

# download & install AppEngine dependencies into local /lib dir
./install-dependencies.sh

# install grunt dependencies
npm install

# build & compress HTML & CSS
grunt prod

# compile ClojureScript/JS app
lein do cljsbuild clean, cljsbuild once prod

# launch AppEngine dev server
./launch.sh

Note: install-dependencies.sh first uses Leining to download all required dependencies and then copies the required jar files from your local Maven repo into this dir: /war/WEB-INF/lib. It assumes the local Maven repo cache (used by Leiningen) is the default ~/.m2/repository. If that's not the case, please edit the path first before running the script...

Then open your browser and navigate to http://localhost:8080/staging/

If you end up hacking the ClojureScript source (in /src-cljs) and want (almost) instant automatic recompilation, open a separate terminal and use this invocation of cljsbuild instead:

lein do cljsbuild clean, cljsbuild auto dev

Likewise, for HTML/LESS editing, it's recommended to use the grunt default target, which will autocompile changes into the staging directory...

Google API key

The backend generates an unique URL for each submitted piece, which due to the nature of UUIDs is not human readable. Therefore the API handler responsible makes use of Google's goo.gl URL shortener to create shorter versions, but requires a valid Google API key to do so. This key needs to be inserted at the bottom of the /src-gae/codefactory/config.clj file before launching the server. You can run the app without such a key, though in this case your objects can of course only be accessed via their original long URL.

License

The source code of this project is licensed under the Apache Software License 2.0.

All non-code assets are published under the Creative Commons Attribution-NonCommercial license.

© 2014 Karsten Schmidt