def test_energy_preset(self): """Checks that energy returns the expected value.""" vertices_rest_pose = np.array(((1.0, 0.0, 0.0), (-1.0, 0.0, 0.0))) vertices_deformed_pose = 2.0 * vertices_rest_pose quaternions = quaternion.from_euler( np.zeros(shape=vertices_deformed_pose.shape)) edges = ((0, 1), ) all_weights_1_energy = as_conformal_as_possible.energy( vertices_rest_pose, vertices_deformed_pose, quaternions, edges) all_weights_1_gt = 4.0 vertex_weights = np.array((2.0, 1.0)) vertex_weights_energy = as_conformal_as_possible.energy( vertices_rest_pose=vertices_rest_pose, vertices_deformed_pose=vertices_deformed_pose, quaternions=quaternions, edges=edges, vertex_weight=vertex_weights) vertex_weights_gt = 10.0 edge_weights = np.array((2.0, )) edge_weights_energy = as_conformal_as_possible.energy( vertices_rest_pose=vertices_rest_pose, vertices_deformed_pose=vertices_deformed_pose, quaternions=quaternions, edges=edges, edge_weight=edge_weights) edge_weights_gt = 16.0 with self.subTest(name="all_weights_1"): self.assertAllClose(all_weights_1_energy, all_weights_1_gt) with self.subTest(name="vertex_weights"): self.assertAllClose(vertex_weights_energy, vertex_weights_gt) with self.subTest(name="edge_weights"): self.assertAllClose(edge_weights_energy, edge_weights_gt)
def test_energy_jacobian_random(self): """Checks the correctness of the jacobian of energy.""" number_vertices = np.random.randint(3, 10) batch_size = np.random.randint(3) batch_shape = np.random.randint(1, 10, size=(batch_size)).tolist() vertices_rest_pose_init = np.random.uniform(size=(number_vertices, 3)) vertices_deformed_pose_init = np.random.uniform(size=batch_shape + [number_vertices, 3]) quaternions_init = np.random.uniform(size=batch_shape + [number_vertices, 4]) num_edges = int(round(number_vertices / 2)) edges = np.zeros(shape=(num_edges, 2), dtype=np.int32) edges[..., 0] = np.linspace(0, number_vertices / 2 - 1, num_edges, dtype=np.int32) edges[..., 1] = np.linspace(number_vertices / 2, number_vertices - 1, num_edges, dtype=np.int32) vertices_rest_pose = tf.convert_to_tensor( value=vertices_rest_pose_init) vertices_deformed_pose = tf.convert_to_tensor( value=vertices_deformed_pose_init) quaternions = tf.convert_to_tensor(value=quaternions_init) conformal_energy = as_conformal_as_possible.energy( vertices_rest_pose=vertices_rest_pose, vertices_deformed_pose=vertices_deformed_pose, quaternions=quaternions, edges=edges, conformal_energy=True) nonconformal_energy = as_conformal_as_possible.energy( vertices_rest_pose=vertices_rest_pose, vertices_deformed_pose=vertices_deformed_pose, quaternions=quaternions, edges=edges, conformal_energy=False) with self.subTest(name="rest_pose"): self.assert_jacobian_is_correct(vertices_rest_pose, vertices_rest_pose_init, conformal_energy) with self.subTest(name="deformed_pose"): self.assert_jacobian_is_correct(vertices_deformed_pose, vertices_deformed_pose_init, conformal_energy) with self.subTest(name="quaternions_scaled"): self.assert_jacobian_is_correct(quaternions, quaternions_init, conformal_energy) with self.subTest(name="quaternions_normalized"): self.assert_jacobian_is_correct(quaternions, quaternions_init, nonconformal_energy)
def test_energy_identity(self): """Checks that energy evaluated between the rest pose and itself is zero.""" number_vertices = np.random.randint(3, 10) batch_size = np.random.randint(3) batch_shape = np.random.randint(1, 10, size=(batch_size)).tolist() vertices_rest_pose = np.random.uniform(size=(number_vertices, 3)) vertices_deformed_pose = tf.broadcast_to(vertices_rest_pose, shape=batch_shape + [number_vertices, 3]) quaternions = quaternion.from_euler( np.zeros(shape=batch_shape + [number_vertices, 3])) num_edges = int(round(number_vertices / 2)) edges = np.zeros(shape=(num_edges, 2), dtype=np.int32) edges[..., 0] = np.linspace(0, number_vertices / 2 - 1, num_edges, dtype=np.int32) edges[..., 1] = np.linspace(number_vertices / 2, number_vertices - 1, num_edges, dtype=np.int32) energy = as_conformal_as_possible.energy( vertices_rest_pose=vertices_rest_pose, vertices_deformed_pose=vertices_deformed_pose, quaternions=quaternions, edges=edges, conformal_energy=False) self.assertAllClose(energy, tf.zeros_like(energy))
def nonconformal_energy(vertices_rest_pose, vertices_deformed_pose, quaternions): return as_conformal_as_possible.energy( vertices_rest_pose=vertices_rest_pose, vertices_deformed_pose=vertices_deformed_pose, quaternions=quaternions, edges=edges, conformal_energy=False)