Created
January 4, 2023 14:45
-
-
Save OptoCloud/48df3c84ea1208eba737491fd29a5dd7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import mathutils | |
def GetMesh(obj_name): | |
obj = bpy.data.objects.get(obj_name) | |
if obj is None: | |
return None | |
return obj.data | |
def GetShapeKey(mesh, shape_key_name): | |
if mesh is None: | |
return None | |
if not mesh.shape_keys: | |
return None | |
shape_keys = mesh.shape_keys.key_blocks | |
if shape_key_name not in shape_keys: | |
return None | |
return shape_keys[shape_key_name] | |
def GetVerticesWithMaterial(mesh, material_name): | |
material_index = None | |
for i, mat in enumerate(mesh.materials): | |
if mat.name == material_name: | |
material_index = i | |
break | |
if material_index is None: | |
return [] | |
vertices = [] | |
uv_layer = mesh.uv_layers.active | |
for poly in mesh.polygons: | |
if poly.material_index == material_index: | |
for loop_index in poly.loop_indices: | |
vertex_index = mesh.loops[loop_index].vertex_index | |
uv_coords = uv_layer.data[loop_index].uv | |
if vertex_index not in vertices: | |
vertices.append((vertex_index, uv_coords)) | |
return vertices | |
def ModifyShapeKeyVertices(source_object_name, source_material_name, target_object_name, target_material_name, shape_key_name, uv_distance_threshold): | |
# Get the source mesh and the target mesh | |
source_mesh = GetMesh(source_object_name) | |
if source_mesh is None: | |
print("Source object not found") | |
return | |
target_mesh = GetMesh(target_object_name) | |
if target_mesh is None: | |
print("Target object not found") | |
return | |
# Get the shape key for the source mesh | |
shape_key = GetShapeKey(source_mesh, shape_key_name) | |
if shape_key is None: | |
print("Shape key not found in source mesh") | |
return | |
# Get the vertices of the source mesh that have the source material | |
source_vertices = GetVerticesWithMaterial(source_mesh, source_material_name) | |
if len(source_vertices) == 0: | |
print("No vertices found with source material") | |
return | |
# Get the vertices of the target mesh that have the target material | |
target_vertices = GetVerticesWithMaterial(target_mesh, target_material_name) | |
if len(target_vertices) == 0: | |
print("No vertices found with target material") | |
return | |
# Create a dictionary mapping UV coordinates of source vertices to vertex indices | |
source_uv_dict = {(vertex[1][0], vertex[1][1]): vertex[0] for vertex in source_vertices} | |
# Iterate through the target vertices and find the closest matching vertex in the source mesh | |
for target_vertex in target_vertices: | |
target_uv = target_vertex[1] | |
closest_uv_distance = float("inf") | |
closest_vertex_index = None | |
for source_vertex in source_vertices: | |
source_uv = source_vertex[1] | |
uv_distance = mathutils.Vector(source_uv - target_uv).length_squared | |
if uv_distance < closest_uv_distance: | |
closest_uv_distance = uv_distance | |
closest_vertex_index = source_vertex[0] | |
# Modify the shape key value for the closest matching vertex if it is within the threshold distance | |
if closest_uv_distance < uv_distance_threshold**2 and closest_vertex_index is not None: | |
shape_key.data[closest_vertex_index].co = target_mesh.vertices[target_vertex[0]].co | |
ModifyShapeKeyVertices("MeshObjectA", "MaterialA", "MeshObjectB", "MaterialB", "ShapekeyA", 0.0001) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment