(mesh)
| 76 | mesh.set_attribute("orientations", orientations); |
| 77 | |
| 78 | def compute_distortion_energies_2D(mesh): |
| 79 | assert(mesh.dim == 2); |
| 80 | regular_tri = pymesh.generate_equilateral_triangle(); |
| 81 | assembler = pymesh.Assembler(regular_tri); |
| 82 | G = assembler.assemble("gradient"); |
| 83 | |
| 84 | vertices = mesh.vertices; |
| 85 | tris = mesh.faces; |
| 86 | Js = [ G * vertices[tri] for tri in tris]; |
| 87 | |
| 88 | J_F = np.array([np.trace(np.dot(J.T, J)) for J in Js]); |
| 89 | J_det = np.array([numpy.linalg.det(J) for J in Js]); |
| 90 | invert_J = lambda args: np.full((3,3), np.inf) if args[1] == 0 else numpy.linalg.inv(args[0]) |
| 91 | J_inv = map(invert_J, zip(Js, J_det)); |
| 92 | J_inv_F = np.array([np.trace(np.dot(Ji.T, Ji)) for Ji in J_inv]); |
| 93 | |
| 94 | conformal_amips = np.divide(J_F, J_det); |
| 95 | finite_conformal_amips = np.isfinite(conformal_amips); |
| 96 | symmetric_dirichlet = J_F + J_inv_F; |
| 97 | finite_symmetric_dirichlet = np.isfinite(symmetric_dirichlet); |
| 98 | |
| 99 | orientations = np.array([pymesh.orient_2D( |
| 100 | vertices[t[0]], vertices[t[1]], vertices[t[2]]) |
| 101 | for t in tris]); |
| 102 | orientations[orientations > 0] = 1; |
| 103 | orientations[orientations < 0] = -1; |
| 104 | |
| 105 | num_degenerate_tets = np.count_nonzero(orientations==0); |
| 106 | num_inverted_tets = np.count_nonzero(orientations<0); |
| 107 | num_nonfinite_amips = np.count_nonzero(np.logical_not(finite_conformal_amips)); |
| 108 | num_nonfinite_dirichlet =\ |
| 109 | np.count_nonzero(np.logical_not(finite_symmetric_dirichlet)); |
| 110 | logger = logging.getLogger("Distorsion"); |
| 111 | if num_degenerate_tets > 0: |
| 112 | logger.warn("degenerate tets: {}".format(num_degenerate_tets)); |
| 113 | if num_inverted_tets > 0: |
| 114 | logger.warn("inverted tets: {}".format(num_inverted_tets)); |
| 115 | if num_nonfinite_amips > 0: |
| 116 | logger.warn("Non-finite conformal AMIPS: {}".format( |
| 117 | num_nonfinite_amips)); |
| 118 | if num_nonfinite_dirichlet > 0: |
| 119 | logger.warn("Non-finite symmetric Dirichlet: {}".format( |
| 120 | num_nonfinite_dirichlet)); |
| 121 | |
| 122 | mesh.add_attribute("conformal_AMIPS"); |
| 123 | mesh.set_attribute("conformal_AMIPS", conformal_amips); |
| 124 | mesh.add_attribute("finite_conformal_AMIPS"); |
| 125 | mesh.set_attribute("finite_conformal_AMIPS", finite_conformal_amips); |
| 126 | mesh.add_attribute("symmetric_Dirichlet"); |
| 127 | mesh.set_attribute("symmetric_Dirichlet", symmetric_dirichlet); |
| 128 | mesh.add_attribute("finite_symmetric_Dirichlet"); |
| 129 | mesh.set_attribute("finite_symmetric_Dirichlet", finite_symmetric_dirichlet); |
| 130 | mesh.add_attribute("orientations"); |
| 131 | mesh.set_attribute("orientations", orientations); |
| 132 | |
| 133 | def compute_grad_upper_bound(mesh): |
| 134 | """ The measure introduced in the following paper: |
no test coverage detected