posted by cimple 2016. 12. 13. 17:55

Maya 에서 Object 들의 Transform 을 얻어오는 방식에 대해서 정리한다.

이것이 중요한 이유는 어플리케이션을 만들 때 get 하는 일이 많이 있는데, 만약 애니메이션 전체에 대해서 빈번하게 발생할 경우 효율적인 계산이 필요하기 때문이다.



Maya Command

xform : 대부분의 transform 정보를 가져올 수 있으나, '현재' 오브젝트에만 접근 가능하다. 즉, 애니메이션 오브젝트의 정보를 가져오려면 currentTime 커맨드와 함께 사용해야만 하는 단점이 있다. 이러면 많이 느려진다.

getAttr: time flag가 있어서 각 애니메이션된 오브젝트들의 attribute 데이터에 빠르게 접근할 수 있다. 그러나 attribute 가 움직이지 않는 데이터(ex. IK chain에서 조인트의 translateXYZ 정보) 등은 받아올 수가 없다.

position 을 확인하기 위한 하나의 꼼수(!) 는 다른 object 에 constraint 를 걸고 이 값을 받아오는 것이다.


 import maya.cmds as mc

import time

def xform_per_frame(object, start_frame, end_frame):
posList = []
for i in range(start_frame, end_frame):
mc.currentTime(i)
pos = mc.xform(object, t=True, q=True, ws=True)
posList.append(pos)
return posList

def getAttr_test(object, start_frame, end_frame):
posList = []
for i in range(start_frame, end_frame):
posX = mc.getAttr(object+'.translateX', t=i)
posY = mc.getAttr(object+'.translateY', t=i)
posZ = mc.getAttr(object+'.translateZ', t=i)
posList.append([posX, posY, posZ])
return posList



t00 = time.time()
xform_list = xform_per_frame('locator1', 1, 100)
t01 = time.time()
getAttr_list = getAttr_test('locator1', 1, 100)
t02 = time.time()

print 'xform time : ', t01-t00
print 'getAttr time : ', t02-t01

위 코드는 xform 과 getAttr 의 시간차이를 나타내주는 코드이다. locator1 에 100프레임의 애니메이션을 주고 position 값을 얻는 동일한 기능을 수행한다.

시간 차이는

xform time :  0.328000068665

getAttr time :  0.0789999961853

로 4~5배정도 차이가 나는 것을 확인할 수 있다. scene 이 무거울수록 currentTime 으로 frame 을 변화시킬 때 발생하는 딜레이 현상은 더 심해진다. 


NOTE

그러나 getAttr 에도 중요한 버그(?) 가 있는데, 만약 해당 object 의 attribute 가 setKeyframe 이나 setAttr 등으로 인하여 변했을 경우, getAttr 을 하면 실제 attribute 가 바뀌었는데도 기존 값이 그대로 들어오는것을 볼 수 있다. 심지어 타임 슬라이더를 왔다갔다 하거나 카메라를 움직이거나 하는 등 씬을 새로고침해도 이 값이 변화하지 않음을 알 수 있다.

의아하게도 getAttr 로 다른 프레임의 값을 한번 읽은 다음 다시 내가 원하는 프레임의 값을 읽으면 정상적으로 값을 불러들여옴을 확인할 수 있다. 이건 버그성이 있는 것 같다.


keyframe: keyframe 을 가진 object 라면 keyframe 커맨드를 통해서 value 를 알아낼 수 있다. 꼭 keyframe 에 해당하는 frame 의 value 뿐만 아니라, key 가 없는 frame 의 value 도 알아낼 수 있다.

print mc.keyframe('ikHandle1.translateX', q=True, ev=True, t=(40,40)) 

getAttr 과는 다르게 중간에 값이 변화하더라도 즉각즉각 변화된 값을 잘 반환해준다.

그러나 아쉽게도 key 값이 없는 object 에 대해서는 값을 반환하지 않는다. 아마도 key 가 생기면 면 animation curve 가 생성되게 되고, keyframe 커맨드는 이 그래프의 값을 반환하는 것으로 생각된다. 


Maya API 를 활용하는 방법

http://cimple.tistory.com/428

해당 포스트를 참조