waterfall-cad-0.2.0.0: src/Waterfall/IO.hs
module Waterfall.IO
( writeSTL
, writeSTEP
) where
import Waterfall.Internal.Solid (Solid(..))
import qualified OpenCascade.BRepMesh.IncrementalMesh as BRepMesh.IncrementalMesh
import qualified OpenCascade.StlAPI.Writer as StlWriter
import qualified OpenCascade.STEPControl.Writer as StepWriter
import qualified OpenCascade.STEPControl.StepModelType as StepModelType
import Control.Monad.IO.Class (liftIO)
import Control.Monad (void, unless)
import System.IO (hPutStrLn, stderr)
import Waterfall.Internal.Finalizers (toAcquire)
import Data.Acquire
-- | Write a `Solid` to a (binary) STL file at a given path
--
-- Because BRep representations of objects can store arbitrary precision curves,
-- but STL files store triangulated surfaces,
-- this function takes a "deflection" argument used to discretize curves.
--
-- The deflection is the maximum allowable distance between a curve and the generated triangulation.
writeSTL :: Double -> FilePath -> Solid -> IO ()
writeSTL linDeflection filepath (Solid ptr) = (`withAcquire` pure) $ do
s <- toAcquire ptr
mesh <- BRepMesh.IncrementalMesh.fromShapeAndLinDeflection s linDeflection
liftIO $ BRepMesh.IncrementalMesh.perform mesh
writer <- StlWriter.new
liftIO $ do
StlWriter.setAsciiMode writer False
res <- StlWriter.write writer s filepath
unless res (hPutStrLn stderr ("failed to write " <> filepath))
return ()
-- | Write a `Solid` to a STEP file at a given path
--
-- STEP files can be imported by [FreeCAD](https://www.freecad.org/)
writeSTEP :: FilePath -> Solid -> IO ()
writeSTEP filepath (Solid ptr) = (`withAcquire` pure) $ do
s <- toAcquire ptr
writer <- StepWriter.new
_ <- liftIO $ StepWriter.transfer writer s StepModelType.Asls True
void . liftIO $ StepWriter.write writer filepath