FunCad is a Haskell library for generating meshes from SDFs and CSG operations.
This project is not at all finished and was just a project to practice Haskell programming for a complete beginner. Several components should be cleaned up and optimized heavily (especially parallelization), before use in anything.
It is heavily inspired from OpenSCAD and aims to be a truely functional CAD language, able to use Haskells power to its fullest extent.
To use the library, simply install it with cabal install --lib .. Then you can start playing around with it in ghci:
ghci> -- Generate a mesh sphere into the file "sphere.stl"
ghci> import FunCad
ghci> import System.IO
ghci> h <- openFile "sphere.stl" WriteMode
ghci> hPutStr h $ sdfToMeshBinarySTL (1/2^5) $ sphere 1
ghci> hClose h
Here is some some more extensive documentation:
SDFs are the way FunCad represents shapes. They take in a point in space and spits out the distance to the shapes, and therefore SDF is just a type synonym for Vec3 -> Float, and you could easily add you own (see this amazing resource by Inigo Quilez).
The following SDFs exists currently:
-- | SDF of a sphere of radius r
sphere :: Float -> SDF
-- | SDF of a cube with half-dimensions (x, y, z)
cube :: Vec3 -> SDF
-- | SDF of a cylinder with height h and radius r
cylinder :: Float -> Float -> SDFOperations allow use to modify one or more SDFs. These are either operations of the SDF or a CSG operation between two SDFs:
-- | Translate a SDF by a point
translate :: SDF -> Vec3 -> SDF
-- | Take the union of several SDFs
union :: [SDF] -> SDF
-- | Take the intersection of several SDFs
intersection :: [SDF] -> SDF
-- | Take the difference between two SDFs
difference :: SDF -> SDF -> SDF
-- | Dilate the SDF by offsetting by a value
dilate :: SDF -> Float -> SDFThen we finally have the mesh/pointcloud generation. It is currently marching cubes (which should probably be replaced with dual contouring), and allow us to output both meshes and pointcloud.
-- | Convert an SDF to ASCII STL of certain subdivision size
sdfToMeshAsciiSTL :: Float -> SDF -> String
-- | Convert an SDF to binary STL of certain subdivision size
sdfToMeshBinarySTL :: Float -> SDF -> ByteString
-- | Convert an SDF to ASCII PCD of a pointcloud of certain subdivision size
sdfToPointcloudPCD :: Float -> SDF -> String
-- | Convert an SDF to ASCII OBJ of a pointcloud of certain subdivision size
sdfToPointcloudOBJ :: Float -> SDF -> String- Add the remaining transformations (Scaling and rotation).
- Add more SDFs.
- Figure out how to optimally parallelize the program.
- Cleanup the marching cubes bit.
- Replace marching cubes with dual contouring.
