diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,1 +1,3 @@
 # Examples for Waterfall CAD
+
+![Waterfall CAD](https://raw.githubusercontent.com/joe-warren/opencascade-hs/main/images/logo/waterfall-cad-logo-name.svg)
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -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")
diff --git a/src/ReadSolidExpressionExample.hs b/src/ReadSolidExpressionExample.hs
new file mode 100644
--- /dev/null
+++ b/src/ReadSolidExpressionExample.hs
@@ -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 
+
+
diff --git a/waterfall-cad-examples.cabal b/waterfall-cad-examples.cabal
--- a/waterfall-cad-examples.cabal
+++ b/waterfall-cad-examples.cabal
@@ -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
