module Waterfall.Internal.Edges
( edgeEndpoints
, wireEndpoints
, allWireEndpoints
, wireTangent
, reverseEdge
, reverseWire
, intersperseLines
, joinWires
) where

import qualified OpenCascade.TopoDS as TopoDS
import qualified OpenCascade.BRep.Tool as BRep.Tool
import qualified OpenCascade.Geom.Curve as Geom.Curve
import qualified OpenCascade.BRepTools.WireExplorer as WireExplorer
import qualified OpenCascade.BRepBuilderAPI.MakeEdge as MakeEdge
import Waterfall.Internal.FromOpenCascade (gpPntToV3, gpVecToV3)
import Data.Acquire
import Control.Monad.IO.Class (liftIO)
import Linear (V3 (..), distance)
import Foreign.Ptr
import qualified OpenCascade.BRepBuilderAPI.MakeWire as MakeWire
import Control.Monad (when)
import Waterfall.Internal.ToOpenCascade (v3ToPnt)
import Data.Foldable (traverse_)

edgeEndpoints :: Ptr TopoDS.Edge -> IO (V3 Double, V3 Double)
edgeEndpoints :: Ptr Edge -> IO (V3 Double, V3 Double)
edgeEndpoints Ptr Edge
edge = (Acquire (V3 Double, V3 Double)
-> ((V3 Double, V3 Double) -> IO (V3 Double, V3 Double))
-> IO (V3 Double, V3 Double)
forall (m :: * -> *) a b.
MonadUnliftIO m =>
Acquire a -> (a -> m b) -> m b
`with` (V3 Double, V3 Double) -> IO (V3 Double, V3 Double)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure) (Acquire (V3 Double, V3 Double) -> IO (V3 Double, V3 Double))
-> Acquire (V3 Double, V3 Double) -> IO (V3 Double, V3 Double)
forall a b. (a -> b) -> a -> b
$ do
    Ptr (Handle Curve)
curve <- Ptr Edge -> Acquire (Ptr (Handle Curve))
BRep.Tool.curve Ptr Edge
edge
    Double
p1 <- IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double)
-> (Ptr Edge -> IO Double) -> Ptr Edge -> Acquire Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Edge -> IO Double
BRep.Tool.curveParamFirst (Ptr Edge -> Acquire Double) -> Ptr Edge -> Acquire Double
forall a b. (a -> b) -> a -> b
$ Ptr Edge
edge
    Double
p2 <- IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double)
-> (Ptr Edge -> IO Double) -> Ptr Edge -> Acquire Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Edge -> IO Double
BRep.Tool.curveParamLast (Ptr Edge -> Acquire Double) -> Ptr Edge -> Acquire Double
forall a b. (a -> b) -> a -> b
$ Ptr Edge
edge
    V3 Double
s <- (IO (V3 Double) -> Acquire (V3 Double)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (V3 Double) -> Acquire (V3 Double))
-> (Ptr Pnt -> IO (V3 Double)) -> Ptr Pnt -> Acquire (V3 Double)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Pnt -> IO (V3 Double)
gpPntToV3) (Ptr Pnt -> Acquire (V3 Double))
-> Acquire (Ptr Pnt) -> Acquire (V3 Double)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr (Handle Curve) -> Double -> Acquire (Ptr Pnt)
Geom.Curve.value Ptr (Handle Curve)
curve Double
p1
    V3 Double
e <- (IO (V3 Double) -> Acquire (V3 Double)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (V3 Double) -> Acquire (V3 Double))
-> (Ptr Pnt -> IO (V3 Double)) -> Ptr Pnt -> Acquire (V3 Double)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Pnt -> IO (V3 Double)
gpPntToV3) (Ptr Pnt -> Acquire (V3 Double))
-> Acquire (Ptr Pnt) -> Acquire (V3 Double)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr (Handle Curve) -> Double -> Acquire (Ptr Pnt)
Geom.Curve.value Ptr (Handle Curve)
curve Double
p2
    (V3 Double, V3 Double) -> Acquire (V3 Double, V3 Double)
forall a. a -> Acquire a
forall (m :: * -> *) a. Monad m => a -> m a
return (V3 Double
s, V3 Double
e)

allWireEndpoints :: Ptr TopoDS.Wire -> IO [(V3 Double, V3 Double)]
allWireEndpoints :: Ptr Wire -> IO [(V3 Double, V3 Double)]
allWireEndpoints Ptr Wire
wire = Acquire (Ptr WireExplorer)
-> (Ptr WireExplorer -> IO [(V3 Double, V3 Double)])
-> IO [(V3 Double, V3 Double)]
forall (m :: * -> *) a b.
MonadUnliftIO m =>
Acquire a -> (a -> m b) -> m b
with (Ptr Wire -> Acquire (Ptr WireExplorer)
WireExplorer.fromWire Ptr Wire
wire) ((Ptr WireExplorer -> IO [(V3 Double, V3 Double)])
 -> IO [(V3 Double, V3 Double)])
-> (Ptr WireExplorer -> IO [(V3 Double, V3 Double)])
-> IO [(V3 Double, V3 Double)]
forall a b. (a -> b) -> a -> b
$ \Ptr WireExplorer
explorer -> do
    let runToEnd :: IO [(V3 Double, V3 Double)]
runToEnd = do
            Ptr Edge
edge <- Ptr WireExplorer -> IO (Ptr Edge)
WireExplorer.current Ptr WireExplorer
explorer
            (V3 Double, V3 Double)
points <- Ptr Edge -> IO (V3 Double, V3 Double)
edgeEndpoints Ptr Edge
edge
            Ptr WireExplorer -> IO ()
WireExplorer.next Ptr WireExplorer
explorer
            Bool
more <- Ptr WireExplorer -> IO Bool
WireExplorer.more Ptr WireExplorer
explorer
            if Bool
more 
                then ((V3 Double, V3 Double)
points(V3 Double, V3 Double)
-> [(V3 Double, V3 Double)] -> [(V3 Double, V3 Double)]
forall a. a -> [a] -> [a]
:) ([(V3 Double, V3 Double)] -> [(V3 Double, V3 Double)])
-> IO [(V3 Double, V3 Double)] -> IO [(V3 Double, V3 Double)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO [(V3 Double, V3 Double)]
runToEnd
                else [(V3 Double, V3 Double)] -> IO [(V3 Double, V3 Double)]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(V3 Double, V3 Double)
points]
    IO [(V3 Double, V3 Double)]
runToEnd

wireEndpoints :: Ptr TopoDS.Wire -> IO (V3 Double, V3 Double)
wireEndpoints :: Ptr Wire -> IO (V3 Double, V3 Double)
wireEndpoints Ptr Wire
wire = Acquire (Ptr WireExplorer)
-> (Ptr WireExplorer -> IO (V3 Double, V3 Double))
-> IO (V3 Double, V3 Double)
forall (m :: * -> *) a b.
MonadUnliftIO m =>
Acquire a -> (a -> m b) -> m b
with (Ptr Wire -> Acquire (Ptr WireExplorer)
WireExplorer.fromWire Ptr Wire
wire) ((Ptr WireExplorer -> IO (V3 Double, V3 Double))
 -> IO (V3 Double, V3 Double))
-> (Ptr WireExplorer -> IO (V3 Double, V3 Double))
-> IO (V3 Double, V3 Double)
forall a b. (a -> b) -> a -> b
$ \Ptr WireExplorer
explorer -> do
    Ptr Edge
v1 <- Ptr WireExplorer -> IO (Ptr Edge)
WireExplorer.current Ptr WireExplorer
explorer
    (V3 Double
s, V3 Double
_) <- Ptr Edge -> IO (V3 Double, V3 Double)
edgeEndpoints Ptr Edge
v1
    let runToEnd :: IO (V3 Double)
runToEnd = do
            Ptr Edge
edge <- Ptr WireExplorer -> IO (Ptr Edge)
WireExplorer.current Ptr WireExplorer
explorer
            (V3 Double
_s, V3 Double
e') <- Ptr Edge -> IO (V3 Double, V3 Double)
edgeEndpoints Ptr Edge
edge
            Ptr WireExplorer -> IO ()
WireExplorer.next Ptr WireExplorer
explorer
            Bool
more <- Ptr WireExplorer -> IO Bool
WireExplorer.more Ptr WireExplorer
explorer
            if Bool
more 
                then IO (V3 Double)
runToEnd
                else V3 Double -> IO (V3 Double)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure V3 Double
e'
    V3 Double
e <- IO (V3 Double)
runToEnd
    (V3 Double, V3 Double) -> IO (V3 Double, V3 Double)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (V3 Double
s, V3 Double
e)

edgeTangent :: Ptr TopoDS.Edge -> IO (V3 Double)
edgeTangent :: Ptr Edge -> IO (V3 Double)
edgeTangent Ptr Edge
e = (Acquire (V3 Double)
-> (V3 Double -> IO (V3 Double)) -> IO (V3 Double)
forall (m :: * -> *) a b.
MonadUnliftIO m =>
Acquire a -> (a -> m b) -> m b
`with` V3 Double -> IO (V3 Double)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure) (Acquire (V3 Double) -> IO (V3 Double))
-> Acquire (V3 Double) -> IO (V3 Double)
forall a b. (a -> b) -> a -> b
$ do
    Ptr (Handle Curve)
curve <- Ptr Edge -> Acquire (Ptr (Handle Curve))
BRep.Tool.curve Ptr Edge
e
    Double
p1 <- IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double)
-> (Ptr Edge -> IO Double) -> Ptr Edge -> Acquire Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Edge -> IO Double
BRep.Tool.curveParamFirst (Ptr Edge -> Acquire Double) -> Ptr Edge -> Acquire Double
forall a b. (a -> b) -> a -> b
$ Ptr Edge
e
    IO (V3 Double) -> Acquire (V3 Double)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (V3 Double) -> Acquire (V3 Double))
-> (Ptr Vec -> IO (V3 Double)) -> Ptr Vec -> Acquire (V3 Double)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Vec -> IO (V3 Double)
gpVecToV3 (Ptr Vec -> Acquire (V3 Double))
-> Acquire (Ptr Vec) -> Acquire (V3 Double)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr (Handle Curve) -> Double -> Int -> Acquire (Ptr Vec)
Geom.Curve.dn Ptr (Handle Curve)
curve Double
p1 Int
1

wireTangent :: Ptr TopoDS.Wire -> IO (V3 Double)
wireTangent :: Ptr Wire -> IO (V3 Double)
wireTangent Ptr Wire
wire = Acquire (Ptr WireExplorer)
-> (Ptr WireExplorer -> IO (V3 Double)) -> IO (V3 Double)
forall (m :: * -> *) a b.
MonadUnliftIO m =>
Acquire a -> (a -> m b) -> m b
with (Ptr Wire -> Acquire (Ptr WireExplorer)
WireExplorer.fromWire Ptr Wire
wire) ((Ptr WireExplorer -> IO (V3 Double)) -> IO (V3 Double))
-> (Ptr WireExplorer -> IO (V3 Double)) -> IO (V3 Double)
forall a b. (a -> b) -> a -> b
$ \Ptr WireExplorer
explorer -> do
    Ptr Edge
v1 <- Ptr WireExplorer -> IO (Ptr Edge)
WireExplorer.current Ptr WireExplorer
explorer
    Ptr Edge -> IO (V3 Double)
edgeTangent Ptr Edge
v1

reverseEdge :: Ptr TopoDS.Edge -> Acquire (Ptr TopoDS.Edge)
reverseEdge :: Ptr Edge -> Acquire (Ptr Edge)
reverseEdge Ptr Edge
e = do
    Ptr (Handle Curve)
curve <- Ptr Edge -> Acquire (Ptr (Handle Curve))
BRep.Tool.curve Ptr Edge
e 
    Double
firstP <- IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double) -> IO Double -> Acquire Double
forall a b. (a -> b) -> a -> b
$ Ptr Edge -> IO Double
BRep.Tool.curveParamFirst Ptr Edge
e
    Double
lastP <- IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double) -> IO Double -> Acquire Double
forall a b. (a -> b) -> a -> b
$ Ptr Edge -> IO Double
BRep.Tool.curveParamLast Ptr Edge
e
    Double
firstP' <- IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double) -> IO Double -> Acquire Double
forall a b. (a -> b) -> a -> b
$ Ptr (Handle Curve) -> Double -> IO Double
Geom.Curve.reversedParameter Ptr (Handle Curve)
curve Double
firstP
    Double
lastP' <- IO Double -> Acquire Double
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Acquire Double) -> IO Double -> Acquire Double
forall a b. (a -> b) -> a -> b
$ Ptr (Handle Curve) -> Double -> IO Double
Geom.Curve.reversedParameter Ptr (Handle Curve)
curve Double
lastP
    Ptr (Handle Curve)
curve' <- Ptr (Handle Curve) -> Acquire (Ptr (Handle Curve))
Geom.Curve.reversed Ptr (Handle Curve)
curve
    Ptr (Handle Curve) -> Double -> Double -> Acquire (Ptr Edge)
