{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} module HCad.SCAD where import HCad.Part import HCad.Expr import Data.List (intercalate, nub) -- import Algebra.Linear import Data.Set (Set) import qualified Data.Set as Set data Options = Options {optFn :: Int} defaultOptions :: Options defaultOptions = Options {optFn = 10} render :: Functor v => Foldable v => Options -> Part xs v Double -> String render Options{..} p = unlines (("$fn="++show optFn++";"): renderCode (toSCAD $ partCode p)++ [";"]) renderP :: Functor v => Foldable v => Options -> Part xs v Expr -> String renderP Options{..} p = unlines (("$fn="++show optFn++";"): concat [["// " ++ paramComment ,paramName ++ " = " ++ show paramDefault ++ "; " ++ "// " ++ v (paramPossible)] | Parameter{..} <- Set.toList ps ] ++ renderCode (toSCAD $ partCode p) ++ [";"]) where ps :: Set Parameter ps = foldMap params (partCode p) v (PRange lo hi) = "["++show lo++":"++ show hi ++"]" v (PSet vals) = show vals renderCode :: SCAD -> [String] renderCode (SCAD fname args body) -- | fname == "union" = rbody | otherwise = (fname <>"(" <> (intercalate ", " [pname <> "=" <> arg | (pname,arg) <- args]) <> ")") `app` rbody where rbody = case body of [] -> [] [x] -> renderCode x xs -> "{" : fmap indent (concatMap (semicolon . renderCode) xs) ++ "}" : [] indent xs = " " ++ xs semicolon [] = error "semicolon: empty" semicolon xs = init xs ++ [last xs ++ ";"] x `app` (y : ys) = (x<>y) : ys app x [] = [x] -- tst :: Part3 '[] Double -- tst = forget $ mirror (V3 (sin (pi/6)) (cos (pi/6)) 0) $ translate (V3 20 0 0) $ on zenith (union $ translate (V3 0 2.5 0) $ scale 5 $ cube) $ scale 10 cube -- main :: IO () -- main = writeFile "tst.scad" $ render defaultOptions tst -- >>> main