function [m,ok] = leaf_circle( m, varargin )
%m = leaf_circle( m, ... )
%   Create a new circular mesh.
%
%   Arguments:
%       M is either empty or an existing mesh.  If it is empty, then an
%       entirely new mesh is created, with the default set of morphogens.
%       If M is an existing mesh, then its geometry is replaced by the new
%       mesh.  It retains the same set of morphogens (all set to zero
%       everywhere on the new mesh), interaction function, and all other
%       properties not depending on the specific geometry of the mesh.
%
%   Options:
%       'xwidth'        The diameter of the circle in the x direction.  Default 2.
%       'ywidth'        The diameter of the circle in the y direction.  Default 2.
%       'rings'         The number of circular rings of triangles to divide
%                       it into. Default 4.
%       'circumpts'     The number of vertexes around the circumference.
%                       The default is rings*6.  It must be at least 4, and
%                       for best results should be at least rings*4.  As a
%                       special case, if zero is specified, rings*6 is
%                       chosen.
%       'innerpts'      The number of vertexes around the innermost ring of
%                       points. Default is max( floor(circum/nrings), 3 ).
%       'dealign'       Dealign the vertexes on adjacent rings. Default
%                       false.  Only applies when circumpts is nonzero.
%       'coneangle'     Make a circular cap of a sphere instead of a flat
%                       circle.  The surface can be defined as the
%                       interscetion of the surface of a sphere with a cone
%                       whose apex is at the centre of the sphere.  The
%                       value of coneangle is the angle between the axis of
%                       the cone and the surface of the cone.  The default
%                       is zero, i.e. make a flat circle.  If coneangle is
%                       negative, the spherical cap is made in the -z
%                       direction.  coneangle should be between -PI and PI.
%       'height'        Modify the height of the circular cap specified by
%                       coneangle, by scaling the z-axis to make the height
%                       of the centre of the cap above the plane of its rim
%                       equal to the specified value.  If coneangle is not
%                       specified, and height is non-zero, then coneangle
%                       defaults to PI/2.  If coneangle is specified and
%                       height is not, then height defaults to thevalue for
%                       a spherical cap, i.e. height = radius(1 -
%                       cos(coneangle), where radius = sqrt(xwidth*ywidth).
%
%   Example:
%       m = leaf_circle( [], 'radius', 2, 'rings', 4 );
%
%   Equivalent GUI operation: selecting "Circle" or "Hemisphere" on the
%   pulldown menu on the "Mesh editor" panel, and clicking the "Generate
%   mesh" button.
%
%   Topics: Mesh creation.

    [s,ok] = safemakestruct( mfilename(), varargin );
    if ~ok, return; end
    setGlobals();
    global gMAX_MGENVERSION
    s = defaultfields( s, 'xwidth', 0, 'ywidth', 0, 'centre', [0 0 0], 'rings', 4, ...
        'circumpts', 0, 'innerpts', 0, 'dealign', 1, 'height', 0, ...
        'coneangle', 0, 'version', gMAX_MGENVERSION );
    ok = checkcommandargs( mfilename(), s, 'exact', ...
        'xwidth', 'ywidth', 'centre', 'rings', 'circumpts', 'innerpts', 'dealign', ...
        'height', 'coneangle', 'version' );
    if ~ok, return; end

    % Each of xwidth and ywidth defaults to the other.
    % If neither is supplied, they default to 2.
    if s.xwidth == 0
        s.xwidth = s.ywidth;
    elseif s.ywidth == 0
        s.ywidth = s.xwidth;
    end
    if s.xwidth == 0
        s.xwidth = 2;
        s.ywidth = 2;
    end
    sz = [s.xwidth, s.ywidth, s.height*sqrt( (s.xwidth * s.ywidth)/4 )];
    
    if s.circumpts==0
        s.circumpts = 6 * s.rings;
    end
    if s.circumpts==0
        newm = hexcircle( s.radius, s.rings, s.centre );
    else
        newm = newcirclemesh( sz, s.circumpts, s.rings, s.centre, s.innerpts, s.dealign, 1, s.coneangle );
    end
    m = setmeshfromnodes( newm, m, s.version );
    m.meshparams = s;
    m.meshparams.randomness = 0;
    if s.height==0
        m.meshparams.type = regexprep( mfilename(), '^leaf_', '' );
    else
        m.meshparams.type = 'hemisphere';
    end
end

