waterfall-cad-0.2.0.0: src/Waterfall/TwoD/Internal/Path2D.hs
module Waterfall.TwoD.Internal.Path2D
( Path2D (..)
, joinPaths
) where
import Data.Foldable (traverse_, toList)
import Waterfall.Internal.Finalizers (toAcquire, unsafeFromAcquire)
import Control.Monad ((<=<))
import Control.Monad.IO.Class (liftIO)
import qualified OpenCascade.TopoDS as TopoDS
import qualified OpenCascade.BRepBuilderAPI.MakeWire as MakeWire
import Foreign.Ptr
import Data.Semigroup (sconcat)
-- | A Path in 2D Space
--
-- Under the hood, this is represented by an OpenCascade `TopoDS.Wire`, constrained to the plane \(z=0\).
--
-- Please feel free to report a bug if you're able to construct a `Path2D`
-- which does not lie on this plane (without using Internal functions).
newtype Path2D = Path2D { rawPath :: Ptr TopoDS.Wire }
joinPaths :: [Path2D] -> Path2D
joinPaths paths = Path2D . unsafeFromAcquire $ do
builder <- MakeWire.new
traverse_ (liftIO . MakeWire.addWire builder <=< toAcquire . rawPath) paths
MakeWire.wire builder
-- | The Semigroup for `Path2D` attempts to join two paths that share a common endpoint.
--
-- Attempts to combine paths that do not share a common endpoint currently in an error case that is not currently handled gracefully.
instance Semigroup Path2D where
sconcat = joinPaths . toList
a <> b = joinPaths [a, b]
instance Monoid Path2D where
mempty = joinPaths []
mconcat = joinPaths