Untitled
unknown
python
2 years ago
2.6 kB
12
Indexable
import maya.cmds as cmds
import math
def get_average_normal(vertices):
"""Calculate the average normal of a list of vertices."""
avg_normal = [0.0, 0.0, 0.0]
for vertex in vertices:
normal = cmds.polyNormalPerVertex(vertex, query=True, xyz=True)
avg_normal = [a + b for a, b in zip(avg_normal, normal)]
total_vertices = len(vertices)
avg_normal = [n / total_vertices for n in avg_normal]
return avg_normal
def find_closest_vertex(source_vertices, target_vertices):
"""Find the closest vertex in target_vertices for each vertex in source_vertices."""
closest_vertices = []
for src_vertex in source_vertices:
src_pos = cmds.xform(src_vertex, query=True, translation=True, worldSpace=True)
closest_vertex = None
min_distance = float('inf')
for tgt_vertex in target_vertices:
tgt_pos = cmds.xform(tgt_vertex, query=True, translation=True, worldSpace=True)
distance = math.sqrt(sum((a - b) ** 2 for a, b in zip(src_pos, tgt_pos)))
if distance < min_distance:
min_distance = distance
closest_vertex = tgt_vertex
closest_vertices.append(closest_vertex)
return closest_vertices
def copy_vertex_normals_in_world_space():
sel = cmds.ls(selection=True, flatten=True)
if len(sel) < 2:
cmds.warning("Please select two rows of vertices: source and target.")
return
# Divide the selected vertices into source and target rows
source_vertices = sel[:len(sel) // 2]
target_vertices = sel[len(sel) // 2:]
if len(source_vertices) != len(target_vertices):
cmds.warning("Both source and target rows must have the same number of vertices.")
return
# Find the closest vertex in the target row for each vertex in the source row
closest_vertices = find_closest_vertex(source_vertices, target_vertices)
# Copy vertex normals from source to target
for src_vertex, tgt_vertex in zip(source_vertices, closest_vertices):
source_normal = cmds.polyNormalPerVertex(src_vertex, query=True, xyz=True)
cmds.polyNormalPerVertex(tgt_vertex, edit=True, normalXYZ=source_normal)
cmds.select(clear=True)
cmds.select(target_vertices, replace=True)
cmds.warning("Vertex normals copied from source to target based on proximity in world space.")
# Example usage:
# Select two rows of vertices: first the source row, then the target row.
# Run the script.
copy_vertex_normals_in_world_space()Editor is loading...