texCoords.push_back(cv::Vec2f((xCoords[i]-*minMaxX.first)/divisorX,1.0f-(yCoords[i]-*minMaxY.first)/divisorY));// We rescale to [0, 1] and at the same time flip the y-coords (because in the isomap, the coordinates are stored upside-down).
texCoords.push_back(std::array<double,2>{(xCoords[i]-*minMaxX.first)/divisorX,1.0f-(yCoords[i]-*minMaxY.first)/divisorY});// We rescale to [0, 1] and at the same time flip the y-coords (because in the isomap, the coordinates are stored upside-down).
py::modulecore_module=eos_module.def_submodule("core","Essential functions and classes to work with 3D face models and landmarks.");
py::class_<core::LandmarkMapper>(core_module,"LandmarkMapper","Represents a mapping from one kind of landmarks to a different format(e.g.model vertices).")
core_module.def("write_obj",&core::write_obj,"Writes the given Mesh to an obj file.",py::arg("mesh"),py::arg("filename"));
/**
* Bindings for the eos::morphablemodel namespace:
* - PcaModel
* - MorphableModel
* - load_model()
* - save_model()
*/
py::modulemorphablemodel_module=eos_module.def_submodule("morphablemodel","Functionality to represent a Morphable Model, its PCA models, and functions to load models and blendshapes.");
py::class_<morphablemodel::PcaModel>(morphablemodel_module,"PcaModel","Class representing a PcaModel with a mean, eigenvectors and eigenvalues, as well as a list of triangles to build a mesh.")
.def(py::init<>(),"Creates an empty model.")
.def(py::init<Eigen::VectorXf,Eigen::MatrixXf,Eigen::VectorXf,std::vector<std::array<int,3>>>(),"Construct a PCA model from given mean, normalised PCA basis, eigenvalues and triangle list.",py::arg("mean"),py::arg("pca_basis"),py::arg("eigenvalues"),py::arg("triangle_list"))
.def("get_num_principal_components",&morphablemodel::PcaModel::get_num_principal_components,"Returns the number of principal components in the model.")
.def("get_data_dimension",&morphablemodel::PcaModel::get_data_dimension,"Returns the dimension of the data, i.e. the number of shape dimensions.")
.def("get_triangle_list",&morphablemodel::PcaModel::get_triangle_list,"Returns a list of triangles on how to assemble the vertices into a mesh.")
.def("get_mean",&morphablemodel::PcaModel::get_mean,"Returns the mean of the model.")
.def("get_mean_at_point",&morphablemodel::PcaModel::get_mean_at_point,"Return the value of the mean at a given vertex index.",py::arg("vertex_index"))
.def("get_normalised_pca_basis",[](constmorphablemodel::PcaModel&m){returnm.get_normalised_pca_basis();},"Returns the PCA basis matrix, i.e. the eigenvectors. Each column of the matrix is an eigenvector.")// use py::overload in VS2017
.def("get_eigenvalues",&morphablemodel::PcaModel::get_eigenvalues,"Returns the models eigenvalues.")
.def("draw_sample",(Eigen::VectorXf(morphablemodel::PcaModel::*)(std::vector<float>)const)&morphablemodel::PcaModel::draw_sample,"Returns a sample from the model with the given PCA coefficients. The given coefficients should follow a standard normal distribution, i.e. not be scaled with their eigenvalues/variances.",py::arg("coefficients"))
;
py::class_<morphablemodel::MorphableModel>(morphablemodel_module,"MorphableModel","A class representing a 3D Morphable Model, consisting of a shape- and colour (albedo) PCA model, as well as texture (uv) coordinates.")
.def(py::init<morphablemodel::PcaModel,morphablemodel::PcaModel,std::vector<std::array<double,2>>>(),"Create a Morphable Model from a shape and a colour PCA model, and optional texture coordinates.",py::arg("shape_model"),py::arg("color_model"),py::arg("texture_coordinates")=std::vector<std::array<double,2>>())
.def("get_shape_model",[](constmorphablemodel::MorphableModel&m){returnm.get_shape_model();},"Returns the PCA shape model of this Morphable Model.")// Not sure if that'll really be const in Python? I think Python does a copy each time this gets called?
.def("get_color_model",[](constmorphablemodel::MorphableModel&m){returnm.get_color_model();},"Returns the PCA colour (albedo) model of this Morphable Model.")
.def("get_color_model",[](constmorphablemodel::MorphableModel&m){returnm.get_color_model();},"Returns the PCA colour (albedo) model of this Morphable Model.")// (continued from above:) We may want to use py::overload, but in any case, we need to tell pybind11 if it should use the const or non-const overload.
.def("get_mean",&morphablemodel::MorphableModel::get_mean,"Returns the mean of the shape- and colour model as a Mesh.")
;
morphablemodel_module.def("load_model",&morphablemodel::load_model,"Load a Morphable Model from a cereal::BinaryInputArchive (.bin) from the harddisk.",py::arg("filename"));
morphablemodel_module.def("save_model",&morphablemodel::save_model,"Save a Morphable Model as cereal::BinaryOutputArchive.",py::arg("model"),py::arg("filename"));