마야(MAYA)에서 오브젝트 중 세로면(Y축과 평행한 면)만 선택하기





import maya.cmds as cmds import maya.api.OpenMaya as om # 선택된 오브젝트 가져오기 sel = cmds.ls(sl=True, dag=True, shapes=True) if not sel: cmds.warning("오브젝트를 선택하세요.") else: obj = sel[0] dag_path = om.MSelectionList().add(obj).getDagPath(0) mesh = om.MFnMesh(dag_path) faces_to_select = [] threshold = 0.05 # Y축과 평행한 정도 (값이 작을수록 더 정확함) for i in range(mesh.numPolygons): normal = mesh.getPolygonNormal(i, om.MSpace.kWorld) # Y축 방향 벡터와의 내적 검사 # Y축과 평행한 면은 normal.y ≈ 0 if abs(normal.y) < threshold: faces_to_select.append(f"{obj}.f[{i}]") if faces_to_select: cmds.select(faces_to_select, r=True) print(f"Y축에 평행한 면 {len(faces_to_select)}개 선택됨.") else: cmds.warning("Y축에 평행한 면을 찾지 못했습니다.")




면이 너무 많으면 세로로 된 면, 오브젝트의 옆면들만 선택하는 것은 거의 불가능에 가깝다. 컴퓨터가 멈춘다 ㅠㅠ 그래서 스트립트가 반드시 필요하다. python이 참 빠르고 간단하여 좋다.



실행하면 이렇게 옆면만 선택을 해준다.
threshold 값이 0.05면 거의 수직인 면만 선택이 되는데 0.1을 해주면 약간 틀어진 면도 수직이니까 선택을 하게 된다. 응용하면 0.4~0.5정도로 해주면 기울어진면도 선택이 되겠지만 이것은 자칫 내가 의도치 않은 면까지 선택이 될 수 있으므로 여러번 테스트가 필요할 듯 하다.


 
스크립트를 좀 더 발전 시켜보면


import maya.cmds as cmds import maya.api.OpenMaya as om # 선택된 항목 가져오기 sel = cmds.ls(sl=True) if len(sel) < 2: cmds.warning("오브젝트와 셰이더를 모두 선택하세요. (오브젝트 먼저, 셰이더 나중)") else: obj = sel[0] shader = sel[-1] # 셰이딩 그룹(SG) 찾기 sg_nodes = cmds.listConnections(shader, type='shadingEngine') if not sg_nodes: # 없으면 새로 생성 sg_nodes = [cmds.sets(renderable=True, noSurfaceShader=True, empty=True, name=f"{shader}SG")] cmds.connectAttr(f"{shader}.outColor", f"{sg_nodes[0]}.surfaceShader", force=True) print(f"'{shader}'용 셰이딩그룹 '{sg_nodes[0]}' 새로 생성됨.") sg = sg_nodes[0] # 메시 접근 shapes = cmds.listRelatives(obj, shapes=True, fullPath=True) if not shapes: cmds.warning("선택한 오브젝트에 메시가 없습니다.") else: dag_path = om.MSelectionList().add(shapes[0]).getDagPath(0) mesh = om.MFnMesh(dag_path) faces_to_select = [] threshold = 0.05 # Y축 평행 판정 기준 for i in range(mesh.numPolygons): normal = mesh.getPolygonNormal(i, om.MSpace.kWorld) if abs(normal.y) < threshold: faces_to_select.append(f"{obj}.f[{i}]") if faces_to_select: cmds.select(faces_to_select, r=True) cmds.sets(faces_to_select, e=True, forceElement=sg) print(f"{len(faces_to_select)}개의 Y축 평행 면에 '{shader}' 셰이더 적용 완료.") else: cmds.warning("Y축에 평행한 면을 찾지 못했습니다.")

오브젝트를 선택하고 셰이더를 선택후 실행시키면
자동으로 수직면을 선택해서 해당 셰이더를 적용시켜준다


여기서 스크립트 더 발전 시켜서 여러개의 오브젝트를 동시에 수행하도록 할 수 있다
여러 오브젝트를 선택하고 마지막에 셰이더를 선택한 후 스크립트를 실행하면
여러개의 오브젝트를 일괄적으로 자동으로 처리할 수 있다.



import maya.cmds as cmds import maya.api.OpenMaya as om # ====================== # 선택 순서: # ① 오브젝트 여러 개 선택 # ② 적용할 셰이더 마지막에 선택 # ====================== sel = cmds.ls(sl=True) if len(sel) < 2: cmds.warning("오브젝트와 셰이더를 모두 선택하세요. (순서: 오브젝트들 → 셰이더)") else: shader = sel[-1] # 마지막 선택 = 셰이더 objects = sel[:-1] # 나머지 = 대상 오브젝트들 # 셰이더에 연결된 쉐이딩그룹 찾기 sg_list = cmds.listConnections(shader, type="shadingEngine") or [] if not sg_list: # 쉐이딩그룹이 없으면 새로 생성 shading_group = cmds.sets(renderable=True, noSurfaceShader=True, empty=True, name=f"{shader}SG") cmds.connectAttr(f"{shader}.outColor", f"{shading_group}.surfaceShader", f=True) print(f"'{shader}'에 새 쉐이딩그룹 '{shading_group}' 생성 및 연결 완료.") else: shading_group = sg_list[0] print(f"적용할 쉐이딩그룹: {shading_group}") threshold = 0.1 # Y축 평행 허용치 all_faces = [] # 전체 선택용 리스트 for obj in objects: # 메시 확인 shapes = cmds.listRelatives(obj, s=True, ni=True) or [] if not shapes: print(f"'{obj}'은(는) 메시 오브젝트가 아닙니다. 건너뜀.") continue # 메시 데이터 접근 dag = om.MSelectionList() dag.add(shapes[0]) mesh = om.MFnMesh(dag.getDagPath(0)) # Y축 평행 면 찾기 faces = [ f"{obj}.f[{i}]" for i in range(mesh.numPolygons) if abs(mesh.getPolygonNormal(i, om.MSpace.kWorld).y) < threshold ] if faces: all_faces.extend(faces) print(f"{obj}에서 {len(faces)}개 면 선택됨.") else: print(f"{obj}에서 Y축 평행 면 없음.") # 면이 하나라도 있으면 셰이더 적용 if all_faces: cmds.select(all_faces, r=True) cmds.hyperShade(assign=shading_group) print(f"\n✅ 총 {len(all_faces)}개 면에 '{shader}' 셰이더 적용 완료!") else: cmds.warning("Y축 평행한 면을 찾지 못했습니다.")

그런데 너무 편한것만 찾으면 결국 그에 대한 반대작용도 있기 마련. 스캔 데이터처럼 너무 복잡한 메쉬 구조로 된 오브젝트를 여러개 일괄 처리하고자 이런 스크립트를 실행하면 컴퓨터가 다운되거나 마야 프로그램이 다운 될 수도 있다. 그러니 적당히 사용해야할 듯.

  




0 comments:

댓글 쓰기

Next 이전 게시물