Maya에서 여러 Python 스크립트를 쉽게 실행하기 위한 UI Panel 만들기

Maya에서 여러 Python 스크립트를 쉽게 실행하기 위한 UI Panel 만들기


 

안녕하세요! 이번 블로그 글에서는 Maya에서 다양한 Python 스크립트를 쉽게 실행할 수 있는 사용자 인터페이스(UI)를 만드는 방법을 단계별로 알려드리겠습니다.
이번 튜토리얼을 따라 하시면, Python 코드를 사용하여 Maya UI를 만들고, 버튼 클릭으로 스크립트를 실행할 수 있게 될 것입니다.

 

사전 준비: 필요한 패키지 설치

 

먼저, 이 튜토리얼을 따라하기 위해 필요한 패키지를 설치해야 합니다.
터미널이나 커맨드 프롬프트에서 아래 명령어를 실행하여 maya 패키지를 설치하세요.

pip install maya

 

1. Maya UI 창 만들기

 

Maya에서 사용자 인터페이스를 만들기 위해 maya.cmds 모듈을 사용합니다.
먼저, 기존에 동일한 이름의 창이 있으면 삭제하고, 새 창을 만듭니다.

import maya.cmds as cmds  # Maya 명령어를 사용할 수 있도록 cmds 모듈을 임포트
import os  # 운영 체제 관련 기능을 사용할 수 있도록 os 모듈을 임포트

# UI를 생성하는 함수 정의
def create_ui():
    # 이미 같은 이름의 창이 있으면 삭제
    if cmds.window("myToolWindow", exists=True):
        cmds.deleteUI("myToolWindow")

    # 새로운 창 생성
    window = cmds.window("myToolWindow", title="Python File Executor", sizeable=False)
    form = cmds.formLayout()  # 폼 레이아웃 생성

 

2. 버튼 및 파일 경로 설정

 

각 버튼을 클릭하면 특정 Python 파일을 실행하게 됩니다.
버튼 레이블과 파일 경로를 딕셔너리 형태로 정의합니다.

    # 버튼 라벨과 파일 경로를 매핑한 딕셔너리 정의
    button_labels = {
        "Bulk Renamer": "파일 경로/BulkRenamer_v1.3.py",
        "Shader Att. Exporter\nto Excel(Arnold)": "파일 경로/ShaderAttExporterArnoldToExcel_v1.0.py",
        "Shader Att. Exporter\nto Excel(V-Ray)": "파일 경로/ShaderAttExporterVRay_v1.1.py",
        "Shader Att. Exporter\nto Excel(standardSurface)": "파일 경로/ShaderAttExporterStandardSurface_v1.0.py",
        "Shader Counter": "파일 경로/ShaderCounter_v1.0.py",
        "UV Tilling Mode\nto UDIM": "파일 경로/UVTillingModeToUDIM_v1.0.py",
        "Shader Duplicator\nfor UDIM": "파일 경로/ShaderDuplicatorForUDIM_v1.0.py",
        "Light Creator\n(V-Ray)": "파일 경로/LightCreatorVRay_v1.1.py",
        "Light Creator\n(Arnold)": "파일 경로/LightCreatorArnold.py"
    }

 

3. 스크립트 실행 함수 작성

 

파일 경로를 받아 해당 스크립트를 실행하는 함수를 작성합니다.
파일이 존재하지 않을 경우 경고 메시지를 출력합니다.

    # 스크립트를 실행하는 함수 정의
    def execute_script(file_path):
        # 파일 경로가 존재하고, 해당 파일이 실제로 존재하는지 확인
        if file_path and os.path.isfile(file_path):
            # 파일을 읽고 그 내용을 실행
            with open(file_path, 'r', encoding='utf-8') as file:
                exec(file.read())
        else:
            # 파일이 존재하지 않으면 경고 메시지 출력
            cmds.warning("File not found: " + file_path)

 

4. 버튼 생성 및 레이아웃 설정

 

