So you want to improve ImplicitCAD. Yay! More help is a good thing.
As of the time of writing, ImplicitCAD has 3417 lines of code, 896 lines of comments, and 877 blank lines, for a total of 5190 lines spread over 42 files. For a project of ImplicitCAD's scope, that's pretty small, but it's still enough that it can be difficult to find the section we need to change...
The structure of ImplicitCAD is as follows:
```
Graphics
└── Implicit
├── Export
│ ├── Render
│ └── Symbolic
├── ExtOpenScad
│ └── Util
└── ObjectUtil
```
`Graphics.Implicit.Export` is, as you may guess, where all the export stuff is. `Graphics.Implicit.ExtOpenScad` is the programming language interpreter for the ExtOpenScad language, our extention of openscad. Finally, the graphics engine is defined in `Graphics.Implicit` and `Graphics.Implicit.ObjectUtil`.
The rest of this file will go through different changes you are likely to want to make and how to implement them.
Language Changes
----------------
Most likely, you want to change one of four things:
* **Expressions**: Expressions are things like `1+2`, `"abc"`, and `[sin(3.14), pi]`. They are defined in `Graphics.Implicit.ExtOpenScad.Expressions`. (Note that `sin` and `pi` are variables, which are defined elsewhere.)
* **Statements**: Statements are things like variable assignment, for loops, and if statements. For example `for (a = [1,2,3]) echo (a);`. Statements are defined in `Graphics.Implicit.ExtOpenScad.Statements`.
* **Default Variables**: Like `sin`, `pi`, `sqrt`. These are all defined in ` Graphics.Implicit.ExtOpenScad.Default`. We can just use `toOObj` to convert Haskell values into `OpenscadObj`s and use them as default variable settings. (Small caveat: inputs to `toOObj` can't be polymorphic, so we use a type signature to force it to a certain type.)
Formats are defined in files like `Graphics.Implicit.Export.TriangleMeshFormats` (as is the case with STLs), `Graphics.Implicit.Export.PolylineMeshFormats` (as is the case with SVGs).
Then, in `Graphics.Implicit.Export`:
```haskell
writeSVG res = writeObject res PolylineFormats.svg
writeSTL res = writeObject res TriangleMeshFormats.stl
```
Rendering Algorithms
--------------------
These are defined in `Graphics.Implicit.Export.Render` and children. `Graphics.Implicit.Export.Render` begins with an outline of how rendering is done:
```haskell
-- Here's the plan for rendering a cube (the 2D case is trivial):
-- (1) We calculate midpoints using interpolate.
-- This guarentees that our mesh will line up everywhere.
If you are interested on working on this part of the code, read it. The children are also well documented.
Graphics Primitives
-------------------
The most complicated part of ImplicitCAD is the actual graphics engine. Before working on it, please familiarize yourself with the theory as described in [Chris' blog post](http://christopherolah.wordpress.com/2011/11/06/manipulation-of-implicit-functions-with-an-eye-on-cad/) (though changes have occured since then).
The simples way to implement a new primitive is using `implicit`, a contructor that takes an implicit function and boudning box, producing an object. For example, we could have originally defined `sphere` as:
```haskell
sphere :: ℝ -> SymbolicObj3
sphere r = implicit (
\(x,y,z) -> sqrt (x^2+y^2+z^2) - r,
((-r, -r, -r), (r, r, r))
)
```
and put it in `Graphics.Implicit.Primitives`. However, to allow more powerful optimizations, meta-inspection, and other goodies, frequently used objects should be put in the `SymbolicObj` definitions in `Graphics.Implicit.Definitions`. For example, `sphere`: