module Waterfall.Internal.Edges ( edgeEndpoints , wireEndpoints , wireTangent ) 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 Waterfall.Internal.FromOpenCascade (gpPntToV3, gpVecToV3) import Data.Acquire import Control.Monad.IO.Class (liftIO) import Linear (V3 (..)) import Foreign.Ptr edgeEndpoints :: Ptr TopoDS.Edge -> IO (V3 Double, V3 Double) edgeEndpoints edge = (`with` pure) $ do curve <- BRep.Tool.curve edge p1 <- liftIO . BRep.Tool.curveParamFirst $ edge p2 <- liftIO . BRep.Tool.curveParamLast $ edge s <- (liftIO . gpPntToV3) =<< Geom.Curve.value curve p1 e <- (liftIO . gpPntToV3) =<< Geom.Curve.value curve p2 return (s, e) wireEndpoints :: Ptr TopoDS.Wire -> IO (V3 Double, V3 Double) wireEndpoints wire = with (WireExplorer.fromWire wire) $ \explorer -> do v1 <- WireExplorer.current explorer (s, _) <- edgeEndpoints v1 let runToEnd = do edge <- WireExplorer.current explorer (_s, e') <- edgeEndpoints edge WireExplorer.next explorer more <- WireExplorer.more explorer if more then runToEnd else pure e' e <- runToEnd return (s, e) edgeTangent :: Ptr TopoDS.Edge -> IO (V3 Double) edgeTangent e = (`with` pure) $ do curve <- BRep.Tool.curve e p1 <- liftIO . BRep.Tool.curveParamFirst $ e liftIO . gpVecToV3 =<< Geom.Curve.dn curve p1 1 wireTangent :: Ptr TopoDS.Wire -> IO (V3 Double) wireTangent wire = with (WireExplorer.fromWire wire) $ \explorer -> do v1 <- WireExplorer.current explorer edgeTangent v1