def jointChainOrient( objs=[] ): # wip ''' update : 2015-04-29 ''' if objs: pm.selec(objs) objs = pm.ls(sl=True, o=True) if not objs: raise joints = pm.ls(sl=True, type='joint') if not joints: raise upMeshs = [] if pm.filterExpand(sm=12): upMeshs = [pm.PyNode(c) for c in pm.filterExpand(sm=12) ] # 업축으로 사용할 메쉬 # 조인트 오리엔트 조정: 메쉬의 가장 가까운 점의 노말을 조인트의 up으로 설정 if upMeshs: for jnt in joints: parentJnt = jnt.getParent() if parentJnt: # point에서 가장 가까운 Vertex의 Normal을 up으로 설정 pos = parentJnt.getTranslation( ws=True) vtx = getClosestVertexOnMesh( upMeshs[0], pos ) pos = vtx.getPosition() norm = vtx.getNormal() upPos = pos + norm * 1000000 # 노말 위치가 가까우면 방향이 틀어져 버림.. 그래서 큰 수를 곱함. upLoc = pm.spaceLocator(n='parentJnt_upLoc#') upLoc.t.set( upPos ) jntOrient( [parentJnt, jnt, upLoc] ) #pm.joint( parentJnt, edit=True, zso=True, oj='xyz', sao='yup' ) pm.delete( upLoc ) else: for jnt in joints: parentJnt = jnt.getParent() if parentJnt and parentJnt.type()=='joint': print jnt up = pm.spaceLocator() grandParent = parentJnt.getParent() if grandParent and grandParent.type()=='joint': pm.delete( pm.parentConstraint( grandParent, up ) ) else: pm.delete( pm.parentConstraint( parentJnt, up ) ) jntOrient( [parentJnt, jnt, up], worldUpType='objectrotation' ) pm.refresh() pm.select(jnt) pm.delete(up) # 끝 조인트 오리엔트 조정 if len(joints)>1: pm.joint( joints[-1], edit=True, oj='none' )
def crvToJnt( objs=[], div=None, ep=True ): ''' update : 2015-04-27 curve, upMesh 순으로 선택하고 실행 div 를 명시하면 일정간격의 조인트를 얻음. import rig.joint as jnt jnt.crvToJnt() jnt.crvToJnt(ep=False) # 해당 없음. 커브 cv 위치에 조인트가 생김 jnt.crvToJnt(div=10) jnt.crvToJnt(ep=True) # 해당 없음. 커브 ep 위치에 조인트가 생김 jnt.crvToJnt(ep=False) # 해당 없음. 커브 cv 위치에 조인트가 생김 jnt.crvToJnt(div=10, ep=True) # 해당 없음. 커브 cv 위치에 조인트가 생김 jnt.crvToJnt(div=10, ep=False) # 해당 없음. 커브 cv 위치에 조인트가 생김 ''' # args if objs: pm.selec(objs) objs = pm.selected() if not objs: raise curves = [pm.PyNode(c) for c in pm.filterExpand(sm=9) ] if not curves: raise upMeshs = [] if pm.filterExpand(sm=12): upMeshs = [pm.PyNode(c) for c in pm.filterExpand(sm=12) ] # 업축으로 사용할 메쉬 node = curves[-1] nodeType = node.nodeType() #cv = True #ep = True transform = None crvShape = None if nodeType == 'nurbsCurve': crvShape = node transform = crvShape.getParent() elif nodeType == 'transform': transform = node crvShape = transform.getShapes( type='nurbsCurve' )[0] if div: rebCrv, rebuild = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 ) # curvature type transform = rebCrv crvShape = transform.getShapes( type='nurbsCurve' )[0] # 위치값 챙김. p=[] if div: if ep: for i in range(div+1): # 커브를 일정하게 나눈 위치 값을 가져옴 p.append( pm.pointOnCurve( crvShape, turnOnPercentage=True, parameter=(1.0/div)*i ) ) else: rebuild.rebuildType.set(0) # uniform rebuild.spans.set(div+1) for i in range( len( rebCrv.getCVs() ) ): p.append( crvShape.cv[i].getPosition() ) else: if ep: # editPoint의 위치값을 가져옴 for i in range( crvShape.numEPs() ): p.append( pm.xform( crvShape.ep[i], q=True, ws=True, t=True) ) else: # cv의 위치값을 가져옴 for i in range( len( crvShape.getCVs() ) ): p.append( crvShape.cv[i].getPosition() ) if div: pm.delete( transform ) JNTs = [] pm.select(cl=True) for pos in p: JNTs.append( pm.joint( p=pos) ) # 조인트 오리엔트 조정: 메쉬의 가장 가까운 점의 노말을 조인트의 up으로 설정 if upMeshs: for jnt in JNTs: parentJnt = jnt.getParent() if parentJnt: # point에서 가장 가까운 Vertex의 Normal을 up으로 설정 pos = parentJnt.getTranslation( ws=True) vtx = getClosestVertexOnMesh( upMeshs[0], pos ) pos = vtx.getPosition() norm = vtx.getNormal() upPos = pos + norm * 1000000 # 노말 위치가 가까우면 방향이 틀어져 버림.. 그래서 큰 수를 곱함. upLoc = pm.spaceLocator(n='parentJnt_upLoc#') upLoc.t.set( upPos ) jntOrient( [parentJnt, jnt, upLoc] ) #pm.joint( parentJnt, edit=True, zso=True, oj='xyz', sao='yup' ) pm.delete( upLoc ) else: for jnt in JNTs: parentJnt = jnt.getParent() if parentJnt: up = pm.spaceLocator() grandParent = parentJnt.getParent() if grandParent: pm.delete( pm.parentConstraint( grandParent, up ) ) else: pm.delete( pm.parentConstraint( parentJnt, up ) ) jntOrient( [parentJnt, jnt, up], worldUpType='objectrotation' ) pm.refresh() pm.select(jnt) pm.delete(up) # 끝 조인트 오리엔트 조정 pm.joint( JNTs[-1], edit=True, oj='none' ) pm.select( JNTs ) return JNTs
def crvToJnt( curves=[], div=None, ep=True ): ''' update : 2015-04-29 ''' # args if curves: pm.selec(curves) curves = [pm.PyNode(c) for c in pm.filterExpand(sm=9) ] if not curves: raise node = curves[-1] nodeType = node.nodeType() transform = None crvShape = None if nodeType == 'nurbsCurve': crvShape = node transform = crvShape.getParent() elif nodeType == 'transform': transform = node crvShape = transform.getShapes( type='nurbsCurve' )[0] if div: rebCrv, rebuild = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 ) # curvature type transform = rebCrv crvShape = transform.getShapes( type='nurbsCurve' )[0] # 위치값 챙김. p=[] if div: if ep: for i in range(div+1): # 커브를 일정하게 나눈 위치 값을 가져옴 p.append( pm.pointOnCurve( crvShape, turnOnPercentage=True, parameter=(1.0/div)*i ) ) else: rebuild.rebuildType.set(0) # uniform rebuild.spans.set(div+1) for i in range( len( rebCrv.getCVs() ) ): p.append( crvShape.cv[i].getPosition() ) else: if ep: # editPoint의 위치값을 가져옴 for i in range( crvShape.numEPs() ): p.append( pm.xform( crvShape.ep[i], q=True, ws=True, t=True) ) else: # cv의 위치값을 가져옴 for i in range( len( crvShape.getCVs() ) ): p.append( crvShape.cv[i].getPosition() ) if div: pm.delete( transform ) JNTs = [] pm.select(cl=True) for pos in p: JNTs.append( pm.joint( p=pos) ) # 조인트 오리엔트 디폴트 pm.joint( JNTs[0], e=True, oj='xyz', secondaryAxisOrient='yup', ch=True, zso=True ) pm.select( JNTs ) return JNTs