waterfall-cad-0.2.2.0: src/Waterfall/Offset.hs
module Waterfall.Offset
( offset
) where
import Waterfall.Internal.Solid (Solid (..), acquireSolid, solidFromAcquire)
import qualified OpenCascade.BRepOffsetAPI.MakeOffsetShape as MakeOffsetShape
import Control.Monad.IO.Class (liftIO)
import OpenCascade.Inheritance (SubTypeOf(upcast), unsafeDowncast)
import qualified OpenCascade.BRepBuilderAPI.MakeShape as MakeShape
import qualified OpenCascade.BRepOffset.Mode as Mode
import qualified OpenCascade.GeomAbs.JoinType as GeomAbs.JoinType
import qualified OpenCascade.BRepBuilderAPI.MakeSolid as MakeSolid
import qualified OpenCascade.TopoDS.Types as TopoDS
import qualified OpenCascade.TopExp.Explorer as TopExp.Explorer
import qualified OpenCascade.TopAbs.ShapeEnum as TopAbs.ShapeEnum
import Control.Monad (when)
import Foreign.Ptr (Ptr)
import Data.Acquire (Acquire)
import Linear.Epsilon (nearZero)
combineShellsToSolid :: Ptr TopoDS.Shape -> Acquire (Ptr TopoDS.Shape)
combineShellsToSolid s = do
explorer <- TopExp.Explorer.new s TopAbs.ShapeEnum.Shell
makeSolid <- MakeSolid.new
let go = do
isMore <- liftIO $ TopExp.Explorer.more explorer
when isMore $ do
shell <- liftIO $ unsafeDowncast =<< TopExp.Explorer.value explorer
liftIO $ MakeSolid.add makeSolid shell
liftIO $ TopExp.Explorer.next explorer
go
go
upcast <$> MakeSolid.solid makeSolid
-- | Expand or contract a `Solid` by a certain amount.
--
-- This seems to be relatively fragile on Sweeps/Prisms
-- (as in, may fail to produce a result)
offset :: Double -- ^ Amount to offset by, positive values expand, negative values contract
-> Double -- ^ Tolerance, this can be relatively small
-> Solid -- ^ the `Solid` to offset
-> Solid
offset value tolerance solid
| nearZero value = solid
| otherwise =
solidFromAcquire $ do
builder <- MakeOffsetShape.new
s <- acquireSolid solid
--liftIO $ MakeOffsetShape.performBySimple builder s value
liftIO $ MakeOffsetShape.performByJoin builder s value tolerance Mode.Skin False False GeomAbs.JoinType.Arc False
shell <- MakeShape.shape (upcast builder)
combineShellsToSolid shell