function varargout = metchgui_one(varargin)
%    alldata = metchgui_one(node,elem,points) or metchgui_one(volume,points,pface)
%
%    A GUI to register a point cloud to a mesh or volumetric image
%
%    author: Qianqian Fang <q.fang at neu.edu>
%    date: 12/16/2008
%
%   parameters:
%        node: node coordinate of the surface mesh (nn x 3)
%        elem: element list of the surface mesh (3 columns for
%              triangular mesh, 4 columns for cubic surface mesh)
%        points: the coordinates (3 columns for x/y/z) of the
%              point cloud which you want to register
%        pface:trianglular surface defined on the point cloud.
%              pface is optional; if presents, metch will display
%              a surface object instead of a point cloud.
%
%   the input can also be two parameters in form of metchgui_one(volume,points),
%    where volume is a 3D image (array).
%
%   outputs:
%        alldata: a structrure containing all processing outputs
%        the fields include:
%         .node: the input node
%         .elem: the input surface mesh elements
%         .volume: if the input volumetric image
%         .A0: the affine rotation for selected point pairs (after Initialize)
%         .b0: the affine translation for selected point pairs (after Initialize)
%         .A: the affine rotation for the point cloud (after Optimize)
%         .b: the affine translation for the point cloud (after Optimize)
%         .points: the input point cloud
%         .pointsinit: the point cloud after initialization
%         .pointsopt: the point cloud after optimization
%         .pointsproj: the point cloud after projecting to the surface
%         .initplot: the handle to the point cloud plot after init
%         .optplot: the handle to the point cloud plot after optimization
%         .projplot: the handle to the point cloud plot after projection
%
%   If user supplys an output variable, the GUI will not return until the
%   user hits the "close" button or close the window; if user does not
%   supply any output, the call will return immediately; any data user
%   intends to save, he has to click on "Save Session" button and provides
%   a mat-file file name. A single structure named "metchsession" will be
%   stored in this file.
%
%   example: (meshasphere/meshunitsphere are defined in iso2mesh http://iso2mesh.sf.net)
%
%       [noderef,faceref,elemref]=meshunitsphere(0.08,10);
%       [no,fc]=removeisolatednode(noderef(:,1:3),faceref(:,1:3));
%       [node,face,elem]=meshasphere([10 20 15],3,0.5,10);
%       [no2,fc2]=removeisolatednode(node(:,1:3),face(:,1:3));
%       alldata = metchgui(no,fc,no2);
%       % or alldata = metchgui(no,fc,no2,fc2);
%
%   Please find more information at http://iso2mesh.sf.net/cgi-bin/index.cgi?metch
%
%   this function is part of "metch" toobox, see COPYING for license

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @metchgui_one_OpeningFcn, ...
                   'gui_OutputFcn',  @metchgui_one_OutputFcn, ...
                   'gui_LayoutFcn',  @metchgui_one_LayoutFcn, ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}, 'hasoutput');
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before metchgui_one is made visible.
function metchgui_one_OpeningFcn(hObject, eventdata, handles, varargin)
handles.hasoutput = 0;
if (isempty(varargin))
    fprintf(1, 'Metch GUI must be called with parameters:\nFormat: alldata = metchgui_one(node,elem,points,pface);\n');
    close(handles.MetchGUI);
    return
end
if (ischar(varargin{end}) && strcmp(varargin{end}, 'hasoutput'))
    handles.hasoutput = 1;
    varargin(end) = [];
end
handles.output = hObject;

set(handles.btAddMeshPt, 'userdata', [handles.axMesh, handles.btAddMeshPt, handles.btAddCloudPt]);
set(handles.btAddCloudPt, 'userdata', [handles.axMesh, handles.btAddCloudPt, handles.btAddMeshPt]);

% if uses supplied 2 input variables, assume a volume image and a point cloud
if (isnumeric(varargin{1}) && length(size(varargin{1})) == 3)
    vol = varargin{1};
    pt = varargin{2};

    dat.volume = vol;
    dat.points = pt;

    slice = round(size(vol, 3) / 2);
    hs = imagesc(vol(:, :, slice), 'parent', handles.axMesh);
    set(handles.slPos, 'max', size(vol, 3), 'min', 1, 'value', slice);

    if (length(varargin) >= 3)
        pface = varargin{3};
        dat.pface = pface;
        trisurf(pface(:, 1:3), pt(:, 1), pt(:, 2), pt(:, 3), 'parent', handles.axPoints);
    else
        % plot3(pt(:,1),pt(:,2),pt(:,3),'.','parent',handles.axPoints);
        ptcolor = (pt - repmat(min(pt), size(pt, 1), 1)) ./ repmat(max(pt) - min(pt), size(pt, 1), 1);
        drawnow;
        scatter3(pt(:, 1), pt(:, 2), pt(:, 3), 3, ptcolor, 'filled');
    end
    set(handles.MetchGUI, 'userdata', dat);

    axis(handles.axMesh, 'equal');
    axis(handles.axPoints, 'equal');
    axis(handles.axMesh, 'off');
    grid(handles.axPoints, 'on');
    % axis(handles.axPoints,'off');

    set(handles.axMesh, 'tag', 'axMesh');
    set(handles.axPoints, 'tag', 'axPoints');
    set(handles.slPos, 'visible', 'on');
    set(handles.lbZPos, 'visible', 'on');
    rotate3d(handles.axPoints, 'on');
    rotate3d(gcf, 'on');
end

% if uses supplied 3 input variables, assume a surface mesh and a point cloud/surface
if (length(varargin) >= 3 && length(size(varargin{1})) == 2)
    node = varargin{1};
    elem = varargin{2};
    pt = varargin{3};

    dat.node = node;
    dat.elem = elem;
    dat.points = pt;
    if (length(varargin) >= 4)
        pface = varargin{4};
        dat.pface = pface;
    end
    set(handles.MetchGUI, 'userdata', dat);

    drawinit(handles, dat);
end
guidata(hObject, handles);

if (handles.hasoutput)
    uiwait(handles.MetchGUI);
end

% ---------------------------------------------------------------------------
function drawinit(handles, dat)

node = dat.node;
elem = dat.elem;
pt = dat.points;

hs = trisurf(elem, node(:, 1), node(:, 2), node(:, 3), 'parent', handles.axMesh);
% set(hs,'linestyle','none');
% set(hs,'facecolor','b','facealpha',0.8);

