~mht/surcut

c28a86678de999bdfa75f7a7e0cb2c7f21ea29c4 — Martin Hafskjold Thoresen 5 years ago f153ab9
Flush out framework for force computation.

Should get something going pretty soon so we can see how it behaves
asap.
2 files changed, 48 insertions(+), 1 deletions(-)

M libigl
M main.cpp
M libigl => libigl +1 -1
@@ 1,1 1,1 @@
Subproject commit aed32a7322b9047576149c483b058bfde36c1eb1
Subproject commit 591b58e37dadb23d4e3d6aecf650de94d2ca5ef0

M main.cpp => main.cpp +47 -0
@@ 24,6 24,8 @@ void draw_menu();
void update_vectors();
void ensure_moldability();
void remesh();
int ray_intersect(Eigen::Vector3d, Eigen::Vector3d, Eigen::MatrixXd &, Eigen::MatrixXi &);
void compute_forces(Eigen::MatrixXd &, Eigen::MatrixXi &);

// Model data
Eigen::MatrixXd V;


@@ 403,6 405,51 @@ void ensure_moldability() {
  igl::per_face_normals(TV, TF, N);
}

void compute_forces(Eigen::MatrixXd &vertices, Eigen::MatrixXi &faces) {
  Eigen::Vector3d remove_dir = plane_n;
  // XXX(refactor): this is computed *a couple* of other places. Refactor.
  std::vector<bool> is_point_above(vertices.rows());
  { /* refactorable */
    auto above_plane = [&](Eigen::Vector3d v) {
      return (v - plane_p).dot(plane_n) >= 0.0;
    };
    for (int i = 0; i < vertices.rows(); i++)
      is_point_above[i] = above_plane(vertices.row(i));
  }

  for (int f = 0; f < TF.rows(); f++) {
    auto normal = N.row(f);
    double dot;
    // XXX(refactor): this is done quite a few times all over the place now.
    auto moldable = arap::is_moldable(remove_dir, is_point_above, TF, f, normal, &dot);
    // XXX(todo): what do we do about `CROSSING`? For now, skip as well.
    if (moldable != arap::NO) continue;

    for (int v_i = 0; v_i < 3; v_i++) {
      // XXX(todo): this will check each vertex once per non-moldable adjacent face, when we only
      // need to check once.
      auto vertex = vertices.row(faces(f, v_i));
      auto other_i = ray_intersect(vertex, remove_dir, vertices, faces);
      if (other_i == -1) continue;
      auto other_vertex = vertices.row(other_i);
      auto force_direction = other_vertex - vertex;
      // XXX(todo): what should the magnitude of the force be? Should probably take a closer look
      // at the dynamics implementation in `arap-mold.cpp`.
      (void)force_direction; /* unused warning */
      // XXX(todo): these forces can be visualized with libigl (?)
    }
  }
}

// Shoot a ray from `p` in direction `v`, and see if it intersects with any of the `faces`. If it
// does, return the index of the closest vertex to the intersection point. If not, return `-1`.
int ray_intersect(Eigen::Vector3d v, Eigen::Vector3d p, Eigen::MatrixXd &vertices, 
                  Eigen::MatrixXi &faces) {
  // XXX(todo): implement this
  assert(false);
  return -1;
}

// Remesh the model based on the deformed version.
// WARNING: THIS WILL DESTROY THE ORIGINAL MODEL, SO `reset` DOES NOTHING!
void remesh() {