OpenSCAD 0.2.1.0 → 0.2.1.1
raw patch · 4 files changed
+83/−12 lines, 4 filesdep +semigroupsdep ~CabalPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: semigroups
Dependency ranges changed: Cabal
API changes (from Hackage documentation)
+ Graphics.OpenSCAD: (#) :: b -> (b -> c) -> c
+ Graphics.OpenSCAD: instance Vector v => Monoid (Model v)
+ Graphics.OpenSCAD: instance Vector v => Semigroup (Model v)
Files
- Graphics/OpenSCAD.hs +23/−7
- Graphics/OpenSCAD/Unicode.hs +2/−1
- OpenSCAD.cabal +14/−4
- UnitTest.hs +44/−0
Graphics/OpenSCAD.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} {- | Module : Graphics.OpenSCAD@@ -120,7 +120,7 @@ -- ** 'Facet's. var, fn, fs, fa, def, -- ** General convenience functions- diam, draw, drawL,+ diam, draw, drawL, (#), module Colours) where@@ -129,6 +129,8 @@ import Data.Colour.Names as Colours import Data.Colour.SRGB (channelRed, channelBlue, channelGreen, toSRGB) import Data.List (elemIndices, nub, intercalate)+import Data.List.NonEmpty (toList)+import Data.Semigroup (Semigroup((<>), sconcat), Monoid(mconcat, mempty, mappend)) import System.FilePath (FilePath) -- A vector in 2 or 3-space. They are used in transformations of@@ -249,7 +251,7 @@ -- the points, it now needs to be in an extra level of 'List'. polygon :: Int -> [[Vector2d]] -> Model2d polygon convexity paths = Shape . Polygon convexity points- $ map (concatMap (\p -> elemIndices p points)) paths+ $ map (concatMap (`elemIndices` points)) paths where points = nub $ concat paths -- | 'offset' a 'Model2d's edges by @offset /delta join/@.@@ -263,7 +265,7 @@ -- | Create a box with @cube /x-size y-size z-size/@ box :: Double -> Double -> Double -> Model3d-box x y z= Solid $ Box x y z+box x y z = Solid $ Box x y z -- | A convenience function for creating a cube as a 'box' with all -- sides the same length.@@ -292,7 +294,7 @@ polyhedron :: Int -> [[Vector3d]] -> Model3d polyhedron convexity paths = Solid . Polyhedron convexity points $ sides sin where points = nub $ concat paths- sin = map (concatMap (\p -> elemIndices p points)) paths+ sin = map (concatMap (`elemIndices` points)) paths sides ss | any ((> 3) . length) ss = Faces sin | all ((== 3) . length) ss = Triangles sin | otherwise = error "All faces must have at least 3 sides."@@ -465,12 +467,12 @@ rSolid (ToSolid s) = render s -- render a list of vectors as an Openscad vector of vectors.-rVectorL vs = "[" ++ (intercalate "," $ map rVector vs) ++ "]"+rVectorL vs = "[" ++ intercalate "," (map rVector vs) ++ "]" -- render a Sides. rSides (Faces vs) = ",faces=" ++ rListL vs rSides (Triangles vs) = ",triangles=" ++ rListL vs-rListL vs = "[" ++ (intercalate "," $ map show vs) ++ "]"+rListL vs = "[" ++ intercalate "," (map show vs) ++ "]" -- | A convenience function to render a list of 'Model's by taking -- their union.@@ -529,3 +531,17 @@ diam :: Double -> Double diam = (/ 2) +-- Now, let Haskell work it's magic+instance Vector v => Semigroup (Model v) where+ a <> b = union [a, b]+ sconcat = union . toList++instance Vector v => Monoid (Model v) where+ mempty = Solid $ Box 0 0 0+ mappend a b = union [a, b]+ mconcat = union++-- | You can use '(#)' to write transformations in a more readable postfix form, +-- cube 3 # color red # translate (-3, -3, -3)+infixl 8 #+(#) = flip ($)
Graphics/OpenSCAD/Unicode.hs view
@@ -11,6 +11,7 @@ module Graphics.OpenSCAD.Unicode where +import Data.Semigroup ((<>)) import Graphics.OpenSCAD infixl 6 ∪@@ -22,7 +23,7 @@ -- -- U+222A, UNION (∪) :: Vector v => Model v -> Model v -> Model v-a ∪ b = union [a, b]+(∪) = (<>) -- | (∩) = 'intersection' --
OpenSCAD.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: OpenSCAD-version: 0.2.1.0+version: 0.2.1.1 synopsis: ADT wrapper and renderer for OpenSCAD models. description: An algebraic data type for describing OpenSCAD models, functions to make building such models easier, and@@ -22,14 +22,24 @@ exposed-modules: Graphics.OpenSCAD, Graphics.OpenSCAD.Unicode -- other-modules: other-extensions: UnicodeSyntax- build-depends: base >=4.6 && <4.8, colour >=2.3 && <2.4, filepath >=1.3 && <1.4+ build-depends: base >=4.6 && <4.8,+ colour >=2.3 && <2.4,+ filepath >=1.3 && <1.4,+ semigroups >= 0.15 && < 1.0 -- hs-source-dirs: default-language: Haskell2010 Test-Suite Units type: exitcode-stdio-1.0 main-is: UnitTest.hs- build-depends: base >=4.6 && <4.8, colour >=2.3 && <2.4, filepath >=1.3 && <1.4, HUnit >=1.2 && <1.4, Cabal >= 1.18 && < 1.21, test-framework-hunit >=0.3 && < 0.5, test-framework >=0.8 && <1.0+ build-depends: base >=4.6 && <4.8,+ colour >=2.3 && <2.4,+ filepath >=1.3 && <1.4,+ HUnit >=1.2 && <1.4,+ Cabal >= 1.18,+ test-framework-hunit >=0.3 && < 0.5,+ test-framework >=0.8 && < 1.0,+ semigroups >= 0.15 && < 1.0 default-language: Haskell2010 source-repository head@@ -39,4 +49,4 @@ source-repository this type: fossil location: https://chiselapp.com/user/mwm/repository/OpenSCAD/- tag: 0.2.1+ tag: 0.2.1.1
UnitTest.hs view
@@ -8,6 +8,8 @@ import Graphics.OpenSCAD import Data.Colour (withOpacity)+import Data.List.NonEmpty (fromList)+import Data.Semigroup (sconcat) sw = concat . words st n e a = testCase n $ (sw e) @=?(sw $ render a)@@ -203,6 +205,48 @@ (var (fa 5) [sphere 2 $ fa 5]), st "facet 3" "assign($fs=0.1){sphere(2.0,$fs=0.1);}" (var (fs 0.1) [sphere 2 $ fs 0.1])+ ],+++ testGroup "Combinations" [+ st "union" "union(){cube([1.0,1.0,1.0]);sphere(1.1,$fs=0.1);}"+ (union [cube 1, sphere 1.1 $ fs 0.1]),+ st "difference" "difference(){cube([1.0,1.0,1.0]);sphere(1.1,$fs=0.1);}"+ (difference (cube 1) . sphere 1.1 $ fs 0.1),+ st "intersection" "intersection(){cube([1.0,1.0,1.0]);sphere(1.1,$fs=0.1);}"+ (intersection [cube 1, sphere 1.1 $ fs 0.1]),+ st "minkowski"+ "minkowski(){cube([10.0,10.0,10.0]);cylinder(r=2.0,h=1.1,$fn=50);}"+ (minkowski [cube 10, cylinder 2 1.1 $ fn 50]),+ st "hull" "hull(){translate([15.0,10.0])circle(10.0);circle(10.0);}"+ (hull [circle 10 def # translate (15, 10), circle 10 def])+ ],++ testGroup "Haskell" [+ st "# 3d" "translate([-3.0,-3.0,-3.0])color([1.0,0.0,0.0])cube([3.0,3.0,3.0]);"+ (cube 3 # color red # translate (-3, -3, -3)),+ st "# 2d"+ "translate([3.0,3.0])color([1.0,0.6470588235294119,0.0])square([2.0,2.0]);"+ (square 2 # color orange # translate (3, 3)),+ st "Monoid 1 3d" "union(){cube([1.0,1.0,1.0]);sphere(1.1,$fs=0.1);}"+ (cube 1 <> sphere 1.1 (fs 0.1)),+ st "Monoid 1 2d" "union(){square([1.0,1.0]);circle(1.1,$fs=0.1);}"+ (square 1 <> circle 1.1 (fs 0.1)),+ st "Monoid 2 3d" "union(){cube([1.0,1.0,1.0]);sphere(1.1,$fs=0.1);}"+ (mconcat [cube 1, sphere 1.1 $ fs 0.1]),+ st "Monoid 2 2d" "union(){square([1.0,1.0]);circle(1.1,$fs=0.1);}"+ (mconcat [square 1, circle 1.1 $ fs 0.1]),+ st "Semigroup 1 3d" "cube([0.0,0.0,0.0]);" (solid mempty),+ -- should we export a "shape" function?+ st "Semigroup 1 2d" "cube([0.0,0.0,0.0]);" (mempty :: Model2d),+ st "Semigroup 2 3d" "union(){cube([1.0,1.0,1.0]);sphere(1.1,$fs=0.1);}"+ (mappend (cube 1) $ sphere 1.1 (fs 0.1)),+ st "Semigroup 2 2d" "union(){square([1.0,1.0]);circle(1.1,$fs=0.1);}"+ (mappend (square 1) $ circle 1.1 (fs 0.1)),+ st "Semigroup 3 3d" "union(){cube([1.0,1.0,1.0]);sphere(1.1,$fs=0.1);}"+ (sconcat $ fromList [cube 1, sphere 1.1 $ fs 0.1]),+ st "Semigroup 3 2d" "union(){square([1.0,1.0]);circle(1.1,$fs=0.1);}"+ (sconcat $ fromList [square 1, circle 1.1 $ fs 0.1]) ] ]