MakeEdge.fromCurveAndParameters Ptr (Handle Curve)
curve' Double
lastP' Double
firstP' 

reverseWire :: Ptr TopoDS.Wire -> Acquire (Ptr TopoDS.Wire) 
reverseWire :: Ptr Wire -> Acquire (Ptr Wire)
reverseWire Ptr Wire
wire = do
    Ptr WireExplorer
explorer <- Ptr Wire -> Acquire (Ptr WireExplorer)
WireExplorer.fromWire Ptr Wire
wire
    Ptr MakeWire
makeWire <- Acquire (Ptr MakeWire)
MakeWire.new
    let runToEnd :: Acquire ()
runToEnd = do
            Ptr Edge
edge <- IO (Ptr Edge) -> Acquire (Ptr Edge)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr Edge) -> Acquire (Ptr Edge))
-> IO (Ptr Edge) -> Acquire (Ptr Edge)
forall a b. (a -> b) -> a -> b
$ Ptr WireExplorer -> IO (Ptr Edge)
WireExplorer.current Ptr WireExplorer
explorer
            Ptr Edge
edge' <- Ptr Edge -> Acquire (Ptr Edge)
reverseEdge Ptr Edge
edge
            IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr WireExplorer -> IO ()
WireExplorer.next Ptr WireExplorer
explorer
            Bool
more <- IO Bool -> Acquire Bool
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> Acquire Bool) -> IO Bool -> Acquire Bool
forall a b. (a -> b) -> a -> b
$ Ptr WireExplorer -> IO Bool
WireExplorer.more Ptr WireExplorer
explorer
            Bool -> Acquire () -> Acquire ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
more Acquire ()
runToEnd
            IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr MakeWire -> Ptr Edge -> IO ()
MakeWire.addEdge Ptr MakeWire
makeWire Ptr Edge
edge'
    Acquire ()
runToEnd
    Ptr MakeWire -> Acquire (Ptr Wire)
MakeWire.wire Ptr MakeWire
makeWire

line' :: V3 Double -> V3 Double -> Acquire (Ptr TopoDS.Wire)
line' :: V3 Double -> V3 Double -> Acquire (Ptr Wire)
line' V3 Double
s V3 Double
e = do
    Ptr MakeWire
builder <- Acquire (Ptr MakeWire)
MakeWire.new
    Ptr Pnt
pt1 <- V3 Double -> Acquire (Ptr Pnt)
v3ToPnt V3 Double
s
    Ptr Pnt
pt2 <- V3 Double -> Acquire (Ptr Pnt)
v3ToPnt V3 Double
e
    Ptr Edge
edge <- Ptr Pnt -> Ptr Pnt -> Acquire (Ptr Edge)
MakeEdge.fromPnts Ptr Pnt
pt1 Ptr Pnt
pt2
    IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr MakeWire -> Ptr Edge -> IO ()
MakeWire.addEdge Ptr MakeWire
builder Ptr Edge
edge
    Ptr MakeWire -> Acquire (Ptr Wire)
MakeWire.wire Ptr MakeWire
builder
    
intersperseLines :: [Ptr TopoDS.Wire] -> Acquire [Ptr TopoDS.Wire]
intersperseLines :: [Ptr Wire] -> Acquire [Ptr Wire]
intersperseLines [] = [Ptr Wire] -> Acquire [Ptr Wire]
forall a. a -> Acquire a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
intersperseLines [Ptr Wire
x] = [Ptr Wire] -> Acquire [Ptr Wire]
forall a. a -> Acquire a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Ptr Wire
x]
intersperseLines (Ptr Wire
a:Ptr Wire
b:[Ptr Wire]
xs) = do
    (V3 Double
_, V3 Double
ea) <- IO (V3 Double, V3 Double) -> Acquire (V3 Double, V3 Double)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (V3 Double, V3 Double) -> Acquire (V3 Double, V3 Double))
-> IO (V3 Double, V3 Double) -> Acquire (V3 Double, V3 Double)
forall a b. (a -> b) -> a -> b
$ Ptr Wire -> IO (V3 Double, V3 Double)
wireEndpoints Ptr Wire
a
    (V3 Double
sb, V3 Double
_) <- IO (V3 Double, V3 Double) -> Acquire (V3 Double, V3 Double)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (V3 Double, V3 Double) -> Acquire (V3 Double, V3 Double))
-> IO (V3 Double, V3 Double) -> Acquire (V3 Double, V3 Double)
forall a b. (a -> b) -> a -> b
$ Ptr Wire -> IO (V3 Double, V3 Double)
wireEndpoints Ptr Wire
b
    if V3 Double -> V3 Double -> Double
