Конкатенация переменных Maya

Имея несколько проблем, в основном вставляя кучу флагов, сгенерированных циклом:

def drawHelix(radius, length, coils): 
    numPoints = int(8)
    degrees = float((360 / numPoints))
    centerX = float(0)
    centerZ = float(0)
    xLoc = float(0)
    zLoc  = float(0)
    yLoc  = float(0)
    yOffset = float(((length / coils) / numPoints))
    vectorIndex = int(0)
    pointStr = ""
    knotStr = ""
    for i in range(1, (360 * coils), 20):
        t = i + degrees
        xLoc = centerX + (math.cos(t) * radius)
        zLoc = centerZ - (math.sin(t) * radius)
        pointStr = (pointStr + " p=(" + str(xLoc) + "," +  str(yLoc) + "," +  str(zLoc) + "),")
        knotStr = (knotStr + "k=(" + str(vectorIndex) + ")")
        vectorIndex = i + 1
        yLoc = yLoc + yOffset
    print pointStr        
    spiral = cmds.curve(d=float(1.0), pointStr, knotStr)
    cmds.rebuildCurve (spiral, ch=1, rpo=1, rt=0, end=1, kr=1, kcp=0, kep=0, kt=0, s=0, d=3, tol=0.001)
    return spiral

С которым я затем запускаю: drawHelix (2.00, 3.00, 5.00)

Проблема в том, что Maya не распознает «pointStr» как флаг для команды кривой, когда я печатаю pointStr, она дает мне именно то, что я хочу, но изо всех сил пытаюсь понять, как на самом деле заставить это работать!


person Shannon Hochkins    schedule 13.01.2013    source источник
comment
Почему так важно, что вы удалили Cheers Shannon @NullPointer , просто поблагодарив всех, кто нашел время, чтобы прочитать это?   -  person Shannon Hochkins    schedule 13.01.2013
comment
Это обычная практика, Шеннон. Вы действительно не должны включать это в свой пост. Будем считать, что вы благодарны. Прочитайте это обсуждение на Meta SO< /а>.   -  person Bart    schedule 13.01.2013
comment
@ShannonHochkins Не уверен, что это вам сильно поможет, но это рабочая форма? Например, используя ваш код и загружая его в Maya, я получаю кривую NURBS в спирали, и единственное предупреждение — об отключении истории для команды. Вы получаете конкретную ошибку с командой?   -  person tanantish    schedule 13.01.2013


Ответы (2)


Я предполагаю, что это то, что вы имели в виду:

from maya import cmds
import math
def drawHelix(radius, length, coils): 
    numPoints = int(8)
    degrees = float((360 / numPoints))
    centerX = float(0)
    centerZ = float(0)
    xLoc = float(0)
    zLoc  = float(0)
    yLoc  = float(0)
    yOffset = float(((length / float(coils)) / float(numPoints)))
    vectorIndex = int(0)
    pointStr = []
    knotStr = []
    yLoc = 0
    for i in range(1, (360 * coils), 20):
        t = i + degrees
        xLoc = centerX + (math.cos(t) * radius)
        zLoc = centerZ - (math.sin(t) * radius)
        pointStr.append((xLoc, yLoc,zLoc))
        knotStr.append(vectorIndex)
        vectorIndex = i + 1
        yLoc = yLoc + yOffset
    print pointStr        
    spiral = cmds.curve(p= pointStr, k=knotStr,d=float(1.0))
    cmds.rebuildCurve (spiral, ch=1, rpo=1, 
                       rt=0, end=1, kr=1, kcp=0, kep=0, 
                       kt=0, s=0, d=3, tol=0.001)
    return spiral

Просто есть гораздо лучший способ сделать это. Вот как вы должны использовать Maya, использовать узлы для создания своих вещей. Итак, вот излишне прокомментированная и многословная версия:

from maya import cmds

def getHistoryShape(name):
    history = cmds.listHistory(name)
    filteredShape = cmds.ls(history, shapes=1)[0]
    return filteredShape 

