module Geometry.HCDT.Delaunay
  ( delaunay,
    cdelaunay
  )
where

import           Foreign.Marshal.Alloc       (free, mallocBytes)
import           Foreign.Marshal.Array       (pokeArray)
import           Foreign.Storable            (peek, sizeOf)
import           Geometry.HCDT.Triangulation
import           Geometry.HCDT.Types         (Triangulation, Vertex, ConstrainedTriangulation, Edge)

-- | Unconstrained 2d Delaunay triangulation.
delaunay :: [Vertex] -> IO Triangulation
delaunay :: [Vertex] -> IO Triangulation
delaunay [Vertex]
vertices = do
  let nvertices :: Int
nvertices = [Vertex] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Vertex]
vertices
  Ptr CVertex
verticesPtr <- Int -> IO (Ptr CVertex)
forall a. Int -> IO (Ptr a)
mallocBytes (Int
nvertices Int -> Int -> Int
forall a. Num a => a -> a -> a
* CVertex -> Int
forall a. Storable a => a -> Int
sizeOf (CVertex
forall a. HasCallStack => a
undefined :: CVertex))
  [CVertex]
cvertices <- (Vertex -> IO CVertex) -> [Vertex] -> IO [CVertex]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Vertex -> IO CVertex
vertexToCVertex [Vertex]
vertices
  Ptr CVertex -> [CVertex] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr CVertex
verticesPtr [CVertex]
cvertices
  Ptr CTriangulation
ctriangulationPtr <- Ptr CVertex -> CSize -> IO (Ptr CTriangulation)
c_delaunay Ptr CVertex
verticesPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nvertices)
  CTriangulation
ctriangulation <- Ptr CTriangulation -> IO CTriangulation
forall a. Storable a => Ptr a -> IO a
peek Ptr CTriangulation
ctriangulationPtr 
  Ptr CVertex -> IO ()
forall a. Ptr a -> IO ()
free Ptr CVertex
verticesPtr
  Ptr CTriangulation -> IO ()
forall a. Ptr a -> IO ()
free Ptr CTriangulation
ctriangulationPtr
  CTriangulation -> IO Triangulation
cTriangulationToTriangulation CTriangulation
ctriangulation

-- | Constrained 2d Delaunay triangulation.
cdelaunay :: [Vertex] -> [Edge] -> IO ConstrainedTriangulation
cdelaunay :: [Vertex] -> [Edge] -> IO ConstrainedTriangulation
cdelaunay [Vertex]
vertices [Edge]
edges = do
  let nvertices :: Int
nvertices = [Vertex] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Vertex]
vertices
  Ptr CVertex
verticesPtr <- Int -> IO (Ptr CVertex)
forall a. Int -> IO (Ptr a)
mallocBytes (Int
nvertices Int -> Int -> Int
forall a. Num a => a -> a -> a
* CVertex -> Int
forall a. Storable a => a -> Int
sizeOf (CVertex
forall a. HasCallStack => a
undefined :: CVertex))
  [CVertex]
cvertices <- (Vertex -> IO CVertex) -> [Vertex] -> IO [CVertex]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Vertex -> IO CVertex
vertexToCVertex [Vertex]
vertices
  Ptr CVertex -> [CVertex] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr CVertex
verticesPtr [CVertex]
cvertices
  let nedges :: Int
nedges = [Edge] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Edge]
edges
  Ptr CEdge
edgesPtr <- Int -> IO (Ptr CEdge)
forall a. Int -> IO (Ptr a)
mallocBytes (Int
nedges Int -> Int -> Int
forall a. Num a => a -> a -> a
* CEdge -> Int
forall a. Storable a => a -> Int
sizeOf (CEdge
forall a. HasCallStack => a
undefined :: CEdge))
  [CEdge]
cedges <- (Edge -> IO CEdge) -> [Edge] -> IO [CEdge]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Edge -> IO CEdge
edgeToCEdge [Edge]
edges
  Ptr CEdge -> [CEdge] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr CEdge
edgesPtr [CEdge]
cedges
  Ptr CCTriangulation
cctriangulationPtr <- Ptr CVertex
-> CSize -> Ptr CEdge -> CSize -> IO (Ptr CCTriangulation)
c_cdelaunay Ptr CVertex
verticesPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nvertices) Ptr CEdge
edgesPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nedges)
  CCTriangulation
cctriangulation <- Ptr CCTriangulation -> IO CCTriangulation
forall a. Storable a => Ptr a -> IO a
peek Ptr CCTriangulation
cctriangulationPtr 
  Ptr CVertex -> IO ()
forall a. Ptr a -> IO ()
free Ptr CVertex
verticesPtr
  Ptr CEdge -> IO ()
forall a. Ptr a -> IO ()
free Ptr CEdge
edgesPtr
  Ptr CCTriangulation -> IO ()
forall a. Ptr a -> IO ()
free Ptr CCTriangulation
cctriangulationPtr
  CCTriangulation -> IO ConstrainedTriangulation
cCTriangulationToConstrainedTriangulation CCTriangulation
cctriangulation