초보자를 대상으로 한 이번 포스팅에서는 Three.js로 제작한 3D Asset viewer에서 사용되는 Arnold 쉐이더의 속성을 Excel 파일로 추출하는 방법을 알아보겠습니다.
필요한 패키지 설치하기
먼저 이 작업을 수행하기 위해 필요한 패키지를 설치해야 합니다. 아래 명령어를 터미널에 입력하여 필요한 패키지를 설치하세요.
pip install openpyxl
쉐이더 속성 추출하기
주어진 코드를 사용하여 쉐이더의 속성을 추출할 수 있습니다. 이 코드는 해당 쉐이더의 baseColor, metalness, specular, specularRoughness, specularColor 등의 속성을 가져옵니다.
쉐이더 속성을 Excel 파일로 저장하기
추출한 쉐이더 속성을 엑셀 파일로 저장할 수 있습니다. 엑셀 파일에는 각 쉐이더의 속성이 시트로 구분되어 저장됩니다.
전체 코드
아래는 전체 코드입니다. 주어진 코드를 사용하여 쉐이더 속성을 추출하고 엑셀 파일로 저장할 수 있습니다.
# 필요한 Maya 모듈 및 외부 라이브러리를 가져옵니다.
import maya.cmds as cmds
import os
from openpyxl import Workbook
from maya.OpenMaya import MGlobal
# 해당 속성이 연결되어 있는지 확인하는 함수
def is_connected(attr):
"""
해당 속성이 연결되어 있는지 여부를 확인합니다.
:param attr: 연결을 확인할 속성의 이름
:return: 연결되어 있으면 True, 아니면 False
"""
return cmds.connectionInfo(attr, isDestination=True) and cmds.listConnections(attr)
# 해당 속성에 연결된 노드를 가져오는 함수
def get_connected_node(attr):
"""
해당 속성에 연결된 노드를 가져옵니다.
:param attr: 연결된 노드를 가져올 속성의 이름
:return: 연결된 노드의 이름, 없으면 None
"""
connections = cmds.listConnections(attr, source=True, destination=False)
if connections:
return connections[0]
else:
return None
# RGB 값을 16진수로 변환하는 함수
def rgb_to_hex(rgb):
"""
RGB 값을 16진수로 변환합니다.
:param rgb: RGB 값의 튜플
:return: 16진수 색상 코드
"""
return '0x{:02x}{:02x}{:02x}'.format(int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255))
# 반사율을 계산하는 함수
def calculate_reflectivity(metalness_weight, specular_weight, specular_color):
"""
반사율을 계산합니다.
:param metalness_weight: 금속성 가중치
:param specular_weight: 반사 가중치
:param specular_color: 반사 색상
:return: 계산된 반사율 값
"""
# 반사 색상이 튜플의 리스트인 경우 첫 번째 값만 사용합니다.
if isinstance(specular_color, list) and len(specular_color) == 1 and isinstance(specular_color[0], tuple):
specular_color = specular_color[0]
specular_brightness = sum(specular_color) / 3.0
if metalness_weight == 1:
return 0.8 + (specular_weight * 0.2)
else:
return specular_weight * specular_brightness
# 쉐이더의 속성을 가져오는 함수
def get_shader_attributes(shader):
"""
쉐이더의 속성을 가져옵니다.
:param shader: 쉐이더의 이름
:return: 쉐이더의 속성 딕셔너리
"""
attributes = {}
# 쉐이더 속성 및 해당하는 메이어 노드 속성 매핑
shader_props = {
"baseColor": "baseColor",
"metalness": "metalness",
"specular": "specularIntensity",
"specularRoughness": "roughness",
"specularColor": "specularColor",
"specularIOR": "ior",
"transmission": "transmission",
"transmissionColor": "transmissionColor",
"coat": "clearcoat",
"coatColor": "clearcoatColor",
"coatRoughness": "clearcoatRoughness",
"sheen": "sheen",
"sheenColor": "sheenColor",
"sheenRoughness": "sheenRoughness",
"emission": "emissive"
}
for prop, attr_name in shader_props.items():
prop_attr = f"{shader}.{prop}"
# 연결된 텍스처 또는 노드인 경우 값을 가져오지 않고 건너뜁니다.
if not is_connected(prop_attr):
if prop in ["baseColor", "specularColor", "transmissionColor", "coatColor", "sheenColor"]:
color_value = cmds.getAttr(prop_attr)[0]
attributes[attr_name] = rgb_to_hex(color_value)
else:
value = cmds.getAttr(prop_attr)
attributes[attr_name] = value
else:
print(f"{prop_attr} is connected to a texture or node, skipping.")
# 반사율을 별도로 계산하고 'reflectivity'에 할당합니다.
if "specularColor" in attributes:
metalness_weight = attributes.get("metalness", 0)
specular_weight = attributes.get("specularIntensity", 0)
specular_color = cmds.getAttr(f"{shader}.specularColor")[0] if "specularColor" in shader_props and not is_connected(f"{shader}.specularColor") else (1, 1, 1)
reflectivity_value = calculate_reflectivity(metalness_weight, specular_weight, specular_color)
attributes["reflectivity"] = reflectivity_value
return attributes
# 쉐이더 속성을 엑셀 파일로 내보내는 함수
def get_shader_properties_xlsx():
"""
쉐이더 속성을 엑셀 파일로 내보냅니다.
"""
# 건너뛸 쉐이더 목록
skip_shaders = ['lambert1', 'particleCloud1', 'shaderGlow1', 'standardSurface1']
current_file = cmds.file(query=True, sceneName=True)
file_path = os.path.dirname(current_file)
output_file_path = os.path.join(file_path, "props.xlsx")
# 파일이 이미 존재하면 삭제합니다.
if os.path.exists(output_file_path):
os.remove(output_file_path)
# 엑셀 워크북 생성
wb = Workbook()
first_sheet = wb.active
first_sheet.title = "Arnold Shaders"
# 모든 쉐이더에 대해 반복하면서 속성을 가져옵니다.
shaders = sorted(cmds.ls(materials=True))
for shader in shaders:
if shader not in skip_shaders and cmds.nodeType(shader) == "aiStandardSurface":
attr_data = get_shader_attributes(shader)
if attr_data:
ws = wb.create_sheet(title=shader)
for attribute, value in attr_data.items():
ws.append([attribute, value])
# 'Arnold Shaders' 시트 삭제
if 'Arnold Shaders' in wb.sheetnames:
wb.remove(wb['Arnold Shaders'])
# 엑셀 파일 저장
wb.save(output_file_path)
MGlobal.displayInfo("props.xlsx 파일 생성이 완료되었습니다!!!")
# 함수 호출
get_shader_properties_xlsx()
# 완료 다이얼로그 표시
cmds.confirmDialog(title='완료', message='프로세스가 성공적으로 완료되었습니다!', button='확인')