% plot3(pt(:,1),pt(:,2),pt(:,3),'.','parent',handles.axPoints);
if (~isfield(dat, 'pface'))
    ptcolor = (pt - repmat(min(pt), size(pt, 1), 1)) ./ repmat(max(pt) - min(pt), size(pt, 1), 1);
    drawnow;
    scatter3(pt(:, 1), pt(:, 2), pt(:, 3), 3, ptcolor, 'filled');
else
    trisurf(dat.pface, pt(:, 1), pt(:, 2), pt(:, 3), 'parent', handles.axPoints);
end
% hold(handles.axPoints,'on');
% plot3(pt(5:7,1),pt(5:7,2),pt(5:7,3),'ro','parent',handles.axPoints);

axis(handles.axMesh, 'equal');
axis(handles.axPoints, 'equal');
axis(handles.axMesh, 'off');
% axis(handles.axPoints,'off');

set(handles.axMesh, 'tag', 'axMesh');
set(handles.axPoints, 'tag', 'axPoints');

if (~exist('OCTAVE_VERSION'))
    rotate3d(handles.axPoints, 'on');
    rotate3d(handles.axMesh, 'on');
end
rotate3d(gcf, 'on');

% ---------------------------------------------------------------------------
function varargout = metchgui_one_OutputFcn(hObject, eventdata, handles)
if (length(handles) && isfield(handles, 'output') && isfield(handles, 'hasoutput') && handles.hasoutput)
    handles.output = get(handles.MetchGUI, 'userdata');
    varargout{1} = handles.output;
    close(handles.MetchGUI);
end

% ---------------------------------------------------------------------------
function lbMesh_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject, 'BackgroundColor'), get(0, 'defaultUicontrolBackgroundColor'))
    set(hObject, 'BackgroundColor', 'white');
end

% ---------------------------------------------------------------------------
function lbPoints_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject, 'BackgroundColor'), get(0, 'defaultUicontrolBackgroundColor'))
    set(hObject, 'BackgroundColor', 'white');
end

% ---------------------------------------------------------------------------
function edit1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject, 'BackgroundColor'), get(0, 'defaultUicontrolBackgroundColor'))
    set(hObject, 'BackgroundColor', 'white');
end

% ---------------------------------------------------------------------------
function edit2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject, 'BackgroundColor'), get(0, 'defaultUicontrolBackgroundColor'))
    set(hObject, 'BackgroundColor', 'white');
end

% ---------------------------------------------------------------------------
function edit3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject, 'BackgroundColor'), get(0, 'defaultUicontrolBackgroundColor'))
    set(hObject, 'BackgroundColor', 'white');
end

% ---------------------------------------------------------------------------
function isSelect_Callback(hObject, eventdata, handles)
if (get(hObject, 'Value'))
    datacursormode(gcf, 'on');
    set(datacursormode(gcf), 'UpdateFcn', @myupdatefcn);
else
    datacursormode(gcf, 'off');
    rotate3d(gcf, 'on');
end

% ---------------------------------------------------------------------------
% the respond function when there is a data-tip to popup
% ---------------------------------------------------------------------------
function txt = myupdatefcn(empt, event_obj)
pos = get(event_obj, 'Position');
idx =  get(event_obj, 'DataIndex');

if (length(pos) == 3)
    txt = {['x: ', num2str(pos(1))], ...
           ['y: ', num2str(pos(2))], ['z: ', num2str(pos(3))], ['index:', num2str(idx)]};
elseif (length(pos) == 2)
    txt = {['x: ', num2str(pos(1))], ['y: ', num2str(pos(2))]};
end
targetup = get(get(event_obj, 'Target'), 'parent');
set(targetup, 'userdata', struct('pos', pos, 'idx', idx));
if (targetup == findobj('tag', 'axMesh'))
    set(findobj('tag', 'btAddMeshPt'), 'enable', 'on');
    set(findobj('tag', 'btAddCloudPt'), 'enable', 'off');
elseif (targetup == findobj('tag', 'axPoints'))
    set(findobj('tag', 'btAddMeshPt'), 'enable', 'off');
    set(findobj('tag', 'btAddCloudPt'), 'enable', 'on');
end

% ---------------------------------------------------------------------------
function bInit_Callback(hObject, eventdata, handles)
mapto = get(handles.lbMesh, 'userdata');
mapfrom = get(handles.lbPoints, 'userdata');

maptoidx = get(handles.txMapTo, 'userdata');
mapfromidx = get(handles.txMapFrom, 'userdata');

if (length(mapto) < 4 | length(mapfrom) < 4)
    msgbox('You have to select >3 points from the point cloud plot and corresponding points from the mesh', 'Error', 'error');
    return
end
[A, b] = affinemap(mapfrom, mapto);
dat = get(handles.MetchGUI, 'userdata');
dat.A0 = A;
dat.b0 = b;

