//=============================================================================

#include "Smoothing.h"

#include <graphene/surface_mesh/algorithms/smoothing/Smoother.h>
#include <graphene/surface_mesh/algorithms/surface_mesh_tools/misc.h>

//=============================================================================

namespace graphene {
namespace character {
//=============================================================================

bool smooth_selection(Character& character, const std::string& s_bodymesh, const std::string& fn_selection,
                      Smoothing_options options)
{
    using Vertex = graphene::surface_mesh::Surface_mesh::Vertex;

    // Load selection of vertices that should be smoothed
    std::vector<int> vertices_to_smooth;
    if (!graphene::surface_mesh::load_selection_from_file(vertices_to_smooth, fn_selection))
    {
        std::cerr << "Pipeline: [ERROR] Cannot load selection for smoothing: " << fn_selection << std::endl;
        return false;
    }

    // Get bodymesh
    int bodymesh_index = character.get_skin_idx(s_bodymesh);
    if (bodymesh_index < 0)
    {
        std::cerr << "[ERROR] " << __FUNCTION__  << ": Cannot get bodymesh " << s_bodymesh << " from character" << std::endl;
        return false;
    }

    auto* mesh = character.skins()[bodymesh_index];

    auto selected_mesh = mesh->vertex_property<bool>("v:selected", false);
    for (int idx : vertices_to_smooth)
        selected_mesh[Vertex(idx)] = true;

    if (options.use_implicit_smoothing)
    {
        graphene::surface_mesh::Smoother smoother_bodymesh(*mesh);
        smoother_bodymesh.smooth_implicit(options.timestep, options.use_uniform_laplace);
    }
    else
    {
        graphene::surface_mesh::Smoother smoother_bodymesh(*mesh);
        smoother_bodymesh.smooth(options.iterations, options.use_uniform_laplace);
    }

    mesh->remove_vertex_property<bool>(selected_mesh);

    return true;
}

//=============================================================================
} // namespace character
} // namespace graphene
//=============================================================================
