diff options
-rw-r--r-- | Carpentry.hs | 163 | ||||
-rw-r--r-- | shelves.hs | 7 |
2 files changed, 166 insertions, 4 deletions
diff --git a/Carpentry.hs b/Carpentry.hs new file mode 100644 index 0000000..030eb86 --- /dev/null +++ b/Carpentry.hs | |||
@@ -0,0 +1,163 @@ | |||
1 | {-# LANGUAGE FlexibleContexts #-} | ||
2 | module Carpentry | ||
3 | ( | ||
4 | place | ||
5 | , placeColored | ||
6 | , placeAlong | ||
7 | , placeTransformed | ||
8 | , at | ||
9 | , spreadEvenly | ||
10 | , v3box | ||
11 | , v3translate | ||
12 | , writeTempSCAD | ||
13 | , openTempSCAD | ||
14 | , assemble | ||
15 | , component | ||
16 | ) where | ||
17 | |||
18 | import Control.Applicative | ||
19 | import Control.Lens hiding (at) | ||
20 | import Data.Colour.RGBSpace | ||
21 | import Data.Either | ||
22 | import Data.Functor | ||
23 | import Data.List | ||
24 | import Data.Maybe | ||
25 | import Graphics.OpenSCAD | ||
26 | import Linear.V3 | ||
27 | import System.IO.Temp | ||
28 | import System.Process | ||
29 | |||
30 | v3box :: R3 t => t Double -> Model3d | ||
31 | v3box v = box (v ^. _x) (v ^. _y) (v ^. _z) | ||
32 | |||
33 | v3translate :: (Vector (c, c, c), R3 t) => t c -> Model (c, c, c) -> Model (c, c, c) | ||
34 | v3translate v m = translate (v ^. _x, v ^. _y, v ^. _z) m | ||
35 | -- ^ doesn't work ?? | ||
36 | |||
37 | place :: (R3 t1, R3 t2) => t2 Double -> [t1 Double] -> [Model (Double, Double, Double)] | ||
38 | place board coords = map (placeOne board) coords | ||
39 | where | ||
40 | boardAt p = translate (p ^. _x, p ^. _y, p ^. _z) $ v3box board | ||
41 | -- boardAt p = v3translate p $ v3box board | ||
42 | |||
43 | placeOne b c = translate (c ^. _x, c ^. _y, c ^. _z) $ v3box b | ||
44 | |||
45 | placeTransformed t r = t $ place r | ||
46 | |||
47 | -- intended usage: place (V3 2 4 16) $ at [0] [0,4..(20*12)] [0] | ||
48 | -- (which would, e.g., place 2x4 planks next to each other for 20 feet (e.g., floor boards) | ||
49 | at :: Applicative f => f a -> f a -> f a -> f (V3 a) | ||
50 | at = liftA3 V3 | ||
51 | --at x y z = V3 <$> x <*> y <*> z -- same as above | ||
52 | |||
53 | placeColored c board coords = map boardAt coords | ||
54 | where | ||
55 | boardAt p = color c $ translate (p ^. _x, p ^. _y, p ^. _z) $ v3box board | ||
56 | |||
57 | -- deprecated due to the superiority of using place in conjunction with at | ||
58 | -- placeAlong (V3 2 4 16) (V3 0 0 0) (_x +~ 4) _x (<= 20) | ||
59 | placeAlong :: | ||
60 | (R3 t1, R3 t2) => | ||
61 | t2 Double | ||
62 | -> t1 Double | ||
63 | -> (t1 Double -> t1 Double) | ||
64 | -> ((t -> Const t t) -> t1 Double -> Const t (t1 Double)) | ||
65 | -> (t -> Bool) | ||
66 | -> [Model (Double, Double, Double)] | ||
67 | placeAlong board initial shift targ cond = | ||
68 | place board positions | ||
69 | where positions = | ||
70 | let next x = | ||
71 | let p = x & shift | ||
72 | in if cond (p ^. targ) | ||
73 | then p : next p | ||
74 | else [] | ||
75 | in initial : next initial | ||
76 | |||
77 | |||
78 | |||
79 | -- data CarpentryProject = CarpentryProject | ||
80 | -- { dimensions :: V3 Double | ||
81 | -- , components :: [ProjectCompnent] | ||
82 | -- } deriving (Show) | ||
83 | |||
84 | -- data Component = Component { | ||
85 | -- name :: String, | ||
86 | -- , dim :: V3 Double | ||
87 | -- , orient :: | ||
88 | -- } | ||
89 | -- assemble | ||
90 | -- assemble [ component "shelves" (V3 1 8 36) _xyz $ at [0] [0,12,24,36] [0] | ||
91 | -- , component "sides" (V3 1 8 40) _xyz $ at [0] [0,36] [0] ] | ||
92 | |||
93 | assemble :: [(String, String, V3 Double, | ||
94 | (V3 Double -> Const (V3 Double) (V3 Double)) | ||
95 | -> V3 Double -> Const (V3 Double) (V3 Double), | ||
96 | [V3 Double])] -> (String, [Model3d]) | ||
97 | assemble c = (cutlist, model) | ||
98 | where | ||
99 | model = concatMap (\(_, c, b, o, p) -> placeColored (safeColor c) (b ^. o) p) c | ||
100 | safeColor :: String -> Colour Double | ||
101 | safeColor = runIdentity . readColourName | ||
102 | cutlist = intercalate "\n" $ map tocut c | ||
103 | tocut (n, c, b, _, p) = n ++ " (" ++ show (length p) ++ ", " ++ c ++ ") @ " ++ v3toStr b | ||
104 | v3toStr c = show (c ^. _x) ++ " x " ++ show (c ^. _y) ++ " x " ++ show (c ^. _z) | ||
105 | |||
106 | --component :: a -> b -> c -> d -> e -> (a, b, c, d, e) | ||
107 | --component :: a -> b -> c -> d -> e -> (a, b, c, d, e) | ||
108 | -- component :: String | ||
109 | -- -> String | ||
110 | -- -> V3 Double | ||
111 | -- -> ((f -> Const f f) -> V3 Double -> Const f (V3 Double)) | ||
112 | -- -> [V3 Double] | ||
113 | -- -> (String, String, V3 Double, | ||
114 | -- (f -> Const f f) -> | ||
115 | -- V3 Double -> Const f (V3 Double), [V3 Double], f) | ||
116 | |||
117 | -- c :: ([Char], [Char], V3 Integer, | ||
118 | -- (V3 a -> ghc-prim-0.5.3:GHC.Types.Any (V3 a)) | ||
119 | -- -> ghc-prim-0.5.3:GHC.Types.Any a | ||
120 | -- -> ghc-prim-0.5.3:GHC.Types.Any (ghc-prim-0.5.3:GHC.Types.Any a), | ||
121 | -- [V3 Integer]) | ||
122 | -- component :: (String, String, V3 Double, | ||
123 | -- (V3 Double -> Const (V3 Double) (V3 Double)) | ||
124 | -- -> V3 Double -> Const (V3 Double) (V3 Double), [V3 Double]) | ||
125 | -- component :: String -> String, V3 Integer, | ||
126 | -- (V3 Integer -> Const (V3 Integer) (V3 Integer)) | ||
127 | -- -> V3 Integer -> Const (V3 Integer) (V3 Integer), | ||
128 | -- [V3 Integer]) | ||
129 | --component name col dim orient pos = (name, col, dim, orient, pos, dim ^. orient) | ||
130 | |||
131 | --component name col dim orient pos = (name, col, dim, orient, pos, dim ^. orient) | ||
132 | component | ||
133 | :: String | ||
134 | -> String | ||
135 | -> V3 Double | ||
136 | -> ((V3 Double -> Const (V3 Double) (V3 Double)) | ||
137 | -> V3 Double -> Const (V3 Double) (V3 Double)) | ||
138 | -> [V3 Double] | ||
139 | -> (String, String, V3 Double, | ||
140 | (V3 Double -> Const (V3 Double) (V3 Double)) | ||
141 | -> V3 Double -> Const (V3 Double) (V3 Double), | ||
142 | [V3 Double]) | ||
143 | component name col dim orient pos = (name, col, dim, orient, pos) | ||
144 | --component name col dim orient pos = (name :: String, col :: String, dim :: V3 Double, orient, pos :: [V3 Double]) | ||
145 | |||
146 | ass = assemble [component "shelves" "neh" (V3 1 8 36) _xyz [V3 0 0 0, V3 0 0 10] ] | ||
147 | |||
148 | |||
149 | |||
150 | -- evenly spread <boardCount> number of boards (of the width <boardWidth>) in <span> space | ||
151 | -- e.g., if you want to have a 20x20 space and want support beams every 16": | ||
152 | -- spreadEvenly 2 20 (20*12/16) | ||
153 | spreadEvenly boardWidth fillSpace boardCount = | ||
154 | let dist = (fillSpace - boardWidth) / fromIntegral (boardCount - 1) | ||
155 | in take boardCount $ iterate (+dist) 0 | ||
156 | |||
157 | writeTempSCAD :: String -> IO FilePath | ||
158 | writeTempSCAD scadstr = writeSystemTempFile "genscad.scad" scadstr | ||
159 | |||
160 | openTempSCAD :: String -> IO ProcessHandle | ||
161 | openTempSCAD scadstr = do | ||
162 | fp <- writeTempSCAD scadstr | ||
163 | runCommand $ "openscad " ++ fp | ||
@@ -1,6 +1,6 @@ | |||
1 | import Graphics.OpenSCAD | 1 | import Graphics.OpenSCAD |
2 | import Linear.V3 | 2 | import Linear.V3 |
3 | import OpenSCAD.Carpentry | 3 | import Carpentry |
4 | import System.Process | 4 | import System.Process |
5 | 5 | ||
6 | -- the minimum paramaters to describe a shelf; the width and depth of a shelf, | 6 | -- the minimum paramaters to describe a shelf; the width and depth of a shelf, |
@@ -14,9 +14,8 @@ data Shelf = Shelf { | |||
14 | } deriving (Show) | 14 | } deriving (Show) |
15 | 15 | ||
16 | myShelf :: Shelf | 16 | myShelf :: Shelf |
17 | myShelf = Shelf { width = 12*4, depth = 12, boardThickness = 1, | 17 | myShelf = Shelf { width = 12*80000, depth = 48, boardThickness = 1, |
18 | shelfHeights = [15, 8, 8, 8] } | 18 | shelfHeights = [36, 36, 36] } |
19 | |||
20 | 19 | ||
21 | calcShelfHeights :: Shelf -> [Double] | 20 | calcShelfHeights :: Shelf -> [Double] |
22 | calcShelfHeights s = scanl (+) 0 [h + (boardThickness s)|h <- (shelfHeights s)] | 21 | calcShelfHeights s = scanl (+) 0 [h + (boardThickness s)|h <- (shelfHeights s)] |