newpt = (A * dat.points' + repmat(b(:), 1, size(dat.points, 1)))';
dat.pointsinit = newpt;

hold(handles.axMesh, 'on');
if (isfield(dat, 'initplot'))
    delete dat.initplot;
    dat.initplot = 0;
end
dat.initplot = plot3(newpt(:, 1), newpt(:, 2), newpt(:, 3), 'r.', 'parent', handles.axMesh);

dat.fromidx = mapfromidx;
dat.toidx = maptoidx;
set(handles.MetchGUI, 'userdata', dat);

% ---------------------------------------------------------------------------
function axPoints_ButtonDownFcn(hObject, eventdata, handles)
if (get(handles.btSelect, 'value') == 1)
    pp = getCursorInfo(datacursormode(gcf));
    str = [get(handles.lbPoints, 'string'); mat2str(pp.Position)];
    set(handles.lbPoints, 'string', str);
end

% ---------------------------------------------------------------------------
function addselectedpt(pos, idx, lb)
if (isempty(get(lb, 'value')))
    set(lb, 'value', 1);
end
listpt = get(lb, 'string');
listpt{end + 1} = [num2str(idx) ':' mat2str(pos)];
set(lb, 'string', listpt);
set(lb, 'userdata', [get(lb, 'userdata'); pos]);

% ---------------------------------------------------------------------------
function btAddMeshPt_Callback(hObject, eventdata, handles)
dat = get(handles.axMesh, 'userdata');

dat0 = get(handles.MetchGUI, 'userdata');
if (isfield(dat0, 'volume'))
    dat.pos(:, 3) = get(handles.slPos, 'value');
end

if (isfield(dat, 'pos'))
    addselectedpt(dat.pos, dat.idx, handles.lbMesh);
    set(handles.txMapTo, 'userdata', [get(handles.txMapTo, 'userdata'); dat.idx]);
    dat0.mapto = get(handles.lbMesh, 'userdata');
    dat0.maptoidx = get(handles.txMapTo, 'userdata');
    set(handles.MetchGUI, 'userdata', dat0);
else
    msgbox('No point was selected. Please click on "Select" and select a point on the mesh or point cloud', 'Error', 'error');
    return
end

% ---------------------------------------------------------------------------
function btAddCloudPt_Callback(hObject, eventdata, handles)
dat = get(handles.axPoints, 'userdata');
dat0 = get(handles.MetchGUI, 'userdata');
if (isfield(dat, 'pos'))
    addselectedpt(dat.pos, dat.idx, handles.lbPoints);
    set(handles.txMapFrom, 'userdata', [get(handles.txMapFrom, 'userdata'); dat.idx]);
    dat0.mapfrom = get(handles.lbPoints, 'userdata');
    dat0.mapfromidx = get(handles.txMapFrom, 'userdata');
    set(handles.MetchGUI, 'userdata', dat0);
else
    msgbox('No point was selected. Please click on "Select" and select a point on the mesh or point cloud', 'Error', 'error');
    return
end

% ---------------------------------------------------------------------------
function btOptimize_Callback(hObject, eventdata, handles)
dat = get(handles.MetchGUI, 'userdata');
if (isfield(dat, 'A0') && isfield(dat, 'b0') & isfield(dat, 'node') & isfield(dat, 'elem') & ...
    isfield(dat, 'pointsinit') & isfield(dat, 'toidx') & isfield(dat, 'fromidx'))
    pmask = -1 * ones(size(dat.pointsinit, 1), 1);
    pmask(dat.fromidx) = dat.toidx;
    if (isfield(dat, 'A') && isfield(dat, 'b'))
        [Anew, bnew, posnew] = regpt2surf(dat.node, dat.elem, dat.points, pmask, dat.A, dat.b, ones(12, 1), 10);
    else
        [Anew, bnew, posnew] = regpt2surf(dat.node, dat.elem, dat.points, pmask, dat.A0, dat.b0, ones(12, 1), 10);
    end
    dat.A = Anew;
    dat.b = bnew;
    dat.pointsopt = posnew;
    if (isfield(dat, 'optplot') && dat.optplot)
        delete dat.optplot;
        dat.optplot = 0;
    end
    dat.optplot = plot3(posnew(:, 1), posnew(:, 2), posnew(:, 3), 'g+', 'parent', handles.axMesh);
else
    msgbox('You have to select 4 points and click "Initialize" button first', 'Error', 'error');
    return
end
set(handles.MetchGUI, 'userdata', dat);

% ---------------------------------------------------------------------------
function slPos_Callback(hObject, eventdata, handles)
dat = get(handles.MetchGUI, 'userdata');
if (isfield(dat, 'volume'))
    hold(handles.axMesh, 'off');
    imagesc(dat.volume(:, :, round(get(hObject, 'value'))), 'parent', handles.axMesh);
    set(handles.axMesh, 'tag', 'axMesh');
    set(handles.lbZPos, 'string', num2str(round(get(hObject, 'value'))));
end
set(handles.MetchGUI, 'userdata', dat);

% ---------------------------------------------------------------------------
function slPos_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject, 'BackgroundColor'), get(0, 'defaultUicontrolBackgroundColor'))
    set(hObject, 'BackgroundColor', [.9 .9 .9]);
end

% --------------------------------------------------------------------------
function btProj_Callback(hObject, eventdata, handles)
dat = get(handles.MetchGUI, 'userdata');
if (isfield(dat, 'pointsopt'))
    if (isfield(dat, 'projplot') && dat.projplot)
        delete dat.projplot;
        dat.projplot = 0;
    end
    nv = nodesurfnorm(dat.node, dat.elem);
    [d2surf, cn] = dist2surf(dat.node, nv, dat.pointsopt);
    [dat.pointsproj dat.elemid dat.weight] = proj2mesh(dat.node, dat.elem, dat.pointsopt, nv, cn);
    hold(handles.axMesh, 'on');
    dat.projplot = plot3(dat.pointsproj(:, 1), dat.pointsproj(:, 2), dat.pointsproj(:, 3), 'c.', 'parent', handles.axMesh);
else
    msgbox('You have to first select 4 points, then click "Initialize" and "Optimize" button', 'Error', 'error');
    return
end
set(handles.MetchGUI, 'userdata', dat);

% --------------------------------------------------------------------------
function btSaveRes_Callback(hObject, eventdata, handles)
[filename, pathname] = uiputfile('*.mat', 'Save Metch Workspace as');
mapto = get(handles.lbMesh, 'userdata');
mapfrom = get(handles.lbPoints, 'userdata');

maptoidx = get(handles.txMapTo, 'userdata');
mapfromidx = get(handles.txMapFrom, 'userdata');

metchsession = get(handles.MetchGUI, 'userdata');
if (~isempty(mapto))
    metchsession.mapto = mapto;
end
if (~isempty(mapfrom))
    metchsession.mapfrom = mapfrom;
end
if (~isempty(maptoidx))
    metchsession.maptoidx = maptoidx;
end
if (~isempty(mapfromidx))
    metchsession.mapfromidx = mapfromidx;
end
fname = [pathname filename];
save(fname, 'metchsession');

% --------------------------------------------------------------------------
function btLoadSession_Callback(hObject, eventdata, handles)
[filename, pathname] = uigetfile('*.mat', 'Load Metch Workspace from');
fname = [pathname filename];
load(fname);
handle.output = metchsession;
cla(handles.axMesh);
cla(handles.axPoints);
drawinit(handles, metchsession.node, metchsession.elem, metchsession.points);

% --------------------------------------------------------------------------
function btPlotResults_Callback(hObject, eventdata, handles)

function btClose_Callback(hObject, eventdata, handles)
guidata(hObject, handles);
uiresume;