def drawHelix(radius, length, coils): 
    cyl = cmds.cylinder( ch=True, radius=radius, ax=(0,1,0),
                         hr=float(length)/float(radius) )

    # build a curve on the cylinders surface
    crv = cmds.curveOnSurface(cyl[0], d=1, 
                              uv=[(0,0),(length, coils*4)],
                              k=[0,1]) 
    # make a duplicate that is visible 
    crv = cmds.duplicateCurve(ch=1, rn=0, local=1)

    # tell maya to ignore the cylinder as a piece of geometry
    shape = getHistoryShape(cyl[0])
    cmds.setAttr(shape+'.intermediateObject', 1)

    cmds.rename(cyl[0],'helix1')
    return crv  

Теперь вы можете изменить параметры спиралей позже, вживую. Вы можете указать параметры радиуса, длины и витков для пользователя, чтобы их можно было анимировать. См., например, фабричные сценарии Maya.

person joojaa    schedule 13.01.2013
comment
Отлично, большое спасибо @joojaa! - person Shannon Hochkins; 13.01.2013
comment
Maya сама по себе является языком программирования. Как правило, если вы не создаете узлы с привязками API, вы не делаете много прямых манипуляций с чем-либо. Что вы делаете, так это используете узлы, которые являются строительными блоками Maya, и заставляете их что-то делать для вас. Таким образом, вы получите больше. То, что более поздний код делает цилиндр, скрывает его, делает кривую на поверхности указанного цилиндра и копирует ее в обычное пространство. Я буду комментировать это лучше. Другой просто разъясняет синтаксис Python. - person joojaa; 14.01.2013
comment
Я понимаю, как зацепить радиус и высоту/длину, но как я могу отцепить катушки? @joojaa - person Shannon Hochkins; 14.01.2013
comment
Вы делаете дополнительный атрибут, соединяющий с ним узел множественного деления, чтобы получить пролеты цилиндра, умноженные на созданный вами атрибут значения катушки. Затем соедините выход для этой кривой на последней вершине Y значения кривой на поверхности. - person joojaa; 14.01.2013
comment
Спасибо @joojaa :) Это прекрасно! Вы не могли бы помочь мне с еще одной моей проблемой, не так ли? stackoverflow.com/questions/14315215/maya-local-direction - person Shannon Hochkins; 14.01.2013
comment
Я получаю цикл, когда делаю это, это если я сделал это правильно! jsfiddle.net/dAEn8 - person Shannon Hochkins; 15.01.2013
comment
Майи под рукой нет. Даже приведенный выше пример кода был написан без тестирования в Maya. - person joojaa; 17.01.2013
comment
О, облом, в любом случае спасибо, мне удалось заставить все работать, кроме редактирования количества катушек, если бы вы могли найти время, это было бы здорово, но если нет, спасибо за вашу помощь! - person Shannon Hochkins; 18.01.2013

Интерпретатор Python не будет расширять ваши строки перед вызовом функции (вы можете добиться этого, используя eval, но обычно это считается плохой практикой - см. этот пост на SO).

Это должно работать при передаче аргументов в виде словаря ключевых слов. Посмотрите здесь:

Итак, вместо:

pointStr = (pointStr + " p=(" + str(xLoc) + "," +  str(yLoc) + "," +  str(zLoc) + "),")
knotStr = (knotStr + "k=(" + str(vectorIndex) + ")")

Ты должен сделать

kwargs['d'] = 1.0
kwargs['p'] = []
for i in range(1, (360 * coils), 20):
    ...
    kwargs['p'].append((xloc, yloc, zloc))
    kwargs['k'].append(vectorIndex)

spiral = cmds.curve(**kwargs) 

Кроме того, в вашем коде есть несколько других проблем:

float((360 / numPoints)) будет оцениваться по-разному в Python2.x и Python3.x. Вот что происходит в 2.x:

In [5]: float(7 / 6)
Out[5]: 1.0

In [6]: 7. / 6
Out[6]: 1.1666666666666667

Если вы хотите убедиться, что в вашем случае выполняется деление с плавающей запятой, используйте degrees = 360. / numPoints. Потенциальные последствия хуже в этой строке вашего кода: yOffset = float(((length / coils) / numPoints)).

Вы объявляете константы float и int, просто записывая их с десятичной точкой или без нее. Не нужно оборачивать их вызовом float() или int().

person Theodros Zelleke    schedule 13.01.2013
comment
Я знаю, что вы можете объявить их без их упаковки, хотя, когда число является динамическим и вводится пользователем и должно быть числом с плавающей запятой, требуемым некоторыми аргументами, тогда это необходимо. - person Shannon Hochkins; 15.01.2013