| 32 | } |
| 33 | |
| 34 | void FaceFrameAttribute::compute_3D_frame_field(Mesh& mesh) { |
| 35 | assert(mesh.get_dim() == 3); |
| 36 | const size_t num_faces = mesh.get_num_faces(); |
| 37 | const size_t num_vertex_per_face = mesh.get_vertex_per_face(); |
| 38 | if (!mesh.has_attribute("edge_length")) { |
| 39 | mesh.add_attribute("edge_length"); |
| 40 | } |
| 41 | if (!mesh.has_attribute("face_normal")) { |
| 42 | mesh.add_attribute("face_normal"); |
| 43 | } |
| 44 | |
| 45 | const auto& faces = mesh.get_faces(); |
| 46 | const auto& edge_lengths = mesh.get_attribute("edge_length"); |
| 47 | const auto& normals = mesh.get_attribute("face_normal"); |
| 48 | assert(normals.size() == num_faces * 3); |
| 49 | |
| 50 | VectorF& frame_field = m_values; |
| 51 | frame_field = VectorF::Zero(num_faces * 6); // 2x3 matrix for each face. |
| 52 | |
| 53 | for (size_t i=0; i<num_faces; i++) { |
| 54 | VectorF edges = edge_lengths.segment( |
| 55 | i*num_vertex_per_face, num_vertex_per_face); |
| 56 | Vector3F n = normals.segment<3>(i*3); |
| 57 | VectorF::Index max_idx; |
| 58 | edges.maxCoeff(&max_idx); |
| 59 | const Vector3F v0 = mesh.get_vertex( |
| 60 | faces[i*num_vertex_per_face + max_idx]); |
| 61 | const Vector3F v1 = mesh.get_vertex( |
| 62 | faces[i*num_vertex_per_face + (max_idx+1) % num_vertex_per_face]); |
| 63 | Vector3F e0 = v1 - v0; |
| 64 | e0.normalize(); |
| 65 | Vector3F e1 = n.cross(e0); |
| 66 | frame_field.segment<6>(i*6) << e0, e1; |
| 67 | } |
| 68 | } |
nothing calls this directly
no test coverage detected