function btHelp_Callback(hObject, eventdata, handles)
helpmsg = {
           'Metch GUI: A mesh/volume registration toolbox'
           ''
           'Author: Qianqian Fang <q.fang at neu.edu>'
           '        Martinos Center for Biomedical Imaging'
           '        Charlestown, MA 02129, USA'
           ''
           '== Description of the workflow =='
           ''
           ' 1. when the GUI pops up, it will display the mesh and the points,'
           '    you can rotate both plots so that you can identify the matching '
           '    features'
           ' 2. switch on "Select" mode, then, click on a land-mark point on the point'
           '    plot, when a data-tip shows up, click "Add Selected" button'
           ' 3. click on the corresponding position on the mesh, and click'
           '    "Add Selected"      '
           ' 4. repeat the above for at least 4 point pairs (you can select more);'
           '    if you want to change views, switch off "Select" box and rotate;'
           '    after rotation, switch on "Select" box again'
           ' 5. click "Initialize": this will create the initial mapping using the'
           '    selected point pairs'
           ' 6. click "Optimize": this will fit the surface with the whole point cloud'
           ' 7. click "Proj2Mesh": this will project the fitted point clouds onto the'
           '    mesh'
           ' 8. you can quit the GUI by hit "Close", your results will be saved to reg'
           ' 9. close the window '};

helpdlg(helpmsg);

% --- Creates and returns a handle to the GUI figure.
function h1 = metchgui_one_LayoutFcn(policy)
% policy - create a new figure or use a singleton. 'new' or 'reuse'.

persistent hsingleton
if (strcmpi(policy, 'reuse') == 1 && ~isempty(hsingleton) && ishandle(hsingleton))
    h1 = hsingleton;
    return
end

appdata = [];
appdata.GUIDEOptions = struct( ...
                              'active_h', [], ...
                              'taginfo', struct( ...
                                                'figure', 2, ...
                                                'axes', 3, ...
                                                'listbox', 3, ...
                                                'edit', 4, ...
                                                'text', 8, ...
                                                'checkbox', 2, ...
                                                'togglebutton', 3, ...
                                                'pushbutton', 13, ...
                                                'slider', 2), ...
                              'override', 0, ...
                              'release', 13, ...
                              'resize', 'none', ...
                              'accessibility', 'callback', ...
                              'mfile', 1, ...
                              'callbacks', 1, ...
                              'singleton', 1, ...
                              'syscolorfig', 1, ...
                              'blocking', 0, ...
                              'lastSavedFile', '/autofs/space/earth_002/users/fangq/pmihome/metch/metchgui_one.m');
appdata.lastValidTag = 'MetchGUI';
appdata.GUIDELayoutEditor = [];

