moonlight-triangulation-0.1.0.0: src-build/Moonlight/Triangulation/Internal/Cdt/Site.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
-- | Siting of constraint endpoints: resolving a point to an existing handle,
-- and materializing one inside an open transaction when it has none.
module Moonlight.Triangulation.Internal.Cdt.Site
( lookupExistingConstraintEndpoint
, placeConstraintEndpoint
) where
import Control.Monad.ST (ST)
import Moonlight.Triangulation.Handles.HandleDefs
import Moonlight.Triangulation.Insertion (insertVertexAtPoint)
import Moonlight.Triangulation.Internal.Mutable
import Moonlight.Triangulation.Internal.OperationState
( Counter (..)
, OperationState
, addCounter
)
import Moonlight.Triangulation.Internal.PointIndex (lookupPointIndex)
import Moonlight.Triangulation.Internal.Probe (Probe (..))
import Moonlight.Triangulation.Internal.Representation
import Moonlight.Triangulation.Internal.Types
import Moonlight.Triangulation.Math
lookupExistingConstraintEndpoint
:: Triangulation mode vertex directed undirected face
-> Point
-> Maybe VertexId
lookupExistingConstraintEndpoint triangulation point =
VertexId . fromIntegral
<$> lookupPointIndex
(triPointX triangulation)
(triPointY triangulation)
(triPointIndex triangulation)
point
-- | Materialize one point in the open transaction. A payload standing at an
-- occupied position keeps that handle and overwrites the payload, which is what
-- the persistent insertion verb settled on.
--
-- The coordinates are checked here rather than by the callers, because a split
-- point is computed rather than supplied: @lineIntersection@ refuses only a
-- zero denominator, and a denominator merely close to zero answers a coordinate
-- no arena should hold.
placeConstraintEndpoint
:: MutableDcel s vertex directed undirected face
-> OperationState s
-> Maybe Int
-> Point
-> vertex
-> ST s (Either BuildError VertexId)
placeConstraintEndpoint mutable operation hint point payload =
case validatePoint Nothing point of
Left failure -> pure (Left failure)
Right _ -> do
addCounter operation CounterInputPoints 1
outcome <- insertVertexAtPoint @'ProbeOff mutable operation hint point payload
case outcome of
Left failure -> pure (Left failure)
Right (vertex, disposition) -> do
case disposition of
AlreadyPresent -> do
writeVertexData mutable vertex payload
addCounter operation CounterExistingPoints 1
addCounter operation CounterDuplicatePoints 1
Inserted -> addCounter operation CounterUniquePoints 1
pure (Right (VertexId (fromIntegral vertex)))