@@ 1,1 1,1 @@
-Subproject commit aed32a7322b9047576149c483b058bfde36c1eb1
+Subproject commit 591b58e37dadb23d4e3d6aecf650de94d2ca5ef0
@@ 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() {