在 Maya 中使用三角函数翻译复制对象 + Python

duplicate objects with trig function translations in Maya + Python

我正在尝试使用 python 循环函数在 XY 平面中围绕中心球体创建一个六角形球体阵列(无法弄清楚如何使用重复特殊来做到这一点)。它最终应该看起来像这样:

  0 0
0  0  0
  0 0    

这是我的代码。我收到语法错误

# Error: line 1: invalid syntax # 

当我调用它时,虽然我很确定第一行没有问题。

import maya.cmds as cmds

class Sphere(radius, tx=0, ty=0, tz=0, sx=0, sy=0, sz=0):
    self.diameter = 2*radius

def createSphere(radius, tx, ty):
    newSphere = Sphere(radius=radius, tx=tx, ty=ty)
    return newSphere

def duplicateSphere(wholeSphere):
    for i in range(6, 1, -1):
        createSphere(tx=wholeSphere.diameter*math.cos(2*math.pi/i), ty=wholeSphere.diameter*math.sin(2*math.pi/i))
        # create spheres with projections onto x and y axes as translation params

duplicateSphere(createSphere(1.03))

对发生的事情有什么想法吗?

好的,首先回答你的问题,SyntaxError是由于class实例化不当造成的。 class声明必须与python中的构造方法分开,像这样:

class Sphere(object):
    def __init__(self, radius, tx=0, ty=0, tz=0, sx=0, sy=0, sz=0):
        self.diameter = 2 * radius

提示:在 maya 脚本编辑器 面板中,如果您启用 History->Show Stack Trace 它会给您一个更好的主意实际错误发生的位置。

但是,还有其他一些问题在起作用。首先,您永远不会将传递给球体的参数存储 class (半径除外,您通过存储直径来隐式存储它)。你可能想要:

class Sphere(object):
    def __init__(self, radius, tx=0, ty=0, tz=0, sx=1, sy=1, sz=1):
        self.radius = radius
        self.tx = tx
        self.ty = ty
        self.tz = tz
        self.sx = sx
        self.sy = sy
        self.sz = sz
        self.diameter = 2 * radius

我将比例默认值更改为 1 而不是 0,这样默认球体就不会小到看不见了。

此外,正如 theodox 指出的那样,您的 createSphere 方法中有一个 TypeError,它需要 3 个参数(其中 none 目前是关键字参数,因此不是可选的)而你只传递了 1.

但是,主要问题是目前您实际上并未在 Maya 中创建任何球体。如果你的意图是你的球体对象是一个围绕 maya.cmds 的面向对象的包装器,你将需要它在某处调用 cmds.sphere,你可能想要 cmds.move()cmds.scale() 它由你的 t* 和 s* 值。如果您在构造函数中执行所有这些操作,您实际上可以根据需要避免为所有球体属性设置实例变量。

这看起来像这样:

cmds.sphere(radius=self.radius)
cmds.move(self.tx,self.ty,self.tz)
cmds.scale(self.sx,self.sy,self.sz)

最后,我认为你的三角函数有点偏离(你希望每次迭代都精确地变化 60° 或 π/3 弧度)。为了获得合适的角度,我想你想要更多的东西:

import math

for i in range(6,0,-1):
    angle = math.pi * i / 3.0
    distance = wholeSphere.diameter
    tx = distance * math.cos(angle)
    ty = distance * math.sin(angle)
    # ...

作为最后一点,请考虑考虑像 pymel 这样的面向对象的解决方案,以避免在对象中包装 maya.cmds 命令方面需要重新发明轮子。

无论如何,应用所有这些更正会产生如下结果:

import maya.cmds as cmds
import math

class Sphere(object):
    def __init__(self, radius, tx=0, ty=0, tz=0, sx=1, sy=1, sz=1):
        self.diameter = 2*radius
        self.radius = radius
        self.tx = tx
        self.ty = ty
        self.tz = tz
        self.sx = sx
        self.sy = sy
        self.sz = sz

        cmds.sphere(radius=self.radius)
        cmds.move(self.tx,self.ty,self.tz)
        cmds.scale(self.sx,self.sy,self.sz)

def createSphere(radius, tx=0, ty=0):
    newSphere = Sphere(radius, tx=tx, ty=ty)
    return newSphere

def duplicateSphere(wholeSphere):
    for i in range(6, 0, -1):
        angle = math.pi * i / 3.0
        distance = wholeSphere.diameter
        tx = distance * math.cos(angle)
        ty = distance * math.sin(angle)
        createSphere(wholeSphere.radius, tx=tx, ty=ty)

duplicateSphere(createSphere(1.03))