각 버튼을 생성하고, 버튼 클릭 시 스크립트가 실행되도록 설정합니다.
버튼의 위치와 크기도 설정합니다.

    button_height = 50  # 버튼 높이 설정
    button_width = 150  # 버튼 너비 설정
    spacing = 5  # 버튼 간 간격 설정

    buttons = []  # 버튼을 저장할 리스트 초기화
    # 딕셔너리의 각 항목에 대해 반복
    for i, (label, file_path) in enumerate(button_labels.items()):
        # 버튼 생성 및 명령 연결
        btn = cmds.button(label=label, width=button_width, height=button_height, command=lambda x, path=file_path: execute_script(path))
        buttons.append(btn)  # 버튼 리스트에 추가

    # 버튼을 폼 레이아웃에 배치
    for i in range(0, len(buttons), 2):
        if i + 1 < len(buttons):
            # 두 개의 버튼을 나란히 배치
            cmds.formLayout(form, edit=True, 
                attachForm=[(buttons[i], 'left', spacing), (buttons[i], 'top', spacing + (button_height + spacing) * (i // 2)),
                            (buttons[i + 1], 'right', spacing), (buttons[i + 1], 'top', spacing + (button_height + spacing) * (i // 2))],
                attachControl=[(buttons[i + 1], 'left', spacing, buttons[i])]
            )
        else:
            # 마지막 버튼이 홀수인 경우 단독 배치
            cmds.formLayout(form, edit=True, 
                attachForm=[(buttons[i], 'left', spacing), (buttons[i], 'right', spacing), (buttons[i], 'top', spacing + (button_height + spacing) * (i // 2))]
            )

    # 창의 크기를 버튼 크기에 맞게 조정
    cmds.window(window, edit=True, widthHeight=(2 * button_width + 3 * spacing, (button_height + spacing) * ((len(button_labels) + 1) // 2) + spacing))
    cmds.showWindow(window)  # 창을 화면에 표시

 

5. UI 생성 함수 호출

 

마지막으로, UI를 생성하는 함수를 호출하여 Maya에서 UI를 실행합니다.

# UI 생성 함수 호출
create_ui()

 







 

최종 코드

 

위에서 설명한 모든 단계를 합치면 아래와 같은 최종 코드가 완성됩니다.
이 코드를 Maya 스크립트 편집기에 붙여넣고 실행하면 UI가 생성됩니다.

import maya.cmds as cmds  # Maya 명령어를 사용할 수 있도록 cmds 모듈을 임포트
import os  # 운영 체제 관련 기능을 사용할 수 있도록 os 모듈을 임포트

# UI를 생성하는 함수 정의
def create_ui():
    # 이미 같은 이름의 창이 있으면 삭제
    if cmds.window("myToolWindow", exists=True):
        cmds.deleteUI("myToolWindow")

    # 새로운 창 생성
    window = cmds.window("myToolWindow", title="Python File Executor", sizeable=False)
    form = cmds.formLayout()  # 폼 레이아웃 생성

    # 버튼 라벨과 파일 경로를 매핑한 딕셔너리 정의
    button_labels = {
        "Bulk Renamer": "파일 경로/BulkRenamer_v1.3.py",
        "Shader Att. Exporter\nto Excel(Arnold)": "파일 경로/ShaderAttExporterArnoldToExcel_v1.0.py",
        "Shader Att. Exporter\nto Excel(V-Ray)": "파일 경로/ShaderAttExporterVRay_v1.1.py",
        "Shader Att. Exporter\nto Excel(standardSurface)": "파일 경로/ShaderAttExporterStandardSurface_v1.0.py",
        "Shader Counter": "파일 경로/ShaderCounter_v1.0.py",
        "UV Tilling Mode\nto UDIM": "파일 경로/UVTillingModeToUDIM_v1.0.py",
        "Shader Duplicator\nfor UDIM": "파일 경로/ShaderDuplicatorForUDIM_v1.0.py",
        "Light Creator\n(V-Ray)": "파일 경로/LightCreatorVRay_v1.1.py",
        "Light Creator\n(Arnold)": "파일 경로/LightCreatorArnold.py"
    }

    # 스크립트를 실행하는 함수 정의
    def execute_script(file_path):
        # 파일 경로가 존재하고, 해당 파일이 실제로 존재하는지 확인
        if file_path and os.path.isfile(file_path):
            # 파일을 읽고 그 내용을 실행
            with open(file_path, 'r', encoding='utf-8') as file:
                exec(file.read())
        else:
            # 파일이 존재하지 않으면 경고 메시지 출력
            cmds.warning("File not found: " + file_path)

    button_height = 50  # 버튼 높이 설정
    button_width = 150  # 버튼 너비 설정
    spacing = 5  # 버튼 간 간격 설정

    buttons = []  # 버튼을 저장할 리스트 초기화
    # 딕셔너리의 각 항목에 대해 반복
    for i, (label, file_path) in enumerate(button_labels.items()):
        # 버튼 생성 및 명령 연결
        btn = cmds.button(label=label, width=button_width, height=button_height, command=lambda x, path=file_path: execute_script(path))
        buttons.append(btn)  # 버튼 리스트에 추가

    # 버튼을 폼 레이아웃에 배치
    for i in range(0, len(buttons), 2):
        if i + 1 < len(buttons):
            # 두 개의 버튼을 나란히 배치
            cmds.formLayout(form, edit=True, 
                attachForm=[(buttons[i], 'left', spacing), (buttons[i], 'top', spacing + (button_height + spacing) * (i // 2)),
                            (buttons[i + 1], 'right', spacing), (buttons[i + 1], 'top', spacing + (button_height + spacing) * (i // 2))],
                attachControl=[(buttons[i + 1], 'left', spacing, buttons[i])]
            )
        else:
            # 마지막 버튼이 홀수인 경우 단독 배치
            cmds.formLayout(form, edit=True, 
                attachForm=[(buttons[i], 'left', spacing), (buttons[i], 'right', spacing), (buttons[i], 'top', spacing + (button_height + spacing) * (i // 2))]
            )

    # 창의 크기를 버튼 크기에 맞게 조정
    cmds.window(window, edit=True, widthHeight=(2 * button_width + 3 * spacing, (button_height + spacing) * ((len(button_labels) + 1) // 2) + spacing))
    cmds.showWindow(window)  # 창을 화면에 표시

# UI 생성 함수 호출
create_ui()

 

위 코드에서 사용된 Maya Python 함수와 명령어들은 다음과 같습니다:

 

6. 이 글에서 사용된 maya.cmds 모듈 함수

 

Maya에서 다양한 작업을 수행할 수 있는 명령어들입니다:

# 새 창을 만듭니다.
🔗cmds.window()

# 폼 레이아웃을 만듭니다.
🔗cmds.formLayout()

# 텍스트 필드를 만듭니다.
🔗cmds.textFieldGrp()

# 버튼을 만듭니다.
🔗cmds.button()

# 창을 표시합니다.
🔗cmds.showWindow()

# 부모 레이아웃을 설정합니다.
🔗cmds.setParent()

# 현재 선택된 객체를 나열합니다.
🔗cmds.ls()

# 객체의 자식 객체를 나열합니다.
🔗cmds.listRelatives()

# 객체가 존재하는지 확인합니다.
🔗cmds.objExists()

# 객체의 이름을 변경합니다.
🔗cmds.rename()
 

2. Python 표준 라이브러리 함수

# 문자열에서 패턴과 일치하는 부분을 다른 문자열로 대체하는 역할을 합니다.
🔗re.sub()