Commit da0a2408 authored by Patrik Huber's avatar Patrik Huber

Moved sample_to_mesh out of the ::detail namespace

Updated all example apps.
parent 5f7933e8
...@@ -421,7 +421,7 @@ int main(int argc, char *argv[]) ...@@ -421,7 +421,7 @@ int main(int argc, char *argv[])
return std::vector<float>(std::begin(vec), std::end(vec)); return std::vector<float>(std::begin(vec), std::end(vec));
}; };
auto shape_ceres = morphable_model.get_shape_model().draw_sample(shape_coefficients) + to_matrix(blendshapes) * Mat(vectord_to_vectorf(blendshape_coefficients), true); auto shape_ceres = morphable_model.get_shape_model().draw_sample(shape_coefficients) + to_matrix(blendshapes) * Mat(vectord_to_vectorf(blendshape_coefficients), true);
render::Mesh mesh = morphablemodel::detail::sample_to_mesh(shape_ceres, morphable_model.get_color_model().draw_sample(colour_coefficients), morphable_model.get_shape_model().get_triangle_list(), morphable_model.get_color_model().get_triangle_list(), morphable_model.get_texture_coordinates()); render::Mesh mesh = morphablemodel::sample_to_mesh(shape_ceres, morphable_model.get_color_model().draw_sample(colour_coefficients), morphable_model.get_shape_model().get_triangle_list(), morphable_model.get_color_model().get_triangle_list(), morphable_model.get_texture_coordinates());
for (auto&& idx : vertex_indices) for (auto&& idx : vertex_indices)
{ {
glm::dvec3 point_3d(mesh.vertices[idx][0], mesh.vertices[idx][1], mesh.vertices[idx][2]); // The 3D model point glm::dvec3 point_3d(mesh.vertices[idx][0], mesh.vertices[idx][1], mesh.vertices[idx][2]); // The 3D model point
......
...@@ -266,7 +266,7 @@ inline std::pair<render::Mesh, fitting::RenderingParameters> fit_shape_and_pose( ...@@ -266,7 +266,7 @@ inline std::pair<render::Mesh, fitting::RenderingParameters> fit_shape_and_pose(
// Current mesh - either from the given coefficients, or the mean: // Current mesh - either from the given coefficients, or the mean:
Mat current_pca_shape = morphable_model.get_shape_model().draw_sample(pca_shape_coefficients); Mat current_pca_shape = morphable_model.get_shape_model().draw_sample(pca_shape_coefficients);
Mat current_combined_shape = current_pca_shape + blendshapes_as_basis * Mat(blendshape_coefficients); Mat current_combined_shape = current_pca_shape + blendshapes_as_basis * Mat(blendshape_coefficients);
auto current_mesh = morphablemodel::detail::sample_to_mesh(current_combined_shape, morphable_model.get_color_model().get_mean(), morphable_model.get_shape_model().get_triangle_list(), morphable_model.get_color_model().get_triangle_list(), morphable_model.get_texture_coordinates()); auto current_mesh = morphablemodel::sample_to_mesh(current_combined_shape, morphable_model.get_color_model().get_mean(), morphable_model.get_shape_model().get_triangle_list(), morphable_model.get_color_model().get_triangle_list(), morphable_model.get_texture_coordinates());
// The 2D and 3D point correspondences used for the fitting: // The 2D and 3D point correspondences used for the fitting:
vector<Vec4f> model_points; // the points in the 3D shape model vector<Vec4f> model_points; // the points in the 3D shape model
...@@ -298,7 +298,7 @@ inline std::pair<render::Mesh, fitting::RenderingParameters> fit_shape_and_pose( ...@@ -298,7 +298,7 @@ inline std::pair<render::Mesh, fitting::RenderingParameters> fit_shape_and_pose(
// Mesh with same PCA coeffs as before, but new expression fit (this is relevant if no initial blendshape coeffs have been given): // Mesh with same PCA coeffs as before, but new expression fit (this is relevant if no initial blendshape coeffs have been given):
current_combined_shape = current_pca_shape + morphablemodel::to_matrix(blendshapes) * Mat(blendshape_coefficients); current_combined_shape = current_pca_shape + morphablemodel::to_matrix(blendshapes) * Mat(blendshape_coefficients);
current_mesh = morphablemodel::detail::sample_to_mesh(current_combined_shape, morphable_model.get_color_model().get_mean(), morphable_model.get_shape_model().get_triangle_list(), morphable_model.get_color_model().get_triangle_list(), morphable_model.get_texture_coordinates()); current_mesh = morphablemodel::sample_to_mesh(current_combined_shape, morphable_model.get_color_model().get_mean(), morphable_model.get_shape_model().get_triangle_list(), morphable_model.get_color_model().get_triangle_list(), morphable_model.get_texture_coordinates());
// The static (fixed) landmark correspondences which will stay the same throughout // The static (fixed) landmark correspondences which will stay the same throughout
// the fitting (the inner face landmarks): // the fitting (the inner face landmarks):
...@@ -356,7 +356,7 @@ inline std::pair<render::Mesh, fitting::RenderingParameters> fit_shape_and_pose( ...@@ -356,7 +356,7 @@ inline std::pair<render::Mesh, fitting::RenderingParameters> fit_shape_and_pose(
blendshape_coefficients = fitting::fit_blendshapes_to_landmarks_nnls(blendshapes, current_pca_shape, affine_from_ortho, image_points, vertex_indices); blendshape_coefficients = fitting::fit_blendshapes_to_landmarks_nnls(blendshapes, current_pca_shape, affine_from_ortho, image_points, vertex_indices);
current_combined_shape = current_pca_shape + blendshapes_as_basis * Mat(blendshape_coefficients); current_combined_shape = current_pca_shape + blendshapes_as_basis * Mat(blendshape_coefficients);
current_mesh = morphablemodel::detail::sample_to_mesh(current_combined_shape, morphable_model.get_color_model().get_mean(), morphable_model.get_shape_model().get_triangle_list(), morphable_model.get_color_model().get_triangle_list(), morphable_model.get_texture_coordinates()); current_mesh = morphablemodel::sample_to_mesh(current_combined_shape, morphable_model.get_color_model().get_mean(), morphable_model.get_shape_model().get_triangle_list(), morphable_model.get_color_model().get_triangle_list(), morphable_model.get_texture_coordinates());
} }
fitted_image_points = image_points; fitted_image_points = image_points;
......
...@@ -35,14 +35,15 @@ ...@@ -35,14 +35,15 @@
#include "glm/vec2.hpp" #include "glm/vec2.hpp"
#include "glm/vec3.hpp" #include "glm/vec3.hpp"
#include "glm/vec4.hpp" #include "glm/vec4.hpp"
#include <vector> #include <vector>
#include <array> #include <array>
#include <cstdint> #include <cstdint>
// Forward declaration of an internal function: // Forward declaration:
namespace eos { namespace morphablemodel { namespace detail { namespace eos { namespace morphablemodel {
eos::render::Mesh sample_to_mesh(cv::Mat shape, cv::Mat color, std::vector<std::array<int, 3>> tvi, std::vector<std::array<int, 3>> tci, std::vector<cv::Vec2f> texture_coordinates = std::vector<cv::Vec2f>()); eos::render::Mesh sample_to_mesh(cv::Mat shape_instance, cv::Mat color_instance, std::vector<std::array<int, 3>> tvi, std::vector<std::array<int, 3>> tci, std::vector<cv::Vec2f> texture_coordinates = std::vector<cv::Vec2f>());
} } } } }
namespace eos { namespace eos {
namespace morphablemodel { namespace morphablemodel {
...@@ -133,10 +134,10 @@ public: ...@@ -133,10 +134,10 @@ public:
render::Mesh mesh; render::Mesh mesh;
if (has_texture_coordinates()) { if (has_texture_coordinates()) {
mesh = detail::sample_to_mesh(shape, color, shape_model.get_triangle_list(), color_model.get_triangle_list(), texture_coordinates); mesh = sample_to_mesh(shape, color, shape_model.get_triangle_list(), color_model.get_triangle_list(), texture_coordinates);
} }
else { else {
mesh = detail::sample_to_mesh(shape, color, shape_model.get_triangle_list(), color_model.get_triangle_list()); mesh = sample_to_mesh(shape, color, shape_model.get_triangle_list(), color_model.get_triangle_list());
} }
return mesh; return mesh;
}; };
...@@ -159,10 +160,10 @@ public: ...@@ -159,10 +160,10 @@ public:
render::Mesh mesh; render::Mesh mesh;
if (has_texture_coordinates()) { if (has_texture_coordinates()) {
mesh = detail::sample_to_mesh(shape_sample, color_sample, shape_model.get_triangle_list(), color_model.get_triangle_list(), texture_coordinates); mesh = sample_to_mesh(shape_sample, color_sample, shape_model.get_triangle_list(), color_model.get_triangle_list(), texture_coordinates);
} }
else { else {
mesh = detail::sample_to_mesh(shape_sample, color_sample, shape_model.get_triangle_list(), color_model.get_triangle_list()); mesh = sample_to_mesh(shape_sample, color_sample, shape_model.get_triangle_list(), color_model.get_triangle_list());
} }
return mesh; return mesh;
}; };
...@@ -203,10 +204,10 @@ public: ...@@ -203,10 +204,10 @@ public:
render::Mesh mesh; render::Mesh mesh;
if (has_texture_coordinates()) { if (has_texture_coordinates()) {
mesh = detail::sample_to_mesh(shape_sample, color_sample, shape_model.get_triangle_list(), color_model.get_triangle_list(), texture_coordinates); mesh = sample_to_mesh(shape_sample, color_sample, shape_model.get_triangle_list(), color_model.get_triangle_list(), texture_coordinates);
} }
else { else {
mesh = detail::sample_to_mesh(shape_sample, color_sample, shape_model.get_triangle_list(), color_model.get_triangle_list()); mesh = sample_to_mesh(shape_sample, color_sample, shape_model.get_triangle_list(), color_model.get_triangle_list());
} }
return mesh; return mesh;
}; };
...@@ -296,41 +297,39 @@ inline void save_model(MorphableModel model, std::string filename) ...@@ -296,41 +297,39 @@ inline void save_model(MorphableModel model, std::string filename)
output_archive(model); output_archive(model);
}; };
namespace detail { /* eos::morphablemodel::detail */
/** /**
* Internal helper function that creates a Mesh from given shape and colour * Helper function that creates a Mesh from given shape and colour PCA
* PCA instances. Needs the vertex index lists as well to assemble the mesh - * instances. Needs the vertex index lists as well to assemble the mesh -
* and optional texture coordinates. * and optional texture coordinates.
* *
* If \c color is empty, it will create a mesh without vertex colouring. * If \c color is empty, it will create a mesh without vertex colouring.
* *
* @param[in] shape PCA shape model instance. * @param[in] shape_instance PCA shape model instance.
* @param[in] color PCA colour model instance. * @param[in] color_instance PCA colour model instance.
* @param[in] tvi Triangle vertex indices. * @param[in] tvi Triangle vertex indices.
* @param[in] tci Triangle colour indices (usually identical to the vertex indices). * @param[in] tci Triangle colour indices (usually identical to the vertex indices).
* @param[in] texture_coordinates Optional texture coordinates for each vertex. * @param[in] texture_coordinates Optional texture coordinates for each vertex.
* @return A mesh created from given parameters. * @return A mesh created from given parameters.
*/ */
inline render::Mesh sample_to_mesh(cv::Mat shape, cv::Mat color, std::vector<std::array<int, 3>> tvi, std::vector<std::array<int, 3>> tci, std::vector<cv::Vec2f> texture_coordinates /* = std::vector<cv::Vec2f>() */) inline render::Mesh sample_to_mesh(cv::Mat shape_instance, cv::Mat color_instance, std::vector<std::array<int, 3>> tvi, std::vector<std::array<int, 3>> tci, std::vector<cv::Vec2f> texture_coordinates /* = std::vector<cv::Vec2f>() */)
{ {
assert(shape.rows == color.rows || color.empty()); // The number of vertices (= model.getDataDimension() / 3) has to be equal for both models, or, alternatively, it has to be a shape-only model. assert(shape_instance.rows == color_instance.rows || color_instance.empty()); // The number of vertices (= model.getDataDimension() / 3) has to be equal for both models, or, alternatively, it has to be a shape-only model.
auto num_vertices = shape.rows / 3; auto num_vertices = shape_instance.rows / 3;
render::Mesh mesh; render::Mesh mesh;
// Construct the mesh vertices: // Construct the mesh vertices:
mesh.vertices.resize(num_vertices); mesh.vertices.resize(num_vertices);
for (auto i = 0; i < num_vertices; ++i) { for (auto i = 0; i < num_vertices; ++i) {
mesh.vertices[i] = glm::tvec4<float>(shape.at<float>(i * 3 + 0), shape.at<float>(i * 3 + 1), shape.at<float>(i * 3 + 2), 1.0f); mesh.vertices[i] = glm::tvec4<float>(shape_instance.at<float>(i * 3 + 0), shape_instance.at<float>(i * 3 + 1), shape_instance.at<float>(i * 3 + 2), 1.0f);
} }
// Assign the vertex colour information if it's not a shape-only model: // Assign the vertex colour information if it's not a shape-only model:
if (!color.empty()) { if (!color_instance.empty()) {
mesh.colors.resize(num_vertices); mesh.colors.resize(num_vertices);
for (auto i = 0; i < num_vertices; ++i) { for (auto i = 0; i < num_vertices; ++i) {
mesh.colors[i] = glm::tvec3<float>(color.at<float>(i * 3 + 0), color.at<float>(i * 3 + 1), color.at<float>(i * 3 + 2)); // order in hdf5: RGB. Order in OCV: BGR. But order in vertex.color: RGB mesh.colors[i] = glm::tvec3<float>(color_instance.at<float>(i * 3 + 0), color_instance.at<float>(i * 3 + 1), color_instance.at<float>(i * 3 + 2)); // order in hdf5: RGB. Order in OCV: BGR. But order in vertex.color: RGB
} }
} }
...@@ -348,7 +347,6 @@ inline render::Mesh sample_to_mesh(cv::Mat shape, cv::Mat color, std::vector<std ...@@ -348,7 +347,6 @@ inline render::Mesh sample_to_mesh(cv::Mat shape, cv::Mat color, std::vector<std
return mesh; return mesh;
}; };
} /* namespace eos::morphablemodel::detail */
} /* namespace morphablemodel */ } /* namespace morphablemodel */
} /* namespace eos */ } /* namespace eos */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment