OpenSCAD (empty) → 0.1.0.0
raw patch · 6 files changed
+648/−0 lines, 6 filesdep +Cabaldep +HUnitdep +basesetup-changed
Dependencies added: Cabal, HUnit, base, colour, filepath, test-framework, test-framework-hunit
Files
- Graphics/OpenSCAD.hs +429/−0
- Graphics/OpenSCAD/Unicode.hs +44/−0
- LICENSE +30/−0
- OpenSCAD.cabal +42/−0
- Setup.hs +2/−0
- UnitTest.hs +101/−0
+ Graphics/OpenSCAD.hs view
@@ -0,0 +1,429 @@+{- |+Module : Graphics.OpenSCAD+Description : Type-checked wrappers for the OpenSCAD primitives.+Copyright : © Mike Meyer, 2014+License : BSD4+Maintainer : mwm@mired.org+Stability : experimental++The Graphics.OpenSCAD module provides abstract data types for creating+OpenSCAD model definitions calls, along with a function to render it+as a string, and some utilities. The primary goal is that the output+should always be valid OpenSCAD. If you manage to generate OpenSCAD+source that causes OpenSCAD to complain, please open an issue.++Standard usage is to have a @main@ function that looks like:++@+main = draw $ /Solid/+@++and then set your IDE's compile command to use @runhaskell@ or+equivalent to run your code and send the output to a .scad file. Open+that file in OpenSCAD, and set it to automatically reload if the file+changes. Recompiling your program will cause the model to be loaded+and displayed by OpenSCAD.++The type constructors are generally not exported, with functions being+exported in their stead. This allows extra checking to be done on+those that need it. It also provides consistency, as otherwise you'd+have to remember whether 'box' is a constructor or a convenience+function, etc.++Because of this, the constructors are not documented, the exported+functions are. The documentation is generally just the corresponding+OpenSCAD function name, along with the names of the arguments from the+OpenSCAD documentation. If no OpenSCAD function name is given, then+it's the same as the 'Graphics.OpenSCAD' function. You should check+the OpenSCAD documentation for usage information.++-}++module Graphics.OpenSCAD (+ -- * Basic data types+ Solid,+ Shape,+ Facet,+ -- * Type aliases to save typing+ Vector, Point,+ -- * Rendering functions+ render, draw,+ -- * Constructors+ -- ** 'Solid's+ sphere, box, cube, cylinder, obCylinder, rectangle3d, square3d, circle3d,+ import3d, linearExtrude, rotateExtrude,+ -- ** 'Shape's+ rectangle, square, circle, import2d, projection,+ -- * Combinations of 'Solid's+ union, intersection, difference, minkowski, hull,+ -- * Transformations+ -- ** 'Solid's+ scale, resize, rotate, translate, mirror, multMatrix, color, transparent, up,+ projection3d, + -- ** 'Shape's+ scale2d, resize2d, rotate2d, translate2d, mirror2d,+ -- ** General convenience functions+ diam,+ -- * Convenience functions for 'Facet's.+ var, fn, fs, fa, def,+ module Colours)++where++import Data.Colour (Colour, AlphaColour, alphaChannel, darken, over, black)+import Data.Colour.SRGB (channelRed, channelBlue, channelGreen, toSRGB)+import System.FilePath (FilePath)+import qualified Data.Colour.Names as Colours++-- | 'Vector' is used where OpenSCAD expects an OpenSCAD @vector@ of length 3.+type Vector = (Float, Float, Float)++-- | 'Point' is used where OpenSCAD expects an OpenSCAD @vector@ of length 3.+type Point = (Float, Float)++-- | These are for @Poly*s@, which don't work yet.+type Path = [Int]+type Face = (Int, Int, Int)++type Transform = ((Float, Float, Float, Float), (Float, Float, Float, Float),+ (Float, Float, Float, Float), (Float, Float, Float, Float))+++-- While it's tempting to add more options to Solid, don't do it. Instead,+-- add functions that add that functionality, like cube vs. box.+--+-- Missing at this time: Poly*s, some special features.+-- There's also no way to set $f? vars globally, due to an OpenSCAD quirk.++-- | A 'Facet' is used to set one of the special variables that+-- control the mesh used during generation of circular objects. They+-- appear as arguments to various constructors, as well as in the+-- 'var' function to set them for the argument objects.+data Facet = Fa Float | Fs Float | Fn Int | Def deriving Show++-- | A 'Shape' is a two-dimensional object. They are a separate type+-- so that Haskell can type check that we aren't using a 2d operation+-- on a 3d shape, or vice versa. Unfortunately, this means the+-- dynamically typed functions that accept either - and possibly+-- generate either - need to have two versions of those functions. I+-- believe the 2d creation functions are more common for 2d objects,+-- but the 3d transformation functions are more common. Hence the 2d+-- creation functions (which have the names of 2d objects like circle,+-- square, etc.) that create 'Solid's have @3d@ appended, but the 3d+-- version of transformations that have both 2d and 3d versions have+-- @3d@ appended.+data Shape =+ Rectangle Float Float+ | Circle Float Facet+ -- add | Polygon [Point] [Path] Int+ | Import2d FilePath+ | Projection Bool Solid+ -- 2d versions of the transformations+ | Scale2d Point Shape+ | Resize2d Point Shape+ | Rotate2d Point Shape+ | Translate2d Point Shape+ | Mirror2d Point Shape+ deriving Show++-- | A 'Solid' is a solid object in OpenSCAD. Since we don't have+-- optional or named objects, some constructors appear twice to allow+-- two different variants to be used. And of course, they all have all+-- their arguments.+data Solid =+ Sphere Float Facet+ | Box Float Float Float+ | Cylinder Float Float Facet+ | ObCylinder Float Float Float Facet+ -- add | Polyhedron [Vector] [Face] Int+ | Import3d FilePath+ | Shape Shape+ -- Combinations+ | Union [Solid]+ | Intersection [Solid]+ | Difference Solid Solid+ | Minkowski [Solid]+ | Hull [Solid]+ -- Transformations+ | Scale Vector Solid+ | Resize Vector Solid+ | Rotate Vector Solid+ | Translate Vector Solid+ | Mirror Vector Solid+ | MultMatrix Transform Solid+ | Color (Colour Float) Solid+ | Transparent (AlphaColour Float) Solid+ | LinearExtrude Float Float Point Int Int Facet Shape+ | RotateExtrude Int Facet Shape+ -- Mesh control+ | Var Facet [Solid]+ deriving Show++-- | 'render' does all the real work. It will walk the AST for a 'Solid',+-- returning an OpenSCAD program in a 'String'.+render :: Solid -> String+render (Sphere x f) = "sphere(" ++ show x ++ rFacet f ++ ");\n\n"+render (Box x y z) =+ "cube([" ++ show x ++ "," ++ show y ++ "," ++ show z ++ "]);\n"+render (Cylinder r h f) =+ "cylinder(r=" ++ show r ++ ",h=" ++ show h ++ rFacet f ++ ");\n\n"+render (ObCylinder r1 h r2 f) =+ "cylinder(r1=" ++ show r1 ++ ",h=" ++ show h ++ ",r2=" ++ show r2 ++ rFacet f+ ++ ");\n\n"+render (Import3d f) = "import(" ++ f ++");\n\n"+render (Shape s) = rShape s+render (Union ss) = rList "union()" ss+render (Intersection ss) = rList "intersection()" ss+render (Difference s1 s2) = "difference(){" ++ render s1 ++ render s2 ++ "}\n\n"+render (Minkowski ss) = rList "minkowski()" ss+render (Hull ss) = rList "hull()" ss+render (Scale v s) = rVecSolid "scale" v s+render (Resize v s) = rVecSolid "resize" v s+render (Translate v s) = rVecSolid "translate" v s+render (Rotate v s) = "rotate(a=" ++ rVector v ++ ")" ++ render s+render (Mirror v s) = rVecSolid "mirror" v s+render (MultMatrix (a, b, c, d) s) =+ "multmatrix([" ++ rQuad a ++ "," ++ rQuad b ++ "," ++ rQuad c ++ ","+ ++ rQuad d ++"])\n" ++ render s+render (Color c s) = let r = toSRGB c in+ "color(" ++ rVector (channelRed r, channelGreen r, channelBlue r) ++ ")\n"+ ++ render s+render (Transparent c s) =+ "color(" ++ rQuad (channelRed r, channelGreen r, channelBlue r, a) ++ ")"+ ++ render s+ where r = toSRGB $ toPure c+ a = alphaChannel c+ toPure ac = if a > 0 then darken (recip a) (ac `over` black) else black+render (LinearExtrude h t sc sl c f sh) =+ "linear_extrude(height=" ++ show h ++ ",twist=" ++ show t ++ ",scale="+ ++ rPoint sc ++ ",slices=" ++ show sl ++ ",convexity=" ++ show c ++ rFacet f+ ++ ")" ++ rShape sh+render (RotateExtrude c f sh) =+ "rotate_extrude(convexity=" ++ show c ++ rFacet f ++ ")" ++ rShape sh+render (Var (Fa f) ss) = rList ("assign($fa=" ++ show f ++ ")") ss+render (Var (Fs f) ss) = rList ("assign($fs=" ++ show f ++ ")") ss+render (Var (Fn n) ss) = rList ("assign($fn=" ++ show n ++ ")") ss++-- | 'draw' is a convenience function to write the rendered 'Solid' to+-- standard output.+draw = putStrLn . render+++-- utilities for rendering Shapes.+rShape (Rectangle r f) = "square([" ++ show r ++ "," ++ show f ++ "]);\n\n"+rShape (Circle r f) = "circle(" ++ show r ++ rFacet f ++ ");\n\n"+rShape (Import2d f) = "import(" ++ f ++ ");\n\n"+rShape (Projection c s) =+ "projection(cut=" ++ (if c then "true)" else "false)") ++ render s+rShape (Scale2d p s) = "scale(" ++ rPoint p ++ ")" ++ rShape s+rShape (Resize2d p s) = "resize(" ++ rPoint p ++ ")" ++ rShape s+rShape (Rotate2d p s) = "rotate(" ++ rPoint p ++ ")" ++ rShape s+rShape (Translate2d p s) = "translate(" ++ rPoint p ++ ")" ++ rShape s+rShape (Mirror2d p s) = "mirror(" ++ rPoint p ++ ")" ++ rShape s++-- And some misc. rendering utilities.+rList n ss = n ++ "{\n" ++ concatMap render ss ++ "}"+rSolid n s = n ++ "()\n" ++ render s+rVector (a, b, c) = "[" ++ show a ++ "," ++ show b ++ "," ++ show c ++ "]"+rVecSolid n v s = n ++ "(" ++ rVector v ++ ")\n" ++ render s+rQuad (w, x, y, z) =+ "[" ++ show w ++ "," ++ show x ++ "," ++ show y ++ "," ++ show z ++ "]"+rFacet Def = ""+rFacet f = "," ++ showFacet f+rPoint (x, y) = "[" ++ show x ++ "," ++ show y ++ "]"++-- render a facet setting.+showFacet :: Facet -> String+showFacet (Fa f) = "$fa=" ++ show f+showFacet (Fs f) = "$fs=" ++ show f+showFacet (Fn n) = "$fn=" ++ show n+showFacet Def = ""++-- | Create a sphere with @sphere /radius 'Facet'/@.+sphere :: Float -> Facet -> Solid+sphere = Sphere++-- | Create a box with @cube /x-size y-size z-size/@+box :: Float -> Float -> Float -> Solid+box = Box++-- | A convenience function for creating a cube as a 'box' with all+-- sides the same length.+cube :: Float -> Solid+cube x = Box x x x++-- | Create a cylinder with @cylinder /radius height 'Facet'/@.+cylinder :: Float -> Float -> Facet -> Solid+cylinder = Cylinder++-- | Create an oblique cylinder with @cylinder /radius1 height radius2+-- 'Facet'/@+obCylinder :: Float -> Float -> Float -> Facet -> Solid+obCylinder = ObCylinder++-- | __UNTESTED__ 'import3d' is @import /filename/@, where /filename/+-- is an stl file. It's /3d/ because import is a key word.+import3d :: FilePath -> Solid+import3d = Import3d++-- | __UNTESTED__ 'import2d' is @import /filename/@, where /filename/+-- is an image or other 2d object.+import2d :: FilePath -> Shape+import2d = Import2d++-- | Create the union of a list of 'Solid's.+union :: [Solid] -> Solid+union = Union++-- | Create the intersection of a list of 'Solid's.+intersection :: [Solid] -> Solid+intersection = Intersection++-- | The difference between two 'Solid's.+difference :: Solid -> Solid -> Solid+difference = Difference++-- | The Minkowski sum of a list of 'Solid's.+minkowski :: [Solid] -> Solid+minkowski = Minkowski++-- | The convex hull of a list of 'Solid's.+hull :: [Solid] -> Solid+hull = Hull++-- | Scale a 'Solid', specifying the scale factor for each axis.+scale :: Vector -> Solid -> Solid+scale = Scale++-- | __UNTESTED__ Resize a 'Solid' to occupy the given dimensions.+resize :: Vector -> Solid -> Solid+resize = Resize++-- | Rotate a 'Solid' by different amounts around each of the three axis.+rotate :: Vector -> Solid -> Solid+rotate = Rotate++-- | Translate a 'Solid' along a 'Vector'.+translate :: Vector -> Solid -> Solid+translate = Translate++-- | Mirror a 'Solid' across a plane intersecting the origin.+mirror :: Vector -> Solid -> Solid+mirror = Mirror++-- | Transform a 'Solid' with a 'Transform' matrix.+multMatrix :: Transform -> Solid -> Solid+multMatrix = MultMatrix++-- | A 'translate' that just goes up, since those seem to be common.+up :: Float -> Solid -> Solid+up f = Translate (0, 0, f)+++-- | Render a 'Solid' in a specific color. This doesn't us the+-- OpenSCAD color model, but instead uses the 'Data.Colour' model. The+-- 'Graphics.OpenSCAD' module rexports 'Data.Colour.Names' so you can+-- conveniently say @'color' 'red' /'Solid'/@.+color :: Colour Float -> Solid -> Solid+color = Color++-- | Render a 'Solid' in a transparent color. This uses the+-- 'Data.Coulor.AphaColour' color model.+transparent :: AlphaColour Float -> Solid -> Solid+transparent = Transparent++-- | Extrude a 'Shape' along a line with @linear_extrude@.+linearExtrude :: Float -- ^ height+ -> Float -- ^ twist+ -> Point -- ^ scale+ -> Int -- ^ slices+ -> Int -- ^ convexity+ -> Facet+ -> Shape -- ^ to extrude+ -> Solid+linearExtrude = LinearExtrude++-- | Rotate a 'Shape' around the origin with @rotate_extrude+-- /convexity 'Facet' 'Shape'/@+rotateExtrude :: Int -> Facet -> Shape -> Solid+rotateExtrude = RotateExtrude++-- | Use 'diam' to turn a diameter into a radius for circles, spheres, etc.+diam :: Float -> Float+diam = (/ 2)++-- | Create a rectangular 'Shape' with @rectangle /x-size y-size/@.+rectangle :: Float -> Float -> Shape+rectangle = Rectangle++-- | Create a rectangular 'Solid' with @rectangle /x-size y-size/@.+rectangle3d :: Float -> Float -> Solid+rectangle3d w d = Shape $ Rectangle w d++-- | 'square' is a 'rectangle' with both sides the same size.+square :: Float -> Shape+square s = rectangle s s++-- | 'square3d' is a 'rectangle3d' with both sides the same size.+square3d :: Float -> Solid+square3d s = rectangle3d s s++-- | Create a circular 'Shape' with @circle /radius/ 'Facet'@.+circle :: Float -> Facet -> Shape+circle = Circle++-- | Create a circular 'Solid' with @circle /radius/ 'Facet'@.+circle3d :: Float -> Facet -> Solid+circle3d r f = Shape $ Circle r f++-- | Project a 'Solid' into a 'Shape' with @projection /cut 'Solid'/@.+projection :: Bool -> Solid -> Shape+projection = Projection++-- | Project a 'Solid' to a thin 'Solid' with @projection /cut 'Solid'/@.+projection3d :: Bool -> Solid -> Solid+projection3d c s = Shape $ Projection c s++-- | 'scale2d' is 'scale' for 'Shape's.+scale2d :: Point -> Shape -> Shape+scale2d = Scale2d++-- | 'resize2d' is 'resize' for 'Shape's.+resize2d :: Point -> Shape -> Shape+resize2d = Resize2d++-- | 'rotate2d' is 'rotate' for 'Shape's.+rotate2d :: Point -> Shape -> Shape+rotate2d = Rotate2d++-- | 'translate2d' is 'translate' for 'Shape's.+translate2d :: Point -> Shape -> Shape+translate2d = Translate2d++-- | 'mirror2d' is 'mirror' for 'Shape's.+mirror2d :: Point -> Shape -> Shape+mirror2d = Mirror2d++-- Convenience functions for Facets.++-- Maybe this should have type [Facet] -> [Solid] -> [Solid]+-- | 'var' uses @assign@ to set a special variable for the 'Solid's.+var :: Facet -> [Solid] -> Solid+var = Var++-- | 'fa' is used to set the @$fa@ variable in a 'Facet' or 'var'.+fa :: Float -> Facet+fa = Fa++-- | 'fs' is used to set the @$fs@ variable in a 'Facet' or 'var'.+fs :: Float -> Facet+fs = Fs++-- | 'fn' is used to set the @$fn@ variable in a 'Facet' or 'var'.+fn :: Int -> Facet+fn = Fn++-- | 'def' is used where a 'Facet' is needed but we don't want to change+-- any of the values.+def :: Facet+def = Def
+ Graphics/OpenSCAD/Unicode.hs view
@@ -0,0 +1,44 @@+{-# LANGUAGE UnicodeSyntax #-}++{-+Module : Graphics.OpenSCAD.Unicode+Description : Unicode operators so you can write @Solid@ expressions.+Copyright : © Mike Meyer, 2014+License : BSD4+Maintainer : mwm@mired.org+Stability : experimental+-}++module Graphics.OpenSCAD.Unicode where++import Graphics.OpenSCAD++infixl 6 ∪+infixr 6 ∩+infixl 9 ∖+infixl 9 ∆++-- | (∪) = 'union'+--+-- U+222A, UNION+(∪) :: Solid -> Solid -> Solid+a ∪ b = union [a, b]++-- | (∩) = 'intersection'+--+-- U+2229, INTERSECTION+(∩) :: Solid -> Solid -> Solid+a ∩ b = intersection [a, b]++-- | (∖) = 'difference'+--+-- U+2216, SET MINUS+(∖):: Solid -> Solid -> Solid+(∖) = difference++-- | (∆) = Symmetric difference+--+-- U+2206, INCREMENT+(∆) :: Solid -> Solid -> Solid+a ∆ b = (a ∖ b) ∪ (b ∖ a)+
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Mike Meyer++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Mike Meyer nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ OpenSCAD.cabal view
@@ -0,0 +1,42 @@+-- Initial OpenSCAD.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: OpenSCAD+version: 0.1.0.0+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+ functions for rendering an ADT into an OpenSCAD program.+homepage: https://graphics-openscad.googlecode.com/+license: BSD3+license-file: LICENSE+author: Mike Meyer+maintainer: mwm@mired.org+-- copyright: +category: Graphics+build-type: Simple+extra-source-files:+cabal-version: >=1.10++library+ 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+ -- 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+ default-language: Haskell2010++source-repository head+ type: hg+ location: https://code.google.com/p/graphics-openscad/++source-repository this+ type: hg+ location: https://code.google.com/p/graphics-openscad/+ tag: 0.1
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ UnitTest.hs view
@@ -0,0 +1,101 @@+module Main where++import Data.Monoid+import Test.HUnit+import Test.Framework+import Test.Framework.Providers.HUnit++import Graphics.OpenSCAD+import Data.Colour.Names+import Data.Colour (withOpacity)++sw = concat . words+st n e a = testCase n $ (sw e) @=?(sw $ render a)++main = defaultMainWithOpts [+ st "sphere 1" "sphere(1.0);" (sphere 1 def),+ st "sphere 2" "sphere(2.0,$fn=100);" (sphere 2 $ fn 100),+ st "sphere 3" "sphere(2.0,$fa=5.0);" (sphere 2 $ fa 5),+ st "sphere 4" "sphere(2.0,$fs=0.1);" (sphere 2 $ fs 0.1),+ st "box" "cube([1.0,2.0,3.0]);" (box 1 2 3),+ st "cube" "cube([2.0,2.0,2.0]);" (cube 2),+ st "cylinder 1" "cylinder(r=1.0,h=2.0);" (cylinder 1 2 def),+ st "cylinder 2" "cylinder(r=1.0,h=2.0,$fs=0.6);" (cylinder 1 2 $ fs 0.6),+ st "cylinder 3" "cylinder(r=1.0,h=2.0,$fn=10);" (cylinder 1 2 $ fn 10),+ st "cylinder 4" "cylinder(r=1.0,h=2.0,$fa=30.0);" (cylinder 1 2 $ fa 30),+ st "obCylinder 1" "cylinder(r1=1.0,h=2.0,r2=2.0);" (obCylinder 1 2 2 def),+ st "obCylinder 2" "cylinder(r1=1.0,h=2.0,r2=2.0,$fs=0.6);"+ (obCylinder 1 2 2 $ fs 0.6),+ st "obCylinder 3" "cylinder(r1=1.0,h=2.0,r2=2.0,$fn=10);"+ (obCylinder 1 2 2 $ fn 10),+ st "obCylinder 4" "cylinder(r1=1.0,h=2.0,r2=2.0,$fa=30.0);"+ (obCylinder 1 2 2 $ fa 30),+ -- polyhedron & import3D goes here+ st "rectangle" "square([2.0,3.0]);" (rectangle3d 2 3),+ st "square" "square([2.0,2.0]);" (square3d 2),+ st "circle 1" "circle(1.0);" (circle3d 1 def),+ st "circle 2" "circle(2.0,$fn=100);" (circle3d 2 $ fn 100),+ st "circle 3" "circle(2.0,$fa=5.0);" (circle3d 2 $ fa 5),+ st "circle 4" "circle(2.0,$fs=0.1);" (circle3d 2 $ fs 0.1),+ -- polygon & import2D goes here+ st "projection" "projection(cut=false)scale([10.0,10.0,10.0])difference(){translate([0.0,0.0,1.0])cube([1.0,1.0,1.0]);translate([0.25,0.25,0.0])cube([0.5,0.5,3.0]);}"+ (projection3d False $ scale (10, 10, 10) $ difference (up 1 (cube 1)) $ translate (0.25, 0.25, 0) (box 0.5 0.5 3)),+ -- Transformations+ st "scale" "scale([0.5,1.0,2.0])cube([1.0,1.0,1.0]);"+ (scale(0.5, 1, 2) $ cube 1),+ -- resize goes here+ st "rotate 1" "rotate(a=[180.0,0.0,0.0])cube([2.0,2.0,2.0]);"+ (rotate (180, 0, 0) $ cube 2),+ st "rotate 2" "rotate(a=[0.0,180.0,0.0])cube([2.0,2.0,2.0]);"+ (rotate (0, 180, 0) $ cube 2),+ st "rotate 3" "rotate(a=[0.0,180.0,180.0])cube([2.0,2.0,2.0]);"+ (rotate (0, 180, 180) $ cube 2),+ st "mirror 1" "mirror([1.0,0.0,0.0])cube([2.0,2.0,2.0]);"+ (mirror (1, 0, 0) $ cube 2),+ st "mirror 2" "mirror([0.0,1.0,0.0])cube([2.0,2.0,2.0]);"+ (mirror (0, 1, 0) $ cube 2),+ st "mirror 3" "rotate(a=[0.0,1.0,1.0])cube([2.0,2.0,2.0]);"+ (rotate (0, 1, 1) $ cube 2),+ st "multmatrix" "multmatrix([[1.0,0.0,0.0,10.0],[0.0,1.0,0.0,20.0],[0.0,0.0,1.0,30.0],[0.0,0.0,0.0,1.0]])cylinder(r=2.0,h=3.0);"+ (multMatrix ( (1, 0, 0, 10),+ (0, 1, 0, 20),+ (0, 0, 1, 30),+ (0, 0, 0, 1) ) $ cylinder 2 3 def),+ st "color" "color([1.0,0.0,0.0])cube([1.0,1.0,1.0]);" (color red $ cube 1),+ st "transparent" "color([1.0,0.0,0.0,0.7])cube([1.0,1.0,1.0]);"+ (transparent (red `withOpacity` 0.7) $ cube 1),+ st "linearExtrude 1"+ "linear_extrude(height=10.0,twist=0.0,scale=[1.0,1.0],slices=10,convexity=10)circle(1.0);"+ (linearExtrude 10 0 (1, 1) 10 10 def $ circle 1 def),+ st "linearExtrude 2"+ "linear_extrude(height=10.0,twist=100.0,scale=[1.0,1.0],slices=10,convexity=10)translate([2.0,0.0])circle(1.0);"+ (linearExtrude 10 100 (1, 1) 10 10 def $ translate2d (2, 0) $ circle 1 def),+ st "linearExtrude 3"+ "linear_extrude(height=10.0,twist=500.0,scale=[1.0,1.0],slices=10,convexity=10)translate([2.0,0.0])circle(1.0);"+ (linearExtrude 10 500 (1, 1) 10 10 def $ translate2d (2, 0) $ circle 1 def),+ st "linearExtrude 4"+ "linear_extrude(height=10.0,twist=360.0,scale=[1.0,1.0],slices=100,convexity=10)translate([2.0,0.0])circle(1.0);"+ (linearExtrude 10 360 (1, 1) 100 10 def $ translate2d (2, 0) $ circle 1 def),+ st "linearExtrude 5"+ "linear_extrude(height=10.0,twist=360.0,scale=[1.0,1.0],slices=100,convexity=10,$fn=100)translate([2.0,0.0])circle(1.0);"+ (linearExtrude 10 360 (1, 1) 100 10 (fn 100) $ translate2d (2, 0) $ circle 1 def),+ st "linearExtrude 6"+ "linear_extrude(height=10.0,twist=0.0,scale=[3.0,3.0],slices=100,convexity=10)translate([2.0,0.0])circle(1.0);"+ (linearExtrude 10 0 (3, 3) 100 10 def $ translate2d (2, 0) $ circle 1 def),+ st "linearExtrude 7"+ "linear_extrude(height=10.0,twist=0.0,scale=[1.0,5.0],slices=100,convexity=10,$fn=100)translate([2.0,0.0])circle(1.0);"+ (linearExtrude 10 0 (1, 5) 100 10 (fn 100) $ translate2d (2, 0)+ $ circle 1 def),+ st "rotate_extrude 1"+ "rotate_extrude(convexity=10)translate([2.0,0.0])circle(1.0);"+ (rotateExtrude 10 def $ translate2d (2, 0) $ circle 1 def),+ st "rotate_extrude 2"+ "rotate_extrude(convexity=10,$fn=100)translate([2.0,0.0])circle(1.0,$fn=100);"+ (rotateExtrude 10 (fn 100) $ translate2d (2, 0) $ circle 1 $ fn 100),+ st "facet 1" "assign($fn=100){sphere(2.0,$fn=100);}"+ (var (fn 100) [sphere 2 $ fn 100]),+ st "facet 2" "assign($fa=5.0){sphere(2.0,$fa=5.0);}"+ (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])+ ] mempty