h1 = figure( ...
            'Units', 'characters', ...
            'PaperUnits', get(0, 'defaultfigurePaperUnits'), ...
            'Color', [0.701960784313725 0.701960784313725 0.701960784313725], ...
            'Colormap', [0 0 0.5625; 0 0 0.625; 0 0 0.6875; 0 0 0.75; 0 0 0.8125; 0 0 0.875; 0 0 0.9375; 0 0 1; 0 0.0625 1; 0 0.125 1; 0 0.1875 1; 0 0.25 1; 0 0.3125 1; 0 0.375 1; 0 0.4375 1; 0 0.5 1; 0 0.5625 1; 0 0.625 1; 0 0.6875 1; 0 0.75 1; 0 0.8125 1; 0 0.875 1; 0 0.9375 1; 0 1 1; 0.0625 1 1; 0.125 1 0.9375; 0.1875 1 0.875; 0.25 1 0.8125; 0.3125 1 0.75; 0.375 1 0.6875; 0.4375 1 0.625; 0.5 1 0.5625; 0.5625 1 0.5; 0.625 1 0.4375; 0.6875 1 0.375; 0.75 1 0.3125; 0.8125 1 0.25; 0.875 1 0.1875; 0.9375 1 0.125; 1 1 0.0625; 1 1 0; 1 0.9375 0; 1 0.875 0; 1 0.8125 0; 1 0.75 0; 1 0.6875 0; 1 0.625 0; 1 0.5625 0; 1 0.5 0; 1 0.4375 0; 1 0.375 0; 1 0.3125 0; 1 0.25 0; 1 0.1875 0; 1 0.125 0; 1 0.0625 0; 1 0 0; 0.9375 0 0; 0.875 0 0; 0.8125 0 0; 0.75 0 0; 0.6875 0 0; 0.625 0 0; 0.5625 0 0], ...
            'IntegerHandle', 'off', ...
            'InvertHardcopy', get(0, 'defaultfigureInvertHardcopy'), ...
            'MenuBar', 'none', ...
            'Name', 'Metch GUI: A mesh/image registration utility', ...
            'NumberTitle', 'off', ...
            'PaperPosition', get(0, 'defaultfigurePaperPosition'), ...
            'PaperSize', [20.98404194812 29.67743169791], ...
            'PaperType', get(0, 'defaultfigurePaperType'), ...
            'Position', [103.8 16.8901098901099 144.5 44.5714285714286], ...
            'Resize', 'off', ...
            'HandleVisibility', 'callback', ...
            'Tag', 'MetchGUI', ...
            'UserData', [], ...
            'Visible', 'on', ...
            'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'axMesh';

h2 = axes( ...
          'Parent', h1, ...
          'Units', 'characters', ...
          'Position', [2.83333333333333 3 80.5 39.3571428571429], ...
          'CameraPosition', [0.5 0.5 9.16025403784439], ...
          'CameraPositionMode', get(0, 'defaultaxesCameraPositionMode'), ...
          'Color', get(0, 'defaultaxesColor'), ...
          'ColorOrder', get(0, 'defaultaxesColorOrder'), ...
          'LooseInset', [18.9583333333333 5.28 13.8541666666667 3.6], ...
          'XColor', get(0, 'defaultaxesXColor'), ...
          'YColor', get(0, 'defaultaxesYColor'), ...
          'ZColor', get(0, 'defaultaxesZColor'), ...
          'ButtonDownFcn', 'metchgui_one(''axMesh_ButtonDownFcn'',gcbo,[],guidata(gcbo))', ...
          'Tag', 'axMesh', ...
          'CreateFcn', {@local_CreateFcn, '', appdata});

h3 = get(h2, 'title');

set(h3, ...
    'Parent', h2, ...
    'Units', 'data', ...
    'FontUnits', 'points', ...
    'BackgroundColor', 'none', ...
    'Color', [0 0 0], ...
    'EdgeColor', 'none', ...
    'FontAngle', 'normal', ...
    'FontName', 'Helvetica', ...
    'FontSize', 10, ...
    'FontWeight', 'normal', ...
    'HorizontalAlignment', 'center', ...
    'LineStyle', '-', ...
    'LineWidth', 0.5, ...
    'Margin', 2, ...
    'Position', [0.5 1.00998185117967 1.00005459937205], ...
    'Rotation', 0, ...
    'String', '', ...
    'Interpreter', 'tex', ...
    'VerticalAlignment', 'bottom', ...
    'ButtonDownFcn', [], ...
    'CreateFcn', {@local_CreateFcn, [], ''}, ...
    'DeleteFcn', [], ...
    'BusyAction', 'queue', ...
    'HandleVisibility', 'off', ...
    'HitTest', 'on', ...
    'Interruptible', 'on', ...
    'SelectionHighlight', 'on', ...
    'Tag', '', ...
    'UserData', [], ...
    'Visible', 'on', ...
    'XLimInclude', 'on', ...
    'YLimInclude', 'on', ...
    'ZLimInclude', 'on', ...
    'Clipping', 'off');

h4 = get(h2, 'xlabel');

set(h4, ...
    'Parent', h2, ...
    'Units', 'data', ...
    'FontUnits', 'points', ...
    'BackgroundColor', 'none', ...
    'Color', [0 0 0], ...
    'EdgeColor', 'none', ...
    'FontAngle', 'normal', ...
    'FontName', 'Helvetica', ...
    'FontSize', 10, ...
    'FontWeight', 'normal', ...
    'HorizontalAlignment', 'center', ...
    'LineStyle', '-', ...
    'LineWidth', 0.5, ...
    'Margin', 2, ...
    'Position', [0.497929606625259 -0.0408348457350272 1.00005459937205], ...
    'Rotation', 0, ...
    'String', '', ...
    'Interpreter', 'tex', ...
    'VerticalAlignment', 'cap', ...
    'ButtonDownFcn', [], ...
    'CreateFcn', {@local_CreateFcn, [], ''}, ...
    'DeleteFcn', [], ...
    'BusyAction', 'queue', ...
    'HandleVisibility', 'off', ...
    'HitTest', 'on', ...
    'Interruptible', 'on', ...
    'SelectionHighlight', 'on', ...
    'Tag', '', ...
    'UserData', [], ...
    'Visible', 'on', ...
    'XLimInclude', 'on', ...
    'YLimInclude', 'on', ...
    'ZLimInclude', 'on', ...
    'Clipping', 'off');

h5 = get(h2, 'ylabel');

set(h5, ...
    'Parent', h2, ...
    'Units', 'data', ...
    'FontUnits', 'points', ...
    'BackgroundColor', 'none', ...
    'Color', [0 0 0], ...
    'EdgeColor', 'none', ...
    'FontAngle', 'normal', ...
    'FontName', 'Helvetica', ...
    'FontSize', 10, ...
    'FontWeight', 'normal', ...
    'HorizontalAlignment', 'center', ...
    'LineStyle', '-', ...
    'LineWidth', 0.5, ...
    'Margin', 2, ...
    'Position', [-0.056935817805383 0.498185117967332 1.00005459937205], ...
    'Rotation', 90, ...
    'String', '', ...
    'Interpreter', 'tex', ...
    'VerticalAlignment', 'bottom', ...
    'ButtonDownFcn', [], ...
    'CreateFcn', {@local_CreateFcn, [], ''}, ...
    'DeleteFcn', [], ...
    'BusyAction', 'queue', ...
    'HandleVisibility', 'off', ...
    'HitTest', 'on', ...
    'Interruptible', 'on', ...
    'SelectionHighlight', 'on', ...
    'Tag', '', ...
    'UserData', [], ...
    'Visible', 'on', ...
    'XLimInclude', 'on', ...
    'YLimInclude', 'on', ...
    'ZLimInclude', 'on', ...
    'Clipping', 'off');

h6 = get(h2, 'zlabel');

set(h6, ...
    'Parent', h2, ...
    'Units', 'data', ...
    'FontUnits', 'points', ...
    'BackgroundColor', 'none', ...
    'Color', [0 0 0], ...
    'EdgeColor', 'none', ...
    'FontAngle', 'normal', ...
    'FontName', 'Helvetica', ...
    'FontSize', 10, ...
    'FontWeight', 'normal', ...
    'HorizontalAlignment', 'right', ...
    'LineStyle', '-', ...
    'LineWidth', 0.5, ...
    'Margin', 2, ...
    'Position', [-0.036231884057971 1.0535390199637 1.00005459937205], ...
    'Rotation', 0, ...
    'String', '', ...
    'Interpreter', 'tex', ...
    'VerticalAlignment', 'middle', ...
    'ButtonDownFcn', [], ...
    'CreateFcn', {@local_CreateFcn, [], ''}, ...
    'DeleteFcn', [], ...
    'BusyAction', 'queue', ...
    'HandleVisibility', 'off', ...
    'HitTest', 'on', ...
    'Interruptible', 'on', ...
    'SelectionHighlight', 'on', ...
    'Tag', '', ...
    'UserData', [], ...
    'Visible', 'off', ...
    'XLimInclude', 'on', ...
    'YLimInclude', 'on', ...
    'ZLimInclude', 'on', ...
    'Clipping', 'off');

appdata = [];
appdata.lastValidTag = 'axPoints';

h7 = axes( ...
          'Parent', h1, ...
          'Units', 'characters', ...
          'Position', [86.8333333333333 19.4285714285714 54.8333333333333 22.4285714285714], ...
          'CameraPosition', [0.5 0.5 9.16025403784439], ...
          'CameraPositionMode', get(0, 'defaultaxesCameraPositionMode'), ...
          'Color', get(0, 'defaultaxesColor'), ...
          'ColorOrder', get(0, 'defaultaxesColorOrder'), ...
          'LooseInset', [18.9583333333333 5.28 13.8541666666667 3.6], ...
          'XColor', get(0, 'defaultaxesXColor'), ...
          'YColor', get(0, 'defaultaxesYColor'), ...
          'ZColor', get(0, 'defaultaxesZColor'), ...
          'ButtonDownFcn', 'metchgui_one(''axPoints_ButtonDownFcn'',gcbo,[],guidata(gcbo))', ...
          'Tag', 'axPoints', ...
          'CreateFcn', {@local_CreateFcn, '', appdata});

h8 = get(h7, 'title');

set(h8, ...
    'Parent', h7, ...
    'Units', 'data', ...
    'FontUnits', 'points', ...
    'BackgroundColor', 'none', ...
    'Color', [0 0 0], ...
    'EdgeColor', 'none', ...
    'FontAngle', 'normal', ...
    'FontName', 'Helvetica', ...
    'FontSize', 10, ...
    'FontWeight', 'normal', ...
    'HorizontalAlignment', 'center', ...
    'LineStyle', '-', ...
    'LineWidth', 0.5, ...
    'Margin', 2, ...
    'Position', [0.5 1.01751592356688 1.00005459937205], ...
    'Rotation', 0, ...
    'String', '', ...
    'Interpreter', 'tex', ...
    'VerticalAlignment', 'bottom', ...
    'ButtonDownFcn', [], ...
    'CreateFcn', {@local_CreateFcn, [], ''}, ...
    'DeleteFcn', [], ...
    'BusyAction', 'queue', ...
    'HandleVisibility', 'off', ...
    'HitTest', 'on', ...
    'Interruptible', 'on', ...
    'SelectionHighlight', 'on', ...
    'Tag', '', ...
    'UserData', [], ...
    'Visible', 'on', ...
    'XLimInclude', 'on', ...
    'YLimInclude', 'on', ...
    'ZLimInclude', 'on', ...
    'Clipping', 'off');

h9 = get(h7, 'xlabel');

set(h9, ...
    'Parent', h7, ...
    'Units', 'data', ...
    'FontUnits', 'points', ...
    'BackgroundColor', 'none', ...
    'Color', [0 0 0], ...
    'EdgeColor', 'none', ...
    'FontAngle', 'normal', ...
    'FontName', 'Helvetica', ...
    'FontSize', 10, ...
    'FontWeight', 'normal', ...
    'HorizontalAlignment', 'center', ...
    'LineStyle', '-', ...
    'LineWidth', 0.5, ...
    'Margin', 2, ...
    'Position', [0.496960486322189 -0.0716560509554141 1.00005459937205], ...
    'Rotation', 0, ...
    'String', '', ...
    'Interpreter', 'tex', ...
    'VerticalAlignment', 'cap', ...
    'ButtonDownFcn', [], ...
    'CreateFcn', {@local_CreateFcn, [], ''}, ...
    'DeleteFcn', [], ...
    'BusyAction', 'queue', ...
    'HandleVisibility', 'off', ...
    'HitTest', 'on', ...
    'Interruptible', 'on', ...
    'SelectionHighlight', 'on', ...
    'Tag', '', ...
    'UserData', [], ...
    'Visible', 'on', ...
    'XLimInclude', 'on', ...
    'YLimInclude', 'on', ...
    'ZLimInclude', 'on', ...
    'Clipping', 'off');

h10 = get(h7, 'ylabel');

set(h10, ...
    'Parent', h7, ...
    'Units', 'data', ...
    'FontUnits', 'points', ...
    'BackgroundColor', 'none', ...
    'Color', [0 0 0], ...
    'EdgeColor', 'none', ...
    'FontAngle', 'normal', ...
    'FontName', 'Helvetica', ...
    'FontSize', 10, ...
    'FontWeight', 'normal', ...
    'HorizontalAlignment', 'center', ...
    'LineStyle', '-', ...
    'LineWidth', 0.5, ...
    'Margin', 2, ...
    'Position', [-0.0835866261398175 0.495222929936306 1.00005459937205], ...
    'Rotation', 90, ...
    'String', '', ...
    'Interpreter', 'tex', ...
    'VerticalAlignment', 'bottom', ...
    'ButtonDownFcn', [], ...
    'CreateFcn', {@local_CreateFcn, [], ''}, ...
    'DeleteFcn', [], ...
    'BusyAction', 'queue', ...
    'HandleVisibility', 'off', ...
    'HitTest', 'on', ...
    'Interruptible', 'on', ...
    'SelectionHighlight', 'on', ...
    'Tag', '', ...
    'UserData', [], ...
    'Visible', 'on', ...
    'XLimInclude', 'on', ...
    'YLimInclude', 'on', ...
    'ZLimInclude', 'on', ...
    'Clipping', 'off');

h11 = get(h7, 'zlabel');

set(h11, ...
    'Parent', h7, ...
    'Units', 'data', ...
    'FontUnits', 'points', ...
    'BackgroundColor', 'none', ...
    'Color', [0 0 0], ...
    'EdgeColor', 'none', ...
    'FontAngle', 'normal', ...
    'FontName', 'Helvetica', ...
    'FontSize', 10, ...
    'FontWeight', 'normal', ...
    'HorizontalAlignment', 'right', ...
    'LineStyle', '-', ...
    'LineWidth', 0.5, ...
    'Margin', 2, ...
    'Position', [-1.58510638297872 1.11624203821656 1.00005459937205], ...
    'Rotation', 0, ...
    'String', '', ...
    'Interpreter', 'tex', ...
    'VerticalAlignment', 'middle', ...
    'ButtonDownFcn', [], ...
    'CreateFcn', {@local_CreateFcn, [], ''}, ...
    'DeleteFcn', [], ...
    'BusyAction', 'queue', ...
    'HandleVisibility', 'off', ...
    'HitTest', 'on', ...
    'Interruptible', 'on', ...
    'SelectionHighlight', 'on', ...
    'Tag', '', ...
    'UserData', [], ...
    'Visible', 'off', ...
    'XLimInclude', 'on', ...
    'YLimInclude', 'on', ...
    'ZLimInclude', 'on', ...
    'Clipping', 'off');

appdata = [];
appdata.lastValidTag = 'lbMesh';

h12 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Position', [85.5 4.35714285714286 27.5 9.35714285714285], ...
                'String', '', ...
                'Style', 'listbox', ...
                'Value', 1, ...
                'Tag', 'lbMesh', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'lbPoints';

h13 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Position', [114 4.35714285714286 27.6666666666667 9.42857142857143], ...
                'String', '', ...
                'Style', 'listbox', ...
                'Value', 1, ...
                'Tag', 'lbPoints', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'isSelect';

h14 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''isSelect_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [85.5 15.8571428571429 10 1.78571428571429], ...
                'String', 'Select', ...
                'Style', 'togglebutton', ...
                'Tag', 'isSelect', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btDelete';

h15 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''btDelete_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [95.8333333333333 15.8571428571429 10 1.78571428571429], ...
                'String', 'Delete', ...
                'Tag', 'btDelete', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'bInit';

h16 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''bInit_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [109 15.8571428571429 10 1.78571428571429], ...
                'String', 'Initialize', ...
                'Tag', 'bInit', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'txMesh';

h17 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'BackgroundColor', [0.614 0.052 0], ...
                'ForegroundColor', [1 1 1], ...
                'Position', [2.66666666666667 42.5 80.6666666666667 1.64285714285714], ...
                'String', 'Surface mesh', ...
                'Style', 'text', ...
                'ButtonDownFcn', 'metchgui_one(''txMesh_ButtonDownFcn'',gcbo,[],guidata(gcbo))', ...
                'Tag', 'txMesh', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'txPoint';

h18 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'BackgroundColor', [0.0487072545035106 0 0.701960784313725], ...
                'ForegroundColor', [1 1 1], ...
                'Position', [85.5 42.5 56 1.64285714285714], ...
                'String', 'Point cloud', ...
                'Style', 'text', ...
                'ButtonDownFcn', 'metchgui_one(''txMesh_ButtonDownFcn'',gcbo,[],guidata(gcbo))', ...
                'Tag', 'txPoint', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btAddMeshPt';

h19 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''btAddMeshPt_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [91.5 2.35714285714286 14.5 1.71428571428571], ...
                'String', 'Add Selected', ...
                'Tag', 'btAddMeshPt', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btAddCloudPt';

h20 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''btAddCloudPt_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [120 2.42857142857143 14.5 1.71428571428571], ...
                'String', 'Add Selected', ...
                'Tag', 'btAddCloudPt', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btProj';

h21 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''btProj_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [129.666666666667 15.8571428571429 12 1.78571428571429], ...
                'String', 'Proj2Mesh', ...
                'Tag', 'btProj', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'txMapTo';

h22 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'BackgroundColor', [0.542 0.063 0], ...
                'ForegroundColor', [1 1 1], ...
                'Position', [85.5 13.9285714285714 28 1.64285714285714], ...
                'String', 'Map To', ...
                'Style', 'text', ...
                'ButtonDownFcn', 'metchgui_one(''txMesh_ButtonDownFcn'',gcbo,[],guidata(gcbo))', ...
                'Tag', 'txMapTo', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'txMapFrom';

h23 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'BackgroundColor', [0.0487072545035106 0 0.701960784313725], ...
                'ForegroundColor', [1 1 1], ...
                'Position', [113.666666666667 13.9285714285714 28 1.64285714285714], ...
                'String', 'Map From', ...
                'Style', 'text', ...
                'ButtonDownFcn', 'metchgui_one(''txMesh_ButtonDownFcn'',gcbo,[],guidata(gcbo))', ...
                'Tag', 'txMapFrom', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btOptimize';

h24 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''btOptimize_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [119.333333333333 15.8571428571429 10 1.78571428571429], ...
                'String', 'Optimize', ...
                'Tag', 'btOptimize', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'slPos';

h25 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'BackgroundColor', [0.9 0.9 0.9], ...
                'Callback', 'metchgui_one(''slPos_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [2.83333333333333 1.42857142857143 80.5 1.57142857142857], ...
                'String', {  'Slider' }, ...
                'Style', 'slider', ...
                'CreateFcn', {@local_CreateFcn, 'metchgui_one(''slPos_CreateFcn'',gcbo,[],guidata(gcbo))', appdata}, ...
                'Tag', 'slPos', ...
                'Visible', 'off');

