@@ 27,7 27,7 @@ struct Ray {
Vector3d dir;
};
-void step_arap(Mesh &);
+bool step_arap(Mesh &);
void draw_plane(Viewer &, Mesh &);
void draw_menu(Mesh &);
void update_vectors();
@@ 52,6 52,8 @@ arap::Args arap_args;
bool stitching = false;
// Toggle running of ARAP
bool run_arap = false;
+// Run arap, and when it converges update the rest state.
+bool run_with_update = false;
// Show rotations for all *faces*
bool show_list = false;
// Visualize the forces on each vertex when stitching
@@ 64,7 66,7 @@ float force_scale = 1.0;
bool area_force = false;
// Force distance cutoff
float force_dist_cutoff = 1.0;
-
+// The number of ARAP iterations performed
int iteration_count = 0;
// Cut plane and point with `float`, for ImGui.
@@ 115,6 117,11 @@ void draw_menu(Mesh &mesh) {
if (ImGui::Button("Stop ARAP"))
run_arap = false;
}
+
+ if (ImGui::Button("Run and Update")) {
+ run_with_update = true;
+ }
+
ImGui::Text("iter count: %d", iteration_count);
if (ImGui::Button("Reset")) {
@@ 194,16 201,21 @@ void draw_menu(Mesh &mesh) {
}
}
-// Perform one ARAP step.
-void step_arap(Mesh &mesh) {
+// Perform one ARAP step. Return `true` if the difference between the previous and current state is
+// negligible.
+bool step_arap(Mesh &mesh) {
iteration_count++;
Eigen::MatrixXd bc(BOUNDARY_SIZE, 3);
for (int i = 0; i < BOUNDARY_SIZE; i++)
bc.row(i) = mesh.rest_state.row(mesh.boundary(i));
arap_args.skip_mold_rotations = regular_arap;
+ Eigen::MatrixXd prev_vertices = mesh.vertices;
arap::iter(mesh, arap_args, bc, arap_data, mesh.vertices);
compute_things(mesh);
+
+ double max_diff = (mesh.vertices - prev_vertices).maxCoeff();
+ return max_diff < scale * 5e-4; /* This factor was found experimentally! */
}
// Compute all the things that we need each time the vertex set changes. Here's
@@ 577,8 589,23 @@ int main(int argc, char *argv[]) {
viewer.callback_pre_draw = [&mesh](Viewer &viewer) {
draw_plane(viewer, mesh);
- if (run_arap) {
- step_arap(mesh);
+ if (run_with_update) {
+ if (step_arap(mesh)) {
+ static int last_iter_update = -99;
+ // If we have converged with rest state updates, stop.
+ if (iteration_count - last_iter_update < 3) { /* This number was also found experimentally */
+ run_with_update = false;
+ }
+ fprintf(stderr, "Rest state update (diff=%d)\n", iteration_count - last_iter_update);
+ mesh.rest_state = mesh.vertices;
+ arap::precomputation(mesh, arap_data);
+ compute_things(mesh);
+ last_iter_update = iteration_count;
+ }
+ } else {
+ if (run_arap) {
+ step_arap(mesh);
+ }
}
return false;
};