Maya -> Houdini -> Maya

소개



Houdini Advent Calendar 2017의 갑작스러운 내용 변경으로, 빙글빙글인 것은 용서해 주세요.
누설 같은 곳이라든지 보충(이미지)라든지 나중에 수정하겠습니다.

내용은 Maya -> Houdini -> Maya에서 가져갈 때의 이야기로, 마지막으로 Maya로 렌더링 할 필요가있는 경우 등에 Maya로 가져와 원래의 머티리얼 등을 한 번에 다시 할당하여 레던링 할 수있는 준비 를 할 수 있도록 하는 부분을 스크립트로 구조 만들어 버리자는 녀석. (이므로, 단면이나 Houdini에서 발생한 것에 관해서는 이번은 제외)
이런 방식도 있는 몸으로 포착해 주시면.

마야



이 흐름에서 규칙 지정은 다음과 같습니다.
  • Shape 이름은 마지막에 반드시 "Shape"라고 붙인다
  • 오리지널의 지오메트리라고 하는 것으로, 「 <なんたら>_model 」라고 Namespace 붙여 넣는다. 그런 다음 "<なんたら>_from_houdini"라고 말하는 것도 확실합니다.
    <なんたら>:ROOT
        |-- <なんたら>_model:ROOT
        |-- <なんたら>_from_houdini:ROOT
    

    이상

    Maya -> Houdini



    우선 보통 Alembic 파일을 내보냅니다.

    Houdini



    Alembic SOP로 로드합니다.
    이때 Geometry > Primitive Groups를 Name Group Using Shape Node Name으로 전환합니다.



    그러면, Alembic을 Unpack했을 때에, Maya에서의 Shape명이 그대로 Houdini상에서 Group 애트리뷰트로 재현된다.

    로드하면 후는 Houdini상에서 좋아하게 작업을 실시하는 것이지만, 중요한 것은, 이 Shape 그룹을 내보내기까지 계속 유지하는 것! !
    나중에 사용하기 때문에 부서지지 않도록 작업한다.

    특히 주의하는 것이, Voronoi SOP등을 디폴트인 채 사용하거나 하면, outside의 Group을 만들지만, 이것이 Shape의 Group과 겹쳐 버려, 내보낼 때 outside가 우선되어 인식되어 버릴 가능성이 이기 위하여.
    만들어도 좋지만, 작업 후에는 그 Group은 삭제하는 것.

    Maya에게 가져 가기 전에 보유하고있는 Shape 그룹을 Python SOP를 사용하여 Primitive의 path 속성으로 추가합니다.

    Python_SOP
    import re
    
    node = hou.pwd()
    geo = node.geometry()
    
    path_attrib = geo.addAttrib(hou.attribType.Prim, 'path', '')
    
    instance = hou.node('..').name()
    base = 'base'
    name = 'name'
    
    for prim in geo.prims():
        grps = prim.groups()
        for grp in grps:
            name = grp.name()
            base = re.split(r'Shape$', grp.name())[0]
    
            path_name = '/' + instance + '/' + base + '/' + name
    
            prim.setAttribValue(path_attrib, path_name)
    

    이를 통해 내보내기를 수행합니다.

    ROP Alembic Output에서 다음 설정을 수행합니다.
  • Use SOP Path: ON
  • Build Hierarchy From Attribute: ON
  • Path Attribute: path



  • 내보내기를 하기 위해서 이하도 마찬가지로 주의해 둔다.
  • 필요없는 Group은 모두 삭제
  • 필요없는 Attribute는 모두 삭제 (Maya에서 사용할 예정이없는 한 기본 버린다.
  • Maya에는 Point 개념이 없으므로 필요한 것은 Vertex에 Promote 해 둡니다.

    결국 이런 느낌의 노드 구성.
    내보내기처럼 이런 작업용과 분리된 네트워크를 준비하는 것이 요시.



    Houdini -> Maya



    원래 모델이 있는 장면에 Alembic 파일을 가져옵니다.

    임포트하면 「Export한 네트워크의 이름 > 각각의 Shape명」으로서 전개된다.
    그리고는 이것에 머티리얼을 해 가는데, 데이터 정리도 함께 해 둔다.
    <なんたら>:ROOT
        |-- <なんたら>_model:ROOT
        |-- <なんたら>_from_houdini:ROOT # Houdiniからimportしてきたやつをここに突っ込む
                |-- <Imported Alembic Cache>
    

    그래도 어딘가의 스크립트를 실행하여 오리지널 지오메트리에서 머티리얼을 재할당한다.

    reassign_material.py
    import re
    
    # マテリアルをオリジナルのやつと同じ名前のやつからひっぱってきてセット
    def matchMat(rshape, houshape):
        material = cmds.listConnections(houshape, sh=True)[0]
        if material:
            cmds.sets(houshape, forceElement=material)
            return True
        else:
            return False
    
    # Shapeアトリビュートを一致させる。Arnoldとかこういうの必要。
    def matchAttr(rshape, houshape):
        attrs = cmds.listAttr(rshape)
        for attr in attrs:
            houshape_attr = houshape + '.' + attr
            if not cmds.ls(houshape_attr):
                continue
            rshape_attr = rshape + '.' + attr
    
            try:
                value = cmds.getAttr(rshape_attr, silent=True)
                cmds.setAttr(houshape_attr, value)
            except:
                pass
    
    # オリジナルの方をHIDE
    def switchVisibility(rshape, houshape):
        cmds.showHidden(houshape)
    
        transform = re.split(r'Shape$', rshape)[0]
        try:
            cmds.hide(transform)
        except:
            print('%s is not found.'%(transform))
    
    
    def main():
        cache_roots = cmds.ls(r'*_model:ROOT', type='transform')
    
        # Show top of effect_cache roots
        if cache_roots:
            cmds.showHidden(cache_roots, above=True)
    
        for root in cache_roots:
            print('===== Excuting reassigning shaders of "%s" ====='%(root))
            houshapes = cmds.ls(cmds.listRelatives(root), dag=True, type='mesh')
            asset = re.split(r'_from_houdini:ROOT', root)[0]
    
            # Namespaces that are pared with from_houdini.
            nsps = [asset+'_model']
    
            for houshape in houshapes:
                result = None
                for nsp as nps:
                    rshape = nsp + ':' + re.split(r':',houshape)[1]
                    if not cmds.ls(rshape):
                        continue
    
                    result = matchMat(rshape, houshape)
                    matchAttr(rshape, houshape)
                    switchVisibility(rshape, houshape)
    
                if not result:
                    print('Material for "%s" is missing. Assigning material is skipped.'%(houshape))
    
    

    스크립트 편집기에서 할 때 모든 것을 치고 main ()으로 호출하십시오.

  • 좋은 웹페이지 즐겨찾기