Skip to content

Latest commit

 

History

History
369 lines (290 loc) · 16.7 KB

index.org

File metadata and controls

369 lines (290 loc) · 16.7 KB

thi.ng/geom

Contents

About the project

Overview

Note: This library relies on the new conditional reader syntax of recent Clojure & Clojurescript versions and therefore is not compatible with Clojure versions < 1.7.0

This project is part of the thi.ng collection of Clojure & Clojurescript libraries. It constitutes the current chapter-in-writing in a long, ongoing quest to create a comprehensive, cross-platform, yet easy-to-use API for 2D/3D geometry operations, both common and more niché. Since geometry is fundamental to so many aspects of design production, as with its Java based predecessor toxiclibs, the objective is not to produce a graphics engine for games or other specific use cases, but aims to provide geometry related functionality in a minimal, modular and as re-usable as possible context, thus making it easy to integrate into a wide number of scenarios: from architecture, digital fabrication to data visualization, generative design in general. We attempt to realise this goal by defining almost all operations as polymorphic protocols (currently approx. 50 of them). These are implemented to different extends by the various basic entities/types and together form a small domain-specific language (whilst remaining fully extensible) to easily create, transform, visualise & export geometry. At the core of this DSL is an extensive (and still growing) set of vector, matrix & quaternion types/operations, which the rest of the library is built on, currently:

Geometric entities

2D3D
Vec2Vec3
Matrix32Matrix44
Quaternion
Line2Line3
LineStrip2LineStrip3
Bezier2Bezier3
Circle2Sphere
Ellipse2 (TBD)Ellipsoid (TBD)
Rect2AABB
Quad2 (TBD)Quad3
Tetrahedron
Triangle2Triangle3
Polygon2Polygon3 (TBD)
Path2Path3 (TBD)
Plane
BasicMesh (polygon soup)
GMesh (navigatable)
Point quadtreePoint octree
SVO (experimental)
Isosurface (experimental)

Once the protocol API is finalized an overview table/graph will show which types implement which protocols. For now please consult the source code to see which operations are supported.

Geometry operations

In addition to these types, the library also implements these common operations:

  • Automatic spline generation from list of points
  • Parallel-transport frame sweep mesh generation
  • Basic SVG path parsing
  • 2D Delaunay triangulation
  • 2D convex hull
  • Shape extrusion as solid or walled mesh
  • Tesselation of simple 2D polygons (no holes)
  • Basic insetting of simple 2D polygons (no miter support)
  • Sutherland-Hodgeman clipping of 2D polygons
  • Entity area, circumference & volume calculations for all implemented types
  • 2D/3D entity intersection checks (vs. line, ray, shape)
  • 2D/3D entity to mesh conversion (w/ many options)
  • Access entities as graph-like structures (vertices/edges)
  • Entity sampling (at fixed resolution or uniform distance)
  • Entity subdivision (only lines, triangles, rects, quads, tetrahedrons)
  • Subdivision meshes (Catmull-Clark, Doo-Sabin, Butterfly)
  • 3D Boolean operations on meshes (union, difference, intersection)
  • 3D geometry export (PLY, STL, OBJ, OFF formats)

API scope

Since the core lib does not provide any display & rendering functionality at all, a number of support modules are being worked on, incl. WebGL & SVG support via Clojurescript and wrappers & GUI libraries for JOGL based desktop apps. Together with sister libraries like luxor, it’s also possible to generate complete 3D scenes for high quality & high resolution rendering using Luxrender.

Furthermore, providing all functionality under a common API for both Clojure & Clojurescript, makes it trivial to offload heavy operations (e.g. large mesh processing) to the server side.

Library module structure

The project has been structured into a number of modules, each addressing a different level of abstraction and to group namespaces based on functionality. This reduces potential code bloat for CLJS applications, but should also make it less daunting for newcomers to navigate this quite large project.

geom-core

module repo | CrossCLJ info

This module forms the library’s core and is required by all others. It defines approx. 50 protocols and provides implementations of fundamental geometry types/functions like 2d/3d vector algebra, matrices, quaternion (and related convenience constructors & conversions) and a number of often needed utility functions to deal with point collections, normals, sampling, triangles etc.

geom-types

module repo | CrossCLJ info

This module defines all high-level 2d/3d data types and implementations of the various core protocols for each. From a user perspective this module should be considered part of the core, however it’s been split out to dramatically reduce code size for use cases where only vectors/matrix ops are needed.

geom-meshops

module repo | CrossCLJ info

This module provides several tools & operations related to working with meshes, incl. I/O, subdivisions, Delaunay triangulation, cleaning, CSG/Boolean mesh merge etc.

geom-physics

module repo | CrossCLJ info

This module consists of a simple particle-based physics engine with Verlet integration and support for behaviors and constaints, both for individual particles and global. Particles can be connected with springs of varying stiffness as well as made interdependent using positive or negative force fields (attractors).

geom-svg

module repo | CrossCLJ info

A module to help with building SVG based visualizations of geom entities using hiccup compatible syntax. Includes a customizable 3D mesh renderer w/ software shader support.

geom-viz

module repo | CrossCLJ info

Declarative, highly customizable 2D data visualization module with ~10 different layout methods, 3 axis types, cartesian and polar domain support. Currently SVG only, but planned to be format-independent.

