%% Reset

clear all
close all
clc

addpath ./src/
addpath ./mex/
addpath ./utils/

addpath(genpath('dwnld'))

%% Choose the parameters

Npatches    	= 200;
overlap_ratio   = 0.5;

%% Load the data

load 01_MorphableModel

shapeEV = double(shapeEV);
shapeMU = double(shapeMU);
shapePC = double(shapePC);
texEV   = double(texEV);
texMU   = double(texMU);
texPC   = double(texPC);

FV.faces    = tl;
FV.vertices = reshape(shapeMU, 3, length(shapeMU) / 3).';

clear segbin segMB segMM tl

load pie_lights_fres

clear feat_mat id info kind

sym_indices         = read_symlist_BFM('face05_symlist.txt');
sym_featurepoints   = read_featurepoints_BFM('Farkas_face05.fp', sym_indices, 'eyes');
featurepoints       = read_featurepoints_BFM('Farkas_face05.fp', [], 'eyes');

load ./save/dsym/DsymMeanFace

%% Segment the mesh

options.verbose                                     = true;
options.seeds                                       = featurepoints;
[sampled_keypoints_seed, I_vertex_nkeypoint_seed]   = segment_mesh_uni(FV, Npatches, options);

clear options

options.verbose                                             = true;
options.Dsym_vertex                                         = Dsym_vertex;
[sampled_sym_keypoints, Isym_vertex_nkeypoint]              = segment_mesh_uni_sym(FV, Npatches, sym_indices, options);
options.sym_seeds                                           = sym_featurepoints;
[sampled_sym_keypoints_seed, Isym_vertex_nkeypoint_seed]    = segment_mesh_uni_sym(FV, Npatches, sym_indices, options);

clear options

%% Grow the patches

options.verbose     = true;
grown_patches_seed  = grow_patches_proj(FV, sampled_keypoints_seed, I_vertex_nkeypoint_seed(:, Npatches), overlap_ratio, options);

clear options

options.verbose                             = true;
grown_sym_patches                           = grow_patches_proj_sym(FV, sampled_sym_keypoints, Isym_vertex_nkeypoint(:, end), sym_indices, overlap_ratio, options);
[grown_sym_patches_seed, sym_patches_seed]  = grow_patches_proj_sym(FV, sampled_sym_keypoints_seed, Isym_vertex_nkeypoint_seed(:, end), sym_indices, overlap_ratio, options);

clear options

%% Generate a face

FVC_model = synthesize_face_model(FV.faces, shapeMU, shapePC, shapeEV, texMU, texPC, texEV, oglp);

%% Hallucinate a face

db           	= './save/db/';
options.verbose = true;
options.blend   = true;
options.lambda  = 1e-6;

[FVC_sym_seed_over, filenames]  = synthesize_face_hallu(FVC_model, grown_sym_patches_seed, db, options);
FVC_sym_seed                    = synthesize_face_hallu(FVC_model, sym_patches_seed, db, options);
FVC_sym_over                    = synthesize_face_hallu(FVC_model, grown_sym_patches, db, options);
FVC_asym_seed_over              = synthesize_face_hallu(FVC_model, grown_patches_seed, db, options);

clear db options

%% Display

figure

subplot(1, 5, 1)
patch(FVC_model, 'FaceColor', 'interp', 'FaceLighting', 'none', 'LineStyle', 'none');
axis equal
axis off
title('Model')

subplot(1, 5, 2)
patch(FVC_sym_seed_over, 'FaceColor', 'interp', 'FaceLighting', 'none', 'LineStyle', 'none');
axis equal
axis off
title('Overlap, seeds, symmetry')

subplot(1, 5, 3)
patch(FVC_sym_seed, 'FaceColor', 'interp', 'FaceLighting', 'none', 'LineStyle', 'none');
axis equal
axis off
title('No overlap')

subplot(1, 5, 4)
patch(FVC_sym_over, 'FaceColor', 'interp', 'FaceLighting', 'none', 'LineStyle', 'none');
axis equal
axis off
title('No seeds')

subplot(1, 5, 5)
patch(FVC_asym_seed_over, 'FaceColor', 'interp', 'FaceLighting', 'none', 'LineStyle', 'none');
axis equal
axis off
title('No symmetry')

figure

subplot(1, 3, 1)

p = patch(FVC_model);

set(p, 'AmbientStrength', 0, 'DiffuseStrength', 1, 'SpecularStrength', 0, 'FaceLighting', 'phong');
light('Position', [0 0 1], 'Style', 'infinite');
title('Identity, lighting')

hold on
axis equal
axis off

[files, ~, j]   = unique(filenames);
map             = jet(length(files));
cdata           = zeros(size(FVC_model.vertices, 1), 3);
for i = 1: length(sym_patches_seed)
    tmp_indices             = sym_patches_seed{i};
    cdata(tmp_indices, 1)   = map(j(i), 1);
    cdata(tmp_indices, 2)   = map(j(i), 2);
    cdata(tmp_indices, 3)   = map(j(i), 3);
end

set(p, 'FaceColor', 'interp', 'FaceVertexCData', cdata, 'LineStyle', 'none')

subplot(1, 3, 2)

p = patch(FVC_model);

set(p, 'AmbientStrength', 0, 'DiffuseStrength', 1, 'SpecularStrength', 0, 'FaceLighting', 'phong');
light('Position', [0 0 1], 'Style', 'infinite');
title('Identity')

hold on
axis equal
axis off

files           = regexprep(filenames, '_\d{1,4}\.mat', '');
[files, ~, j]   = unique(files);
map             = jet(length(files));
cdata           = zeros(size(FVC_model.vertices, 1), 3);
for i = 1: length(sym_patches_seed)
    tmp_indices             = sym_patches_seed{i};
    cdata(tmp_indices, 1)   = map(j(i), 1);
    cdata(tmp_indices, 2)   = map(j(i), 2);
    cdata(tmp_indices, 3)   = map(j(i), 3);
end

set(p, 'FaceColor', 'interp', 'FaceVertexCData', cdata, 'LineStyle', 'none')

subplot(1, 3, 3)

p = patch(FVC_model);

set(p, 'AmbientStrength', 0, 'DiffuseStrength', 1, 'SpecularStrength', 0, 'FaceLighting', 'phong');
light('Position', [0 0 1], 'Style', 'infinite');
title('Lighting')

hold on
axis equal
axis off

files           = strrep(regexprep(filenames, '\d{1,4}_', ''), '.mat', '');
[files, ~, j]   = unique(files);
map             = jet(length(files));
cdata           = zeros(size(FVC_model.vertices, 1), 3);
for i = 1: length(sym_patches_seed)
    tmp_indices             = sym_patches_seed{i};
    cdata(tmp_indices, 1)   = map(j(i), 1);
    cdata(tmp_indices, 2)   = map(j(i), 2);
    cdata(tmp_indices, 3)   = map(j(i), 3);
end

set(p, 'FaceColor', 'interp', 'FaceVertexCData', cdata, 'LineStyle', 'none')

clear files i j p tmp_indices map cdata