appdata = [];
appdata.lastValidTag = 'lbZPos';

h26 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Position', [41.8333333333333 -0.0714285714285714 6.66666666666667 1.57142857142857], ...
                'String', '', ...
                'Style', 'text', ...
                'Tag', 'lbZPos', ...
                'Visible', 'off', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btSaveRes';

h27 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''btSaveRes_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [84.3333333333333 -0.0714285714285714 16 1.71428571428571], ...
                'String', 'Save Session', ...
                'Tag', 'btSaveRes', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btLoadSession';

h28 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''btLoadSession_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [100.833333333333 -0.0714285714285714 16 1.71428571428571], ...
                'String', 'Load Session', ...
                'Tag', 'btLoadSession', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btPlotResults';

h29 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'Callback', 'metchgui_one(''btPlotResults_Callback'',gcbo,[],guidata(gcbo))', ...
                'Position', [117.333333333333 -0.0714285714285714 16 1.71428571428571], ...
                'String', 'Plot Results', ...
                'Tag', 'btPlotResults', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btClose';

h30 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'BackgroundColor', [0.701960784313725 0.0456922325275102 0.0152120246425083], ...
                'Callback', 'metchgui_one(''btClose_Callback'',gcbo,[],guidata(gcbo))', ...
                'ForegroundColor', [1 1 1], ...
                'Position', [134 -0.0714285714285714 10 1.71428571428571], ...
                'String', 'Close', ...
                'Tag', 'btClose', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

appdata = [];
appdata.lastValidTag = 'btHelp';

h31 = uicontrol( ...
                'Parent', h1, ...
                'Units', 'characters', ...
                'BackgroundColor', [0.12 0.542 0], ...
                'Callback', 'metchgui_one(''btHelp_Callback'',gcbo,[],guidata(gcbo))', ...
                'ForegroundColor', [1 1 1], ...
                'Position', [108.166666666667 2.35714285714286 10 1.71428571428571], ...
                'String', 'Help', ...
                'Tag', 'btHelp', ...
                'CreateFcn', {@local_CreateFcn, '', appdata});

hsingleton = h1;

% --- Set application data first then calling the CreateFcn.
function local_CreateFcn(hObject, eventdata, createfcn, appdata)

if ~isempty(appdata)
    names = fieldnames(appdata);
    for i = 1:length(names)
        name = char(names(i));
        setappdata(hObject, name, getfield(appdata, name));
    end
end

if ~isempty(createfcn)
    eval(createfcn);
end

% --- Handles default GUIDE GUI creation and callback dispatch
function varargout = gui_mainfcn(gui_State, varargin)

gui_StateFields =  {'gui_Name'
                    'gui_Singleton'
                    'gui_OpeningFcn'
                    'gui_OutputFcn'
                    'gui_LayoutFcn'
                    'gui_Callback'};
gui_Mfile = '';
for i = 1:length(gui_StateFields)
    if ~isfield(gui_State, gui_StateFields{i})
        error('Could not find field %s in the gui_State struct in GUI M-file %s', gui_StateFields{i}, gui_Mfile);
    elseif isequal(gui_StateFields{i}, 'gui_Name')
        gui_Mfile = [gui_State.(gui_StateFields{i}), '.m'];
    end
end

numargin = length(varargin);

if numargin == 0
    % METCHGUI_ONE
    % create the GUI
    gui_Create = 1;
