getAngle fm id = let
    ps     = V.map controlPoint . V.fromList . IM.elems . controlPoints $ fm
    func x = do
      s            <- M.lookup x (surfaces fm)
      (patch, pos) <- findVertex (patchs s) id
      tn1          <- normalize <$> tan1 (evalPatch ps patch) pos
      tn2          <- normalize <$> tan2 (evalPatch ps patch) pos
      return (acos $ tn1 &. tn2)
    in case IM.lookup id (controlPoints fm) of
      Nothing -> []
      Just cp -> let
        sIDs   = S.elems $ surfaceMembers cp
        in mapMaybe func sIDs
getAngle fm id = let
    ps     = V.map controlPoint . V.fromList . IM.elems . controlPoints $ fm
    func x = do
      s            <- M.lookup x (surfaces fm)
      (patch, pos) <- findVertex (patchs s) id
      tn1          <- normalize <$> tan1 (evalPatch ps patch) pos
      tn2          <- normalize <$> tan2 (evalPatch ps patch) pos
      return (acos $ tn1 &. tn2)
    in case IM.lookup id (controlPoints fm) of
      Nothing -> []
      Just cp -> let
        sIDs   = S.elems $ surfaceMembers cp
        in mapMaybe func sIDs
getAngle fm id = let
    ps     = V.map controlPoint . V.fromList . IM.elems . controlPoints $ fm
    func x = do
      s            <- M.lookup x (surfaces fm)
      (patch, pos) <- findVertex (patchs s) id
      tn1          <- normalize <$> tan1 (evalPatch ps patch) pos
      tn2          <- normalize <$> tan2 (evalPatch ps patch) pos
      return (acos $ tn1 &. tn2)
    in case IM.lookup id (controlPoints fm) of
      Nothing -> []
      Just cp -> let
        sIDs   = S.elems $ surfaceMembers cp
        in mapMaybe func sIDs