def fixedCamera(render_cam, frame): ''' Create an fgshooter camera fixed at the render camera's position for a spcified frame. ''' # Not the best way to get the world position and rotation values out of the render_camera... but it works. # Pymel's matrix.rotate and matrix.getRotation() seem to be broken. tmp_node = pm.createNode("decomposeMatrix") render_cam.worldMatrix >> tmp_node.inputMatrix frame_position = [tmp_node.outputTranslateX.get(time = frame), tmp_node.outputTranslateY.get(time = frame), tmp_node.outputTranslateZ.get(time = frame)] frame_rotation = [tmp_node.outputRotateX.get(time = frame), tmp_node.outputRotateY.get(time = frame), tmp_node.outputRotateZ.get(time = frame)] pm.delete(tmp_node) # Create the fixed camera. Change it's wireframe color. fg_cam, fg_cam_shape = pm.camera(name="fgshooterCamera", position=frame_position, rotation=frame_rotation) pm.color(fg_cam, ud=2) # Adjust the fgshooter camera's scale to pass aperture, aspect, and focal length information. aperture = render_cam.horizontalFilmAperture.get(time = frame) aspect = aperture / pm.Attribute("defaultResolution.deviceAspectRatio").get(time = frame) focal = 0.03937 * render_cam.focalLength.get(time = frame) fg_cam.scaleX.set(aperture) fg_cam.scaleY.set(aspect) fg_cam.scaleZ.set(focal) return fg_cam_shape
def currentCamera(render_cam): ''' Create an fgshooter camera at same location as the render camera. ''' # Duplicate the render camera and make sure the duplicate is not renderable. fg_cam = pm.duplicate(render_cam, rr=True, name="fgshooterCamera")[0] fg_cam_shape = fg_cam.getShape() fg_cam_shape.renderable.set(False) # Change the fgshooter camera's wireframe color. pm.color(fg_cam, ud=2) # Find the render camera's transfrom and parent the fgshooter to it. render_cam_transform = render_cam.listRelatives(p=True, type="transform")[0] pm.parent(fg_cam, render_cam_transform) # Pass aperture and aspect information with the fgshooter camera's scale. aperture = render_cam.horizontalFilmAperture.get() aspect = aperture / pm.Attribute("defaultResolution.deviceAspectRatio").get() fg_cam.scaleX.set(aperture) fg_cam.scaleY.set(aspect) # Connect the render camera's focal length to the fgshooter since it could be animated. multiply_divide = pm.createNode("multiplyDivide") multiply_divide.input2X.set(0.03937) render_cam.focalLength >> multiply_divide.input1X multiply_divide.outputX >> fg_cam.scaleZ return fg_cam_shape
def currentCamera(render_cam): ''' Create an fgshooter camera at same location as the render camera. ''' # Duplicate the render camera and make sure the duplicate is not renderable. fg_cam = pm.duplicate(render_cam, rr=True, name="fgshooterCamera")[0] fg_cam_shape = fg_cam.getShape() fg_cam_shape.renderable.set(False) # Change the fgshooter camera's wireframe color. pm.color(fg_cam, ud=2) # Find the render camera's transfrom and parent the fgshooter to it. render_cam_transform = render_cam.listRelatives(p=True, type="transform")[0] pm.parent(fg_cam, render_cam_transform) # Pass aperture and aspect information with the fgshooter camera's scale. aperture = render_cam.horizontalFilmAperture.get() aspect = aperture / pm.Attribute( "defaultResolution.deviceAspectRatio").get() fg_cam.scaleX.set(aperture) fg_cam.scaleY.set(aspect) # Connect the render camera's focal length to the fgshooter since it could be animated. multiply_divide = pm.createNode("multiplyDivide") multiply_divide.input2X.set(0.03937) render_cam.focalLength >> multiply_divide.input1X multiply_divide.outputX >> fg_cam.scaleZ return fg_cam_shape
def maketwistJoints(self, parentJnt, nTwistJoint, rotAxis): prefix = name.removeSuffix(parentJnt) parentJntChild = pm.listRelatives(parentJnt, c=1, type='joint')[0] # make twist joints twistJntGrp = pm.group(n=prefix + 'TwistJoint_GRP', p=self.twistJointsMainGrp, em=1) twistParentJnt = pm.duplicate(parentJnt, n=prefix + 'TwistStart_JNT', parentOnly=True)[0] twistChildJnt = pm.duplicate(parentJntChild, n=prefix + 'TwistEnd_JNT', parentOnly=True)[0] # adjust twist joints origJntRadius = pm.getAttr(parentJnt + '.radius') for j in [twistParentJnt, twistChildJnt]: pm.setAttr(j + '.radius', origJntRadius * 2) pm.color(j, ud=1) pm.parent(twistChildJnt, twistParentJnt) pm.parent(twistParentJnt, twistJntGrp) # attach twist joints pm.pointConstraint(parentJnt, twistParentJnt) # make IK handle twistIk = pm.ikHandle(n=prefix + 'TwistJoint_IKH', sol='ikSCsolver', sj=twistParentJnt, ee=twistChildJnt)[0] pm.hide(twistIk) pm.parent(twistIk, twistJntGrp) pm.parentConstraint(parentJntChild, twistIk) pm.hide(twistParentJnt) innerJointList = self.makeInnerTwistJoints(prefix, twistParentJnt, twistChildJnt, nTwistJoint, rotAxis) pm.parent(innerJointList, twistJntGrp) # Constriant twistJoint group to main Joint pm.parentConstraint(parentJnt, twistJntGrp, mo=True)
def createLinkedCrv( *curves ): ''' update : 2015-04-24 ''' if curves: pm.select( curves ) curves = pm.selected() if not curves: raise #curves = pm.filterExpand( sm=9 ) #curves = [ pm.PyNode(curve) for curve in curves ] linkedCrvs = [] for curve in curves: # 입력된 커브의 트랜스폼 노드의 히아라키 위치를 맞춰줌 linkedCrv = pm.group(em=True) parent = curve.getParent() if parent: linkedCrv.setParent(space, r=True) linkedCrv.setMatrix( curve.getMatrix( ws=True ), ws=True ) # 피봇 위치 맞춤 rotatePiv = curve.getRotatePivot( space='world' ) scalePiv = curve.getScalePivot( space='world' ) linkedCrv.setRotatePivot( rotatePiv, ws=True ) linkedCrv.setScalePivot( scalePiv, ws=True ) # 커브 쉐입 생성 linkedCrvShape = pm.createNode('nurbsCurve', p=linkedCrv ) # 연결 : 핵심 ! curve.getShape().worldSpace[0] >> linkedCrvShape.create # 컬러 변경 pm.color( linkedCrvShape, ud=1 ) # 이름 변경 linkedCrv.rename( curve+'_linkedCrv#') linkedCrvs.append( linkedCrv ) pm.select(linkedCrvs) return linkedCrvs
def fixedCamera(render_cam, frame): ''' Create an fgshooter camera fixed at the render camera's position for a spcified frame. ''' # Not the best way to get the world position and rotation values out of the render_camera... but it works. # Pymel's matrix.rotate and matrix.getRotation() seem to be broken. tmp_node = pm.createNode("decomposeMatrix") render_cam.worldMatrix >> tmp_node.inputMatrix frame_position = [ tmp_node.outputTranslateX.get(time=frame), tmp_node.outputTranslateY.get(time=frame), tmp_node.outputTranslateZ.get(time=frame) ] frame_rotation = [ tmp_node.outputRotateX.get(time=frame), tmp_node.outputRotateY.get(time=frame), tmp_node.outputRotateZ.get(time=frame) ] pm.delete(tmp_node) # Create the fixed camera. Change it's wireframe color. fg_cam, fg_cam_shape = pm.camera(name="fgshooterCamera", position=frame_position, rotation=frame_rotation) pm.color(fg_cam, ud=2) # Adjust the fgshooter camera's scale to pass aperture, aspect, and focal length information. aperture = render_cam.horizontalFilmAperture.get(time=frame) aspect = aperture / pm.Attribute( "defaultResolution.deviceAspectRatio").get(time=frame) focal = 0.03937 * render_cam.focalLength.get(time=frame) fg_cam.scaleX.set(aperture) fg_cam.scaleY.set(aspect) fg_cam.scaleZ.set(focal) return fg_cam_shape
def rigLimbCmd( prefix='leg_', suffix=None, side=LEFT_SIDE, hasStretch=False, hasFootRoll=False, footRollMode=FOOTROLL_AUTO ): suffix = suffix or ('_l','_r')[side] exp_template = "" labels = { 'control' : prefix + 'control' + suffix, 'aimControl' : prefix + 'aim' + suffix, 'ik' : prefix + 'ik' + suffix, 'ikEnd' : prefix + 'ik_end' + suffix, 'expression' : prefix + 'control' + suffix + '_EXP', 'guideJointIk' : prefix + 'ik_guide_', 'guideJoint' : prefix + 'guide_', 'ikStretch' : prefix + 'ik_stretch' + suffix, 'locStart' : prefix + 'loc_start' + suffix, 'locMid' : prefix + 'loc_mid' + suffix, 'locEnd' : prefix + 'loc_end' + suffix, 'locGuide' : prefix + 'loc_guide' + suffix, 'ikGuide' : prefix + 'ik_guide' + suffix, } try: start_joint, end_joint = pm.ls(sl=1,type="joint") except ValueError: raise ValueError, "Select the start and end joints to setup." mid_joint = end_joint.getParent() parent_joint = start_joint.getParent() unit_scale = start_joint.getRotatePivot(ws=1)[-1] # -- positions and length start_point = start_joint.getRotatePivot(ws=1) * unit_scale end_point = end_joint.getRotatePivot(ws=1) * unit_scale mid_point = mid_joint.getRotatePivot(ws=1) * unit_scale length = start_point.distanceTo( end_point ) # -- Create Control control = createNurbsShape( labels['control'], 'sphere', size=length*.2 ) control2 = createNurbsShape( labels['control'], 'locator', size=length*.3 ) pm.parent( control2.getShape(), control, r=1, s=1 ) pm.delete( control2 ) control.translate.set( end_point ) pm.makeIdentity( control, apply=True, s=0, r=0, t=1, n=0 ) control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 ) control.addAttr( "orientBlend", at='double', k=1, dv=0, min=0, max=1 ) # -- Create Aim Control v1 = end_point - start_point v2 = mid_point - start_point v3 = v1.cross( v2 ) v4 = v3.cross( v1 ) aim_point = start_point + ( v4.normal() * length * 1.5 ) aim_control = createNurbsShape( labels['aimControl'], 'arrow', size=length/5 ) pm.xform( aim_control, t=aim_point ) pm.makeIdentity( apply=True, s=0, r=0, t=1, n=0 ) pm.aimConstraint( mid_joint, aim_control, weight=1, aimVector=(0, 0, 1) ) # -- Create Aim Line aim_line = pm.curve( name=labels['aimControl']+'_line', d=1, p=[aim_point, mid_point], k=[0, 1] ) line_cluster0, line_handle0 = pm.cluster( aim_line+'.cv[0]', n=labels['aimControl']+'_line_0', en=1, rel=1 ) line_cluster1, line_handle1 = pm.cluster( aim_line+'.cv[1]', n=labels['aimControl']+'_line_1', en=1, rel=1 ) pm.pointConstraint( aim_control, line_handle0, offset=(0,0,0), weight=1 ) pm.pointConstraint( mid_joint, line_handle1, offset=(0,0,0), weight=1 ) line_group0 = pm.group( line_handle0, name=line_handle0.name() + "_grp" ) line_group1 = pm.group( line_handle1, name=line_handle0.name() + "_grp" ) pm.parent( [aim_line, line_group0, line_group1, aim_control] ) line_group0.v.set(0) line_group1.v.set(0) setAttrs( line_group0, ['t','r','s','v'], lock=1 ) setAttrs( line_group1, ['t','r','s','v'], lock=1 ) setAttrs( aim_line, ['t','r','s','v'], lock=1 ) aim_line.overrideEnabled.set(1) aim_line.overrideDisplayType.set(1) if hasStretch: guide_ik_start = pm.duplicate( start_joint, rc=1 )[0] guide_ik_mid, guide_ik_end = pm.ls( guide_ik_start, dag=1 )[1:3] for n in pm.ls( guide_ik_start, dag=1 ): pm.rename( n, labels['guideJointIk'] + n[:-1] ) guide_start = pm.duplicate( start_joint, rc=1 )[0] guide_mid, guide_end = pm.ls( guide_start, dag=1 )[1:3] for n in pm.ls( guide_start, dag=1 ): pm.rename( n, labels['guideJoint'] + n[:-1] ) parent_group = pm.group( name=labels['ikStretch'], em=1 ) if parent_joint is not None: parent_group.setRotatePivot( parent_joint.getRotatePivot(ws=1) * unit_scale, ws=1 ) pm.parentConstraint( parent_joint, parent_group, weight=1 ) pm.parent( guide_ik_start, guide_start, parent_group ) # -- build a temp joint chain to get loc_mid position loc_start = pm.group( n=labels['locStart'], em=1 ) pm.parent( loc_start, parent_group ) loc_start.setRotatePivot( start_joint.getRotatePivot( ws=1) * unit_scale, ws=1 ) pm.aimConstraint( control, loc_start, weight=1, aimVector=(1,0,0) ) loc_end = pm.group( n=labels['locEnd'], em=1, parent=loc_start ) loc_end.setRotatePivot( start_joint.getRotatePivot( ws=1) * unit_scale, ws=1 ) pm.pointConstraint( control, loc_end, offset=(0,0,0), skip=('y','z'), weight=1 ) pm.select(cl=1) temp_start = pm.joint( p=start_point ) temp_end = pm.joint( p=end_point ) pm.joint( temp_start, edit=1, oj='xyz', secondaryAxisOrient='yup', ch=1 ) pm.pointConstraint( mid_joint, temp_end, offset=(0,0,0), skip=('y','z'), weight=1 ) loc_mid_point = temp_end.getRotatePivot(ws=1) * unit_scale pm.delete( temp_start ) # -- create the mid locator loc_mid = pm.group( n=labels['locMid'], em=1)#spaceLocator() loc_mid.translate.set( loc_mid_point ) pm.makeIdentity( apply=True, s=0, r=0, t=1, n=0 ) pm.pointConstraint( loc_start, loc_mid, mo=1, weight=1 ) pm.pointConstraint( loc_end, loc_mid, mo=1, weight=1 ) # -- create the guide locator loc_guide = pm.group( n=labels['locGuide'], em=1) guide_constraint = pm.pointConstraint( loc_mid, loc_guide, offset=(0,0,0), weight=1 ) pm.pointConstraint( guide_ik_mid, loc_guide, offset=(0,0,0), weight=1 ) pm.parent( loc_mid, loc_guide, parent_group ) guide_ik, guide_ee = pm.ikHandle( sj=guide_ik_start, ee=guide_ik_end, solver="ikRPsolver", dh=1 ) pm.poleVectorConstraint( aim_control, guide_ik, weight=1 ) pm.delete( guide_ik_end ) pm.rename( guide_ik, labels['ikGuide'] ) # -- SET STRETCH BLEND START guide_ik.addAttr( "stretchStart", at='double', k=1 ) guide_ik.stretchStart.set( loc_end.tx.get() ) # -- SET STRETCH BLEND END guide_ik.addAttr( "stretchEnd", at='double', k=1 ) guide_ik.stretchEnd.set( loc_end.tx.get()*1.1 ) # -- SET STRETCH BLEND END guide_ik.addAttr( "stretchFactor", at='double', k=1 ) guide_ik.stretchFactor.set( 0.22 ) # -- setup guide joints pm.aimConstraint( loc_guide, guide_start, weight=1, aimVector=(1,0,0) ) pm.aimConstraint( loc_end, guide_mid, weight=1, aimVector=(1,0,0) ) pm.pointConstraint( loc_guide, guide_mid, offset=(0,0,0), skip=('y','z'), weight=1 ) pm.pointConstraint( loc_end, guide_end, offset=(0,0,0), skip=('y','z'), weight=1 ) pm.parent( guide_ik, loc_end ) pm.parent( guide_ik, control ) # -- add stretch addtributes start_joint.addAttr( "stretch", at='double', k=1, dv=0 ) mid_joint.addAttr( "stretch", at='double', k=1, dv=0 ) control.addAttr( "stretchBlend", at='double', k=1, dv=0, min=0, max=1 ) # -- build the expression exp_template += EXP_STRETCH \ % { 'guide_ik' : guide_ik, 'loc_end' : loc_end, 'constraint' : guide_constraint, # -- we only need these names for the constraint attribute names 'guide_ik_mid' : guide_ik_mid.split('|')[-1], 'loc_mid' : loc_mid.split('|')[-1], 'control' : control, 'start_joint' : start_joint, 'mid_joint' : mid_joint, 'end_joint' : end_joint, 'guide_mid' : guide_mid, 'guide_end' : guide_end, } # -- make things look pretty for n in pm.ls( [ parent_group, guide_ik ], dag=1 ): n.visibility.set(0) for obj in guide_end.getChildren( type='joint' ): try: pm.delete( obj ) except: pass # -- hook up the original joints main_ik, main_ee = pm.ikHandle( sj=start_joint, ee=end_joint, solver="ikRPsolver", dh=1 ) pm.poleVectorConstraint( aim_control, main_ik, weight=1 ) pm.rename( main_ik, labels['ik'] ) end_ik, end_ee = pm.ikHandle( sj=end_joint, ee=end_joint.getChildren(type='joint')[0], solver="ikRPsolver", dh=1 ) pm.rename( end_ik, labels['ikEnd'] ) pm.parent( main_ik, end_ik, control ) # -- fill out the expression template exp_template += EXP_IKFK + EXP_VIS exp_str = exp_template \ % { #'guide_ik' : guide_ik, #'loc_end' : loc_end, #'constraint' : guide_constraint, #we only need these names for the constraint attribute names #'guide_ik_mid' : guide_ik_mid.split('|')[-1], #'loc_mid' : loc_mid.split('|')[-1], 'control' : control, 'start_joint' : start_joint, 'mid_joint' : mid_joint, 'end_joint' : end_joint, #'guide_mid' : guide_mid, #'guide_end' : guide_end, 'main_ik' : main_ik, 'end_ik' : end_ik, 'shape1' : control.getChildren(type="nurbsCurve")[0], 'shape2' : control.getChildren(type="nurbsCurve")[1], } pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' ) if hasFootRoll: rigFootRoll( end_joint, control, prefix, suffix, side=side, footRollMode=footRollMode ) resetIkSetupCmd(end_joint, control) resetIkSetupCmd(start_joint, aim_control) # -- make things look pretty for n in pm.ls( control, dag=1, type="transform" )[1:]: if n.type() != "transform": n.visibility.set(0) setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) setAttrs( aim_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) pm.setAttr(control.v, keyable=0 ) pm.setAttr(aim_control.v, keyable=0 ) addToSet( [control, aim_control], 'controlsSet' ) pm.select( [control, aim_control], r=1 ) pm.color( ud=(CntlColors.left, CntlColors.right)[side] ) control.displayHandle.set(1) pm.select( control, r=1 ) pm.reorder( control.getShape(), back=1 ) return [ control, aim_control ]
def rigHeadCmd( prefix='head_', suffix='', hasStretch=True ): exp_template = EXP_HEAD labels = { 'control' : prefix + 'control' + suffix, 'aimControl' : prefix + 'aim' + suffix, 'ik' : prefix + 'ik' + suffix, 'ikEnd' : prefix + 'ik_end' + suffix, 'parent' : prefix + 'parent' + suffix, 'expression' : prefix + 'control' + suffix + '_EXP', 'parent' : prefix + 'parent' + suffix, 'pivot' : prefix + 'pivot' + suffix, } try: start_joint = pm.ls(sl=1,type="joint")[0] except ValueError: raise ValueError, "Select the root joint to setup." end_joint = start_joint.getChildren(type='joint')[0] neck_joint = start_joint.getParent() parent_joint = neck_joint.getParent() if neck_joint is None: raise ValueError, "Start joint must have a parent joint (neck)." if parent_joint is None: raise ValueError, "Start joint parent must have a parent transform (spine)." unit_scale = start_joint.getRotatePivot(ws=1)[-1] start_point = start_joint.getRotatePivot(ws=1) * unit_scale end_point = end_joint.getRotatePivot(ws=1) * unit_scale mid_point = ( start_point + end_point ) / 2 length = start_point.distanceTo( end_point ) aim_point = Vector( start_point[0], start_point[1], start_point[1])*100 # -- build controls control = createNurbsShape( labels['control'], width=length, height=length*1.2, depth=length*1.1 ) control.translate.set( mid_point ) pm.makeIdentity( control, apply=True, t=1 ) control.rotatePivot.set( start_joint.getRotatePivot(ws=1) * unit_scale ) control.scalePivot.set( start_joint.getRotatePivot(ws=1) * unit_scale ) control.selectHandle.set( start_joint.getRotatePivot(ws=1) * unit_scale ) control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 ) control.addAttr( "aimBlend", at='double', k=1, dv=0, min=0, max=1 ) # -- build aim control aim_control = createNurbsShape( labels['aimControl'], 'arrow', size=length/1.5 ) aim_control.translate.set( aim_point ) pm.makeIdentity( aim_control, apply=True, t=1 ) pm.aimConstraint( start_joint, aim_control, weight=1, aimVector=(0, 0, 1) ) # -- Create Aim Line aim_line = pm.curve( name=labels['aimControl']+'_line', d=1, p=[aim_point, mid_point], k=[0, 1] ) line_cluster0, line_handle0 = pm.cluster( aim_line+'.cv[0]', n=labels['aimControl']+'_line_0', en=1, rel=1 ) line_cluster1, line_handle1 = pm.cluster( aim_line+'.cv[1]', n=labels['aimControl']+'_line_1', en=1, rel=1 ) pm.pointConstraint( aim_control, line_handle0, offset=(0,0,0), weight=1 ) pm.pointConstraint( start_joint, line_handle1, offset=(0,0,0), weight=1 ) line_group0 = pm.group( line_handle0, name=line_handle0.name() + "_grp" ) line_group1 = pm.group( line_handle1, name=line_handle0.name() + "_grp" ) pm.parent( [aim_line, line_group0, line_group1, aim_control] ) line_group0.v.set(0) line_group1.v.set(0) setAttrs( line_group0, ['t','r','s','v'], lock=1 ) setAttrs( line_group1, ['t','r','s','v'], lock=1 ) setAttrs( aim_line, ['t','r','s','v'], lock=1 ) aim_line.overrideEnabled.set(1) aim_line.overrideDisplayType.set(1) # -- build helper groups pivot_grp = pm.group( n=labels['pivot'], em=1 ) parent_grp = pm.group( pivot_grp, n=labels['parent'] ) parent_grp.translate.set( control.getRotatePivot(ws=1) * unit_scale ) pm.makeIdentity( parent_grp, apply=True, t=1 ) pivot_grp.rotateOrder.set(2) # -- create ik handles main_ik, main_ee = pm.ikHandle( n=labels['ik'], sj=neck_joint, ee=end_joint, sol='ikRPsolver', dh=1 ) #main_ik, main_ee = pm.ikHandle( n=labels['ik'], sj=neck_joint, ee=start_joint, sol='ikRPsolver', dh=1 ) #end_ik, end_ee = pm.ikHandle( n=labels['ikEnd'], sj=start_joint, ee=end_joint, sol='ikSCsolver', dh=1 ) pm.parent( main_ik, control ) pm.parent( control, pivot_grp ) # -- set up constraints #pm.aimConstraint( control, aim_control, weight=1, aimVector=(0, 0, -1), mo=1 ) pm.aimConstraint( aim_control, pivot_grp, weight=1, aimVector=(0, 0, 1), mo=1 ) pm.setKeyframe( pivot_grp.r ) pm.parentConstraint( parent_joint, parent_grp, weight=1, mo=1 ) resetIkSetupCmd(start_joint, control) resetIkSetupCmd(start_joint, aim_control) exp_str = exp_template \ % { 'control' : control, 'start_joint' : start_joint, 'end_joint' : end_joint, 'parent_joint' : parent_joint, 'main_ik' : main_ik, #'end_ik' : end_ik, 'pivot' : pivot_grp, 'shape' : control.getShape(), } pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' ) # -- make things look pretty for n in pm.ls( [main_ik], dag=1, type="transform" ): n.visibility.set(0) control.displayHandle.set(1) addToSet( [control, aim_control], 'controlsSet' ) setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) setAttrs( aim_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) pm.setAttr(control.v, keyable=0 ) pm.setAttr(aim_control.v, keyable=0 ) pm.select( [control,aim_control], r=1 ) pm.color( ud=CntlColors.head ) return [ control, aim_control ]
def rigSpineCmd( prefix='spine_', suffix='', hasStretch=False, worldSpace=False ): exp_template = '' labels = { 'end_control' : prefix + 'control_end' + suffix, 'mid_control' : prefix + 'control_mid' + suffix, 'ik' : prefix + 'ik' + suffix, 'curve' : prefix + 'curve' + suffix, 'cluster' : prefix + 'cluster' + suffix, 'clusters' : prefix + 'clusters' + suffix, 'parent' : prefix + 'parent' + suffix, 'expression' : prefix + 'controls' + suffix + '_EXP', } try: start_joint, end_joint = pm.ls(sl=1,type="joint") except ValueError: raise ValueError, "Select the start and end joints to setup." parent_joint = start_joint.getParent() mid_joint = start_joint.getChildren(type='joint')[0] if parent_joint is None: raise ValueError, "Start joint must have a parent transform." main_ik, main_ee, main_curve = pm.ikHandle( n=labels['ik'], sj=start_joint, ee=end_joint, sol='ikSplineSolver', pcv=True, numSpans=1, dh=1 ) main_curve.rename( labels['curve'] ) cluster0, handle0 = pm.cluster( main_curve+'.cv[0]', main_curve+'.cv[1]', n=labels['cluster']+'0', en=1, rel=1 ) cluster1, handle1 = pm.cluster( main_curve+'.cv[1]', main_curve+'.cv[2]', n=labels['cluster']+'1', en=1, rel=1 ) cluster2, handle2 = pm.cluster( main_curve+'.cv[4]', n=labels['cluster']+'2', en=1, rel=1 ) start_point = start_joint.getRotatePivot(ws=1) * start_joint.getRotatePivot(ws=1)[-1] end_point = end_joint.getRotatePivot(ws=1) * end_joint.getRotatePivot(ws=1)[-1] handle1_point = handle1.getRotatePivot(ws=1) * handle1.getRotatePivot(ws=1)[-1] length = start_point.distanceTo( end_point ) # -- build controls control = pm.circle( n=labels['end_control'], radius=(length / 2), normal=(0,1,0), ch=0 )[0] control.translate.set( end_point ) control.rotateOrder.set(1) mid_control = pm.circle( n=labels['mid_control'], radius=(length / 2), normal=(0,1,0), ch=0 )[0] mid_control.translate.set( handle1_point ) pm.makeIdentity( [ control, mid_control ], apply=True, s=0, r=0, t=1, n=0 ) # -- add control attributes control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 ) # -- constrain controls pm.pointConstraint( control, handle2, offset=(0,0,0), weight=1 ) pm.aimConstraint( handle1, control, weight=1, aimVector=(0,-1,0), skip='y' ) pm.pointConstraint( mid_control, handle1, offset=(0,0,0), weight=1 ) pm.aimConstraint( handle0, mid_control, weight=1, aimVector=(0,1,0) ) if worldSpace: pm.pointConstraint( parent_joint, handle0, maintainOffset=1, weight=1 ) # -- group and parent nodes cluster_group = pm.group( handle0, handle1, handle2, name=labels['clusters'] ) parent_group = pm.group( name=labels['parent'], em=1 ) parent_group.rotatePivot.set( parent_joint.getRotatePivot(ws=1) ) pm.parent( control, mid_control, main_ik, main_curve, cluster_group, parent_group ) if not worldSpace: pm.parentConstraint( parent_joint, parent_group, w=1, mo=1 ) if hasStretch: control.addAttr( "stretch", at='double', k=1, dv=0, min=-1, max=1 ) exp_template += EXP_SPINE_STRETCH exp_template += EXP_SPINE exp_str = exp_template \ % { 'control' : control, 'start_joint' : start_joint, 'end_joint' : end_joint, 'mid_joint' : mid_joint, 'parent_joint' : parent_joint, 'main_ik' : main_ik, 'shape' : control.getShape(), 'mid_shape' : mid_control.getShape(), } pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' ) resetIkSetupCmd(end_joint, control) # -- make things look pretty for n in pm.ls( [main_ik, main_curve, cluster_group], dag=1, type="transform" ): n.visibility.set(0) addToSet( [control, mid_control], 'controlsSet' ) control.displayHandle.set(1) setAttrs( control, ['rx','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) setAttrs( mid_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) pm.setAttr(control.v, keyable=0 ) pm.setAttr(mid_control.v, keyable=0 ) pm.color( ud=CntlColors.center ) pm.select( control, r=1 ) return [ control, mid_control ]
def rigRootCmd( prefix='root_', seperate_rotation=False, rotate_prefix='pelvis_' ): labels = { 'control' : prefix + 'control', 'rotateControl' : rotate_prefix + 'control' } try: start_joint = pm.ls(sl=1,type="joint")[0] except ValueError: raise ValueError, "Select the root joint to setup." start_point = start_joint.getRotatePivot(ws=1) * start_joint.getRotatePivot(ws=1)[-1] control = pm.circle( n=labels['control'], radius=(start_point[1] / .035), normal=(0,1,0), ch=0 )[0] control2 = createNurbsShape( labels['rotateControl'], width=( start_point[1] / .025), height=(start_point[1] / .045), depth=( start_point[1] / .035), ) control.translate.set( start_point ) control2.translate.set( start_point ) if not seperate_rotation: pm.parent( control2.getShape(), control, r=1, s=1 ) pm.delete( control2 ) else: pm.parent( control2, control ) pm.makeIdentity( control2, apply=True, s=0, r=0, t=1, n=0 ) pm.makeIdentity( control, apply=True, s=0, r=0, t=1, n=0 ) pm.pointConstraint( control, start_joint, offset=(0,0,0), weight=1 ) if not seperate_rotation: pm.orientConstraint( control, start_joint, weight=1, mo=1 ) else: pm.orientConstraint( control2, start_joint, weight=1, mo=1 ) control.displayHandle.set(1) addToSet( [control], 'controlsSet' ) setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) pm.setAttr(control.v, keyable=0 ) pm.select( control, r=1 ) pm.color( ud=CntlColors.center ) pm.reorder( control.getShape(), back=1 ) if seperate_rotation: addToSet( [control2], 'controlsSet' ) setAttrs( control2, ['t','s'], channelBox=0, keyable=0, lock=1 ) pm.setAttr(control2.v, keyable=0 ) pm.select( control2, add=1 ) pm.color( ud=CntlColors.center ) return pm.ls(sl=1)
def rigFootRoll( foot_joint, control, prefix, suffix=None, side=LEFT_SIDE, footRollMode=FOOTROLL_AUTO ): suffix = suffix or ('_l','_r')[side] exp_template = "" labels = { 'expression' : prefix + 'control' + suffix + '_EXP', 'ikToe' : prefix + 'ik_toe' + suffix, 'pivotBall' : prefix + 'pivot_ball' + suffix, 'pivotToe' : prefix + 'pivot_toe' + suffix, 'rotateToe' : prefix + 'rotate_toe' + suffix, 'pivotHeel' : prefix + 'pivot_heel' + suffix, } handles = control.getChildren(type='ikHandle') if len(handles) == 3: guide_ik, main_ik, end_ik = handles else: main_ik, end_ik = handles guide_ik = None toe_joint, heel_joint = foot_joint.getChildren( type='joint' )[:2] end_joint = toe_joint.getChildren( type='joint' )[0] toe_length = toe_joint.translate.get().length() heel_length = heel_joint.translate.get().length() pm.select( toe_joint, end_joint, r=1 ) toe_ik, toe_ee = pm.ikHandle( name=labels['ikToe'], sol='ikRPsolver', dh=1 ) # -- add pivot groups pivot_ball = createNurbsShape( labels['pivotBall'], shape='U', size=toe_length ) pivot_ball.translate.set( toe_joint.getRotatePivot(ws=1)/100 ) pivot_ball.ty.set( pivot_ball.ty.get() + toe_length/2 ) pivot_ball.rotate.set(-90,90,0) pm.makeIdentity(pivot_ball, apply=True, translate=True, rotate=True, scale=True) pivot_ball.setRotatePivot( toe_joint.getRotatePivot(ws=1), ws=1 ) if guide_ik: pm.parent( main_ik, guide_ik, pivot_ball ) else: pm.parent( main_ik, pivot_ball ) pivot_toe = createNurbsShape( labels['pivotToe'], shape='U', size=toe_length ) pivot_toe.translate.set( end_joint.getRotatePivot(ws=1)/100 ) pm.makeIdentity(pivot_toe, apply=True, translate=True, rotate=True, scale=True) pm.parent( pivot_ball, end_ik, pivot_toe ) rotate_toe = pm.group( toe_ik, n=labels['rotateToe'] ) rotate_toe.setRotatePivot( toe_joint.getRotatePivot(ws=1), ws=1 ) pivot_heel = createNurbsShape( labels['pivotHeel'], shape='U', size=heel_length ) pivot_heel.translate.set( heel_joint.getRotatePivot(ws=1)/100 ) pivot_heel.ry.set(180) pm.makeIdentity(pivot_heel, apply=True, translate=True, rotate=True, scale=True) pm.parent( pivot_toe, rotate_toe, pivot_heel ) pm.parent( pivot_heel, control ) exp_str = pm.expression( labels['expression'], query=1, s=1 ) # -- fill out the expression template exp_template += EXP_FOOT_IKFK exp_str += exp_template \ % { 'toe_ik' : toe_ik, 'end_ik' : end_ik } if footRollMode == FOOTROLL_AUTO: control.addAttr( "footRoll", sn="fr", at='double', k=1, dv=0, min=-10, max=20 ) control.addAttr( "toeRotate", sn="tr", at='double', k=1, dv=0 ) control.tr >> rotate_toe.rx # -- Set Driven Keys pm.setDrivenKeyframe( pivot_toe.rx, cd=control.fr, dv=10, v=0, ott='linear' ) pm.setDrivenKeyframe( pivot_toe.rx, cd=control.fr, dv=20, v=60, itt='linear' ) pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=0, v=0, ott='linear' ) pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=10, v=60, itt='linear' ) pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=20, v=0, itt='linear' ) pm.setDrivenKeyframe( pivot_heel.rx, cd=control.fr, dv=0, v=0, ott='linear' ) pm.setDrivenKeyframe( pivot_heel.rx, cd=control.fr, dv=-10, v=-40, itt='linear' ) elif footRollMode == FOOTROLL_CONTROLS: for obj in pm.ls( control, dag=1, type="nurbsCurve" ): addToSet( [obj.getParent()], 'controlsSet' ) exp_template += EXP_FOOT_IKFK exp_str += EXP_FOOT_IKFK_CONTROLS \ % { 'heel_pivot_shape' : pivot_heel.getShape(), 'ball_pivot_shape' : pivot_ball.getShape(), 'toe_pivot_shape' : pivot_toe.getShape(), 'end_ik' : end_ik } else: #footRollMode == FOOTROLL_ATTRIBUTES control.addAttr( "heelPivot", sn="hp", at='double', k=1, dv=0 ) control.addAttr( "ballPivot", sn="bp", at='double', k=1, dv=0 ) control.addAttr( "toePivot", sn="tp", at='double', k=1, dv=0 ) control.addAttr( "toeRotate", sn="tr", at='double', k=1, dv=0 ) control.hp >> pivot_heel.rx control.bp >> pivot_ball.rx control.tp >> pivot_toe.rx control.tr >> rotate_toe.rx for obj in pm.ls( control, dag=1, type="transform" ): shape = obj.getShape() if shape is not None: pm.reorder(shape, back=1) if obj != control: setAttrs( obj, ['t','s'], channelBox=0, keyable=0, lock=1 ) if footRollMode != FOOTROLL_CONTROLS: setAttrs( obj, ['r'], channelBox=1, keyable=0, lock=0 ) obj.visibility.set(0) obj.v.set( channelBox=0, keyable=0 ) pm.select( obj, r=1 ) pm.color( ud=(CntlColors.left, CntlColors.right)[side] ) pm.expression( labels['expression'], edit=1, s=exp_str )
def calcMidPoint(planeLoc, geo): originalSelect = pm.ls(sl=True) sel = om.MSelectionList() sel.add(planeLoc) dag = sel.getDagPath(0) planeTransform = om.MFnTransform(dag) planePoint = om.MVector(planeTransform.translation(om.MSpace.kWorld)) planeNormal = om.MVector.kZaxisVector * planeTransform.transformation( ).asMatrix() sel = om.MSelectionList() sel.add(geo) dag = sel.getDagPath(0) mesh = om.MFnMesh(dag) edgeIt = om.MItMeshEdge(dag) polygonIt = om.MItMeshPolygon(dag) intesectList = {} while not edgeIt.isDone(): vtxA = mesh.getPoint(edgeIt.vertexId(0), om.MSpace.kWorld) vtxB = mesh.getPoint(edgeIt.vertexId(1), om.MSpace.kWorld) A = om.MVector(vtxA) B = om.MVector(vtxB) result = intersectEdgePlane(planePoint, planeNormal, A, B) onBoudary = edgeIt.onBoundary() if result: #doLoc ('center1', result) intesectList[edgeIt.index()] = [result, onBoudary] edgeIt.next() if intesectList == {}: return allSortedEdges = [] sortedEdges = [] edgeIt.reset() remainedEdges = intesectList.keys() count = len(remainedEdges) boundary = [x for x in remainedEdges if intesectList[x][1] == True] if boundary: i = boundary[0] isClosed = False else: i = remainedEdges[0] isClosed = True while not count == 0: sortedEdges.append(i) remainedEdges.remove(i) edgeIt.setIndex(i) connectedFaces = edgeIt.getConnectedFaces() nextEdge = [] for f in connectedFaces: polygonIt.setIndex(f) connectedEdges = polygonIt.getEdges() a = [x for x in connectedEdges if x in remainedEdges] if a: i = a[0] nextEdge.append(i) if nextEdge: i = nextEdge[0] else: allSortedEdges.append([sortedEdges, isClosed]) if remainedEdges: boundary = [ x for x in remainedEdges if intesectList[x][1] == True ] if boundary: i = boundary[0] isClosed = False else: i = remainedEdges[0] isClosed = True sortedEdges = [] count -= 1 for loop in allSortedEdges: maxD = -100000.0 minD = 100000.0 minIndex = 0 maxIndex = 0 for vtx in loop[0]: vtxPoint = om.MVector(intesectList[vtx][0]) if maxD < vtxPoint.length(): maxD = vtxPoint.length() maxIndex = vtx if minD > vtxPoint.length(): minD = vtxPoint.length() minIndex = vtx p1 = om.MVector(intesectList[maxIndex][0]) p2 = om.MVector(intesectList[minIndex][0]) c = (p1 + p2) / 2 d = om.MVector(planePoint - c) distTreshold = .5 if d.length() < distTreshold: v1 = om.MVector(p1 - c) v2 = v1 ^ planeNormal p3 = c + v2.normal() * v2.length() p4 = c - v2.normal() * v2.length() crv = pm.curve(n='clipCurve', d=1, p=(p1, p3, p2, p4, p1), k=(0, 1, 2, 3, 4)) loc = doLoc('center1', c) pm.color(crv, rgb=(1, 0, 0)) pm.color(loc, rgb=(0, 1, 0)) pm.select(originalSelect)
def offsetCamera(render_cam, offset): ''' Create an fgshooter camera offset from the render camera by a few frames. ''' # Create camera and change wireframe color. fg_cam, fg_cam_shape = pm.camera(name = "fgshooterCamera") pm.color(fg_cam, ud=2) # Create all the connection nodes we are going to need. decompose_matrix = pm.createNode("decomposeMatrix") multiply_divide = pm.createNode("multiplyDivide") frame_cache_tx = pm.createNode("frameCache") frame_cache_ty = pm.createNode("frameCache") frame_cache_tz = pm.createNode("frameCache") frame_cache_rx = pm.createNode("frameCache") frame_cache_ry = pm.createNode("frameCache") frame_cache_rz = pm.createNode("frameCache") frame_cache_fl = pm.createNode("frameCache") # Connect all of those nodes to the render camera. render_cam.worldMatrix >> decompose_matrix.inputMatrix decompose_matrix.outputTranslateX >> frame_cache_tx.stream decompose_matrix.outputTranslateY >> frame_cache_ty.stream decompose_matrix.outputTranslateZ >> frame_cache_tz.stream decompose_matrix.outputRotateX >> frame_cache_rx.stream decompose_matrix.outputRotateY >> frame_cache_ry.stream decompose_matrix.outputRotateZ >> frame_cache_rz.stream render_cam.focalLength >> frame_cache_fl.stream # If the offset is positive, use the future attribute. if offset > 0: # Workaround for a pymel bug offset = ".future[" + str(offset) +"]" pm.Attribute(frame_cache_tx + offset) >> fg_cam.translateX pm.Attribute(frame_cache_ty + offset) >> fg_cam.translateY pm.Attribute(frame_cache_tz + offset) >> fg_cam.translateZ pm.Attribute(frame_cache_rx + offset) >> fg_cam.rotateX pm.Attribute(frame_cache_ry + offset) >> fg_cam.rotateY pm.Attribute(frame_cache_rz + offset) >> fg_cam.rotateZ pm.Attribute(frame_cache_fl + offset) >> multiply_divide.input1X # If the offset is negative, use the past attribute. else: offset = -offset frame_cache_tx.past[offset] >> fg_cam.translateX frame_cache_ty.past[offset] >> fg_cam.translateY frame_cache_tz.past[offset] >> fg_cam.translateZ frame_cache_rx.past[offset] >> fg_cam.rotateX frame_cache_ry.past[offset] >> fg_cam.rotateY frame_cache_rz.past[offset] >> fg_cam.rotateZ frame_cache_fl.past[offset] >> multiply_divide.input1X # Pass aperture, aspect, and focal length infromation with the fgshooter camera's scale. # Focal length is connected because it could be animated. aperture = render_cam.horizontalFilmAperture.get() aspect = aperture / pm.Attribute("defaultResolution.deviceAspectRatio").get() multiply_divide.input2X.set(0.03937) fg_cam.scaleX.set(aperture) fg_cam.scaleY.set(aspect) multiply_divide.outputX >> fg_cam.scaleZ return fg_cam_shape
def offsetCamera(render_cam, offset): ''' Create an fgshooter camera offset from the render camera by a few frames. ''' # Create camera and change wireframe color. fg_cam, fg_cam_shape = pm.camera(name="fgshooterCamera") pm.color(fg_cam, ud=2) # Create all the connection nodes we are going to need. decompose_matrix = pm.createNode("decomposeMatrix") multiply_divide = pm.createNode("multiplyDivide") frame_cache_tx = pm.createNode("frameCache") frame_cache_ty = pm.createNode("frameCache") frame_cache_tz = pm.createNode("frameCache") frame_cache_rx = pm.createNode("frameCache") frame_cache_ry = pm.createNode("frameCache") frame_cache_rz = pm.createNode("frameCache") frame_cache_fl = pm.createNode("frameCache") # Connect all of those nodes to the render camera. render_cam.worldMatrix >> decompose_matrix.inputMatrix decompose_matrix.outputTranslateX >> frame_cache_tx.stream decompose_matrix.outputTranslateY >> frame_cache_ty.stream decompose_matrix.outputTranslateZ >> frame_cache_tz.stream decompose_matrix.outputRotateX >> frame_cache_rx.stream decompose_matrix.outputRotateY >> frame_cache_ry.stream decompose_matrix.outputRotateZ >> frame_cache_rz.stream render_cam.focalLength >> frame_cache_fl.stream # If the offset is positive, use the future attribute. if offset > 0: # Workaround for a pymel bug offset = ".future[" + str(offset) + "]" pm.Attribute(frame_cache_tx + offset) >> fg_cam.translateX pm.Attribute(frame_cache_ty + offset) >> fg_cam.translateY pm.Attribute(frame_cache_tz + offset) >> fg_cam.translateZ pm.Attribute(frame_cache_rx + offset) >> fg_cam.rotateX pm.Attribute(frame_cache_ry + offset) >> fg_cam.rotateY pm.Attribute(frame_cache_rz + offset) >> fg_cam.rotateZ pm.Attribute(frame_cache_fl + offset) >> multiply_divide.input1X # If the offset is negative, use the past attribute. else: offset = -offset frame_cache_tx.past[offset] >> fg_cam.translateX frame_cache_ty.past[offset] >> fg_cam.translateY frame_cache_tz.past[offset] >> fg_cam.translateZ frame_cache_rx.past[offset] >> fg_cam.rotateX frame_cache_ry.past[offset] >> fg_cam.rotateY frame_cache_rz.past[offset] >> fg_cam.rotateZ frame_cache_fl.past[offset] >> multiply_divide.input1X # Pass aperture, aspect, and focal length infromation with the fgshooter camera's scale. # Focal length is connected because it could be animated. aperture = render_cam.horizontalFilmAperture.get() aspect = aperture / pm.Attribute( "defaultResolution.deviceAspectRatio").get() multiply_divide.input2X.set(0.03937) fg_cam.scaleX.set(aperture) fg_cam.scaleY.set(aspect) multiply_divide.outputX >> fg_cam.scaleZ return fg_cam_shape