Привязка объекта к другой вершине объекта в Maya через Python Script

Я хочу привязать/выровнять object A по вершине object B. Я попытался использовать приведенный ниже скрипт, но он не привязывается точно к вершине, а привязывается со смещением. Может ли кто-нибудь предложить мне решение. Вот снимки.

import maya.cmds as cmds

vertices = [];
srcObj = "pCone1";

def snapToVertex(vertex,object):

    cmds.select(vertex);
    x,y,z = cmds.pointPosition();
    cmds.select(object);
    cmds.duplicate();
    cmds.move(x,y,z);

def processTask():

    cmds.select( cmds.polyListComponentConversion( tv=True ) );        
    vertices = cmds.ls(sl = True);

    print vertices;
    for vrtx in vertices:
        snapToVertex(vrtx,srcObj);

processTask();

Привязано с помощью моего вышеприведенного скрипта, который не привязывался точно к вершине.

введите здесь описание изображения

Но он должен быть привязан точно к Vervex, как показано ниже.

введите здесь описание изображения


person Rao    schedule 31.05.2017    source источник
comment
Ссылаются ли координаты объекта на ограничивающую рамку или на конкретную точку привязки внутри объекта? В любом случае, я предполагаю, что вам нужен способ установить, какую точку объекта вы хотите привязать к вершине   -  person Peter Gibson    schedule 31.05.2017
comment
я переместил ось конуса к его краю, чтобы добиться этого. я думаю что-то мне нужно сделать с в то время как я двигаюсь.   -  person Rao    schedule 31.05.2017


Ответы (2)


Лучше не использовать команду Reset Transformations для вашего Cone из главного меню Modify, потому что точка поворота возвращается в исходное положение. Аналогом полезной команды Freeze Transformations в Python является cmds.makeIdentity(). Даже если вы переместили свою опорную точку на 1 единиц (например) по оси +Y, не забудьте вычесть эти 1 из variable y, потому что Майя каким-то образом запоминает положение опорной точки. Смещение точки поворота конуса (для привязки поворота к вершине) зависит от размера самого конуса. По умолчанию это 1.

Добавьте этот фрагмент в свой код, чтобы переместить дубликаты в World Space:

# cmds.makeIdentity( 'pCone1', apply=True )

pivSnap = 1  
cmds.xform( 'pCone1', piv=[ 0, pivSnap, 0 ] )
cmds.move( x, y-pivSnap, z, a=True, ws=True, wd=True )

введите здесь описание изображения

Вы можете протестировать этот код (здесь я переместил точку поворота вверх на 0.5):

import maya.cmds as cmds

cmds.polyCube( sx=1, sy=15, sz=1, w=1, h=15, d=1 )
cmds.polyCone( r=.5, h=1, sx=10 )
cmds.move( 10, x=True )
pivSnap = .5
cmds.xform( 'pCone1', piv=[ 0, pivSnap, 0 ] )
cmds.rotate( 0, 0, '45deg' )
cmds.select( 'pCube1.e[33]','pCube1.e[37]','pCube1.e[41]','pCube1.e[45]','pCube1.e[49]','pCube1.e[53]','pCube1.e[57]','pCube1.e[61]' )
vertices = []
srcObj = "pCone1"

def snapToVertex( vertex, object ):

    cmds.select( vertex )
    x,y,z = cmds.pointPosition()
    print( x,y,z )

    cmds.select( object )
    cmds.manipMoveContext( m=2 )
    cmds.delete( 'pCube1', ch=True )
    cmds.duplicate()    
    cmds.move( x, y-pivSnap, z, a=True, ws=True, wd=True )

def processTask():

    cmds.select( cmds.polyListComponentConversion( tv=True ) )      
    vertices = cmds.ls( sl=True )
    print( vertices )

    for vrtx in vertices:
        snapToVertex( vrtx, srcObj )

processTask()

введите здесь описание изображения

person Andy Fedoroff    schedule 31.05.2017
comment
по умолчанию мы получаем позицию в мире, если мы не укажем (l=True). Это я уже проверил. Это не проблема - person Rao; 31.05.2017

вы можете значительно упростить свой код и использовать только несколько команд

import maya.cmds as mc

verts = mc.ls(os=True)
src = 'pCone1'
base_name = 'fancy_cone'

for i, vert in enumerate(verts):
    dup = mc.duplicate(src, n='%s_%s' %(base_name, i))[0]
    mc.xform(dup, ws=True, t=mc.xform(vert, q=True, ws=True, t=True))

имейте в виду несколько предостережений:

1) это предполагает, что стержень вашего исходного конуса находится на кончике с кончиком в начале координат... поэтому требуется настроить этот исходный конус так, как вы хотите, как если бы исходная точка была вершиной, которую вы будете привязывать это к. Это также было бы полезно, если объект, к которому вы «закрепляете», вращается (нет необходимости выполнять какие-либо векторные вычисления, чтобы определить позиционное смещение таким образом)
2) использовать orderedSelection (os) в команде ls, вы должны убедиться, что отслеживание порядка выбора включено в ваших настройках Maya в подразделе выбора — таким образом вы можете выбрать вершины, которые вы хотите, в том порядке, в котором вы хотите, чтобы они были созданы (сверху вниз, снизу вверх, как угодно) вместо порядка индекса вершины

Это также должно быть значительно быстрее - отслеживая любые созданные объекты, вам фактически не нужно ничего выбирать, и вы можете напрямую манипулировать объектами. Я также поместил все это в один цикл без каких-либо вызовов функций, что было бы быстрее (хотя вы, вероятно, не заметите этого, если не сделаете их LOOOOOOT).

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

Что-то вроде этого (с учетом тех же предостережений, что и выше):

import maya.cmds as mc

def snapToVertex(vertex, object):
    pos = mc.xform(vertex, q=True, ws=True, t=True)
    mc.xform(object, ws=True, t=pos)  # combine to single line if prefered

def processTask():
    verts = mc.ls(os=True)
    src = 'pCone1'
    base_name = 'fancy_cone'

    for i, vert in enumerate(verts):
        dup = mc.duplicate(src, n='%s_%s' %(base_name, i))[0]
        snapToVertex(vert, dup)

processTask()
person silent_sight    schedule 08.06.2017