// This file is part of GOAST, a C++ library for variational methods in Geometry Processing
//
// Copyright (C) 2021 Behrend Heeren & Josua Sassen, University of Bonn <goast@ins.uni-bonn.de>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef SHELL_BENDING_ENERGY_H
#define SHELL_BENDING_ENERGY_H

#include <Eigen/Dense>
#include <Eigen/Sparse>

namespace shell{
  double bending_energy( const Eigen::MatrixXd &V_undef, const Eigen::MatrixXd &V_def, const Eigen::MatrixXi &F,
                         const Eigen::MatrixXi &uE, const Eigen::VectorXi &EMAP, const Eigen::MatrixXi &EF,
                         const Eigen::MatrixXi &EI );

  void bending_deformed_gradient( const Eigen::MatrixXd &V_undef, const Eigen::MatrixXd &V_def,
                                  const Eigen::MatrixXi &F, const Eigen::MatrixXi &uE, const Eigen::VectorXi &EMAP,
                                  const Eigen::MatrixXi &EF, const Eigen::MatrixXi &EI, Eigen::MatrixXd &grad );

  void bending_undeformed_gradient( const Eigen::MatrixXd &V_undef, const Eigen::MatrixXd &V_def,
                                    const Eigen::MatrixXi &F, const Eigen::MatrixXi &uE, const Eigen::VectorXi &EMAP,
                                    const Eigen::MatrixXi &EF, const Eigen::MatrixXi &EI, Eigen::MatrixXd &grad );

  void bending_deformed_hessian( const Eigen::MatrixXd &V_undef, const Eigen::MatrixXd &V_def,
                                 const Eigen::MatrixXi &F, const Eigen::MatrixXi &uE, const Eigen::VectorXi &EMAP,
                                 const Eigen::MatrixXi &EF, const Eigen::MatrixXi &EI,
                                 Eigen::SparseMatrix<double> &Hess );

  void bending_undeformed_hessian( const Eigen::MatrixXd &V_undef, const Eigen::MatrixXd &V_def,
                                   const Eigen::MatrixXi &F, const Eigen::MatrixXi &uE, const Eigen::VectorXi &EMAP,
                                   const Eigen::MatrixXi &EF, const Eigen::MatrixXi &EI,
                                   Eigen::SparseMatrix<double> &Hess );

  void bending_mixed_hessian( const Eigen::MatrixXd &V_undef, const Eigen::MatrixXd &V_def,
                              const Eigen::MatrixXi &F, const Eigen::MatrixXi &uE, const Eigen::VectorXi &EMAP,
                              const Eigen::MatrixXi &EF, const Eigen::MatrixXi &EI, Eigen::SparseMatrix<double> &Hess,
                              bool FirstDerivativeWRTDef = true );
}
#endif //SHELL_BENDING_ENERGY_H

