def createTimeNetwork(self, control=None, name=None, numJnts=None): ''' Mel expression that gets base value for sine rig. Uses control attributes: amplitude, speed Results in control attribute: time_sine_value Also sets up direction switch counter for offset motion. ''' s = "// Expression: amplitude * ( sin(time*speed) )\n" s += 'float $last_frame = %s.last_frame;\n' % control s += 'float $offset = %s.time_offset;\n' % control s += "float $amp = %s.amplitude;\n" % control s += "float $speed = %s.speed;\n" % control s += "%s.time_sine_value = $amp * sin((time + $offset) * $speed);\n" % control s += '\n// Switch counter incrementation\n' s += 'float $sw_count = %s.switch_count;\n' % control s += 'if($offset > 0)\n' s += '{ if((`currentTime -query` % $offset) == 0)\n' s += ' { if( $last_frame < `currentTime -query` )\n' s += ' { %s.switch_count = $sw_count + 1;}\n' % control s += ' else{ %s.switch_count = $sw_count - 1;}\n' % control s += ' }\n' s += ' if($sw_count > %s)\n' % numJnts s += ' { %s.switch_count = 1; }\n' % control s += '}\n' s += '\n// Store value in Last_Frame\n' s += '%s.last_frame = frame;\n' % control pm.expression(name='%s_SineRig_exp' % name, s=s)
def setSlide(*args): State.refresh() State.dump() for obj in State._selectedObjects: for axis in ['X', 'Y', 'Z']: pm.expression(name=State._makeExprName(obj, axis), string=State._makeExpr(obj, axis))
def create_frustum_curve(camera): """Creates a curve showing the frustum of the given camera :param camera: :return: """ if isinstance(camera, pm.nt.Transform): camera_tranform = camera camera = camera_tranform.getShape() elif isinstance(camera, pm.nt.Camera): camera_tranform = camera.getParent() # validate the camera if not isinstance(camera, pm.nt.Camera): raise RuntimeError('Please select a camera') # create the outer box frame_curve = pm.curve(d=1, p=[(-0.5, 0.5, 0), (0.5, 0.5, 0), (0.5, -0.5, 0), (-0.5, -0.5, 0), (-0.5, 0.5, 0)], k=[0, 1, 2, 3, 4]) pm.parent(frame_curve, camera_tranform, r=True) # transform the frame curve frame_curve.tz.set(-10.0) exp = """float $flen = {camera}.focalLength; float $hfa = {camera}.horizontalFilmAperture * 25.4; {curve}.sx = {curve}.sy = -{curve}.translateZ * $hfa/ $flen;""".format( camera=camera.name(), curve=frame_curve.name()) pm.expression(s=exp, o='', ae=1, uc="all") return frame_curve
def camera_focus_plane_tool(): """sets up a focus plane for the selected camera """ camera = pm.ls(sl=1)[0] camera_shape = camera.getShape() frame = pm.nurbsPlane( n='focusPlane#', p=(0, 0, 0), ax=(0, 0, 1), w=1, lr=1, d=1, u=1, v=1, ch=0 )[0] frame_shape = frame.getShape() pm.parent(frame, camera, r=True) #transform the frame surface frame.tz.set(-10.0) exp = """float $flen = %(camera)s.focalLength; float $hfa = %(camera)s.horizontalFilmAperture * 25.4; %(frame)s.sx = -%(frame)s.translateZ * $hfa/ $flen; %(frame)s.sy = %(frame)s.sx / defaultResolution.deviceAspectRatio; %(camera)s.focusDistance = -%(frame)s.tz; %(camera)s.aiFocusDistance = %(camera)s.focusDistance; %(camera)s.aiApertureSize = %(camera)s.focalLength / %(camera)s.fStop * 0.1; """ % { 'camera': camera_shape.name(), 'frame': frame.name() } pm.expression(s=exp, ae=1, uc="all") # set material surface_shader = pm.shadingNode('surfaceShader', asShader=1) pm.select(frame) pm.hyperShade(a=surface_shader.name()) surface_shader.setAttr('outColor', (0.4, 0, 0)) surface_shader.setAttr('outTransparency', (0.5, 0.5, 0.5)) # prevent it from being rendered frame_shape.setAttr('castsShadows', 0) frame_shape.setAttr('receiveShadows', 0) frame_shape.setAttr('motionBlur', 0) frame_shape.setAttr('primaryVisibility', 0) frame_shape.setAttr('smoothShading', 0) frame_shape.setAttr('visibleInReflections', 0) frame_shape.setAttr('visibleInRefractions', 0) # Arnold attributes frame_shape.setAttr('aiSelfShadows', 0) frame_shape.setAttr('aiVisibleInDiffuse', 0) frame_shape.setAttr('aiVisibleInGlossy', 0) # hide unnecessary attributes frame.setAttr('tx', lock=True, keyable=False) frame.setAttr('ty', lock=True, keyable=False) frame.setAttr('rx', lock=True, keyable=False) frame.setAttr('ry', lock=True, keyable=False) frame.setAttr('rz', lock=True, keyable=False) frame.setAttr('sx', lock=True, keyable=False) frame.setAttr('sy', lock=True, keyable=False) frame.setAttr('sz', lock=True, keyable=False)
def completeStretchySetup( expr, expressionNode, characterNode, curveInfoNodeBack ): pymelLogger.debug('Starting: completeStretchySetup()...') # if stretchy back is selected # When scaling characterNode character breaks # because the backcurve is also scaling # applying two time scale # we need to edit ikcurve expression and change the scale to # $scale = (curveinfoName).normalizedScale/(characterNode).scaleY; endFirstLineExpr = expr.find('\n') slicedExpr = expr[endFirstLineExpr:] # Edit first line and add the old expression sliced newExpr = '$scale = ' + curveInfoNodeBack + '.normalizedScale/' + characterNode + '.scaleY;\n' newExpr += slicedExpr pm.expression(expressionNode, edit = True, string=newExpr) # To avoid scaling uniformally in x and z # the scale Y attr will drive X and Z pm.connectAttr(characterNode+'.scaleY', characterNode+'.scaleX') pm.connectAttr(characterNode+'.scaleY', characterNode+'.scaleZ') # Now we can lock and hide scale X and Z hideLockAttr(characterNode, lockHideXZ) # Change attr name of Scale Y to name = globalScale # it allows us to still use the scale manipulator # instead of adding a new attr for that pm.aliasAttr('globalScale', characterNode + '.scaleY') pymelLogger.debug('End: completeStretchySetup()...')
def completeStretchySetup(expr, expressionNode, characterNode, curveInfoNodeBack): pymelLogger.debug('Starting: completeStretchySetup()...') # if stretchy back is selected # When scaling characterNode character breaks # because the backcurve is also scaling # applying two time scale # we need to edit ikcurve expression and change the scale to # $scale = (curveinfoName).normalizedScale/(characterNode).scaleY; endFirstLineExpr = expr.find('\n') slicedExpr = expr[endFirstLineExpr:] # Edit first line and add the old expression sliced newExpr = '$scale = ' + curveInfoNodeBack + '.normalizedScale/' + characterNode + '.scaleY;\n' newExpr += slicedExpr pm.expression(expressionNode, edit=True, string=newExpr) # To avoid scaling uniformally in x and z # the scale Y attr will drive X and Z pm.connectAttr(characterNode + '.scaleY', characterNode + '.scaleX') pm.connectAttr(characterNode + '.scaleY', characterNode + '.scaleZ') # Now we can lock and hide scale X and Z hideLockAttr(characterNode, lockHideXZ) # Change attr name of Scale Y to name = globalScale # it allows us to still use the scale manipulator # instead of adding a new attr for that pm.aliasAttr('globalScale', characterNode + '.scaleY') pymelLogger.debug('End: completeStretchySetup()...')
def addC(ctrl, target): ''' Puts a `ctrl` on each child joint of the selected joints Target is a mirror list of the bound joints ''' #expression -e -s "//\njoint5.rotateZ = nurbsCircle21.rotateZ + (nurbsCircle22.rz + nurbsCircle20.rotateZ)*.5;" -o joint5 -ae 1 -uc all expression2; obj = selected()[0] controls = [] groups = [] while obj: c = duplicate(ctrl)[0] c.setParent(obj) c.t.set(0, 0, 0) controls.append(c) spinner = group(em=True) spinner.setParent(obj) spinner.t.set(0, 0, 0) groups.append(spinner) pointConstraint(obj, target) orientConstraint(spinner, target) children = obj.listRelatives(type='joint') if children: obj = children[0] else: obj = None break target = target.listRelatives(type='joint')[0] for i, s in enumerate(groups[2:-2], 2): msg = '{0}.rz = {1[2]}.rz + ( {1[1]}.rz + {1[3]}.rz ) * 0.5 + ( {1[0]}.rz + {1[4]}.rz ) * 0.2;'.format( s, controls[i - 2:i + 3]) expression(s=msg) msg = '{0}.rz = {1[0]}.rz + ( {1[1]}.rz ) * 0.5 + ( {1[2]}.rz ) * 0.2;'.format( groups[0], controls[:3]) expression(s=msg) msg = '{0}.rz = {1[1]}.rz + ( {1[0]}.rz + {1[2]}.rz ) * 0.5 + ( {1[3]}.rz ) * 0.2;'.format( groups[1], controls[:4]) expression(s=msg) msg = '{0}.rz = {1[2]}.rz + ( {1[1]}.rz ) * 0.5 + ( {1[0]}.rz ) * 0.2;'.format( groups[-1], controls[-3:]) expression(s=msg) msg = '{0}.rz = {1[2]}.rz + ( {1[1]}.rz + {1[3]}.rz ) * 0.5 + ( {1[0]}.rz ) * 0.2;'.format( groups[-2], controls[-4:]) expression(s=msg)
def setupTimeSineExp(self, control=None): ''' Create expression that generates si n(time) value and display it on an attribute to drive blendshape expression connect to blendshapes''' s = 'float $speed = %s.speed;\n' % control s += 'float $val = float((abs((frame/$speed) % 10.0))/10.0);\n' s += '%s.time_sine = $val;\n' % (control) pm.expression(name='%s_timeSine_exp', s=s)
def sequin_expression_builder(): control = pm.PyNode('billboardB_lodA_GRP') expr_result = '' for sequin in pm.ls('sequin_row*plate_inst_GEO'): offset = random()*30 expr = '%s.rotateY = sin((time-%s)*%s)*%s;' % (sequin, offset, control.speed, control.amplitude) expr_result+=expr+'\n' pm.expression(s=expr_result, o=control, n='sequin_rotator_EXPR', ae=True, uc='all')
def create_radian_trigger(prefix): prefix = ("%s_radianTrigger") %prefix display = pm.group(empty=True, name="%s_display" %prefix) display.overrideEnabled.set(1) display.overrideDisplayType.set(2) grp = pm.group(empty=True, name="%s_grp" %prefix) loc = pm.spaceLocator(name = "%s_target" %prefix) pm.addAttr(loc, at='double', ln="radical", k=True) pm.addAttr(loc, at='double', ln="angle", k=True) pos = pm.spaceLocator(name = "%s_pos" %prefix) loc.ty.set(1) loc.tz.set(1) pos.tz.set(1) radical_exp = '%s.radical = rad_to_deg( atan2( %s.translateY , %s.translateX ) )' %(loc.name(), loc.name(), loc.name()) angle_exp = "%s.angle = rad_to_deg( acos( %s.translateZ / (sqrt( pow(%s.translateX, 2) + pow(%s.translateY, 2) + pow(%s.translateZ, 2) ) ) ) )" %(loc.name(), loc.name(), loc.name(), loc.name(), loc.name()) pm.expression( o=loc, s= radical_exp, name="%s_radical_exp" %prefix) pm.expression( o=loc, s= angle_exp, name="%s_angle_exp" %prefix) planer_curve = "curve -d 1 -p 0 0 0 -p -1 0 0 -p -0.965926 0.258819 0 -p -0.765926 0.258819 0 -p -0.865926 0.258819 0 -p -0.865926 0.358819 0 -p -0.865926 0.158819 0 -p -0.865926 0.258819 0 -p -0.965926 0.258819 0 -p -0.866025 0.5 0 -p -0.707107 0.707107 0 -p -0.353553 0.353553 0 -p -0.707107 0.707107 0 -p -0.5 0.866025 0 -p -0.258819 0.965926 0 -p 0 1 0 -p 0 0.5 0 -p 0 1 0 -p 0.258819 0.965926 0 -p 0.5 0.866025 0 -p 0.707107 0.707107 0 -p 0.353553 0.353553 0 -p 0.707107 0.707107 0 -p 0.866025 0.5 0 -p 0.965926 0.258819 0 -p 1 0 0 -p 0.5 0 0 -p 1 0 0 -p 0.965926 -0.258819 0 -p 0.866025 -0.5 0 -p 0.707107 -0.707107 0 -p 0.353553 -0.353553 0 -p 0.707107 -0.707107 0 -p 0.5 -0.866025 0 -p 0.258819 -0.965926 0 -p 0 -1 0 -p 0 -0.5 0 -p 0 -1 0 -p -0.258819 -0.965926 0 -p -0.5 -0.866025 0 -p -0.707107 -0.707107 0 -p -0.353553 -0.353553 0 -p -0.707107 -0.707107 0 -p -0.866025 -0.5 0 -p -0.965926 -0.258819 0 -p -0.765926 -0.258819 0 -p -0.965926 -0.258819 0 -p -1 0 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 -k 15 -k 16 -k 17 -k 18 -k 19 -k 20 -k 21 -k 22 -k 23 -k 24 -k 25 -k 26 -k 27 -k 28 -k 29 -k 30 -k 31 -k 32 -k 33 -k 34 -k 35 -k 36 -k 37 -k 38 -k 39 -k 40 -k 41 -k 42 -k 43 -k 44 -k 45 -k 46 -k 47" planer = pm.PyNode(pm.mel.eval(planer_curve)) planer.rename("%s_planer" %prefix) arrow_curve = 'curve -d 1 -p 0 0 0 -p 0 0.377909 0 -p -0.0449662 0.378085 0 -p 0 0.460303 0 -p 0.0449662 0.378085 0 -p 0 0.377909 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 ;' arrow = pm.PyNode(pm.mel.eval(arrow_curve)) pm.makeIdentity(arrow, apply=True, t=True, r=True, s=True) arrow.rename("%s_arrow" %prefix) angle_curves = pm.circle(name="%s_angleCurve" %prefix, r=0.5) pm.aimConstraint(pos, angle_curves[0], mo=False, aimVector=[0,1,0], upVector=[-1,0,0], worldUpType='object', worldUpObject=loc) pm.parent(arrow, angle_curves) loc.angle >> angle_curves[-1].sweep posPointer = pm.curve(name='%s_posPointer'%prefix, d = 1, p = [(0,0,0), (0,0,1)]) pointer = pm.curve(name='%s_targetPointer'%prefix, d = 1, p = [(0,0,0), (0,0,0)]) pointer.inheritsTransform.set(0) cls1 = pm.cluster(pointer.cv[0], name='%s_pointerClusterStart' %prefix) cls2 = pm.cluster(pointer.cv[1], name='%s_pointerClusterEnd' %prefix) pm.parent(pos, planer, angle_curves[0], cls1, pointer, posPointer, display) pm.parent(display, loc, grp) pm.parent(cls2, loc, r=True) cls1[1].v.set(0) cls2[1].v.set(0) pos.v.set(0)
def bspb_frameCounterUpdate(): """ @ update frame counter using heads up display refresh flag. Returns: frame counter update using headsUpDisplay. """ if pm.windows.headsUpDisplay('frameCounterUpdateEXP', q=True, ex=True): pm.delete('frameCounterUpdateEXP') pm.expression(s='headsUpDisplay -r "frameCounterHUD";', n='frameCounterUpdateEXP', ae=1, uc='all')
def curveInfo(): sel = pm.ls(sl = True)[0] curve = pm.arclen(sel, ch = True) print pm.rename(curve, (sel.name() + "_info")) print curve pm.addAttr( sel, longName = "part", attributeType = 'double' ) pm.setAttr( (sel + ".part") , keyable = True ) str =(sel + ".part = " + curve + ".arcLength/8 ;") print str pm.expression(s = str, o = sel, ae = True, uc = "all" , n = (sel + "_part"))
def setExpression(self): if pm.objExists('olp_intervalsPerOrbits_expression'): pm.delete('olp_intervalsPerOrbits_expression') if pm.objExists('olp_orbits_expression'): pm.delete('olp_orbits_expression') interv_int = self.interv_int.value() orbit_int = self.orbit_int.value() intervExpression = pm.expression(o=rigInterv, n='olp_intervalsPerOrbits_expression', s='rx = frame * (360/{0}.000);'.format(interv_int)) if_block = 'rz = (frame/{0}) * ((360/{1}.000)/2.000);'.format(interv_int, orbit_int) orbitExpression = pm.expression(o=rigOrbit, n='olp_orbits_expression', s='if (frame%{0} == 0) {1}'.format(interv_int, if_block))
def bspb_focalLengthUpdate(): """ @ update focal length using headsUpDisplay refresh command. Returns: update focal length. """ if pm.windows.headsUpDisplay('focalLengthUpdateEXP', q=True, ex=True): pm.delete('focalLengthUpdateEXP') pm.expression(s='headsUpDisplay -r "focalLengthHUD";', n='focalLengthUpdateEXP', ae=1, uc='all')
def createNoiseExpressions(self): # Loop over translation (T) and rotation (R) expression_text = '' for noise_type in ['T', 'R']: # Loop over three axes for axis in ['X', 'Y', 'Z']: rand = random.randint(0, 9999) # random seed for each axis noise_exp = 'noise((frame * %s.Frequency_%s%s / 100) + %s.Seed_%s + %d) * %s.Amplitude_%s%s / %s' %(self.control, noise_type, axis, self.control, noise_type, rand, self.control, noise_type, axis, '100' if noise_type == 'T' else '1') jitter_exp = 'noise((frame * 10) + %s.Seed_%s + %d) * %s.Amplitude_%s%s * %s.Jitter_%s / 100' %(self.control, noise_type, rand, self.control, noise_type, axis, self.control, noise_type) final_exp = '((%s) + (%s)) * %s.Noise' %(noise_exp, jitter_exp, self.control) target_attribute = '%s.%s%s' %(self.target, ('translate' if noise_type == 'T' else 'rotate'), axis) expression_text += '%s = %s;\n' %(target_attribute, final_exp) pc.expression(s=expression_text, n='%s_exp'%self.target)
def createGtoViz(self, podPath): ggcp = GtoGeometryCachePod.fromPodFile(podPath) startFrame = ggcp.startFrame endFrame = ggcp.endFrame cacheFilename = ggcp.cacheFilename pm.loadPlugin('TipGtoView', qt=True) gtoViz = pm.createNode('TipGtoView')#, n='%sVizShape_'%curChar) pm.setAttr('%s.filterPolys'%gtoViz, 1) pm.setAttr('%s.filterCurves'%gtoViz, 0) pm.setAttr('%s.filterNURBS'%gtoViz, 0) pm.setAttr('%s.filterPoints'%gtoViz, 0) pm.setAttr('%s.filterPattern'%gtoViz, '*body_ShapeN*') pm.setAttr('%s.cacheStartFrame'%gtoViz, startFrame) pm.setAttr('%s.cacheEndFrame'%gtoViz, endFrame) pm.expression(s='%s.currentTime = frame'%gtoViz) pm.setAttr('%s.animFile'%gtoViz, cacheFilename) if ggcp.hasReference: pm.setAttr('%s.refFile'%gtoViz, ggcp.referenceFilename) else: pm.warning('No reference gto found. GtoViz will be slower.') pm.setAttr('%s.refFile'%gtoViz, cacheFilename) gtoViz.addAttr('originalName', dt="string") gtoViz.addAttr('podFile', dt="string") gtoViz.addAttr('originalSeq', dt="string") gtoViz.addAttr('originalChar', dt="string") pm.setAttr('%s.podFile'%gtoViz, podPath, type="string") curSeq=str(self.animLibComboBox.currentText()) curChar=str(self.characterComboBox.currentText()) pm.setAttr('%s.originalSeq'%gtoViz, curSeq) pm.setAttr('%s.originalChar'%gtoViz, curChar) gtoTrans = gtoViz.listRelatives(p=True)[0] pm.setAttr('%s.scaleX'%gtoTrans, l=True) pm.setAttr('%s.scaleY'%gtoTrans, l=True) pm.setAttr('%s.scaleZ'%gtoTrans, l=True) pm.setAttr('%s.rotateOrder'%gtoTrans, l=True) origName = NAMES_INFO[bdNamingConventions.getCharacterFromPod(podPath)]['fullname'] pm.setAttr('%s.originalName'%gtoViz, origName, type="string") pm.setAttr('%s.label'%gtoViz, origName, type="string") vizName = curChar + '_' + curSeq + '_Viz_' gtoTrans.rename(vizName) updateWindow()
def addNoiseOnControl(Object, Control): if Object.__class__ == list: pass elif Object.__class__ in [str, unicode]: Object = [Object] else: "Not Valid Arguments on Add Noise" return None Expresion = '''//{0} {0}.rotateX=`noise((time+{2})*{1}.frequency)`*{1}.amplitud; {0}.rotateY=`noise((time+{2}+30)*{1}.frequency)`*{1}.amplitud; {0}.rotateZ=`noise((time+{2}+60)*{1}.frequency)`*{1}.amplitud; {0}.ty=`noise((time+{2}+90)*{1}.frequency)`*{1}.movY + {1}.movY; ''' if not isNoiseControl(Control): addAttributes(Control) for eachObject in Object: constraints = constraintComponents(gessFrom=eachObject) ResetGroup = RMRigTools.RMCreateGroupOnObj(eachObject, Type="child") for eachkey in constraints.constraintDic: pm.delete(eachkey) pm.parentConstraint(ResetGroup, constraints.constraintDic[eachkey]["affected"], mo=True) ExpressionNode = pm.expression(name="NoiseMainExpresion", string=Expresion.format( ResetGroup, Control, random.uniform(0, 100)))
def squashLinker(name, ctrlA, ctrlB): ''' Name the control that will be made to handle the sizes of two squash controllers. ''' temp = pdil.dagObj.zero(ctrlA, apply=False, make=False).getParent() aTarget = parentConstraint(temp, q=True, tl=True)[0] temp = pdil.dagObj.zero(ctrlB, apply=False, make=False).getParent() bTarget = parentConstraint(temp, q=True, tl=True)[0] if aTarget.fullPath() in bTarget.fullPath(): child, parent = aTarget, bTarget childCtrl, parentCtrl = ctrlA, ctrlB elif bTarget.fullPath() in aTarget.fullPath(): child, parent = bTarget, aTarget childCtrl, parentCtrl = ctrlB, ctrlA else: raise Exception('Selected controls do not map to related joints') joints = getChain(child, parent) # Get the current distance along the bones to get the 'zeroed' value. total = 0 lengthCalc = '' for j in joints[1:]: total += max([abs(t) for t in j.t.get()]) lengthCalc += 'abs({0}.t{1}) + '.format(j, identifyAxis(j)) lengthCalc = lengthCalc[:-3] ctrl = controllerShape.build(name, {'shape': 'sphere'}) zeroGrp = pdil.dagObj.zero(ctrl) pointConstraint(child, parent, zeroGrp) aimConstraint(child, zeroGrp) pdil.dagObj.lock(ctrl, 's r ty tz') exp = ('{child}.size = 1.0 * ((1.0/ ({length}/{total}) )-1.0) + 1.0*{ctrl}.tx;\n' '{parent}.size = 1.0 * ((1.0/ ({length}/{total}) )-1.0) - 1.0*{ctrl}.tx;') \ .format( child=childCtrl, parent=parentCtrl, ctrl=ctrl, length=lengthCalc, total=total ) print(exp) expression(s=exp)
def assign_special_node(self, dic_nodes, node, attr_name, attr_value): if attr_name == 'animation_curve': curve_node = node curve_node.setPreInfinityType(attr_value[0]) curve_node.setPostInfinityType(attr_value[1]) for idx, value in attr_value[2].items(): pm.setKeyframe(curve_node, f=value[2], v=value[3], itt=value[0], ott=value[1]) return True if attr_name == 'expression': for attr in node.connections(c=1, p=1): attr[0].disconnect() expression_value = attr_value for node_original_name, node_current_name in dic_nodes.items(): expression_value = expression_value.replace('{}.'.format(node_original_name), '{}.'.format(node_current_name.name())) pm.expression(node, s=expression_value, ae=1, uc='all', e=1, o="") return True
def create_frustum_curve(camera): """Creates a curve showing the frustum of the given camera :param camera: :return: """ if isinstance(camera, pm.nt.Transform): camera_tranform = camera camera = camera_tranform.getShape() elif isinstance(camera, pm.nt.Camera): camera_tranform = camera.getParent() # validate the camera if not isinstance(camera, pm.nt.Camera): raise RuntimeError('Please select a camera') # create the outer box frame_curve = pm.curve( d=1, p=[(-0.5, 0.5, 0), (0.5, 0.5, 0), (0.5, -0.5, 0), (-0.5, -0.5, 0), (-0.5, 0.5, 0)], k=[0, 1, 2, 3, 4] ) pm.parent(frame_curve, camera_tranform, r=True) # transform the frame curve frame_curve.tz.set(-10.0) exp = """float $flen = {camera}.focalLength; float $hfa = {camera}.horizontalFilmAperture * 25.4; {curve}.sx = {curve}.sy = -{curve}.translateZ * $hfa/ $flen;""".format( camera=camera.name(), curve=frame_curve.name() ) pm.expression(s=exp, o='', ae=1, uc="all") return frame_curve
def createNoiseExpressions(self): # Loop over translation (T) and rotation (R) expression_text = '' for noise_type in ['T', 'R']: # Loop over three axes for axis in ['X', 'Y', 'Z']: rand = random.randint(0, 9999) # random seed for each axis noise_exp = 'noise((frame * %s.Frequency_%s%s / 100) + %s.Seed_%s + %d) * %s.Amplitude_%s%s / %s' % ( self.control, noise_type, axis, self.control, noise_type, rand, self.control, noise_type, axis, '100' if noise_type == 'T' else '1') jitter_exp = 'noise((frame * 10) + %s.Seed_%s + %d) * %s.Amplitude_%s%s * %s.Jitter_%s / 100' % ( self.control, noise_type, rand, self.control, noise_type, axis, self.control, noise_type) final_exp = '((%s) + (%s)) * %s.Noise' % ( noise_exp, jitter_exp, self.control) target_attribute = '%s.%s%s' % (self.target, ('translate' if noise_type == 'T' else 'rotate'), axis) expression_text += '%s = %s;\n' % (target_attribute, final_exp) pc.expression(s=expression_text, n='%s_exp' % self.target)
def FTV_setupFluidForceRefresh ( fluidShape, atts ): ''' a special expression to force the refresh of the fluid anytime we modify an input''' import re conns = pm.listConnections( fluidShape+'.voxelQuality', s=True, d=False, p=False ) expr = None text = None attributesTrigger = atts[:] #shallow copy if conns is not None and len(conns)>0 and fluidShape.hasAttr('voxelQualityChooser') : if pm.objectType( conns[0], isType='expression' ) == False: raise FTV_msCommandException('The fluid [ '+fluidShape+' ] has an incoming connection in attribute voxelQuality, unable to setup a refresh expression') expr = conns[0] text = pm.expression( expr, q=True, s=True) else: if len(conns)>0: raise FTV_msCommandException('The fluid [ '+fluidShape+' ] has an incoming connection in attribute voxelQuality, unable to setup a refresh expression') if fluidShape.hasAttr('voxelQualityChooser') == False: current = pm.getAttr( fluidShape+'.voxelQuality' ) fluidShape.addAttr( 'voxelQualityChooser', k=True, at='enum', en='faster=1:better=2', dv=current) if text is not None: #let's gather the trigger of refresh inside the expression matches = re.findall(r'.*?\$trigs\[size\(\$trigs\)\]=(.*?);', text ) #$triggers[0]=.I[0]; for m in matches: if re.match( r'\.I\[[0-9]+?\]', m) is None: attributesTrigger.append(m) text = '// Fluid display Refresh expression\n' text += '// you can add triggers here but you have to follow the current syntax\n' text += 'float $trigs[];clear $trigs;\n\n' for i in range(len(attributesTrigger)): text += '$trigs[size($trigs)]='+attributesTrigger[i]+';\n' text += '\n//Result\n' text += 'voxelQuality = voxelQualityChooser;\n' if expr : pm.expression( expr, e=True, s=text, o=fluidShape, ae=False) else: pm.expression( s=text, o=fluidShape, ae=True, n='forceFluidDisplayRefreshExpr#')
def setup_vertigo(camera): """sets up the vertigo for the given camera """ # camera should have the vertigo locator global vertigo_attr_name global vertigo_global_attr_name vertigo_loc = camera.attr(vertigo_attr_name).inputs()[0] # get the initial distance of the vertigo locator z1 = vertigo_loc.tz.get() f1 = camera.focalLength.get() # create a locator under world to hold the locator at the same place world_loc = pm.spaceLocator(n=camera.name() + "vertigo_space_loc#") # connect world_loc to camera if not camera.hasAttr(vertigo_global_attr_name): pm.addAttr(camera, ln=vertigo_global_attr_name, at="message") world_loc.message >> camera.attr(vertigo_global_attr_name) # position the world_loc to the correct place pm.parent(world_loc, vertigo_loc) world_loc.t.set(0, 0, 0) world_loc.r.set(0, 0, 0) pm.parent(world_loc, w=True) # unlock vertigo_loc's translate vertigo_loc.tx.unlock() vertigo_loc.ty.unlock() pm.pointConstraint(world_loc, vertigo_loc) # create the expression expr_str = camera.name() + ".focalLength = (" + vertigo_loc.name() + \ ".tz / " + str(z1) + ") * " + str(f1) + ";" expr = pm.expression(s=expr_str)
def execute(self, *args): try: pm.select(self.myCurve) handSelection = pm.listRelatives(s=True) curveShape = pm.ls(handSelection[0])[0] # ik Handle selektieren -> daraus eine Liste aller "Bind Joints" erstellen ikHandle = pm.listConnections(curveShape, s=True, d=True) ikHandle = pm.ls(ikHandle, type='ikHandle')[0] jointList = pm.ikHandle(ikHandle, q=True, jl=True) curveInfoNode = pm.createNode('curveInfo', n='CurveInfoNode') pm.addAttr(longName='normalizedScale', attributeType='float') curveShape.worldSpace.worldSpace[0] >> curveInfoNode.inputCurve multiplyDivide = pm.createNode('multiplyDivide', n='{}normalizedScale'.format(self.myCurve.name())) multiplyDivide.setAttr('operation', 2) # Wenn Maintain Scale angehakt ist, sollten hier die entsprechenden Operationen stattfinden if pm.checkBox(self.myCheckbox, query=True, value=True)==True: maintainScaleMD = pm.createNode('multiplyDivide', n='maintainScaleMD') maintainScaleMD.setAttr('operation', 2) self.mainController.scale.scaleY >> maintainScaleMD.input2.input2X curveInfoNode.arcLength >> maintainScaleMD.input1.input1X maintainScaleMD.output.outputX >> multiplyDivide.input1.input1X else: curveInfoNode.arcLength >> multiplyDivide.input1.input1X multiplyDivide.setAttr('input2.input2X', multiplyDivide.getAttr('input1.input1X')) multiplyDivide.outputX >> curveInfoNode.normalizedScale expString = '$scale = {}.normalizedScale;\n'.format(curveInfoNode.name()) expString += '$sqrt = 1/sqrt($scale);\n' # Es gilt herauszufinden, mit welcher Achse die Bind Joints auf ihr Child zeigen. # Dazu ermittelt man, ob tx, ty oder tz des zweiten Joints am groessten ist. # In axisActionList wird eingetragen, fuer welchen Translate Wert nachher # die Variable sqrt oder scale verrechnet wird. actionList = ["$sqrt", "$scale"] axisActionList = [ actionList[abs(jointList[1].getAttr(axis)) > 0.00001] for axis in ['tx', 'ty', 'tz'] ] scaleAxis = ['sx', 'sy', 'sz'] for joint in jointList: for i in range(3): expString = "{}{}.{}={};\n".format( expString, joint.name(), scaleAxis[i], axisActionList[i] ) pm.expression(n='{}Exp'.format(self.myCurve.name()), s=expString) # Schliessen des Fensters if CreateStretchSplineClass.win is not None: try: pm.deleteUI(CreateStretchSplineClass.win) except RuntimeError: pass except IndexError: pm.textFieldButtonGrp(self.tFBG, edit=True, placeholderText='Load your Spine Curve first!') except: print(sys.exc_info()[0])
def mip_move_image_plane(imagePlane='', *args, **kwargs): if imagePlane: connections = pm.connectionInfo(imagePlane + '.message', destinationFromSource=True) cam = 'none' for item in connections: if item.split('Shape.')[0] == 'front': cam = 'front' if item.split('Shape.')[0] == 'side': cam = 'side' if item.split('Shape.')[0] == 'top': cam = 'top' if cam != 'none': curve = pm.curve(per=True, d=1, p=[(0.5, 0, 0.5), (0.5, 0, -0.5), (-0.5, 0, -0.5), (-0.5, 0, 0.5), (0.5, 0, 0.5)], k=[0, 1, 2, 3, 4]) if cam == 'front': curve.setRotation((90, 0, 0)) if cam == 'top': curve.setRotation((0, 0, 0)) if cam == 'side': curve.setRotation((90, 90, 0)) pm.setAttr(curve + '.rx', lock=True, keyable=False, channelBox=False) pm.setAttr(curve + '.ry', lock=True, keyable=False, channelBox=False) pm.setAttr(curve + '.rz', lock=True, keyable=False, channelBox=False) pm.setAttr(curve + '.sy', lock=True, keyable=False, channelBox=False) filename = pm.getAttr(imagePlane + '.imageName').split('/')[-1].split('.')[0] pm.rename(curve, 'Mover_' + filename) pm.expression(name=imagePlane + '_expression', s='{0}.displayMode = {1}.visibility * 3'.format( imagePlane, curve)) ratio = 1.0 coverageX = float(pm.getAttr(imagePlane + '.coverageX')) coverageY = float(pm.getAttr(imagePlane + '.coverageY')) size = 1.0 sizeW = float(pm.getAttr(imagePlane + '.width')) sizeH = float(pm.getAttr(imagePlane + '.height')) if sizeW > sizeH: size = sizeW else: size = sizeH if coverageX > coverageY: ratio = coverageX / coverageY x = size z = size / ratio curve.setScale((x, 1, z)) pm.select(curve.cv[0:3]) pm.scale(1.2, 1 + (.2 / ratio), 1) else: ratio = coverageY / coverageX x = size / ratio z = size curve.setScale((x, 1, z)) pm.select(curve.cv[0:3]) pm.scale(1 + (.2 / ratio), 1.2, 1) if pm.mel.getApplicationVersionAsFloat() > 2012: pm.connectAttr(curve.translate, imagePlane + '.imageCenter') else: pm.connectAttr(curve.translate, imagePlane + '.center') pm.connectAttr(curve.scaleX, imagePlane + '.width') pm.connectAttr(curve.scaleZ, imagePlane + '.height') pm.select(curve, replace=True) else: pm.warning('not using the front, side or top camera !!!')
def Create(self, _name, _controlFile, _animationModuleInstance, _lod = 1, _translation = True, _rotation = True, _globalScale = True, _spaceSwitching = False): if _translation == True or _translation == False: translation = [_translation, _translation, _translation] if _rotation == True or _rotation == False: rotation = [_rotation, _rotation, _rotation] self.translation = translation self.rotation = rotation self.globalScale = _globalScale animationModuleName = _animationModuleInstance.moduleNamespace blueprintModuleNameSpace = _animationModuleInstance.blueprintNamespace blueprintModuleUserSpecifiedName = utils.StripAllNamespaces(blueprintModuleNameSpace)[1].partition("__")[2] animationModuleNamespace = "%s:%s" %(blueprintModuleNameSpace, animationModuleName) # import control object #controlObjectFile = "%s/ControlObjects/Animation/%s" %(self.directory, _controlFile) controlObjectFile = "%s/ControlObjects/Animation/%s" %(os.environ["RIGGING_TOOL_ROOT"], _controlFile) pm.importFile(controlObjectFile) self.controlObject = pm.rename("control", "%s:%s" %(animationModuleNamespace, _name)) self.rootParent = self.controlObject self.SetupIconScale(animationModuleNamespace) pm.setAttr("%s.overrideEnabled" %self.controlObject, 1) pm.setAttr("%s.overrideShading" %self.controlObject, 0) pm.connectAttr("%s:module_grp.overrideColor" %animationModuleNamespace, "%s.overrideColor" %self.controlObject) pm.container("%s:module_container" %animationModuleNamespace, edit = True, addNode = self.controlObject, includeHierarchyBelow = True, includeNetwork = True) if _globalScale: pm.connectAttr("%s.scaleY" %self.controlObject, "%s.scaleX" %self.controlObject) pm.connectAttr("%s.scaleY" %self.controlObject, "%s.scaleZ" %self.controlObject) pm.aliasAttr("globalScale", "%s.scaleY" %self.controlObject) attributes = [] if self.translation == [True, True, True]: attributes.append([True, ".translate", "T"]) else: attributes.extend([[translation[0], ".translateX", "TX"], [translation[1], ".translateY", "TY"], [translation[2], ".translateZ", "TZ"]]) if self.rotation == [True, True, True]: attributes.append([True, ".rotate", "R"]) else: attributes.extend([[rotation[0], ".rotateX", "RX"], [rotation[1], ".rotateY", "RY"], [rotation[2], ".rotateZ", "RZ"]]) attributes.append([_globalScale, ".globalScale", "scale"]) for attrInfo in attributes: if attrInfo[0]: attributeNiceName = "%s_%s" %(_name, attrInfo[2]) _animationModuleInstance.PublishNameToModuleContainer("%s%s" %(self.controlObject, attrInfo[1]), attributeNiceName, True) pm.select(self.controlObject, replace = True) pm.addAttr(attributeType = "bool", defaultValue = 1, keyable = True, longName = "display") _animationModuleInstance.PublishNameToModuleContainer("%s.display" %self.controlObject, "display", False) moduleGrp = "%s:module_grp" %animationModuleNamespace visibilityExpression = '%s.visibility = %s.display * (%s.levelOfDetail >= %d);' %(self.controlObject, self.controlObject, moduleGrp, _lod) expression = pm.expression(name = "%s_visibility_expression" %self.controlObject, string = visibilityExpression) utils.AddNodeToContainer("%s:module_container" %animationModuleNamespace, expression) return (self.controlObject, self.rootParent)
import pymel.core as pm axes = ['X', 'Y', 'Z'] translate = ['translate'+x for x in axes] rot = ['rotate'+x for x in axes] scale = ['scale'+x for x in axes] attrs = translate + rot + scale attrs for attr in attrs: pm.expression(s='pCube1.'+attr+ ' = pCube2.'+attr)
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 extendPipe( jointLength=1 ): defaultLength = 3.0 currJnt = '' name = '' root = '' newJnts = [] for sel in pm.selected(): sel.select() # for now, there's no branching, so we find the deepest joint try: currJnt = sel name = currJnt.split('_')[0] root = pm.nt.Joint( '%s_Jnt0' % name ) except: raise "select an object on the pipe that you want to extend" # naming #---------- num = int(currJnt.extractNum()) try: twoPrev = int(currJnt.getParent().getParent().extractNum()) except: twoPrev = num-2 try: prev = int(currJnt.getParent().extractNum()) except: prev = num-1 curr = num new = int(currJnt.nextUniqueName().extractNum()) print "extending from", currJnt, new branchNum = len(currJnt.getChildren()) #print '%s has %s children' % (currJnt, branchNum) if branchNum: print "new segment is a branching joint" currJnt.addAttr( 'pipeLengthInBtwn%s' % branchNum, min=0 ) #currJnt.attr( 'pipeLengthInBtwn%s' % branchNum ).showInChannelBox(1) #print twoPrev, prev, curr, new rigGrp = '%s_RigGrp' % name geoGrp = '%s_GeoGrp' % name # new skeletal joint #--------------------- if new>1: prevJnt = pm.nt.Joint( '%s_Jnt%s' % (name, prev) ) pos = 2*currJnt.getTranslation(ws=1) - prevJnt.getTranslation(ws=1) else: prevJnt = None pos = currJnt.getTranslation(ws=1) + [0,defaultLength,0] newJnt = pm.joint( p=pos, n= '%s_Jnt%s' % (name, new) ) # re-orient the last created joint, which is considered our current joint pm.joint( currJnt, e=1, zeroScaleOrient=1, secondaryAxisOrient='yup', orientJoint='xyz') # pymel method: NEEDS FIXING #currJnt.setZeroScaleOrient(1) #currJnt.setSecondaryAxisOrient('yup') # Flag secondaryAxisOrient can only be used in conjunction with orientJoint flag. #currJnt.setOrientJoint('xyz') newJnt.scale.lock() newJnt.addAttr( 'pipeLength', defaultValue=jointLength, min=.0001 ) newJnt.pipeLength.showInChannelBox(1) newJnt.addAttr( 'pipeLengthInBtwn0', min=0 ) #newJnt.attr( 'pipeLengthInBtwn0' ).showInChannelBox(1) newJnt.addAttr( 'pipeLeadIn', dv=0, min=0 ) newJnt.pipeLeadIn.showInChannelBox(1) newJnt.addAttr( 'radiusMultiplier', dv=1, min=0 ) newJnt.radiusMultiplier.showInChannelBox(1) newJnt.displayHandle = 1 newJnt.radius.showInChannelBox(0) # bend hierarchy #----------------- trans = pm.group( empty=1, n='%s_Elbow%s' % (name, new)) trans.rotateOrder = 1 pm.aimConstraint( currJnt, trans, aimVector = [0, -1, 0], upVector = [-1, 0, 0] ) pm.pointConstraint( newJnt, trans ) trans.setParent( rigGrp ) # keep the end joint oriented along the joint chain so that it can be slid back # and forth to change the length of the current pipe segment pm.delete( pm.orientConstraint( trans, newJnt ) ) # Main Pipe #------------ pipe, pipeHist = pm.polyCylinder( height = 1, radius=1, name = '%s_Geo%s' % (name, new) ) pipeHist = pipeHist.rename( '%s_GeoHist%s' % (name, new) ) pipe.setPivots( [0, -.5, 0], r=1 ) root.globalPipeRadius >> pipe.sx root.globalPipeRadius >> pipe.sz pipeHist.createUVs = 3 # normalize and preserve aspect ratio root.subdivisionsAxis >> pipeHist.subdivisionsAxis # Pipe Connectors #------------- pipeConn1, pipeConnHist1 = pm.polyCylinder( height = .1, radius=1, name = '%s_Connector1AGeo%s' % (name, new) ) pipeConnHist1 = pipeConnHist1.rename( '%s_Connector1AHist%s' % (name, new) ) pipeConn1.setPivots( [0, -.05, 0], r=1 ) pipeConn1.setParent( pipe, relative=True ) pipeConn1.rotate.lock() root.subdivisionsAxis >> pipeConnHist1.subdivisionsAxis pipeConn2, pipeConnHist2 = pm.polyCylinder( height = .1, radius=1, name = '%s_Connector2AGeo%s' % (name, new) ) pipeConnHist2 = pipeConnHist2.rename( '%s_Connector2AHist%s' % (name, new) ) pipeConn2.setPivots( [0, .05, 0], r=1 ) pipeConn2.setParent( pipe, relative=True ) pipeConn2.rotate.lock() root.subdivisionsAxis >> pipeConnHist2.subdivisionsAxis pipeConn1, pipeConnHist1 = pm.polyCylinder( height = .1, radius=1, name = '%s_Connector1BGeo%s' % (name, new) ) pipeConnHist1 = pipeConnHist1.rename( '%s_Connector1BHist%s' % (name, new) ) pipeConn1.setPivots( [0, -.05, 0], r=1 ) pipeConn1.setParent( pipe, relative=True ) pipeConn1.rotate.lock() pipeConn1.visibility = 0 root.subdivisionsAxis >> pipeConnHist1.subdivisionsAxis pipeConn2, pipeConnHist2 = pm.polyCylinder( height = .1, radius=1, name = '%s_Connector2BGeo%s' % (name, new) ) pipeConnHist2 = pipeConnHist2.rename( '%s_Connector2BHist%s' % (name, new) ) pipeConn2.setPivots( [0, .05, 0], r=1 ) pipeConn2.setParent( pipe, relative=True ) pipeConn2.rotate.lock() pipeConn2.visibility = 0 root.subdivisionsAxis >> pipeConnHist2.subdivisionsAxis pipe.setParent( geoGrp ) #constraints pm.pointConstraint( currJnt, pipe ) aim = pm.aimConstraint( newJnt, pipe ) aim.offsetZ = -90 # convert the previous pipe joint into a bendy joint if new > 1: currElbow = pm.PyNode('%s_Elbow%s' % (name, curr) ) pipeLoc = pm.spaceLocator( n= '%s_PipeDummy%s' % (name, new) ) pipeLoc.hide() tweak = pm.group(n='%s_ElbowTweak%s' % (name, new)) tweak.rotateOrder = 2 #tweak.translate = currElbow.translate.get() tweak.setParent( currElbow, r=1 ) pm.aimConstraint( prevJnt, tweak, aimVector = [1, 0, 0], upVector = [0, -1, 0], skip=['z', 'x'] ) # Pipe Joint #------------ pipeJnt, pipeJntHist = pm.polyCylinder( height = 1, radius=1, name = '%s_JntGeo%s' % (name, new), subdivisionsAxis = 20, subdivisionsHeight = 30 ) pipeJnt.setParent( geoGrp ) pipeJnt.sy = jointLength pipeJnt.visibility = 0 pipeJntHist = pipeJntHist.rename( '%s_JntGeoHist%s' % (name, new) ) pipeJntHist.createUVs = 3 # normalize and preserve aspect ratio root.subdivisionsAxis >> pipeJntHist.subdivisionsAxis root.subdivisionsJoint >> pipeJntHist.subdivisionsHeight # constraints pm.parentConstraint( pipeLoc, pipeJnt ) pipeJnt.translate.lock() pipeJnt.rotate.lock() #pipeJnt.scale.lock() aim = pm.PyNode('%s_Elbow%s_aimConstraint1' % (name, curr)) aim.setWorldUpType( 2 ) aim.setWorldUpObject( newJnt ) bend, bendHandle = pm.nonLinear( '%s_JntGeo%s' % (name, new), type='bend' ) bendHandle = pm.nt.Transform(bendHandle).rename( '%s_BendHandle%s' % (name, new) ) bendHandle.sx =.5 bendHandle.hide() bend.rename( '%s_Bend%s' % (name, new) ) pm.parentConstraint( '%s_ElbowTweak%s' % (name, new), bendHandle ) aim = '%s_ElbowTweak%s_aimConstraint1' % (name, new) #aim.worldUpType.set( 1 ) pm.aimConstraint( aim, e=1, worldUpType='object', worldUpObject=newJnt ) bendHandle.setParent(rigGrp) expr = """ float $v1[]; $v1[0] = %(name)s_Elbow%(twoPrev)s.translateX - %(name)s_Elbow%(prev)s.translateX; $v1[1] = %(name)s_Elbow%(twoPrev)s.translateY - %(name)s_Elbow%(prev)s.translateY; $v1[2] = %(name)s_Elbow%(twoPrev)s.translateZ - %(name)s_Elbow%(prev)s.translateZ; float $v2[]; $v2[0] = %(name)s_Elbow%(curr)s.translateX - %(name)s_Elbow%(prev)s.translateX; $v2[1] = %(name)s_Elbow%(curr)s.translateY - %(name)s_Elbow%(prev)s.translateY; $v2[2] = %(name)s_Elbow%(curr)s.translateZ - %(name)s_Elbow%(prev)s.translateZ; float $mag = sqrt ( $v2[0]*$v2[0] + $v2[1]*$v2[1] + $v2[2]*$v2[2] ); float $angleData[] = `angleBetween -v1 $v1[0] $v1[1] $v1[2] -v2 $v2[0] $v2[1] $v2[2] `; float $angle = $angleData[3]; if ( !equivalentTol($angle,180.0, 0.1) ) { float $jointDeg = 180 - $angle; float $jointRad = -1 * deg_to_rad( $jointDeg ); %(name)s_Bend%(curr)s.curvature = $jointRad/2; %(name)s_ElbowTweak%(curr)s.rotateZ = $jointDeg/2; %(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s = %(name)s_Jnt%(prev)s.pipeLength; float $pipeLength = %(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s; float $centerAngleRad = deg_to_rad(90 -$angle/2); float $delta = 0; float $pipeLengthRatio = 1; if ($centerAngleRad > 0.0) { float $radius = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s/ $centerAngleRad; $delta = $radius - ($radius * cos( $centerAngleRad )); $pipeLengthRatio = .5 * $pipeLength / ( $radius * sin( $centerAngleRad ) ); $pipeLength *= $pipeLengthRatio; } %(name)s_PipeDummy%(curr)s.translateX = -1*$delta; %(name)s_BendHandle%(curr)s.scaleX = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s; %(name)s_BendHandle%(curr)s.scaleY = %(name)s_BendHandle%(curr)s.scaleX; %(name)s_BendHandle%(curr)s.scaleZ = %(name)s_BendHandle%(curr)s.scaleX; %(name)s_JntGeo%(curr)s.scaleY = $pipeLength * (1.0+%(name)s_Jnt%(curr)s.pipeLeadIn); %(name)s_JntGeo%(curr)s.scaleX = %(name)s_Jnt0.globalPipeRadius + %(name)s_Jnt0.globalJointRadius; %(name)s_JntGeo%(curr)s.scaleZ = %(name)s_JntGeo%(curr)s.scaleX; %(name)s_JntGeo%(curr)s.visibility = 1; %(name)s_Connector1BGeo%(curr)s.visibility=1; %(name)s_Connector2BGeo%(curr)s.visibility=1; } else { %(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s = 0; %(name)s_JntGeo%(curr)s.scaleY = 0; %(name)s_JntGeo%(curr)s.visibility = 0; %(name)s_Connector1BGeo%(curr)s.visibility=0; %(name)s_Connector2BGeo%(curr)s.visibility=0; } %(name)s_Connector1AGeo%(curr)s.scaleY = %(name)s_Jnt0.globalConnectorThickness * (1/%(name)s_Geo%(curr)s.scaleY); %(name)s_Connector2AGeo%(curr)s.scaleY = %(name)s_Connector1AGeo%(curr)s.scaleY; %(name)s_Connector1AGeo%(curr)s.translateY = -.5 + %(name)s_Connector1AHist%(curr)s.height/2 + .1*%(name)s_Jnt0.globalConnectorOffset; %(name)s_Connector2AGeo%(curr)s.translateY = 0.5 - %(name)s_Connector1AHist%(curr)s.height/2 - .1*%(name)s_Jnt0.globalConnectorOffset; %(name)s_Connector1AGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector1AGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector2AGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector2AGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector1BGeo%(curr)s.scaleY = %(name)s_Jnt0.globalConnectorThickness * (1/%(name)s_Geo%(curr)s.scaleY); %(name)s_Connector2BGeo%(curr)s.scaleY = %(name)s_Connector1BGeo%(curr)s.scaleY; %(name)s_Connector1BGeo%(curr)s.translateY = -.5 + %(name)s_Connector1BHist%(curr)s.height/2 - .1*%(name)s_Jnt0.globalConnectorOffset - .1*%(name)s_Connector1BGeo%(curr)s.scaleY; %(name)s_Connector2BGeo%(curr)s.translateY = 0.5 - %(name)s_Connector1BHist%(curr)s.height/2 + .1*%(name)s_Jnt0.globalConnectorOffset + .1*%(name)s_Connector1BGeo%(curr)s.scaleY; %(name)s_Connector1BGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector1BGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector2BGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector2BGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Geo%(curr)s.scaleY = $mag - .5*%(name)s_Jnt%(curr)s.pipeLengthInBtwn0 - .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s; normalize($v2); %(name)s_Geo%(curr)s_pointConstraint1.offsetX = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s * $v2[0]; %(name)s_Geo%(curr)s_pointConstraint1.offsetY = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s * $v2[1]; %(name)s_Geo%(curr)s_pointConstraint1.offsetZ = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s * $v2[2]; """ % { 'twoPrev' : prev, 'prev' : curr, 'curr' : new, 'new' : new+1, 'name': name, 'branch': branchNum } #print expr print 'editing %s_PipeExpr%s' % (name, new) #expression( '%s_PipeExpr%s' % (name, curr), e=1, s=expr, ae=1 ) pm.expression( s=expr, ae=1, n = '%s_PipeExpr%s' % (name, new) ) # special case for first joint else: expr = """ float $x = %(newJnt)s.tx; float $y = %(newJnt)s.ty; float $z = %(newJnt)s.tz; float $mag = sqrt ( $x*$x + $y*$y + $z*$z ); %(name)s_Geo%(curr)s.sy = $mag - .5*%(newJnt)s.pipeLengthInBtwn0; %(name)s_Connector1AGeo%(curr)s.scaleY = %(name)s_Jnt0.globalConnectorThickness * 1/%(name)s_Geo%(curr)s.scaleY; %(name)s_Connector2AGeo%(curr)s.scaleY = %(name)s_Connector1AGeo%(curr)s.scaleY; %(name)s_Connector1AGeo%(curr)s.translateY = -.5 + %(name)s_Connector1AHist%(curr)s.height/2 + .1*%(name)s_Jnt0.globalConnectorOffset; %(name)s_Connector2AGeo%(curr)s.translateY = 0.5 - %(name)s_Connector1AHist%(curr)s.height/2 - .1*%(name)s_Jnt0.globalConnectorOffset; %(name)s_Connector1AGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector1AGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector2AGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius; %(name)s_Connector2AGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius; """ % { 'newJnt': newJnt, 'curr' : new, 'name': name } print 'creating %s_PipeExpr1' % (name) pm.expression( s=expr, ae=1, n = '%s_PipeExpr1' % (name)) ''' expr = """ %(pipeJnt)s.scaleX = %(root)s.globalPipeRadius + %(root)s.globalJointRadius; %(pipeJnt)s.scaleZ = %(pipeJnt)s.scaleX; """ % { 'pipeJnt': pipeJnt, 'root' : '%s_Jnt0' % (name) } print 'creating %s_PipeExpr%s' % (name, new) expression( s=expr, ae=1, n = '%s_PipeExpr%s' % (name, new)) ''' pipe.translate.lock() pipe.rotate.lock() #pipe.scale.lock() newJnts.append( newJnt ) pm.select(newJnts)
def createCamRig(self, cam=None): # NOTE 创建 Cam_Shaker_GRP 大组 pm.select(cl=1) shaker_grp = "Cam_Shaker_GRP" if not pm.objExists(shaker_grp): shaker_grp = pm.group(n="Cam_Shaker_GRP", w=1) # NOTE 创建 Rig locator ---------------------------------------------------------------- CAM_LOC = pm.spaceLocator(n="CAM_LOC_#") ZROT_ROLL = pm.group(n="ZROT_ROLL_#") XROT_TILT = pm.group(n="XROT_TILT_#") YROT_PAN = pm.group(n="YROT_PAN_#") SHAKER = pm.group(n="SHAKER_#") XYX_TRANS = pm.group(n="XYX_TRANS_#") self.CAM_CTRL = pm.group(n="%s_CAM_CTRL" % cam) self.CAM_CTRL.setParent(shaker_grp) # SHAKER.setParent(CAM_CTRL) # XYX_TRANS.setParent(SHAKER) # YROT_PAN.setParent(XYX_TRANS) # XROT_TILT.setParent(YROT_PAN) # ZROT_ROLL.setParent(XROT_TILT) # CAM_LOC.setParent(ZROT_ROLL) # NOTE 添加相关的属性 ---------------------------------------------------------------- self.CAM_CTRL.addAttr("locator_ScaleX", attributeType="double", defaultValue=3, keyable=1) self.CAM_CTRL.addAttr("locator_ScaleY", attributeType="double", defaultValue=3, keyable=1) self.CAM_CTRL.addAttr("locator_ScaleZ", attributeType="double", defaultValue=3, keyable=1) self.CAM_CTRL.addAttr("transform", attributeType="enum", en="menu") self.CAM_CTRL.transform.set(cb=1, l=1) self.CAM_CTRL.addAttr("trans_Cam_TransX", attributeType="double", defaultValue=0, keyable=1) self.CAM_CTRL.addAttr("trans_Cam_TransY", attributeType="double", defaultValue=0, keyable=1) self.CAM_CTRL.addAttr("trans_Cam_TransZ", attributeType="double", defaultValue=0, keyable=1) self.CAM_CTRL.addAttr("trans_XROT_TILT", attributeType="double", defaultValue=0, keyable=1) self.CAM_CTRL.addAttr("trans_YROT_PAN", attributeType="double", defaultValue=0, keyable=1) self.CAM_CTRL.addAttr("trans_ZROT_ROLL", attributeType="double", defaultValue=0, keyable=1) self.CAM_CTRL.addAttr("trans_scaleXYZ", attributeType="double", defaultValue=3, keyable=1) self.CAM_CTRL.addAttr("trans_focalLength", attributeType="double", defaultValue=35, min=2.5, smx=50, keyable=1) self.CAM_CTRL.addAttr("weight", attributeType="enum", en="menu") self.CAM_CTRL.weight.set(cb=1, l=1) self.CAM_CTRL.addAttr("weight_shk_tx", attributeType="double", defaultValue=0, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("weight_shk_ty", attributeType="double", defaultValue=0, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("weight_shk_tz", attributeType="double", defaultValue=0, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("weight_shk_rx", attributeType="double", defaultValue=0, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("weight_shk_ry", attributeType="double", defaultValue=0, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("weight_shk_rz", attributeType="double", defaultValue=0, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("weight_shk_focalLength", attributeType="double", defaultValue=0, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("amplify", attributeType="enum", en="menu") self.CAM_CTRL.amplify.set(cb=1, l=1) self.CAM_CTRL.addAttr("amplify_shk_tx", attributeType="double", defaultValue=1, min=0, smx=20, max=999, keyable=1) self.CAM_CTRL.addAttr("amplify_shk_ty", attributeType="double", defaultValue=1, min=0, smx=20, max=999, keyable=1) self.CAM_CTRL.addAttr("amplify_shk_tz", attributeType="double", defaultValue=1, min=0, smx=20, max=999, keyable=1) self.CAM_CTRL.addAttr("amplify_shk_rx", attributeType="double", defaultValue=1, min=0, smx=20, max=999, keyable=1) self.CAM_CTRL.addAttr("amplify_shk_ry", attributeType="double", defaultValue=1, min=0, smx=20, max=999, keyable=1) self.CAM_CTRL.addAttr("amplify_shk_rz", attributeType="double", defaultValue=1, min=0, smx=20, max=999, keyable=1) self.CAM_CTRL.addAttr("amplify_shk_focalLength", attributeType="double", defaultValue=1, min=0, smx=20, max=999, keyable=1) self.CAM_CTRL.addAttr("noise_weight", attributeType="enum", en="menu") self.CAM_CTRL.noise_weight.set(cb=1, l=1) self.CAM_CTRL.addAttr("noise_shk_tx", attributeType="double", defaultValue=1, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("noise_shk_ty", attributeType="double", defaultValue=1, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("noise_shk_tz", attributeType="double", defaultValue=1, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("noise_shk_rx", attributeType="double", defaultValue=1, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("noise_shk_ry", attributeType="double", defaultValue=1, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("noise_shk_rz", attributeType="double", defaultValue=1, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("noise_shk_focalLength", attributeType="double", defaultValue=1, min=0, max=1, keyable=1) self.CAM_CTRL.addAttr("shakingAttr", attributeType="enum", en="menu") self.CAM_CTRL.shakingAttr.set(cb=1, l=1) self.CAM_CTRL.addAttr("attr_tx_Frequency", attributeType="double", defaultValue=20, keyable=1) self.CAM_CTRL.addAttr("attr_tx_Seed", attributeType="double", defaultValue=1, keyable=1) self.CAM_CTRL.addAttr("attr_ty_Frequency", attributeType="double", defaultValue=20, keyable=1) self.CAM_CTRL.addAttr("attr_ty_Seed", attributeType="double", defaultValue=1, keyable=1) self.CAM_CTRL.addAttr("attr_tz_Frequency", attributeType="double", defaultValue=20, keyable=1) self.CAM_CTRL.addAttr("attr_tz_Seed", attributeType="double", defaultValue=1, keyable=1) self.CAM_CTRL.addAttr("attr_rx_Frequency", attributeType="double", defaultValue=20, keyable=1) self.CAM_CTRL.addAttr("attr_rx_Seed", attributeType="double", defaultValue=1, keyable=1) self.CAM_CTRL.addAttr("attr_ry_Frequency", attributeType="double", defaultValue=20, keyable=1) self.CAM_CTRL.addAttr("attr_ry_Seed", attributeType="double", defaultValue=1, keyable=1) self.CAM_CTRL.addAttr("attr_rz_Frequency", attributeType="double", defaultValue=20, keyable=1) self.CAM_CTRL.addAttr("attr_rz_Seed", attributeType="double", defaultValue=1, keyable=1) self.CAM_CTRL.addAttr("attr_focalLength_Frequency", attributeType="double", defaultValue=20, keyable=1) self.CAM_CTRL.addAttr("attr_focalLength_Seed", attributeType="double", defaultValue=1, keyable=1) exp = '' # NOTE 连接摄像机 ---------------------------------------------------------------- if cam: # NOTE 匹配当前摄像机位置 pm.delete(pm.parentConstraint(cam, CAM_LOC, mo=0)) pm.parentConstraint(CAM_LOC, cam) cam_shape = cam.getShape() self.CAM_CTRL.trans_scaleXYZ.connect(cam_shape.locatorScale) # NOTE 添加 focal length 抖动 attr = "focalLength" exp += "{SHAKER}.{attr} = {CAM_CTRL}.trans_focalLength + {CAM_CTRL}.weight_shk_{attr} * {CAM_CTRL}.amplify_shk_{attr} * (({CAM_CTRL}.noise_shk_{attr} * noise((frame + {CAM_CTRL}.attr_{attr}_Seed)/{CAM_CTRL}.attr_{attr}_Frequency)));\n".format( SHAKER=cam_shape, attr=attr, CAM_CTRL=self.CAM_CTRL) # NOTE 添加表达式 ---------------------------------------------------------------- for attr, axis in product(('t', 'r'), ('x', 'y', 'z')): attr = "%s%s" % (attr, axis) # exp += "{SHAKER}.{attr} = {CAM_CTRL}.weight_shk_{attr} * (0.282*(1-{CAM_CTRL}.noise_shk_{attr}) + ({CAM_CTRL}.noise_shk_{attr} * noise((frame + {CAM_CTRL}.attr_{attr}_Seed)/{CAM_CTRL}.attr_{attr}_Frequency)));\n".format(SHAKER=SHAKER,attr=attr,CAM_CTRL=self.CAM_CTRL) exp += "{SHAKER}.{attr} = {CAM_CTRL}.weight_shk_{attr} * {CAM_CTRL}.amplify_shk_{attr} * (({CAM_CTRL}.noise_shk_{attr} * noise((frame + {CAM_CTRL}.attr_{attr}_Seed)/{CAM_CTRL}.attr_{attr}_Frequency)));\n".format( SHAKER=SHAKER, attr=attr, CAM_CTRL=self.CAM_CTRL) pm.expression(n="%s_exp" % self.CAM_CTRL, s=exp, o=str(SHAKER), ae=1, uc="all") # NOTE 连接属性 ---------------------------------------------------------------- loc_shape = CAM_LOC.getShape() self.CAM_CTRL.locator_ScaleX.connect(loc_shape.localScaleX) self.CAM_CTRL.locator_ScaleY.connect(loc_shape.localScaleY) self.CAM_CTRL.locator_ScaleZ.connect(loc_shape.localScaleZ) self.CAM_CTRL.trans_Cam_TransX.connect(XYX_TRANS.tx) self.CAM_CTRL.trans_Cam_TransY.connect(XYX_TRANS.ty) self.CAM_CTRL.trans_Cam_TransZ.connect(XYX_TRANS.tz) self.CAM_CTRL.trans_XROT_TILT.connect(XROT_TILT.rx) self.CAM_CTRL.trans_YROT_PAN.connect(YROT_PAN.rx) self.CAM_CTRL.trans_ZROT_ROLL.connect(ZROT_ROLL.rz) # NOTE 锁定隐藏属性 ---------------------------------------------------------------- self.CAM_CTRL.tx.set(l=1, k=0, cb=0) self.CAM_CTRL.ty.set(l=1, k=0, cb=0) self.CAM_CTRL.tz.set(l=1, k=0, cb=0) self.CAM_CTRL.rx.set(l=1, k=0, cb=0) self.CAM_CTRL.ry.set(l=1, k=0, cb=0) self.CAM_CTRL.rz.set(l=1, k=0, cb=0) self.CAM_CTRL.sx.set(l=1, k=0, cb=0) self.CAM_CTRL.sy.set(l=1, k=0, cb=0) self.CAM_CTRL.sz.set(l=1, k=0, cb=0) self.CAM_CTRL.v.set(l=1, k=0, cb=0) XYX_TRANS.rx.set(l=1, k=0, cb=0) XYX_TRANS.ry.set(l=1, k=0, cb=0) XYX_TRANS.rz.set(l=1, k=0, cb=0) XYX_TRANS.sx.set(l=1, k=0, cb=0) XYX_TRANS.sy.set(l=1, k=0, cb=0) XYX_TRANS.sz.set(l=1, k=0, cb=0) YROT_PAN.tx.set(l=1, k=0, cb=0) YROT_PAN.ty.set(l=1, k=0, cb=0) YROT_PAN.tz.set(l=1, k=0, cb=0) YROT_PAN.rx.set(l=1, k=0, cb=0) YROT_PAN.rz.set(l=1, k=0, cb=0) YROT_PAN.sx.set(l=1, k=0, cb=0) YROT_PAN.sy.set(l=1, k=0, cb=0) YROT_PAN.sz.set(l=1, k=0, cb=0) XROT_TILT.tx.set(l=1, k=0, cb=0) XROT_TILT.ty.set(l=1, k=0, cb=0) XROT_TILT.tz.set(l=1, k=0, cb=0) XROT_TILT.ry.set(l=1, k=0, cb=0) XROT_TILT.rz.set(l=1, k=0, cb=0) XROT_TILT.sx.set(l=1, k=0, cb=0) XROT_TILT.sy.set(l=1, k=0, cb=0) XROT_TILT.sz.set(l=1, k=0, cb=0) ZROT_ROLL.tx.set(l=1, k=0, cb=0) ZROT_ROLL.ty.set(l=1, k=0, cb=0) ZROT_ROLL.tz.set(l=1, k=0, cb=0) ZROT_ROLL.ry.set(l=1, k=0, cb=0) ZROT_ROLL.rx.set(l=1, k=0, cb=0) ZROT_ROLL.sx.set(l=1, k=0, cb=0) ZROT_ROLL.sy.set(l=1, k=0, cb=0) ZROT_ROLL.sz.set(l=1, k=0, cb=0) self.CAM_CTRL = None
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 mip_move_image_plane(imagePlane = '', *args, **kwargs): if imagePlane: connections = pm.connectionInfo(imagePlane+'.message', destinationFromSource=True) cam = 'none' for item in connections: if item.split('Shape.')[0] == 'front': cam = 'front' if item.split('Shape.')[0] == 'side': cam = 'side' if item.split('Shape.')[0] == 'top': cam = 'top' if cam != 'none': curve = pm.curve(per=True, d=1, p=[(0.5,0,0.5), (0.5,0,-0.5), (-0.5,0,-0.5), (-0.5,0,0.5), (0.5,0,0.5)], k=[0,1,2,3,4]) if cam == 'front': curve.setRotation((90,0,0)) if cam == 'top': curve.setRotation((0,0,0)) if cam == 'side': curve.setRotation((90,90,0)) pm.setAttr(curve+'.rx', lock=True, keyable=False, channelBox=False) pm.setAttr(curve+'.ry', lock=True, keyable=False, channelBox=False) pm.setAttr(curve+'.rz', lock=True, keyable=False, channelBox=False) pm.setAttr(curve+'.sy', lock=True, keyable=False, channelBox=False) filename = pm.getAttr(imagePlane+'.imageName').split('/')[-1].split('.')[0] pm.rename(curve, 'Mover_'+filename) pm.expression(name=imagePlane+'_expression', s='{0}.displayMode = {1}.visibility * 3'.format(imagePlane, curve)) ratio = 1.0 coverageX = float(pm.getAttr(imagePlane+'.coverageX')) coverageY = float(pm.getAttr(imagePlane+'.coverageY')) size = 1.0 sizeW = float(pm.getAttr(imagePlane+'.width')) sizeH = float(pm.getAttr(imagePlane+'.height')) if sizeW>sizeH: size = sizeW else: size = sizeH if coverageX > coverageY: ratio = coverageX/coverageY x = size z = size/ratio curve.setScale((x,1,z)) pm.select(curve.cv[0:3]) pm.scale(1.2,1+(.2/ratio),1) else: ratio = coverageY/coverageX x = size/ratio z = size curve.setScale((x,1,z)) pm.select(curve.cv[0:3]) pm.scale(1+(.2/ratio),1.2,1) if pm.mel.getApplicationVersionAsFloat() > 2012: pm.connectAttr(curve.translate, imagePlane+'.imageCenter') else: pm.connectAttr(curve.translate, imagePlane+'.center') pm.connectAttr(curve.scaleX, imagePlane+'.width') pm.connectAttr(curve.scaleZ, imagePlane+'.height') pm.select(curve, replace=True) else: pm.warning('not using the front, side or top camera !!!')
def main(count=100): # create locators start_locator = pm.spaceLocator(name="start_point") end_locator = pm.spaceLocator(name="end_point") pm.setAttr(end_locator.tx, 5) start_x = pm.getAttr(start_locator.tx) start_y = pm.getAttr(start_locator.ty) start_z = pm.getAttr(start_locator.tz) end_x = pm.getAttr(end_locator.tx) end_y = pm.getAttr(end_locator.ty) end_z = pm.getAttr(end_locator.tz) # create guide curve and divide into select spans guide_curve_transform = pm.curve(name='guide_curve', degree=1, p=([start_x, start_y, start_z], [end_x, end_y, end_z])) guide_curve = pm.listRelatives(guide_curve_transform, children=True)[0] pm.rebuildCurve(guide_curve, spans=(count - 3), degree=3) # convert to soft body particle_pack = pm.nSoft(guide_curve, convert=True) particle_transform = particle_pack[0] index = guide_curve[-1] try: index = int(index) particle_transform = pm.rename(particle_transform, "lightning_particle%s" % index) except: particle_transform = pm.rename(particle_transform, "lightning_particle") particle_system = pm.listRelatives(particle_transform, children=True)[0] # turn off gravity effects pm.setAttr(particle_system.ignoreSolverGravity, 1) pm.dynExpression( particle_system, creation=1, string=str( "{ps}.position = hermite ( <<{sp}.translateX,{sp}.translateY,{sp}.translateZ>>, \n\t\t\t <<{ep}.translateX,{ep}.translateY,{ep}.translateZ>>,\n <<{ep}.translateX-{sp}.translateX,{ep}.translateY-{sp}.translateY,{ep}.translateZ-{sp}.translateZ>>,<<{sp}.translateX-{sp}.translateX,{ep}.translateY-{sp}.translateY,{ep}.translateZ-{sp}.translateZ>>,\n linstep(0,{ps}.count-1,{ps}.particleId) );\n\nfloat $inNoise = (0.5- abs(0.5- linstep(0,{ps}.count,{ps}.particleId) ) )*2;\nfloat $speed_1 = 0.5;\nfloat $speed_2 = 2;\nfloat $speed_3 = 2; \n{ps}.position += << noise({ps}.particleId/50 + $speed_1*time ), \n\t\t\t \t\t\t\t\t\tnoise(({ps}.particleId-{ps}.count/2)/50 + $speed_1*time ),\n\t\t\t \t\t\t\t\t\tnoise(({ps}.particleId-{ps}.count)/50 + $speed_1*time ) >> * 1 *$inNoise;\n{ps}.position += << noise({ps}.particleId/10 + $speed_2*time ),\n\t\t\t \t\t\t\t\t\tnoise(({ps}.particleId-{ps}.count/2)/10 + $speed_2*time ),\n\t\t\t \t\t\t\t\t\tnoise(({ps}.particleId-{ps}.count)/10 + $speed_2*time ) >> *0.3 *$inNoise;\n{ps}.position += << noise({ps}.particleId/2 + $speed_3*time ),\n\t\t \t \t\t\t\t\t\tnoise(({ps}.particleId-{ps}.count/2)/2 + $speed_3*time ),\n\t\t\t \t\t\t\t\t\tnoise(({ps}.particleId-{ps}.count)/2 + $speed_3*time ) >> *0.1 *$inNoise;" .format(ps=particle_system, sp=start_locator, ep=end_locator))) pm.dynExpression( particle_system, runtimeBeforeDynamics=1, string=str( "{ps}.position = hermite ( <<{sp}.translateX,{sp}.translateY,{sp}.translateZ>>,\n <<{ep}.translateX,{ep}.translateY,{ep}.translateZ>>,\n <<{ep}.translateX-{sp}.translateX,{ep}.translateY-{sp}.translateY,{ep}.translateZ-{sp}.translateZ>>,<<{ep}.translateX-{sp}.translateX,{ep}.translateY-{sp}.translateY,{ep}.translateZ-{sp}.translateZ>>,\n linstep(0,{ps}.count-1,{ps}.particleId) );\n\nfloat $inNoise = (0.5- abs(0.5- linstep(0,{ps}.count,{ps}.particleId) ) )*2;\nfloat $speed_1 = 6;\nfloat $speed_2 = 5;\nfloat $speed_3 = 5;\n{ps}.position += << noise({ps}.particleId/50 + $speed_1*-time ),\n noise(({ps}.particleId-{ps}.count/2)/50 + $speed_1*-time ),\n noise(({ps}.particleId-{ps}.count)/50 + $speed_1*-time ) >> * 1.3 *$inNoise;\n{ps}.position += << noise({ps}.particleId/10 + $speed_2*-time ),\n noise(({ps}.particleId-{ps}.count/2)/10 + $speed_2*-time ),\n noise(({ps}.particleId-{ps}.count)/10 + $speed_2*-time ) >> *0.2 *$inNoise;\n{ps}.position += << noise({ps}.particleId/2 + $speed_3*-time ),\n noise(({ps}.particleId-{ps}.count/2)/2 + $speed_3*-time ),\n noise(({ps}.particleId-{ps}.count)/2 + $speed_3*-time ) >> *0.05 *$inNoise;" .format(ps=particle_system, sp=start_locator, ep=end_locator))) # do the extrude for the nurbcurve # make the circle curve makeNurbCircle = pm.createNode("makeNurbCircle") pm.setAttr(makeNurbCircle.radius, 1.35) pm.setAttr(makeNurbCircle.normal, [1, 0, 0]) circle_curve = pm.createNode('nurbsCurve', n='circle_curve') circle_curve_transform = pm.listRelatives(circle_curve, fullPath=True, allParents=True)[0] pm.connectAttr(start_locator.translate, circle_curve_transform.translate) pm.setAttr(circle_curve_transform.scale, [0.019, 0.019, 0.019]) pm.getAttr(circle_curve_transform.scale) pm.rename(circle_curve_transform, "%s_transform" % circle_curve) pm.connectAttr(makeNurbCircle.outputCurve, circle_curve.create) # create extrude node extrude_node = pm.createNode('extrude', n='extrude_node') pm.setAttr(extrude_node.useProfileNormal, 0) pm.setAttr(extrude_node.fixedPath, 0) pm.setAttr(extrude_node.useComponentPivot, 0) pm.setAttr(extrude_node.scale, 0.25) pm.connectAttr(guide_curve.worldSpace[0], extrude_node.path) pm.connectAttr(circle_curve.worldSpace[0], extrude_node.profile) #create tessellate node nurbsTessellate = pm.createNode('nurbsTessellate', n='nurbsTessellate') pm.setAttr(nurbsTessellate.polygonType, 1) pm.setAttr("%s.format" % nurbsTessellate, 2) pm.setAttr(nurbsTessellate.uNumber, 1) pm.setAttr(nurbsTessellate.useChordHeightRatio, 0) pm.setAttr(nurbsTessellate.vNumber, 1) pm.connectAttr(extrude_node.outputSurface, nurbsTessellate.inputSurface) #create a mesh for curve extrude extrude_mesh = pm.createNode('mesh', name='extrude_mesh') extrude_mesh_transform = pm.listRelatives(extrude_mesh, parent=True)[0] extrude_mesh_transform = pm.rename(extrude_mesh_transform, "%s_transform" % extrude_mesh) pm.connectAttr(nurbsTessellate.outputPolygon, extrude_mesh.inMesh) brush = pm.createNode("brush", name="lightning_spark") pm.setAttr(brush.brushType, 5) pm.setAttr(brush.globalScale, 7.458) pm.setAttr(brush.depth, 1) pm.setAttr(brush.brushWidth, 0) pm.setAttr(brush.softness, 0) pm.setAttr(brush.mapDisplacement, 1) pm.setAttr(brush.luminanceIsDisplacement, 0) pm.setAttr(brush.textureType, 3) pm.setAttr(brush.texAlpha1, 0.386) pm.setAttr(brush.texAlpha2, 1) pm.setAttr(brush.repeatU, 2.542) pm.setAttr(brush.blurMult, 5) pm.setAttr(brush.smear, 251) pm.setAttr(brush.fractalAmplitude, 2.094) pm.setAttr(brush.fractalRatio, 0.592) pm.setAttr(brush.tubes, 1) pm.setAttr(brush.tubeCompletion, 0) pm.setAttr(brush.tubesPerStep, 0.061) pm.setAttr(brush.segments, 70) pm.setAttr(brush.lengthMin, 0.061) pm.setAttr(brush.lengthMax, 1.104) pm.setAttr(brush.blurMult, 5) pm.setAttr(brush.tubeWidth1, 0.04) pm.setAttr(brush.tubeWidth2, 0) pm.setAttr(brush.widthRand, 0.282) pm.setAttr(brush.widthBias, -0.215) #the width scale pm.setAttr(brush.widthScale[1].widthScale_FloatValue, 0.96) pm.setAttr(brush.widthScale[1].widthScale_Position, 0.982609) pm.setAttr(brush.widthScale[1].widthScale_Interp, 1) pm.setAttr(brush.widthScale[1].widthScale_Position, 1) pm.setAttr(brush.widthScale[1].widthScale_FloatValue, 0.72) pm.setAttr(brush.elevationMin, 0) pm.setAttr(brush.elevationMax, 0.160) pm.setAttr(brush.azimuthMin, -0.068) pm.setAttr(brush.azimuthMax, 0.006) #growth pm.setAttr(brush.branches, 1) #branches pm.setAttr(brush.numBranches, 3) pm.setAttr(brush.branchDropout, 0.359) pm.setAttr(brush.splitAngle, 36.7) pm.setAttr(brush.splitBias, 0.368) pm.setAttr(brush.minSize, 0.003) #behavior #displacement pm.setAttr(brush.displacementDelay, 0.117) pm.setAttr(brush.noise, 10) pm.setAttr(brush.noiseFrequency, 0.074) pm.setAttr(brush.wiggleFrequency, 5) #force pm.setAttr(brush.gravity, 0.107) #gaps pm.setAttr(brush.gapSpacing, 0.02) pm.setAttr(brush.gapRand, 1) #flow animation pm.connectAttr("time1.outTime", brush.time) ################## #create stroke stroke = pm.createNode("stroke", name="lightning_stroke") stroke_transform = pm.listRelatives(stroke, fullPath=True, allParents=True)[0] stroke_transform = pm.rename(stroke_transform, "%s_transform" % stroke) pm.connectAttr(guide_curve.worldSpace, stroke.pathCurve[0].curve) pm.connectAttr(brush.outBrush, stroke.brush) #basic pm.expression( string="float $a = rand(1);\nif($a>0.5)\n{\n\t%s.seed=frame;\n}" % stroke, object=stroke, alwaysEvaluate=True, unitConversion=all) pm.setAttr(stroke.sampleDensity, 0.109) #normal_direction pm.setAttr(stroke.minimalTwist, 1) #pressure mapping pm.setAttr(stroke.minimalTwist, 1) pm.setAttr(stroke.pressureScale[0].pressureScale_Position, 0) pm.setAttr(stroke.pressureScale[0].pressureScale_FloatValue, 0.12) pm.setAttr(stroke.pressureScale[1].pressureScale_FloatValue, 0) pm.setAttr(stroke.pressureScale[1].pressureScale_Position, 1) pm.setAttr(stroke.pressureMap1, 6) #input curves #******************** #path curve pm.setAttr(stroke.pathCurve[0].samples, 588) pm.setAttr(stroke.mainVertBufSize, 906) #mesh output pm.setAttr(stroke.meshQuadOutput, 1) #object display pm.setAttr(stroke.visibility, 0) ############# #create a mesh for the strock stroke_mesh = pm.createNode("mesh", name="stroke_mesh") pm.connectAttr(stroke.worldMainMesh, stroke_mesh.inMesh) stroke_mesh_transform = pm.listRelatives(stroke_mesh, parent=True)[0] stroke_mesh_transform = pm.rename(stroke_mesh_transform, "%s_transform" % stroke_mesh) #hide the curve and particle pm.hide(guide_curve_transform) pm.hide(circle_curve_transform) pm.hide(stroke_transform) ## #group all elements in a group trans_list = [ start_locator, end_locator, guide_curve_transform, circle_curve_transform, stroke_mesh_transform, stroke_transform, extrude_mesh_transform ] group_lightning = pm.group(trans_list) group_lightning = pm.rename(group_lightning, "lightning_group") return group_lightning
#calc calcList = [] mantGroup = pm.group(name = 'mantleGroup', world = True, empty = True)#creating calc joints for i in pm.listRelatives(mantleParent): cal = pm.duplicate(i, name = i[:7] + '_Calc', parentOnly = True) pm.parent(cal, mantGroup) spaceLoc = pm.spaceLocator(name = 'simLoc_' + i[5:])#creating simloc locator pm.xform(spaceLoc, ws = True, translation = pm.xform(i, query = True, translation = True, ws = True))#moving it to the right place pm.xform(spaceLoc, relative = True, translation = [0, -25.627, 0]) pm.addAttr(spaceLoc, longName = 'momentumX', attributeType = 'float') pm.addAttr(spaceLoc, longName = 'momentumY', attributeType = 'float') pm.addAttr(spaceLoc, longName = 'momentumZ', attributeType = 'float') #creating expression to drive the SimLoc's translations pm.expression(object = spaceLoc, name = spaceLoc + '_translationExp', string = '$f = `currentTime -q`;\n$lastposX = `getAttr -t ($f - mantle_Control.Drag) %s.translateX`;\n%s.translateX = %s.translateX - (%s.translateX - $lastposX);\n$lastposY = `getAttr -t ($f - mantle_Control.Drag) %s.translateY`;\n%s.translateY = %s.translateY - (%s.translateY - $lastposY) - 25.627;\n$lastposZ = `getAttr -t ($f - mantle_Control.Drag) %s.translateZ`;\n%s.translateZ = %s.translateZ - (%s.translateZ - $lastposZ);' %(cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0])) ''' '$f = `currentTime -q`;\n $lastposX = `getAttr -t ($f - mantle_Control.Drag) %s.translateX`;\n %s.translateX = %s.translateX - (%s.translateX - $lastposX);\n $lastposY = `getAttr -t ($f - mantle_Control.Drag) %s.translateY`;\n %s.translateY = %s.translateY - (%s.translateY - $lastposY) - 25.627;\n $lastposZ = `getAttr -t ($f - mantle_Control.Drag) %s.translateZ`;\n %s.translateZ = %s.translateZ - (%s.translateZ - $lastposZ);' %(cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0]) ''' #create expression for the momentum attributes if i[5:] == 'R': xVar = '- 0.000001' else: xVar = '+ 0.000001'
def createStretchSpline(curveObj, volume, worldScale, worldScaleObj, worldScaleAttr, disable=0, disableObj='', disableAttr=''): """ Script: js_createStretchSpline.mel Author: Jason Schleifer Descr: Given the selected curve, it will tell the joints to stretch. It's easiest to use with the js_createStretchSplineUI.mel script Inputs: $curveObj => The nurbs curve that will be stretched $maintainVolume => Whether or not to maintain volume on the joints if this is on, then it will be made with an expression, if not then we'll use nodes. $worldScale => Whether or not to take worldScale into account $worldScaleObj => The object that will be used for world scale $worldScaleAttr => The attribute to be used for world scale $disable => Option to control and disable stretch with control $disableObj => The object that will be used for disable $disableAttr => The attribute to be used for disable Req: getStretchAxis createCurveControl """ node = pm.arclen(curveObj, n= '%s_curveInfo'%curveObj, ch=1) # based on the given curve, tell the joints to stretch # create a curveInfo node # get the ikhandle shape = pm.listRelatives(curveObj, s=1, f=1) con = pm.listConnections((shape[0] + ".worldSpace[0]"), type='ikHandle') ikHandle = con[0] # find out what joints are in the list joints = pm.ikHandle(ikHandle, q=1, jl=1) # we need to figure out which direction the curve should be scaling. # do to that, we'll look at the translate values of the second joint. Whichever translate has the # highest value, that'll be the first one and the other two axis will be the shrinking one stretchAxis = getStretchAxis(joints[1]) # create a normalizedScale attr on the curveInfo node pm.addAttr(node, ln="normalizedScale", at="double") length = pm.getAttr(str(node) + ".arcLength") # create blend node for on/off blendStretch = pm.shadingNode('blendColors', asUtility=1, name='%s_stretchBlend'%curveObj) pm.setAttr(str(blendStretch) + '.color1R', length) pm.connectAttr((str(node) + ".arcLength"), str(blendStretch) + '.color2R') # create a NormalizedScale node to connect to everything. multDivide = pm.createNode('multiplyDivide') multDivide = pm.rename(multDivide, (curveObj + "_normalizedScale")) # set the multiplyDivide node to division pm.setAttr((str(multDivide) + ".operation"), 2) pm.connectAttr("%s.outputR"%blendStretch, "%s.input1X"%multDivide) pm.setAttr((str(multDivide) + ".input2X"), length) pm.connectAttr((str(multDivide) + ".outputX"), (str(node) + ".normalizedScale")) if disable: pm.connectAttr('%s.%s'%(disableObj, disableAttr), '%s.blender'%blendStretch ) else: pm.setAttr('%s.blender'%blendStretch, 1 ) # if worldscale is off, and volume deformation is off, we can just connect directly to the joints if (worldScale == 0) and (volume == 0): for joint in joints: print "connecting to " + str(joint) + "." + stretchAxis[0] + "\n" pm.connectAttr((str(node) + ".normalizedScale"), (str(joint) + "." + stretchAxis[0]), f=1) elif (worldScale == 1) and (volume == 0): md2 = pm.createNode('multiplyDivide', n=(curveObj + "_worldScale")) # if $worldScale is on, but volume is off we can just add another multiply divide node # and connect to that # create a multiplyDivide node pm.setAttr((str(md2) + ".operation"), 2) pm.connectAttr((str(node) + ".normalizedScale"), (str(md2) + ".input1X")) pm.connectAttr((worldScaleObj + "." + worldScaleAttr), (str(md2) + ".input2X")) for joint in joints: pm.connectAttr((str(md2) + ".outputX"), (str(joint) + "." + stretchAxis[0]), f=1) else: pm.select(joints) # also create an anim curve which we can use to connnect to the joints to help # determine the scaling power in X and Z. This will be attached to the curve itself utils.createCurveControl(curveObj, "scalePower", "pow") # start creating an expression expr = "" # for each joint, connect the scaleX to the normalizedScale # if worldScale and disable: # expr += ("$scale = " + str(node) + ".normalizedScale *" + worldScaleObj + "." + worldScaleAttr + " * " + disableObj + "." + disableAttr + ";\n") if worldScale: expr += ("$scale = " + str(node) + ".normalizedScale *" + worldScaleObj + "." + worldScaleAttr + ";\n") # elif disable: # expr += ("$scale = " + str(node) + ".normalizedScale *" + disableObj + "." + disableAttr + ";\n") else: expr += ("$scale = " + str(node) + ".normalizedScale;\n") expr += ("$sqrt = 1/sqrt($scale);\n") size = len(joints) for x in range(0, size): item = joints[x] # set a powPosition based on the number of joints which will be scaling, from 0 to 1 expr = (expr + str(item) + "." + stretchAxis[0] + " = $scale;\n") expr = (expr + str(item) + "." + stretchAxis[1] + " = pow($sqrt," + str(item) + ".pow);\n") expr = (expr + str(item) + "." + stretchAxis[2] + " = pow($sqrt," + str(item) + ".pow);\n") pm.expression(s=expr, n=(curveObj + "_expr")) pm.select(curveObj) return joints
def createNetwork(self, control=None, name=None, sine_grp=None, jnt=None, axis=None, count=None, numJnts=None): ''' Use attributes: time_sine_value, z_rotation or y_rotation, fwd_limit, back_limit, effect, count, numJnts Create expression to animate sine_grp rotations. ''' s = '//Expression to drive %s sine_grp.rotate%s\n' % (jnt, axis) s += 'float $sw_count = %s.switch_count;\n' % (control) s += 'float $sine = %s.time_sine_value;\n' % (control) s += 'float $amplitude = %s.amplitude;\n' % (control) s += 'float $offset = %s.time_offset;\n' % (control) s += 'float $fwd_limit = %s.fwd_limit;\n' % (control) s += 'float $back_limit = %s.back_limit;\n' % (control) s += 'float $effect = %s.effect;\n' % (control) s += 'float $effect_val = %s.sine_effect_value;\n' % jnt s += 'float $direction = %s.sine_direction;\n' % jnt s += 'float $temp1 = 0;\n' s += 'float $temp2 = 0;\n' if axis == 'z': s += 'float $r_value = %s.z_rotation;\n\n' % control else: s += 'float $r_value = %s.y_rotation;\n\n' % control s += '$temp1 = $sine;\n' s += '\n// Remap range to user set min / max range\n' s += 'float $old_range = ($amplitude - (-$amplitude));\n' s += 'float $new_range = ($fwd_limit - $back_limit);\n' s += '$temp2 = (((($temp1 - (-$amplitude)) * $new_range)/$old_range)' + \ '+ $back_limit) * $r_value;\n' s += '\n// Apply direction section\n' # s += '$temp1 = $temp1 * $direction;\n' # s += '$temp2 = $temp2 * $direction;\n' s += '\n// Final connection to rotation of sine_grp\n' if axis == 'z': s += '\n// Change Direction value on joint only in z exp, not y.\n' s += 'if($sw_count == %s)\n' % count s += '{ %s.sine_direction = $direction * -1; }\n' % jnt s += 'if($effect>0){ // Dampen effect\n' s += ' %s.rotateZ = $temp2 * ($effect_val/100) * $effect;}\n' \ % (sine_grp) s += 'else{\n' s += ' %s.rotateZ = $temp1 * $r_value;}\n' % (sine_grp) else: s += 'if($effect>0){ // Dampen effect\n' s += ' %s.rotateY = $temp2 * ($effect_val/100) * $effect;}\n' \ % (sine_grp) s += 'else{\n' s += ' %s.rotateY = $temp1 * $r_value;}\n' % (sine_grp) pm.expression(name='%s_%s_%s_SineRig_exp' % (name, jnt, axis), s=s)
def camera_film_offset_tool(): """Adds a locator to the selected camera with which you can adjust the 2d pan and zoom. Usage : ------- - to add it, select the camera and use oyCameraFilmOffsetTool - to remove it, set the transformations to 0 0 1 and then simply delete the curve """ sel_list = pm.ls(sl=1) camera_shape = "" found_camera = 0 for obj in sel_list: #if it is a transform node query for shapes if isinstance(obj, pm.nt.Transform): for shape in obj.listRelatives(s=True): if isinstance(shape, pm.nt.Camera): camera_shape = shape found_camera = 1 break elif isinstance(obj, pm.nt.Camera): camera_shape = obj found_camera = 1 break if found_camera: pass else: raise RuntimeError("please select one camera!") #get the camera transform node temp = camera_shape.listRelatives(p=True) camera_transform = temp[0] pm.getAttr("defaultResolution.deviceAspectRatio") pm.getAttr("defaultResolution.pixelAspect") #create the outer box frame_curve = pm.curve( d=1, p=[(-0.5, 0.5, 0), (0.5, 0.5, 0), (0.5, -0.5, 0), (-0.5, -0.5, 0), (-0.5, 0.5, 0)], k=[0, 1, 2, 3, 4] ) pm.parent(frame_curve, camera_transform, r=True) #transform the frame curve frame_curve.tz.set(-10.0) #create the locator temp = pm.spaceLocator() adj_locator = temp adj_locator_shape = temp adj_locator.addAttr('enable', at='bool', dv=True, k=True) pm.parent(adj_locator, frame_curve, r=True) pm.transformLimits(adj_locator, tx=(-0.5, 0.5), etx=(True, True)) pm.transformLimits(adj_locator, ty=(-0.5, 0.5), ety=(True, True)) pm.transformLimits(adj_locator, sx=(0.01, 2.0), esx=(True, True)) #connect the locator tx and ty to film offset x and y adj_locator.tx >> camera_shape.pan.horizontalPan adj_locator.ty >> camera_shape.pan.verticalPan exp = 'float $flen = %s.focalLength;\n\n' \ 'float $hfa = %s.horizontalFilmAperture * 25.4;\n' \ '%s.sx = %s.sy = -%s.translateZ * $hfa/ $flen;' % ( camera_shape, camera_shape, frame_curve, frame_curve, frame_curve) pm.expression(s=exp, o='', ae=1, uc="all") adj_locator.sx >> adj_locator.sy adj_locator.sx >> adj_locator.sz adj_locator.sx >> camera_shape.zoom adj_locator.enable >> camera_shape.panZoomEnabled adj_locator_shape.localScaleZ.set(0) adj_locator.tz.set(lock=True, keyable=False) adj_locator.rx.set(lock=True, keyable=False) adj_locator.ry.set(lock=True, keyable=False) adj_locator.rz.set(lock=True, keyable=False) adj_locator.sy.set(lock=True, keyable=False) adj_locator.sz.set(lock=True, keyable=False)
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 sleeveCreate(): cmds.file('K:/design/maya/data/tool/scData/Sleeve_Install/sleeve_mesh.ma', i = True) # pm.xform(pm.ls(sl = True), rotatePivot = [-57.014295, 126.663641, -0.458615], scalePivot = [-57.014295, 126.663641, -0.458615], preserve = True) pm.xform(pm.ls(sl = True), rotatePivot = [57.014295, 126.663641, -0.458615], scalePivot = [57.014295, 126.663641, -0.458615], preserve = True) pm.xform('L_sleeve_mesh', translation = pm.xform('L_hand', query = True, translation = True, ws = True)) pm.xform('R_sleeve_mesh', translation = pm.xform('R_hand', query = True, translation = True, ws = True)) pm.makeIdentity('L_sleeve_mesh', 'R_sleeve_mesh', translate = True, rotate = True, apply = True) pm.xform('L_sleeve_mesh', 'R_sleeve_mesh', ztp = True) pm.bakePartialHistory('L_sleeve_mesh', 'R_sleeve_mesh', prePostDeformers = True, preDeformers = True) #[(0, 2, 0), (1, 0, -1), (-1, 0, -1), (0, 2, 0), (-1, 0, 1), (1, 0, 1), (0, 2, 0), (1, 0, -1), (1, 0, 1), (-1, 0, 1), (-1, 0, -1)], knot = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] #creating controller for sleeve attributes LsleeveAttr = pm.curve(name = 'L_sleeveAttr', degree = 1, point = [(0, 2, 0), (1, 0, -1), (-1, 0, -1), (0, 2, 0), (-1, 0, 1), (1, 0, 1), (0, 2, 0), (1, 0, -1), (1, 0, 1), (-1, 0, 1), (-1, 0, -1)], knot = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) pm.xform(LsleeveAttr, translation = (44, 139.5, -11), scale = (3,3,3)) pm.addAttr(LsleeveAttr, longName = 'Drag', minValue = 0, defaultValue = 5, attributeType = 'float', keyable = True) pm.addAttr(LsleeveAttr, longName = 'Cycle', minValue = 0, maxValue = 1, defaultValue = 0, attributeType = 'short', keyable = True) pm.addAttr(LsleeveAttr, longName = 'Speed', minValue = -30, maxValue = 0, defaultValue = 0, attributeType = 'short', keyable = True) pm.setAttr(LsleeveAttr.tx, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.ty, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.tz, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.rx, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.ry, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.rz, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.sx, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.sy, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.sz, channelBox = False, keyable = False) pm.setAttr(LsleeveAttr.v, channelBox = False, keyable = False) pm.parent(LsleeveAttr, 'L_elbow_ctrl') RsleeveAttr = pm.curve(name = 'R_sleeveAttr', degree = 1, point = [(0, 2, 0), (1, 0, -1), (-1, 0, -1), (0, 2, 0), (-1, 0, 1), (1, 0, 1), (0, 2, 0), (1, 0, -1), (1, 0, 1), (-1, 0, 1), (-1, 0, -1)], knot = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) pm.xform(RsleeveAttr, translation = (-44, 139.5, -11), scale = (3,3,3)) pm.addAttr(RsleeveAttr, longName = 'Drag', minValue = 0, defaultValue = 5, attributeType = 'float', keyable = True) pm.addAttr(RsleeveAttr, longName = 'Cycle', minValue = 0, maxValue = 1, defaultValue = 0, attributeType = 'short', keyable = True) pm.addAttr(RsleeveAttr, longName = 'Speed', minValue = -30, maxValue = 0, defaultValue = 0, attributeType = 'short', keyable = True) pm.setAttr(RsleeveAttr.tx, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.ty, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.tz, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.rx, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.ry, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.rz, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.sx, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.sy, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.sz, channelBox = False, keyable = False) pm.setAttr(RsleeveAttr.v, channelBox = False, keyable = False) pm.parent(RsleeveAttr, 'R_elbow_ctrl') pm.select(d = True) #deselect everything first #create a loop to create joints and move them into the right position jointNames = ['forearm1', 'hand', 'upperarm2'] sideList = ['L_', 'R_'] allList = [] for i in sideList: for j in jointNames: allList.append(i + j) print allList sleeveGroup = pm.group(name = 'Sleeve',empty = True) #creating empty sleeve Group sleeveJoints = [] for i in allList: #loop #creating joints and moving them into position if i.find('forearm') != -1: jointName = i.replace('forearm1', 'elbow') elif i.find('upperarm2') != -1: jointName = i.replace('upperarm2', 'UpperArm') else: jointName = i.replace('hand', 'wrist') j = pm.joint(p = pm.xform(i, q = True, translation = True, worldSpace = True), name = jointName, roo = 'xzy') sleeveJoints.append(j) pm.parent(j, world = True) if i.find('L_upperarm2') != -1: pm.move(11.613, 0, 0, j, relative = True) #translate x to 17.613 elif i.find('R_upperarm2') != -1: pm.move(-11.613, 0, 0, j, relative = True) #translate x to -17.613 #apply constraint to joints as part of loop pm.parentConstraint(i, j, mo = True, skipRotate = ['x']) #This chunk below is to create a flip check that automatically flips the joint X axis by 180 whenever it detects a gimbal pop #this first part creates the necessary elements jointDupe = pm.duplicate(j, name = j + '_dupe', po = True) if jointDupe[0].find('L_UpperArm') != -1: pm.move(10.0, 0, 0, jointDupe, relative = True) #translate x to 17.613 if jointDupe[0].find('R_UpperArm') != -1: pm.move(-10.0, 0, 0, jointDupe, relative = True) #translate x to 17.613 jointFlipCheck = pm.duplicate(jointDupe, name = j + '_dupe_check', po = True) pm.move(0, 5, 0, jointFlipCheck, relative = True) dupeConstr = pm.parentConstraint(i, jointDupe, mo = True, skipRotate = ['x']) flipCheckConstr = pm.parentConstraint(jointDupe, jointFlipCheck, mo = True) pm.expression(name = j + '_rotateX_Exp', s = "if (%s.translateY < %s.translateY) {\n %s.rotateX = 0;\n}else {\n %s.rotateX = 180;}" % (j, jointFlipCheck[0], j, j)) #this part performs adds the necessary expression #end addition pm.parent(j, sleeveGroup) #parenting to sleeveGroup pm.parent(jointDupe, sleeveGroup) #parenting to sleeveGroup pm.parent(jointFlipCheck, sleeveGroup) #parenting to sleeveGroup parentDict = dict() k = 0 while k < 6: parentDict.update({sleeveJoints[k] : allList[k]}) k += 1 #create sleeve chain for i in sleeveJoints: if i.find('L_') != -1: side = 'L_' else: side = 'R_' #create joint origin pm.select(i) exportOrigin = pm.joint(name = i + '_export', p = (0, 0, 0), relative = True) #creating bone for export pm.parent(exportOrigin, parentDict[i]) #parenting export joint to where it belongs originJoint = pm.joint(name = i + '_sleeve_origin', p = (0, 0, 0), relative = True) #name = str(i[0]) + 'origin' pm.parent(originJoint, w = True) #create joint sim offset by 33.22, name = pm.ls(i)[0] sim = pm.joint(name = i + '_sleeve_sim', p = (0, -33.22, 0), relative = True) #name = str(i[0]) + 'sim' exportSim = pm.joint(name = i + '_export_sim', p = (0, 0, 0), relative = True) #creating bone for export pm.parent(exportSim, exportOrigin) #parenting exportSim to exportOrigin #create joint unity offset by 31.758 pm.joint(name = i + '_0___yure__IS__ST_02__DR_001__SF_0_m01_0', p = (0, -1, 0), relative = True) #create joint end for unity pm.joint(name = i + '_x', p = (0, -30.758, 0), relative = True) #apply constraint to origin joint pm.parentConstraint(i, originJoint, mo = True) ik = pm.ikHandle(startJoint = originJoint, endEffector = sim, name = i + '_ikHandle', solver = 'ikRPsolver') #create IK for both sides #create sim locators locator = pm.spaceLocator(name = i + '_locator_sim') pm.xform(locator, translation = pm.xform(pm.ls(sim), query = True, translation = True, worldSpace = True)) #apply expressions to locators #DO NOT FORGET TO INCLUDE LINKS TO DRAG/delay pm.expression(name = i + '_simExp', s = "$f = `currentTime -q`;\n $lastposX = `getAttr -t ($f - %s.Drag) %s.translateX`;\n %s.translateX = %s.translateX - (%s.translateX - $lastposX);" % (side + 'sleeveAttr', i, i + '_locator_sim', i, i)) #PLEASE CHECK EXPRESSION BEFORE SUBMITTING pm.expression(name = i + '_simExp', s = "$f = `currentTime -q`;\n$posY = %s.translateY - 33.22;\n $lastposY = `getAttr -t ($f - %s.Drag) %s.translateY` - 33.22;\n%s.translateY = ($posY - ($posY - $lastposY))/1.5;" % (i ,side + 'sleeveAttr', i, i + '_locator_sim')) #PLEASE CHECK EXPRESSION BEFORE SUBMITTING pm.expression(name = i + '_simExp', s = "$excep = 0;\nif (%ssleeveAttr.Cycle == 1) {\n $excep = %ssleeveAttr.Speed;\n}$f = `currentTime -q`;\n $lastposZ = `getAttr -t ($f - %s.Drag) %s.translateZ`;\n %s.translateZ = %s.translateZ - (%s.translateZ - $lastposZ) + $excep;" % (side, side, side + 'sleeveAttr', i, i + '_locator_sim', i, i)) #PLEASE CHECK EXPRESSION BEFORE SUBMITTING pm.expression(name = i + '_simExp', s = "$f = `currentTime -q`;\n $lastrotY = `getAttr -t ($f - %s.Drag) %s.rotateY`;\n %s.rotateY = %s.rotateY - (%s.rotateY - $lastrotY);" % (side + 'sleeveAttr', i, i + '_locator_sim', i, i)) #PLEASE CHECK EXPRESSION BEFORE SUBMITTING #constraint IK handles to sim pm.parentConstraint(locator, ik[0], mo = False) #this point onwards is to create the polevector for the sleeves if not pm.ls('%ssleeve_pv' %side): poleVector = pm.spaceLocator(name = side + 'sleeve_pv') pm.xform(poleVector, translation = pm.xform(pm.ls(originJoint), query = True, translation = True, worldSpace = True)) if side == 'L_': pm.move(-13, 0, 0, poleVector, relative = True) else: pm.move(13, 0, 0, poleVector, relative = True) pm.parent(poleVector, '%sforearm1' %side) #parent polevector to bone pm.poleVectorConstraint(poleVector, ik[0]) else: pm.poleVectorConstraint(poleVector, ik[0]) #write an if else statement for the 2nd polevector for upper arm if not pm.ls('%supper_pv' %side): poleVectorUpperArm = pm.spaceLocator(name = side + 'upper_pv') pm.xform(poleVectorUpperArm, translation = pm.xform(pm.ls('%supperarm2' %side), query = True, translation = True, worldSpace = True)) pm.parent(poleVectorUpperArm, '%supperarm2' %side) if i.find('UpperArm') != -1: pm.poleVectorConstraint(poleVectorUpperArm, ik[0]) pm.poleVectorConstraint(poleVector, ik[0], remove = True) #creating parent constraints to connect the motions of the sleeve simulation and the export bones pm.parentConstraint(i, exportOrigin, mo = True) pm.parentConstraint(sim, exportSim, mo = True) pm.parent(originJoint, exportOrigin, locator, ik[0], sleeveGroup)#sleeveGroup parent pm.parent('R_sleeve_mesh', 'L_sleeve_mesh', 'Poly') fileRead = open('K:/design/maya/data/tool/scData/Sleeve_Install/sleeve/Sleeve_weight.weightMap', 'r') fileRead.seek(0) boneList = dict() fileRead.readline() fileRead.readline() for i in fileRead.readlines(): x = i.split() if boneList.has_key(x[0]): boneList[x[0]].append(x[1]) else: boneList[x[0]] = [x[1]] print boneList keys = boneList.keys() for i in keys: print i pm.skinCluster(i, boneList[i], tsb = True) fileRead.close() mel.eval('source kkCharaSetup;') pm.select('L_sleeve_mesh') mel.eval('kkCharaSetup_charaWeight_r;') pm.select('R_sleeve_mesh') mel.eval('kkCharaSetup_charaWeight_r;') pm.parent(sleeveGroup, 'CharaA')
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 buildPlayblastWindow(cameras, layer, layer_number, add_float_window, renderers, is_rear_layer=True, \ ratio=2.387, display_elements={}): print 'Start to build playblasting window...' p_window = None p_editor = None center = cameras['center'] try: p_window = pm.window(title='stereo_pb_window', w=512, h=215) form = pm.formLayout() p_editor = pm.modelEditor(displayAppearance='smoothShaded', displayTextures=True, displayLights='default') #print 'set basic display mode' # use viewport engine pm.modelEditor(p_editor, e=True, rnm=renderers) if display_elements['displayLights']: pm.modelEditor(p_editor, e=True, displayLights='all') #print 'set displayLights' # display elements for k,v in display_elements.iteritems(): cmd = 'modelEditor -e -'+k+(' on ' if v else ' off ')+'"'+p_editor.name()+'"' try: pm.mel.eval(cmd) #print 'set '+k except: pass # turn off sortTransparent pm.modelEditor(p_editor, e=True, sortTransparent=False) #print 'turn off sortTransparent' # turn off color management for view port 2.0 #if renderers=='vp2Renderer': # try: # pm.modelEditor(p_editor, e=True, cmEnabled=False) # print 'disable color management for viewport2.0' # except: # pass column = pm.columnLayout('true') pm.formLayout( form, edit=True, attachForm=[(column, 'top', 0), (column, 'left', 0), (p_editor, 'top', 0), (p_editor, 'bottom', 0), (p_editor, 'right', 0)], attachNone=[(column, 'bottom'), (column, 'right')], attachControl=(p_editor, 'left', 0, column)) pm.showWindow( p_window ) except: print traceback.format_exc() # hud display, we disable all available hud, only show the custom value at the top right, and restore the previous hud after playblasting huds_current = [] hud_stereo = 'HudStereo' try: for huds in pm.headsUpDisplay(query=True, lh=True): if pm.headsUpDisplay(huds, query=True, ex=True) and pm.headsUpDisplay(huds, query=True, vis=True): huds_current.append(huds) pm.headsUpDisplay(huds, edit=True, vis=False) if pm.headsUpDisplay(hud_stereo, query=True, ex=True): pm.headsUpDisplay(hud_stereo, rem=True) block = pm.headsUpDisplay(nfb=4) if layer=='near': block = block + 1 elif layer=='far': if layer_number==2: block = block + 1 elif layer_number==3: block = block + 2 try: pm.headsUpDisplay( hud_stereo, ao=True, section=4, block=block, padding=15, blockSize='small', blockAlignment='right', dataAlignment='right', label='', dataFontSize='large', command=pm.Callback(getCustomHUD, str(center), layer), event='timeChanged' ) pm.headsUpDisplay( hud_stereo, refresh=True ) except: print traceback.format_exc() try: pm.toggleAxis(origin=False) pm.viewManip(visible=False) except: print traceback.format_exc() except: for huds in huds_current: if pm.headsUpDisplay(huds, query=True, ex=True): pm.headsUpDisplay(huds, edit=True, vis=True) pm.modelEditor(p_editor, edit=True, hud=False) # create floating window if any safearea = None if add_float_window: try: safearea_inst = sa.SafeArea() safearea_inst.enable() safearea = safearea_inst.safearea try: safearea.attr('useSpReticle').set(0) except: pass safearea.attr('panScanDisplayMode').set(2) safearea.attr('panScanLineTrans').set(1) safearea.attr('panScanMaskTrans').set(0) safearea.attr('panScanRatio').set(ratio) safearea.attr('panScanAspectRatio').set(ratio) except: print traceback.format_exc() # change background color bgColor = None if not is_rear_layer: bgColor = makeBluescreen({}, renderers) # hide stereo layer try: scf.showLayer2(layer) except: print traceback.format_exc() # set up expression for updating hud if pm.headsUpDisplay(hud_stereo, query=True, ex=True) and not pm.objExists('stereoUpdateHUD'): pm.expression(n='stereoUpdateHUD', ae=True, s='headsUpDisplay -r '+hud_stereo) global stereo_pb_window stereo_pb_window = { 'window':p_window, 'editor':p_editor, 'safearea':safearea, 'hud_stereo':hud_stereo, \ 'huds_current':huds_current, 'bgColor':bgColor, 'ratio':ratio} return stereo_pb_window
def mantleCreate(charaHeight=2): #default 2, 160cm height locM = pm.spaceLocator(name='locM') pm.xform(locM, ws=True, translation=[ 8.17948246602115e-16, 126.43254364390185, -8.830608530289298 ], scale=[3, 3, 3]) #shifting it into place locR = pm.spaceLocator(name='locR') pm.xform(locR, ws=True, translation=[-10, 124.043, -9.221], scale=[3, 3, 3]) #shifting it into place locRR = pm.spaceLocator(name='locRR') pm.xform(locRR, ws=True, translation=[-14, 129, -1.6], scale=[3, 3, 3]) #shifting it into place locL = pm.spaceLocator(name='locL') pm.xform(locL, ws=True, translation=[10, 124.043, -9.221], scale=[3, 3, 3]) #shifting it into place locLL = pm.spaceLocator(name='locLL') pm.xform(locLL, ws=True, translation=[14, 129, -1.6], scale=[3, 3, 3]) #shifting it into place heightPosition = {} #order of data is M, R, RR, L, LL heightPosition['1'] = [0, 117.518, -8.237], [-9.25, 115.129, -8.627], [-11, 120.1, -1.00], [9.25, 115.129, -8.627 ], [11, 120.1, -1] #1 = 150cm heightPosition['1sim'] = [0.001, 61.086, -9.781], [-19, 77.696, -9.919], [-28, 120.1, -1], [19, 77.696, -9.919 ], [28, 120.1, -1] heightPosition['2'] = [ 8.17948246602115e-16, 126.43254364390185, -8.830608530289298 ], [-10, 124.043, -9.221], [-14, 129, -1.6], [10, 124.043, -9.221], [14, 129, -1.6] #2 = 160cm heightPosition['2sim'] = [0.001, 70, -11.002], [-21.549, 80, -10.513 ], [-31, 129, -1.6], [21.549, 80, -10.513], [31, 129, -1.6] heightPosition['3'] = [0, 133.789, -13.546], [-11, 131.4, -13.936], [-15, 136.357, -4.721 ], [11, 131.4, -13.936 ], [15, 136.357, -4.721] #3 = 170cm heightPosition['3sim'] = [0.001, 77.357, -15.717], [-25.5, 79, -15.228], [ -32, 136.357, -4.721 ], [25.5, 79, -15.228], [32, 136.357, -4.721] heightPosition['4'] = [0, 157.786, -14.305], [-12, 155, -14.695], [-20, 160.353, -4.5 ], [12, 155, -14.695 ], [20, 160.353, -4.5] #4 = 180cm heightPosition['4sim'] = [0.001, 101.353, -16.476], [-25.75, 100, -15.987], [-37, 160.353, -4.5 ], [25.75, 100, -15.987 ], [37, 160.353, -4.5] #translating the locators to their position pm.xform('loc' + 'M', ws=True, translation=heightPosition['%s' % (charaHeight)][0], scale=[3, 3, 3]) pm.xform('loc' + 'R', ws=True, translation=heightPosition['%s' % (charaHeight)][1], scale=[3, 3, 3]) pm.xform('loc' + 'RR', ws=True, translation=heightPosition['%s' % (charaHeight)][2], scale=[3, 3, 3]) pm.xform('loc' + 'L', ws=True, translation=heightPosition['%s' % (charaHeight)][3], scale=[3, 3, 3]) pm.xform('loc' + 'LL', ws=True, translation=heightPosition['%s' % (charaHeight)][4], scale=[3, 3, 3]) locList = [locM, locR, locRR, locL, locLL] locDict = {} locSimList = [] for i in locList: sim = pm.duplicate(i, name=i[:3] + '_sim' + i[3:]) locSimList.append(i) locDict[i] = sim #translating the sim locators to their positions pm.xform('loc_sim' + 'M', ws=True, translation=heightPosition['%ssim' % (charaHeight)][0], scale=[3, 3, 3]) pm.xform('loc_sim' + 'R', ws=True, translation=heightPosition['%ssim' % (charaHeight)][1], scale=[3, 3, 3]) pm.xform('loc_sim' + 'RR', ws=True, translation=heightPosition['%ssim' % (charaHeight)][2], scale=[3, 3, 3]) pm.xform('loc_sim' + 'L', ws=True, translation=heightPosition['%ssim' % (charaHeight)][3], scale=[3, 3, 3]) pm.xform('loc_sim' + 'LL', ws=True, translation=heightPosition['%ssim' % (charaHeight)][4], scale=[3, 3, 3]) #____________________________________________________________________________________________________________________________________________________ #locList = pm.ls('locM', 'locR','locRR', 'locL', 'locLL')#recreate the list data #locSimList = pm.ls('loc_simM', 'loc_simR','loc_simRR', 'loc_simL', 'loc_simLL')#recreating the list data #locDict = {} #for i in locList: # locDict[i] = pm.ls(i[:3] + '_sim' + i[3:]) #create mantle control mantContr = mel.eval( 'curve -d 1 -p -0.5 1 0.866025 -p 0.5 1 0.866025 -p 0.5 -1 0.866025 -p 1 -1 0 -p 1 1 0 -p 0.5 1 -0.866025 -p 0.5 -1 -0.866025 -p -0.5 -1 -0.866026 -p -0.5 1 -0.866026 -p -1 1 -1.5885e-007 -p -1 -1 -1.5885e-007 -p -0.5 -1 0.866025 -p -0.5 1 0.866025 -p -1 1 -1.5885e-007 -p -0.5 1 -0.866026 -p 0.5 1 -0.866025 -p 1 1 0 -p 0.5 1 0.866025 -p 0.5 -1 0.866025 -p -0.5 -1 0.866025 -p -1 -1 -1.5885e-007 -p -0.5 -1 -0.866026 -p 0.5 -1 -0.866025 -p 1 -1 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 -k 15 -k 16 -k 17 -k 18 -k 19 -k 20 -k 21 -k 22 -k 23 -n "controller1" ;' ) mantContr = pm.rename(mantContr, 'mantle_Control') pm.addAttr(mantContr, longName='Drag', attributeType='short', keyable=True, defaultValue=5, minValue=0) #adding drag attribute pm.select(deselect=True) #deselect so it won't be the child of anything mantleParent = pm.joint(name='mantleParent', position=pm.xform('locM', query=True, worldSpace=True, translation=True), radius=2.5) #creating mantle parent #main joints jointList = {} for i in locList: pm.select(deselect=True) #deselect so it is parented to world j = pm.joint(name='joint' + i[3:], position=pm.xform(i, query=True, worldSpace=True, translation=True), radius=2.5) jointList[j] = None #setting transform and rotation limits if i[2:5] == 'cR': pm.transformLimits(j, rotationX=[-5, 90], rotationY=[-45, 45], rotationZ=[-45, 25], erx=[True, True], ery=[True, True], erz=[True, True]) elif i[2:5] == 'cM': pm.transformLimits(j, rotationX=[-5, 90], rotationY=[-45, 45], rotationZ=[-15, 15], erx=[True, True], ery=[True, True], erz=[True, True]) elif i[2:5] == 'cL': pm.transformLimits(j, rotationX=[-5, 90], rotationY=[-45, 45], rotationZ=[-25, 45], erx=[True, True], ery=[True, True], erz=[True, True]) #main sims for i in jointList: pm.select(i) #selecting so it is parented to parent joint sim = pm.joint(name='sim' + i[5:], position=pm.xform('loc_sim' + i[5:], query=True, worldSpace=True, translation=True), radius=1.5) jointList[i] = sim if i[5:] == 'LL' or i[5:] == 'RR': print('re-orient' + i) pm.joint( i, edit=True, orientJoint='xyz', secondaryAxisOrient='zup', zeroScaleOrient=True ) #orienting joint so it move appropriately from UpperArm2 pm.select(deselect=True) for i in jointList: #selecting joints pm.select(i, add=True) pm.parent(pm.ls(sl=True), mantleParent) #calc calcList = [] mantGroup = pm.group(name='mantleGroup', world=True, empty=True) #creating calc joints for i in pm.listRelatives(mantleParent): cal = pm.duplicate(i, name=i[:7] + '_Calc', parentOnly=True) pm.parent(cal, mantGroup) spaceLoc = pm.spaceLocator(name='simLoc_' + i[5:]) #creating simloc locator pm.xform(spaceLoc, ws=True, translation=pm.xform(i, query=True, translation=True, ws=True)) #moving it to the right place pm.xform(spaceLoc, relative=True, translation=[0, -25.627, 0]) pm.addAttr(spaceLoc, longName='momentumX', attributeType='float') pm.addAttr(spaceLoc, longName='momentumY', attributeType='float') pm.addAttr(spaceLoc, longName='momentumZ', attributeType='float') #creating expression to drive the SimLoc's translations pm.expression( object=spaceLoc, name=spaceLoc + '_translationExp', string= '$f = `currentTime -q`;\n$lastposX = `getAttr -t ($f - mantle_Control.Drag) %s.translateX`;\n%s.translateX = %s.translateX - (%s.translateX - $lastposX);\n$lastposY = `getAttr -t ($f - mantle_Control.Drag) %s.translateY`;\n%s.translateY = %s.translateY - (%s.translateY - $lastposY) - 25.627;\n$lastposZ = `getAttr -t ($f - mantle_Control.Drag) %s.translateZ`;\n%s.translateZ = %s.translateZ - (%s.translateZ - $lastposZ);' % (cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0])) ''' '$f = `currentTime -q`;\n $lastposX = `getAttr -t ($f - mantle_Control.Drag) %s.translateX`;\n %s.translateX = %s.translateX - (%s.translateX - $lastposX);\n $lastposY = `getAttr -t ($f - mantle_Control.Drag) %s.translateY`;\n %s.translateY = %s.translateY - (%s.translateY - $lastposY) - 25.627;\n $lastposZ = `getAttr -t ($f - mantle_Control.Drag) %s.translateZ`;\n %s.translateZ = %s.translateZ - (%s.translateZ - $lastposZ);' %(cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0]) ''' #create expression for the momentum attributes if i[5:] == 'R': xVar = '- 0.000001' else: xVar = '+ 0.000001' pm.expression( object=spaceLoc, name=spaceLoc + '_momentumExp', string= '%s.momentumX = %s.translateX - %s.translateX %s;\n%s.momentumY = %s.translateY - %s.translateY;\n%s.momentumZ = %s.translateZ - %s.translateZ + 0.001;' % (spaceLoc, cal[0], spaceLoc, xVar, spaceLoc, cal[0], spaceLoc, spaceLoc, cal[0], spaceLoc)) ''' %s.momentumX = %s.translateX - %s.translateX %s;\n %s.momentumY = %s.translateY - %s.translateY;\n %s.momentumZ = %s.translateZ - %s.translateZ + 0.001;' % (spaceLoc, cal, spaceloc, xVar, spaceLoc, cal, spaceloc, spaceLoc, cal, spaceloc) '%s.momentumX = %s.translateX - %s.translateX %s;\n%s.momentumY = %s.translateY - %s.translateY;\n%s.momentumZ = %s.translateZ - %s.translateZ + 0.001;' % (spaceLoc, cal[0], spaceLoc, xVar, spaceLoc, cal[0], spaceLoc, spaceLoc, cal[0], spaceLoc) ''' pm.parent(spaceLoc, mantGroup) if not cal[0][5:7] == 'RR' and not cal[0][5:7] == 'LL': calcList.append(cal[0]) #creating transform limits for calc joints pm.transformLimits(cal[0], rotationX=[-5, 360], enableRotationY=[True, False]) pm.delete( 'simLoc_RR', 'simLoc_LL', 'jointRR_Calc', 'jointLL_Calc') #deleting the RR and LL simlocs that we won't need pm.parent(mantleParent, 'spine2') #parenting main joints into joint hierarchy #calcDriver calcDriver = pm.duplicate( mantleParent, parentOnly=True, name='mantleCalcDriver') #creating calcDriver joints for i in pm.listRelatives(mantleParent): j = pm.duplicate(i, name=i[:7] + '_CalcDriver', parentOnly=True) pm.parent(j, calcDriver) #trigo trigoJointList = [] trigoParent = pm.duplicate(mantleParent, parentOnly=True, name='mantle_trigo') #creating trigoJoints for i in pm.listRelatives(mantleParent): trigoJoint = pm.duplicate(i, name=i[:7] + '_trigo') sim = pm.rename(pm.listRelatives(trigoJoint[0]), 'sim' + i[5:] + '_trigo') pm.parent(trigoJoint, trigoParent) if not (str(trigoJoint[0][5:7]) == 'RR') and not (str( trigoJoint[0][5:7]) == 'LL'): trigoJointList.append(trigoJoint[0]) #creating transform limits pm.transformLimits(trigoJoint[0], rotationY=[-45, 45], ery=[True, True]) if trigoJoint[0][5:7] == 'RR' or trigoJoint[0][ 5: 7] == 'LL': #performing parentConstraint from upperarm2 to RR or LL joint print('RR or LL joint constrained to upper arm') pm.joint( trigoJoint[0], edit=True, orientJoint='xyz', secondaryAxisOrient='zup', zeroScaleOrient=True ) #orienting joint so it move appropriately from UpperArm2 pm.parentConstraint(trigoJoint[0][5] + '_upperarm2', trigoJoint[0], mo=True) #write a combined trigo expression pm.expression( object=trigoJointList[0], name=trigoJointList[0] + '_trigoExp', string= '%s.rotateX = atand(%s.momentumZ/%s.momentumY) - pelvis.rotateX - spine1.rotateZ - spine2.rotateZ;\n%s.rotateY = atand(%s.momentumX/%s.momentumZ) - pelvis.rotateY - spine1.rotateX - spine2.rotateX;\n%s.rotateX = atand(%s.momentumZ/%s.momentumY) - pelvis.rotateX - spine1.rotateZ - spine2.rotateZ;\n%s.rotateY = atand(%s.momentumX/%s.momentumZ) - pelvis.rotateY - spine1.rotateX - spine2.rotateX;\n%s.rotateX = atand(%s.momentumZ/%s.momentumY) - pelvis.rotateX - spine1.rotateZ - spine2.rotateZ;\n%s.rotateY = atand(%s.momentumX/%s.momentumZ) - pelvis.rotateY - spine1.rotateX - spine2.rotateX;' % (trigoJointList[1], 'simLoc_' + trigoJointList[1][5], 'simLoc_' + trigoJointList[1][5], trigoJointList[1], 'simLoc_' + trigoJointList[1][5], 'simLoc_' + trigoJointList[1][5], trigoJointList[0], 'simLoc_' + trigoJointList[0][5], 'simLoc_' + trigoJointList[0][5], trigoJointList[0], 'simLoc_' + trigoJointList[0][5], 'simLoc_' + trigoJointList[0][5], trigoJointList[2], 'simLoc_' + trigoJointList[2][5], 'simLoc_' + trigoJointList[2][5], trigoJointList[2], 'simLoc_' + trigoJointList[2][5], 'simLoc_' + trigoJointList[2][5])) ''' %s.rotateX = atand(%s.momentumZ/%s.momentumY) - pelvis.rotateX - spine1.rotateZ - spine2.rotateZ;\n jointR_Driver1.rotateY = atand(simLocR1.momentumX/simLocR1.momentumZ) - pelvis.rotateY - spine1.rotateX - spine2.rotateX;\n jointM_Driver1.rotateX = atand(simLocM1.momentumZ/simLocM1.momentumY) - pelvis.rotateX - spine1.rotateZ - spine2.rotateZ;\n jointM_Driver1.rotateY = atand(simLocM1.momentumX/simLocM1.momentumZ) - pelvis.rotateY - spine1.rotateX - spine2.rotateX;\n jointL_Driver1.rotateX = atand(simLocL1.momentumZ/simLocL1.momentumY) - pelvis.rotateX - spine1.rotateZ - spine2.rotateZ;\n jointL_Driver1.rotateY = atand(simLocL1.momentumX/simLocL1.momentumZ) - pelvis.rotateY - spine1.rotateX - spine2.rotateX;\n % (trigoJointList[1], 'simLoc' + trigoJointList[1][5], 'simLoc' + trigoJointList[1][5], trigoJointList[1], 'simLoc' + trigoJointList[1][5], 'simLoc' + trigoJointList[1][5], trigoJointList[0], 'simLoc' + trigoJointList[0][5], 'simLoc' + trigoJointList[0][5], trigoJointList[0], 'simLoc' + trigoJointList[0][5], 'simLoc' + trigoJointList[0][5], trigoJointList[2], 'simLoc' + trigoJointList[2][5], 'simLoc' + trigoJointList[2][5], trigoJointList[2], 'simLoc' + trigoJointList[2][5], 'simLoc' + trigoJointList[2][5]) ''' #create the constraints for calcDriver -> calc for i in calcList: pm.parentConstraint(i + 'Driver', i, mo=False) #create IK for i in trigoJointList: ik = pm.ikHandle(name='ikHandle' + i[5], sj=i[:6], ee=pm.listRelatives(i[:6])[0], solver='ikRPsolver')[0] pm.parent(ik, mantleParent) pm.parentConstraint(pm.listRelatives(i)[0], ik, mo=False, weight=1) #create constraints between trigo and IK #if i[5] != 'M': #pm.parentConstraint('sim' + i[5] + i[5] + '_trigo', ik, mo = True, weight = 0.25) #creating another parent constraint for the LL and RR to affect the R pm.parentConstraint('jointRR_trigo', 'jointRR', mo=True) pm.parentConstraint('jointLL_trigo', 'jointLL', mo=True) pm.delete(locList, locSimList, locDict) #deleting unnecessary stuff used to create the rig if charaHeight == 1: #importing mantle Mesh cmds.file( 'K:/design/maya/data/tool/scData/Mant/mantMesh/mantMesh150.ma', i=True) elif charaHeight == 2: cmds.file( 'K:/design/maya/data/tool/scData/Mant/mantMesh/mantMesh160.ma', i=True) elif charaHeight == 3: cmds.file( 'K:/design/maya/data/tool/scData/Mant/mantMesh/mantMesh170.ma', i=True) #adjust address later elif charaHeight == 4: cmds.file( 'K:/design/maya/data/tool/scData/Mant/mantMesh/mantMesh180.ma', i=True) #adjust address later if not charaHeight == 0: pm.skinCluster(pm.listRelatives(mantleParent), mantleParent, 'mantMesh', toSelectedBones=True) pm.select('mantMesh') mel.eval('source kkCharaSetup;kkCharaSetup_charaWeight_r;' ) #imports weights from data embedded inside already
def setupStretchyIk(name="leg"): 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() 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, name + "_guide_ik_%s" % 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, name + "_guide_%s" % n[:-1]) # positions and length 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] length = start_point.distanceTo(end_point) # Create Control control = rigging.createNurbsShape("%s_control" % name, width=length * 0.2, height=length * 0.2, depth=length * 0.2) control.translate.set(end_point / end_point[-1]) pm.makeIdentity(apply=True, s=0, r=0, t=1, n=0) parent_group = pm.group(name="%s_stretch_ik" % name, em=1) if parent_joint is not None: parent_group.setRotatePivot(parent_joint.getRotatePivot(ws=1), 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="%s_loc_start" % name, em=1) pm.parent(loc_start, parent_group) loc_start.setRotatePivot(start_joint.getRotatePivot(ws=1), ws=1) pm.aimConstraint(control, loc_start, weight=1, aimVector=(1, 0, 0)) loc_end = pm.group(n="%s_loc_end" % name, em=1, parent=loc_start) loc_end.setRotatePivot(start_joint.getRotatePivot(ws=1), 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) mid_point = temp_end.getRotatePivot(ws=1) pm.delete(temp_start) # create the mid locator loc_mid = pm.group(n="%s_loc_mid" % name, em=1) # spaceLocator() loc_mid.translate.set(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="%s_loc_guide" % name, 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) pm.delete(guide_ik_end) pm.rename(guide_ik, "%s_guide_ik" % name) pm.rename(guide_ee, "%s_guide_effector" % name) # 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(1) # hook up the original joints main_ik, main_ee = pm.ikHandle(sj=start_joint, ee=end_joint) pm.rename(main_ik, "%s_ik" % name) pm.rename(main_ee, "%s_effector" % name) pm.parent(guide_ik, loc_end) pm.parent(main_ik, guide_ik, control) # add stretch addtributes start_joint.addAttr("stretch", at="double", k=1, dv=1) mid_joint.addAttr("stretch", at="double", k=1, dv=1) control.addAttr("stretchBlend", at="double", k=1, dv=1) # 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) # build the expression exp_str = """ $stretch_blend = linstep( %(guide_ik)s.stretchStart, %(guide_ik)s.stretchEnd, %(loc_end)s.tx); %(constraint)s.%(loc_mid)sW0 = $stretch_blend; %(constraint)s.%(guide_ik_mid)sW1 = 1-$stretch_blend; %(start_joint)s.scaleX = %(start_joint)s.stretch + ( abs( %(guide_mid)s.translateX ) - abs( %(mid_joint)s.translateX ) ) * %(guide_ik)s.stretchFactor * %(control)s.stretchBlend; %(mid_joint)s.scaleX = %(mid_joint)s.stretch + ( abs( %(guide_end)s.translateX ) - abs( %(end_joint)s.translateX ) ) * %(guide_ik)s.stretchFactor * %(control)s.stretchBlend; """ % { "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, } pm.expression(s=exp_str, o="", n="%s_EXP" % start_joint, a=1, uc="all") # make things look pretty for n in pm.ls([parent_group, main_ik, guide_ik], dag=1): n.visibility.set(0) try: pm.delete(guide_end.getChildren()[0]) except: pass try: pm.delete(guide_ik_end.getChildren()[0]) except: pass control.displayHandle.set(1) pm.select(control, r=1) """
def createParticleEmitter(self, meshEmitter, collider): # Force nParticle balls at creation pm.optionVar(sv=("NParticleStyle", "Balls")) self.particle, self.partShape = pm.nParticle(n=str(meshEmitter) + "_particle") # Add attribute in particleShape pm.addAttr(self.partShape, ln="indexPP", dt="doubleArray") pm.addAttr(self.partShape, ln="rotatePP", dt="vectorArray") pm.addAttr(self.partShape, ln="scalePP", dt="vectorArray") pm.addAttr(self.partShape, ln="rgbPP", dt="vectorArray") pm.addAttr(self.partShape, ln="fixPosPP", dt="vectorArray") pm.addAttr(self.partShape, ln="opacityPP", dt="doubleArray") pm.addAttr(self.partShape, ln="typePP", dt="doubleArray") self.nameEmitter = str(meshEmitter) + "_emitter" pm.emitter(meshEmitter, type="surface", name=self.nameEmitter, r=float(self.ui.simulationEmit_le.text())) pm.connectDynamic(self.partShape, em=self.nameEmitter) # Used maya command because pymel crash when find nucleus node self.nucleusName = mel.eval('listConnections -type "nucleus" ' + self.partShape + ";")[0] pm.parent(self.partShape, self.worldParent) pm.parent(self.nameEmitter, self.worldParent) pm.parent(self.nucleusName, self.worldParent) self.setParamaters(self.partShape, self.particleParameter) self.setParamaters(self.nameEmitter, self.emitterParameter) self.setParamaters(self.nucleusName, self.nucleusParameter) pm.addAttr(self.partShape, ln="radiusPP", dt="doubleArray") # Create Rigid pm.select(collider, r=1) pm.runtime.nClothMakeCollide(collider) self.nrigid = pm.listConnections(collider.listRelatives(s=1, c=1)[0], type="nRigid")[0] self.setParamaters(self.nrigid.listRelatives(s=1, c=1)[0], self.rigidParameter) pm.parent(self.nrigid, self.worldParent) self.nrigid.setAttr("v", 0) # Create instancer self.instancer = pm.particleInstancer( self.partShape, a=True, object=self.listInstance, n=str(meshEmitter) + "_instancer", cycle="sequential", age="indexPP", rotation="rotatePP", scale="scalePP", visibility="opacityPP", ) pm.parent(self.instancer, self.worldParent) # Create proc Colision expression = """ global proc forestGeneratorEvent(string $particleObject,int $particleId, string $geometryObject) { vector $rgb = `nParticle -attribute rgbPP -id $particleId -q $particleObject`; if ($rgb != << 1,1,1 >>) { nParticle -e -attribute rgbPP -id $particleId -vv 0 1 0 $particleObject; } vector $pos = `nParticle -attribute position -id $particleId -q $particleObject`; vector $lastPos = `nParticle -attribute lastPosition -id $particleId -q $particleObject`; nParticle -e -attribute opacityPP -id $particleId -fv 1 $particleObject; if (mag($pos - $lastPos) >= 10 && $rgb != << 1,1,1 >>){ nParticle -e -attribute lifespanPP -id $particleId -fv 0 $particleObject; } }""" pm.expression(s=expression, n="forestGenerator_exp") # Create Colision event pm.event(self.partShape, die=0, count=0, proc="forestGeneratorEvent")
def addTwistControls(controlChain, boundChain, boundEnd, influenceDist=3): ''' Put a rotation controller under each child of the controlChain to drive .rz of the boundChain. They must both be the same size. :param Joint controlChain: The first joint of the controlling rig (ideally pruned) :param Joint boundChain: The first joint of joints being controlled by the spline. :param Joint boundEnd: The last joint in the bound chain, used to address possible branching. :param int influenceDist: How many adjacent joints are influenced (total # is 2x since it influences both directions). ''' obj = controlChain[0] target = boundChain #controlJoints = getChain( controlChain, findChild(controlChain, shortName(boundEnd)) ) controlJoints = controlChain boundJoints = util.getChain( boundChain, util.findChild(boundChain, pdil.shortName(boundEnd)) ) assert len(controlJoints) == len(boundJoints), "Failure when adding twist controls, somehow the chains don't match length, contorls {0} != {1}".format( len(controlJoints), len(boundJoints) ) controls = [] groups = [] pointConstraints = [] orientConstraints = [] for i, (obj, target) in enumerate(zip(controlJoints, boundJoints)): c = controllerShape.simpleCircle() c.setParent(obj) c.t.set(0, 0, 0) c.r.set(0, 0, 0) controls.append(c) spinner = group(em=True, name='spinner%i' % i, p=target) spinner.r.set(0, 0, 0) spinner.setParent(obj) spinner.t.set(0, 0, 0) # Aligning the spinners to the bound joint means we don't have to offset # the orientConstraint which means nicer numbers. # spinner.setRotation( target.getRotation(space='world'), space='world' ) groups.append(spinner) pointConstraints.append( pdil.constraints.pointConst( obj, target, maintainOffset=False ) ) orientConstraints.append( pdil.constraints.orientConst( spinner, target, maintainOffset=False ) ) children = obj.listRelatives(type='joint') if children: obj = children[0] else: obj = None break for pSrc, pDest in zip( pointConstraints[:-1], pointConstraints[1:]): pSrc >> pDest for oSrc, oDest in zip( orientConstraints[:-1], orientConstraints[1:]): oSrc >> oDest # &&& This and the i+7 reflect the number of controls that influence bigList = [None] * influenceDist + controls + [None] * influenceDist influenceRange = (influenceDist * 2) + 1 axis = util.identifyAxis(controlChain[0].listRelatives(type='joint')[0]) exp = [] for i, spinner in enumerate(groups): exp.append(driverExpression( spinner, bigList[i: i + influenceRange], axis )) expression( s=';\n'.join(exp) ) return controls, util.ConstraintResults( pointConstraints[0], orientConstraints[0] )
def volumeConservation( ikHandleTorso, curveInfoNodeBack, jntList, opt = 1 ): pymelLogger.debug('Starting: volumeConservation()...') # for now volumeConservation inclues yes and no # List with all joints endJnt = len(jntList)-1 jntToScale = jntList[:-1] if opt == 0: # Connect output x of the multiplydivide node to the x scale of the joint # (or the axis that goes down the joint) # Do not connect the end joint for jnt in jntToScale: pm.connectAttr( curveInfoNodeBack + '.normalizedScale', jnt + '.scaleX') else: # if volume # following jasons techniques # we will create a anim curve that will be used to determine # the scaling power of the joints # Add Attr to curve (scalePower) this will let us control the curve pm.addAttr(ikHandleTorso[2], longName='scalePower', attributeType='double') # Make it keyable pm.setAttr(ikHandleTorso[2] + '.scalePower', keyable = True) # Get total number of joints to scale # this will be the range we will have to keyframe # we will put keyframe on 1 and another at X (depending on how many joints are created) numOfJnts = len(jntToScale) # Set the two keyframes pm.setKeyframe(ikHandleTorso[2], attribute = 'scalePower', time = 1, value = 0) pm.setKeyframe(ikHandleTorso[2], attribute = 'scalePower', time = numOfJnts, value = 0) # We configure the shape of the animation curve # weightingtangents and setting an out and in angle pm.keyTangent(ikHandleTorso[2], weightedTangents=True, weightLock = False, attribute = 'scalePower') pm.keyTangent(ikHandleTorso[2], edit=True, absolute = True, time=(1,numOfJnts), outAngle=50, attribute = 'scalePower') pm.keyTangent(ikHandleTorso[2], edit=True, absolute = True, time=(numOfJnts,numOfJnts), inAngle=-50, attribute = 'scalePower') # Creating a frameCache for each joint to be scaled # Connecting scalePower to each frameCache Stream fCount = 1 for jnt in jntToScale: frameC = pm.createNode('frameCache', name = jnt + '_'+Names.suffixes['frameCache']) pm.connectAttr(ikHandleTorso[2] + '.scalePower', frameC + '.stream') # set frame number pm.setAttr(frameC+'.vt', fCount) fCount += 1 # Create Attr Pow for each joint powJnt = pm.addAttr(jnt, longName='pow', attributeType='double') pm.setAttr(jnt + '.pow', keyable = True) # Connect Attr varying to jnt.pow pm.connectAttr(frameC + '.v', jnt + '.pow', force=True) # Writing the expression to apply the scale expr = '$scale = ' + curveInfoNodeBack + '.normalizedScale;\n' # inv scale expr += '$sqrt = 1/sqrt($scale);\n' for jnt in jntToScale: # x joint scale expr += jnt+'.scaleX = $scale;\n' expr += jnt+'.scaleY = pow($sqrt,'+jnt+'.pow);\n' expr += jnt+'.scaleZ = pow($sqrt,'+jnt+'.pow);\n' # Create expression expressionNode = pm.expression(string=expr, name=ikHandleTorso[2]+'_'+Names.suffixes['expression']) rList = [expr, expressionNode] return rList pymelLogger.debug('End: volumeConservation()...')
def volumeConservation(ikHandleTorso, curveInfoNodeBack, jntList, opt=1): pymelLogger.debug('Starting: volumeConservation()...') # for now volumeConservation inclues yes and no # List with all joints endJnt = len(jntList) - 1 jntToScale = jntList[:-1] if opt == 0: # Connect output x of the multiplydivide node to the x scale of the joint # (or the axis that goes down the joint) # Do not connect the end joint for jnt in jntToScale: pm.connectAttr(curveInfoNodeBack + '.normalizedScale', jnt + '.scaleX') else: # if volume # following jasons techniques # we will create a anim curve that will be used to determine # the scaling power of the joints # Add Attr to curve (scalePower) this will let us control the curve pm.addAttr(ikHandleTorso[2], longName='scalePower', attributeType='double') # Make it keyable pm.setAttr(ikHandleTorso[2] + '.scalePower', keyable=True) # Get total number of joints to scale # this will be the range we will have to keyframe # we will put keyframe on 1 and another at X (depending on how many joints are created) numOfJnts = len(jntToScale) # Set the two keyframes pm.setKeyframe(ikHandleTorso[2], attribute='scalePower', time=1, value=0) pm.setKeyframe(ikHandleTorso[2], attribute='scalePower', time=numOfJnts, value=0) # We configure the shape of the animation curve # weightingtangents and setting an out and in angle pm.keyTangent(ikHandleTorso[2], weightedTangents=True, weightLock=False, attribute='scalePower') pm.keyTangent(ikHandleTorso[2], edit=True, absolute=True, time=(1, numOfJnts), outAngle=50, attribute='scalePower') pm.keyTangent(ikHandleTorso[2], edit=True, absolute=True, time=(numOfJnts, numOfJnts), inAngle=-50, attribute='scalePower') # Creating a frameCache for each joint to be scaled # Connecting scalePower to each frameCache Stream fCount = 1 for jnt in jntToScale: frameC = pm.createNode('frameCache', name=jnt + '_' + Names.suffixes['frameCache']) pm.connectAttr(ikHandleTorso[2] + '.scalePower', frameC + '.stream') # set frame number pm.setAttr(frameC + '.vt', fCount) fCount += 1 # Create Attr Pow for each joint powJnt = pm.addAttr(jnt, longName='pow', attributeType='double') pm.setAttr(jnt + '.pow', keyable=True) # Connect Attr varying to jnt.pow pm.connectAttr(frameC + '.v', jnt + '.pow', force=True) # Writing the expression to apply the scale expr = '$scale = ' + curveInfoNodeBack + '.normalizedScale;\n' # inv scale expr += '$sqrt = 1/sqrt($scale);\n' for jnt in jntToScale: # x joint scale expr += jnt + '.scaleX = $scale;\n' expr += jnt + '.scaleY = pow($sqrt,' + jnt + '.pow);\n' expr += jnt + '.scaleZ = pow($sqrt,' + jnt + '.pow);\n' # Create expression expressionNode = pm.expression(string=expr, name=ikHandleTorso[2] + '_' + Names.suffixes['expression']) rList = [expr, expressionNode] return rList pymelLogger.debug('End: volumeConservation()...')
def doRig(self): anchorList = [] cntrlList = [] locList = [] dummyCrv = self.ribbonDict['moveallSetup']['nameTempl'] + '_dummy_crv' pm.hide(pm.polyCube(n=dummyCrv)) if pm.objExists(self.ribbonDict['noMoveSetup']['nameTempl']): pm.delete(self.ribbonDict['noMoveSetup']['nameTempl']) if pm.objExists(self.ribbonDict['moveallSetup']['nameTempl']): pm.delete(self.ribbonDict['moveallSetup']['nameTempl']) logger ###Estrutura que nao deve ter transformacao noMoveSpace = pm.group(empty=True, n=self.ribbonDict['noMoveSetup']['nameTempl']) if not pm.objExists('NOMOVE'): pm.group(self.ribbonDict['noMoveSetup']['nameTempl'], n='NOMOVE') else: pm.parent(self.ribbonDict['noMoveSetup']['nameTempl'], 'NOMOVE') pm.parent(self.ribbonDict['moveallSetup']['nameTempl'] + '_dummy_crv', noMoveSpace) noMoveSpace.visibility.set(0) noMoveBend1 = pm.nurbsPlane(p=(self.size * 0.5, 0, 0), ax=(0, 0, 1), w=self.size, lr=0.1, d=3, u=5, v=1) # noMoveCrvJnt = pm.curve ( bezier=True, d=3, p=[(self.size*-0.5,0,0),(self.size*-0.4,0,0),(self.size*-0.1,0,0),(0,0,0),(self.size*0.1,0,0),(self.size*0.4,0,0),(self.size*0.5,0,0)], k=[0,0,0,1,1,1,2,2,2]) noMoveCrvJnt = pm.curve( bezier=True, d=3, p=[(self.size * -0.50, 0, 0), (self.size * -0.499, 0, 0), (self.size * -0.496, 0, 0), (self.size * -0.495, 0, 0), (self.size * -0.395, 0, 0), (self.size * -0.10, 0, 0), (0, 0, 0), (self.size * 0.10, 0, 0), (self.size * 0.395, 0, 0), (self.size * 0.495, 0, 0), (self.size * 0.496, 0, 0), (self.size * 0.499, 0, 0), (self.size * 0.50, 0, 0)], k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10]) noMoveCrvJnt.translate.set(self.size * 0.5, 0, 0) # Deformers das superficies noMove twist1 = pm.nonLinear(noMoveBend1[0], type='twist') # twist das superficies noMove twist1[1].rotateZ.set(90) # IMPLEMENTAR O TWIST DO MEIO twist2 = pm.nonLinear(noMoveBend1[0].name() + '.cv[0:3][0:3]', type='twist') # twist das superficies noMove twist2[1].rotateZ.set(90) twist3 = pm.nonLinear(noMoveBend1[0].name() + '.cv[4:7][0:3]', type='twist') # twist das superficies noMove twist3[1].rotateZ.set(90) wireDef = pm.wire(noMoveBend1[0], w=noMoveCrvJnt, dds=[(0, 50)]) # Wire das superficies noMove wireDef[0].rotation.set(1) # seta rotacao pra acontecer baseWire = [ x for x in wireDef[0].connections() if 'BaseWire' in x.name() ] pm.group(baseWire, noMoveCrvJnt, noMoveBend1[0], p=noMoveSpace, n=self.name + 'Deforms_grp') pm.parent(twist1[1], twist2[1], twist3[1], noMoveSpace) ###Estrutura que pode ser movida cntrlsSpace = pm.group(empty=True, n=self.ribbonDict['moveallSetup']['nameTempl']) bendSurf1 = pm.nurbsPlane(p=(self.size * -0.5, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) blend1 = pm.blendShape(noMoveBend1[0], bendSurf1[0]) pm.blendShape(blend1, e=True, w=[(0, 1)]) pm.parent(bendSurf1[0], cntrlsSpace) ##Cntrls for i in range(0, 7): anchor = pm.cluster(noMoveCrvJnt.name() + '.cv[' + str(i + 3) + ']') pm.cluster(anchor[1], e=True, g=dummyCrv) clsHandle = anchor[1] anchorGrp = pm.group(em=True, n='clusterGrp' + str(i)) anchorDrn = pm.group(em=True, n='clusterDrn' + str(i), p=anchorGrp) pos = pm.xform(anchor, q=True, ws=True, rp=True) pm.xform(anchorGrp, t=pos, ws=True) pm.parent(anchor[1], anchorDrn) anchorList.append(anchor[1]) if i == 0 or i == 6: displaySetup = self.ribbonDict['cntrlSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) elif i == 3: displaySetup = self.ribbonDict['midCntrlSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) else: displaySetup = self.ribbonDict['cntrlTangSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) # Nao pode fazer conexao na criacao do controle, pois tera conexao direta pm.xform(cntrl.getParent(), t=pos, ws=True) # estrutura de buffers para conexao direta auxLocGrp = pm.group(em=True, n=self.name + 'auxLoc_grp') auxLoc = pm.group(em=True, p=auxLocGrp, n=self.name + 'aux_loc') pm.xform(auxLocGrp, t=pos, ws=True) loc = pm.PyNode(auxLoc) if i == 1 or i == 4: pm.xform(anchorGrp, s=(-1, 1, 1), r=True) pm.xform(cntrl.getParent(), s=(-1, 1, 1), r=True) pm.xform(loc.getParent(), s=(-1, 1, 1), r=True) # Conexoes dos buffers cm os clusters e com os controles pm.parentConstraint(cntrl, loc) loc.translate >> anchorDrn.translate loc.rotate >> anchorDrn.rotate cntrlList.append(cntrl) locList.append(loc) startCls = pm.cluster(noMoveCrvJnt.name() + '.cv[0:2]') endCls = pm.cluster(noMoveCrvJnt.name() + '.cv[10:14]') pm.cluster(startCls[1], e=True, g=dummyCrv) pm.cluster(endCls[1], e=True, g=dummyCrv) pm.parent(startCls, anchorList[0]) pm.parent(endCls, anchorList[6]) cntrlsSpace.addAttr('cntrlsVis', at='double', dv=1, k=True, h=False) cntrlsSpace.addAttr('extraCntrlsVis', at='double', dv=0, k=True, h=False) cntrlList[0].addAttr('twist', at='double', dv=0, k=True) cntrlList[0].addAttr('stretchDist', at='double', dv=0, k=True) cntrlList[0].addAttr('autoVolumStregth', at='double', dv=0, k=True) cntrlList[3].addAttr('twist', at='double', dv=0, k=True) cntrlList[3].addAttr('autoVolume', at='double', dv=0, k=True) cntrlList[6].addAttr('twist', at='double', dv=0, k=True) cntrlList[6].addAttr('stretchDist', at='double', dv=0, k=True) cntrlList[6].addAttr('autoVolumStregth', at='double', dv=0, k=True) cntrlList[0].twist >> twist1[0].endAngle cntrlList[3].twist >> twist2[0].startAngle cntrlList[3].twist >> twist3[0].endAngle cntrlList[6].twist >> twist1[0].startAngle # hierarquia pm.parent(anchorList[1].getParent(2), anchorList[0]) pm.parent(anchorList[5].getParent(2), anchorList[6]) pm.parent(anchorList[2].getParent(2), anchorList[4].getParent(2), anchorList[3]) pm.parent(cntrlList[1].getParent(), cntrlList[0]) pm.parent(cntrlList[5].getParent(), cntrlList[6]) pm.parent(cntrlList[2].getParent(), cntrlList[4].getParent(), cntrlList[3]) pm.parent(cntrlList[3].getParent(), cntrlList[0].getParent(), cntrlList[6].getParent(), cntrlsSpace) pm.parent(locList[1].getParent(), locList[0]) pm.parent(locList[5].getParent(), locList[6]) pm.parent(locList[2].getParent(), locList[4].getParent(), locList[3]) pm.parent(locList[3].getParent(), locList[0].getParent(), locList[6].getParent(), cntrlsSpace) pm.parent(anchorList[3].getParent(2), anchorList[0].getParent(2), anchorList[6].getParent(2), noMoveSpace) # Skin joints do ribbon skinJntsGrp = pm.group(em=True, n=self.name + 'SkinJnts_grp') follGrp = pm.group(em=True, n=self.name + 'Foll_grp') # cria ramps para controlar o perfil de squash e stretch ramp1 = pm.createNode('ramp', n=self.name + 'SquashRamp1') ramp1.attr('type').set(1) # ramp2 = pm.createNode ('ramp') # ramp2.attr('type').set(1) expre1 = "float $dummy = " + ramp1.name( ) + ".outAlpha;float $output[];float $color[];" # expre2 = "float $dummy = "+ramp2.name()+".outAlpha;float $output[];float $color[];" extraCntrlsGrp = pm.group(em=True, r=True, p=cntrlsSpace, n=self.name + 'extraCntrls_grp') # loop pra fazer os colocar o numero escolhido de joints ao longo do ribbon. # cria tmb node tree pro squash/stretch # e controles extras vIncrement = float( (1.0 - (self.offsetStart + self.offsetEnd)) / (self.numJnts - 1)) for i in range(1, self.numJnts + 1): # cria estrutura pra superficie 1 pm.select(cl=True) jntName = self.ribbonDict['jntSetup']['nameTempl'] + str( i) + self.jntSulfix jnt1 = pm.joint(p=(0, 0, 0), n=jntName) self.skinJoints.append(jnt1) displaySetup = self.ribbonDict['cntrlExtraSetup'].copy() cntrlName = displaySetup['nameTempl'] + 'A' + str(i) cntrl1 = controlTools.cntrlCrv(name=cntrlName, obj=jnt1, connType='parentConstraint', **displaySetup) # node tree blend1A = pm.createNode('blendTwoAttr', n=self.name + 'VolumeBlend1A') blend1B = pm.createNode('blendTwoAttr', n=self.name + 'VolumeBlend1B') gammaCorr1 = pm.createNode('gammaCorrect', n=self.name + 'VolumeGamma1') cntrlList[0].attr('autoVolumStregth') >> gammaCorr1.gammaX cntrlList[0].attr('stretchDist') >> gammaCorr1.value.valueX blend1A.input[0].set(1) gammaCorr1.outValueX >> blend1A.input[1] blend1B.input[0].set(1) blend1A.output >> blend1B.input[1] cntrlList[3].attr('autoVolume') >> blend1B.attributesBlender blend1B.output >> cntrl1.getParent().scaleY blend1B.output >> cntrl1.getParent().scaleZ # expressao que le a rampa para setar valores da escala de cada joint quando fizer squash/stretch expre1 = expre1 + "$color = `colorAtPoint -o RGB -u " + str( self.offsetStart + (i - 1) * vIncrement) + " -v 0.5 " + ramp1.name( ) + " `;$output[" + str(i) + "] = $color[0];" + blend1A.name( ) + ".attributesBlender=$output[" + str(i) + "];" # prende joints nas supeficies com follicules foll1 = self.attachObj(cntrl1.getParent(), bendSurf1[0], self.offsetStart + (i - 1) * vIncrement, 0.5, 4) pm.parent(cntrl1.getParent(), extraCntrlsGrp) pm.parent(jnt1, skinJntsGrp) pm.parent(foll1, follGrp) # seta expressoes para so serem avaliadas por demanda pm.expression(s=expre1, ae=False) pm.parent(skinJntsGrp, cntrlsSpace) pm.parent(follGrp, noMoveSpace) # hideCntrls pm.toggle(bendSurf1[0], g=True) bendSurf1[0].visibility.set(0) # skinJntsGrp.visibility.set(0) cntrlsSpace.extraCntrlsVis >> extraCntrlsGrp.visibility cntrlsSpace.cntrlsVis >> cntrlList[0].getParent().visibility cntrlsSpace.cntrlsVis >> cntrlList[3].getParent().visibility cntrlsSpace.cntrlsVis >> cntrlList[6].getParent().visibility # povoa ribbon Dict self.ribbonDict['name'] = 'bezierRibbon' self.ribbonDict['ribbonMoveAll'] = cntrlsSpace for i in range(0, 7): self.ribbonDict['cntrl' + str(i)] = cntrlList[i] self.startCntrl = cntrlList[0] self.midCntrl = cntrlList[3] self.endCntrl = cntrlList[6] self.moveall = cntrlsSpace
def createMultiStereoCamera(root, rootShape, camIndex, nStereoCams=9): ''' create a multi stereo camera and setup control expressions ''' cam, camShape = pc.camera() pc.parent(cam, root) name = str(root) + '_StereoCam%d' % (camIndex+1) cam.rename(name) camShape.renderable.set(False) # Connect the camera attributes from the master, hide them # for attr in [ 'horizontalFilmAperture', 'verticalFilmAperture', 'focalLength', 'lensSqueezeRatio', 'fStop', 'focusDistance', 'shutterAngle', 'cameraPrecompTemplate', 'filmFit', 'displayFilmGate', 'displayResolution', 'nearClipPlane', 'farClipPlane' ] : camShapeAttr = camShape.attr(attr) rootShape.attr(attr) >> camShapeAttr camShapeAttr.set(keyable=False) for attr in [ 'visibility', 'centerOfInterest' ] : cam.attr(attr).set(keyable=False) #stereoOffset = stereoEyeSeparation * (camIndex - nCams/2.0 + 0.5) #shift = -stereoOffset * (fl/10.0) / imageZ * p / (INCHES_TO_MM/10) mult = camIndex - nStereoCams / 2.0 + 0.5 mult *= 2 offsetAttr = 'stereoRightOffset' rotAttr = 'stereoRightAngle' hfoAttr = 'filmBackOutputRight' if mult < 0: offsetAttr = 'stereoLeftOffset' rotAttr = 'stereoLeftAngle' hfoAttr = 'filmBackOutputLeft' mult = abs(mult) offsetAttr = root.attr(offsetAttr) rotAttr = root.attr(rotAttr) hfoAttr = root.attr(hfoAttr) expression = getMultStereoExpression( mult, hfoAttr, offsetAttr, rotAttr, rootShape.zeroParallax, cam.translateX, camShape.hfo, cam.rotateY ) exprNode = pc.expression(s=expression) exprNode.rename(cam.name() + '_expression') lockAndHide(cam) return cam
def createParticleEmitter(self, meshEmitter, collider): # Force nParticle balls at creation pm.optionVar(sv=("NParticleStyle", "Balls")) self.particle, self.partShape = pm.nParticle(n=str(meshEmitter) + "_particle") #Add attribute in particleShape pm.addAttr(self.partShape, ln="indexPP", dt="doubleArray") pm.addAttr(self.partShape, ln="rotatePP", dt="vectorArray") pm.addAttr(self.partShape, ln="scalePP", dt="vectorArray") pm.addAttr(self.partShape, ln="rgbPP", dt="vectorArray") pm.addAttr(self.partShape, ln="fixPosPP", dt="vectorArray") pm.addAttr(self.partShape, ln="opacityPP", dt="doubleArray") pm.addAttr(self.partShape, ln="typePP", dt="doubleArray") self.nameEmitter = str(meshEmitter) + "_emitter" pm.emitter(meshEmitter, type="surface", name=self.nameEmitter, r=float(self.ui.simulationEmit_le.text())) pm.connectDynamic(self.partShape, em=self.nameEmitter) #Used maya command because pymel crash when find nucleus node self.nucleusName = mel.eval("listConnections -type \"nucleus\" " + self.partShape + ";")[0] pm.parent(self.partShape, self.worldParent) pm.parent(self.nameEmitter, self.worldParent) pm.parent(self.nucleusName, self.worldParent) self.setParamaters(self.partShape, self.particleParameter) self.setParamaters(self.nameEmitter, self.emitterParameter) self.setParamaters(self.nucleusName, self.nucleusParameter) pm.addAttr(self.partShape, ln="radiusPP", dt="doubleArray") #Create Rigid pm.select(collider, r=1) pm.runtime.nClothMakeCollide(collider) self.nrigid = pm.listConnections(collider.listRelatives(s=1, c=1)[0], type='nRigid')[0] self.setParamaters( self.nrigid.listRelatives(s=1, c=1)[0], self.rigidParameter) pm.parent(self.nrigid, self.worldParent) self.nrigid.setAttr("v", 0) #Create instancer self.instancer = pm.particleInstancer(self.partShape, a=True, object=self.listInstance, n=str(meshEmitter) + "_instancer", cycle="sequential", age="indexPP", rotation="rotatePP", scale="scalePP", visibility="opacityPP") pm.parent(self.instancer, self.worldParent) #Create proc Colision expression = """ global proc forestGeneratorEvent(string $particleObject,int $particleId, string $geometryObject) { vector $rgb = `nParticle -attribute rgbPP -id $particleId -q $particleObject`; if ($rgb != << 1,1,1 >>) { nParticle -e -attribute rgbPP -id $particleId -vv 0 1 0 $particleObject; } vector $pos = `nParticle -attribute position -id $particleId -q $particleObject`; vector $lastPos = `nParticle -attribute lastPosition -id $particleId -q $particleObject`; nParticle -e -attribute opacityPP -id $particleId -fv 1 $particleObject; if (mag($pos - $lastPos) >= 10 && $rgb != << 1,1,1 >>){ nParticle -e -attribute lifespanPP -id $particleId -fv 0 $particleObject; } }""" pm.expression(s=expression, n="forestGenerator_exp") #Create Colision event pm.event(self.partShape, die=0, count=0, proc="forestGeneratorEvent")
def make(cls, start, end, name="soMuscle"): """Creates a new muscle positioned between start and end. start & end must both be locators. The locators are hijacked by the muscle and moved into its own special group. :param start: A locator describing where the muscle starts. :param end: A locator describing where the muscle ends. :param name: (optional) A descriptive name for the muscle (group.) """ snode = pm.PyNode(start) if snode is None: raise ValueError("Couldn't deduce Maya type for start.") enode = pm.PyNode(end) if enode is None: raise ValueError("Couldn't dedude Maya type for end.") def findshape(n): if n.nodeType() == "transform": children = n.getChildren() # Can probably use n.getShape() here. if len(children) > 0: return children[0], n else: raise TypeError("Expected a locator or its transform node in start") elif n.nodeType() == "locator": return n, n.getParent() else: raise TypeError("Expected a locator or its transform node in start") def getrottrans(trans): return trans.getRotation(space="world"), trans.getTranslation(space="world") # Find locator shapes, mostly to make sure they are locators. # Their transforms are needed though. snode, sloctrans = findshape(snode) enode, eloctrans = findshape(enode) mloctrans = pm.spaceLocator() # Point-constrain and orient constrain to other locators. pm.pointConstraint(sloctrans, eloctrans, mloctrans, maintainOffset=False) pm.orientConstraint(sloctrans, eloctrans, mloctrans) maingrp = pm.group(empty=True, name=name) maingrp.translate.lock(), maingrp.rotate.lock(), maingrp.scale.lock() grp = pm.group(empty=True, name="moveGroup") grp.setParent(maingrp) sloctrans.setParent(grp), sloctrans.rename("muscleStart") eloctrans.setParent(grp), eloctrans.rename("muscleEnd") mloctrans.setParent(grp), mloctrans.rename("muscleMid") # Make the locators smaller in the UI. for loctrans in [sloctrans, mloctrans, eloctrans]: loctrans.getShape().localScale.set(0.25, 0.25, 0.25) startdef = ("start", sloctrans) + getrottrans(sloctrans) enddef = ("end", eloctrans) + getrottrans(eloctrans) middef = ("mid", mloctrans) + getrottrans(mloctrans) circles = [] for name, parent, rot, pos in [startdef, middef, enddef]: transform, _ = pm.circle(radius=0.1) pm.delete(transform, ch=True) circles.append(transform) transform.setParent(parent) # Change name AFTER we've parented them, so we can avoid naming collisions. transform.rename(name) transform.setRotation(rot) transform.setTranslation(pos, space="world") loftrans, _ = pm.loft(*circles) loftrans.setParent(maingrp) # Put in maingrp, so we avoid double transforms. loftrans.rename("muscleSurface") midcircle = circles[1] def addfloat3(obj, attrname): obj.addAttr(attrname, at="float3") for suffix in ["X", "Y", "Z"]: obj.addAttr(attrname + suffix, at="float", parent=attrname, k=True) addfloat3(midcircle, "startPos") addfloat3(midcircle, "endPos") maingrp.addAttr("bulgeFactor", at="float", defaultValue=1.0, minValue=0.01, maxValue=1000, k=True) sloctrans.translate >> midcircle.startPos eloctrans.translate >> midcircle.endPos # Some horrible MEL to preserve volume. expression = """ vector $a = <<{0}.startPosX, {0}.startPosY, {0}.startPosZ>>; vector $b = <<{0}.endPosX, {0}.endPosY, {0}.endPosZ>>; float $len = `mag ($b - $a)`; $len += 0.0000001; float $f = {1}.bulgeFactor / $len; scaleX = $f; scaleY = $f; """.format(midcircle.name(), maingrp.name()) pm.expression(o=midcircle, s=expression)