forall a. Floating a => V3 a -> V3 a -> a
forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a -> a
distance V3 Double
ea V3 Double
sb Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
1e-6
            then (Ptr Wire
a Ptr Wire -> [Ptr Wire] -> [Ptr Wire]
forall a. a -> [a] -> [a]
:) ([Ptr Wire] -> [Ptr Wire])
-> Acquire [Ptr Wire] -> Acquire [Ptr Wire]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Ptr Wire] -> Acquire [Ptr Wire]
intersperseLines (Ptr Wire
bPtr Wire -> [Ptr Wire] -> [Ptr Wire]
forall a. a -> [a] -> [a]
:[Ptr Wire]
xs)
            else (Ptr Wire
a Ptr Wire -> [Ptr Wire] -> [Ptr Wire]
forall a. a -> [a] -> [a]
:) ([Ptr Wire] -> [Ptr Wire])
-> Acquire [Ptr Wire] -> Acquire [Ptr Wire]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((:) (Ptr Wire -> [Ptr Wire] -> [Ptr Wire])
-> Acquire (Ptr Wire) -> Acquire ([Ptr Wire] -> [Ptr Wire])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> V3 Double -> V3 Double -> Acquire (Ptr Wire)
line' V3 Double
ea V3 Double
sb Acquire ([Ptr Wire] -> [Ptr Wire])
-> Acquire [Ptr Wire] -> Acquire [Ptr Wire]
forall a b. Acquire (a -> b) -> Acquire a -> Acquire b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Ptr Wire] -> Acquire [Ptr Wire]
intersperseLines (Ptr Wire
bPtr Wire -> [Ptr Wire] -> [Ptr Wire]
forall a. a -> [a] -> [a]
:[Ptr Wire]
xs))

joinWires :: [Ptr TopoDS.Wire] -> Acquire (Ptr TopoDS.Wire)
joinWires :: [Ptr Wire] -> Acquire (Ptr Wire)
joinWires [Ptr Wire]
wires = do
    Ptr MakeWire
builder <- Acquire (Ptr MakeWire)
MakeWire.new
    let addWire :: Ptr Wire -> Acquire ()
addWire Ptr Wire
wire = do 
            Ptr WireExplorer
explorer <- Ptr Wire -> Acquire (Ptr WireExplorer)
WireExplorer.fromWire Ptr Wire
wire
            let runToEnd :: Acquire ()
runToEnd = do
                    Ptr Edge
edge <- IO (Ptr Edge) -> Acquire (Ptr Edge)
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr Edge) -> Acquire (Ptr Edge))
-> IO (Ptr Edge) -> Acquire (Ptr Edge)
forall a b. (a -> b) -> a -> b
$ Ptr WireExplorer -> IO (Ptr Edge)
WireExplorer.current Ptr WireExplorer
explorer
                    IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr MakeWire -> Ptr Edge -> IO ()
MakeWire.addEdge Ptr MakeWire
builder Ptr Edge
edge
                    IO () -> Acquire ()
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Acquire ()) -> IO () -> Acquire ()
forall a b. (a -> b) -> a -> b
$ Ptr WireExplorer -> IO ()
WireExplorer.next Ptr WireExplorer
explorer
                    Bool
more <- IO Bool -> Acquire Bool
forall a. IO a -> Acquire a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> Acquire Bool) -> IO Bool -> Acquire Bool
forall a b. (a -> b) -> a -> b
$ Ptr WireExplorer -> IO Bool
WireExplorer.more Ptr WireExplorer
explorer
                    Bool -> Acquire () -> Acquire ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
more Acquire ()
runToEnd
            Acquire ()
runToEnd
    (Ptr Wire -> Acquire ()) -> [Ptr Wire] -> Acquire ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Ptr Wire -> Acquire ()
addWire ([Ptr Wire] -> Acquire ()) -> [Ptr Wire] -> Acquire ()
forall a b. (a -> b) -> a -> b
$ [Ptr Wire]
wires
    Ptr MakeWire -> Acquire (Ptr Wire)
MakeWire.wire Ptr MakeWire
builder