Map vertex attribute from mesh1 to mesh2 based on closest points. Args: mesh1 (:class:`Mesh`): Source mesh, where the attribute is defined. mesh2 (:class:`Mesh`): Target mesh, where the attribute is mapped to. attr_name (``string``): Attribute name. bvh (:class:
(mesh1, mesh2, attr_name, bvh=None)
| 4 | from .aabb_tree import BVH |
| 5 | |
| 6 | def map_vertex_attribute(mesh1, mesh2, attr_name, bvh=None): |
| 7 | """ Map vertex attribute from mesh1 to mesh2 based on closest points. |
| 8 | |
| 9 | Args: |
| 10 | mesh1 (:class:`Mesh`): Source mesh, where the attribute is defined. |
| 11 | mesh2 (:class:`Mesh`): Target mesh, where the attribute is mapped to. |
| 12 | attr_name (``string``): Attribute name. |
| 13 | bvh (:class:`BVH`): Pre-computed Bounded volume hierarchy if available. |
| 14 | |
| 15 | A new attribute with name ``attr_name`` is added to ``mesh2``. |
| 16 | """ |
| 17 | |
| 18 | assert(mesh1.dim == mesh2.dim) |
| 19 | assert(mesh1.vertex_per_face == 3) |
| 20 | assert(mesh2.vertex_per_face == 3) |
| 21 | assert(mesh1.has_attribute(attr_name)) |
| 22 | values = mesh1.get_vertex_attribute(attr_name) |
| 23 | |
| 24 | if bvh is None: |
| 25 | bvh = BVH(dim=mesh1.dim) |
| 26 | bvh.load_mesh(mesh1) |
| 27 | dists, closest_faces, p = bvh.lookup(mesh2.vertices) |
| 28 | |
| 29 | vertices = mesh1.vertices |
| 30 | faces = mesh1.faces |
| 31 | v0 = vertices[faces[closest_faces,0],:] |
| 32 | v1 = vertices[faces[closest_faces,1],:] |
| 33 | v2 = vertices[faces[closest_faces,2],:] |
| 34 | |
| 35 | a01 = np.linalg.norm(np.cross(v0-p, v1-p), axis=1).reshape((-1,1)) |
| 36 | a12 = np.linalg.norm(np.cross(v1-p, v2-p), axis=1).reshape((-1,1)) |
| 37 | a20 = np.linalg.norm(np.cross(v2-p, v0-p), axis=1).reshape((-1,1)) |
| 38 | |
| 39 | a = a01 + a12 + a20 |
| 40 | |
| 41 | val_0 = values[faces[closest_faces, 0],:] |
| 42 | val_1 = values[faces[closest_faces, 1],:] |
| 43 | val_2 = values[faces[closest_faces, 2],:] |
| 44 | |
| 45 | target_val = (val_0 * a12 + val_1 * a20 + val_2 * a01) / a |
| 46 | |
| 47 | if not mesh2.has_attribute(attr_name): |
| 48 | mesh2.add_attribute(attr_name) |
| 49 | mesh2.set_attribute(attr_name, target_val) |
| 50 | |
| 51 | |
| 52 | def map_face_attribute(mesh1, mesh2, attr_name, bvh=None): |
nothing calls this directly
no test coverage detected