waterfall-cad-examples 0.2.1.0 → 0.2.2.0
raw patch · 5 files changed
+72/−9 lines, 5 filesdep +parsecdep +parser-combinatorsdep ~opencascade-hsdep ~waterfall-cadPVP ok
version bump matches the API change (PVP)
Dependencies added: parsec, parser-combinators
Dependency ranges changed: opencascade-hs, waterfall-cad
API changes (from Hackage documentation)
+ ReadSolidExpressionExample: readSolidExpressionExample :: String -> IO Solid
Files
- CHANGELOG.md +5/−0
- README.md +2/−0
- app/Main.hs +12/−4
- src/ReadSolidExpressionExample.hs +43/−0
- waterfall-cad-examples.cabal +10/−5
CHANGELOG.md view
@@ -8,6 +8,11 @@ ## Unreleased +## 0.2.2.0++- Added an example demonstrating `Waterfall.IO.readSolid`+- Added support for writing files as OBJ+ ## 0.2.1.0 - Added support for writing files as GLTF/GLB
README.md view
@@ -1,1 +1,3 @@ # Examples for Waterfall CAD++
app/Main.hs view
@@ -9,7 +9,8 @@ import OffsetExample (offsetExample) import TextExample (textExample) import BoundingBoxExample (boundingBoxExample)-import Waterfall.IO (writeSTL, writeSTEP, writeGLTF, writeGLB)+import ReadSolidExpressionExample (readSolidExpressionExample)+import Waterfall.IO (writeSTL, writeSTEP, writeGLTF, writeGLB, writeOBJ) import qualified Waterfall.Solids as Solids import qualified Options.Applicative as OA import Control.Applicative ((<|>), liftA2)@@ -20,7 +21,8 @@ let stlOption = (flip writeSTL) <$> OA.strOption (OA.long "stl" <> OA.metavar "Stl file to write results to") gltfOption = (flip writeGLTF) <$> OA.strOption (OA.long "gltf" <> OA.metavar "GLTF file to write results to") glbOption = (flip writeGLB) <$> OA.strOption (OA.long "glb" <> OA.metavar "GLB file to write results to")- meshOptionsNoResolution = stlOption <|> gltfOption <|> glbOption+ objOption = (flip writeOBJ) <$> OA.strOption (OA.long "obj" <> OA.metavar "OBJ file to write results to")+ meshOptionsNoResolution = stlOption <|> gltfOption <|> glbOption <|> objOption meshOptions = meshOptionsNoResolution <*> (OA.option OA.auto (OA.long "resolution" <> OA.help "linear tolerance for mesh file formats") <|> pure 0.001) stepOption = writeSTEP <$> OA.strOption (OA.long "step" <> OA.metavar "Stl file to write results to")@@ -44,6 +46,13 @@ <|> ((* (pi/180)) <$> OA.option OA.auto (OA.long "pitchDegrees" <> OA.help "pitch angle in degrees")) <|> pure (20*pi/180)) )) <|> + ( let readSolidExprDescription = + "load solid files, and combine them with boolean operatiors according to an expression.\n" <> + "filenames in expressions should be wrapped in braces {}, Expressions support brackets (),\n" <>+ "and the + * and - infix operators, meaning union, intersection and difference.\n" <>+ "eg. \"({fileA.stl}*{fileB.stl})-{fileC.stl}\"" + in readSolidExpressionExample <$> OA.strOption (OA.long "read-solid-expression" <> OA.help readSolidExprDescription)+ ) <|> (OA.flag' textExample (OA.long "text" <> OA.help "render text") <*> (OA.strOption (OA.long "font" <> OA.help "font path")) <*> (OA.option OA.auto (OA.long "size" <> OA.help "font size") <|> pure 12.0) <*>@@ -51,11 +60,10 @@ (OA.option OA.auto (OA.long "depth" <> OA.help "depth to extrude the text to") <|> pure 10.0) ) - main :: IO () main = join (OA.execParser opts) where- opts = OA.info ((liftA2 (=<<) outputOption exampleOption) OA.<**> OA.helper) + opts = OA.info ((liftA2 (=<<) outputOption exampleOption) OA.<**> OA.helper) (OA.fullDesc <> OA.progDesc "generate and write a 3D model" <> OA.header "examples for Waterfall-CAD")
+ src/ReadSolidExpressionExample.hs view
@@ -0,0 +1,43 @@+module ReadSolidExpressionExample +( readSolidExpressionExample+) where++import qualified Waterfall.Solids as Solids+import qualified Waterfall.Booleans as Booleans+import qualified Waterfall.IO+import Control.Applicative (liftA2)+import Text.Parsec+import Control.Monad.Combinators.Expr++type Parser a = Parsec String () a++atomParser :: Parser (IO Solids.Solid)+atomParser = + let filenameParser = char '{' *> (manyTill anyChar (try $ char '}')) <?> "filename"+ in Waterfall.IO.readSolid <$> filenameParser++termParser :: Parser (IO Solids.Solid)+termParser = + let brackets = between (char '(') (char ')')+ in brackets exprParser <|> atomParser <?> "term"++exprParser :: Parser (IO Solids.Solid)+exprParser = + let binary name f = InfixL (f <$ name)+ table =+ [ [ binary (char '*') (liftA2 Booleans.intersection)]+ , [ binary (char '+') (liftA2 Booleans.union) + , binary (char '-') (liftA2 Booleans.difference)+ ]+ ]+ in makeExprParser termParser table++readSolidExpressionExample :: String -> IO Solids.Solid+readSolidExpressionExample expression = + case runParser exprParser () "expression" expression of + Left err -> do + print err+ fail "Error when parsing expression"+ Right action -> action ++
waterfall-cad-examples.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: waterfall-cad-examples-version: 0.2.1.0+version: 0.2.2.0 synopsis: Examples for Waterfall CAD, a Declarative CAD/Solid Modeling Library description: Please see the README on GitHub at <https://github.com/joe-warren/opencascade-hs#readme> category: Graphics@@ -34,6 +34,7 @@ GearExample OffsetExample PrismExample+ ReadSolidExpressionExample RevolutionExample SweepExample TextExample@@ -46,9 +47,11 @@ base >=4.7 && <5 , lens ==5.* , linear >=1.21 && <2- , opencascade-hs >=0.2.1.0 && <0.3+ , opencascade-hs >=0.2.2.0 && <0.3 , optparse-applicative >=0.17 && <0.19- , waterfall-cad >=0.2.1.0 && <0.3+ , parsec ==3.1.*+ , parser-combinators >=1.2 && <1.4+ , waterfall-cad >=0.2.2.0 && <0.3 default-language: Haskell2010 executable waterfall-cad-examples@@ -62,8 +65,10 @@ base >=4.7 && <5 , lens ==5.* , linear >=1.21 && <2- , opencascade-hs >=0.2.1.0 && <0.3+ , opencascade-hs >=0.2.2.0 && <0.3 , optparse-applicative >=0.17 && <0.19- , waterfall-cad >=0.2.1.0 && <0.3+ , parsec ==3.1.*+ , parser-combinators >=1.2 && <1.4+ , waterfall-cad >=0.2.2.0 && <0.3 , waterfall-cad-examples default-language: Haskell2010