这个Maya Python脚本旨在帮助我们通过选择圆弧上的面来计算圆的圆心,并在该位置创建一个定位器。首先,脚本获取用户当前选择的面和这些面的顶点位置。然后,使用最小二乘法拟合一个圆,计算出圆心和半径。最后,在计算出的圆心位置创建一个定位器,便于进一步操作和参考。这个工具对于需要精确定位和操作基于圆弧几何体的用户非常有用,可以显著提高建模和动画制作的效率。用户只需选择圆弧上的面并运行脚本,便可自动完成圆心计算和定位器创建。
一、效果展示
我这个模型外围有几个小圆环,如果可以将圆环的坐标轴移动到大环的中心上,那就可以利用旋转复制快速操作小圆环了,于是有了这个小脚本。
二、关于脚本
选中相关的面后,直接将代码复制到脚本框里,点击运行就可以了,具体操作可以参考我的这篇文章:在MAYA中使用Python脚本进行批量轴居中(点击跳转)
import maya.cmds as cmds
import numpy as np
def calculate_circle_center_and_radius(points):
# 最小二乘法拟合圆
A = np.array([[2*point[0], 2*point[1], 1] for point in points])
b = np.array([[point[0]**2 + point[1]**2] for point in points])
x = np.linalg.lstsq(A, b, rcond=None)[0]
center_x = x[0][0]
center_y = x[1][0]
radius = np.sqrt(x[2][0] + center_x**2 + center_y**2)
return (center_x, center_y), radius
def get_vertices_positions(mesh, face):
vertices = cmds.polyInfo(face, faceToVertex=True)[0].split()[2:]
vertices = [int(v) for v in vertices]
vertex_positions = [cmds.pointPosition(f"{mesh}.vtx[{v}]") for v in vertices]
return vertex_positions
def main():
# 获取当前选择的面
selected_faces = cmds.ls(selection=True, flatten=True)
if not selected_faces:
raise RuntimeError("请先选择一些面")
# 获取物体名称
mesh = selected_faces[0].split('.')[0]
# 获取所有选择面上的顶点位置
all_vertex_positions = []
for face in selected_faces:
vertex_positions = get_vertices_positions(mesh, face)
all_vertex_positions.extend(vertex_positions)
# 使用最小二乘法拟合圆,计算圆心和半径
points_2d = [(pos[0], pos[2]) for pos in all_vertex_positions] # 使用 XZ 平面上的点
center, radius = calculate_circle_center_and_radius(points_2d)
# 计算平均高度
avg_height = np.mean([pos[1] for pos in all_vertex_positions])
# 创建定位器
locator = cmds.spaceLocator(p=[center[0], avg_height, center[1]])[0]
# 居中轴心
cmds.xform(locator, centerPivots=True)
print(f"圆心: {center}, 半径: {radius}, 高度: {avg_height}")
if __name__ == "__main__":
main()
三、代码说明
1. 脚本说明
该脚本用于根据在 Maya 中选择的一组圆弧面,计算出对应的圆心,并在圆心位置创建一个定位器,同时将定位器的轴心居中。
2. 功能简介
- 获取用户选择的圆弧面。
- 提取这些面的顶点位置。
- 使用最小二乘法拟合圆,计算圆心和半径。
- 计算顶点的平均高度。
- 在圆心和平均高度位置创建一个定位器,并将其轴心居中。
3. 代码解析
(1)导入必要的模块
import maya.cmds as cmds
import numpy as np
(2)定义计算圆心和半径的函数
def calculate_circle_center_and_radius(points):
A = np.array([[2*point[0], 2*point[1], 1] for point in points])
b = np.array([[point[0]**2 + point[1]**2] for point in points])
x = np.linalg.lstsq(A, b, rcond=None)[0]
center_x = x[0][0]
center_y = x[1][0]
radius = np.sqrt(x[2][0] + center_x**2 + center_y**2)
return (center_x, center_y), radius
(3)定义获取面顶点位置的函数
def get_vertices_positions(mesh, face):
vertices = cmds.polyInfo(face, faceToVertex=True)[0].split()[2:]
vertices = [int(v) for v in vertices]
vertex_positions = [cmds.pointPosition(f"{mesh}.vtx[{v}]") for v in vertices]
return vertex_positions
(4)主函数
def main():
# 获取当前选择的面
selected_faces = cmds.ls(selection=True, flatten=True)
if not selected_faces:
raise RuntimeError("请先选择一些面")
# 获取物体名称
mesh = selected_faces[0].split('.')[0]
# 获取所有选择面上的顶点位置
all_vertex_positions = []
for face in selected_faces:
vertex_positions = get_vertices_positions(mesh, face)
all_vertex_positions.extend(vertex_positions)
# 使用最小二乘法拟合圆,计算圆心和半径
points_2d = [(pos[0], pos[2]) for pos in all_vertex_positions] # 使用 XZ 平面上的点
center, radius = calculate_circle_center_and_radius(points_2d)
# 计算平均高度
avg_height = np.mean([pos[1] for pos in all_vertex_positions])
# 创建定位器
locator = cmds.spaceLocator(p=[center[0], avg_height, center[1]])[0]
# 居中轴心
cmds.xform(locator, centerPivots=True)
print(f"圆心: {center}, 半径: {radius}, 高度: {avg_height}")
if __name__ == "__main__":
main()
四、文章最后
注意咯,我在这里,有问题或有需要可以随时联系。
(如果找不到可以直接搜索DianPu “第五设计”)