function [m,ok] = setmeshfromnodes( newmesh, oldmesh, version )
%m = setmeshfromnodes( newmesh, oldmesh )    Complete a mesh structure
%    which only has tricellvxs and either nodes or prismnodes defined.
%    If oldmesh is provided, it is assumed to be a complete mesh structure,
%    and as much information as possible is reused from it.

    setGlobals();
    global gMAX_MGENVERSION
    global gOLD_NUMRESERVEDMGENS
    global gNEW_NUMRESERVEDMGENS
    global gDEFAULTFIELDS

    if nargin < 3
        version = gMAX_MGENVERSION;
    end

    if version==0
        NUMRESERVEDMGENS = gOLD_NUMRESERVEDMGENS;
    else
        NUMRESERVEDMGENS = gNEW_NUMRESERVEDMGENS;
    end
    
    if (nargin >= 2) && ~isempty( oldmesh )
        oldmesh.plotdata = struct([]);
        m = replaceNodes( oldmesh, newmesh );
        m = calculateOutputs( m );
        return;
    end
    
    numMorphogens = NUMRESERVEDMGENS;
    m = newmesh;

    m = defaultFromStruct( m, gDEFAULTFIELDS );

    if ~isfield( m, 'versioninfo' )
        m.versioninfo = newversioninfo( [], version );
    end
    
    if ~isfield( m, 'drivennodes' )
        m.drivennodes = [];
    end
    
    if ~isfield( m, 'drivenpositions' )
        m.drivenpositions = [];
    end
    
    if ~isfield( m, 'decorFEs' )
        m.decorFEs = [];
    end
    
    if ~isfield( m, 'decorBCs' )
        m.decorBCs = [];
    end
    
    if ~isfield( m, 'mgenposcolors' )
        m.mgenposcolors = defaultMgenColors( 1:numMorphogens );
        m.mgennegcolors = oppositeColor( m.mgenposcolors' )';
    end
    
    global gGlobalProps;
    if isfield( m, 'globalProps' )
        m.globalProps = defaultFromStruct( m.globalProps, gGlobalProps );
    else
        m.globalProps = gGlobalProps;
    end
    global gGlobalDynamicProps;
    if isfield( m, 'globalDynamicProps' )
        m.globalDynamicProps = defaultFromStruct( m.globalDynamicProps, gGlobalDynamicProps );
    else
        m.globalDynamicProps = gGlobalDynamicProps;
    end

    m = setmeshgeomfromnodes( m );
    m = buildMorphogenDict( m );
    
    m.scripthistory = {};
    m = updateElasticity( m );
    m = clearInteractionMode( m );

    setGlobals();
    global gDefaultPlotOptions;
    if isfield( m, 'plotdefaults' )
        m.plotdefaults = defaultFromStruct( m.plotdefaults, gDefaultPlotOptions );
    else
        m.plotdefaults = gDefaultPlotOptions;
    end
    
    numnodes = size( m.nodes, 1 );
    numcells = size( m.tricellvxs, 1 );
    if m.versioninfo.mgenversion==0
        numStdMgens = gOLD_NUMRESERVEDMGENS;
    else
        numStdMgens = gNEW_NUMRESERVEDMGENS;
    end
    m = applyMgenDefaults( m, 1:numMorphogens, numnodes );
    for i=1:numStdMgens
        m.mgen_interpType{i} = 'mid';
    end
    
    m.mgen_plotpriority = zeros( 1, numMorphogens );
    m.growthanglepervertex = [];
    m.growthangleperFE = [];
    m.fixedDFmap = false( numnodes, 6 );
    m.gradpolgrowth = zeros( numcells, 3 );
    m.polfreeze = zeros( numcells, 3 );
    m.polfreezebc = zeros( numcells, 3 );
    m.polfrozen = false( numcells, 1 );
    m.allMutantEnabled = true;
    m.cellbulkmodulus = repmat( m.globalProps.bulkmodulus, [size(m.tricellvxs,1), 1] );
    m.cellpoisson = repmat( m.globalProps.poissonsRatio, [size(m.tricellvxs,1), 1] );
    m.cellstiffness = repmat( m.globalProps.D, [1,1,size(m.tricellvxs,1)] );
    m.transportfield = cell( 1, numMorphogens );

    m = makeedgethreshsq( m );
    m.effectiveGrowthTensor = zeros( numcells, 6 );

    m = generateCellData( m );
    m = calculateOutputs( m );
    m.saved = 0;
    m.stop = false;
    m.rewriteIFneeded = false;
    
    m.pictures = [];
    
    m.userdata = struct();
    m.waypoints = [];
    m.moviescripts = [];
    m.movieselected = [];
    
    m = recalc3d(m);
    bboxlo = min( m.nodes, [], 1 );
    bboxhi = max( m.nodes, [], 1 );
    delta = max(bboxhi - bboxlo)/2;
    bboxcentre = (bboxhi + bboxlo)/2;
    bbox = reshape( [ bboxcentre-delta; bboxcentre+delta ], 1, [] );
    
    matlabViewParams = autozoomcentre( m.plotdefaults.matlabViewParams, bbox, true, true );
    m.plotdefaults.matlabViewParams = matlabViewParams;
    m.plotdefaults.ourViewParams = ourViewParamsFromCameraParams( m.plotdefaults.matlabViewParams );
    m.globalProps.defaultViewParams = m.plotdefaults.matlabViewParams;
    [ok,m] = validmesh(m);
end
