;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; LUSH Lisp Universal Shell
;;;   Copyright (C) 2002 Leon Bottou, Yann Le Cun, AT&T Corp, NECI.
;;; Includes parts of TL3:
;;;   Copyright (C) 1987-1999 Leon Bottou and Neuristique.
;;; Includes selected parts of SN3.2:
;;;   Copyright (C) 1991-2001 AT&T Corp.
;;;
;;; Includes information derived from the GSL (Gnu Scientific Library)
;;;   header files which are copyrighted and distributed under the GPL
;;;   by their respective authors.
;;;
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2 of the License, or
;;; (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program; if not, write to the Free Software
;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(libload "opencv/cv-config")



#? *** subdiv

;; dummy function that adds OpenCV C header files in C file
(eval `(de dummy_subdiv () ,cv-cpheader-cmd ()))

;; #? * (dummy_subdiv)

;; ********************************************************

;;  /****************************************************************************************\
;;  *                              Planar subdivisions                                       *
;;  \****************************************************************************************/

#? * (cvsubdiv2dnextedge <edge>)
;;.PRE
;;  /************ Basic quad-edge navigation and operations ************/
;;  CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DNextEdge( CvSubdiv2DEdge edge );
;;  CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DNextEdge( CvSubdiv2DEdge edge )
;;  {
;;      return  CV_SUBDIV2D_NEXT_EDGE(edge);
;;  }
(de cvSubdiv2DNextEdge ( edge)
    ((-int-) edge)
    (int #{ cvSubdiv2DNextEdge( (long) $edge) #}))

#? * (cvsubdiv2drotateedge <edge> <rotate>)
;;.PRE
;;  CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DRotateEdge( CvSubdiv2DEdge edge, int rotate );
;;  CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DRotateEdge( CvSubdiv2DEdge edge, int rotate )
;;  {
;;      return  (edge & ~3) + ((edge + rotate) & 3);
;;  }

(de cvsubdiv2drotateedge (edge rotate)
    ((-int-) edge rotate)
    (int #{ cvSubdiv2DRotateEdge((long) $edge, $rotate) #} ))

#? * (cvsubdiv2dsymedge <edge>)
;;.PRE
;;  CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DSymEdge( CvSubdiv2DEdge edge );
;;  CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DSymEdge( CvSubdiv2DEdge edge )
;;  {
;;      return edge ^ 2;
;;  }

(de cvsubdiv2dsymedge (edge)
    ((-int-) edge)
    (int #{ cvSubdiv2DSymEdge((long)$edge) #} ))

#? * (cvsubdiv2dgetedge <edge> <type>)
;;.PRE
;;  CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type );
;;  CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type )
;;  {
;;      CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3);
;;      edge = e->next[(edge + (int)type) & 3];
;;      return  (edge & ~3) + ((edge + ((int)type >> 4)) & 3);
;;  }

(de cvsubdiv2dgetedge (edge type)
    ((-int-) edge type)
    (int #{ cvSubdiv2DGetEdge((long)$edge, $type) #}))

#? * (cvsubdiv2dedgeorg <edge>)
;;.PRE
;;  CV_INLINE  CvSubdiv2DPoint*  cvSubdiv2DEdgeOrg( CvSubdiv2DEdge edge );
;;  CV_INLINE  CvSubdiv2DPoint*  cvSubdiv2DEdgeOrg( CvSubdiv2DEdge edge )
;;  {
;;      CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3);
;;      return e->pt[edge & 3];
;;  }

(de cvsubdiv2dedgeorg (edge)
    ((-int-) edge)
    (gptr #{ cvSubdiv2DEdgeOrg ((long)$edge) #}))

#? * (cvsubdiv2dedgedst <edge>)
;;.PRE
;;  CV_INLINE  CvSubdiv2DPoint*  cvSubdiv2DEdgeDst( CvSubdiv2DEdge edge );
;;  CV_INLINE  CvSubdiv2DPoint*  cvSubdiv2DEdgeDst( CvSubdiv2DEdge edge )
;;  {
;;      CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3);
;;      return e->pt[(edge + 2) & 3];
;;  }

(de cvsubdiv2dEdgeDst (edge )
    ((-int-) edge)
    (gptr #{ cvSubdiv2DEdgeDst((long)$edge) #} ))

#? * (cvtrianglearea <a> <b> <c>)
;;.PRE
;;  CV_INLINE  double  cvTriangleArea( CvPoint2D32f a, CvPoint2D32f b, CvPoint2D32f c );
;;  CV_INLINE  double  cvTriangleArea( CvPoint2D32f a, CvPoint2D32f b, CvPoint2D32f c )
;;  {
;;      return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
;;  }

(de cvTriangleArea(a b c)
    ((-gptr- "CvPoint2D32f *") a b c)
    (double #{ cvTriangleArea(*$a, *$b, *$c) #} ))

#? * (cvcreatesubdiv2d <subdiv_type> <header_size> <vtx_size> <quadedge_size> <storage>)
;;.PRE
;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvCreateSubdiv2D
;;  //    Purpose: creates initially empty planar subdivision structure
;;  //    Context:
;;  //    Parameters:
;;  //      subdiv_type - type of subdivision
;;  //      header_size - size of header(>= sizeof(CvSubdiv2D))
;;  //      quadedge_size - size of quad-edges(>= sizeof(CvQuadEdge2D))
;;  //      vtx_size - size of vertices(>= sizeof(CvSubdiv2DPoint))
;;  //      storage  - size of memory storage
;;  //    Returns:
;;  //      created subdivision
;;  //F*/
;;  OPENCVAPI  CvSubdiv2D*  cvCreateSubdiv2D( int subdiv_type, int header_size,
;;                                         int vtx_size, int quadedge_size,
;;                                         CvMemStorage* storage );

(de cvCreateSubdiv2D ( subdiv_type  header_size  vtx_size  quadedge_size  storage)
    ((-int-) subdiv_type   header_size   vtx_size  quadedge_size)
    ((-gptr- "CvMemStorage *") storage)
    (gptr #{ cvCreateSubdiv2D($subdiv_type, $header_size, $vtx_size, $quadedge_size, $storage) #} ))



#? * (cvsubdiv2dlocate <subdiv> <pt> <edge> <point>)
;;.PRE
;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvSubdiv2DLocate
;;  //    Purpose:  finds location of the point within the Delaunay triangulation
;;  //              origin point of the second edge
;;  //    Context:
;;  //    Parameters:
;;  //      subdiv - subdivison
;;  //      pt     - searched point
;;  //      _edge  - bounding edge for facet, containing the point
;;  //      _point - vertex(if searched point coincides with the vertex)
;;  //F*/
;;  OPENCVAPI  CvSubdiv2DPointLocation  cvSubdiv2DLocate(
;;                                 CvSubdiv2D* subdiv, CvPoint2D32f pt,
;;                                 CvSubdiv2DEdge *_edge,
;;                                 CvSubdiv2DPoint** _point CV_DEFAULT(0) );

(de cvSubdiv2DLocate (subdiv pt  edge  point)
    ((-gptr- "CvSubdiv2D *") subdiv)
    ((-gptr- "CvPoint2D32f *") pt)
    ((-gptr- "CvSubdiv2DEdge *") edge)
    ((-gptr- "CvSubdiv2DPoint **") point)
    (int #{ cvSubdiv2DLocate($subdiv, *$pt, $edge, $point) #} ))


#? * (cvFindNearestPoint2D <subdiv> <pt>)
;; /* Finds the nearest to the given point vertex in subdivision. */
;; CVAPI(CvSubdiv2DPoint*) cvFindNearestPoint2D( CvSubdiv2D* subdiv, CvPoint2D32f pt );
(de cvFindNearestPoint2D (subdiv pt)
    ((-gptr- "CvSubdiv2D *") subdiv)
    ((-gptr- "CvPoint2D32f *") pt)
    (let ((p (gptr ())))
      ((-gptr- "CvSubdiv2DPoint *") p)
      #{ $p = cvFindNearestPoint2D($subdiv, *$pt) #} 
      p))

    
#? * (cvinitsubdivdelaunay2d <subdiv> <rect>)
;;.PRE
;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvInitSubdivDelaunay2D
;;  //    Purpose:  connect destination point of the first edge with
;;  //              origin point of the second edge
;;  //    Context:
;;  //    Parameters:
;;  //      subdiv - subdivison
;;  //      pt     - searched point
;;  //      _edge  - bounding edge for facet, containing the point
;;  //      _point - vertex(if searched point coincides with the vertex)
;;  //F*/
;;  OPENCVAPI  void  cvInitSubdivDelaunay2D( CvSubdiv2D* subdiv, CvRect rect );

(de cvInitSubdivDelaunay2D (subdiv rect)
    ((-gptr- "CvSubdiv2D *") subdiv)
    ((-gptr- "CvRect *") rect)
    #{ cvInitSubdivDelaunay2D ($subdiv, *$rect); #}
    ())

#? * (cvsubdivdelaunay2dinsert <subdiv> <pt>)
;;.PRE
;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvSubdivDelaunay2DInsert
;;  //    Purpose:  insert the point into the triangulation
;;  //    Context:
;;  //    Parameters:
;;  //      subdiv - subdivison
;;  //      pt     - inserted point
;;  //F*/
;;  OPENCVAPI  CvSubdiv2DPoint*  cvSubdivDelaunay2DInsert( CvSubdiv2D* subdiv, CvPoint2D32f pt);

(de cvSubdivDelaunay2DInsert( subdiv  pt)
    ((-gptr- "CvSubdiv2D *") subdiv)
    ((-gptr- "CvPoint2D32f *") pt)
    (gptr #{ cvSubdivDelaunay2DInsert($subdiv, *$pt) #}))



#? * (cvcalcsubdivvoronoi2d <subdiv>)
;;.PRE
;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvCalcSubdivVoronoi2D
;;  //    Purpose:  calculates Voronoi tesselation( Coordinates of Voronoi points)
;;  //    Context:
;;  //    Parameters:
;;  //      subdiv - subdivison
;;  //    Note:
;;  //      Before calculations the function checks the flag, indicating that
;;  //      the Voronoi tesselation is already calculated.
;;  //      If subdivision is modified(some points have been inserted), the flag is cleared.
;;  //F*/
;;  OPENCVAPI  void  cvCalcSubdivVoronoi2D( CvSubdiv2D* subdiv );

(de cvCalcSubdivVoronoi2D (subdiv)
    ((-gptr- "CvSubdiv2D *") subdiv)
    #{ cvCalcSubdivVoronoi2D($subdiv); #}
    ())

#? * (cvclearsubdivvoronoi2d <subdiv>)
;;.PRE
;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvClearSubdivVoronoi2D
;;  //    Purpose:  removes all Voronoi points from the tesselation.
;;  //    Context:
;;  //    Parameters:
;;  //      subdiv - subdivison
;;  //    Note:
;;  //      The function is called implicitly from the cvCalcSubdivVoronoi2D
;;  //      before Voronoi tesselation is calculated.
;;  //F*/
;;  OPENCVAPI  void  cvClearSubdivVoronoi2D( CvSubdiv2D* subdiv );

(de cvClearSubdivVoronoi2D (subdiv)
    ((-gptr- "CvSubdiv2D *") subdiv)
    #{ cvClearSubdivVoronoi2D($subdiv); #} 
    ())

;; ********************************************************

(dhc-make ()
  dummy_subdiv
  cvsubdiv2dnextedge
  cvsubdiv2drotateedge
  cvsubdiv2dsymedge
  cvsubdiv2dgetedge
  cvsubdiv2dedgeorg
  cvsubdiv2dedgedst
  cvtrianglearea
  cvcreatesubdiv2d
  cvsubdiv2dlocate
  cvfindnearestpoint2d
  cvinitsubdivdelaunay2d
  cvsubdivdelaunay2dinsert
  cvcalcsubdivvoronoi2d
  cvclearsubdivvoronoi2d
)
