OpenMaya.MEventMessage와 ScriptJob의 실행 타이밍은 다릅니다.

8734 단어 파이썬maya
이 기사는 Takumi Akashiro 혼자 Advent Calendar 2020의 22 일째 기사입니다.

처음에



MEventMessage, ScriptJob 모두 Event가 발화하면 등록한 콜백 함수를 실행시키는 구조입니다만,
실은 MEventMessage와 ScriptJob의 실행 타이밍은 다릅니다.

커멘드 레퍼런스를 제대로 읽은 적이 있는 분은, 어째서인지 그렇게 되는 이해할 수 있다고 생각합니다.

우선 둘 다 시도해 보겠습니다.



이번에는 알기 쉬운 SelectionChanged Event에 후크하겠습니다

sample_scriptJob.py
#! python2
# encoding: utf-8
from maya import cmds


def print_func(text):
    print(text)


if __name__ == '__main__':
    if 'scriptjob_id' in globals() and cmds.scriptJob(ex=scriptjob_id):
        cmds.scriptJob(kill=scriptjob_id)
    scriptjob_id = cmds.scriptJob(event=["SelectionChanged", "print_func('SelectionChanged: ScriptJob')"])




sample_m_event_message.py
#! python2
# encoding: utf-8
from maya.api import OpenMaya


def print_func(text):
    print(text)


if __name__ == '__main__':

    if 'm_event_message_cbk_id' in globals():  # コールバックIDが生きてるか確認する手段が思いつかなったのでtry-exceptで誤魔化す。
        try:
            OpenMaya.MEventMessage.removeCallback(m_event_message_cbk_id)
        except RuntimeError, UnicodeDecodeError:  # UnicodeDecodeErrorは日本語環境用
            pass
    m_event_message_cbk_id = OpenMaya.MEventMessage.addEventCallback("SelectionChanged", print_func, 'SelectionChanged: MEventMessage')




ScriptJob도 MEventMessage도 똑같이 움직이고 있는 '처럼' 보이네요!

MEventMessage와 ScriptJob, 그 차이



ScriptEditor에서 다음을 실행해 보겠습니다.
#! python2
# encoding: utf-8
from maya import cmds

for x in range(3):
    cmds.select(cmds.ls(sl=True))

ScriptJob


OpenMaya.MEventMessage


뭐야?
ScriptJob은 한 번만 실행되지만 MEventMessage는 세 번 실행됩니다.

왜 그렇게 될까



이것은 Scriptjob의 실행 타이밍에 비밀이 있습니다.
공식 참조를 읽어 보자.

스크립트 작업은 대화형 응용 프로그램의 이벤트 루프에 연결됩니다.
이 작업은 유휴 이벤트 중에 실행됩니다.
이는 스크립트 작업이 배치 응용 프로그램에 존재하지 않음을 의미합니다. scriptJob 명령은 배치 모드에서 아무 작업도 수행하지 않습니다.
Command Reference: scriptJob - Maya 고객센터 더 발췌

그래서 ScriptJob은 처리가 끝나고 아이돌 상태가 되지 않으면 움직이지 않는 것입니다.

그래서 ScriptJob과 MEventMessage를 병용한 상태에서 조금 전에 스크립트에 print문을 더해 움직이면…
#! python2
# encoding: utf-8
from maya import cmds

print('-'*10 + '\nStart')

for x in range(3):
    print('Selection_before: %s' % x)
    cmds.select(cmds.ls(sl=True))
    print('Selection_after: %s' % x)
    if x != 2:
        print('-'*10)

print('-'*10 + '\nEnd')




처리 직후에 MEventMessage가 실행되고 처리가 완전히 끝난 후,
Maya가 아이돌이 된 단계에서 ScriptJob이 겨우 실행되는 것입니다.

조임



차이점을 알면 처리 횟수를 최대한 줄이기 위해 ScriptJob을 사용하거나,
엄격하게 감시하기 위해서 MEventMessage를 사용하는 등, 사용법을 나눌 수 있다고 생각합니다.

Event에 후크시키는 시스템은 편리합니다만, 교환에 조작 응답을 나쁘게 할 가능성이 있으므로,
이쪽은 의식할 수 있으면 좋네요!

좋은 웹페이지 즐겨찾기