elseif isequal(ishandle(varargin{1}), 1) && ispc && iscom(varargin{1}) && isequal(varargin{1}, gcbo)
    % METCHGUI_ONE(ACTIVEX,...)
    vin{1} = gui_State.gui_Name;
    vin{2} = [get(varargin{1}.Peer, 'Tag'), '_', varargin{end}];
    vin{3} = varargin{1};
    vin{4} = varargin{end - 1};
    vin{5} = guidata(varargin{1}.Peer);
    feval(vin{:});
    return
elseif ischar(varargin{1}) && numargin > 1 && isequal(ishandle(varargin{2}), 1)
    % METCHGUI_ONE('CALLBACK',hObject,eventData,handles,...)
    gui_Create = 0;
else
    % METCHGUI_ONE(...)
    % create the GUI and hand varargin to the openingfcn
    gui_Create = 1;
end

if gui_Create == 0
    varargin{1} = gui_State.gui_Callback;
    if nargout
        [varargout{1:nargout}] = feval(varargin{:});
    else
        feval(varargin{:});
    end
else
    if gui_State.gui_Singleton
        gui_SingletonOpt = 'reuse';
    else
        gui_SingletonOpt = 'new';
    end

    % Open fig file with stored settings.  Note: This executes all component
    % specific CreateFunctions with an empty HANDLES structure.

    % Do feval on layout code in m-file if it exists
    if ~isempty(gui_State.gui_LayoutFcn)
        gui_hFigure = feval(gui_State.gui_LayoutFcn, gui_SingletonOpt);
        % openfig (called by local_openfig below) does this for guis without
        % the LayoutFcn. Be sure to do it here so guis show up on screen.
        if (exist('movegui'))
            movegui(gui_hFigure, 'onscreen');
        end
    else
        gui_hFigure = local_openfig(gui_State.gui_Name, gui_SingletonOpt);
        % If the figure has InGUIInitialization it was not completely created
        % on the last pass.  Delete this handle and try again.
        if isappdata(gui_hFigure, 'InGUIInitialization')
            delete(gui_hFigure);
            gui_hFigure = local_openfig(gui_State.gui_Name, gui_SingletonOpt);
        end
    end

    % Set flag to indicate starting GUI initialization
    setappdata(gui_hFigure, 'InGUIInitialization', 1);

    % Fetch GUIDE Application options
    gui_Options = getappdata(gui_hFigure, 'GUIDEOptions');

    if ~isappdata(gui_hFigure, 'GUIOnScreen')
        % Adjust background color
        if gui_Options.syscolorfig
            set(gui_hFigure, 'Color', get(0, 'DefaultUicontrolBackgroundColor'));
        end

        % Generate HANDLES structure and store with GUIDATA. If there is
        % user set GUI data already, keep that also.
        data = guidata(gui_hFigure);
        handles = guihandles(gui_hFigure);
        if ~isempty(handles)
            if isempty(data)
                data = handles;
            else
                names = fieldnames(handles);
                for k = 1:length(names)
                    data.(char(names(k))) = handles.(char(names(k)));
                end
            end
        end
        guidata(gui_hFigure, data);
    end

    % If user specified 'Visible','off' in p/v pairs, don't make the figure
    % visible.
    gui_MakeVisible = 1;
    for ind = 1:2:length(varargin)
        if length(varargin) == ind
            break
        end
        len1 = min(length('visible'), length(varargin{ind}));
        len2 = min(length('off'), length(varargin{ind + 1}));
        if ischar(varargin{ind}) && ischar(varargin{ind + 1}) && ...
                strncmpi(varargin{ind}, 'visible', len1) && len2 > 1
            if strncmpi(varargin{ind + 1}, 'off', len2)
                gui_MakeVisible = 0;
            elseif strncmpi(varargin{ind + 1}, 'on', len2)
                gui_MakeVisible = 1;
            end
        end
    end

    % Check for figure param value pairs
    for index = 1:2:length(varargin)
        if length(varargin) == index || ~ischar(varargin{index})
            break
        end
        try
            set(gui_hFigure, varargin{index}, varargin{index + 1});
        catch
            break
        end
    end

    % If handle visibility is set to 'callback', turn it on until finished
    % with OpeningFcn
    gui_HandleVisibility = get(gui_hFigure, 'HandleVisibility');
    if strcmp(gui_HandleVisibility, 'callback')
        set(gui_hFigure, 'HandleVisibility', 'on');
    end

    feval(gui_State.gui_OpeningFcn, gui_hFigure, [], guidata(gui_hFigure), varargin{:});

    if ishandle(gui_hFigure)
        % Update handle visibility
        set(gui_hFigure, 'HandleVisibility', gui_HandleVisibility);

        % Make figure visible
        if gui_MakeVisible
            set(gui_hFigure, 'Visible', 'on');
            if gui_Options.singleton
                setappdata(gui_hFigure, 'GUIOnScreen', 1);
            end
        end

        % Done with GUI initialization
        rmappdata(gui_hFigure, 'InGUIInitialization');
    end

    % If handle visibility is set to 'callback', turn it on until finished with
    % OutputFcn
    if ishandle(gui_hFigure)
        gui_HandleVisibility = get(gui_hFigure, 'HandleVisibility');
        if strcmp(gui_HandleVisibility, 'callback')
            set(gui_hFigure, 'HandleVisibility', 'on');
        end
        gui_Handles = guidata(gui_hFigure);
    else
        gui_Handles = [];
    end

    if nargout
        [varargout{1:nargout}] = feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
    else
        feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
    end

    if ishandle(gui_hFigure)
        set(gui_hFigure, 'HandleVisibility', gui_HandleVisibility);
    end
end

function gui_hFigure = local_openfig(name, singleton)

% this application data is used to indicate the running mode of a GUIDE
% GUI to distinguish it from the design mode of the GUI in GUIDE.
setappdata(0, 'OpenGuiWhenRunning', 1);

% openfig with three arguments was new from R13. Try to call that first, if
% failed, try the old openfig.
try
    gui_hFigure = openfig(name, singleton, 'auto');
catch
    % OPENFIG did not accept 3rd input argument until R13,
    % toggle default figure visible to prevent the figure
    % from showing up too soon.
    gui_OldDefaultVisible = get(0, 'defaultFigureVisible');
    set(0, 'defaultFigureVisible', 'off');
    gui_hFigure = openfig(name, singleton);
    set(0, 'defaultFigureVisible', gui_OldDefaultVisible);
end
rmappdata(0, 'OpenGuiWhenRunning');
