Assignment 3
Mesh Deformation
Submission date: Friday, 11/14/14, 23:59
Objective:
Develop and implement a mesh deformation tool. Select a linear deformation method among those taught in class and implement a variation of it. Experiment with using a linear solver library.Tasks:
Instructions:
Selection and Deformation:
The selection of vertices is not implemented, and will need to be done. Something like below, though you are encouraged to encapsulate it in a check to only select while the right mouse button is clicked (it will drastically slow down rendering otherwise). Also, any extra checks to avoid testing un-nessecary vertices would be ideal.
== in ControlState.h add: ==
std::set<size_t> selected_verts;
== in Main.cpp: ==
#include "Utils.h"
...
/*************************************
* Draw Selection Box
*************************************/
w_state->useProgram(2);
glm::vec3 s_bl, s_tr;
c_state.getMouseSelection(s_bl, s_tr);
glUniform3fv(glGetUniformLocation(w_state->getCurrentProgram(),"bot_left"), 1, glm::value_ptr(s_bl));
glUniform3fv(glGetUniformLocation(w_state->getCurrentProgram(),"top_right"), 1, glm::value_ptr(s_tr));
//determine which vertices are in the selection box
GLint select_viewport[4];
glGetIntegerv(GL_VIEWPORT,select_viewport);
glm::vec3 bl = glm::unProject(glm::vec3(s_bl.x,s_bl.y,0), w_state->view * w_state->model, w_state->projection, glm::vec4(0.0,0.0,select_viewport[2],select_viewport[3]));
glm::vec3 bl_ray = glm::unProject(glm::vec3(s_bl.x,s_bl.y,1), w_state->view * w_state->model, w_state->projection, glm::vec4(0.0,0.0,select_viewport[2],select_viewport[3]));
glm::vec3 br = glm::unProject(glm::vec3(s_tr.x,s_bl.y,0), w_state->view * w_state->model, w_state->projection, glm::vec4(0.0,0.0,select_viewport[2],select_viewport[3]));
glm::vec3 br_ray = glm::unProject(glm::vec3(s_tr.x,s_bl.y,1), w_state->view * w_state->model, w_state->projection, glm::vec4(0.0,0.0,select_viewport[2],select_viewport[3]));
glm::vec3 tr = glm::unProject(glm::vec3(s_tr.x,s_tr.y,0), w_state->view * w_state->model, w_state->projection, glm::vec4(0.0,0.0,select_viewport[2],select_viewport[3]));
glm::vec3 tr_ray = glm::unProject(glm::vec3(s_tr.x,s_tr.y,1), w_state->view * w_state->model, w_state->projection, glm::vec4(0.0,0.0,select_viewport[2],select_viewport[3]));
glm::vec3 tl = glm::unProject(glm::vec3(s_bl.x,s_tr.y,0), w_state->view * w_state->model, w_state->projection, glm::vec4(0.0,0.0,select_viewport[2],select_viewport[3]));
glm::vec3 tl_ray = glm::unProject(glm::vec3(s_bl.x,s_tr.y,1), w_state->view * w_state->model, w_state->projection, glm::vec4(0.0,0.0,select_viewport[2],select_viewport[3]));
int vert_size = g_mesh->info_sizev();
for (int i = 0; i < vert_size; i++)
{
Eigen::Vector3d vert = g_mesh->info_vertex(i);
if (vert_inside_select_box(Eigen::Vector3d(bl.x,bl.y,bl.z),
Eigen::Vector3d(bl_ray.x,bl_ray.y,bl_ray.z),
Eigen::Vector3d(br.x,br.y,br.z),
Eigen::Vector3d(br_ray.x,br_ray.y,br_ray.z),
Eigen::Vector3d(tr.x,tr.y,tr.z),
Eigen::Vector3d(tr_ray.x,tr_ray.y,tr_ray.z),
Eigen::Vector3d(tl.x,tl.y,tl.z),
Eigen::Vector3d(tl_ray.x,tl_ray.y,tl_ray.z),
vert))
{
c_state.selected_verts.insert(i);
}
}
Similar to the above, you can calculate the direction your mouse has moved in screen coordinates. This can be used to interactively deform your mesh. Or alternatively, once selected, you can input (through the console) an amount to deform the mesh and a specific
axis of deformation.
Solver:
Eigen is very easy to use, and you are already familiar with many of its types (they are used throughout Cartel). The most important thing to be aware of when solving a system is that you should be using a Sparse solver. If you are solving the system Ax = b. You would proceed as below:
Eigen::VectorXd b;
Eigen::VectorXd x;
Eigen::SparseMatrix<double> A(m, n);
// populate b
...
// populate A
std::vector<Eigen::Triplet<double>> A_elem;
for (non-zero elements) {
A_elem.push_back( Eigen::Triplet<double>(row, column, value) );
}
A.setFromTriplets(A_elem.begin(), A_elem.end());
// solve using your prefered solver, we recommend LDLT or LLT
Eigen::SimplicialLDLT< Eigen::SparseMatrix<double> > solver(A);
x = solver.solve();
// alternatively you can pass the matrix to solve to the solve function
// instead of initializing it.
Submission:
Send an email to Alla with the subject "DGP assign3" containing a zip file with your code. Submit your sources only.