geom-voxel

module repo | CrossCLJ info

An experimental implementation of a in-memory sparse voxel tree (SVO) and related functionality to extract isosurface meshes from the tree.

geom-webgl

module repo | CrossCLJ info

This is a pure CLJS module and provides a common WebGL functionality (context creation, shader management & presets, buffer management, textures, FBO etc.), as well as a number of conversion & rendering functions to simplify the use of types defined in the geom-types module under CLJS with WebGL.

Status

The project has been in development since late 2011 and is currently in its 4th iteration/rewrite cycle. It should still be considered BETA quality. On the other hand, the library has already been used successfully in several commercial projects over the past 2 years and can be considered stable for most use cases.

A full test suite, website & tutorials are actively being worked on.

Example usage

Demo repository for all thi.ng libraries:

A preliminary list of other projects using this library:

Several small examples are still included in this repo (but will be migrated to the demo repo soon):

Building & testing this project

This project is written in a literate programming format and requires Emacs & Org-mode to generate usable source code. Assuming both tools are installed, the easiest way to generate a working project is via command line (make sure emacs is on your path or else edit its path in tangle.sh):

git clone https://github.com/thi-ng/geom.git
cd geom

# tangle all modules...
./tangle-all.sh

# ...or just tangle an individual module
./tangle.sh geom-core/src/*.org geom-core/test/*.org

# ...or an individual file
./tangle.sh geom-core/src/utils.org

Tangling is the process of extracting & combining source blocks from .org files into an actual working project/source tree. This project currently consists of 30 namespaces and 6800+ lines of code, the tangling of which takes approx. 20 secs.

Once tangling is complete, you can cd into the generated project directory of a module (babel in this case) and then use lein as usual.

Testing

The project.clj files of each module define an alias to trigger a complete build & tests for both CLJ & CLJS versions.

cd <<module-name>>/babel
lein cleantest # some tests currently fail due to still missing protocol impls

Important note: Due to the newness of the conditional reader expressions and the CLJC file format introduced with Clojure 1.7, the lein test task does currently not find any of the Clojure tests automatically and you’ll need to specify them manually as argument to this command. E.g. like this:

lein test thi.ng.geom.core.test.core

Afterwards, to build the Clojurescript version simply run lein cljsbuild test from the same directory. A small HTML harness for the resulting JS file is also located in that folder (babel/index.html), allowing for further experimentation in the browser.

Working with the REPL

Editing code blocks / files in Org-mode, then re-loading & testing changes is quite trivial. Simply launch a REPL (via lein or Emacs) as usual. Everytime you’ve made changes to an .org file, re-tangle it from Emacs or tangle.sh, then reload the namespace in the REPL via (require 'thi.ng.geom... :reload) or similar.

Injected properties

Leiningen project file

(defproject <<project-name>> "<<conf-version()>>"
  :description  "thi.ng geometry kit - meta project spec including all modules"
  :url          "<<conf-project-url>>"
  :license      {:name "Apache Software License"
                 :url  "http://www.apache.org/licenses/LICENSE-2.0"
                 :distribution :repo}
  :scm          {:name "git"
                 :url  "<<conf-project-url>>"}

  :dependencies [[thi.ng/geom-core "<<conf-version()>>"]
                 [thi.ng/geom-types "<<conf-version()>>"]
                 [thi.ng/geom-meshops "<<conf-version()>>"]
                 [thi.ng/geom-physics "<<conf-version()>>"]
                 [thi.ng/geom-svg "<<conf-version()>>"]
                 [thi.ng/geom-viz "<<conf-version()>>"]
                 [thi.ng/geom-voxel "<<conf-version()>>"]
                 [thi.ng/geom-webgl "<<conf-version()>>"]]

  :pom-addition [:developers [:developer
                              [:name "Karsten Schmidt"]
                              [:url "http://postspectacular.com"]
                              [:timezone "0"]]])

Release history & changelog

See CHANGELOG.org for further details.

VersionReleasedLein coordinatesTagged Github URL
0.0.9082015-11-08[thi.ng/geom "0.0.908"]r908
0.0.8812015-06-21[thi.ng/geom "0.0.881"]r881
0.0.8592015-06-15[thi.ng/geom "0.0.859"]r859
0.0.8562015-06-14[thi.ng/geom "0.0.856"]r856
0.0.8152015-06-01[thi.ng/geom "0.0.815"]r815
0.0.8032015-05-26[thi.ng/geom "0.0.803"]r803
0.0.7832015-04-27[thi.ng/geom "0.0.783"]r783
0.0.7702015-03-29[thi.ng/geom "0.0.770"]r770
0.0.7432015-03-23[thi.ng/geom "0.0.743"]r743
0.0.7372015-03-22[thi.ng/geom "0.0.737"]r737
0.0-7252015-03-15[thi.ng/geom "0.0-725"]r725
0.0-7152015-02-25[thi.ng/geom "0.0-715"]r715
0.0-7092015-02-22[thi.ng/geom "0.0-709"]r709
0.2.02014-03-10[thi.ng/geom "0.2.0"]0.2.0

Contributors

NameRoleWebsite
Karsten Schmidtinitiator & principal developerpostspectacular.com
thi.ng

License

This project is open source and licensed under the Apache Software License 2.0.